diff --git a/en/v1.12-dev/.documenter-siteinfo.json b/en/v1.12-dev/.documenter-siteinfo.json index 496e50a429de..d574a5debc3f 100644 --- a/en/v1.12-dev/.documenter-siteinfo.json +++ b/en/v1.12-dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.12.0-DEV.246","generation_timestamp":"2024-03-26T09:47:41","documenter_version":"1.3.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.12.0-DEV.247","generation_timestamp":"2024-03-26T13:22:10","documenter_version":"1.3.0"}} \ No newline at end of file diff --git a/en/v1.12-dev/NEWS/index.html b/en/v1.12-dev/NEWS/index.html index 315b56caac92..0b1c9cfc1148 100644 --- a/en/v1.12-dev/NEWS/index.html +++ b/en/v1.12-dev/NEWS/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Julia v1.12 Release Notes

New language features

Language changes

  • When methods are replaced with exactly equivalent ones, the old method is no longer deleted implicitly simultaneously, although the new method does take priority and become more specific than the old method. Thus if the new method is deleted later, the old method will resume operating. This can be useful to mocking frameworks (such as in SparseArrays, Pluto, and Mocking, among others), as they do not need to explicitly restore the old method. While inference and compilation still must be repeated with this, it also may pave the way for inference to be able to intelligently re-use the old results, once the new method is deleted. (#53415)

  • Macro expansion will no longer eargerly recurse into into Expr(:toplevel) expressions returned from macros. Instead, macro expansion of :toplevel expressions will be delayed until evaluation time. This allows a later expression within a given :toplevel expression to make use of macros defined earlier in the same :toplevel expression. (#53515)

Compiler/Runtime improvements

  • Generated LLVM IR now uses actual pointer types instead of passing pointers as integers. This affects llvmcall: Inline LLVM IR should be updated to use i8* or ptr instead of i32 or i64, and remove unneeded ptrtoint/inttoptr conversions. For compatibility, IR with integer pointers is still supported, but generates a deprecation warning. (#53687)

Command-line option changes

  • The -m/--module flag can be passed to run the main function inside a package with a set of arguments. This main function should be declared using @main to indicate that it is an entry point.

Multi-threading changes

Build system changes

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 if put!(c, some_value) will block. (#53159)
  • waitany(tasks; throw=false) and waitall(tasks; failfast=false, throw=false) which wait multiple tasks at once (#53341).

New library features

  • invmod(n, T) where T is a native integer type now computes the modular inverse of n in the modular integer ring that T defines (#52180).
  • invmod(n) is an abbreviation for invmod(n, typeof(n)) for native integer types (#52180).
  • replace(string, pattern...) now supports an optional IO argument to write the output to a stream rather than returning a string (#48625).
  • sizehint!(s, n) now supports an optional shrink argument to disable shrinking (#51929).
  • New function Docs.hasdoc(module, symbol) tells whether a name has a docstring (#52139).
  • New function Docs.undocumented_names(module) returns a module's undocumented public names (#52413).
  • Passing an IOBuffer as a stdout argument for Process spawn now works as expected, synchronized with wait or success, so a Base.BufferStream is no longer required there for correctness to avoid data races (#52461).
  • After a process exits, closewrite will no longer be automatically called on the stream passed to it. Call wait on the process instead to ensure the content is fully written, then call closewrite manually to avoid data-races. Or use the callback form of open to have all that handled automatically.
  • @timed now additionally returns the elapsed compilation and recompilation time (#52889)
  • filter can now act on a NamedTuple (#50795).
  • tempname can now take a suffix string to allow the file name to include a suffix and include that suffix in the uniquing checking (#53474)
  • RegexMatch objects can now be used to construct NamedTuples and Dicts (#50988)

Standard library changes

StyledStrings

JuliaSyntaxHighlighting

Package Manager

LinearAlgebra

Logging

Printf

Profile

Random

REPL

SuiteSparse

SparseArrays

Test

Dates

Statistics

Distributed

Unicode

DelimitedFiles

InteractiveUtils

Deprecated or removed

External dependencies

Tooling Improvements

+

Julia v1.12 Release Notes

New language features

Language changes

  • When methods are replaced with exactly equivalent ones, the old method is no longer deleted implicitly simultaneously, although the new method does take priority and become more specific than the old method. Thus if the new method is deleted later, the old method will resume operating. This can be useful to mocking frameworks (such as in SparseArrays, Pluto, and Mocking, among others), as they do not need to explicitly restore the old method. While inference and compilation still must be repeated with this, it also may pave the way for inference to be able to intelligently re-use the old results, once the new method is deleted. (#53415)

  • Macro expansion will no longer eargerly recurse into into Expr(:toplevel) expressions returned from macros. Instead, macro expansion of :toplevel expressions will be delayed until evaluation time. This allows a later expression within a given :toplevel expression to make use of macros defined earlier in the same :toplevel expression. (#53515)

Compiler/Runtime improvements

  • Generated LLVM IR now uses actual pointer types instead of passing pointers as integers. This affects llvmcall: Inline LLVM IR should be updated to use i8* or ptr instead of i32 or i64, and remove unneeded ptrtoint/inttoptr conversions. For compatibility, IR with integer pointers is still supported, but generates a deprecation warning. (#53687)

Command-line option changes

  • The -m/--module flag can be passed to run the main function inside a package with a set of arguments. This main function should be declared using @main to indicate that it is an entry point.

Multi-threading changes

Build system changes

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 if put!(c, some_value) will block. (#53159)
  • waitany(tasks; throw=false) and waitall(tasks; failfast=false, throw=false) which wait multiple tasks at once (#53341).

New library features

  • invmod(n, T) where T is a native integer type now computes the modular inverse of n in the modular integer ring that T defines (#52180).
  • invmod(n) is an abbreviation for invmod(n, typeof(n)) for native integer types (#52180).
  • replace(string, pattern...) now supports an optional IO argument to write the output to a stream rather than returning a string (#48625).
  • sizehint!(s, n) now supports an optional shrink argument to disable shrinking (#51929).
  • New function Docs.hasdoc(module, symbol) tells whether a name has a docstring (#52139).
  • New function Docs.undocumented_names(module) returns a module's undocumented public names (#52413).
  • Passing an IOBuffer as a stdout argument for Process spawn now works as expected, synchronized with wait or success, so a Base.BufferStream is no longer required there for correctness to avoid data races (#52461).
  • After a process exits, closewrite will no longer be automatically called on the stream passed to it. Call wait on the process instead to ensure the content is fully written, then call closewrite manually to avoid data-races. Or use the callback form of open to have all that handled automatically.
  • @timed now additionally returns the elapsed compilation and recompilation time (#52889)
  • filter can now act on a NamedTuple (#50795).
  • tempname can now take a suffix string to allow the file name to include a suffix and include that suffix in the uniquing checking (#53474)
  • RegexMatch objects can now be used to construct NamedTuples and Dicts (#50988)

Standard library changes

StyledStrings

JuliaSyntaxHighlighting

Package Manager

LinearAlgebra

Logging

Printf

Profile

Random

REPL

SuiteSparse

SparseArrays

Test

Dates

Statistics

Distributed

Unicode

DelimitedFiles

InteractiveUtils

Deprecated or removed

External dependencies

Tooling Improvements

diff --git a/en/v1.12-dev/base/arrays/index.html b/en/v1.12-dev/base/arrays/index.html index 5fa4be4f5976..6988aec48f88 100644 --- a/en/v1.12-dev/base/arrays/index.html +++ b/en/v1.12-dev/base/arrays/index.html @@ -3,7 +3,7 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Arrays

Constructors and Types

Core.ArrayType
Array{T,N} <: AbstractArray{T,N}

N-dimensional dense array with elements of type T.

source
Core.ArrayMethod
Array{T}(undef, dims)
+

Arrays

Constructors and Types

Core.ArrayType
Array{T,N} <: AbstractArray{T,N}

N-dimensional dense array with elements of type T.

source
Core.ArrayMethod
Array{T}(undef, dims)
 Array{T,N}(undef, dims)

Construct an uninitialized N-dimensional Array containing elements of type T. N can either be supplied explicitly, as in Array{T,N}(undef, dims), or be determined by the length or number of dims. dims may be a tuple or a series of integer arguments corresponding to the lengths in each dimension. If the rank N is supplied explicitly, then it must match the length or number of dims. Here undef is the UndefInitializer.

Examples

julia> A = Array{Float64, 2}(undef, 2, 3) # N given explicitly
 2×3 Matrix{Float64}:
  6.90198e-310  6.90198e-310  6.90198e-310
@@ -20,7 +20,7 @@
 2×4×1 Array{Float64, 3}:
 [:, :, 1] =
  2.26703e-314  2.26708e-314  0.0           2.80997e-314
- 0.0           2.26703e-314  2.26708e-314  0.0
source
Core.ArrayMethod
Array{T}(nothing, dims)
+ 0.0           2.26703e-314  2.26708e-314  0.0
source
Core.ArrayMethod
Array{T}(nothing, dims)
 Array{T,N}(nothing, dims)

Construct an N-dimensional Array containing elements of type T, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.

Examples

julia> Array{Union{Nothing, String}}(nothing, 2)
 2-element Vector{Union{Nothing, String}}:
  nothing
@@ -29,7 +29,7 @@
 julia> Array{Union{Nothing, Int}}(nothing, 2, 3)
 2×3 Matrix{Union{Nothing, Int64}}:
  nothing  nothing  nothing
- nothing  nothing  nothing
source
Core.ArrayMethod
Array{T}(missing, dims)
 Array{T,N}(missing, dims)

Construct an N-dimensional Array containing elements of type T, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.

Examples

julia> Array{Union{Missing, String}}(missing, 2)
 2-element Vector{Union{Missing, String}}:
  missing
@@ -38,25 +38,25 @@
 julia> Array{Union{Missing, Int}}(missing, 2, 3)
 2×3 Matrix{Union{Missing, Int64}}:
  missing  missing  missing
- missing  missing  missing
source
Core.UndefInitializerType
UndefInitializer

Singleton type used in array initialization, indicating the array-constructor-caller would like an uninitialized array. See also undef, an alias for UndefInitializer().

Examples

julia> Array{Float64, 1}(UndefInitializer(), 3)
+ missing  missing  missing
source
Core.UndefInitializerType
UndefInitializer

Singleton type used in array initialization, indicating the array-constructor-caller would like an uninitialized array. See also undef, an alias for UndefInitializer().

Examples

julia> Array{Float64, 1}(UndefInitializer(), 3)
 3-element Array{Float64, 1}:
  2.2752528595e-314
  2.202942107e-314
- 2.275252907e-314
source
Core.undefConstant
undef

Alias for UndefInitializer(), which constructs an instance of the singleton type UndefInitializer, used in array initialization to indicate the array-constructor-caller would like an uninitialized array.

See also: missing, similar.

Examples

julia> Array{Float64, 1}(undef, 3)
+ 2.275252907e-314
source
Core.undefConstant
undef

Alias for UndefInitializer(), which constructs an instance of the singleton type UndefInitializer, used in array initialization to indicate the array-constructor-caller would like an uninitialized array.

See also: missing, similar.

Examples

julia> Array{Float64, 1}(undef, 3)
 3-element Vector{Float64}:
  2.2752528595e-314
  2.202942107e-314
- 2.275252907e-314
source
Base.VectorType
Vector{T} <: AbstractVector{T}

One-dimensional dense array with elements of type T, often used to represent a mathematical vector. Alias for Array{T,1}.

See also empty, similar and zero for creating vectors.

source
Base.VectorMethod
Vector{T}(undef, n)

Construct an uninitialized Vector{T} of length n.

Examples

julia> Vector{Float64}(undef, 3)
+ 2.275252907e-314
source
Base.VectorType
Vector{T} <: AbstractVector{T}

One-dimensional dense array with elements of type T, often used to represent a mathematical vector. Alias for Array{T,1}.

See also empty, similar and zero for creating vectors.

source
Base.VectorMethod
Vector{T}(undef, n)

Construct an uninitialized Vector{T} of length n.

Examples

julia> Vector{Float64}(undef, 3)
 3-element Array{Float64, 1}:
  6.90966e-310
  6.90966e-310
- 6.90966e-310
source
Base.VectorMethod
Vector{T}(nothing, m)

Construct a Vector{T} of length m, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.

Examples

julia> Vector{Union{Nothing, String}}(nothing, 2)
+ 6.90966e-310
source
Base.VectorMethod
Vector{T}(nothing, m)

Construct a Vector{T} of length m, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.

Examples

julia> Vector{Union{Nothing, String}}(nothing, 2)
 2-element Vector{Union{Nothing, String}}:
  nothing
- nothing
source
Base.VectorMethod
Vector{T}(missing, m)

Construct a Vector{T} of length m, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.

Examples

julia> Vector{Union{Missing, String}}(missing, 2)
+ nothing
source
Base.VectorMethod
Vector{T}(missing, m)

Construct a Vector{T} of length m, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.

Examples

julia> Vector{Union{Missing, String}}(missing, 2)
 2-element Vector{Union{Missing, String}}:
  missing
- missing
source
Base.MatrixMethod
Matrix{T}(undef, m, n)

Construct an uninitialized Matrix{T} of size m×n.

Examples

julia> Matrix{Float64}(undef, 2, 3)
+ missing
source
Base.MatrixMethod
Matrix{T}(undef, m, n)

Construct an uninitialized Matrix{T} of size m×n.

Examples

julia> Matrix{Float64}(undef, 2, 3)
 2×3 Array{Float64, 2}:
  2.36365e-314  2.28473e-314    5.0e-324
  2.26704e-314  2.26711e-314  NaN
@@ -64,21 +64,21 @@
 julia> similar(ans, Int32, 2, 2)
 2×2 Matrix{Int32}:
  490537216  1277177453
-         1  1936748399
source
Base.MatrixMethod
Matrix{T}(nothing, m, n)

Construct a Matrix{T} of size m×n, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.

Examples

julia> Matrix{Union{Nothing, String}}(nothing, 2, 3)
+         1  1936748399
source
Base.MatrixMethod
Matrix{T}(nothing, m, n)

Construct a Matrix{T} of size m×n, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.

Examples

julia> Matrix{Union{Nothing, String}}(nothing, 2, 3)
 2×3 Matrix{Union{Nothing, String}}:
  nothing  nothing  nothing
- nothing  nothing  nothing
source
Base.MatrixMethod
Matrix{T}(missing, m, n)

Construct a Matrix{T} of size m×n, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.

Examples

julia> Matrix{Union{Missing, String}}(missing, 2, 3)
+ nothing  nothing  nothing
source
Base.MatrixMethod
Matrix{T}(missing, m, n)

Construct a Matrix{T} of size m×n, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.

Examples

julia> Matrix{Union{Missing, String}}(missing, 2, 3)
 2×3 Matrix{Union{Missing, String}}:
  missing  missing  missing
- missing  missing  missing
source
Base.VecOrMatType
VecOrMat{T}

Union type of Vector{T} and Matrix{T} which allows functions to accept either a Matrix or a Vector.

Examples

julia> Vector{Float64} <: VecOrMat{Float64}
+ missing  missing  missing
source
Base.VecOrMatType
VecOrMat{T}

Union type of Vector{T} and Matrix{T} which allows functions to accept either a Matrix or a Vector.

Examples

julia> Vector{Float64} <: VecOrMat{Float64}
 true
 
 julia> Matrix{Float64} <: VecOrMat{Float64}
 true
 
 julia> Array{Float64, 3} <: VecOrMat{Float64}
-false
source
Core.DenseArrayType
DenseArray{T, N} <: AbstractArray{T,N}

N-dimensional dense array with elements of type T. The elements of a dense array are stored contiguously in memory.

source
Base.StridedArrayType
StridedArray{T, N}

A hard-coded Union of common array types that follow the strided array interface, with elements of type T and N dimensions.

If A is a StridedArray, then its elements are stored in memory with offsets, which may vary between dimensions but are constant within a dimension. For example, A could have stride 2 in dimension 1, and stride 3 in dimension 2. Incrementing A along dimension d jumps in memory by [stride(A, d)] slots. Strided arrays are particularly important and useful because they can sometimes be passed directly as pointers to foreign language libraries like BLAS.

source
Core.MemoryType
Memory{T} == GenericMemory{:not_atomic, T, Core.CPU}

One-dimensional dense array with elements of type T.

Julia 1.11

This type requires Julia 1.11 or later.

source
Core.MemoryRefType
MemoryRef(memory)

Construct a MemoryRef from a memory object. This does not fail, but the resulting memory may point out-of-bounds if the memory is empty.

source
MemoryRef(::Memory, index::Integer)
-MemoryRef(::MemoryRef, index::Integer)

Construct a MemoryRef from a memory object and an offset index (1-based) which can also be negative. This always returns an inbounds object, and will throw an error if that is not possible (because the index would result in a shift out-of-bounds of the underlying memory).

source
Base.SlicesType
Slices{P,SM,AX,S,N} <: AbstractSlices{S,N}

An AbstractArray of slices into a parent array over specified dimension(s), returning views that select all the data from the other dimension(s).

These should typically be constructed by eachslice, eachcol or eachrow.

parent(s::Slices) will return the parent array.

source
Base.getindexMethod
getindex(type[, elements...])

Construct a 1-d array of the specified type. This is usually called with the syntax Type[]. Element values can be specified using Type[a,b,c,...].

Examples

julia> Int8[1, 2, 3]
+false
source
Core.DenseArrayType
DenseArray{T, N} <: AbstractArray{T,N}

N-dimensional dense array with elements of type T. The elements of a dense array are stored contiguously in memory.

source
Base.StridedArrayType
StridedArray{T, N}

A hard-coded Union of common array types that follow the strided array interface, with elements of type T and N dimensions.

If A is a StridedArray, then its elements are stored in memory with offsets, which may vary between dimensions but are constant within a dimension. For example, A could have stride 2 in dimension 1, and stride 3 in dimension 2. Incrementing A along dimension d jumps in memory by [stride(A, d)] slots. Strided arrays are particularly important and useful because they can sometimes be passed directly as pointers to foreign language libraries like BLAS.

source
Core.MemoryType
Memory{T} == GenericMemory{:not_atomic, T, Core.CPU}

One-dimensional dense array with elements of type T.

Julia 1.11

This type requires Julia 1.11 or later.

source
Core.MemoryRefType
MemoryRef(memory)

Construct a MemoryRef from a memory object. This does not fail, but the resulting memory may point out-of-bounds if the memory is empty.

source
MemoryRef(::Memory, index::Integer)
+MemoryRef(::MemoryRef, index::Integer)

Construct a MemoryRef from a memory object and an offset index (1-based) which can also be negative. This always returns an inbounds object, and will throw an error if that is not possible (because the index would result in a shift out-of-bounds of the underlying memory).

source
Base.SlicesType
Slices{P,SM,AX,S,N} <: AbstractSlices{S,N}

An AbstractArray of slices into a parent array over specified dimension(s), returning views that select all the data from the other dimension(s).

These should typically be constructed by eachslice, eachcol or eachrow.

parent(s::Slices) will return the parent array.

source
Base.getindexMethod
getindex(type[, elements...])

Construct a 1-d array of the specified type. This is usually called with the syntax Type[]. Element values can be specified using Type[a,b,c,...].

Examples

julia> Int8[1, 2, 3]
 3-element Vector{Int8}:
  1
  2
@@ -88,7 +88,7 @@
 3-element Vector{Int8}:
  1
  2
- 3
source
Base.zerosFunction
zeros([T=Float64,] dims::Tuple)
 zeros([T=Float64,] dims...)

Create an Array, with element type T, of all zeros with size specified by dims. See also fill, ones, zero.

Examples

julia> zeros(1)
 1-element Vector{Float64}:
  0.0
@@ -96,7 +96,7 @@
 julia> zeros(Int8, 2, 3)
 2×3 Matrix{Int8}:
  0  0  0
- 0  0  0
source
Base.onesFunction
ones([T=Float64,] dims::Tuple)
 ones([T=Float64,] dims...)

Create an Array, with element type T, of all ones with size specified by dims. See also fill, zeros.

Examples

julia> ones(1,2)
 1×2 Matrix{Float64}:
  1.0  1.0
@@ -104,7 +104,7 @@
 julia> ones(ComplexF64, 2, 3)
 2×3 Matrix{ComplexF64}:
  1.0+0.0im  1.0+0.0im  1.0+0.0im
- 1.0+0.0im  1.0+0.0im  1.0+0.0im
source
Base.BitArrayType
BitArray{N} <: AbstractArray{Bool, N}

Space-efficient N-dimensional boolean array, using just one bit for each boolean value.

BitArrays pack up to 64 values into every 8 bytes, resulting in an 8x space efficiency over Array{Bool, N} and allowing some operations to work on 64 values at once.

By default, Julia returns BitArrays from broadcasting operations that generate boolean elements (including dotted-comparisons like .==) as well as from the functions trues and falses.

Note

Due to its packed storage format, concurrent access to the elements of a BitArray where at least one of them is a write is not thread-safe.

source
Base.BitArrayMethod
BitArray(undef, dims::Integer...)
+ 1.0+0.0im  1.0+0.0im  1.0+0.0im
source
Base.BitArrayType
BitArray{N} <: AbstractArray{Bool, N}

Space-efficient N-dimensional boolean array, using just one bit for each boolean value.

BitArrays pack up to 64 values into every 8 bytes, resulting in an 8x space efficiency over Array{Bool, N} and allowing some operations to work on 64 values at once.

By default, Julia returns BitArrays from broadcasting operations that generate boolean elements (including dotted-comparisons like .==) as well as from the functions trues and falses.

Note

Due to its packed storage format, concurrent access to the elements of a BitArray where at least one of them is a write is not thread-safe.

source
Base.BitArrayMethod
BitArray(undef, dims::Integer...)
 BitArray{N}(undef, dims::NTuple{N,Int})

Construct an undef BitArray with the given dimensions. Behaves identically to the Array constructor. See undef.

Examples

julia> BitArray(undef, 2, 2)
 2×2 BitMatrix:
  0  0
@@ -114,7 +114,7 @@
 3×1 BitMatrix:
  0
  0
- 0
source
Base.BitArrayMethod
BitArray(itr)

Construct a BitArray generated by the given iterable object. The shape is inferred from the itr object.

Examples

julia> BitArray([1 0; 0 1])
+ 0
source
Base.BitArrayMethod
BitArray(itr)

Construct a BitArray generated by the given iterable object. The shape is inferred from the itr object.

Examples

julia> BitArray([1 0; 0 1])
 2×2 BitMatrix:
  1  0
  0  1
@@ -131,13 +131,13 @@
  0
  1
  0
- 0
source
Base.truesFunction
trues(dims)

Create a BitArray with all values set to true.

Examples

julia> trues(2,3)
+ 0
source
Base.truesFunction
trues(dims)

Create a BitArray with all values set to true.

Examples

julia> trues(2,3)
 2×3 BitMatrix:
  1  1  1
- 1  1  1
source
Base.falsesFunction
falses(dims)

Create a BitArray with all values set to false.

Examples

julia> falses(2,3)
+ 1  1  1
source
Base.falsesFunction
falses(dims)

Create a BitArray with all values set to false.

Examples

julia> falses(2,3)
 2×3 BitMatrix:
  0  0  0
- 0  0  0
source
Base.fillFunction
fill(value, dims::Tuple)
 fill(value, dims...)

Create an array of size dims with every location set to value.

For example, fill(1.0, (5,5)) returns a 5×5 array of floats, with 1.0 in every location of the array.

The dimension lengths dims may be specified as either a tuple or a sequence of arguments. An N-length tuple or N arguments following the value specify an N-dimensional array. Thus, a common idiom for creating a zero-dimensional array with its only location set to x is fill(x).

Every location of the returned array is set to (and is thus === to) the value that was passed; this means that if the value is itself modified, all elements of the filled array will reflect that modification because they're still that very value. This is of no concern with fill(1.0, (5,5)) as the value 1.0 is immutable and cannot itself be modified, but can be unexpected with mutable values like — most commonly — arrays. For example, fill([], 3) places the very same empty array in all three locations of the returned vector:

julia> v = fill([], 3)
 3-element Vector{Vector{Any}}:
  []
@@ -194,7 +194,7 @@
 julia> A # both A[1] and A[2] are the very same vector
 2-element Vector{Vector{Float64}}:
  [42.0, 0.0]
- [42.0, 0.0]
source
Base.fill!Function
fill!(A, x)

Fill array A with the value x. If x is an object reference, all elements will refer to the same object. fill!(A, Foo()) will return A filled with the result of evaluating Foo() once.

Examples

julia> A = zeros(2,3)
+ [42.0, 0.0]
source
Base.fill!Function
fill!(A, x)

Fill array A with the value x. If x is an object reference, all elements will refer to the same object. fill!(A, Foo()) will return A filled with the result of evaluating Foo() once.

Examples

julia> A = zeros(2,3)
 2×3 Matrix{Float64}:
  0.0  0.0  0.0
  0.0  0.0  0.0
@@ -214,11 +214,11 @@
 3-element Vector{Int64}:
  1
  1
- 1
source
Base.emptyFunction
empty(x::Tuple)

Return an empty tuple, ().

source
empty(v::AbstractVector, [eltype])

Create an empty vector similar to v, optionally changing the eltype.

See also: empty!, isempty, isassigned.

Examples

julia> empty([1.0, 2.0, 3.0])
+ 1
source
Base.emptyFunction
empty(x::Tuple)

Return an empty tuple, ().

source
empty(v::AbstractVector, [eltype])

Create an empty vector similar to v, optionally changing the eltype.

See also: empty!, isempty, isassigned.

Examples

julia> empty([1.0, 2.0, 3.0])
 Float64[]
 
 julia> empty([1.0, 2.0, 3.0], String)
-String[]
source
empty(a::AbstractDict, [index_type=keytype(a)], [value_type=valtype(a)])

Create an empty AbstractDict container which can accept indices of type index_type and values of type value_type. The second and third arguments are optional and default to the input's keytype and valtype, respectively. (If only one of the two types is specified, it is assumed to be the value_type, and the index_type we default to keytype(a)).

Custom AbstractDict subtypes may choose which specific dictionary type is best suited to return for the given index and value types, by specializing on the three-argument signature. The default is to return an empty Dict.

source
Base.similarFunction
similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}

Create an uninitialized mutable array with the given element type, index type, and size, based upon the given source SparseMatrixCSC. The new sparse matrix maintains the structure of the original sparse matrix, except in the case where dimensions of the output matrix are different from the output.

The output matrix has zeros in the same locations as the input, but uninitialized values for the nonzero locations.

similar(array, [element_type=eltype(array)], [dims=size(array)])

Create an uninitialized mutable array with the given element type and size, based upon the given source array. The second and third arguments are both optional, defaulting to the given array's eltype and size. The dimensions may be specified either as a single tuple argument or as a series of integer arguments.

Custom AbstractArray subtypes may choose which specific array type is best-suited to return for the given element type and dimensionality. If they do not specialize this method, the default is an Array{element_type}(undef, dims...).

For example, similar(1:10, 1, 4) returns an uninitialized Array{Int,2} since ranges are neither mutable nor support 2 dimensions:

julia> similar(1:10, 1, 4)
+String[]
source
empty(a::AbstractDict, [index_type=keytype(a)], [value_type=valtype(a)])

Create an empty AbstractDict container which can accept indices of type index_type and values of type value_type. The second and third arguments are optional and default to the input's keytype and valtype, respectively. (If only one of the two types is specified, it is assumed to be the value_type, and the index_type we default to keytype(a)).

Custom AbstractDict subtypes may choose which specific dictionary type is best suited to return for the given index and value types, by specializing on the three-argument signature. The default is to return an empty Dict.

source
Base.similarFunction
similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}

Create an uninitialized mutable array with the given element type, index type, and size, based upon the given source SparseMatrixCSC. The new sparse matrix maintains the structure of the original sparse matrix, except in the case where dimensions of the output matrix are different from the output.

The output matrix has zeros in the same locations as the input, but uninitialized values for the nonzero locations.

similar(array, [element_type=eltype(array)], [dims=size(array)])

Create an uninitialized mutable array with the given element type and size, based upon the given source array. The second and third arguments are both optional, defaulting to the given array's eltype and size. The dimensions may be specified either as a single tuple argument or as a series of integer arguments.

Custom AbstractArray subtypes may choose which specific array type is best-suited to return for the given element type and dimensionality. If they do not specialize this method, the default is an Array{element_type}(undef, dims...).

For example, similar(1:10, 1, 4) returns an uninitialized Array{Int,2} since ranges are neither mutable nor support 2 dimensions:

julia> similar(1:10, 1, 4)
 1×4 Matrix{Int64}:
  4419743872  4374413872  4419743888  0

Conversely, similar(trues(10,10), 2) returns an uninitialized BitVector with two elements since BitArrays are both mutable and can support 1-dimensional arrays:

julia> similar(trues(10,10), 2)
 2-element BitVector:
@@ -226,19 +226,19 @@
  0

Since BitArrays can only store elements of type Bool, however, if you request a different element type it will create a regular Array instead:

julia> similar(falses(10), Float64, 2, 4)
 2×4 Matrix{Float64}:
  2.18425e-314  2.18425e-314  2.18425e-314  2.18425e-314
- 2.18425e-314  2.18425e-314  2.18425e-314  2.18425e-314

See also: undef, isassigned.

source
similar(storagetype, axes)

Create an uninitialized mutable array analogous to that specified by storagetype, but with axes specified by the last argument.

Examples:

similar(Array{Int}, axes(A))

creates an array that "acts like" an Array{Int} (and might indeed be backed by one), but which is indexed identically to A. If A has conventional indexing, this will be identical to Array{Int}(undef, size(A)), but if A has unconventional indexing then the indices of the result will match A.

similar(BitArray, (axes(A, 2),))

would create a 1-dimensional logical array whose indices match those of the columns of A.

source

Basic functions

Base.ndimsFunction
ndims(A::AbstractArray) -> Integer

Return the number of dimensions of A.

See also: size, axes.

Examples

julia> A = fill(1, (3,4,5));
+ 2.18425e-314  2.18425e-314  2.18425e-314  2.18425e-314

See also: undef, isassigned.

source
similar(storagetype, axes)

Create an uninitialized mutable array analogous to that specified by storagetype, but with axes specified by the last argument.

Examples:

similar(Array{Int}, axes(A))

creates an array that "acts like" an Array{Int} (and might indeed be backed by one), but which is indexed identically to A. If A has conventional indexing, this will be identical to Array{Int}(undef, size(A)), but if A has unconventional indexing then the indices of the result will match A.

similar(BitArray, (axes(A, 2),))

would create a 1-dimensional logical array whose indices match those of the columns of A.

source

Basic functions

Base.ndimsFunction
ndims(A::AbstractArray) -> Integer

Return the number of dimensions of A.

See also: size, axes.

Examples

julia> A = fill(1, (3,4,5));
 
 julia> ndims(A)
-3
source
Base.sizeFunction
size(A::AbstractArray, [dim])

Return a tuple containing the dimensions of A. Optionally you can specify a dimension to just get the length of that dimension.

Note that size may not be defined for arrays with non-standard indices, in which case axes may be useful. See the manual chapter on arrays with custom indices.

See also: length, ndims, eachindex, sizeof.

Examples

julia> A = fill(1, (2,3,4));
+3
source
Base.sizeFunction
size(A::AbstractArray, [dim])

Return a tuple containing the dimensions of A. Optionally you can specify a dimension to just get the length of that dimension.

Note that size may not be defined for arrays with non-standard indices, in which case axes may be useful. See the manual chapter on arrays with custom indices.

See also: length, ndims, eachindex, sizeof.

Examples

julia> A = fill(1, (2,3,4));
 
 julia> size(A)
 (2, 3, 4)
 
 julia> size(A, 2)
-3
source
Base.axesMethod
axes(A)

Return the tuple of valid indices for array A.

See also: size, keys, eachindex.

Examples

julia> A = fill(1, (5,6,7));
 
 julia> axes(A)
-(Base.OneTo(5), Base.OneTo(6), Base.OneTo(7))
source
Base.axesMethod
axes(A, d)

Return the valid range of indices for array A along dimension d.

See also size, and the manual chapter on arrays with custom indices.

Examples

julia> A = fill(1, (5,6,7));
+(Base.OneTo(5), Base.OneTo(6), Base.OneTo(7))
source
Base.axesMethod
axes(A, d)

Return the valid range of indices for array A along dimension d.

See also size, and the manual chapter on arrays with custom indices.

Examples

julia> A = fill(1, (5,6,7));
 
 julia> axes(A, 2)
 Base.OneTo(6)
@@ -246,18 +246,18 @@
 julia> axes(A, 4) == 1:1  # all dimensions d > ndims(A) have size 1
 true

Usage note

Each of the indices has to be an AbstractUnitRange{<:Integer}, but at the same time can be a type that uses custom indices. So, for example, if you need a subset, use generalized indexing constructs like begin/end or firstindex/lastindex:

ix = axes(v, 1)
 ix[2:end]          # will work for eg Vector, but may fail in general
-ix[(begin+1):end]  # works for generalized indexes
source
Base.lengthMethod
length(A::AbstractArray)

Return the number of elements in the array, defaults to prod(size(A)).

Examples

julia> length([1, 2, 3, 4])
+ix[(begin+1):end]  # works for generalized indexes
source
Base.lengthMethod
length(A::AbstractArray)

Return the number of elements in the array, defaults to prod(size(A)).

Examples

julia> length([1, 2, 3, 4])
 4
 
 julia> length([1 2; 3 4])
-4
source
Base.keysMethod
keys(a::AbstractArray)

Return an efficient array describing all valid indices for a arranged in the shape of a itself.

The keys of 1-dimensional arrays (vectors) are integers, whereas all other N-dimensional arrays use CartesianIndex to describe their locations. Often the special array types LinearIndices and CartesianIndices are used to efficiently represent these arrays of integers and CartesianIndexes, respectively.

Note that the keys of an array might not be the most efficient index type; for maximum performance use eachindex instead.

Examples

julia> keys([4, 5, 6])
+4
source
Base.keysMethod
keys(a::AbstractArray)

Return an efficient array describing all valid indices for a arranged in the shape of a itself.

The keys of 1-dimensional arrays (vectors) are integers, whereas all other N-dimensional arrays use CartesianIndex to describe their locations. Often the special array types LinearIndices and CartesianIndices are used to efficiently represent these arrays of integers and CartesianIndexes, respectively.

Note that the keys of an array might not be the most efficient index type; for maximum performance use eachindex instead.

Examples

julia> keys([4, 5, 6])
 3-element LinearIndices{1, Tuple{Base.OneTo{Int64}}}:
  1
  2
  3
 
 julia> keys([4 5; 6 7])
-CartesianIndices((2, 2))
source
Base.eachindexFunction
eachindex(A...)
 eachindex(::IndexStyle, A::AbstractArray...)

Create an iterable object for visiting each index of an AbstractArray A in an efficient manner. For array types that have opted into fast linear indexing (like Array), this is simply the range 1:length(A) if they use 1-based indexing. For array types that have not opted into fast linear indexing, a specialized Cartesian range is typically returned to efficiently index into the array with indices specified for every dimension.

In general eachindex accepts arbitrary iterables, including strings and dictionaries, and returns an iterator object supporting arbitrary index types (e.g. unevenly spaced or non-integer indices).

If A is AbstractArray it is possible to explicitly specify the style of the indices that should be returned by eachindex by passing a value having IndexStyle type as its first argument (typically IndexLinear() if linear indices are required or IndexCartesian() if Cartesian range is wanted).

If you supply more than one AbstractArray argument, eachindex will create an iterable object that is fast for all arguments (typically a UnitRange if all inputs have fast linear indexing, a CartesianIndices otherwise). If the arrays have different sizes and/or dimensionalities, a DimensionMismatch exception will be thrown.

See also pairs(A) to iterate over indices and values together, and axes(A, 2) for valid indices along one dimension.

Examples

julia> A = [10 20; 30 40];
 
 julia> for i in eachindex(A) # linear indexing
@@ -272,8 +272,8 @@
            println(i)
        end
 CartesianIndex(1, 1)
-CartesianIndex(2, 1)
source
Base.IndexStyleType
IndexStyle(A)
-IndexStyle(typeof(A))

IndexStyle specifies the "native indexing style" for array A. When you define a new AbstractArray type, you can choose to implement either linear indexing (with IndexLinear) or cartesian indexing. If you decide to only implement linear indexing, then you must set this trait for your array type:

Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()

The default is IndexCartesian().

Julia's internal indexing machinery will automatically (and invisibly) recompute all indexing operations into the preferred style. This allows users to access elements of your array using any indexing style, even when explicit methods have not been provided.

If you define both styles of indexing for your AbstractArray, this trait can be used to select the most performant indexing style. Some methods check this trait on their inputs, and dispatch to different algorithms depending on the most efficient access pattern. In particular, eachindex creates an iterator whose type depends on the setting of this trait.

source
Base.IndexLinearType
IndexLinear()

Subtype of IndexStyle used to describe arrays which are optimally indexed by one linear index.

A linear indexing style uses one integer index to describe the position in the array (even if it's a multidimensional array) and column-major ordering is used to efficiently access the elements. This means that requesting eachindex from an array that is IndexLinear will return a simple one-dimensional range, even if it is multidimensional.

A custom array that reports its IndexStyle as IndexLinear only needs to implement indexing (and indexed assignment) with a single Int index; all other indexing expressions — including multidimensional accesses — will be recomputed to the linear index. For example, if A were a 2×3 custom matrix with linear indexing, and we referenced A[1, 3], this would be recomputed to the equivalent linear index and call A[5] since 1 + 2*(3 - 1) = 5.

See also IndexCartesian.

source
Base.IndexCartesianType
IndexCartesian()

Subtype of IndexStyle used to describe arrays which are optimally indexed by a Cartesian index. This is the default for new custom AbstractArray subtypes.

A Cartesian indexing style uses multiple integer indices to describe the position in a multidimensional array, with exactly one index per dimension. This means that requesting eachindex from an array that is IndexCartesian will return a range of CartesianIndices.

A N-dimensional custom array that reports its IndexStyle as IndexCartesian needs to implement indexing (and indexed assignment) with exactly N Int indices; all other indexing expressions — including linear indexing — will be recomputed to the equivalent Cartesian location. For example, if A were a 2×3 custom matrix with cartesian indexing, and we referenced A[5], this would be recomputed to the equivalent Cartesian index and call A[1, 3] since 5 = 1 + 2*(3 - 1).

It is significantly more expensive to compute Cartesian indices from a linear index than it is to go the other way. The former operation requires division — a very costly operation — whereas the latter only uses multiplication and addition and is essentially free. This asymmetry means it is far more costly to use linear indexing with an IndexCartesian array than it is to use Cartesian indexing with an IndexLinear array.

See also IndexLinear.

source
Base.conj!Function
conj!(A)

Transform an array to its complex conjugate in-place.

See also conj.

Examples

julia> A = [1+im 2-im; 2+2im 3+im]
+CartesianIndex(2, 1)
source
Base.IndexStyleType
IndexStyle(A)
+IndexStyle(typeof(A))

IndexStyle specifies the "native indexing style" for array A. When you define a new AbstractArray type, you can choose to implement either linear indexing (with IndexLinear) or cartesian indexing. If you decide to only implement linear indexing, then you must set this trait for your array type:

Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()

The default is IndexCartesian().

Julia's internal indexing machinery will automatically (and invisibly) recompute all indexing operations into the preferred style. This allows users to access elements of your array using any indexing style, even when explicit methods have not been provided.

If you define both styles of indexing for your AbstractArray, this trait can be used to select the most performant indexing style. Some methods check this trait on their inputs, and dispatch to different algorithms depending on the most efficient access pattern. In particular, eachindex creates an iterator whose type depends on the setting of this trait.

source
Base.IndexLinearType
IndexLinear()

Subtype of IndexStyle used to describe arrays which are optimally indexed by one linear index.

A linear indexing style uses one integer index to describe the position in the array (even if it's a multidimensional array) and column-major ordering is used to efficiently access the elements. This means that requesting eachindex from an array that is IndexLinear will return a simple one-dimensional range, even if it is multidimensional.

A custom array that reports its IndexStyle as IndexLinear only needs to implement indexing (and indexed assignment) with a single Int index; all other indexing expressions — including multidimensional accesses — will be recomputed to the linear index. For example, if A were a 2×3 custom matrix with linear indexing, and we referenced A[1, 3], this would be recomputed to the equivalent linear index and call A[5] since 1 + 2*(3 - 1) = 5.

See also IndexCartesian.

source
Base.IndexCartesianType
IndexCartesian()

Subtype of IndexStyle used to describe arrays which are optimally indexed by a Cartesian index. This is the default for new custom AbstractArray subtypes.

A Cartesian indexing style uses multiple integer indices to describe the position in a multidimensional array, with exactly one index per dimension. This means that requesting eachindex from an array that is IndexCartesian will return a range of CartesianIndices.

A N-dimensional custom array that reports its IndexStyle as IndexCartesian needs to implement indexing (and indexed assignment) with exactly N Int indices; all other indexing expressions — including linear indexing — will be recomputed to the equivalent Cartesian location. For example, if A were a 2×3 custom matrix with cartesian indexing, and we referenced A[5], this would be recomputed to the equivalent Cartesian index and call A[1, 3] since 5 = 1 + 2*(3 - 1).

It is significantly more expensive to compute Cartesian indices from a linear index than it is to go the other way. The former operation requires division — a very costly operation — whereas the latter only uses multiplication and addition and is essentially free. This asymmetry means it is far more costly to use linear indexing with an IndexCartesian array than it is to use Cartesian indexing with an IndexLinear array.

See also IndexLinear.

source
Base.conj!Function
conj!(A)

Transform an array to its complex conjugate in-place.

See also conj.

Examples

julia> A = [1+im 2-im; 2+2im 3+im]
 2×2 Matrix{Complex{Int64}}:
  1+1im  2-1im
  2+2im  3+1im
@@ -283,16 +283,16 @@
 julia> A
 2×2 Matrix{Complex{Int64}}:
  1-1im  2+1im
- 2-2im  3-1im
source
Base.strideFunction
stride(A, k::Integer)

Return the distance in memory (in number of elements) between adjacent elements in dimension k.

See also: strides.

Examples

julia> A = fill(1, (3,4,5));
+ 2-2im  3-1im
source
Base.strideFunction
stride(A, k::Integer)

Return the distance in memory (in number of elements) between adjacent elements in dimension k.

See also: strides.

Examples

julia> A = fill(1, (3,4,5));
 
 julia> stride(A,2)
 3
 
 julia> stride(A,3)
-12
source
Base.stridesFunction
strides(A)

Return a tuple of the memory strides in each dimension.

See also: stride.

Examples

julia> A = fill(1, (3,4,5));
+12
source
Base.stridesFunction
strides(A)

Return a tuple of the memory strides in each dimension.

See also: stride.

Examples

julia> A = fill(1, (3,4,5));
 
 julia> strides(A)
-(1, 3, 12)
source

Broadcast and vectorization

See also the dot syntax for vectorizing functions; for example, f.(args...) implicitly calls broadcast(f, args...). Rather than relying on "vectorized" methods of functions like sin to operate on arrays, you should use sin.(a) to vectorize via broadcast.

Base.Broadcast.broadcastFunction
broadcast(f, As...)

Broadcast the function f over the arrays, tuples, collections, Refs and/or scalars As.

Broadcasting applies the function f over the elements of the container arguments and the scalars themselves in As. Singleton and missing dimensions are expanded to match the extents of the other arguments by virtually repeating the value. By default, only a limited number of types are considered scalars, including Numbers, Strings, Symbols, Types, Functions and some common singletons like missing and nothing. All other arguments are iterated over or indexed into elementwise.

The resulting container type is established by the following rules:

  • If all the arguments are scalars or zero-dimensional arrays, it returns an unwrapped scalar.
  • If at least one argument is a tuple and all others are scalars or zero-dimensional arrays, it returns a tuple.
  • All other combinations of arguments default to returning an Array, but custom container types can define their own implementation and promotion-like rules to customize the result when they appear as arguments.

A special syntax exists for broadcasting: f.(args...) is equivalent to broadcast(f, args...), and nested f.(g.(args...)) calls are fused into a single broadcast loop.

Examples

julia> A = [1, 2, 3, 4, 5]
+(1, 3, 12)
source

Broadcast and vectorization

See also the dot syntax for vectorizing functions; for example, f.(args...) implicitly calls broadcast(f, args...). Rather than relying on "vectorized" methods of functions like sin to operate on arrays, you should use sin.(a) to vectorize via broadcast.

Base.Broadcast.broadcastFunction
broadcast(f, As...)

Broadcast the function f over the arrays, tuples, collections, Refs and/or scalars As.

Broadcasting applies the function f over the elements of the container arguments and the scalars themselves in As. Singleton and missing dimensions are expanded to match the extents of the other arguments by virtually repeating the value. By default, only a limited number of types are considered scalars, including Numbers, Strings, Symbols, Types, Functions and some common singletons like missing and nothing. All other arguments are iterated over or indexed into elementwise.

The resulting container type is established by the following rules:

  • If all the arguments are scalars or zero-dimensional arrays, it returns an unwrapped scalar.
  • If at least one argument is a tuple and all others are scalars or zero-dimensional arrays, it returns a tuple.
  • All other combinations of arguments default to returning an Array, but custom container types can define their own implementation and promotion-like rules to customize the result when they appear as arguments.

A special syntax exists for broadcasting: f.(args...) is equivalent to broadcast(f, args...), and nested f.(g.(args...)) calls are fused into a single broadcast loop.

Examples

julia> A = [1, 2, 3, 4, 5]
 5-element Vector{Int64}:
  1
  2
@@ -338,7 +338,7 @@
  "two: 2"
  "three: 3"
  "four: 4"
-
source
Base.Broadcast.broadcast!Function
broadcast!(f, dest, As...)

Like broadcast, but store the result of broadcast(f, As...) in the dest array. Note that dest is only used to store the result, and does not supply arguments to f unless it is also listed in the As, as in broadcast!(f, A, A, B) to perform A[:] = broadcast(f, A, B).

Examples

julia> A = [1.0; 0.0]; B = [0.0; 0.0];
+
source
Base.Broadcast.broadcast!Function
broadcast!(f, dest, As...)

Like broadcast, but store the result of broadcast(f, As...) in the dest array. Note that dest is only used to store the result, and does not supply arguments to f unless it is also listed in the As, as in broadcast!(f, A, A, B) to perform A[:] = broadcast(f, A, B).

Examples

julia> A = [1.0; 0.0]; B = [0.0; 0.0];
 
 julia> broadcast!(+, B, A, (0, -2.0));
 
@@ -357,17 +357,17 @@
 julia> A
 2-element Vector{Float64}:
   1.0
- -2.0
source
Base.Broadcast.@__dot__Macro
@. expr

Convert every function call or operator in expr into a "dot call" (e.g. convert f(x) to f.(x)), and convert every assignment in expr to a "dot assignment" (e.g. convert += to .+=).

If you want to avoid adding dots for selected function calls in expr, splice those function calls in with $. For example, @. sqrt(abs($sort(x))) is equivalent to sqrt.(abs.(sort(x))) (no dot for sort).

(@. is equivalent to a call to @__dot__.)

Examples

julia> x = 1.0:3.0; y = similar(x);
+ -2.0
source
Base.Broadcast.@__dot__Macro
@. expr

Convert every function call or operator in expr into a "dot call" (e.g. convert f(x) to f.(x)), and convert every assignment in expr to a "dot assignment" (e.g. convert += to .+=).

If you want to avoid adding dots for selected function calls in expr, splice those function calls in with $. For example, @. sqrt(abs($sort(x))) is equivalent to sqrt.(abs.(sort(x))) (no dot for sort).

(@. is equivalent to a call to @__dot__.)

Examples

julia> x = 1.0:3.0; y = similar(x);
 
 julia> @. y = x + 3 * sin(x)
 3-element Vector{Float64}:
  3.5244129544236893
  4.727892280477045
- 3.4233600241796016
source

For specializing broadcast on custom types, see

Base.Broadcast.BroadcastStyleType

BroadcastStyle is an abstract type and trait-function used to determine behavior of objects under broadcasting. BroadcastStyle(typeof(x)) returns the style associated with x. To customize the broadcasting behavior of a type, one can declare a style by defining a type/method pair

struct MyContainerStyle <: BroadcastStyle end
-Base.BroadcastStyle(::Type{<:MyContainer}) = MyContainerStyle()

One then writes method(s) (at least similar) operating on Broadcasted{MyContainerStyle}. There are also several pre-defined subtypes of BroadcastStyle that you may be able to leverage; see the Interfaces chapter for more information.

source
Base.Broadcast.AbstractArrayStyleType

Broadcast.AbstractArrayStyle{N} <: BroadcastStyle is the abstract supertype for any style associated with an AbstractArray type. The N parameter is the dimensionality, which can be handy for AbstractArray types that only support specific dimensionalities:

struct SparseMatrixStyle <: Broadcast.AbstractArrayStyle{2} end
+ 3.4233600241796016
source

For specializing broadcast on custom types, see

Base.Broadcast.BroadcastStyleType

BroadcastStyle is an abstract type and trait-function used to determine behavior of objects under broadcasting. BroadcastStyle(typeof(x)) returns the style associated with x. To customize the broadcasting behavior of a type, one can declare a style by defining a type/method pair

struct MyContainerStyle <: BroadcastStyle end
+Base.BroadcastStyle(::Type{<:MyContainer}) = MyContainerStyle()

One then writes method(s) (at least similar) operating on Broadcasted{MyContainerStyle}. There are also several pre-defined subtypes of BroadcastStyle that you may be able to leverage; see the Interfaces chapter for more information.

source
Base.Broadcast.AbstractArrayStyleType

Broadcast.AbstractArrayStyle{N} <: BroadcastStyle is the abstract supertype for any style associated with an AbstractArray type. The N parameter is the dimensionality, which can be handy for AbstractArray types that only support specific dimensionalities:

struct SparseMatrixStyle <: Broadcast.AbstractArrayStyle{2} end
 Base.BroadcastStyle(::Type{<:SparseMatrixCSC}) = SparseMatrixStyle()

For AbstractArray types that support arbitrary dimensionality, N can be set to Any:

struct MyArrayStyle <: Broadcast.AbstractArrayStyle{Any} end
 Base.BroadcastStyle(::Type{<:MyArray}) = MyArrayStyle()

In cases where you want to be able to mix multiple AbstractArrayStyles and keep track of dimensionality, your style needs to support a Val constructor:

struct MyArrayStyleDim{N} <: Broadcast.AbstractArrayStyle{N} end
-(::Type{<:MyArrayStyleDim})(::Val{N}) where N = MyArrayStyleDim{N}()

Note that if two or more AbstractArrayStyle subtypes conflict, broadcasting machinery will fall back to producing Arrays. If this is undesirable, you may need to define binary BroadcastStyle rules to control the output type.

See also Broadcast.DefaultArrayStyle.

source
Base.Broadcast.DefaultArrayStyleType

Broadcast.DefaultArrayStyle{N}() is a BroadcastStyle indicating that an object behaves as an N-dimensional array for broadcasting. Specifically, DefaultArrayStyle is used for any AbstractArray type that hasn't defined a specialized style, and in the absence of overrides from other broadcast arguments the resulting output type is Array. When there are multiple inputs to broadcast, DefaultArrayStyle "loses" to any other Broadcast.ArrayStyle.

source
Base.Broadcast.broadcastableFunction
Broadcast.broadcastable(x)

Return either x or an object like x such that it supports axes, indexing, and its type supports ndims.

If x supports iteration, the returned value should have the same axes and indexing behaviors as collect(x).

If x is not an AbstractArray but it supports axes, indexing, and its type supports ndims, then broadcastable(::typeof(x)) may be implemented to just return itself. Further, if x defines its own BroadcastStyle, then it must define its broadcastable method to return itself for the custom style to have any effect.

Examples

julia> Broadcast.broadcastable([1,2,3]) # like `identity` since arrays already support axes and indexing
+(::Type{<:MyArrayStyleDim})(::Val{N}) where N = MyArrayStyleDim{N}()

Note that if two or more AbstractArrayStyle subtypes conflict, broadcasting machinery will fall back to producing Arrays. If this is undesirable, you may need to define binary BroadcastStyle rules to control the output type.

See also Broadcast.DefaultArrayStyle.

source
Base.Broadcast.DefaultArrayStyleType

Broadcast.DefaultArrayStyle{N}() is a BroadcastStyle indicating that an object behaves as an N-dimensional array for broadcasting. Specifically, DefaultArrayStyle is used for any AbstractArray type that hasn't defined a specialized style, and in the absence of overrides from other broadcast arguments the resulting output type is Array. When there are multiple inputs to broadcast, DefaultArrayStyle "loses" to any other Broadcast.ArrayStyle.

source
Base.Broadcast.broadcastableFunction
Broadcast.broadcastable(x)

Return either x or an object like x such that it supports axes, indexing, and its type supports ndims.

If x supports iteration, the returned value should have the same axes and indexing behaviors as collect(x).

If x is not an AbstractArray but it supports axes, indexing, and its type supports ndims, then broadcastable(::typeof(x)) may be implemented to just return itself. Further, if x defines its own BroadcastStyle, then it must define its broadcastable method to return itself for the custom style to have any effect.

Examples

julia> Broadcast.broadcastable([1,2,3]) # like `identity` since arrays already support axes and indexing
 3-element Vector{Int64}:
  1
  2
@@ -377,16 +377,16 @@
 Base.RefValue{Type{Int64}}(Int64)
 
 julia> Broadcast.broadcastable("hello") # Strings break convention of matching iteration and act like a scalar instead
-Base.RefValue{String}("hello")
source
Base.Broadcast.combine_axesFunction
combine_axes(As...) -> Tuple

Determine the result axes for broadcasting across all values in As.

julia> Broadcast.combine_axes([1], [1 2; 3 4; 5 6])
+Base.RefValue{String}("hello")
source
Base.Broadcast.combine_axesFunction
combine_axes(As...) -> Tuple

Determine the result axes for broadcasting across all values in As.

julia> Broadcast.combine_axes([1], [1 2; 3 4; 5 6])
 (Base.OneTo(3), Base.OneTo(2))
 
 julia> Broadcast.combine_axes(1, 1, 1)
-()
source
Base.Broadcast.combine_stylesFunction
combine_styles(cs...) -> BroadcastStyle

Decides which BroadcastStyle to use for any number of value arguments. Uses BroadcastStyle to get the style for each argument, and uses result_style to combine styles.

Examples

julia> Broadcast.combine_styles([1], [1 2; 3 4])
-Base.Broadcast.DefaultArrayStyle{2}()
source
Base.Broadcast.result_styleFunction
result_style(s1::BroadcastStyle[, s2::BroadcastStyle]) -> BroadcastStyle

Takes one or two BroadcastStyles and combines them using BroadcastStyle to determine a common BroadcastStyle.

Examples

julia> Broadcast.result_style(Broadcast.DefaultArrayStyle{0}(), Broadcast.DefaultArrayStyle{3}())
+()
source
Base.Broadcast.combine_stylesFunction
combine_styles(cs...) -> BroadcastStyle

Decides which BroadcastStyle to use for any number of value arguments. Uses BroadcastStyle to get the style for each argument, and uses result_style to combine styles.

Examples

julia> Broadcast.combine_styles([1], [1 2; 3 4])
+Base.Broadcast.DefaultArrayStyle{2}()
source
Base.Broadcast.result_styleFunction
result_style(s1::BroadcastStyle[, s2::BroadcastStyle]) -> BroadcastStyle

Takes one or two BroadcastStyles and combines them using BroadcastStyle to determine a common BroadcastStyle.

Examples

julia> Broadcast.result_style(Broadcast.DefaultArrayStyle{0}(), Broadcast.DefaultArrayStyle{3}())
 Base.Broadcast.DefaultArrayStyle{3}()
 
 julia> Broadcast.result_style(Broadcast.Unknown(), Broadcast.DefaultArrayStyle{1}())
-Base.Broadcast.DefaultArrayStyle{1}()
source

Indexing and assignment

Base.getindexMethod
getindex(A, inds...)

Return a subset of array A as selected by the indices inds.

Each index may be any supported index type, such as an Integer, CartesianIndex, range, or array of supported indices. A : may be used to select all elements along a specific dimension, and a boolean array (e.g. an Array{Bool} or a BitArray) may be used to filter for elements where the corresponding index is true.

When inds selects multiple elements, this function returns a newly allocated array. To index multiple elements without making a copy, use view instead.

See the manual section on array indexing for details.

Examples

julia> A = [1 2; 3 4]
+Base.Broadcast.DefaultArrayStyle{1}()
source

Indexing and assignment

Base.getindexMethod
getindex(A, inds...)

Return a subset of array A as selected by the indices inds.

Each index may be any supported index type, such as an Integer, CartesianIndex, range, or array of supported indices. A : may be used to select all elements along a specific dimension, and a boolean array (e.g. an Array{Bool} or a BitArray) may be used to filter for elements where the corresponding index is true.

When inds selects multiple elements, this function returns a newly allocated array. To index multiple elements without making a copy, use view instead.

See the manual section on array indexing for details.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -424,7 +424,7 @@
 julia> getindex(A, A .> 2)
 2-element Vector{Int64}:
  3
- 4
source
Base.setindex!Method
setindex!(A, X, inds...)
 A[inds...] = X

Store values from array X within some subset of A as specified by inds. The syntax A[inds...] = X is equivalent to (setindex!(A, X, inds...); X).

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = zeros(2,2);
 
 julia> setindex!(A, [10, 20], [1, 2]);
@@ -434,7 +434,7 @@
 julia> A
 2×2 Matrix{Float64}:
  10.0  30.0
- 20.0  40.0
source
Base.nextindFunction
nextind(A, i)

Return the index after i in A. The returned index is often equivalent to `i

  • 1for an integeri`. This function can be useful for generic code.
Warning

The returned index might be out of bounds. Consider using checkbounds.

See also: prevind.

Examples

julia> x = [1 2; 3 4]
+ 20.0  40.0
source
Base.nextindFunction
nextind(A, i)

Return the index after i in A. The returned index is often equivalent to `i

  • 1for an integeri`. This function can be useful for generic code.
Warning

The returned index might be out of bounds. Consider using checkbounds.

See also: prevind.

Examples

julia> x = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -449,7 +449,7 @@
 CartesianIndex(2, 1)
 
 julia> nextind(x, CartesianIndex(2, 2)) # invalid result
-CartesianIndex(1, 3)
source
Base.previndFunction
prevind(A, i)

Return the index before i in A. The returned index is often equivalent to `i

  • 1for an integeri`. This function can be useful for generic code.
Warning

The returned index might be out of bounds. Consider using checkbounds.

See also: nextind.

Examples

julia> x = [1 2; 3 4]
+CartesianIndex(1, 3)
source
Base.previndFunction
prevind(A, i)

Return the index before i in A. The returned index is often equivalent to `i

  • 1for an integeri`. This function can be useful for generic code.
Warning

The returned index might be out of bounds. Consider using checkbounds.

See also: nextind.

Examples

julia> x = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -464,7 +464,7 @@
 CartesianIndex(1, 2)
 
 julia> prevind(x, CartesianIndex(1, 1)) # invalid result
-CartesianIndex(2, 0)
source
Base.copyto!Method
copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest

Copy the block of src in the range of Rsrc to the block of dest in the range of Rdest. The sizes of the two regions must match.

Examples

julia> A = zeros(5, 5);
+CartesianIndex(2, 0)
source
Base.copyto!Method
copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest

Copy the block of src in the range of Rsrc to the block of dest in the range of Rdest. The sizes of the two regions must match.

Examples

julia> A = zeros(5, 5);
 
 julia> B = [1 2; 3 4];
 
@@ -478,7 +478,7 @@
  0.0  1.0  2.0  0.0  0.0
  0.0  3.0  4.0  0.0  0.0
  0.0  0.0  0.0  0.0  0.0
- 0.0  0.0  0.0  0.0  0.0
source
Base.copy!Function
copy!(dst, src) -> dst

In-place copy of src into dst, discarding any pre-existing elements in dst. If dst and src are of the same type, dst == src should hold after the call. If dst and src are multidimensional arrays, they must have equal axes.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also copyto!.

Julia 1.1

This method requires at least Julia 1.1. In Julia 1.0 this method is available from the Future standard library as Future.copy!.

source
Base.isassignedFunction
isassigned(array, i) -> Bool

Test whether the given array has a value associated with index i. Return false if the index is out of bounds, or has an undefined reference.

Examples

julia> isassigned(rand(3, 3), 5)
+ 0.0  0.0  0.0  0.0  0.0
source
Base.copy!Function
copy!(dst, src) -> dst

In-place copy of src into dst, discarding any pre-existing elements in dst. If dst and src are of the same type, dst == src should hold after the call. If dst and src are multidimensional arrays, they must have equal axes.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also copyto!.

Julia 1.1

This method requires at least Julia 1.1. In Julia 1.0 this method is available from the Future standard library as Future.copy!.

source
Base.isassignedFunction
isassigned(array, i) -> Bool

Test whether the given array has a value associated with index i. Return false if the index is out of bounds, or has an undefined reference.

Examples

julia> isassigned(rand(3, 3), 5)
 true
 
 julia> isassigned(rand(3, 3), 3 * 3 + 1)
@@ -493,7 +493,7 @@
  #undef
 
 julia> isassigned(v, 1)
-false
source
Base.ColonType
Colon()

Colons (:) are used to signify indexing entire objects or dimensions at once.

Very few operations are defined on Colons directly; instead they are converted by to_indices to an internal vector type (Base.Slice) to represent the collection of indices they span before being used.

The singleton instance of Colon is also a function used to construct ranges; see :.

source
Base.ColonType
Colon()

Colons (:) are used to signify indexing entire objects or dimensions at once.

Very few operations are defined on Colons directly; instead they are converted by to_indices to an internal vector type (Base.Slice) to represent the collection of indices they span before being used.

The singleton instance of Colon is also a function used to construct ranges; see :.

source
Base.IteratorsMD.CartesianIndexType
CartesianIndex(i, j, k...)   -> I
 CartesianIndex((i, j, k...)) -> I

Create a multidimensional index I, which can be used for indexing a multidimensional array A. In particular, A[I] is equivalent to A[i,j,k...]. One can freely mix integer and CartesianIndex indices; for example, A[Ipre, i, Ipost] (where Ipre and Ipost are CartesianIndex indices and i is an Int) can be a useful expression when writing algorithms that work along a single dimension of an array of arbitrary dimensionality.

A CartesianIndex is sometimes produced by eachindex, and always when iterating with an explicit CartesianIndices.

An I::CartesianIndex is treated as a "scalar" (not a container) for broadcast. In order to iterate over the components of a CartesianIndex, convert it to a tuple with Tuple(I).

Examples

julia> A = reshape(Vector(1:16), (2, 2, 2, 2))
 2×2×2×2 Array{Int64, 4}:
 [:, :, 1, 1] =
@@ -519,7 +519,7 @@
 9
 
 julia> A[CartesianIndex((1, 1, 2, 1))]
-5
Julia 1.10

Using a CartesianIndex as a "scalar" for broadcast requires Julia 1.10; in previous releases, use Ref(I).

source
Base.IteratorsMD.CartesianIndicesType
CartesianIndices(sz::Dims) -> R
+5
Julia 1.10

Using a CartesianIndex as a "scalar" for broadcast requires Julia 1.10; in previous releases, use Ref(I).

source
Base.IteratorsMD.CartesianIndicesType
CartesianIndices(sz::Dims) -> R
 CartesianIndices((istart:[istep:]istop, jstart:[jstep:]jstop, ...)) -> R

Define a region R spanning a multidimensional rectangular range of integer indices. These are most commonly encountered in the context of iteration, where for I in R ... end will return CartesianIndex indices I equivalent to the nested loops

for j = jstart:jstep:jstop
     for i = istart:istep:istop
         ...
@@ -552,7 +552,7 @@
 CartesianIndex(3, 4)
 
 julia> CIs .+ CI
-CartesianIndices((5:6, 9:10))

For cartesian to linear index conversion, see LinearIndices.

source
Base.LinearIndicesType
LinearIndices(A::AbstractArray)

Return a LinearIndices array with the same shape and axes as A, holding the linear index of each entry in A. Indexing this array with cartesian indices allows mapping them to linear indices.

For arrays with conventional indexing (indices start at 1), or any multidimensional array, linear indices range from 1 to length(A). However, for AbstractVectors linear indices are axes(A, 1), and therefore do not start at 1 for vectors with unconventional indexing.

Calling this function is the "safe" way to write algorithms that exploit linear indexing.

Examples

julia> A = fill(1, (5,6,7));
+CartesianIndices((5:6, 9:10))

For cartesian to linear index conversion, see LinearIndices.

source
Base.LinearIndicesType
LinearIndices(A::AbstractArray)

Return a LinearIndices array with the same shape and axes as A, holding the linear index of each entry in A. Indexing this array with cartesian indices allows mapping them to linear indices.

For arrays with conventional indexing (indices start at 1), or any multidimensional array, linear indices range from 1 to length(A). However, for AbstractVectors linear indices are axes(A, 1), and therefore do not start at 1 for vectors with unconventional indexing.

Calling this function is the "safe" way to write algorithms that exploit linear indexing.

Examples

julia> A = fill(1, (5,6,7));
 
 julia> b = LinearIndices(A);
 
@@ -566,7 +566,7 @@
  3  6
 
 julia> linear[1,2]
-4
source
Base.to_indicesFunction
to_indices(A, I::Tuple)

Convert the tuple I to a tuple of indices for use in indexing into array A.

The returned tuple must only contain either Ints or AbstractArrays of scalar indices that are supported by array A. It will error upon encountering a novel index type that it does not know how to process.

For simple index types, it defers to the unexported Base.to_index(A, i) to process each index i. While this internal function is not intended to be called directly, Base.to_index may be extended by custom array or index types to provide custom indexing behaviors.

More complicated index types may require more context about the dimension into which they index. To support those cases, to_indices(A, I) calls to_indices(A, axes(A), I), which then recursively walks through both the given tuple of indices and the dimensional indices of A in tandem. As such, not all index types are guaranteed to propagate to Base.to_index.

Examples

julia> A = zeros(1,2,3,4);
+4
source
Base.to_indicesFunction
to_indices(A, I::Tuple)

Convert the tuple I to a tuple of indices for use in indexing into array A.

The returned tuple must only contain either Ints or AbstractArrays of scalar indices that are supported by array A. It will error upon encountering a novel index type that it does not know how to process.

For simple index types, it defers to the unexported Base.to_index(A, i) to process each index i. While this internal function is not intended to be called directly, Base.to_index may be extended by custom array or index types to provide custom indexing behaviors.

More complicated index types may require more context about the dimension into which they index. To support those cases, to_indices(A, I) calls to_indices(A, axes(A), I), which then recursively walks through both the given tuple of indices and the dimensional indices of A in tandem. As such, not all index types are guaranteed to propagate to Base.to_index.

Examples

julia> A = zeros(1,2,3,4);
 
 julia> to_indices(A, (1,1,2,2))
 (1, 1, 2, 2)
@@ -581,7 +581,7 @@
 ([1, 1], 1:2, 3, 4)
 
 julia> to_indices(A, (1,2)) # no shape checking
-(1, 2)
source
Base.checkboundsFunction
checkbounds(Bool, A, I...)

Return true if the specified indices I are in bounds for the given array A. Subtypes of AbstractArray should specialize this method if they need to provide custom bounds checking behaviors; however, in many cases one can rely on A's indices and checkindex.

See also checkindex.

Examples

julia> A = rand(3, 3);
+(1, 2)
source
Base.checkboundsFunction
checkbounds(Bool, A, I...)

Return true if the specified indices I are in bounds for the given array A. Subtypes of AbstractArray should specialize this method if they need to provide custom bounds checking behaviors; however, in many cases one can rely on A's indices and checkindex.

See also checkindex.

Examples

julia> A = rand(3, 3);
 
 julia> checkbounds(Bool, A, 2)
 true
@@ -593,12 +593,12 @@
 true
 
 julia> checkbounds(Bool, A, 1:3, 2:4)
-false
source
checkbounds(A, I...)

Throw an error if the specified indices I are not in bounds for the given array A.

source
Base.checkindexFunction
checkindex(Bool, inds::AbstractUnitRange, index)

Return true if the given index is within the bounds of inds. Custom types that would like to behave as indices for all arrays can extend this method in order to provide a specialized bounds checking implementation.

See also checkbounds.

Examples

julia> checkindex(Bool, 1:20, 8)
+false
source
checkbounds(A, I...)

Throw an error if the specified indices I are not in bounds for the given array A.

source
Base.checkindexFunction
checkindex(Bool, inds::AbstractUnitRange, index)

Return true if the given index is within the bounds of inds. Custom types that would like to behave as indices for all arrays can extend this method in order to provide a specialized bounds checking implementation.

See also checkbounds.

Examples

julia> checkindex(Bool, 1:20, 8)
 true
 
 julia> checkindex(Bool, 1:20, 21)
-false
source
Base.elsizeFunction
elsize(type)

Compute the memory stride in bytes between consecutive elements of eltype stored inside the given type, if the array elements are stored densely with a uniform linear stride.

Examples

julia> Base.elsize(rand(Float32, 10))
-4
source

Views (SubArrays and other view types)

A “view” is a data structure that acts like an array (it is a subtype of AbstractArray), but the underlying data is actually part of another array.

For example, if x is an array and v = @view x[1:10], then v acts like a 10-element array, but its data is actually accessing the first 10 elements of x. Writing to a view, e.g. v[3] = 2, writes directly to the underlying array x (in this case modifying x[3]).

Slicing operations like x[1:10] create a copy by default in Julia. @view x[1:10] changes it to make a view. The @views macro can be used on a whole block of code (e.g. @views function foo() .... end or @views begin ... end) to change all the slicing operations in that block to use views. Sometimes making a copy of the data is faster and sometimes using a view is faster, as described in the performance tips.

Base.viewFunction
view(A, inds...)

Like getindex, but returns a lightweight array that lazily references (or is effectively a view into) the parent array A at the given index or indices inds instead of eagerly extracting elements or constructing a copied subset. Calling getindex or setindex! on the returned value (often a SubArray) computes the indices to access or modify the parent array on the fly. The behavior is undefined if the shape of the parent array is changed after view is called because there is no bound check for the parent array; e.g., it may cause a segmentation fault.

Some immutable parent arrays (like ranges) may choose to simply recompute a new array in some circumstances instead of returning a SubArray if doing so is efficient and provides compatible semantics.

Julia 1.6

In Julia 1.6 or later, view can be called on an AbstractString, returning a SubString.

Examples

julia> A = [1 2; 3 4]
+false
source
Base.elsizeFunction
elsize(type)

Compute the memory stride in bytes between consecutive elements of eltype stored inside the given type, if the array elements are stored densely with a uniform linear stride.

Examples

julia> Base.elsize(rand(Float32, 10))
+4
source

Views (SubArrays and other view types)

A “view” is a data structure that acts like an array (it is a subtype of AbstractArray), but the underlying data is actually part of another array.

For example, if x is an array and v = @view x[1:10], then v acts like a 10-element array, but its data is actually accessing the first 10 elements of x. Writing to a view, e.g. v[3] = 2, writes directly to the underlying array x (in this case modifying x[3]).

Slicing operations like x[1:10] create a copy by default in Julia. @view x[1:10] changes it to make a view. The @views macro can be used on a whole block of code (e.g. @views function foo() .... end or @views begin ... end) to change all the slicing operations in that block to use views. Sometimes making a copy of the data is faster and sometimes using a view is faster, as described in the performance tips.

Base.viewFunction
view(A, inds...)

Like getindex, but returns a lightweight array that lazily references (or is effectively a view into) the parent array A at the given index or indices inds instead of eagerly extracting elements or constructing a copied subset. Calling getindex or setindex! on the returned value (often a SubArray) computes the indices to access or modify the parent array on the fly. The behavior is undefined if the shape of the parent array is changed after view is called because there is no bound check for the parent array; e.g., it may cause a segmentation fault.

Some immutable parent arrays (like ranges) may choose to simply recompute a new array in some circumstances instead of returning a SubArray if doing so is efficient and provides compatible semantics.

Julia 1.6

In Julia 1.6 or later, view can be called on an AbstractString, returning a SubString.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -619,7 +619,7 @@
  0  4
 
 julia> view(2:5, 2:3) # returns a range as type is immutable
-3:4
source
Base.@viewMacro
@view A[inds...]

Transform the indexing expression A[inds...] into the equivalent view call.

This can only be applied directly to a single indexing expression and is particularly helpful for expressions that include the special begin or end indexing syntaxes like A[begin, 2:end-1] (as those are not supported by the normal view function).

Note that @view cannot be used as the target of a regular assignment (e.g., @view(A[1, 2:end]) = ...), nor would the un-decorated indexed assignment (A[1, 2:end] = ...) or broadcasted indexed assignment (A[1, 2:end] .= ...) make a copy. It can be useful, however, for updating broadcasted assignments like @view(A[1, 2:end]) .+= 1 because this is a simple syntax for @view(A[1, 2:end]) .= @view(A[1, 2:end]) + 1, and the indexing expression on the right-hand side would otherwise make a copy without the @view.

See also @views to switch an entire block of code to use views for non-scalar indexing.

Julia 1.5

Using begin in an indexing expression to refer to the first index requires at least Julia 1.5.

Examples

julia> A = [1 2; 3 4]
+3:4
source
Base.@viewMacro
@view A[inds...]

Transform the indexing expression A[inds...] into the equivalent view call.

This can only be applied directly to a single indexing expression and is particularly helpful for expressions that include the special begin or end indexing syntaxes like A[begin, 2:end-1] (as those are not supported by the normal view function).

Note that @view cannot be used as the target of a regular assignment (e.g., @view(A[1, 2:end]) = ...), nor would the un-decorated indexed assignment (A[1, 2:end] = ...) or broadcasted indexed assignment (A[1, 2:end] .= ...) make a copy. It can be useful, however, for updating broadcasted assignments like @view(A[1, 2:end]) .+= 1 because this is a simple syntax for @view(A[1, 2:end]) .= @view(A[1, 2:end]) + 1, and the indexing expression on the right-hand side would otherwise make a copy without the @view.

See also @views to switch an entire block of code to use views for non-scalar indexing.

Julia 1.5

Using begin in an indexing expression to refer to the first index requires at least Julia 1.5.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -637,7 +637,7 @@
 julia> A
 2×2 Matrix{Int64}:
  0  2
- 0  4
source
Base.@viewsMacro
@views expression

Convert every array-slicing operation in the given expression (which may be a begin/end block, loop, function, etc.) to return a view. Scalar indices, non-array types, and explicit getindex calls (as opposed to array[...]) are unaffected.

Similarly, @views converts string slices into SubString views.

Note

The @views macro only affects array[...] expressions that appear explicitly in the given expression, not array slicing that occurs in functions called by that code.

Julia 1.5

Using begin in an indexing expression to refer to the first index was implemented in Julia 1.4, but was only supported by @views starting in Julia 1.5.

Examples

julia> A = zeros(3, 3);
+ 0  4
source
Base.@viewsMacro
@views expression

Convert every array-slicing operation in the given expression (which may be a begin/end block, loop, function, etc.) to return a view. Scalar indices, non-array types, and explicit getindex calls (as opposed to array[...]) are unaffected.

Similarly, @views converts string slices into SubString views.

Note

The @views macro only affects array[...] expressions that appear explicitly in the given expression, not array slicing that occurs in functions called by that code.

Julia 1.5

Using begin in an indexing expression to refer to the first index was implemented in Julia 1.4, but was only supported by @views starting in Julia 1.5.

Examples

julia> A = zeros(3, 3);
 
 julia> @views for row in 1:3
            b = A[row, :] # b is a view, not a copy
@@ -648,7 +648,7 @@
 3×3 Matrix{Float64}:
  1.0  1.0  1.0
  2.0  2.0  2.0
- 3.0  3.0  3.0
source
Base.parentFunction
parent(A)

Return the underlying parent object of the view. This parent of objects of types SubArray, SubString, ReshapedArray or LinearAlgebra.Transpose is what was passed as an argument to view, reshape, transpose, etc. during object creation. If the input is not a wrapped object, return the input itself. If the input is wrapped multiple times, only the outermost wrapper will be removed.

Examples

julia> A = [1 2; 3 4]
+ 3.0  3.0  3.0
source
Base.parentFunction
parent(A)

Return the underlying parent object of the view. This parent of objects of types SubArray, SubString, ReshapedArray or LinearAlgebra.Transpose is what was passed as an argument to view, reshape, transpose, etc. during object creation. If the input is not a wrapped object, return the input itself. If the input is wrapped multiple times, only the outermost wrapper will be removed.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -661,7 +661,7 @@
 julia> parent(V)
 2×2 Matrix{Int64}:
  1  2
- 3  4
source
Base.parentindicesFunction
parentindices(A)

Return the indices in the parent which correspond to the view A.

Examples

julia> A = [1 2; 3 4];
+ 3  4
source
Base.parentindicesFunction
parentindices(A)

Return the indices in the parent which correspond to the view A.

Examples

julia> A = [1 2; 3 4];
 
 julia> V = view(A, 1, :)
 2-element view(::Matrix{Int64}, 1, :) with eltype Int64:
@@ -669,7 +669,7 @@
  2
 
 julia> parentindices(V)
-(1, Base.Slice(Base.OneTo(2)))
source
Base.selectdimFunction
selectdim(A, d::Integer, i)

Return a view of all the data of A where the index for dimension d equals i.

Equivalent to view(A,:,:,...,i,:,:,...) where i is in position d.

See also: eachslice.

Examples

julia> A = [1 2 3 4; 5 6 7 8]
+(1, Base.Slice(Base.OneTo(2)))
source
Base.selectdimFunction
selectdim(A, d::Integer, i)

Return a view of all the data of A where the index for dimension d equals i.

Equivalent to view(A,:,:,...,i,:,:,...) where i is in position d.

See also: eachslice.

Examples

julia> A = [1 2 3 4; 5 6 7 8]
 2×4 Matrix{Int64}:
  1  2  3  4
  5  6  7  8
@@ -682,7 +682,7 @@
 julia> selectdim(A, 2, 3:4)
 2×2 view(::Matrix{Int64}, :, 3:4) with eltype Int64:
  3  4
- 7  8
source
Base.reinterpretFunction
reinterpret(::Type{Out}, x::In)

Change the type-interpretation of the binary data in the isbits value x to that of the isbits type Out. The size (ignoring padding) of Out has to be the same as that of the type of x. For example, reinterpret(Float32, UInt32(7)) interprets the 4 bytes corresponding to UInt32(7) as a Float32. Note that reinterpret(In, reinterpret(Out, x)) === x

julia> reinterpret(Float32, UInt32(7))
+ 7  8
source
Base.reinterpretFunction
reinterpret(::Type{Out}, x::In)

Change the type-interpretation of the binary data in the isbits value x to that of the isbits type Out. The size (ignoring padding) of Out has to be the same as that of the type of x. For example, reinterpret(Float32, UInt32(7)) interprets the 4 bytes corresponding to UInt32(7) as a Float32. Note that reinterpret(In, reinterpret(Out, x)) === x

julia> reinterpret(Float32, UInt32(7))
 1.0f-44
 
 julia> reinterpret(NTuple{2, UInt8}, 0x1234)
@@ -692,7 +692,7 @@
 0x1234
 
 julia> reinterpret(Tuple{UInt16, UInt8}, (0x01, 0x0203))
-(0x0301, 0x02)
Note

The treatment of padding differs from reinterpret(::DataType, ::AbstractArray).

Warning

Use caution if some combinations of bits in Out are not considered valid and would otherwise be prevented by the type's constructors and methods. Unexpected behavior may result without additional validation.

source
reinterpret(T::DataType, A::AbstractArray)

Construct a view of the array with the same binary data as the given array, but with T as element type.

This function also works on "lazy" array whose elements are not computed until they are explicitly retrieved. For instance, reinterpret on the range 1:6 works similarly as on the dense vector collect(1:6):

julia> reinterpret(Float32, UInt32[1 2 3 4 5])
+(0x0301, 0x02)
Note

The treatment of padding differs from reinterpret(::DataType, ::AbstractArray).

Warning

Use caution if some combinations of bits in Out are not considered valid and would otherwise be prevented by the type's constructors and methods. Unexpected behavior may result without additional validation.

source
reinterpret(T::DataType, A::AbstractArray)

Construct a view of the array with the same binary data as the given array, but with T as element type.

This function also works on "lazy" array whose elements are not computed until they are explicitly retrieved. For instance, reinterpret on the range 1:6 works similarly as on the dense vector collect(1:6):

julia> reinterpret(Float32, UInt32[1 2 3 4 5])
 1×5 reinterpret(Float32, ::Matrix{UInt32}):
  1.0f-45  3.0f-45  4.0f-45  6.0f-45  7.0f-45
 
@@ -710,7 +710,7 @@
 julia> b = reinterpret(UInt32, Tuple{UInt8, UInt32}[(0x01, 0x00000002)]); # showing will error
 
 julia> b[1]
-ERROR: Padding of type UInt32 is not compatible with type Tuple{UInt8, UInt32}.
source
reinterpret(reshape, T, A::AbstractArray{S}) -> B

Change the type-interpretation of A while consuming or adding a "channel dimension."

If sizeof(T) = n*sizeof(S) for n>1, A's first dimension must be of size n and B lacks A's first dimension. Conversely, if sizeof(S) = n*sizeof(T) for n>1, B gets a new first dimension of size n. The dimensionality is unchanged if sizeof(T) == sizeof(S).

Julia 1.6

This method requires at least Julia 1.6.

Examples

julia> A = [1 2; 3 4]
+ERROR: Padding of type UInt32 is not compatible with type Tuple{UInt8, UInt32}.
source
reinterpret(reshape, T, A::AbstractArray{S}) -> B

Change the type-interpretation of A while consuming or adding a "channel dimension."

If sizeof(T) = n*sizeof(S) for n>1, A's first dimension must be of size n and B lacks A's first dimension. Conversely, if sizeof(S) = n*sizeof(T) for n>1, B gets a new first dimension of size n. The dimensionality is unchanged if sizeof(T) == sizeof(S).

Julia 1.6

This method requires at least Julia 1.6.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -729,7 +729,7 @@
 3×2 reinterpret(reshape, Int64, ::Vector{Tuple{Int64, Int64, Int64}}) with eltype Int64:
  1  4
  2  5
- 3  6
source
Base.reshapeFunction
reshape(A, dims...) -> AbstractArray
 reshape(A, dims) -> AbstractArray

Return an array with the same data as A, but with different dimension sizes or number of dimensions. The two arrays share the same underlying data, so that the result is mutable if and only if A is mutable, and setting elements of one alters the values of the other.

The new dimensions may be specified either as a list of arguments or as a shape tuple. At most one dimension may be specified with a :, in which case its length is computed such that its product with all the specified dimensions is equal to the length of the original array A. The total number of elements must not change.

Examples

julia> A = Vector(1:16)
 16-element Vector{Int64}:
   1
@@ -764,7 +764,7 @@
 julia> reshape(1:6, 2, 3)
 2×3 reshape(::UnitRange{Int64}, 2, 3) with eltype Int64:
  1  3  5
- 2  4  6
source
Base.dropdimsFunction
dropdims(A; dims)

Return an array with the same data as A, but with the dimensions specified by dims removed. size(A,d) must equal 1 for every d in dims, and repeated dimensions or numbers outside 1:ndims(A) are forbidden.

The result shares the same underlying data as A, such that the result is mutable if and only if A is mutable, and setting elements of one alters the values of the other.

See also: reshape, vec.

Examples

julia> a = reshape(Vector(1:4),(2,2,1,1))
+ 2  4  6
source
Base.dropdimsFunction
dropdims(A; dims)

Return an array with the same data as A, but with the dimensions specified by dims removed. size(A,d) must equal 1 for every d in dims, and repeated dimensions or numbers outside 1:ndims(A) are forbidden.

The result shares the same underlying data as A, such that the result is mutable if and only if A is mutable, and setting elements of one alters the values of the other.

See also: reshape, vec.

Examples

julia> a = reshape(Vector(1:4),(2,2,1,1))
 2×2×1×1 Array{Int64, 4}:
 [:, :, 1, 1] =
  1  3
@@ -780,7 +780,7 @@
 2×2×1×1 Array{Int64, 4}:
 [:, :, 1, 1] =
  5  3
- 2  4
source
Base.vecFunction
vec(a::AbstractArray) -> AbstractVector

Reshape the array a as a one-dimensional column vector. Return a if it is already an AbstractVector. The resulting array shares the same underlying data as a, so it will only be mutable if a is mutable, in which case modifying one will also modify the other.

Examples

julia> a = [1 2 3; 4 5 6]
+ 2  4
source
Base.vecFunction
vec(a::AbstractArray) -> AbstractVector

Reshape the array a as a one-dimensional column vector. Return a if it is already an AbstractVector. The resulting array shares the same underlying data as a, so it will only be mutable if a is mutable, in which case modifying one will also modify the other.

Examples

julia> a = [1 2 3; 4 5 6]
 2×3 Matrix{Int64}:
  1  2  3
  4  5  6
@@ -795,7 +795,7 @@
  6
 
 julia> vec(1:3)
-1:3

See also reshape, dropdims.

source
Base.SubArrayType
SubArray{T,N,P,I,L} <: AbstractArray{T,N}

N-dimensional view into a parent array (of type P) with an element type T, restricted by a tuple of indices (of type I). L is true for types that support fast linear indexing, and false otherwise.

Construct SubArrays using the view function.

source
Base.wrapFunction
wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)

Create an array of size dims using m as the underlying memory. This can be thought of as a safe version of unsafe_wrap utilizing Memory or MemoryRef instead of raw pointers.

source

Concatenation and permutation

Base.catFunction
cat(A...; dims)

Concatenate the input arrays along the dimensions specified in dims.

Along a dimension d in dims, the size of the output array is sum(size(a,d) for a in A). Along other dimensions, all input arrays should have the same size, which will also be the size of the output array along those dimensions.

If dims is a single number, the different arrays are tightly packed along that dimension. If dims is an iterable containing several dimensions, the positions along these dimensions are increased simultaneously for each input array, filling with zero elsewhere. This allows one to construct block-diagonal matrices as cat(matrices...; dims=(1,2)), and their higher-dimensional analogues.

The special case dims=1 is vcat, and dims=2 is hcat. See also hvcat, hvncat, stack, repeat.

The keyword also accepts Val(dims).

Julia 1.8

For multiple dimensions dims = Val(::Tuple) was added in Julia 1.8.

Examples

Concatenate two arrays in different dimensions:

julia> a = [1 2 3]
+1:3

See also reshape, dropdims.

source
Base.SubArrayType
SubArray{T,N,P,I,L} <: AbstractArray{T,N}

N-dimensional view into a parent array (of type P) with an element type T, restricted by a tuple of indices (of type I). L is true for types that support fast linear indexing, and false otherwise.

Construct SubArrays using the view function.

source
Base.wrapFunction
wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)

Create an array of size dims using m as the underlying memory. This can be thought of as a safe version of unsafe_wrap utilizing Memory or MemoryRef instead of raw pointers.

source

Concatenation and permutation

Base.catFunction
cat(A...; dims)

Concatenate the input arrays along the dimensions specified in dims.

Along a dimension d in dims, the size of the output array is sum(size(a,d) for a in A). Along other dimensions, all input arrays should have the same size, which will also be the size of the output array along those dimensions.

If dims is a single number, the different arrays are tightly packed along that dimension. If dims is an iterable containing several dimensions, the positions along these dimensions are increased simultaneously for each input array, filling with zero elsewhere. This allows one to construct block-diagonal matrices as cat(matrices...; dims=(1,2)), and their higher-dimensional analogues.

The special case dims=1 is vcat, and dims=2 is hcat. See also hvcat, hvncat, stack, repeat.

The keyword also accepts Val(dims).

Julia 1.8

For multiple dimensions dims = Val(::Tuple) was added in Julia 1.8.

Examples

Concatenate two arrays in different dimensions:

julia> a = [1 2 3]
 1×3 Matrix{Int64}:
  1  2  3
 
@@ -847,7 +847,7 @@
  "aaa"  "bbb"
 
 julia> a * b
-"aaabbb"
source
Base.vcatFunction
vcat(A...)

Concatenate arrays or numbers vertically. Equivalent to cat(A...; dims=1), and to the syntax [a; b; c].

To concatenate a large vector of arrays, reduce(vcat, A) calls an efficient method when A isa AbstractVector{<:AbstractVecOrMat}, rather than working pairwise.

See also hcat, Iterators.flatten, stack.

Examples

julia> v = vcat([1,2], [3,4])
+"aaabbb"
source
Base.vcatFunction
vcat(A...)

Concatenate arrays or numbers vertically. Equivalent to cat(A...; dims=1), and to the syntax [a; b; c].

To concatenate a large vector of arrays, reduce(vcat, A) calls an efficient method when A isa AbstractVector{<:AbstractVecOrMat}, rather than working pairwise.

See also hcat, Iterators.flatten, stack.

Examples

julia> v = vcat([1,2], [3,4])
 4-element Vector{Int64}:
  1
  2
@@ -890,7 +890,7 @@
  6
 
 julia> ans == collect(Iterators.flatten(vs))
-true
source
Base.hcatFunction
hcat(A...)

Concatenate arrays or numbers horizontally. Equivalent to cat(A...; dims=2), and to the syntax [a b c] or [a;; b;; c].

For a large vector of arrays, reduce(hcat, A) calls an efficient method when A isa AbstractVector{<:AbstractVecOrMat}. For a vector of vectors, this can also be written stack(A).

See also vcat, hvcat.

Examples

julia> hcat([1,2], [3,4], [5,6])
+true
source
Base.hcatFunction
hcat(A...)

Concatenate arrays or numbers horizontally. Equivalent to cat(A...; dims=2), and to the syntax [a b c] or [a;; b;; c].

For a large vector of arrays, reduce(hcat, A) calls an efficient method when A isa AbstractVector{<:AbstractVecOrMat}. For a vector of vectors, this can also be written stack(A).

See also vcat, hvcat.

Examples

julia> hcat([1,2], [3,4], [5,6])
 2×3 Matrix{Int64}:
  1  3  5
  2  4  6
@@ -922,7 +922,7 @@
 julia> hcat([1.1, 9.9], Matrix(undef, 2, 0))  # hcat with empty 2×0 Matrix
 2×1 Matrix{Any}:
  1.1
- 9.9
source
Base.hvcatFunction
hvcat(blocks_per_row::Union{Tuple{Vararg{Int}}, Int}, values...)

Horizontal and vertical concatenation in one call. This function is called for block matrix syntax. The first argument specifies the number of arguments to concatenate in each block row. If the first argument is a single integer n, then all block rows are assumed to have n block columns.

Examples

julia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
+ 9.9
source
Base.hvcatFunction
hvcat(blocks_per_row::Union{Tuple{Vararg{Int}}, Int}, values...)

Horizontal and vertical concatenation in one call. This function is called for block matrix syntax. The first argument specifies the number of arguments to concatenate in each block row. If the first argument is a single integer n, then all block rows are assumed to have n block columns.

Examples

julia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
 (1, 2, 3, 4, 5, 6)
 
 julia> [a b c; d e f]
@@ -947,7 +947,7 @@
  3  4
  5  6
 julia> hvcat((2,2,2), a,b,c,d,e,f) == hvcat(2, a,b,c,d,e,f)
-true
source
Base.hvncatFunction
hvncat(dim::Int, row_first, values...)
 hvncat(dims::Tuple{Vararg{Int}}, row_first, values...)
 hvncat(shape::Tuple{Vararg{Tuple}}, row_first, values...)

Horizontal, vertical, and n-dimensional concatenation of many values in one call.

This function is called for block matrix syntax. The first argument either specifies the shape of the concatenation, similar to hvcat, as a tuple of tuples, or the dimensions that specify the key number of elements along each axis, and is used to determine the output dimensions. The dims form is more performant, and is used by default when the concatenation operation has the same number of elements along each axis (e.g., [a b; c d;;; e f ; g h]). The shape form is used when the number of elements along each axis is unbalanced (e.g., [a b ; c]). Unbalanced syntax needs additional validation overhead. The dim form is an optimization for concatenation along just one dimension. row_first indicates how values are ordered. The meaning of the first and second elements of shape are also swapped based on row_first.

Examples

julia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
 (1, 2, 3, 4, 5, 6)
@@ -1006,7 +1006,7 @@
  4             = elements in each 3d slice (4,)
  _____________
  4             = elements in each 4d slice (4,)
-⇒ shape = ((2, 1, 1), (3, 1), (4,), (4,)) with `row_first` = true
source
Base.stackFunction
stack(iter; [dims])

Combine a collection of arrays (or other iterable objects) of equal size into one larger array, by arranging them along one or more new dimensions.

By default the axes of the elements are placed first, giving size(result) = (size(first(iter))..., size(iter)...). This has the same order of elements as Iterators.flatten(iter).

With keyword dims::Integer, instead the ith element of iter becomes the slice selectdim(result, dims, i), so that size(result, dims) == length(iter). In this case stack reverses the action of eachslice with the same dims.

The various cat functions also combine arrays. However, these all extend the arrays' existing (possibly trivial) dimensions, rather than placing the arrays along new dimensions. They also accept arrays as separate arguments, rather than a single collection.

Julia 1.9

This function requires at least Julia 1.9.

Examples

julia> vecs = (1:2, [30, 40], Float32[500, 600]);
+⇒ shape = ((2, 1, 1), (3, 1), (4,), (4,)) with `row_first` = true
source
Base.stackFunction
stack(iter; [dims])

Combine a collection of arrays (or other iterable objects) of equal size into one larger array, by arranging them along one or more new dimensions.

By default the axes of the elements are placed first, giving size(result) = (size(first(iter))..., size(iter)...). This has the same order of elements as Iterators.flatten(iter).

With keyword dims::Integer, instead the ith element of iter becomes the slice selectdim(result, dims, i), so that size(result, dims) == length(iter). In this case stack reverses the action of eachslice with the same dims.

The various cat functions also combine arrays. However, these all extend the arrays' existing (possibly trivial) dimensions, rather than placing the arrays along new dimensions. They also accept arrays as separate arguments, rather than a single collection.

Julia 1.9

This function requires at least Julia 1.9.

Examples

julia> vecs = (1:2, [30, 40], Float32[500, 600]);
 
 julia> mat = stack(vecs)
 2×3 Matrix{Float32}:
@@ -1064,7 +1064,7 @@
 (35, 2, 3)
 
 julia> hvcat(5, M...) |> size  # hvcat puts matrices next to each other
-(14, 15)
source
stack(f, args...; [dims])

Apply a function to each element of a collection, and stack the result. Or to several collections, zipped together.

The function should return arrays (or tuples, or other iterators) all of the same size. These become slices of the result, each separated along dims (if given) or by default along the last dimensions.

See also mapslices, eachcol.

Examples

julia> stack(c -> (c, c-32), "julia")
+(14, 15)
source
stack(f, args...; [dims])

Apply a function to each element of a collection, and stack the result. Or to several collections, zipped together.

The function should return arrays (or tuples, or other iterators) all of the same size. These become slices of the result, each separated along dims (if given) or by default along the last dimensions.

See also mapslices, eachcol.

Examples

julia> stack(c -> (c, c-32), "julia")
 2×5 Matrix{Char}:
  'j'  'u'  'l'  'i'  'a'
  'J'  'U'  'L'  'I'  'A'
@@ -1074,11 +1074,11 @@
        end
 2×9 Matrix{Float64}:
  1.0  2.0  3.0   10.0   20.0   30.0  0.1   0.2   0.3
- 4.0  5.0  6.0  400.0  500.0  600.0  0.04  0.05  0.06
source
Base.vectFunction
vect(X...)

Create a Vector with element type computed from the promote_typeof of the argument, containing the argument list.

Examples

julia> a = Base.vect(UInt8(1), 2.5, 1//2)
+ 4.0  5.0  6.0  400.0  500.0  600.0  0.04  0.05  0.06
source
Base.vectFunction
vect(X...)

Create a Vector with element type computed from the promote_typeof of the argument, containing the argument list.

Examples

julia> a = Base.vect(UInt8(1), 2.5, 1//2)
 3-element Vector{Float64}:
  1.0
  2.5
- 0.5
source
Base.circshiftFunction
circshift(A, shifts)

Circularly shift, i.e. rotate, the data in A. The second argument is a tuple or vector giving the amount to shift in each dimension, or an integer to shift only in the first dimension.

The generated code is most efficient when the shift amounts are known at compile-time, i.e., compile-time constants.

See also: circshift!, circcopy!, bitrotate, <<.

Examples

julia> b = reshape(Vector(1:16), (4,4))
+ 0.5
source
Base.circshiftFunction
circshift(A, shifts)

Circularly shift, i.e. rotate, the data in A. The second argument is a tuple or vector giving the amount to shift in each dimension, or an integer to shift only in the first dimension.

The generated code is most efficient when the shift amounts are known at compile-time, i.e., compile-time constants.

See also: circshift!, circcopy!, bitrotate, <<.

Examples

julia> b = reshape(Vector(1:16), (4,4))
 4×4 Matrix{Int64}:
  1  5   9  13
  2  6  10  14
@@ -1133,7 +1133,7 @@
 (1, 'a', -7.0, 3)
 
 julia> circshift(z, -1)
-('a', -7.0, 3, 1)
source
Base.circshift!Function
circshift!(dest, src, shifts)

Circularly shift, i.e. rotate, the data in src, storing the result in dest. shifts specifies the amount to shift in each dimension.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also circshift.

source
Base.circcopy!Function
circcopy!(dest, src)

Copy src to dest, indexing each dimension modulo its length. src and dest must have the same size, but can be offset in their indices; any offset results in a (circular) wraparound. If the arrays have overlapping indices, then on the domain of the overlap dest agrees with src.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also: circshift.

Examples

julia> src = reshape(Vector(1:16), (4,4))
+('a', -7.0, 3, 1)
source
Base.circshift!Function
circshift!(dest, src, shifts)

Circularly shift, i.e. rotate, the data in src, storing the result in dest. shifts specifies the amount to shift in each dimension.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also circshift.

source
Base.circcopy!Function
circcopy!(dest, src)

Copy src to dest, indexing each dimension modulo its length. src and dest must have the same size, but can be offset in their indices; any offset results in a (circular) wraparound. If the arrays have overlapping indices, then on the domain of the overlap dest agrees with src.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also: circshift.

Examples

julia> src = reshape(Vector(1:16), (4,4))
 4×4 Array{Int64,2}:
  1  5   9  13
  2  6  10  14
@@ -1150,7 +1150,7 @@
  7  11  15  3
 
 julia> dest[1:3,2:4] == src[1:3,2:4]
-true
source
Base.findallMethod
findall(A)

Return a vector I of the true indices or keys of A. If there are no such elements of A, return an empty array. To search for other kinds of values, pass a predicate as the first argument.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

See also: findfirst, searchsorted.

Examples

julia> A = [true, false, false, true]
+true
source
Base.findallMethod
findall(A)

Return a vector I of the true indices or keys of A. If there are no such elements of A, return an empty array. To search for other kinds of values, pass a predicate as the first argument.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

See also: findfirst, searchsorted.

Examples

julia> A = [true, false, false, true]
 4-element Vector{Bool}:
  1
  0
@@ -1173,7 +1173,7 @@
  CartesianIndex(2, 2)
 
 julia> findall(falses(3))
-Int64[]
source
Base.findallMethod
findall(f::Function, A)

Return a vector I of the indices or keys of A where f(A[I]) returns true. If there are no such elements of A, return an empty array.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> x = [1, 3, 4]
+Int64[]
source
Base.findallMethod
findall(f::Function, A)

Return a vector I of the indices or keys of A where f(A[I]) returns true. If there are no such elements of A, return an empty array.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> x = [1, 3, 4]
 3-element Vector{Int64}:
  1
  3
@@ -1210,7 +1210,7 @@
 2-element Vector{Symbol}:
  :A
  :C
-
source
Base.findfirstMethod
findfirst(A)

Return the index or key of the first true value in A. Return nothing if no such value is found. To search for other kinds of values, pass a predicate as the first argument.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

See also: findall, findnext, findlast, searchsortedfirst.

Examples

julia> A = [false, false, true, false]
+
source
Base.findfirstMethod
findfirst(A)

Return the index or key of the first true value in A. Return nothing if no such value is found. To search for other kinds of values, pass a predicate as the first argument.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

See also: findall, findnext, findlast, searchsortedfirst.

Examples

julia> A = [false, false, true, false]
 4-element Vector{Bool}:
  0
  0
@@ -1228,7 +1228,7 @@
  1  0
 
 julia> findfirst(A)
-CartesianIndex(2, 1)
source
Base.findfirstMethod
findfirst(predicate::Function, A)

Return the index or key of the first element of A for which predicate returns true. Return nothing if there is no such element.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [1, 4, 2, 2]
+CartesianIndex(2, 1)
source
Base.findfirstMethod
findfirst(predicate::Function, A)

Return the index or key of the first element of A for which predicate returns true. Return nothing if there is no such element.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [1, 4, 2, 2]
 4-element Vector{Int64}:
  1
  4
@@ -1249,7 +1249,7 @@
  2  2
 
 julia> findfirst(iseven, A)
-CartesianIndex(2, 1)
source
Base.findlastMethod
findlast(A)

Return the index or key of the last true value in A. Return nothing if there is no true value in A.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

See also: findfirst, findprev, findall.

Examples

julia> A = [true, false, true, false]
+CartesianIndex(2, 1)
source
Base.findlastMethod
findlast(A)

Return the index or key of the last true value in A. Return nothing if there is no true value in A.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

See also: findfirst, findprev, findall.

Examples

julia> A = [true, false, true, false]
 4-element Vector{Bool}:
  1
  0
@@ -1269,7 +1269,7 @@
  1  0
 
 julia> findlast(A)
-CartesianIndex(2, 1)
source
Base.findlastMethod
findlast(predicate::Function, A)

Return the index or key of the last element of A for which predicate returns true. Return nothing if there is no such element.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [1, 2, 3, 4]
+CartesianIndex(2, 1)
source
Base.findlastMethod
findlast(predicate::Function, A)

Return the index or key of the last element of A for which predicate returns true. Return nothing if there is no such element.

Indices or keys are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [1, 2, 3, 4]
 4-element Vector{Int64}:
  1
  2
@@ -1287,7 +1287,7 @@
  3  4
 
 julia> findlast(isodd, A)
-CartesianIndex(2, 1)
source
Base.findnextMethod
findnext(A, i)

Find the next index after or including i of a true element of A, or nothing if not found.

Indices are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [false, false, true, false]
+CartesianIndex(2, 1)
source
Base.findnextMethod
findnext(A, i)

Find the next index after or including i of a true element of A, or nothing if not found.

Indices are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [false, false, true, false]
 4-element Vector{Bool}:
  0
  0
@@ -1305,7 +1305,7 @@
  1  0
 
 julia> findnext(A, CartesianIndex(1, 1))
-CartesianIndex(2, 1)
source
Base.findnextMethod
findnext(predicate::Function, A, i)

Find the next index after or including i of an element of A for which predicate returns true, or nothing if not found. This works for Arrays, Strings, and most other collections that support getindex, keys(A), and nextind.

Indices are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [1, 4, 2, 2];
+CartesianIndex(2, 1)
source
Base.findnextMethod
findnext(predicate::Function, A, i)

Find the next index after or including i of an element of A for which predicate returns true, or nothing if not found. This works for Arrays, Strings, and most other collections that support getindex, keys(A), and nextind.

Indices are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [1, 4, 2, 2];
 
 julia> findnext(isodd, A, 1)
 1
@@ -1318,7 +1318,7 @@
 CartesianIndex(1, 1)
 
 julia> findnext(isspace, "a b c", 3)
-4
source
Base.findprevMethod
findprev(A, i)

Find the previous index before or including i of a true element of A, or nothing if not found.

Indices are of the same type as those returned by keys(A) and pairs(A).

See also: findnext, findfirst, findall.

Examples

julia> A = [false, false, true, true]
+4
source
Base.findprevMethod
findprev(A, i)

Find the previous index before or including i of a true element of A, or nothing if not found.

Indices are of the same type as those returned by keys(A) and pairs(A).

See also: findnext, findfirst, findall.

Examples

julia> A = [false, false, true, true]
 4-element Vector{Bool}:
  0
  0
@@ -1336,7 +1336,7 @@
  1  1
 
 julia> findprev(A, CartesianIndex(2, 1))
-CartesianIndex(2, 1)
source
Base.findprevMethod
findprev(predicate::Function, A, i)

Find the previous index before or including i of an element of A for which predicate returns true, or nothing if not found. This works for Arrays, Strings, and most other collections that support getindex, keys(A), and nextind.

Indices are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [4, 6, 1, 2]
+CartesianIndex(2, 1)
source
Base.findprevMethod
findprev(predicate::Function, A, i)

Find the previous index before or including i of an element of A for which predicate returns true, or nothing if not found. This works for Arrays, Strings, and most other collections that support getindex, keys(A), and nextind.

Indices are of the same type as those returned by keys(A) and pairs(A).

Examples

julia> A = [4, 6, 1, 2]
 4-element Vector{Int64}:
  4
  6
@@ -1357,7 +1357,7 @@
 CartesianIndex(2, 1)
 
 julia> findprev(isspace, "a b c", 3)
-2
source
Base.permutedimsFunction
permutedims(A::AbstractArray, perm)
 permutedims(A::AbstractMatrix)

Permute the dimensions (axes) of array A. perm is a tuple or vector of ndims(A) integers specifying the permutation.

If A is a 2d array (AbstractMatrix), then perm defaults to (2,1), swapping the two axes of A (the rows and columns of the matrix). This differs from transpose in that the operation is not recursive, which is especially useful for arrays of non-numeric values (where the recursive transpose would throw an error) and/or 2d arrays that do not represent linear operators.

For 1d arrays, see permutedims(v::AbstractVector), which returns a 1-row “matrix”.

See also permutedims!, PermutedDimsArray, transpose, invperm.

Examples

2d arrays:

Unlike transpose, permutedims can be used to swap rows and columns of 2d arrays of arbitrary non-numeric elements, such as strings:

julia> A = ["a" "b" "c"
             "d" "e" "f"]
 2×3 Matrix{String}:
@@ -1422,7 +1422,7 @@
 (13, 5, 11, 7)
 
 julia> size(A)[perm] == ans
-true
source
permutedims(v::AbstractVector)

Reshape vector v into a 1 × length(v) row matrix. Differs from transpose in that the operation is not recursive, which is especially useful for arrays of non-numeric values (where the recursive transpose might throw an error).

Examples

Unlike transpose, permutedims can be used on vectors of arbitrary non-numeric elements, such as strings:

julia> permutedims(["a", "b", "c"])
+true
source
permutedims(v::AbstractVector)

Reshape vector v into a 1 × length(v) row matrix. Differs from transpose in that the operation is not recursive, which is especially useful for arrays of non-numeric values (where the recursive transpose might throw an error).

Examples

Unlike transpose, permutedims can be used on vectors of arbitrary non-numeric elements, such as strings:

julia> permutedims(["a", "b", "c"])
 1×3 Matrix{String}:
  "a"  "b"  "c"

For vectors of numbers, permutedims(v) works much like transpose(v) except that the return type differs (it uses reshape rather than a LinearAlgebra.Transpose view, though both share memory with the original array v):

julia> v = [1, 2, 3, 4]
 4-element Vector{Int64}:
@@ -1463,7 +1463,7 @@
 
 julia> transpose(V)
 1×2 transpose(::Vector{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:
- [1 3; 2 4]  [5 7; 6 8]
source
Base.permutedims!Function
permutedims!(dest, src, perm)

Permute the dimensions of array src and store the result in the array dest. perm is a vector specifying a permutation of length ndims(src). The preallocated array dest should have size(dest) == size(src)[perm] and is completely overwritten. No in-place permutation is supported and unexpected results will happen if src and dest have overlapping memory regions.

See also permutedims.

source
Base.PermutedDimsArrays.PermutedDimsArrayType
PermutedDimsArray(A, perm) -> B

Given an AbstractArray A, create a view B such that the dimensions appear to be permuted. Similar to permutedims, except that no copying occurs (B shares storage with A).

See also permutedims, invperm.

Examples

julia> A = rand(3,5,4);
+ [1 3; 2 4]  [5 7; 6 8]
source
Base.permutedims!Function
permutedims!(dest, src, perm)

Permute the dimensions of array src and store the result in the array dest. perm is a vector specifying a permutation of length ndims(src). The preallocated array dest should have size(dest) == size(src)[perm] and is completely overwritten. No in-place permutation is supported and unexpected results will happen if src and dest have overlapping memory regions.

See also permutedims.

source
Base.PermutedDimsArrays.PermutedDimsArrayType
PermutedDimsArray(A, perm) -> B

Given an AbstractArray A, create a view B such that the dimensions appear to be permuted. Similar to permutedims, except that no copying occurs (B shares storage with A).

See also permutedims, invperm.

Examples

julia> A = rand(3,5,4);
 
 julia> B = PermutedDimsArray(A, (3,1,2));
 
@@ -1471,7 +1471,7 @@
 (4, 3, 5)
 
 julia> B[3,1,2] == A[1,2,3]
-true
source
Base.promote_shapeFunction
promote_shape(s1, s2)

Check two array shapes for compatibility, allowing trailing singleton dimensions, and return whichever shape has more dimensions.

Examples

julia> a = fill(1, (3,4,1,1,1));
+true
source
Base.promote_shapeFunction
promote_shape(s1, s2)

Check two array shapes for compatibility, allowing trailing singleton dimensions, and return whichever shape has more dimensions.

Examples

julia> a = fill(1, (3,4,1,1,1));
 
 julia> b = fill(1, (3,4));
 
@@ -1479,7 +1479,7 @@
 (Base.OneTo(3), Base.OneTo(4), Base.OneTo(1), Base.OneTo(1), Base.OneTo(1))
 
 julia> promote_shape((2,3,1,4), (2, 3, 1, 4, 1))
-(2, 3, 1, 4, 1)
source

Array functions

Base.accumulateFunction
accumulate(op, A; dims::Integer, [init])

Cumulative operation op along the dimension dims of A (providing dims is optional for vectors). An initial value init may optionally be provided by a keyword argument. See also accumulate! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).

For common operations there are specialized variants of accumulate, see cumsum, cumprod. For a lazy version, see Iterators.accumulate.

Julia 1.5

accumulate on a non-array iterator requires at least Julia 1.5.

Examples

julia> accumulate(+, [1,2,3])
+(2, 3, 1, 4, 1)
source

Array functions

Base.accumulateFunction
accumulate(op, A; dims::Integer, [init])

Cumulative operation op along the dimension dims of A (providing dims is optional for vectors). An initial value init may optionally be provided by a keyword argument. See also accumulate! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).

For common operations there are specialized variants of accumulate, see cumsum, cumprod. For a lazy version, see Iterators.accumulate.

Julia 1.5

accumulate on a non-array iterator requires at least Julia 1.5.

Examples

julia> accumulate(+, [1,2,3])
 3-element Vector{Int64}:
  1
  3
@@ -1506,7 +1506,7 @@
 julia> accumulate(+, fill(1, 2, 5), dims=2, init=100.0)
 2×5 Matrix{Float64}:
  101.0  102.0  103.0  104.0  105.0
- 101.0  102.0  103.0  104.0  105.0
source
Base.accumulate!Function
accumulate!(op, B, A; [dims], [init])

Cumulative operation op on A along the dimension dims, storing the result in B. Providing dims is optional for vectors. If the keyword argument init is given, its value is used to instantiate the accumulation.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also accumulate, cumsum!, cumprod!.

Examples

julia> x = [1, 0, 2, 0, 3];
+ 101.0  102.0  103.0  104.0  105.0
source
Base.accumulate!Function
accumulate!(op, B, A; [dims], [init])

Cumulative operation op on A along the dimension dims, storing the result in B. Providing dims is optional for vectors. If the keyword argument init is given, its value is used to instantiate the accumulation.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also accumulate, cumsum!, cumprod!.

Examples

julia> x = [1, 0, 2, 0, 3];
 
 julia> y = rand(5);
 
@@ -1532,7 +1532,7 @@
 julia> accumulate!(*, B, A, dims=2, init=10)
 2×3 Matrix{Int64}:
  10   20    60
- 40  200  1200
source
Base.cumprodFunction
cumprod(A; dims::Integer)

Cumulative product along the dimension dim. See also cumprod! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).

Examples

julia> a = Int8[1 2 3; 4 5 6];
+ 40  200  1200
source
Base.cumprodFunction
cumprod(A; dims::Integer)

Cumulative product along the dimension dim. See also cumprod! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).

Examples

julia> a = Int8[1 2 3; 4 5 6];
 
 julia> cumprod(a, dims=1)
 2×3 Matrix{Int64}:
@@ -1542,7 +1542,7 @@
 julia> cumprod(a, dims=2)
 2×3 Matrix{Int64}:
  1   2    6
- 4  20  120
source
cumprod(itr)

Cumulative product of an iterator.

See also cumprod!, accumulate, cumsum.

Julia 1.5

cumprod on a non-array iterator requires at least Julia 1.5.

Examples

julia> cumprod(fill(1//2, 3))
+ 4  20  120
source
cumprod(itr)

Cumulative product of an iterator.

See also cumprod!, accumulate, cumsum.

Julia 1.5

cumprod on a non-array iterator requires at least Julia 1.5.

Examples

julia> cumprod(fill(1//2, 3))
 3-element Vector{Rational{Int64}}:
  1//2
  1//4
@@ -1557,7 +1557,7 @@
  "ju"
  "jul"
  "juli"
- "julia"
source
Base.cumprod!Function
cumprod!(B, A; dims::Integer)

Cumulative product of A along the dimension dims, storing the result in B. See also cumprod.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
cumprod!(y::AbstractVector, x::AbstractVector)

Cumulative product of a vector x, storing the result in y. See also cumprod.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.cumsumFunction
cumsum(A; dims::Integer)

Cumulative sum along the dimension dims. See also cumsum! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).

Examples

julia> a = [1 2 3; 4 5 6]
+ "julia"
source
Base.cumprod!Function
cumprod!(B, A; dims::Integer)

Cumulative product of A along the dimension dims, storing the result in B. See also cumprod.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
cumprod!(y::AbstractVector, x::AbstractVector)

Cumulative product of a vector x, storing the result in y. See also cumprod.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.cumsumFunction
cumsum(A; dims::Integer)

Cumulative sum along the dimension dims. See also cumsum! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).

Examples

julia> a = [1 2 3; 4 5 6]
 2×3 Matrix{Int64}:
  1  2  3
  4  5  6
@@ -1578,7 +1578,7 @@
 julia> accumulate(+,Int8[100, 28])
 2-element Vector{Int8}:
   100
- -128

In the former case, the integers are widened to system word size and therefore the result is Int64[100, 128]. In the latter case, no such widening happens and integer overflow results in Int8[100, -128].

source
cumsum(itr)

Cumulative sum of an iterator.

See also accumulate to apply functions other than +.

Julia 1.5

cumsum on a non-array iterator requires at least Julia 1.5.

Examples

julia> cumsum(1:3)
+ -128

In the former case, the integers are widened to system word size and therefore the result is Int64[100, 128]. In the latter case, no such widening happens and integer overflow results in Int8[100, -128].

source
cumsum(itr)

Cumulative sum of an iterator.

See also accumulate to apply functions other than +.

Julia 1.5

cumsum on a non-array iterator requires at least Julia 1.5.

Examples

julia> cumsum(1:3)
 3-element Vector{Int64}:
  1
  3
@@ -1591,7 +1591,7 @@
 3-element Vector{Vector{Int64}}:
  [1, 1]
  [2, 2]
- [3, 3]
source
Base.cumsum!Function
cumsum!(B, A; dims::Integer)

Cumulative sum of A along the dimension dims, storing the result in B. See also cumsum.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.diffFunction
diff(A::AbstractVector)
+ [3, 3]
source
Base.cumsum!Function
cumsum!(B, A; dims::Integer)

Cumulative sum of A along the dimension dims, storing the result in B. See also cumsum.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.diffFunction
diff(A::AbstractVector)
 diff(A::AbstractArray; dims::Integer)

Finite difference operator on a vector or a multidimensional array A. In the latter case the dimension to operate on needs to be specified with the dims keyword argument.

Julia 1.1

diff for arrays with dimension higher than 2 requires at least Julia 1.1.

Examples

julia> a = [2 4; 6 16]
 2×2 Matrix{Int64}:
  2   4
@@ -1606,7 +1606,7 @@
 3-element Vector{Int64}:
   4
  -2
- 12
source
Base.repeatFunction
repeat(A::AbstractArray, counts::Integer...)

Construct an array by repeating array A a given number of times in each dimension, specified by counts.

See also: fill, Iterators.repeated, Iterators.cycle.

Examples

julia> repeat([1, 2, 3], 2)
+ 12
source
Base.repeatFunction
repeat(A::AbstractArray, counts::Integer...)

Construct an array by repeating array A a given number of times in each dimension, specified by counts.

See also: fill, Iterators.repeated, Iterators.cycle.

Examples

julia> repeat([1, 2, 3], 2)
 6-element Vector{Int64}:
  1
  2
@@ -1622,7 +1622,7 @@
  3  3  3
  1  1  1
  2  2  2
- 3  3  3
source
repeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A)))

Construct an array by repeating the entries of A. The i-th element of inner specifies the number of times that the individual entries of the i-th dimension of A should be repeated. The i-th element of outer specifies the number of times that a slice along the i-th dimension of A should be repeated. If inner or outer are omitted, no repetition is performed.

Examples

julia> repeat(1:2, inner=2)
+ 3  3  3
source
repeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A)))

Construct an array by repeating the entries of A. The i-th element of inner specifies the number of times that the individual entries of the i-th dimension of A should be repeated. The i-th element of outer specifies the number of times that a slice along the i-th dimension of A should be repeated. If inner or outer are omitted, no repetition is performed.

Examples

julia> repeat(1:2, inner=2)
 4-element Vector{Int64}:
  1
  1
@@ -1641,9 +1641,9 @@
  1  2  1  2  1  2
  1  2  1  2  1  2
  3  4  3  4  3  4
- 3  4  3  4  3  4
source
repeat(s::AbstractString, r::Integer)

Repeat a string r times. This can be written as s^r.

See also ^.

Examples

julia> repeat("ha", 3)
-"hahaha"
source
repeat(c::AbstractChar, r::Integer) -> String

Repeat a character r times. This can equivalently be accomplished by calling c^r.

Examples

julia> repeat('A', 3)
-"AAA"
source
Base.rot180Function
rot180(A)

Rotate matrix A 180 degrees.

Examples

julia> a = [1 2; 3 4]
+ 3  4  3  4  3  4
source
repeat(s::AbstractString, r::Integer)

Repeat a string r times. This can be written as s^r.

See also ^.

Examples

julia> repeat("ha", 3)
+"hahaha"
source
repeat(c::AbstractChar, r::Integer) -> String

Repeat a character r times. This can equivalently be accomplished by calling c^r.

Examples

julia> repeat('A', 3)
+"AAA"
source
Base.rot180Function
rot180(A)

Rotate matrix A 180 degrees.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1651,7 +1651,7 @@
 julia> rot180(a)
 2×2 Matrix{Int64}:
  4  3
- 2  1
source
rot180(A, k)

Rotate matrix A 180 degrees an integer k number of times. If k is even, this is equivalent to a copy.

Examples

julia> a = [1 2; 3 4]
+ 2  1
source
rot180(A, k)

Rotate matrix A 180 degrees an integer k number of times. If k is even, this is equivalent to a copy.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1664,7 +1664,7 @@
 julia> rot180(a,2)
 2×2 Matrix{Int64}:
  1  2
- 3  4
source
Base.rotl90Function
rotl90(A)

Rotate matrix A left 90 degrees.

Examples

julia> a = [1 2; 3 4]
+ 3  4
source
Base.rotl90Function
rotl90(A)

Rotate matrix A left 90 degrees.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1672,7 +1672,7 @@
 julia> rotl90(a)
 2×2 Matrix{Int64}:
  2  4
- 1  3
source
rotl90(A, k)

Left-rotate matrix A 90 degrees counterclockwise an integer k number of times. If k is a multiple of four (including zero), this is equivalent to a copy.

Examples

julia> a = [1 2; 3 4]
+ 1  3
source
rotl90(A, k)

Left-rotate matrix A 90 degrees counterclockwise an integer k number of times. If k is a multiple of four (including zero), this is equivalent to a copy.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1695,7 +1695,7 @@
 julia> rotl90(a,4)
 2×2 Matrix{Int64}:
  1  2
- 3  4
source
Base.rotr90Function
rotr90(A)

Rotate matrix A right 90 degrees.

Examples

julia> a = [1 2; 3 4]
+ 3  4
source
Base.rotr90Function
rotr90(A)

Rotate matrix A right 90 degrees.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1703,7 +1703,7 @@
 julia> rotr90(a)
 2×2 Matrix{Int64}:
  3  1
- 4  2
source
rotr90(A, k)

Right-rotate matrix A 90 degrees clockwise an integer k number of times. If k is a multiple of four (including zero), this is equivalent to a copy.

Examples

julia> a = [1 2; 3 4]
+ 4  2
source
rotr90(A, k)

Right-rotate matrix A 90 degrees clockwise an integer k number of times. If k is a multiple of four (including zero), this is equivalent to a copy.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1726,7 +1726,7 @@
 julia> rotr90(a,4)
 2×2 Matrix{Int64}:
  1  2
- 3  4
source
Base.mapslicesFunction
mapslices(f, A; dims)

Transform the given dimensions of array A by applying a function f on each slice of the form A[..., :, ..., :, ...], with a colon at each d in dims. The results are concatenated along the remaining dimensions.

For example, if dims = [1,2] and A is 4-dimensional, then f is called on x = A[:,:,i,j] for all i and j, and f(x) becomes R[:,:,i,j] in the result R.

See also eachcol or eachslice, used with map or stack.

Examples

julia> A = reshape(1:30,(2,5,3))
+ 3  4
source
Base.mapslicesFunction
mapslices(f, A; dims)

Transform the given dimensions of array A by applying a function f on each slice of the form A[..., :, ..., :, ...], with a colon at each d in dims. The results are concatenated along the remaining dimensions.

For example, if dims = [1,2] and A is 4-dimensional, then f is called on x = A[:,:,i,j] for all i and j, and f(x) becomes R[:,:,i,j] in the result R.

See also eachcol or eachslice, used with map or stack.

Examples

julia> A = reshape(1:30,(2,5,3))
 2×5×3 reshape(::UnitRange{Int64}, 2, 5, 3) with eltype Int64:
 [:, :, 1] =
  1  3  5  7   9
@@ -1774,7 +1774,7 @@
  9//29
 
 julia> mapslices(sum, A; dims=(1,3)) == sum(A; dims=(1,3))
-true

Notice that in eachslice(A; dims=2), the specified dimension is the one without a colon in the slice. This is view(A,:,i,:), whereas mapslices(f, A; dims=(1,3)) uses A[:,i,:]. The function f may mutate values in the slice without affecting A.

source
Base.eachrowFunction
eachrow(A::AbstractVecOrMat) <: AbstractVector

Create a RowSlices object that is a vector of rows of matrix or vector A. Row slices are returned as AbstractVector views of A.

For the inverse, see stack(rows; dims=1).

See also eachcol, eachslice and mapslices.

Julia 1.1

This function requires at least Julia 1.1.

Julia 1.9

Prior to Julia 1.9, this returned an iterator.

Examples

julia> a = [1 2; 3 4]
+true

Notice that in eachslice(A; dims=2), the specified dimension is the one without a colon in the slice. This is view(A,:,i,:), whereas mapslices(f, A; dims=(1,3)) uses A[:,i,:]. The function f may mutate values in the slice without affecting A.

source
Base.eachrowFunction
eachrow(A::AbstractVecOrMat) <: AbstractVector

Create a RowSlices object that is a vector of rows of matrix or vector A. Row slices are returned as AbstractVector views of A.

For the inverse, see stack(rows; dims=1).

See also eachcol, eachslice and mapslices.

Julia 1.1

This function requires at least Julia 1.1.

Julia 1.9

Prior to Julia 1.9, this returned an iterator.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1787,7 +1787,7 @@
 julia> s[1]
 2-element view(::Matrix{Int64}, 1, :) with eltype Int64:
  1
- 2
source
Base.eachcolFunction
eachcol(A::AbstractVecOrMat) <: AbstractVector

Create a ColumnSlices object that is a vector of columns of matrix or vector A. Column slices are returned as AbstractVector views of A.

For the inverse, see stack(cols) or reduce(hcat, cols).

See also eachrow, eachslice and mapslices.

Julia 1.1

This function requires at least Julia 1.1.

Julia 1.9

Prior to Julia 1.9, this returned an iterator.

Examples

julia> a = [1 2; 3 4]
+ 2
source
Base.eachcolFunction
eachcol(A::AbstractVecOrMat) <: AbstractVector

Create a ColumnSlices object that is a vector of columns of matrix or vector A. Column slices are returned as AbstractVector views of A.

For the inverse, see stack(cols) or reduce(hcat, cols).

See also eachrow, eachslice and mapslices.

Julia 1.1

This function requires at least Julia 1.1.

Julia 1.9

Prior to Julia 1.9, this returned an iterator.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1800,7 +1800,7 @@
 julia> s[1]
 2-element view(::Matrix{Int64}, :, 1) with eltype Int64:
  1
- 3
source
Base.eachsliceFunction
eachslice(A::AbstractArray; dims, drop=true)

Create a Slices object that is an array of slices over dimensions dims of A, returning views that select all the data from the other dimensions in A. dims can either be an integer or a tuple of integers.

If drop = true (the default), the outer Slices will drop the inner dimensions, and the ordering of the dimensions will match those in dims. If drop = false, then the Slices will have the same dimensionality as the underlying array, with inner dimensions having size 1.

See stack(slices; dims) for the inverse of eachslice(A; dims::Integer).

See also eachrow, eachcol, mapslices and selectdim.

Julia 1.1

This function requires at least Julia 1.1.

Julia 1.9

Prior to Julia 1.9, this returned an iterator, and only a single dimension dims was supported.

Examples

julia> m = [1 2 3; 4 5 6; 7 8 9]
+ 3
source
Base.eachsliceFunction
eachslice(A::AbstractArray; dims, drop=true)

Create a Slices object that is an array of slices over dimensions dims of A, returning views that select all the data from the other dimensions in A. dims can either be an integer or a tuple of integers.

If drop = true (the default), the outer Slices will drop the inner dimensions, and the ordering of the dimensions will match those in dims. If drop = false, then the Slices will have the same dimensionality as the underlying array, with inner dimensions having size 1.

See stack(slices; dims) for the inverse of eachslice(A; dims::Integer).

See also eachrow, eachcol, mapslices and selectdim.

Julia 1.1

This function requires at least Julia 1.1.

Julia 1.9

Prior to Julia 1.9, this returned an iterator, and only a single dimension dims was supported.

Examples

julia> m = [1 2 3; 4 5 6; 7 8 9]
 3×3 Matrix{Int64}:
  1  2  3
  4  5  6
@@ -1822,7 +1822,7 @@
 3×1 Slices{Matrix{Int64}, Tuple{Int64, Colon}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}, 2}:
  [1, 2, 3]
  [4, 5, 6]
- [7, 8, 9]
source

Combinatorics

Base.invpermFunction
invperm(v)

Return the inverse permutation of v. If B = A[v], then A == B[invperm(v)].

See also sortperm, invpermute!, isperm, permutedims.

Examples

julia> p = (2, 3, 1);
+ [7, 8, 9]
source

Combinatorics

Base.invpermFunction
invperm(v)

Return the inverse permutation of v. If B = A[v], then A == B[invperm(v)].

See also sortperm, invpermute!, isperm, permutedims.

Examples

julia> p = (2, 3, 1);
 
 julia> invperm(p)
 (3, 1, 2)
@@ -1850,11 +1850,11 @@
  'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
  'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
  'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
- 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
source
Base.ispermFunction
isperm(v) -> Bool

Return true if v is a valid permutation.

Examples

julia> isperm([1; 2])
+ 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
source
Base.ispermFunction
isperm(v) -> Bool

Return true if v is a valid permutation.

Examples

julia> isperm([1; 2])
 true
 
 julia> isperm([1; 3])
-false
source
Base.permute!Method
permute!(v, p)

Permute vector v in-place, according to permutation p. No checking is done to verify that p is a permutation.

To return a new permutation, use v[p]. This is generally faster than permute!(v, p); it is even faster to write into a pre-allocated output array with u .= @view v[p]. (Even though permute! overwrites v in-place, it internally requires some allocation to keep track of which elements have been moved.)

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also invpermute!.

Examples

julia> A = [1, 1, 3, 4];
+false
source
Base.permute!Method
permute!(v, p)

Permute vector v in-place, according to permutation p. No checking is done to verify that p is a permutation.

To return a new permutation, use v[p]. This is generally faster than permute!(v, p); it is even faster to write into a pre-allocated output array with u .= @view v[p]. (Even though permute! overwrites v in-place, it internally requires some allocation to keep track of which elements have been moved.)

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also invpermute!.

Examples

julia> A = [1, 1, 3, 4];
 
 julia> perm = [2, 4, 3, 1];
 
@@ -1865,7 +1865,7 @@
  1
  4
  3
- 1
source
Base.invpermute!Function
invpermute!(v, p)

Like permute!, but the inverse of the given permutation is applied.

Note that if you have a pre-allocated output array (e.g. u = similar(v)), it is quicker to instead employ u[p] = v. (invpermute! internally allocates a copy of the data.)

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1, 1, 3, 4];
+ 1
source
Base.invpermute!Function
invpermute!(v, p)

Like permute!, but the inverse of the given permutation is applied.

Note that if you have a pre-allocated output array (e.g. u = similar(v)), it is quicker to instead employ u[p] = v. (invpermute! internally allocates a copy of the data.)

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1, 1, 3, 4];
 
 julia> perm = [2, 4, 3, 1];
 
@@ -1876,7 +1876,7 @@
  4
  1
  3
- 1
source
Base.reverseMethod
reverse(A; dims=:)

Reverse A along dimension dims, which can be an integer (a single dimension), a tuple of integers (a tuple of dimensions) or : (reverse along all the dimensions, the default). See also reverse! for in-place reversal.

Examples

julia> b = Int64[1 2; 3 4]
+ 1
source
Base.reverseMethod
reverse(A; dims=:)

Reverse A along dimension dims, which can be an integer (a single dimension), a tuple of integers (a tuple of dimensions) or : (reverse along all the dimensions, the default). See also reverse! for in-place reversal.

Examples

julia> b = Int64[1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1889,7 +1889,7 @@
 julia> reverse(b)
 2×2 Matrix{Int64}:
  4  3
- 2  1
Julia 1.6

Prior to Julia 1.6, only single-integer dims are supported in reverse.

source
Base.reverseindFunction
reverseind(v, i)

Given an index i in reverse(v), return the corresponding index in v so that v[reverseind(v,i)] == reverse(v)[i]. (This can be nontrivial in cases where v contains non-ASCII characters.)

Examples

julia> s = "Julia🚀"
+ 2  1
Julia 1.6

Prior to Julia 1.6, only single-integer dims are supported in reverse.

source
Base.reverseindFunction
reverseind(v, i)

Given an index i in reverse(v), return the corresponding index in v so that v[reverseind(v,i)] == reverse(v)[i]. (This can be nontrivial in cases where v contains non-ASCII characters.)

Examples

julia> s = "Julia🚀"
 "Julia🚀"
 
 julia> r = reverse(s)
@@ -1898,7 +1898,7 @@
 julia> for i in eachindex(s)
            print(r[reverseind(r, i)])
        end
-Julia🚀
source
Base.reverse!Function
reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v

In-place version of reverse.

Examples

julia> A = Vector(1:5)
+Julia🚀
source
Base.reverse!Function
reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v

In-place version of reverse.

Examples

julia> A = Vector(1:5)
 5-element Vector{Int64}:
  1
  2
@@ -1914,4 +1914,4 @@
  4
  3
  2
- 1
source
reverse!(A; dims=:)

Like reverse, but operates in-place in A.

Julia 1.6

Multidimensional reverse! requires Julia 1.6.

source
+ 1
source
reverse!(A; dims=:)

Like reverse, but operates in-place in A.

Julia 1.6

Multidimensional reverse! requires Julia 1.6.

source
diff --git a/en/v1.12-dev/base/base/index.html b/en/v1.12-dev/base/base/index.html index 92815b86610e..3dc842aac0a9 100644 --- a/en/v1.12-dev/base/base/index.html +++ b/en/v1.12-dev/base/base/index.html @@ -3,25 +3,25 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Essentials

Introduction

Julia Base contains a range of functions and macros appropriate for performing scientific and numerical computing, but is also as broad as those of many general purpose programming languages. Additional functionality is available from a growing collection of available packages. Functions are grouped by topic below.

Some general notes:

  • To use module functions, use import Module to import the module, and Module.fn(x) to use the functions.
  • Alternatively, using Module will import all exported Module functions into the current namespace.
  • By convention, function names ending with an exclamation point (!) modify their arguments. Some functions have both modifying (e.g., sort!) and non-modifying (sort) versions.

The behaviors of Base and standard libraries are stable as defined in SemVer only if they are documented; i.e., included in the Julia documentation and not marked as unstable. See API FAQ for more information.

Getting Around

Base.exitFunction
exit(code=0)

Stop the program with an exit code. The default exit code is zero, indicating that the program completed successfully. In an interactive session, exit() can be called with the keyboard shortcut ^D.

source
Base.atexitFunction
atexit(f)

Register a zero- or one-argument function f() to be called at process exit. atexit() hooks are called in last in first out (LIFO) order and run before object finalizers.

If f has a method defined for one integer argument, it will be called as f(n::Int32), where n is the current exit code, otherwise it will be called as f().

Julia 1.9

The one-argument form requires Julia 1.9

Exit hooks are allowed to call exit(n), in which case Julia will exit with exit code n (instead of the original exit code). If more than one exit hook calls exit(n), then Julia will exit with the exit code corresponding to the last called exit hook that calls exit(n). (Because exit hooks are called in LIFO order, "last called" is equivalent to "first registered".)

Note: Once all exit hooks have been called, no more exit hooks can be registered, and any call to atexit(f) after all hooks have completed will throw an exception. This situation may occur if you are registering exit hooks from background Tasks that may still be executing concurrently during shutdown.

source
Base.summarysizeFunction
Base.summarysize(obj; exclude=Union{...}, chargeall=Union{...}) -> Int

Compute the amount of memory, in bytes, used by all unique objects reachable from the argument.

Keyword Arguments

  • exclude: specifies the types of objects to exclude from the traversal.
  • chargeall: specifies the types of objects to always charge the size of all of their fields, even if those fields would normally be excluded.

See also sizeof.

Examples

julia> Base.summarysize(1.0)
+

Essentials

Introduction

Julia Base contains a range of functions and macros appropriate for performing scientific and numerical computing, but is also as broad as those of many general purpose programming languages. Additional functionality is available from a growing collection of available packages. Functions are grouped by topic below.

Some general notes:

  • To use module functions, use import Module to import the module, and Module.fn(x) to use the functions.
  • Alternatively, using Module will import all exported Module functions into the current namespace.
  • By convention, function names ending with an exclamation point (!) modify their arguments. Some functions have both modifying (e.g., sort!) and non-modifying (sort) versions.

The behaviors of Base and standard libraries are stable as defined in SemVer only if they are documented; i.e., included in the Julia documentation and not marked as unstable. See API FAQ for more information.

Getting Around

Base.exitFunction
exit(code=0)

Stop the program with an exit code. The default exit code is zero, indicating that the program completed successfully. In an interactive session, exit() can be called with the keyboard shortcut ^D.

source
Base.atexitFunction
atexit(f)

Register a zero- or one-argument function f() to be called at process exit. atexit() hooks are called in last in first out (LIFO) order and run before object finalizers.

If f has a method defined for one integer argument, it will be called as f(n::Int32), where n is the current exit code, otherwise it will be called as f().

Julia 1.9

The one-argument form requires Julia 1.9

Exit hooks are allowed to call exit(n), in which case Julia will exit with exit code n (instead of the original exit code). If more than one exit hook calls exit(n), then Julia will exit with the exit code corresponding to the last called exit hook that calls exit(n). (Because exit hooks are called in LIFO order, "last called" is equivalent to "first registered".)

Note: Once all exit hooks have been called, no more exit hooks can be registered, and any call to atexit(f) after all hooks have completed will throw an exception. This situation may occur if you are registering exit hooks from background Tasks that may still be executing concurrently during shutdown.

source
Base.summarysizeFunction
Base.summarysize(obj; exclude=Union{...}, chargeall=Union{...}) -> Int

Compute the amount of memory, in bytes, used by all unique objects reachable from the argument.

Keyword Arguments

  • exclude: specifies the types of objects to exclude from the traversal.
  • chargeall: specifies the types of objects to always charge the size of all of their fields, even if those fields would normally be excluded.

See also sizeof.

Examples

julia> Base.summarysize(1.0)
 8
 
 julia> Base.summarysize(Ref(rand(100)))
 864
 
 julia> sizeof(Ref(rand(100)))
-8
source
Base.__precompile__Function
__precompile__(isprecompilable::Bool)

Specify whether the file calling this function is precompilable, defaulting to true. If a module or file is not safely precompilable, it should call __precompile__(false) in order to throw an error if Julia attempts to precompile it.

source
Base.includeFunction
Base.include([mapexpr::Function,] m::Module, path::AbstractString)

Evaluate the contents of the input source file in the global scope of module m. Every module (except those defined with baremodule) has its own definition of include omitting the m argument, which evaluates the file in that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to include will search relative to that path. This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files.

The optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in path, the include function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.

Julia 1.5

Julia 1.5 is required for passing the mapexpr argument.

source
includeFunction
include([mapexpr::Function,] path::AbstractString)

Evaluate the contents of the input source file in the global scope of the containing module. Every module (except those defined with baremodule) has its own definition of include, which evaluates the file in that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to include will search relative to that path. This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files. The argument path is normalized using normpath which will resolve relative path tokens such as .. and convert / to the appropriate path separator.

The optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in path, the include function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.

Use Base.include to evaluate a file into another module.

Julia 1.5

Julia 1.5 is required for passing the mapexpr argument.

source
Base.include_stringFunction
include_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString="string")

Like include, except reads code from the given string rather than from a file.

The optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in code, the include_string function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.

Julia 1.5

Julia 1.5 is required for passing the mapexpr argument.

source
Base.include_dependencyFunction
include_dependency(path::AbstractString; track_content::Bool=false)

In a module, declare that the file, directory, or symbolic link specified by path (relative or absolute) is a dependency for precompilation; that is, the module will need to be recompiled if the modification time mtime of path changes. If track_content=true recompilation is triggered when the content of path changes (if path is a directory the content equals join(readdir(path))).

This is only needed if your module depends on a path that is not used via include. It has no effect outside of compilation.

Julia 1.11

Keyword argument track_content requires at least Julia 1.11.

source
__init__Keyword
__init__

The __init__() function in a module executes immediately after the module is loaded at runtime for the first time. It is called once, after all other statements in the module have been executed. Because it is called after fully importing the module, __init__ functions of submodules will be executed first. Two typical uses of __init__ are calling runtime initialization functions of external C libraries and initializing global constants that involve pointers returned by external libraries. See the manual section about modules for more details.

Examples

const foo_data_ptr = Ref{Ptr{Cvoid}}(0)
+8
source
Base.__precompile__Function
__precompile__(isprecompilable::Bool)

Specify whether the file calling this function is precompilable, defaulting to true. If a module or file is not safely precompilable, it should call __precompile__(false) in order to throw an error if Julia attempts to precompile it.

source
Base.includeFunction
Base.include([mapexpr::Function,] m::Module, path::AbstractString)

Evaluate the contents of the input source file in the global scope of module m. Every module (except those defined with baremodule) has its own definition of include omitting the m argument, which evaluates the file in that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to include will search relative to that path. This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files.

The optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in path, the include function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.

Julia 1.5

Julia 1.5 is required for passing the mapexpr argument.

source
includeFunction
include([mapexpr::Function,] path::AbstractString)

Evaluate the contents of the input source file in the global scope of the containing module. Every module (except those defined with baremodule) has its own definition of include, which evaluates the file in that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to include will search relative to that path. This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files. The argument path is normalized using normpath which will resolve relative path tokens such as .. and convert / to the appropriate path separator.

The optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in path, the include function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.

Use Base.include to evaluate a file into another module.

Julia 1.5

Julia 1.5 is required for passing the mapexpr argument.

source
Base.include_stringFunction
include_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString="string")

Like include, except reads code from the given string rather than from a file.

The optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in code, the include_string function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.

Julia 1.5

Julia 1.5 is required for passing the mapexpr argument.

source
Base.include_dependencyFunction
include_dependency(path::AbstractString; track_content::Bool=false)

In a module, declare that the file, directory, or symbolic link specified by path (relative or absolute) is a dependency for precompilation; that is, the module will need to be recompiled if the modification time mtime of path changes. If track_content=true recompilation is triggered when the content of path changes (if path is a directory the content equals join(readdir(path))).

This is only needed if your module depends on a path that is not used via include. It has no effect outside of compilation.

Julia 1.11

Keyword argument track_content requires at least Julia 1.11.

source
__init__Keyword
__init__

The __init__() function in a module executes immediately after the module is loaded at runtime for the first time. It is called once, after all other statements in the module have been executed. Because it is called after fully importing the module, __init__ functions of submodules will be executed first. Two typical uses of __init__ are calling runtime initialization functions of external C libraries and initializing global constants that involve pointers returned by external libraries. See the manual section about modules for more details.

Examples

const foo_data_ptr = Ref{Ptr{Cvoid}}(0)
 function __init__()
     ccall((:foo_init, :libfoo), Cvoid, ())
     foo_data_ptr[] = ccall((:foo_data, :libfoo), Ptr{Cvoid}, ())
     nothing
-end
source
Base.whichMethod
which(f, types)

Returns the method of f (a Method object) that would be called for arguments of the given types.

If types is an abstract type, then the method that would be called by invoke is returned.

See also: parentmodule, @which, and @edit.

source
Base.methodsFunction
methods(f, [types], [module])

Return the method table for f.

If types is specified, return an array of methods whose types match. If module is specified, return an array of methods defined in that module. A list of modules can also be specified as an array.

Julia 1.4

At least Julia 1.4 is required for specifying a module.

See also: which, @which and methodswith.

source
Base.@showMacro
@show exs...

Prints one or more expressions, and their results, to stdout, and returns the last result.

See also: show, @info, println.

Examples

julia> x = @show 1+2
+end
source
Base.whichMethod
which(f, types)

Returns the method of f (a Method object) that would be called for arguments of the given types.

If types is an abstract type, then the method that would be called by invoke is returned.

See also: parentmodule, @which, and @edit.

source
Base.methodsFunction
methods(f, [types], [module])

Return the method table for f.

If types is specified, return an array of methods whose types match. If module is specified, return an array of methods defined in that module. A list of modules can also be specified as an array.

Julia 1.4

At least Julia 1.4 is required for specifying a module.

See also: which, @which and methodswith.

source
Base.@showMacro
@show exs...

Prints one or more expressions, and their results, to stdout, and returns the last result.

See also: show, @info, println.

Examples

julia> x = @show 1+2
 1 + 2 = 3
 3
 
 julia> @show x^2 x/2;
 x ^ 2 = 9
-x / 2 = 1.5
source
Base.MainInclude.ansConstant
ans

A variable referring to the last computed value, automatically imported to the interactive prompt.

source
Base.MainInclude.errConstant
err

A variable referring to the last thrown errors, automatically imported to the interactive prompt. The thrown errors are collected in a stack of exceptions.

source

Keywords

This is the list of reserved keywords in Julia: baremodule, begin, break, catch, const, continue, do, else, elseif, end, export, false, finally, for, function, global, if, import, let, local, macro, module, quote, return, struct, true, try, using, while. Those keywords are not allowed to be used as variable names.

The following two-word sequences are reserved: abstract type, mutable struct, primitive type. However, you can create variables with names: abstract, mutable, primitive and type.

Finally: where is parsed as an infix operator for writing parametric method and type definitions; in and isa are parsed as infix operators; public is parsed as a keyword when beginning a toplevel statement; outer is parsed as a keyword when used to modify the scope of a variable in an iteration specification of a for loop; and as is used as a keyword to rename an identifier brought into scope by import or using. Creation of variables named where, in, isa, outer and as is allowed, though.

moduleKeyword
module

module declares a Module, which is a separate global variable workspace. Within a module, you can control which names from other modules are visible (via importing), and specify which of your names are intended to be public (via export and public). Modules allow you to create top-level definitions without worrying about name conflicts when your code is used together with somebody else’s. See the manual section about modules for more details.

Examples

module Foo
+x / 2 = 1.5
source
Base.MainInclude.ansConstant
ans

A variable referring to the last computed value, automatically imported to the interactive prompt.

source
Base.MainInclude.errConstant
err

A variable referring to the last thrown errors, automatically imported to the interactive prompt. The thrown errors are collected in a stack of exceptions.

source

Keywords

This is the list of reserved keywords in Julia: baremodule, begin, break, catch, const, continue, do, else, elseif, end, export, false, finally, for, function, global, if, import, let, local, macro, module, quote, return, struct, true, try, using, while. Those keywords are not allowed to be used as variable names.

The following two-word sequences are reserved: abstract type, mutable struct, primitive type. However, you can create variables with names: abstract, mutable, primitive and type.

Finally: where is parsed as an infix operator for writing parametric method and type definitions; in and isa are parsed as infix operators; public is parsed as a keyword when beginning a toplevel statement; outer is parsed as a keyword when used to modify the scope of a variable in an iteration specification of a for loop; and as is used as a keyword to rename an identifier brought into scope by import or using. Creation of variables named where, in, isa, outer and as is allowed, though.

moduleKeyword
module

module declares a Module, which is a separate global variable workspace. Within a module, you can control which names from other modules are visible (via importing), and specify which of your names are intended to be public (via export and public). Modules allow you to create top-level definitions without worrying about name conflicts when your code is used together with somebody else’s. See the manual section about modules for more details.

Examples

module Foo
 import Base.show
 export MyType, foo
 
@@ -32,7 +32,7 @@
 bar(x) = 2x
 foo(a::MyType) = bar(a.x) + 1
 show(io::IO, a::MyType) = print(io, "MyType $(a.x)")
-end
source
exportKeyword
export

export is used within modules to tell Julia which names should be made available to the user. For example: export foo makes the name foo available when using the module. See the manual section about modules for details.

source
publicKeyword
public

public is used within modules to tell Julia which names are part of the public API of the module. For example: public foo indicates that the name foo is public, without making it available when using the module.

As export already indicates that a name is public, it is unnecessary and an error to declare a name both as public and as exported. See the manual section about modules for details.

Julia 1.11

The public keyword was added in Julia 1.11. Prior to this the notion of publicness was less explicit.

source
importKeyword
import

import Foo will load the module or package Foo. Names from the imported Foo module can be accessed with dot syntax (e.g. Foo.foo to access the name foo). See the manual section about modules for details.

source
usingKeyword
using

using Foo will load the module or package Foo and make its exported names available for direct use. Names can also be used via dot syntax (e.g. Foo.foo to access the name foo), whether they are exported or not. See the manual section about modules for details.

source
asKeyword
as

as is used as a keyword to rename an identifier brought into scope by import or using, for the purpose of working around name conflicts as well as for shortening names. (Outside of import or using statements, as is not a keyword and can be used as an ordinary identifier.)

import LinearAlgebra as LA brings the imported LinearAlgebra standard library into scope as LA.

import LinearAlgebra: eigen as eig, cholesky as chol brings the eigen and cholesky methods from LinearAlgebra into scope as eig and chol respectively.

as works with using only when individual identifiers are brought into scope. For example, using LinearAlgebra: eigen as eig or using LinearAlgebra: eigen as eig, cholesky as chol works, but using LinearAlgebra as LA is invalid syntax, since it is nonsensical to rename all exported names from LinearAlgebra to LA.

source
baremoduleKeyword
baremodule

baremodule declares a module that does not contain using Base or local definitions of eval and include. It does still import Core. In other words,

module Mod
+end
source
exportKeyword
export

export is used within modules to tell Julia which names should be made available to the user. For example: export foo makes the name foo available when using the module. See the manual section about modules for details.

source
publicKeyword
public

public is used within modules to tell Julia which names are part of the public API of the module. For example: public foo indicates that the name foo is public, without making it available when using the module.

As export already indicates that a name is public, it is unnecessary and an error to declare a name both as public and as exported. See the manual section about modules for details.

Julia 1.11

The public keyword was added in Julia 1.11. Prior to this the notion of publicness was less explicit.

source
importKeyword
import

import Foo will load the module or package Foo. Names from the imported Foo module can be accessed with dot syntax (e.g. Foo.foo to access the name foo). See the manual section about modules for details.

source
usingKeyword
using

using Foo will load the module or package Foo and make its exported names available for direct use. Names can also be used via dot syntax (e.g. Foo.foo to access the name foo), whether they are exported or not. See the manual section about modules for details.

source
asKeyword
as

as is used as a keyword to rename an identifier brought into scope by import or using, for the purpose of working around name conflicts as well as for shortening names. (Outside of import or using statements, as is not a keyword and can be used as an ordinary identifier.)

import LinearAlgebra as LA brings the imported LinearAlgebra standard library into scope as LA.

import LinearAlgebra: eigen as eig, cholesky as chol brings the eigen and cholesky methods from LinearAlgebra into scope as eig and chol respectively.

as works with using only when individual identifiers are brought into scope. For example, using LinearAlgebra: eigen as eig or using LinearAlgebra: eigen as eig, cholesky as chol works, but using LinearAlgebra as LA is invalid syntax, since it is nonsensical to rename all exported names from LinearAlgebra to LA.

source
baremoduleKeyword
baremodule

baremodule declares a module that does not contain using Base or local definitions of eval and include. It does still import Core. In other words,

module Mod
 
 ...
 
@@ -45,9 +45,9 @@
 
 ...
 
-end
source
functionKeyword
function

Functions are defined with the function keyword:

function add(a, b)
+end
source
functionKeyword
function

Functions are defined with the function keyword:

function add(a, b)
     return a + b
-end

Or the short form notation:

add(a, b) = a + b

The use of the return keyword is exactly the same as in other languages, but is often optional. A function without an explicit return statement will return the last expression in the function body.

source
macroKeyword
macro

macro defines a method for inserting generated code into a program. A macro maps a sequence of argument expressions to a returned expression, and the resulting expression is substituted directly into the program at the point where the macro is invoked. Macros are a way to run generated code without calling eval, since the generated code instead simply becomes part of the surrounding program. Macro arguments may include expressions, literal values, and symbols. Macros can be defined for variable number of arguments (varargs), but do not accept keyword arguments. Every macro also implicitly gets passed the arguments __source__, which contains the line number and file name the macro is called from, and __module__, which is the module the macro is expanded in.

See the manual section on Metaprogramming for more information about how to write a macro.

Examples

julia> macro sayhello(name)
+end

Or the short form notation:

add(a, b) = a + b

The use of the return keyword is exactly the same as in other languages, but is often optional. A function without an explicit return statement will return the last expression in the function body.

source
macroKeyword
macro

macro defines a method for inserting generated code into a program. A macro maps a sequence of argument expressions to a returned expression, and the resulting expression is substituted directly into the program at the point where the macro is invoked. Macros are a way to run generated code without calling eval, since the generated code instead simply becomes part of the surrounding program. Macro arguments may include expressions, literal values, and symbols. Macros can be defined for variable number of arguments (varargs), but do not accept keyword arguments. Every macro also implicitly gets passed the arguments __source__, which contains the line number and file name the macro is called from, and __module__, which is the module the macro is expanded in.

See the manual section on Metaprogramming for more information about how to write a macro.

Examples

julia> macro sayhello(name)
            return :( println("Hello, ", $name, "!") )
        end
 @sayhello (macro with 1 method)
@@ -61,7 +61,7 @@
 @saylots (macro with 1 method)
 
 julia> @saylots "hey " "there " "friend"
-Say: hey there friend
source
returnKeyword
return

return x causes the enclosing function to exit early, passing the given value x back to its caller. return by itself with no value is equivalent to return nothing (see nothing).

function compare(a, b)
+Say: hey there friend
source
returnKeyword
return

return x causes the enclosing function to exit early, passing the given value x back to its caller. return by itself with no value is equivalent to return nothing (see nothing).

function compare(a, b)
     a == b && return "equal to"
     a < b ? "less than" : "greater than"
 end

In general you can place a return statement anywhere within a function body, including within deeply nested loops or conditionals, but be careful with do blocks. For example:

function test1(xs)
@@ -75,11 +75,11 @@
         iseven(x) && return 2x
         x
     end
-end

In the first example, the return breaks out of test1 as soon as it hits an even number, so test1([5,6,7]) returns 12.

You might expect the second example to behave the same way, but in fact the return there only breaks out of the inner function (inside the do block) and gives a value back to map. test2([5,6,7]) then returns [5,12,7].

When used in a top-level expression (i.e. outside any function), return causes the entire current top-level expression to terminate early.

source
doKeyword
do

Create an anonymous function and pass it as the first argument to a function call. For example:

map(1:10) do x
+end

In the first example, the return breaks out of test1 as soon as it hits an even number, so test1([5,6,7]) returns 12.

You might expect the second example to behave the same way, but in fact the return there only breaks out of the inner function (inside the do block) and gives a value back to map. test2([5,6,7]) then returns [5,12,7].

When used in a top-level expression (i.e. outside any function), return causes the entire current top-level expression to terminate early.

source
doKeyword
do

Create an anonymous function and pass it as the first argument to a function call. For example:

map(1:10) do x
     2x
 end

is equivalent to map(x->2x, 1:10).

Use multiple arguments like so:

map(1:10, 11:20) do x, y
     x + y
-end
source
beginKeyword
begin

begin...end denotes a block of code.

begin
+end
source
beginKeyword
begin

begin...end denotes a block of code.

begin
     println("Hello, ")
     println("World!")
 end

Usually begin will not be necessary, since keywords such as function and let implicitly begin blocks of code. See also ;.

begin may also be used when indexing to represent the first index of a collection or the first index of a dimension of an array.

Examples

julia> A = [1 2; 3 4]
@@ -90,7 +90,7 @@
 julia> A[begin, :]
 2-element Array{Int64,1}:
  1
- 2
source
endKeyword
end

end marks the conclusion of a block of expressions, for example module, struct, mutable struct, begin, let, for etc.

end may also be used when indexing to represent the last index of a collection or the last index of a dimension of an array.

Examples

julia> A = [1 2; 3 4]
+ 2
source
endKeyword
end

end marks the conclusion of a block of expressions, for example module, struct, mutable struct, begin, let, for etc.

end may also be used when indexing to represent the last index of a collection or the last index of a dimension of an array.

Examples

julia> A = [1 2; 3 4]
 2×2 Array{Int64, 2}:
  1  2
  3  4
@@ -98,7 +98,7 @@
 julia> A[end, :]
 2-element Array{Int64, 1}:
  3
- 4
source
letKeyword
let

let blocks create a new hard scope and optionally introduce new local bindings.

Just like the other scope constructs, let blocks define the block of code where newly introduced local variables are accessible. Additionally, the syntax has a special meaning for comma-separated assignments and variable names that may optionally appear on the same line as the let:

let var1 = value1, var2, var3 = value3
+ 4
source
letKeyword
let

let blocks create a new hard scope and optionally introduce new local bindings.

Just like the other scope constructs, let blocks define the block of code where newly introduced local variables are accessible. Additionally, the syntax has a special meaning for comma-separated assignments and variable names that may optionally appear on the same line as the let:

let var1 = value1, var2, var3 = value3
     code
 end

The variables introduced on this line are local to the let block and the assignments are evaluated in order, with each right-hand side evaluated in the scope without considering the name on the left-hand side. Therefore it makes sense to write something like let x = x, since the two x variables are distinct with the left-hand side locally shadowing the x from the outer scope. This can even be a useful idiom as new local variables are freshly created each time local scopes are entered, but this is only observable in the case of variables that outlive their scope via closures. A let variable without an assignment, such as var2 in the example above, declares a new local variable that is not yet bound to a value.

By contrast, begin blocks also group multiple expressions together but do not introduce scope or have the special assignment syntax.

Examples

In the function below, there is a single x that is iteratively updated three times by the map. The closures returned all reference that one x at its final value:

julia> function test_outer_x()
            x = 0
@@ -139,19 +139,19 @@
 3-element Vector{Int64}:
  1
  2
- 3
source
ifKeyword
if/elseif/else

if/elseif/else performs conditional evaluation, which allows portions of code to be evaluated or not evaluated depending on the value of a boolean expression. Here is the anatomy of the if/elseif/else conditional syntax:

if x < y
+ 3
source
ifKeyword
if/elseif/else

if/elseif/else performs conditional evaluation, which allows portions of code to be evaluated or not evaluated depending on the value of a boolean expression. Here is the anatomy of the if/elseif/else conditional syntax:

if x < y
     println("x is less than y")
 elseif x > y
     println("x is greater than y")
 else
     println("x is equal to y")
 end

If the condition expression x < y is true, then the corresponding block is evaluated; otherwise the condition expression x > y is evaluated, and if it is true, the corresponding block is evaluated; if neither expression is true, the else block is evaluated. The elseif and else blocks are optional, and as many elseif blocks as desired can be used.

In contrast to some other languages conditions must be of type Bool. It does not suffice for conditions to be convertible to Bool.

julia> if 1 end
-ERROR: TypeError: non-boolean (Int64) used in boolean context
source
forKeyword
for

for loops repeatedly evaluate a block of statements while iterating over a sequence of values.

The iteration variable is always a new variable, even if a variable of the same name exists in the enclosing scope. Use outer to reuse an existing local variable for iteration.

Examples

julia> for i in [1, 4, 0]
+ERROR: TypeError: non-boolean (Int64) used in boolean context
source
forKeyword
for

for loops repeatedly evaluate a block of statements while iterating over a sequence of values.

The iteration variable is always a new variable, even if a variable of the same name exists in the enclosing scope. Use outer to reuse an existing local variable for iteration.

Examples

julia> for i in [1, 4, 0]
            println(i)
        end
 1
 4
-0
source
whileKeyword
while

while loops repeatedly evaluate a conditional expression, and continue evaluating the body of the while loop as long as the expression remains true. If the condition expression is false when the while loop is first reached, the body is never evaluated.

Examples

julia> i = 1
+0
source
whileKeyword
while

while loops repeatedly evaluate a conditional expression, and continue evaluating the body of the while loop as long as the expression remains true. If the condition expression is false when the while loop is first reached, the body is never evaluated.

Examples

julia> i = 1
 1
 
 julia> while i < 5
@@ -161,7 +161,7 @@
 1
 2
 3
-4
source
breakKeyword
break

Break out of a loop immediately.

Examples

julia> i = 0
+4
source
breakKeyword
break

Break out of a loop immediately.

Examples

julia> i = 0
 0
 
 julia> while true
@@ -173,13 +173,13 @@
 2
 3
 4
-5
source
continueKeyword
continue

Skip the rest of the current loop iteration.

Examples

julia> for i = 1:6
+5
source
continueKeyword
continue

Skip the rest of the current loop iteration.

Examples

julia> for i = 1:6
            iseven(i) && continue
            println(i)
        end
 1
 3
-5
source
tryKeyword
try/catch

A try/catch statement allows intercepting errors (exceptions) thrown by throw so that program execution can continue. For example, the following code attempts to write a file, but warns the user and proceeds instead of terminating execution if the file cannot be written:

try
+5
source
tryKeyword
try/catch

A try/catch statement allows intercepting errors (exceptions) thrown by throw so that program execution can continue. For example, the following code attempts to write a file, but warns the user and proceeds instead of terminating execution if the file cannot be written:

try
     open("/danger", "w") do f
         println(f, "Hello")
     end
@@ -191,16 +191,16 @@
     end
 catch
     @warn "File not found."
-end

The syntax catch e (where e is any variable) assigns the thrown exception object to the given variable within the catch block.

The power of the try/catch construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions.

source
finallyKeyword
finally

Run some code when a given block of code exits, regardless of how it exits. For example, here is how we can guarantee that an opened file is closed:

f = open("file")
+end

The syntax catch e (where e is any variable) assigns the thrown exception object to the given variable within the catch block.

The power of the try/catch construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions.

source
finallyKeyword
finally

Run some code when a given block of code exits, regardless of how it exits. For example, here is how we can guarantee that an opened file is closed:

f = open("file")
 try
     operate_on_file(f)
 finally
     close(f)
-end

When control leaves the try block (for example, due to a return, or just finishing normally), close(f) will be executed. If the try block exits due to an exception, the exception will continue propagating. A catch block may be combined with try and finally as well. In this case the finally block will run after catch has handled the error.

source
quoteKeyword
quote

quote creates multiple expression objects in a block without using the explicit Expr constructor. For example:

ex = quote
+end

When control leaves the try block (for example, due to a return, or just finishing normally), close(f) will be executed. If the try block exits due to an exception, the exception will continue propagating. A catch block may be combined with try and finally as well. In this case the finally block will run after catch has handled the error.

source
quoteKeyword
quote

quote creates multiple expression objects in a block without using the explicit Expr constructor. For example:

ex = quote
     x = 1
     y = 2
     x + y
-end

Unlike the other means of quoting, :( ... ), this form introduces QuoteNode elements to the expression tree, which must be considered when directly manipulating the tree. For other purposes, :( ... ) and quote .. end blocks are treated identically.

source
localKeyword
local

local introduces a new local variable. See the manual section on variable scoping for more information.

Examples

julia> function foo(n)
+end

Unlike the other means of quoting, :( ... ), this form introduces QuoteNode elements to the expression tree, which must be considered when directly manipulating the tree. For other purposes, :( ... ) and quote .. end blocks are treated identically.

source
localKeyword
local

local introduces a new local variable. See the manual section on variable scoping for more information.

Examples

julia> function foo(n)
            x = 0
            for i = 1:n
                local x # introduce a loop-local x
@@ -211,7 +211,7 @@
 foo (generic function with 1 method)
 
 julia> foo(10)
-0
source
globalKeyword
global

global x makes x in the current scope and its inner scopes refer to the global variable of that name. See the manual section on variable scoping for more information.

Examples

julia> z = 3
 3
 
 julia> function foo()
@@ -223,7 +223,7 @@
 6
 
 julia> z
-6
source
outerKeyword
for outer

Reuse an existing local variable for iteration in a for loop.

See the manual section on variable scoping for more information.

See also for.

Examples

julia> function f()
            i = 0
            for i = 1:3
                # empty
@@ -245,7 +245,7 @@
        for outer i = 1:3
        end
 ERROR: syntax: no outer local variable declaration exists for "for outer"
-[...]
source
constKeyword
const

const is used to declare global variables whose values will not change. In almost all code (and particularly performance sensitive code) global variables should be declared constant in this way.

const x = 5

Multiple variables can be declared within a single const:

const y, z = 7, 11

Note that const only applies to one = operation, therefore const x = y = 1 declares x to be constant but not y. On the other hand, const x = const y = 1 declares both x and y constant.

Note that "constant-ness" does not extend into mutable containers; only the association between a variable and its value is constant. If x is an array or dictionary (for example) you can still modify, add, or remove elements.

In some cases changing the value of a const variable gives a warning instead of an error. However, this can produce unpredictable behavior or corrupt the state of your program, and so should be avoided. This feature is intended only for convenience during interactive use.

source
structKeyword
struct

The most commonly used kind of type in Julia is a struct, specified as a name and a set of fields.

struct Point
+[...]
source
constKeyword
const

const is used to declare global variables whose values will not change. In almost all code (and particularly performance sensitive code) global variables should be declared constant in this way.

const x = 5

Multiple variables can be declared within a single const:

const y, z = 7, 11

Note that const only applies to one = operation, therefore const x = y = 1 declares x to be constant but not y. On the other hand, const x = const y = 1 declares both x and y constant.

Note that "constant-ness" does not extend into mutable containers; only the association between a variable and its value is constant. If x is an array or dictionary (for example) you can still modify, add, or remove elements.

In some cases changing the value of a const variable gives a warning instead of an error. However, this can produce unpredictable behavior or corrupt the state of your program, and so should be avoided. This feature is intended only for convenience during interactive use.

source
structKeyword
struct

The most commonly used kind of type in Julia is a struct, specified as a name and a set of fields.

struct Point
     x
     y
 end

Fields can have type restrictions, which may be parameterized:

struct Point{X}
@@ -254,7 +254,7 @@
 end

A struct can also declare an abstract super type via <: syntax:

struct Point <: AbstractPoint
     x
     y
-end

structs are immutable by default; an instance of one of these types cannot be modified after construction. Use mutable struct instead to declare a type whose instances can be modified.

See the manual section on Composite Types for more details, such as how to define constructors.

source
mutable structKeyword
mutable struct

mutable struct is similar to struct, but additionally allows the fields of the type to be set after construction. See the manual section on Composite Types for more information.

source
Base.@kwdefMacro
@kwdef typedef

This is a helper macro that automatically defines a keyword-based constructor for the type declared in the expression typedef, which must be a struct or mutable struct expression. The default argument is supplied by declaring fields of the form field::T = default or field = default. If no default is provided then the keyword argument becomes a required keyword argument in the resulting type constructor.

Inner constructors can still be defined, but at least one should accept arguments in the same form as the default inner constructor (i.e. one positional argument per field) in order to function correctly with the keyword outer constructor.

Julia 1.1

Base.@kwdef for parametric structs, and structs with supertypes requires at least Julia 1.1.

Julia 1.9

This macro is exported as of Julia 1.9.

Examples

julia> @kwdef struct Foo
+end

structs are immutable by default; an instance of one of these types cannot be modified after construction. Use mutable struct instead to declare a type whose instances can be modified.

See the manual section on Composite Types for more details, such as how to define constructors.

source
mutable structKeyword
mutable struct

mutable struct is similar to struct, but additionally allows the fields of the type to be set after construction. See the manual section on Composite Types for more information.

source
Base.@kwdefMacro
@kwdef typedef

This is a helper macro that automatically defines a keyword-based constructor for the type declared in the expression typedef, which must be a struct or mutable struct expression. The default argument is supplied by declaring fields of the form field::T = default or field = default. If no default is provided then the keyword argument becomes a required keyword argument in the resulting type constructor.

Inner constructors can still be defined, but at least one should accept arguments in the same form as the default inner constructor (i.e. one positional argument per field) in order to function correctly with the keyword outer constructor.

Julia 1.1

Base.@kwdef for parametric structs, and structs with supertypes requires at least Julia 1.1.

Julia 1.9

This macro is exported as of Julia 1.9.

Examples

julia> @kwdef struct Foo
            a::Int = 1         # specified default
            b::String          # required keyword
        end
@@ -266,10 +266,10 @@
 julia> Foo()
 ERROR: UndefKeywordError: keyword argument `b` not assigned
 Stacktrace:
-[...]
source
abstract typeKeyword
abstract type

abstract type declares a type that cannot be instantiated, and serves only as a node in the type graph, thereby describing sets of related concrete types: those concrete types which are their descendants. Abstract types form the conceptual hierarchy which makes Julia’s type system more than just a collection of object implementations. For example:

abstract type Number end
-abstract type Real <: Number end

Number has no supertype, whereas Real is an abstract subtype of Number.

source
primitive typeKeyword
primitive type

primitive type declares a concrete type whose data consists only of a series of bits. Classic examples of primitive types are integers and floating-point values. Some example built-in primitive type declarations:

primitive type Char 32 end
-primitive type Bool <: Integer 8 end

The number after the name indicates how many bits of storage the type requires. Currently, only sizes that are multiples of 8 bits are supported. The Bool declaration shows how a primitive type can be optionally declared to be a subtype of some supertype.

source
whereKeyword
where

The where keyword creates a type that is an iterated union of other types, over all values of some variable. For example Vector{T} where T<:Real includes all Vectors where the element type is some kind of Real number.

The variable bound defaults to Any if it is omitted:

Vector{T} where T    # short for `where T<:Any`

Variables can also have lower bounds:

Vector{T} where T>:Int
-Vector{T} where Int<:T<:Real

There is also a concise syntax for nested where expressions. For example, this:

Pair{T, S} where S<:Array{T} where T<:Number

can be shortened to:

Pair{T, S} where {T<:Number, S<:Array{T}}

This form is often found on method signatures.

Note that in this form, the variables are listed outermost-first. This matches the order in which variables are substituted when a type is "applied" to parameter values using the syntax T{p1, p2, ...}.

source
...Keyword
...

The "splat" operator, ..., represents a sequence of arguments. ... can be used in function definitions, to indicate that the function accepts an arbitrary number of arguments. ... can also be used to apply a function to a sequence of arguments.

Examples

julia> add(xs...) = reduce(+, xs)
+[...]
source
abstract typeKeyword
abstract type

abstract type declares a type that cannot be instantiated, and serves only as a node in the type graph, thereby describing sets of related concrete types: those concrete types which are their descendants. Abstract types form the conceptual hierarchy which makes Julia’s type system more than just a collection of object implementations. For example:

abstract type Number end
+abstract type Real <: Number end

Number has no supertype, whereas Real is an abstract subtype of Number.

source
primitive typeKeyword
primitive type

primitive type declares a concrete type whose data consists only of a series of bits. Classic examples of primitive types are integers and floating-point values. Some example built-in primitive type declarations:

primitive type Char 32 end
+primitive type Bool <: Integer 8 end

The number after the name indicates how many bits of storage the type requires. Currently, only sizes that are multiples of 8 bits are supported. The Bool declaration shows how a primitive type can be optionally declared to be a subtype of some supertype.

source
whereKeyword
where

The where keyword creates a type that is an iterated union of other types, over all values of some variable. For example Vector{T} where T<:Real includes all Vectors where the element type is some kind of Real number.

The variable bound defaults to Any if it is omitted:

Vector{T} where T    # short for `where T<:Any`

Variables can also have lower bounds:

Vector{T} where T>:Int
+Vector{T} where Int<:T<:Real

There is also a concise syntax for nested where expressions. For example, this:

Pair{T, S} where S<:Array{T} where T<:Number

can be shortened to:

Pair{T, S} where {T<:Number, S<:Array{T}}

This form is often found on method signatures.

Note that in this form, the variables are listed outermost-first. This matches the order in which variables are substituted when a type is "applied" to parameter values using the syntax T{p1, p2, ...}.

source
...Keyword
...

The "splat" operator, ..., represents a sequence of arguments. ... can be used in function definitions, to indicate that the function accepts an arbitrary number of arguments. ... can also be used to apply a function to a sequence of arguments.

Examples

julia> add(xs...) = reduce(+, xs)
 add (generic function with 1 method)
 
 julia> add(1, 2, 3, 4, 5)
@@ -279,7 +279,7 @@
 6
 
 julia> add(7, 1:100..., 1000:1100...)
-111107
source
;Keyword
;

; has a similar role in Julia as in many C-like languages, and is used to delimit the end of the previous statement.

; is not necessary at the end of a line, but can be used to separate statements on a single line or to join statements into a single expression.

Adding ; at the end of a line in the REPL will suppress printing the result of that expression.

In function declarations, and optionally in calls, ; separates regular arguments from keywords.

In array literals, arguments separated by semicolons have their contents concatenated together. A separator made of a single ; concatenates vertically (i.e. along the first dimension), ;; concatenates horizontally (second dimension), ;;; concatenates along the third dimension, etc. Such a separator can also be used in last position in the square brackets to add trailing dimensions of length 1.

A ; in first position inside of parentheses can be used to construct a named tuple. The same (; ...) syntax on the left side of an assignment allows for property destructuring.

In the standard REPL, typing ; on an empty line will switch to shell mode.

Examples

julia> function foo()
+111107
source
;Keyword
;

; has a similar role in Julia as in many C-like languages, and is used to delimit the end of the previous statement.

; is not necessary at the end of a line, but can be used to separate statements on a single line or to join statements into a single expression.

Adding ; at the end of a line in the REPL will suppress printing the result of that expression.

In function declarations, and optionally in calls, ; separates regular arguments from keywords.

In array literals, arguments separated by semicolons have their contents concatenated together. A separator made of a single ; concatenates vertically (i.e. along the first dimension), ;; concatenates horizontally (second dimension), ;;; concatenates along the third dimension, etc. Such a separator can also be used in last position in the square brackets to add trailing dimensions of length 1.

A ; in first position inside of parentheses can be used to construct a named tuple. The same (; ...) syntax on the left side of an assignment allows for property destructuring.

In the standard REPL, typing ; on an empty line will switch to shell mode.

Examples

julia> function foo()
            x = "Hello, "; x *= "World!"
            return x
        end
@@ -333,7 +333,7 @@
 
 julia> ; # upon typing ;, the prompt changes (in place) to: shell>
 shell> echo hello
-hello
source
=Keyword
=

= is the assignment operator.

  • For variable a and expression b, a = b makes a refer to the value of b.
  • For functions f(x), f(x) = x defines a new function constant f, or adds a new method to f if f is already defined; this usage is equivalent to function f(x); x; end.
  • a[i] = v calls setindex!(a,v,i).
  • a.b = c calls setproperty!(a,:b,c).
  • Inside a function call, f(a=b) passes b as the value of keyword argument a.
  • Inside parentheses with commas, (a=1,) constructs a NamedTuple.

Examples

Assigning a to b does not create a copy of b; instead use copy or deepcopy.

julia> b = [1]; a = b; b[1] = 2; a
+hello
source
=Keyword
=

= is the assignment operator.

  • For variable a and expression b, a = b makes a refer to the value of b.
  • For functions f(x), f(x) = x defines a new function constant f, or adds a new method to f if f is already defined; this usage is equivalent to function f(x); x; end.
  • a[i] = v calls setindex!(a,v,i).
  • a.b = c calls setproperty!(a,:b,c).
  • Inside a function call, f(a=b) passes b as the value of keyword argument a.
  • Inside parentheses with commas, (a=1,) constructs a NamedTuple.

Examples

Assigning a to b does not create a copy of b; instead use copy or deepcopy.

julia> b = [1]; a = b; b[1] = 2; a
 1-element Array{Int64, 1}:
  2
 
@@ -378,11 +378,11 @@
 2-element Array{Int64, 1}:
  2
  3
-
source
?:Keyword
a ? b : c

Short form for conditionals; read "if a, evaluate b otherwise evaluate c". Also known as the ternary operator.

This syntax is equivalent to if a; b else c end, but is often used to emphasize the value b-or-c which is being used as part of a larger expression, rather than the side effects that evaluating b or c may have.

See the manual section on control flow for more details.

Examples

julia> x = 1; y = 2;
+
source
?:Keyword
a ? b : c

Short form for conditionals; read "if a, evaluate b otherwise evaluate c". Also known as the ternary operator.

This syntax is equivalent to if a; b else c end, but is often used to emphasize the value b-or-c which is being used as part of a larger expression, rather than the side effects that evaluating b or c may have.

See the manual section on control flow for more details.

Examples

julia> x = 1; y = 2;
 
 julia> x > y ? println("x is larger") : println("y is larger")
-y is larger
source

Standard Modules

MainModule
Main

Main is the top-level module, and Julia starts with Main set as the current module. Variables defined at the prompt go in Main, and varinfo lists variables in Main.

julia> @__MODULE__
-Main
source
CoreModule
Core

Core is the module that contains all identifiers considered "built in" to the language, i.e. part of the core language and not libraries. Every module implicitly specifies using Core, since you can't do anything without those definitions.

source
BaseModule
Base

The base library of Julia. Base is a module that contains basic functionality (the contents of base/). All modules implicitly contain using Base, since this is needed in the vast majority of cases.

source

Base Submodules

Base.DocsModule
Docs

The Docs module provides the @doc macro which can be used to set and retrieve documentation metadata for Julia objects.

Please see the manual section on documentation for more information.

source
Base.StackTracesModule

Tools for collecting and manipulating stack traces. Mainly used for building errors.

source
Base.SysModule

Provide methods for retrieving information about hardware and the operating system.

source
Base.GCModule
Base.GC

Module with garbage collection utilities.

source

All Objects

Standard Modules

MainModule
Main

Main is the top-level module, and Julia starts with Main set as the current module. Variables defined at the prompt go in Main, and varinfo lists variables in Main.

julia> @__MODULE__
+Main
source
CoreModule
Core

Core is the module that contains all identifiers considered "built in" to the language, i.e. part of the core language and not libraries. Every module implicitly specifies using Core, since you can't do anything without those definitions.

source
BaseModule
Base

The base library of Julia. Base is a module that contains basic functionality (the contents of base/). All modules implicitly contain using Base, since this is needed in the vast majority of cases.

source

Base Submodules

Base.DocsModule
Docs

The Docs module provides the @doc macro which can be used to set and retrieve documentation metadata for Julia objects.

Please see the manual section on documentation for more information.

source
Base.StackTracesModule

Tools for collecting and manipulating stack traces. Mainly used for building errors.

source
Base.SysModule

Provide methods for retrieving information about hardware and the operating system.

source
Base.GCModule
Base.GC

Module with garbage collection utilities.

source

All Objects

Core.:===Function
===(x,y) -> Bool
 ≡(x,y) -> Bool

Determine whether x and y are identical, in the sense that no program could distinguish them. First the types of x and y are compared. If those are identical, mutable objects are compared by address in memory and immutable objects (such as numbers) are compared by contents at the bit level. This function is sometimes called "egal". It always returns a Bool value.

Examples

julia> a = [1, 2]; b = [1, 2];
 
 julia> a == b
@@ -392,7 +392,7 @@
 false
 
 julia> a === a
-true
source
Core.isaFunction
isa(x, type) -> Bool

Determine whether x is of the given type. Can also be used as an infix operator, e.g. x isa type.

Examples

julia> isa(1, Int)
+true
source
Core.isaFunction
isa(x, type) -> Bool

Determine whether x is of the given type. Can also be used as an infix operator, e.g. x isa type.

Examples

julia> isa(1, Int)
 true
 
 julia> isa(1, Matrix)
@@ -405,7 +405,7 @@
 true
 
 julia> 1 isa Number
-true
source
Base.isequalFunction
isequal(x, y) -> Bool

Similar to ==, except for the treatment of floating point numbers and of missing values. isequal treats all floating-point NaN values as equal to each other, treats -0.0 as unequal to 0.0, and missing as equal to missing. Always returns a Bool value.

isequal is an equivalence relation - it is reflexive (=== implies isequal), symmetric (isequal(a, b) implies isequal(b, a)) and transitive (isequal(a, b) and isequal(b, c) implies isequal(a, c)).

Implementation

The default implementation of isequal calls ==, so a type that does not involve floating-point values generally only needs to define ==.

isequal is the comparison function used by hash tables (Dict). isequal(x,y) must imply that hash(x) == hash(y).

This typically means that types for which a custom == or isequal method exists must implement a corresponding hash method (and vice versa). Collections typically implement isequal by calling isequal recursively on all contents.

Furthermore, isequal is linked with isless, and they work together to define a fixed total ordering, where exactly one of isequal(x, y), isless(x, y), or isless(y, x) must be true (and the other two false).

Scalar types generally do not need to implement isequal separate from ==, unless they represent floating-point numbers amenable to a more efficient implementation than that provided as a generic fallback (based on isnan, signbit, and ==).

Examples

julia> isequal([1., NaN], [1., NaN])
+true
source
Base.isequalFunction
isequal(x, y) -> Bool

Similar to ==, except for the treatment of floating point numbers and of missing values. isequal treats all floating-point NaN values as equal to each other, treats -0.0 as unequal to 0.0, and missing as equal to missing. Always returns a Bool value.

isequal is an equivalence relation - it is reflexive (=== implies isequal), symmetric (isequal(a, b) implies isequal(b, a)) and transitive (isequal(a, b) and isequal(b, c) implies isequal(a, c)).

Implementation

The default implementation of isequal calls ==, so a type that does not involve floating-point values generally only needs to define ==.

isequal is the comparison function used by hash tables (Dict). isequal(x,y) must imply that hash(x) == hash(y).

This typically means that types for which a custom == or isequal method exists must implement a corresponding hash method (and vice versa). Collections typically implement isequal by calling isequal recursively on all contents.

Furthermore, isequal is linked with isless, and they work together to define a fixed total ordering, where exactly one of isequal(x, y), isless(x, y), or isless(y, x) must be true (and the other two false).

Scalar types generally do not need to implement isequal separate from ==, unless they represent floating-point numbers amenable to a more efficient implementation than that provided as a generic fallback (based on isnan, signbit, and ==).

Examples

julia> isequal([1., NaN], [1., NaN])
 true
 
 julia> [1., NaN] == [1., NaN]
@@ -421,15 +421,15 @@
 missing
 
 julia> isequal(missing, missing)
-true
source
isequal(x)

Create a function that compares its argument to x using isequal, i.e. a function equivalent to y -> isequal(y, x).

The returned function is of type Base.Fix2{typeof(isequal)}, which can be used to implement specialized methods.

source
Base.islessFunction
isless(x, y)

Test whether x is less than y, according to a fixed total order (defined together with isequal). isless is not defined for pairs (x, y) of all types. However, if it is defined, it is expected to satisfy the following:

  • If isless(x, y) is defined, then so is isless(y, x) and isequal(x, y), and exactly one of those three yields true.
  • The relation defined by isless is transitive, i.e., isless(x, y) && isless(y, z) implies isless(x, z).

Values that are normally unordered, such as NaN, are ordered after regular values. missing values are ordered last.

This is the default comparison used by sort!.

Implementation

Non-numeric types with a total order should implement this function. Numeric types only need to implement it if they have special values such as NaN. Types with a partial order should implement <. See the documentation on Alternate Orderings for how to define alternate ordering methods that can be used in sorting and related functions.

Examples

julia> isless(1, 3)
+true
source
isequal(x)

Create a function that compares its argument to x using isequal, i.e. a function equivalent to y -> isequal(y, x).

The returned function is of type Base.Fix2{typeof(isequal)}, which can be used to implement specialized methods.

source
Base.islessFunction
isless(x, y)

Test whether x is less than y, according to a fixed total order (defined together with isequal). isless is not defined for pairs (x, y) of all types. However, if it is defined, it is expected to satisfy the following:

  • If isless(x, y) is defined, then so is isless(y, x) and isequal(x, y), and exactly one of those three yields true.
  • The relation defined by isless is transitive, i.e., isless(x, y) && isless(y, z) implies isless(x, z).

Values that are normally unordered, such as NaN, are ordered after regular values. missing values are ordered last.

This is the default comparison used by sort!.

Implementation

Non-numeric types with a total order should implement this function. Numeric types only need to implement it if they have special values such as NaN. Types with a partial order should implement <. See the documentation on Alternate Orderings for how to define alternate ordering methods that can be used in sorting and related functions.

Examples

julia> isless(1, 3)
 true
 
 julia> isless("Red", "Blue")
-false
source
Base.isunorderedFunction
isunordered(x)

Return true if x is a value that is not orderable according to <, such as NaN or missing.

The values that evaluate to true with this predicate may be orderable with respect to other orderings such as isless.

Julia 1.7

This function requires Julia 1.7 or later.

source
Base.ifelseFunction
ifelse(condition::Bool, x, y)

Return x if condition is true, otherwise return y. This differs from ? or if in that it is an ordinary function, so all the arguments are evaluated first. In some cases, using ifelse instead of an if statement can eliminate the branch in generated code and provide higher performance in tight loops.

Examples

julia> ifelse(1 > 2, 1, 2)
-2
source
Core.typeassertFunction
typeassert(x, type)

Throw a TypeError unless x isa type. The syntax x::type calls this function.

Examples

julia> typeassert(2.5, Int)
+false
source
Base.isunorderedFunction
isunordered(x)

Return true if x is a value that is not orderable according to <, such as NaN or missing.

The values that evaluate to true with this predicate may be orderable with respect to other orderings such as isless.

Julia 1.7

This function requires Julia 1.7 or later.

source
Base.ifelseFunction
ifelse(condition::Bool, x, y)

Return x if condition is true, otherwise return y. This differs from ? or if in that it is an ordinary function, so all the arguments are evaluated first. In some cases, using ifelse instead of an if statement can eliminate the branch in generated code and provide higher performance in tight loops.

Examples

julia> ifelse(1 > 2, 1, 2)
+2
source
Core.typeassertFunction
typeassert(x, type)

Throw a TypeError unless x isa type. The syntax x::type calls this function.

Examples

julia> typeassert(2.5, Int)
 ERROR: TypeError: in typeassert, expected Int64, got a value of type Float64
 Stacktrace:
-[...]
source
Core.typeofFunction
typeof(x)

Get the concrete type of x.

See also eltype.

Examples

julia> a = 1//2;
 
 julia> typeof(a)
 Rational{Int64}
@@ -437,20 +437,20 @@
 julia> M = [1 2; 3.5 4];
 
 julia> typeof(M)
-Matrix{Float64} (alias for Array{Float64, 2})
source
Core.tupleFunction
tuple(xs...)

Construct a tuple of the given objects.

See also Tuple, ntuple, NamedTuple.

Examples

julia> tuple(1, 'b', pi)
+Matrix{Float64} (alias for Array{Float64, 2})
source
Core.tupleFunction
tuple(xs...)

Construct a tuple of the given objects.

See also Tuple, ntuple, NamedTuple.

Examples

julia> tuple(1, 'b', pi)
 (1, 'b', π)
 
 julia> ans === (1, 'b', π)
 true
 
 julia> Tuple(Real[1, 2, pi])  # takes a collection
-(1, 2, π)
source
Base.ntupleFunction
ntuple(f, n::Integer)

Create a tuple of length n, computing each element as f(i), where i is the index of the element.

Examples

julia> ntuple(i -> 2*i, 4)
-(2, 4, 6, 8)
source
ntuple(f, ::Val{N})

Create a tuple of length N, computing each element as f(i), where i is the index of the element. By taking a Val(N) argument, it is possible that this version of ntuple may generate more efficient code than the version taking the length as an integer. But ntuple(f, N) is preferable to ntuple(f, Val(N)) in cases where N cannot be determined at compile time.

Examples

julia> ntuple(i -> 2*i, Val(4))
-(2, 4, 6, 8)
source
Base.objectidFunction
objectid(x) -> UInt

Get a hash value for x based on object identity.

If x === y then objectid(x) == objectid(y), and usually when x !== y, objectid(x) != objectid(y).

See also hash, IdDict.

source
Base.hashFunction
hash(x[, h::UInt]) -> UInt

Compute an integer hash code such that isequal(x,y) implies hash(x)==hash(y). The optional second argument h is another hash code to be mixed with the result.

New types should implement the 2-argument form, typically by calling the 2-argument hash method recursively in order to mix hashes of the contents with each other (and with h). Typically, any type that implements hash should also implement its own == (hence isequal) to guarantee the property mentioned above. Types supporting subtraction (operator -) should also implement widen, which is required to hash values inside heterogeneous arrays.

The hash value may change when a new Julia process is started.

julia> a = hash(10)
+(1, 2, π)
source
Base.ntupleFunction
ntuple(f, n::Integer)

Create a tuple of length n, computing each element as f(i), where i is the index of the element.

Examples

julia> ntuple(i -> 2*i, 4)
+(2, 4, 6, 8)
source
ntuple(f, ::Val{N})

Create a tuple of length N, computing each element as f(i), where i is the index of the element. By taking a Val(N) argument, it is possible that this version of ntuple may generate more efficient code than the version taking the length as an integer. But ntuple(f, N) is preferable to ntuple(f, Val(N)) in cases where N cannot be determined at compile time.

Examples

julia> ntuple(i -> 2*i, Val(4))
+(2, 4, 6, 8)
source
Base.objectidFunction
objectid(x) -> UInt

Get a hash value for x based on object identity.

If x === y then objectid(x) == objectid(y), and usually when x !== y, objectid(x) != objectid(y).

See also hash, IdDict.

source
Base.hashFunction
hash(x[, h::UInt]) -> UInt

Compute an integer hash code such that isequal(x,y) implies hash(x)==hash(y). The optional second argument h is another hash code to be mixed with the result.

New types should implement the 2-argument form, typically by calling the 2-argument hash method recursively in order to mix hashes of the contents with each other (and with h). Typically, any type that implements hash should also implement its own == (hence isequal) to guarantee the property mentioned above. Types supporting subtraction (operator -) should also implement widen, which is required to hash values inside heterogeneous arrays.

The hash value may change when a new Julia process is started.

julia> a = hash(10)
 0x95ea2955abd45275
 
 julia> hash(10, a) # only use the output of another hash function as the second argument
-0xd42bad54a8575b16

See also: objectid, Dict, Set.

source
Base.finalizerFunction
finalizer(f, x)

Register a function f(x) to be called when there are no program-accessible references to x, and return x. The type of x must be a mutable struct, otherwise the function will throw.

f must not cause a task switch, which excludes most I/O operations such as println. Using the @async macro (to defer context switching to outside of the finalizer) or ccall to directly invoke IO functions in C may be helpful for debugging purposes.

Note that there is no guaranteed world age for the execution of f. It may be called in the world age in which the finalizer was registered or any later world age.

Examples

finalizer(my_mutable_struct) do x
+0xd42bad54a8575b16

See also: objectid, Dict, Set.

source
Base.finalizerFunction
finalizer(f, x)

Register a function f(x) to be called when there are no program-accessible references to x, and return x. The type of x must be a mutable struct, otherwise the function will throw.

f must not cause a task switch, which excludes most I/O operations such as println. Using the @async macro (to defer context switching to outside of the finalizer) or ccall to directly invoke IO functions in C may be helpful for debugging purposes.

Note that there is no guaranteed world age for the execution of f. It may be called in the world age in which the finalizer was registered or any later world age.

Examples

finalizer(my_mutable_struct) do x
     @async println("Finalizing $x.")
 end
 
@@ -463,7 +463,7 @@
         f(t) = @async println("Finalizing $t.")
         finalizer(f, x)
     end
-end
source
Base.copyFunction
copy(x)

Create a shallow copy of x: the outer structure is copied, but not all internal values. For example, copying an array produces a new array with identically-same elements as the original.

See also copy!, copyto!, deepcopy.

source
Base.deepcopyFunction
deepcopy(x)

Create a deep copy of x: everything is copied recursively, resulting in a fully independent object. For example, deep-copying an array creates deep copies of all the objects it contains and produces a new array with the consistent relationship structure (e.g., if the first two elements are the same object in the original array, the first two elements of the new array will also be the same deepcopyed object). Calling deepcopy on an object should generally have the same effect as serializing and then deserializing it.

While it isn't normally necessary, user-defined types can override the default deepcopy behavior by defining a specialized version of the function deepcopy_internal(x::T, dict::IdDict) (which shouldn't otherwise be used), where T is the type to be specialized for, and dict keeps track of objects copied so far within the recursion. Within the definition, deepcopy_internal should be used in place of deepcopy, and the dict variable should be updated as appropriate before returning.

source
Base.copyFunction
copy(x)

Create a shallow copy of x: the outer structure is copied, but not all internal values. For example, copying an array produces a new array with identically-same elements as the original.

See also copy!, copyto!, deepcopy.

source
Base.deepcopyFunction
deepcopy(x)

Create a deep copy of x: everything is copied recursively, resulting in a fully independent object. For example, deep-copying an array creates deep copies of all the objects it contains and produces a new array with the consistent relationship structure (e.g., if the first two elements are the same object in the original array, the first two elements of the new array will also be the same deepcopyed object). Calling deepcopy on an object should generally have the same effect as serializing and then deserializing it.

While it isn't normally necessary, user-defined types can override the default deepcopy behavior by defining a specialized version of the function deepcopy_internal(x::T, dict::IdDict) (which shouldn't otherwise be used), where T is the type to be specialized for, and dict keeps track of objects copied so far within the recursion. Within the definition, deepcopy_internal should be used in place of deepcopy, and the dict variable should be updated as appropriate before returning.

source
Base.getpropertyFunction
getproperty(value, name::Symbol)
 getproperty(value, name::Symbol, order::Symbol)

The syntax a.b calls getproperty(a, :b). The syntax @atomic order a.b calls getproperty(a, :b, :order) and the syntax @atomic a.b calls getproperty(a, :b, :sequentially_consistent).

Examples

julia> struct MyType{T <: Number}
            x::T
        end
@@ -482,8 +482,8 @@
 2
 
 julia> obj.x
-1

One should overload getproperty only when necessary, as it can be confusing if the behavior of the syntax obj.f is unusual. Also note that using methods is often preferable. See also this style guide documentation for more information: Prefer exported methods over direct field access.

See also getfield, propertynames and setproperty!.

source
Base.setproperty!Function
setproperty!(value, name::Symbol, x)
-setproperty!(value, name::Symbol, x, order::Symbol)

The syntax a.b = c calls setproperty!(a, :b, c). The syntax @atomic order a.b = c calls setproperty!(a, :b, c, :order) and the syntax @atomic a.b = c calls setproperty!(a, :b, c, :sequentially_consistent).

Julia 1.8

setproperty! on modules requires at least Julia 1.8.

See also setfield!, propertynames and getproperty.

source
Base.replaceproperty!Function
replaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)

Perform a compare-and-swap operation on x.f from expected to desired, per egal. The syntax @atomicreplace x.f expected => desired can be used instead of the function call form.

See also replacefield! setproperty!, setpropertyonce!.

source
Base.swapproperty!Function
swapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)

The syntax @atomic a.b, _ = c, a.b returns (c, swapproperty!(a, :b, c, :sequentially_consistent)), where there must be one getproperty expression common to both sides.

See also swapfield! and setproperty!.

source
Base.modifyproperty!Function
modifyproperty!(x, f::Symbol, op, v, order::Symbol=:not_atomic)

The syntax @atomic op(x.f, v) (and its equivalent @atomic x.f op v) returns modifyproperty!(x, :f, op, v, :sequentially_consistent), where the first argument must be a getproperty expression and is modified atomically.

Invocation of op(getproperty(x, f), v) must return a value that can be stored in the field f of the object x by default. In particular, unlike the default behavior of setproperty!, the convert function is not called automatically.

See also modifyfield! and setproperty!.

source
Base.setpropertyonce!Function
setpropertyonce!(x, f::Symbol, value, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)

Perform a compare-and-swap operation on x.f to set it to value if previously unset. The syntax @atomiconce x.f = value can be used instead of the function call form.

See also setfieldonce!, setproperty!, replaceproperty!.

Julia 1.11

This function requires Julia 1.11 or later.

source
Base.propertynamesFunction
propertynames(x, private=false)

Get a tuple or a vector of the properties (x.property) of an object x. This is typically the same as fieldnames(typeof(x)), but types that overload getproperty should generally overload propertynames as well to get the properties of an instance of the type.

propertynames(x) may return only "public" property names that are part of the documented interface of x. If you want it to also return "private" property names intended for internal use, pass true for the optional second argument. REPL tab completion on x. shows only the private=false properties.

See also: hasproperty, hasfield.

source
Base.haspropertyFunction
hasproperty(x, s::Symbol)

Return a boolean indicating whether the object x has s as one of its own properties.

Julia 1.2

This function requires at least Julia 1.2.

See also: propertynames, hasfield.

source
Base.setproperty!Function
setproperty!(value, name::Symbol, x)
+setproperty!(value, name::Symbol, x, order::Symbol)

The syntax a.b = c calls setproperty!(a, :b, c). The syntax @atomic order a.b = c calls setproperty!(a, :b, c, :order) and the syntax @atomic a.b = c calls setproperty!(a, :b, c, :sequentially_consistent).

Julia 1.8

setproperty! on modules requires at least Julia 1.8.

See also setfield!, propertynames and getproperty.

source
Base.replaceproperty!Function
replaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)

Perform a compare-and-swap operation on x.f from expected to desired, per egal. The syntax @atomicreplace x.f expected => desired can be used instead of the function call form.

See also replacefield! setproperty!, setpropertyonce!.

source
Base.swapproperty!Function
swapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)

The syntax @atomic a.b, _ = c, a.b returns (c, swapproperty!(a, :b, c, :sequentially_consistent)), where there must be one getproperty expression common to both sides.

See also swapfield! and setproperty!.

source
Base.modifyproperty!Function
modifyproperty!(x, f::Symbol, op, v, order::Symbol=:not_atomic)

The syntax @atomic op(x.f, v) (and its equivalent @atomic x.f op v) returns modifyproperty!(x, :f, op, v, :sequentially_consistent), where the first argument must be a getproperty expression and is modified atomically.

Invocation of op(getproperty(x, f), v) must return a value that can be stored in the field f of the object x by default. In particular, unlike the default behavior of setproperty!, the convert function is not called automatically.

See also modifyfield! and setproperty!.

source
Base.setpropertyonce!Function
setpropertyonce!(x, f::Symbol, value, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)

Perform a compare-and-swap operation on x.f to set it to value if previously unset. The syntax @atomiconce x.f = value can be used instead of the function call form.

See also setfieldonce!, setproperty!, replaceproperty!.

Julia 1.11

This function requires Julia 1.11 or later.

source
Base.propertynamesFunction
propertynames(x, private=false)

Get a tuple or a vector of the properties (x.property) of an object x. This is typically the same as fieldnames(typeof(x)), but types that overload getproperty should generally overload propertynames as well to get the properties of an instance of the type.

propertynames(x) may return only "public" property names that are part of the documented interface of x. If you want it to also return "private" property names intended for internal use, pass true for the optional second argument. REPL tab completion on x. shows only the private=false properties.

See also: hasproperty, hasfield.

source
Base.haspropertyFunction
hasproperty(x, s::Symbol)

Return a boolean indicating whether the object x has s as one of its own properties.

Julia 1.2

This function requires at least Julia 1.2.

See also: propertynames, hasfield.

source
Core.getfieldFunction
getfield(value, name::Symbol, [order::Symbol])
 getfield(value, i::Int, [order::Symbol])

Extract a field from a composite value by name or position. Optionally, an ordering can be defined for the operation. If the field was declared @atomic, the specification is strongly recommended to be compatible with the stores to that location. Otherwise, if not declared as @atomic, this parameter must be :not_atomic if specified. See also getproperty and fieldnames.

Examples

julia> a = 1//2
 1//2
 
@@ -494,7 +494,7 @@
 1
 
 julia> getfield(a, 1)
-1
source
Core.setfield!Function
setfield!(value, name::Symbol, x, [order::Symbol])
 setfield!(value, i::Int, x, [order::Symbol])

Assign x to a named field in value of composite type. The value must be mutable and x must be a subtype of fieldtype(typeof(value), name). Additionally, an ordering can be specified for this operation. If the field was declared @atomic, this specification is mandatory. Otherwise, if not declared as @atomic, it must be :not_atomic if specified. See also setproperty!.

Examples

julia> mutable struct MyMutableStruct
            field::Int
        end
@@ -510,11 +510,11 @@
 1//2
 
 julia> setfield!(a, :num, 3);
-ERROR: setfield!: immutable struct of type Rational cannot be changed
source
Core.modifyfield!Function
modifyfield!(value, name::Symbol, op, x, [order::Symbol]) -> Pair
+ERROR: setfield!: immutable struct of type Rational cannot be changed
source
Core.modifyfield!Function
modifyfield!(value, name::Symbol, op, x, [order::Symbol]) -> Pair
 modifyfield!(value, i::Int, op, x, [order::Symbol]) -> Pair

Atomically perform the operations to get and set a field after applying the function op.

y = getfield(value, name)
 z = op(y, x)
 setfield!(value, name, z)
-return y => z

If supported by the hardware (for example, atomic increment), this may be optimized to the appropriate hardware instruction, otherwise it'll use a loop.

Julia 1.7

This function requires Julia 1.7 or later.

source
Core.replacefield!Function
replacefield!(value, name::Symbol, expected, desired,
+return y => z

If supported by the hardware (for example, atomic increment), this may be optimized to the appropriate hardware instruction, otherwise it'll use a loop.

Julia 1.7

This function requires Julia 1.7 or later.

source
Core.replacefield!Function
replacefield!(value, name::Symbol, expected, desired,
               [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)
 replacefield!(value, i::Int, expected, desired,
               [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)

Atomically perform the operations to get and conditionally set a field to a given value.

y = getfield(value, name, fail_order)
@@ -522,15 +522,15 @@
 if ok
     setfield!(value, name, desired, success_order)
 end
-return (; old = y, success = ok)

If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise it'll use a loop.

Julia 1.7

This function requires Julia 1.7 or later.

source
Core.swapfield!Function
swapfield!(value, name::Symbol, x, [order::Symbol])
+return (; old = y, success = ok)

If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise it'll use a loop.

Julia 1.7

This function requires Julia 1.7 or later.

source
Core.swapfield!Function
swapfield!(value, name::Symbol, x, [order::Symbol])
 swapfield!(value, i::Int, x, [order::Symbol])

Atomically perform the operations to simultaneously get and set a field:

y = getfield(value, name)
 setfield!(value, name, x)
-return y
Julia 1.7

This function requires Julia 1.7 or later.

source
Core.setfieldonce!Function
setfieldonce!(value, name::Union{Int,Symbol}, desired,
+return y
Julia 1.7

This function requires Julia 1.7 or later.

source
Core.setfieldonce!Function
setfieldonce!(value, name::Union{Int,Symbol}, desired,
               [success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool

Atomically perform the operations to set a field to a given value, only if it was previously not set.

ok = !isdefined(value, name, fail_order)
 if ok
     setfield!(value, name, desired, success_order)
 end
-return ok
Julia 1.11

This function requires Julia 1.11 or later.

source
Core.isdefinedFunction
isdefined(m::Module, s::Symbol, [order::Symbol])
+return ok
Julia 1.11

This function requires Julia 1.11 or later.

source
Core.isdefinedFunction
isdefined(m::Module, s::Symbol, [order::Symbol])
 isdefined(object, s::Symbol, [order::Symbol])
 isdefined(object, index::Int, [order::Symbol])

Tests whether a global variable or object field is defined. The arguments can be a module and a symbol or a composite object and field name (as a symbol) or index. Optionally, an ordering can be defined for the operation. If the field was declared @atomic, the specification is strongly recommended to be compatible with the stores to that location. Otherwise, if not declared as @atomic, this parameter must be :not_atomic if specified.

To test whether an array element is defined, use isassigned instead.

See also @isdefined.

Examples

julia> isdefined(Base, :sum)
 true
@@ -550,7 +550,7 @@
 true
 
 julia> isdefined(a, :numerator)
-false
source
Base.@isdefinedMacro
@isdefined s -> Bool

Tests whether variable s is defined in the current scope.

See also isdefined for field properties and isassigned for array indexes or haskey for other mappings.

Examples

julia> @isdefined newvar
+false
source
Base.@isdefinedMacro
@isdefined s -> Bool

Tests whether variable s is defined in the current scope.

See also isdefined for field properties and isassigned for array indexes or haskey for other mappings.

Examples

julia> @isdefined newvar
 false
 
 julia> newvar = 1
@@ -568,7 +568,7 @@
 
 julia> f()
 false
-true
source
Base.convertFunction
convert(T, x)

Convert x to a value of type T.

If T is an Integer type, an InexactError will be raised if x is not representable by T, for example if x is not integer-valued, or is outside the range supported by T.

Examples

julia> convert(Int, 3.0)
+true
source
Base.convertFunction
convert(T, x)

Convert x to a value of type T.

If T is an Integer type, an InexactError will be raised if x is not representable by T, for example if x is not integer-valued, or is outside the range supported by T.

Examples

julia> convert(Int, 3.0)
 3
 
 julia> convert(Int, 3.5)
@@ -586,7 +586,7 @@
 julia> y = convert(Vector{Int}, x);
 
 julia> y === x
-true

See also: round, trunc, oftype, reinterpret.

source
Base.promoteFunction
promote(xs...)

Convert all arguments to a common type, and return them all (as a tuple). If no arguments can be converted, an error is raised.

See also: promote_type, promote_rule.

Examples

julia> promote(Int8(1), Float16(4.5), Float32(4.1))
 (1.0f0, 4.5f0, 4.1f0)
 
 julia> promote_type(Int8, Float16, Float32)
@@ -600,7 +600,7 @@
 [...]
 
 julia> promote_type(Int, String)
-Any
source
Base.oftypeFunction
oftype(x, y)

Convert y to the type of x i.e. convert(typeof(x), y).

Examples

julia> x = 4;
+Any
source
Base.oftypeFunction
oftype(x, y)

Convert y to the type of x i.e. convert(typeof(x), y).

Examples

julia> x = 4;
 
 julia> y = 3.;
 
@@ -608,12 +608,12 @@
 3
 
 julia> oftype(y, x)
-4.0
source
Base.widenFunction
widen(x)

If x is a type, return a "larger" type, defined so that arithmetic operations + and - are guaranteed not to overflow nor lose precision for any combination of values that type x can hold.

For fixed-size integer types less than 128 bits, widen will return a type with twice the number of bits.

If x is a value, it is converted to widen(typeof(x)).

Examples

julia> widen(Int32)
+4.0
source
Base.widenFunction
widen(x)

If x is a type, return a "larger" type, defined so that arithmetic operations + and - are guaranteed not to overflow nor lose precision for any combination of values that type x can hold.

For fixed-size integer types less than 128 bits, widen will return a type with twice the number of bits.

If x is a value, it is converted to widen(typeof(x)).

Examples

julia> widen(Int32)
 Int64
 
 julia> widen(1.5f0)
-1.5
source
Base.identityFunction
identity(x)

The identity function. Returns its argument.

See also: one, oneunit, and LinearAlgebra's I.

Examples

julia> identity("Well, what did you expect?")
-"Well, what did you expect?"
source
Core.WeakRefType
WeakRef(x)

w = WeakRef(x) constructs a weak reference to the Julia value x: although w contains a reference to x, it does not prevent x from being garbage collected. w.value is either x (if x has not been garbage-collected yet) or nothing (if x has been garbage-collected).

julia> x = "a string"
+1.5
source
Base.identityFunction
identity(x)

The identity function. Returns its argument.

See also: one, oneunit, and LinearAlgebra's I.

Examples

julia> identity("Well, what did you expect?")
+"Well, what did you expect?"
source
Core.WeakRefType
WeakRef(x)

w = WeakRef(x) constructs a weak reference to the Julia value x: although w contains a reference to x, it does not prevent x from being garbage collected. w.value is either x (if x has not been garbage-collected yet) or nothing (if x has been garbage-collected).

julia> x = "a string"
 "a string"
 
 julia> w = WeakRef(x)
@@ -629,8 +629,8 @@
 julia> GC.gc()
 
 julia> w
-WeakRef(nothing)
source

Properties of Types

Type relations

Base.supertypeFunction
supertype(T::DataType)

Return the supertype of DataType T.

Examples

julia> supertype(Int32)
-Signed
source
Core.TypeType
Core.Type{T}

Core.Type is an abstract type which has all type objects as its instances. The only instance of the singleton type Core.Type{T} is the object T.

Examples

julia> isa(Type{Float64}, Type)
+WeakRef(nothing)
source

Properties of Types

Type relations

Base.supertypeFunction
supertype(T::DataType)

Return the supertype of DataType T.

Examples

julia> supertype(Int32)
+Signed
source
Core.TypeType
Core.Type{T}

Core.Type is an abstract type which has all type objects as its instances. The only instance of the singleton type Core.Type{T} is the object T.

Examples

julia> isa(Type{Float64}, Type)
 true
 
 julia> isa(Float64, Type)
@@ -640,7 +640,7 @@
 false
 
 julia> isa(Real, Type{Real})
-true
source
Core.DataTypeType
DataType <: Type{T}

DataType represents explicitly declared types that have names, explicitly declared supertypes, and, optionally, parameters. Every concrete value in the system is an instance of some DataType.

Examples

julia> typeof(Real)
+true
source
Core.DataTypeType
DataType <: Type{T}

DataType represents explicitly declared types that have names, explicitly declared supertypes, and, optionally, parameters. Every concrete value in the system is an instance of some DataType.

Examples

julia> typeof(Real)
 DataType
 
 julia> typeof(Int)
@@ -652,7 +652,7 @@
        end
 
 julia> typeof(Point)
-DataType
source
Core.:<:Function
<:(T1, T2)::Bool

Subtyping relation, defined between two types. In Julia, a type S is said to be a subtype of a type T if and only if we have S <: T.

For any type L and any type R, L <: R implies that any value v of type L is also of type R. I.e., (L <: R) && (v isa L) implies v isa R.

The subtyping relation is a partial order. I.e., <: is:

  • reflexive: for any type T, T <: T holds

  • antisymmetric: for any type A and any type B, (A <: B) && (B <: A) implies A == B

  • transitive: for any type A, any type B and any type C; (A <: B) && (B <: C) implies A <: C

See also info on Types, Union{}, Any, isa.

Examples

julia> Float64 <: AbstractFloat
+DataType
source
Core.:<:Function
<:(T1, T2)::Bool

Subtyping relation, defined between two types. In Julia, a type S is said to be a subtype of a type T if and only if we have S <: T.

For any type L and any type R, L <: R implies that any value v of type L is also of type R. I.e., (L <: R) && (v isa L) implies v isa R.

The subtyping relation is a partial order. I.e., <: is:

  • reflexive: for any type T, T <: T holds

  • antisymmetric: for any type A and any type B, (A <: B) && (B <: A) implies A == B

  • transitive: for any type A, any type B and any type C; (A <: B) && (B <: C) implies A <: C

See also info on Types, Union{}, Any, isa.

Examples

julia> Float64 <: AbstractFloat
 true
 
 julia> Vector{Int} <: AbstractArray
@@ -668,11 +668,11 @@
 true
 
 julia> Union{} <: Float32 <: AbstractFloat <: Real <: Number <: Any  # Operator chaining
-true

The <: keyword also has several syntactic uses which represent the same subtyping relation, but which do not execute the operator or return a Bool:

  • To specify the lower bound and the upper bound on a parameter of a UnionAll type in a where statement.

  • To specify the lower bound and the upper bound on a (static) parameter of a method, see Parametric Methods.

  • To define a subtyping relation while declaring a new type, see struct and abstract type.

source
Base.:>:Function
>:(T1, T2)

Supertype operator, equivalent to T2 <: T1.

source
Base.typejoinFunction
typejoin(T, S, ...)

Return the closest common ancestor of types T and S, i.e. the narrowest type from which they both inherit. Recurses on additional varargs.

Examples

julia> typejoin(Int, Float64)
+true

The <: keyword also has several syntactic uses which represent the same subtyping relation, but which do not execute the operator or return a Bool:

  • To specify the lower bound and the upper bound on a parameter of a UnionAll type in a where statement.

  • To specify the lower bound and the upper bound on a (static) parameter of a method, see Parametric Methods.

  • To define a subtyping relation while declaring a new type, see struct and abstract type.

source
Base.:>:Function
>:(T1, T2)

Supertype operator, equivalent to T2 <: T1.

source
Base.typejoinFunction
typejoin(T, S, ...)

Return the closest common ancestor of types T and S, i.e. the narrowest type from which they both inherit. Recurses on additional varargs.

Examples

julia> typejoin(Int, Float64)
 Real
 
 julia> typejoin(Int, Float64, ComplexF32)
-Number
source
Base.typeintersectFunction
typeintersect(T::Type, S::Type)

Compute a type that contains the intersection of T and S. Usually this will be the smallest such type or one close to it.

A special case where exact behavior is guaranteed: when T <: S, typeintersect(S, T) == T == typeintersect(T, S).

source
Base.promote_typeFunction
promote_type(type1, type2, ...)

Promotion refers to converting values of mixed types to a single common type. promote_type represents the default promotion behavior in Julia when operators (usually mathematical) are given arguments of differing types. promote_type generally tries to return a type which can at least approximate most values of either input type without excessively widening. Some loss is tolerated; for example, promote_type(Int64, Float64) returns Float64 even though strictly, not all Int64 values can be represented exactly as Float64 values.

See also: promote, promote_typejoin, promote_rule.

Examples

julia> promote_type(Int64, Float64)
+Number
source
Base.typeintersectFunction
typeintersect(T::Type, S::Type)

Compute a type that contains the intersection of T and S. Usually this will be the smallest such type or one close to it.

A special case where exact behavior is guaranteed: when T <: S, typeintersect(S, T) == T == typeintersect(T, S).

source
Base.promote_typeFunction
promote_type(type1, type2, ...)

Promotion refers to converting values of mixed types to a single common type. promote_type represents the default promotion behavior in Julia when operators (usually mathematical) are given arguments of differing types. promote_type generally tries to return a type which can at least approximate most values of either input type without excessively widening. Some loss is tolerated; for example, promote_type(Int64, Float64) returns Float64 even though strictly, not all Int64 values can be represented exactly as Float64 values.

See also: promote, promote_typejoin, promote_rule.

Examples

julia> promote_type(Int64, Float64)
 Float64
 
 julia> promote_type(Int32, Int64)
@@ -688,38 +688,38 @@
 Float16
 
 julia> promote_type(Int8, UInt16)
-UInt16
Don't overload this directly

To overload promotion for your own types you should overload promote_rule. promote_type calls promote_rule internally to determine the type. Overloading promote_type directly can cause ambiguity errors.

source
Base.promote_ruleFunction
promote_rule(type1, type2)

Specifies what type should be used by promote when given values of types type1 and type2. This function should not be called directly, but should have definitions added to it for new types as appropriate.

source
Base.promote_typejoinFunction
promote_typejoin(T, S)

Compute a type that contains both T and S, which could be either a parent of both types, or a Union if appropriate. Falls back to typejoin.

See instead promote, promote_type.

Examples

julia> Base.promote_typejoin(Int, Float64)
+UInt16
Don't overload this directly

To overload promotion for your own types you should overload promote_rule. promote_type calls promote_rule internally to determine the type. Overloading promote_type directly can cause ambiguity errors.

source
Base.promote_ruleFunction
promote_rule(type1, type2)

Specifies what type should be used by promote when given values of types type1 and type2. This function should not be called directly, but should have definitions added to it for new types as appropriate.

source
Base.promote_typejoinFunction
promote_typejoin(T, S)

Compute a type that contains both T and S, which could be either a parent of both types, or a Union if appropriate. Falls back to typejoin.

See instead promote, promote_type.

Examples

julia> Base.promote_typejoin(Int, Float64)
 Real
 
 julia> Base.promote_type(Int, Float64)
-Float64
source
Base.isdispatchtupleFunction
isdispatchtuple(T)

Determine whether type T is a tuple "leaf type", meaning it could appear as a type signature in dispatch and has no subtypes (or supertypes) which could appear in a call. If T is not a type, then return false.

source

Declared structure

Base.ismutableFunction
ismutable(v) -> Bool

Return true if and only if value v is mutable. See Mutable Composite Types for a discussion of immutability. Note that this function works on values, so if you give it a DataType, it will tell you that a value of the type is mutable.

Note

For technical reasons, ismutable returns true for values of certain special types (for example String and Symbol) even though they cannot be mutated in a permissible way.

See also isbits, isstructtype.

Examples

julia> ismutable(1)
+Float64
source
Base.isdispatchtupleFunction
isdispatchtuple(T)

Determine whether type T is a tuple "leaf type", meaning it could appear as a type signature in dispatch and has no subtypes (or supertypes) which could appear in a call. If T is not a type, then return false.

source

Declared structure

Base.ismutableFunction
ismutable(v) -> Bool

Return true if and only if value v is mutable. See Mutable Composite Types for a discussion of immutability. Note that this function works on values, so if you give it a DataType, it will tell you that a value of the type is mutable.

Note

For technical reasons, ismutable returns true for values of certain special types (for example String and Symbol) even though they cannot be mutated in a permissible way.

See also isbits, isstructtype.

Examples

julia> ismutable(1)
 false
 
 julia> ismutable([1,2])
-true
Julia 1.5

This function requires at least Julia 1.5.

source
Base.isimmutableFunction
isimmutable(v) -> Bool
Warning

Consider using !ismutable(v) instead, as isimmutable(v) will be replaced by !ismutable(v) in a future release. (Since Julia 1.5)

Return true iff value v is immutable. See Mutable Composite Types for a discussion of immutability. Note that this function works on values, so if you give it a type, it will tell you that a value of DataType is mutable.

Examples

julia> isimmutable(1)
+true
Julia 1.5

This function requires at least Julia 1.5.

source
Base.isimmutableFunction
isimmutable(v) -> Bool
Warning

Consider using !ismutable(v) instead, as isimmutable(v) will be replaced by !ismutable(v) in a future release. (Since Julia 1.5)

Return true iff value v is immutable. See Mutable Composite Types for a discussion of immutability. Note that this function works on values, so if you give it a type, it will tell you that a value of DataType is mutable.

Examples

julia> isimmutable(1)
 true
 
 julia> isimmutable([1,2])
-false
source
Base.ismutabletypeFunction
ismutabletype(T) -> Bool

Determine whether type T was declared as a mutable type (i.e. using mutable struct keyword). If T is not a type, then return false.

Julia 1.7

This function requires at least Julia 1.7.

source
Base.isabstracttypeFunction
isabstracttype(T)

Determine whether type T was declared as an abstract type (i.e. using the abstract type syntax). Note that this is not the negation of isconcretetype(T). If T is not a type, then return false.

Examples

julia> isabstracttype(AbstractArray)
+false
source
Base.ismutabletypeFunction
ismutabletype(T) -> Bool

Determine whether type T was declared as a mutable type (i.e. using mutable struct keyword). If T is not a type, then return false.

Julia 1.7

This function requires at least Julia 1.7.

source
Base.isabstracttypeFunction
isabstracttype(T)

Determine whether type T was declared as an abstract type (i.e. using the abstract type syntax). Note that this is not the negation of isconcretetype(T). If T is not a type, then return false.

Examples

julia> isabstracttype(AbstractArray)
 true
 
 julia> isabstracttype(Vector)
-false
source
Base.isprimitivetypeFunction
isprimitivetype(T) -> Bool

Determine whether type T was declared as a primitive type (i.e. using the primitive type syntax). If T is not a type, then return false.

source
Base.issingletontypeFunction
Base.issingletontype(T)

Determine whether type T has exactly one possible instance; for example, a struct type with no fields except other singleton values. If T is not a concrete type, then return false.

source
Base.isstructtypeFunction
isstructtype(T) -> Bool

Determine whether type T was declared as a struct type (i.e. using the struct or mutable struct keyword). If T is not a type, then return false.

source
Base.nameofMethod
nameof(t::DataType) -> Symbol

Get the name of a (potentially UnionAll-wrapped) DataType (without its parent module) as a symbol.

Examples

julia> module Foo
+false
source
Base.isprimitivetypeFunction
isprimitivetype(T) -> Bool

Determine whether type T was declared as a primitive type (i.e. using the primitive type syntax). If T is not a type, then return false.

source
Base.issingletontypeFunction
Base.issingletontype(T)

Determine whether type T has exactly one possible instance; for example, a struct type with no fields except other singleton values. If T is not a concrete type, then return false.

source
Base.isstructtypeFunction
isstructtype(T) -> Bool

Determine whether type T was declared as a struct type (i.e. using the struct or mutable struct keyword). If T is not a type, then return false.

source
Base.nameofMethod
nameof(t::DataType) -> Symbol

Get the name of a (potentially UnionAll-wrapped) DataType (without its parent module) as a symbol.

Examples

julia> module Foo
            struct S{T}
            end
        end
 Foo
 
 julia> nameof(Foo.S{T} where T)
-:S
source
Base.fieldnamesFunction
fieldnames(x::DataType)

Get a tuple with the names of the fields of a DataType.

See also propertynames, hasfield.

Examples

julia> fieldnames(Rational)
 (:num, :den)
 
 julia> fieldnames(typeof(1+im))
-(:re, :im)
source
Base.fieldnameFunction
fieldname(x::DataType, i::Integer)

Get the name of field i of a DataType.

Examples

julia> fieldname(Rational, 1)
+(:re, :im)
source
Base.fieldnameFunction
fieldname(x::DataType, i::Integer)

Get the name of field i of a DataType.

Examples

julia> fieldname(Rational, 1)
 :num
 
 julia> fieldname(Rational, 2)
-:den
source
Core.fieldtypeFunction
fieldtype(T, name::Symbol | index::Int)

Determine the declared type of a field (specified by name or index) in a composite DataType T.

Examples

julia> struct Foo
+:den
source
Core.fieldtypeFunction
fieldtype(T, name::Symbol | index::Int)

Determine the declared type of a field (specified by name or index) in a composite DataType T.

Examples

julia> struct Foo
            x::Int64
            y::String
        end
@@ -728,13 +728,13 @@
 Int64
 
 julia> fieldtype(Foo, 2)
-String
source
Base.fieldtypesFunction
fieldtypes(T::Type)

The declared types of all fields in a composite DataType T as a tuple.

Julia 1.1

This function requires at least Julia 1.1.

Examples

julia> struct Foo
+String
source
Base.fieldtypesFunction
fieldtypes(T::Type)

The declared types of all fields in a composite DataType T as a tuple.

Julia 1.1

This function requires at least Julia 1.1.

Examples

julia> struct Foo
            x::Int64
            y::String
        end
 
 julia> fieldtypes(Foo)
-(Int64, String)
source
Base.fieldcountFunction
fieldcount(t::Type)

Get the number of fields that an instance of the given type would have. An error is thrown if the type is too abstract to determine this.

source
Base.hasfieldFunction
hasfield(T::Type, name::Symbol)

Return a boolean indicating whether T has name as one of its own fields.

See also fieldnames, fieldcount, hasproperty.

Julia 1.2

This function requires at least Julia 1.2.

Examples

julia> struct Foo
+(Int64, String)
source
Base.fieldcountFunction
fieldcount(t::Type)

Get the number of fields that an instance of the given type would have. An error is thrown if the type is too abstract to determine this.

source
Base.hasfieldFunction
hasfield(T::Type, name::Symbol)

Return a boolean indicating whether T has name as one of its own fields.

See also fieldnames, fieldcount, hasproperty.

Julia 1.2

This function requires at least Julia 1.2.

Examples

julia> struct Foo
             bar::Int
        end
 
@@ -742,7 +742,7 @@
 true
 
 julia> hasfield(Foo, :x)
-false
source
Core.nfieldsFunction
nfields(x) -> Int

Get the number of fields in the given object.

Examples

julia> a = 1//2;
+false
source
Core.nfieldsFunction
nfields(x) -> Int

Get the number of fields in the given object.

Examples

julia> a = 1//2;
 
 julia> nfields(a)
 2
@@ -756,7 +756,7 @@
 julia> ex = ErrorException("I've done a bad thing");
 
 julia> nfields(ex)
-1

In these examples, a is a Rational, which has two fields. b is an Int, which is a primitive bitstype with no fields at all. ex is an ErrorException, which has one field.

source
Base.isconstFunction
isconst(m::Module, s::Symbol) -> Bool

Determine whether a global is declared const in a given module m.

source
isconst(t::DataType, s::Union{Int,Symbol}) -> Bool

Determine whether a field s is declared const in a given type t.

source
Base.isfieldatomicFunction
isfieldatomic(t::DataType, s::Union{Int,Symbol}) -> Bool

Determine whether a field s is declared @atomic in a given type t.

source

Memory layout

Base.sizeofMethod
sizeof(T::DataType)
+1

In these examples, a is a Rational, which has two fields. b is an Int, which is a primitive bitstype with no fields at all. ex is an ErrorException, which has one field.

source
Base.isconstFunction
isconst(m::Module, s::Symbol) -> Bool

Determine whether a global is declared const in a given module m.

source
isconst(t::DataType, s::Union{Int,Symbol}) -> Bool

Determine whether a field s is declared const in a given type t.

source
Base.isfieldatomicFunction
isfieldatomic(t::DataType, s::Union{Int,Symbol}) -> Bool

Determine whether a field s is declared @atomic in a given type t.

source

Memory layout

Base.sizeofMethod
sizeof(T::DataType)
 sizeof(obj)

Size, in bytes, of the canonical binary representation of the given DataType T, if any. Or the size, in bytes, of object obj if it is not a DataType.

See also Base.summarysize.

Examples

julia> sizeof(Float32)
 4
 
@@ -781,7 +781,7 @@
 9

If DataType T does not have a specific size, an error is thrown.

julia> sizeof(AbstractArray)
 ERROR: Abstract type AbstractArray does not have a definite size.
 Stacktrace:
-[...]
source
Base.isconcretetypeFunction
isconcretetype(T)

Determine whether type T is a concrete type, meaning it could have direct instances (values x such that typeof(x) === T). Note that this is not the negation of isabstracttype(T). If T is not a type, then return false.

See also: isbits, isabstracttype, issingletontype.

Examples

julia> isconcretetype(Complex)
+[...]
source
Base.isconcretetypeFunction
isconcretetype(T)

Determine whether type T is a concrete type, meaning it could have direct instances (values x such that typeof(x) === T). Note that this is not the negation of isabstracttype(T). If T is not a type, then return false.

See also: isbits, isabstracttype, issingletontype.

Examples

julia> isconcretetype(Complex)
 false
 
 julia> isconcretetype(Complex{Float32})
@@ -797,11 +797,11 @@
 false
 
 julia> isconcretetype(Union{Int,String})
-false
source
Base.isbitstypeFunction
isbitstype(T)

Return true if type T is a "plain data" type, meaning it is immutable and contains no references to other values, only primitive types and other isbitstype types. Typical examples are numeric types such as UInt8, Float64, and Complex{Float64}. This category of types is significant since they are valid as type parameters, may not track isdefined / isassigned status, and have a defined layout that is compatible with C. If T is not a type, then return false.

See also isbits, isprimitivetype, ismutable.

Examples

julia> isbitstype(Complex{Float64})
+false
source
Base.isbitstypeFunction
isbitstype(T)

Return true if type T is a "plain data" type, meaning it is immutable and contains no references to other values, only primitive types and other isbitstype types. Typical examples are numeric types such as UInt8, Float64, and Complex{Float64}. This category of types is significant since they are valid as type parameters, may not track isdefined / isassigned status, and have a defined layout that is compatible with C. If T is not a type, then return false.

See also isbits, isprimitivetype, ismutable.

Examples

julia> isbitstype(Complex{Float64})
 true
 
 julia> isbitstype(Complex)
-false
source
Base.fieldoffsetFunction
fieldoffset(type, i)

The byte offset of field i of a type relative to the data start. For example, we could use it in the following manner to summarize information about a struct:

julia> structinfo(T) = [(fieldoffset(T,i), fieldname(T,i), fieldtype(T,i)) for i = 1:fieldcount(T)];
+false
source
Base.fieldoffsetFunction
fieldoffset(type, i)

The byte offset of field i of a type relative to the data start. For example, we could use it in the following manner to summarize information about a struct:

julia> structinfo(T) = [(fieldoffset(T,i), fieldname(T,i), fieldtype(T,i)) for i = 1:fieldcount(T)];
 
 julia> structinfo(Base.Filesystem.StatStruct)
 13-element Vector{Tuple{UInt64, Symbol, Type}}:
@@ -817,7 +817,7 @@
  (0x0000000000000048, :blksize, Int64)
  (0x0000000000000050, :blocks, Int64)
  (0x0000000000000058, :mtime, Float64)
- (0x0000000000000060, :ctime, Float64)
source
Base.datatype_alignmentFunction
Base.datatype_alignment(dt::DataType) -> Int

Memory allocation minimum alignment for instances of this type. Can be called on any isconcretetype, although for Memory it will give the alignment of the elements, not the whole object.

source
Base.datatype_haspaddingFunction
Base.datatype_haspadding(dt::DataType) -> Bool

Return whether the fields of instances of this type are packed in memory, with no intervening padding bits (defined as bits whose value does not uniquely impact the egal test when applied to the struct fields). Can be called on any isconcretetype.

source
Base.datatype_pointerfreeFunction
Base.datatype_pointerfree(dt::DataType) -> Bool

Return whether instances of this type can contain references to gc-managed memory. Can be called on any isconcretetype.

source

Special values

Base.typeminFunction
typemin(T)

The lowest value representable by the given (real) numeric DataType T.

See also: floatmin, typemax, eps.

Examples

julia> typemin(Int8)
+ (0x0000000000000060, :ctime, Float64)
source
Base.datatype_alignmentFunction
Base.datatype_alignment(dt::DataType) -> Int

Memory allocation minimum alignment for instances of this type. Can be called on any isconcretetype, although for Memory it will give the alignment of the elements, not the whole object.

source
Base.datatype_haspaddingFunction
Base.datatype_haspadding(dt::DataType) -> Bool

Return whether the fields of instances of this type are packed in memory, with no intervening padding bits (defined as bits whose value does not uniquely impact the egal test when applied to the struct fields). Can be called on any isconcretetype.

source
Base.datatype_pointerfreeFunction
Base.datatype_pointerfree(dt::DataType) -> Bool

Return whether instances of this type can contain references to gc-managed memory. Can be called on any isconcretetype.

source

Special values

Base.typeminFunction
typemin(T)

The lowest value representable by the given (real) numeric DataType T.

See also: floatmin, typemax, eps.

Examples

julia> typemin(Int8)
 -128
 
 julia> typemin(UInt32)
@@ -830,7 +830,7 @@
 -Inf32
 
 julia> nextfloat(-Inf32)  # smallest finite Float32 floating point number
--3.4028235f38
source
Base.typemaxFunction
typemax(T)

The highest value representable by the given (real) numeric DataType.

See also: floatmax, typemin, eps.

Examples

julia> typemax(Int8)
+-3.4028235f38
source
Base.typemaxFunction
typemax(T)

The highest value representable by the given (real) numeric DataType.

See also: floatmax, typemin, eps.

Examples

julia> typemax(Int8)
 127
 
 julia> typemax(UInt32)
@@ -843,14 +843,14 @@
 Inf32
 
 julia> floatmax(Float32)  # largest finite Float32 floating point number
-3.4028235f38
source
Base.floatminFunction
floatmin(T = Float64)

Return the smallest positive normal number representable by the floating-point type T.

Examples

julia> floatmin(Float16)
+3.4028235f38
source
Base.floatminFunction
floatmin(T = Float64)

Return the smallest positive normal number representable by the floating-point type T.

Examples

julia> floatmin(Float16)
 Float16(6.104e-5)
 
 julia> floatmin(Float32)
 1.1754944f-38
 
 julia> floatmin()
-2.2250738585072014e-308
source
Base.floatmaxFunction
floatmax(T = Float64)

Return the largest finite number representable by the floating-point type T.

See also: typemax, floatmin, eps.

Examples

julia> floatmax(Float16)
+2.2250738585072014e-308
source
Base.floatmaxFunction
floatmax(T = Float64)

Return the largest finite number representable by the floating-point type T.

See also: typemax, floatmin, eps.

Examples

julia> floatmax(Float16)
 Float16(6.55e4)
 
 julia> floatmax(Float32)
@@ -860,7 +860,7 @@
 1.7976931348623157e308
 
 julia> typemax(Float64)
-Inf
source
Base.maxintfloatFunction
maxintfloat(T=Float64)

The largest consecutive integer-valued floating-point number that is exactly represented in the given floating-point type T (which defaults to Float64).

That is, maxintfloat returns the smallest positive integer-valued floating-point number n such that n+1 is not exactly representable in the type T.

When an Integer-type value is needed, use Integer(maxintfloat(T)).

source
maxintfloat(T, S)

The largest consecutive integer representable in the given floating-point type T that also does not exceed the maximum integer representable by the integer type S. Equivalently, it is the minimum of maxintfloat(T) and typemax(S).

source
Base.maxintfloatFunction
maxintfloat(T=Float64)

The largest consecutive integer-valued floating-point number that is exactly represented in the given floating-point type T (which defaults to Float64).

That is, maxintfloat returns the smallest positive integer-valued floating-point number n such that n+1 is not exactly representable in the type T.

When an Integer-type value is needed, use Integer(maxintfloat(T)).

source
maxintfloat(T, S)

The largest consecutive integer representable in the given floating-point type T that also does not exceed the maximum integer representable by the integer type S. Equivalently, it is the minimum of maxintfloat(T) and typemax(S).

source
Base.epsMethod
eps(::Type{T}) where T<:AbstractFloat
 eps()

Return the machine epsilon of the floating point type T (T = Float64 by default). This is defined as the gap between 1 and the next largest value representable by typeof(one(T)), and is equivalent to eps(one(T)). (Since eps(T) is a bound on the relative error of T, it is a "dimensionless" quantity like one.)

Examples

julia> eps()
 2.220446049250313e-16
 
@@ -871,7 +871,7 @@
 1.0000000000000002
 
 julia> 1.0 + eps()/2
-1.0
source
Base.epsMethod
eps(x::AbstractFloat)

Return the unit in last place (ulp) of x. This is the distance between consecutive representable floating point values at x. In most cases, if the distance on either side of x is different, then the larger of the two is taken, that is

eps(x) == max(x-prevfloat(x), nextfloat(x)-x)

The exceptions to this rule are the smallest and largest finite values (e.g. nextfloat(-Inf) and prevfloat(Inf) for Float64), which round to the smaller of the values.

The rationale for this behavior is that eps bounds the floating point rounding error. Under the default RoundNearest rounding mode, if $y$ is a real number and $x$ is the nearest floating point number to $y$, then

\[|y-x| \leq \operatorname{eps}(x)/2.\]

See also: nextfloat, issubnormal, floatmax.

Examples

julia> eps(1.0)
+1.0
source
Base.epsMethod
eps(x::AbstractFloat)

Return the unit in last place (ulp) of x. This is the distance between consecutive representable floating point values at x. In most cases, if the distance on either side of x is different, then the larger of the two is taken, that is

eps(x) == max(x-prevfloat(x), nextfloat(x)-x)

The exceptions to this rule are the smallest and largest finite values (e.g. nextfloat(-Inf) and prevfloat(Inf) for Float64), which round to the smaller of the values.

The rationale for this behavior is that eps bounds the floating point rounding error. Under the default RoundNearest rounding mode, if $y$ is a real number and $x$ is the nearest floating point number to $y$, then

\[|y-x| \leq \operatorname{eps}(x)/2.\]

See also: nextfloat, issubnormal, floatmax.

Examples

julia> eps(1.0)
 2.220446049250313e-16
 
 julia> eps(prevfloat(2.0))
@@ -887,10 +887,10 @@
 Inf
 
 julia> x + prevfloat(eps(x)/2) # rounds down
-1.7976931348623157e308
source
Base.instancesFunction
instances(T::Type)

Return a collection of all instances of the given type, if applicable. Mostly used for enumerated types (see @enum).

Examples

julia> @enum Color red blue green
+1.7976931348623157e308
source
Base.instancesFunction
instances(T::Type)

Return a collection of all instances of the given type, if applicable. Mostly used for enumerated types (see @enum).

Examples

julia> @enum Color red blue green
 
 julia> instances(Color)
-(red, blue, green)
source

Special Types

Core.AnyType
Any::DataType

Any is the union of all types. It has the defining property isa(x, Any) == true for any x. Any therefore describes the entire universe of possible values. For example Integer is a subset of Any that includes Int, Int8, and other integer types.

source
Core.UnionType
Union{Types...}

A Union type is an abstract type which includes all instances of any of its argument types. This means that T <: Union{T,S} and S <: Union{T,S}.

Like other abstract types, it cannot be instantiated, even if all of its arguments are non abstract.

Examples

julia> IntOrString = Union{Int,AbstractString}
+(red, blue, green)
source

Special Types

Core.AnyType
Any::DataType

Any is the union of all types. It has the defining property isa(x, Any) == true for any x. Any therefore describes the entire universe of possible values. For example Integer is a subset of Any that includes Int, Int8, and other integer types.

source
Core.UnionType
Union{Types...}

A Union type is an abstract type which includes all instances of any of its argument types. This means that T <: Union{T,S} and S <: Union{T,S}.

Like other abstract types, it cannot be instantiated, even if all of its arguments are non abstract.

Examples

julia> IntOrString = Union{Int,AbstractString}
 Union{Int64, AbstractString}
 
 julia> 1 isa IntOrString # instance of Int is included in the union
@@ -900,12 +900,12 @@
 true
 
 julia> 1.0 isa IntOrString # Float64 is not included because it is neither Int nor AbstractString
-false

Extended Help

Unlike most other parametric types, unions are covariant in their parameters. For example, Union{Real, String} is a subtype of Union{Number, AbstractString}.

The empty union Union{} is the bottom type of Julia.

source
Union{}Keyword
Union{}

Union{}, the empty Union of types, is the type that has no values. That is, it has the defining property isa(x, Union{}) == false for any x. Base.Bottom is defined as its alias and the type of Union{} is Core.TypeofBottom.

Examples

julia> isa(nothing, Union{})
-false
source
Core.UnionAllType
UnionAll

A union of types over all values of a type parameter. UnionAll is used to describe parametric types where the values of some parameters are not known. See the manual section on UnionAll Types.

Examples

julia> typeof(Vector)
+false

Extended Help

Unlike most other parametric types, unions are covariant in their parameters. For example, Union{Real, String} is a subtype of Union{Number, AbstractString}.

The empty union Union{} is the bottom type of Julia.

source
Union{}Keyword
Union{}

Union{}, the empty Union of types, is the type that has no values. That is, it has the defining property isa(x, Union{}) == false for any x. Base.Bottom is defined as its alias and the type of Union{} is Core.TypeofBottom.

Examples

julia> isa(nothing, Union{})
+false
source
Core.UnionAllType
UnionAll

A union of types over all values of a type parameter. UnionAll is used to describe parametric types where the values of some parameters are not known. See the manual section on UnionAll Types.

Examples

julia> typeof(Vector)
 UnionAll
 
 julia> typeof(Vector{Int})
-DataType
source
Core.TupleType
Tuple{Types...}

A tuple is a fixed-length container that can hold any values of different types, but cannot be modified (it is immutable). The values can be accessed via indexing. Tuple literals are written with commas and parentheses:

julia> (1, 1+1)
+DataType
source
Core.TupleType
Tuple{Types...}

A tuple is a fixed-length container that can hold any values of different types, but cannot be modified (it is immutable). The values can be accessed via indexing. Tuple literals are written with commas and parentheses:

julia> (1, 1+1)
 (1, 2)
 
 julia> (1,)
@@ -922,8 +922,8 @@
 ("a", 1)
 
 julia> Tuple{String, Float64}(["a", 1])
-("a", 1.0)

Tuple types are covariant in their parameters: Tuple{Int} is a subtype of Tuple{Any}. Therefore Tuple{Any} is considered an abstract type, and tuple types are only concrete if their parameters are. Tuples do not have field names; fields are only accessed by index. Tuple types may have any number of parameters.

See the manual section on Tuple Types.

See also Vararg, NTuple, ntuple, tuple, NamedTuple.

source
Core.NTupleType
NTuple{N, T}

A compact way of representing the type for a tuple of length N where all elements are of type T.

Examples

julia> isa((1, 2, 3, 4, 5, 6), NTuple{6, Int})
-true

See also ntuple.

source
Core.NamedTupleType
NamedTuple

NamedTuples are, as their name suggests, named Tuples. That is, they're a tuple-like collection of values, where each entry has a unique name, represented as a Symbol. Like Tuples, NamedTuples are immutable; neither the names nor the values can be modified in place after construction.

A named tuple can be created as a tuple literal with keys, e.g. (a=1, b=2), or as a tuple literal with semicolon after the opening parenthesis, e.g. (; a=1, b=2) (this form also accepts programmatically generated names as described below), or using a NamedTuple type as constructor, e.g. NamedTuple{(:a, :b)}((1,2)).

Accessing the value associated with a name in a named tuple can be done using field access syntax, e.g. x.a, or using getindex, e.g. x[:a] or x[(:a, :b)]. A tuple of the names can be obtained using keys, and a tuple of the values can be obtained using values.

Note

Iteration over NamedTuples produces the values without the names. (See example below.) To iterate over the name-value pairs, use the pairs function.

The @NamedTuple macro can be used for conveniently declaring NamedTuple types.

Examples

julia> x = (a=1, b=2)
+("a", 1.0)

Tuple types are covariant in their parameters: Tuple{Int} is a subtype of Tuple{Any}. Therefore Tuple{Any} is considered an abstract type, and tuple types are only concrete if their parameters are. Tuples do not have field names; fields are only accessed by index. Tuple types may have any number of parameters.

See the manual section on Tuple Types.

See also Vararg, NTuple, ntuple, tuple, NamedTuple.

source
Core.NTupleType
NTuple{N, T}

A compact way of representing the type for a tuple of length N where all elements are of type T.

Examples

julia> isa((1, 2, 3, 4, 5, 6), NTuple{6, Int})
+true

See also ntuple.

source
Core.NamedTupleType
NamedTuple

NamedTuples are, as their name suggests, named Tuples. That is, they're a tuple-like collection of values, where each entry has a unique name, represented as a Symbol. Like Tuples, NamedTuples are immutable; neither the names nor the values can be modified in place after construction.

A named tuple can be created as a tuple literal with keys, e.g. (a=1, b=2), or as a tuple literal with semicolon after the opening parenthesis, e.g. (; a=1, b=2) (this form also accepts programmatically generated names as described below), or using a NamedTuple type as constructor, e.g. NamedTuple{(:a, :b)}((1,2)).

Accessing the value associated with a name in a named tuple can be done using field access syntax, e.g. x.a, or using getindex, e.g. x[:a] or x[(:a, :b)]. A tuple of the names can be obtained using keys, and a tuple of the values can be obtained using values.

Note

Iteration over NamedTuples produces the values without the names. (See example below.) To iterate over the name-value pairs, use the pairs function.

The @NamedTuple macro can be used for conveniently declaring NamedTuple types.

Examples

julia> x = (a=1, b=2)
 (a = 1, b = 2)
 
 julia> x.a
@@ -973,7 +973,7 @@
 (x = 0,)
 
 julia> (; t.x)
-(x = 0,)
Julia 1.5

Implicit names from identifiers and dot expressions are available as of Julia 1.5.

Julia 1.7

Use of getindex methods with multiple Symbols is available as of Julia 1.7.

source
Base.@NamedTupleMacro
@NamedTuple{key1::Type1, key2::Type2, ...}
+(x = 0,)
Julia 1.5

Implicit names from identifiers and dot expressions are available as of Julia 1.5.

Julia 1.7

Use of getindex methods with multiple Symbols is available as of Julia 1.7.

source
Base.@NamedTupleMacro
@NamedTuple{key1::Type1, key2::Type2, ...}
 @NamedTuple begin key1::Type1; key2::Type2; ...; end

This macro gives a more convenient syntax for declaring NamedTuple types. It returns a NamedTuple type with the given keys and types, equivalent to NamedTuple{(:key1, :key2, ...), Tuple{Type1,Type2,...}}. If the ::Type declaration is omitted, it is taken to be Any. The begin ... end form allows the declarations to be split across multiple lines (similar to a struct declaration), but is otherwise equivalent. The NamedTuple macro is used when printing NamedTuple types to e.g. the REPL.

For example, the tuple (a=3.1, b="hello") has a type NamedTuple{(:a, :b), Tuple{Float64, String}}, which can also be declared via @NamedTuple as:

julia> @NamedTuple{a::Float64, b::String}
 @NamedTuple{a::Float64, b::String}
 
@@ -981,7 +981,7 @@
            a::Float64
            b::String
        end
-@NamedTuple{a::Float64, b::String}
Julia 1.5

This macro is available as of Julia 1.5.

source
Base.@KwargsMacro
@Kwargs{key1::Type1, key2::Type2, ...}

This macro gives a convenient way to construct the type representation of keyword arguments from the same syntax as @NamedTuple. For example, when we have a function call like func([positional arguments]; kw1=1.0, kw2="2"), we can use this macro to construct the internal type representation of the keyword arguments as @Kwargs{kw1::Float64, kw2::String}. The macro syntax is specifically designed to simplify the signature type of a keyword method when it is printed in the stack trace view.

julia> @Kwargs{init::Int} # the internal representation of keyword arguments
+@NamedTuple{a::Float64, b::String}
Julia 1.5

This macro is available as of Julia 1.5.

source
Base.@KwargsMacro
@Kwargs{key1::Type1, key2::Type2, ...}

This macro gives a convenient way to construct the type representation of keyword arguments from the same syntax as @NamedTuple. For example, when we have a function call like func([positional arguments]; kw1=1.0, kw2="2"), we can use this macro to construct the internal type representation of the keyword arguments as @Kwargs{kw1::Float64, kw2::String}. The macro syntax is specifically designed to simplify the signature type of a keyword method when it is printed in the stack trace view.

julia> @Kwargs{init::Int} # the internal representation of keyword arguments
 Base.Pairs{Symbol, Int64, Tuple{Symbol}, @NamedTuple{init::Int64}}
 
 julia> sum("julia"; init=1)
@@ -1016,14 +1016,14 @@
   [9] sum(a::String; kw::@Kwargs{init::Int64})
     @ Base ./reduce.jl:564 [inlined]
  [10] top-level scope
-    @ REPL[12]:1
Julia 1.10

This macro is available as of Julia 1.10.

source
Base.ValType
Val(c)

Return Val{c}(), which contains no run-time data. Types like this can be used to pass the information between functions through the value c, which must be an isbits value or a Symbol. The intent of this construct is to be able to dispatch on constants directly (at compile time) without having to test the value of the constant at run time.

Examples

julia> f(::Val{true}) = "Good"
+    @ REPL[12]:1
Julia 1.10

This macro is available as of Julia 1.10.

source
Base.ValType
Val(c)

Return Val{c}(), which contains no run-time data. Types like this can be used to pass the information between functions through the value c, which must be an isbits value or a Symbol. The intent of this construct is to be able to dispatch on constants directly (at compile time) without having to test the value of the constant at run time.

Examples

julia> f(::Val{true}) = "Good"
 f (generic function with 1 method)
 
 julia> f(::Val{false}) = "Bad"
 f (generic function with 2 methods)
 
 julia> f(Val(true))
-"Good"
source
Core.VarargConstant
Vararg{T,N}

The last parameter of a tuple type Tuple can be the special value Vararg, which denotes any number of trailing elements. Vararg{T,N} corresponds to exactly N elements of type T. Finally Vararg{T} corresponds to zero or more elements of type T. Vararg tuple types are used to represent the arguments accepted by varargs methods (see the section on Varargs Functions in the manual.)

See also NTuple.

Examples

julia> mytupletype = Tuple{AbstractString, Vararg{Int}}
+"Good"
source
Core.VarargConstant
Vararg{T,N}

The last parameter of a tuple type Tuple can be the special value Vararg, which denotes any number of trailing elements. Vararg{T,N} corresponds to exactly N elements of type T. Finally Vararg{T} corresponds to zero or more elements of type T. Vararg tuple types are used to represent the arguments accepted by varargs methods (see the section on Varargs Functions in the manual.)

See also NTuple.

Examples

julia> mytupletype = Tuple{AbstractString, Vararg{Int}}
 Tuple{AbstractString, Vararg{Int64}}
 
 julia> isa(("1",), mytupletype)
@@ -1036,7 +1036,7 @@
 true
 
 julia> isa(("1",1,2,3.0), mytupletype)
-false
source
Base.SomeType
Some{T}

A wrapper type used in Union{Some{T}, Nothing} to distinguish between the absence of a value (nothing) and the presence of a nothing value (i.e. Some(nothing)).

Use something to access the value wrapped by a Some object.

source
Base.SomeType
Some{T}

A wrapper type used in Union{Some{T}, Nothing} to distinguish between the absence of a value (nothing) and the presence of a nothing value (i.e. Some(nothing)).

Use something to access the value wrapped by a Some object.

source
Base.somethingFunction
something(x...)

Return the first value in the arguments which is not equal to nothing, if any. Otherwise throw an error. Arguments of type Some are unwrapped.

See also coalesce, skipmissing, @something.

Examples

julia> something(nothing, 1)
 1
 
 julia> something(Some(1), nothing)
@@ -1049,7 +1049,7 @@
 missing
 
 julia> something(nothing, nothing)
-ERROR: ArgumentError: No value arguments present
source
Base.@somethingMacro
@something(x...)

Short-circuiting version of something.

Examples

julia> f(x) = (println("f($x)"); nothing);
+ERROR: ArgumentError: No value arguments present
source
Base.@somethingMacro
@something(x...)

Short-circuiting version of something.

Examples

julia> f(x) = (println("f($x)"); nothing);
 
 julia> a = 1;
 
@@ -1069,7 +1069,7 @@
 f(3)
 
 julia> b === nothing
-true
Julia 1.7

This macro is available as of Julia 1.7.

source
Base.Enums.@enumMacro
@enum EnumName[::BaseType] value1[=x] value2[=y]

Create an Enum{BaseType} subtype with name EnumName and enum member values of value1 and value2 with optional assigned values of x and y, respectively. EnumName can be used just like other types and enum member values as regular values, such as

Examples

julia> @enum Fruit apple=1 orange=2 kiwi=3
+true
Julia 1.7

This macro is available as of Julia 1.7.

source
Base.Enums.@enumMacro
@enum EnumName[::BaseType] value1[=x] value2[=y]

Create an Enum{BaseType} subtype with name EnumName and enum member values of value1 and value2 with optional assigned values of x and y, respectively. EnumName can be used just like other types and enum member values as regular values, such as

Examples

julia> @enum Fruit apple=1 orange=2 kiwi=3
 
 julia> f(x::Fruit) = "I'm a Fruit with value: $(Int(x))"
 f (generic function with 1 method)
@@ -1083,7 +1083,7 @@
     value2
 end

BaseType, which defaults to Int32, must be a primitive subtype of Integer. Member values can be converted between the enum type and BaseType. read and write perform these conversions automatically. In case the enum is created with a non-default BaseType, Integer(value1) will return the integer value1 with the type BaseType.

To list all the instances of an enum use instances, e.g.

julia> instances(Fruit)
 (apple, orange, kiwi)

It is possible to construct a symbol from an enum instance:

julia> Symbol(apple)
-:apple
source
Core.ExprType
Expr(head::Symbol, args...)

A type representing compound expressions in parsed julia code (ASTs). Each expression consists of a head Symbol identifying which kind of expression it is (e.g. a call, for loop, conditional statement, etc.), and subexpressions (e.g. the arguments of a call). The subexpressions are stored in a Vector{Any} field called args.

See the manual chapter on Metaprogramming and the developer documentation Julia ASTs.

Examples

julia> Expr(:call, :+, 1, 2)
+:apple
source
Core.ExprType
Expr(head::Symbol, args...)

A type representing compound expressions in parsed julia code (ASTs). Each expression consists of a head Symbol identifying which kind of expression it is (e.g. a call, for loop, conditional statement, etc.), and subexpressions (e.g. the arguments of a call). The subexpressions are stored in a Vector{Any} field called args.

See the manual chapter on Metaprogramming and the developer documentation Julia ASTs.

Examples

julia> Expr(:call, :+, 1, 2)
 :(1 + 2)
 
 julia> dump(:(a ? b : c))
@@ -1092,7 +1092,7 @@
   args: Array{Any}((3,))
     1: Symbol a
     2: Symbol b
-    3: Symbol c
source
Core.SymbolType
Symbol

The type of object used to represent identifiers in parsed julia code (ASTs). Also often used as a name or label to identify an entity (e.g. as a dictionary key). Symbols can be entered using the : quote operator:

julia> :name
+    3: Symbol c
source
Core.SymbolType
Symbol

The type of object used to represent identifiers in parsed julia code (ASTs). Also often used as a name or label to identify an entity (e.g. as a dictionary key). Symbols can be entered using the : quote operator:

julia> :name
 :name
 
 julia> typeof(:name)
@@ -1102,18 +1102,18 @@
 42
 
 julia> eval(:x)
-42

Symbols can also be constructed from strings or other values by calling the constructor Symbol(x...).

Symbols are immutable and their implementation re-uses the same object for all Symbols with the same name.

Unlike strings, Symbols are "atomic" or "scalar" entities that do not support iteration over characters.

source
Core.SymbolMethod
Symbol(x...) -> Symbol

Create a Symbol by concatenating the string representations of the arguments together.

Examples

julia> Symbol("my", "name")
+42

Symbols can also be constructed from strings or other values by calling the constructor Symbol(x...).

Symbols are immutable and their implementation re-uses the same object for all Symbols with the same name.

Unlike strings, Symbols are "atomic" or "scalar" entities that do not support iteration over characters.

source
Core.SymbolMethod
Symbol(x...) -> Symbol

Create a Symbol by concatenating the string representations of the arguments together.

Examples

julia> Symbol("my", "name")
 :myname
 
 julia> Symbol("day", 4)
-:day4
source
Core.ModuleType
Module

A Module is a separate global variable workspace. See module and the manual section about modules for details.

Module(name::Symbol=:anonymous, std_imports=true, default_names=true)

Return a module with the specified name. A baremodule corresponds to Module(:ModuleName, false)

An empty module containing no names at all can be created with Module(:ModuleName, false, false). This module will not import Base or Core and does not contain a reference to itself.

source

Generic Functions

Core.FunctionType
Function

Abstract type of all functions.

Examples

julia> isa(+, Function)
+:day4
source
Core.ModuleType
Module

A Module is a separate global variable workspace. See module and the manual section about modules for details.

Module(name::Symbol=:anonymous, std_imports=true, default_names=true)

Return a module with the specified name. A baremodule corresponds to Module(:ModuleName, false)

An empty module containing no names at all can be created with Module(:ModuleName, false, false). This module will not import Base or Core and does not contain a reference to itself.

source

Generic Functions

Core.FunctionType
Function

Abstract type of all functions.

Examples

julia> isa(+, Function)
 true
 
 julia> typeof(sin)
 typeof(sin) (singleton type of function sin, subtype of Function)
 
 julia> ans <: Function
-true
source
Base.hasmethodFunction
hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool

Determine whether the given generic function has a method matching the given Tuple of argument types with the upper bound of world age given by world.

If a tuple of keyword argument names kwnames is provided, this also checks whether the method of f matching t has the given keyword argument names. If the matching method accepts a variable number of keyword arguments, e.g. with kwargs..., any names given in kwnames are considered valid. Otherwise the provided names must be a subset of the method's keyword arguments.

See also applicable.

Julia 1.2

Providing keyword argument names requires Julia 1.2 or later.

Examples

julia> hasmethod(length, Tuple{Array})
+true
source
Base.hasmethodFunction
hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool

Determine whether the given generic function has a method matching the given Tuple of argument types with the upper bound of world age given by world.

If a tuple of keyword argument names kwnames is provided, this also checks whether the method of f matching t has the given keyword argument names. If the matching method accepts a variable number of keyword arguments, e.g. with kwargs..., any names given in kwnames are considered valid. Otherwise the provided names must be a subset of the method's keyword arguments.

See also applicable.

Julia 1.2

Providing keyword argument names requires Julia 1.2 or later.

Examples

julia> hasmethod(length, Tuple{Array})
 true
 
 julia> f(; oranges=0) = oranges;
@@ -1127,7 +1127,7 @@
 julia> g(; xs...) = 4;
 
 julia> hasmethod(g, Tuple{}, (:a, :b, :c, :d))  # g accepts arbitrary kwargs
-true
source
Core.applicableFunction
applicable(f, args...) -> Bool

Determine whether the given generic function has a method applicable to the given arguments.

See also hasmethod.

Examples

julia> function f(x, y)
+true
source
Core.applicableFunction
applicable(f, args...) -> Bool

Determine whether the given generic function has a method applicable to the given arguments.

See also hasmethod.

Examples

julia> function f(x, y)
            x + y
        end;
 
@@ -1135,7 +1135,7 @@
 false
 
 julia> applicable(f, 1, 2)
-true
source
Base.isambiguousFunction
Base.isambiguous(m1, m2; ambiguous_bottom=false) -> Bool

Determine whether two methods m1 and m2 may be ambiguous for some call signature. This test is performed in the context of other methods of the same function; in isolation, m1 and m2 might be ambiguous, but if a third method resolving the ambiguity has been defined, this returns false. Alternatively, in isolation m1 and m2 might be ordered, but if a third method cannot be sorted with them, they may cause an ambiguity together.

For parametric types, the ambiguous_bottom keyword argument controls whether Union{} counts as an ambiguous intersection of type parameters – when true, it is considered ambiguous, when false it is not.

Examples

julia> foo(x::Complex{<:Integer}) = 1
+true
source
Base.isambiguousFunction
Base.isambiguous(m1, m2; ambiguous_bottom=false) -> Bool

Determine whether two methods m1 and m2 may be ambiguous for some call signature. This test is performed in the context of other methods of the same function; in isolation, m1 and m2 might be ambiguous, but if a third method resolving the ambiguity has been defined, this returns false. Alternatively, in isolation m1 and m2 might be ordered, but if a third method cannot be sorted with them, they may cause an ambiguity together.

For parametric types, the ambiguous_bottom keyword argument controls whether Union{} counts as an ambiguous intersection of type parameters – when true, it is considered ambiguous, when false it is not.

Examples

julia> foo(x::Complex{<:Integer}) = 1
 foo (generic function with 1 method)
 
 julia> foo(x::Complex{<:Rational}) = 2
@@ -1150,7 +1150,7 @@
 true
 
 julia> Base.isambiguous(m1, m2, ambiguous_bottom=false)
-false
source
Core.invokeFunction
invoke(f, argtypes::Type, args...; kwargs...)

Invoke a method for the given generic function f matching the specified types argtypes on the specified arguments args and passing the keyword arguments kwargs. The arguments args must conform with the specified types in argtypes, i.e. conversion is not automatically performed. This method allows invoking a method other than the most specific matching method, which is useful when the behavior of a more general definition is explicitly needed (often as part of the implementation of a more specific method of the same function).

Be careful when using invoke for functions that you don't write. What definition is used for given argtypes is an implementation detail unless the function is explicitly states that calling with certain argtypes is a part of public API. For example, the change between f1 and f2 in the example below is usually considered compatible because the change is invisible by the caller with a normal (non-invoke) call. However, the change is visible if you use invoke.

Examples

julia> f(x::Real) = x^2;
+false
source
Core.invokeFunction
invoke(f, argtypes::Type, args...; kwargs...)

Invoke a method for the given generic function f matching the specified types argtypes on the specified arguments args and passing the keyword arguments kwargs. The arguments args must conform with the specified types in argtypes, i.e. conversion is not automatically performed. This method allows invoking a method other than the most specific matching method, which is useful when the behavior of a more general definition is explicitly needed (often as part of the implementation of a more specific method of the same function).

Be careful when using invoke for functions that you don't write. What definition is used for given argtypes is an implementation detail unless the function is explicitly states that calling with certain argtypes is a part of public API. For example, the change between f1 and f2 in the example below is usually considered compatible because the change is invisible by the caller with a normal (non-invoke) call. However, the change is visible if you use invoke.

Examples

julia> f(x::Real) = x^2;
 
 julia> f(x::Integer) = 1 + invoke(f, Tuple{Real}, x);
 
@@ -1174,7 +1174,7 @@
 Real
 
 julia> invoke(f2, Tuple{Real}, 1)
-Integer
source
Base.@invokeMacro
@invoke f(arg::T, ...; kwargs...)

Provides a convenient way to call invoke by expanding @invoke f(arg1::T1, arg2::T2; kwargs...) to invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...). When an argument's type annotation is omitted, it's replaced with Core.Typeof that argument. To invoke a method where an argument is untyped or explicitly typed as Any, annotate the argument with ::Any.

It also supports the following syntax:

  • @invoke (x::X).f expands to invoke(getproperty, Tuple{X,Symbol}, x, :f)
  • @invoke (x::X).f = v::V expands to invoke(setproperty!, Tuple{X,Symbol,V}, x, :f, v)
  • @invoke (xs::Xs)[i::I] expands to invoke(getindex, Tuple{Xs,I}, xs, i)
  • @invoke (xs::Xs)[i::I] = v::V expands to invoke(setindex!, Tuple{Xs,V,I}, xs, v, i)

Examples

julia> @macroexpand @invoke f(x::T, y)
+Integer
source
Base.@invokeMacro
@invoke f(arg::T, ...; kwargs...)

Provides a convenient way to call invoke by expanding @invoke f(arg1::T1, arg2::T2; kwargs...) to invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...). When an argument's type annotation is omitted, it's replaced with Core.Typeof that argument. To invoke a method where an argument is untyped or explicitly typed as Any, annotate the argument with ::Any.

It also supports the following syntax:

  • @invoke (x::X).f expands to invoke(getproperty, Tuple{X,Symbol}, x, :f)
  • @invoke (x::X).f = v::V expands to invoke(setproperty!, Tuple{X,Symbol,V}, x, :f, v)
  • @invoke (xs::Xs)[i::I] expands to invoke(getindex, Tuple{Xs,I}, xs, i)
  • @invoke (xs::Xs)[i::I] = v::V expands to invoke(setindex!, Tuple{Xs,V,I}, xs, v, i)

Examples

julia> @macroexpand @invoke f(x::T, y)
 :(Core.invoke(f, Tuple{T, Core.Typeof(y)}, x, y))
 
 julia> @invoke 420::Integer % Unsigned
@@ -1190,7 +1190,7 @@
 :(Core.invoke(Base.getindex, Tuple{Xs, I}, xs, i))
 
 julia> @macroexpand @invoke (xs::Xs)[i::I] = v::V
-:(Core.invoke(Base.setindex!, Tuple{Xs, V, I}, xs, v, i))
Julia 1.7

This macro requires Julia 1.7 or later.

Julia 1.9

This macro is exported as of Julia 1.9.

Julia 1.10

The additional syntax is supported as of Julia 1.10.

source
Base.invokelatestFunction
invokelatest(f, args...; kwargs...)

Calls f(args...; kwargs...), but guarantees that the most recent method of f will be executed. This is useful in specialized circumstances, e.g. long-running event loops or callback functions that may call obsolete versions of a function f. (The drawback is that invokelatest is somewhat slower than calling f directly, and the type of the result cannot be inferred by the compiler.)

Julia 1.9

Prior to Julia 1.9, this function was not exported, and was called as Base.invokelatest.

source
Base.@invokelatestMacro
@invokelatest f(args...; kwargs...)

Provides a convenient way to call invokelatest. @invokelatest f(args...; kwargs...) will simply be expanded into Base.invokelatest(f, args...; kwargs...).

It also supports the following syntax:

  • @invokelatest x.f expands to Base.invokelatest(getproperty, x, :f)
  • @invokelatest x.f = v expands to Base.invokelatest(setproperty!, x, :f, v)
  • @invokelatest xs[i] expands to Base.invokelatest(getindex, xs, i)
  • @invokelatest xs[i] = v expands to Base.invokelatest(setindex!, xs, v, i)
julia> @macroexpand @invokelatest f(x; kw=kwv)
+:(Core.invoke(Base.setindex!, Tuple{Xs, V, I}, xs, v, i))
Julia 1.7

This macro requires Julia 1.7 or later.

Julia 1.9

This macro is exported as of Julia 1.9.

Julia 1.10

The additional syntax is supported as of Julia 1.10.

source
Base.invokelatestFunction
invokelatest(f, args...; kwargs...)

Calls f(args...; kwargs...), but guarantees that the most recent method of f will be executed. This is useful in specialized circumstances, e.g. long-running event loops or callback functions that may call obsolete versions of a function f. (The drawback is that invokelatest is somewhat slower than calling f directly, and the type of the result cannot be inferred by the compiler.)

Julia 1.9

Prior to Julia 1.9, this function was not exported, and was called as Base.invokelatest.

source
Base.@invokelatestMacro
@invokelatest f(args...; kwargs...)

Provides a convenient way to call invokelatest. @invokelatest f(args...; kwargs...) will simply be expanded into Base.invokelatest(f, args...; kwargs...).

It also supports the following syntax:

  • @invokelatest x.f expands to Base.invokelatest(getproperty, x, :f)
  • @invokelatest x.f = v expands to Base.invokelatest(setproperty!, x, :f, v)
  • @invokelatest xs[i] expands to Base.invokelatest(getindex, xs, i)
  • @invokelatest xs[i] = v expands to Base.invokelatest(setindex!, xs, v, i)
julia> @macroexpand @invokelatest f(x; kw=kwv)
 :(Base.invokelatest(f, x; kw = kwv))
 
 julia> @macroexpand @invokelatest x.f
@@ -1203,14 +1203,14 @@
 :(Base.invokelatest(Base.getindex, xs, i))
 
 julia> @macroexpand @invokelatest xs[i] = v
-:(Base.invokelatest(Base.setindex!, xs, v, i))
Julia 1.7

This macro requires Julia 1.7 or later.

Julia 1.9

Prior to Julia 1.9, this macro was not exported, and was called as Base.@invokelatest.

Julia 1.10

The additional x.f and xs[i] syntax requires Julia 1.10.

source
newKeyword
new, or new{A,B,...}

Special function available to inner constructors which creates a new object of the type. The form new{A,B,...} explicitly specifies values of parameters for parametric types. See the manual section on Inner Constructor Methods for more information.

source
Base.:|>Function
|>(x, f)

Infix operator which applies function f to the argument x. This allows f(g(x)) to be written x |> g |> f. When used with anonymous functions, parentheses are typically required around the definition to get the intended chain.

Examples

julia> 4 |> inv
+:(Base.invokelatest(Base.setindex!, xs, v, i))
Julia 1.7

This macro requires Julia 1.7 or later.

Julia 1.9

Prior to Julia 1.9, this macro was not exported, and was called as Base.@invokelatest.

Julia 1.10

The additional x.f and xs[i] syntax requires Julia 1.10.

source
newKeyword
new, or new{A,B,...}

Special function available to inner constructors which creates a new object of the type. The form new{A,B,...} explicitly specifies values of parameters for parametric types. See the manual section on Inner Constructor Methods for more information.

source
Base.:|>Function
|>(x, f)

Infix operator which applies function f to the argument x. This allows f(g(x)) to be written x |> g |> f. When used with anonymous functions, parentheses are typically required around the definition to get the intended chain.

Examples

julia> 4 |> inv
 0.25
 
 julia> [2, 3, 5] |> sum |> inv
 0.1
 
 julia> [0 1; 2 3] .|> (x -> x^2) |> sum
-14
source
Base.:∘Function
f ∘ g

Compose functions: i.e. (f ∘ g)(args...; kwargs...) means f(g(args...; kwargs...)). The symbol can be entered in the Julia REPL (and most editors, appropriately configured) by typing \circ<tab>.

Function composition also works in prefix form: ∘(f, g) is the same as f ∘ g. The prefix form supports composition of multiple functions: ∘(f, g, h) = f ∘ g ∘ h and splatting ∘(fs...) for composing an iterable collection of functions. The last argument to execute first.

Julia 1.4

Multiple function composition requires at least Julia 1.4.

Julia 1.5

Composition of one function ∘(f) requires at least Julia 1.5.

Julia 1.7

Using keyword arguments requires at least Julia 1.7.

Examples

julia> map(uppercase∘first, ["apple", "banana", "carrot"])
+14
source
Base.:∘Function
f ∘ g

Compose functions: i.e. (f ∘ g)(args...; kwargs...) means f(g(args...; kwargs...)). The symbol can be entered in the Julia REPL (and most editors, appropriately configured) by typing \circ<tab>.

Function composition also works in prefix form: ∘(f, g) is the same as f ∘ g. The prefix form supports composition of multiple functions: ∘(f, g, h) = f ∘ g ∘ h and splatting ∘(fs...) for composing an iterable collection of functions. The last argument to execute first.

Julia 1.4

Multiple function composition requires at least Julia 1.4.

Julia 1.5

Composition of one function ∘(f) requires at least Julia 1.5.

Julia 1.7

Using keyword arguments requires at least Julia 1.7.

Examples

julia> map(uppercase∘first, ["apple", "banana", "carrot"])
 3-element Vector{Char}:
  'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
  'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
@@ -1230,7 +1230,7 @@
        ];
 
 julia> ∘(fs...)(3)
-2.0

See also ComposedFunction, !f::Function.

source
Base.ComposedFunctionType
ComposedFunction{Outer,Inner} <: Function

Represents the composition of two callable objects outer::Outer and inner::Inner. That is

ComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))

The preferred way to construct an instance of ComposedFunction is to use the composition operator :

julia> sin ∘ cos === ComposedFunction(sin, cos)
+2.0

See also ComposedFunction, !f::Function.

source
Base.ComposedFunctionType
ComposedFunction{Outer,Inner} <: Function

Represents the composition of two callable objects outer::Outer and inner::Inner. That is

ComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))

The preferred way to construct an instance of ComposedFunction is to use the composition operator :

julia> sin ∘ cos === ComposedFunction(sin, cos)
 true
 
 julia> typeof(sin∘cos)
@@ -1241,7 +1241,7 @@
 true
 
 julia> composition.inner === cos
-true
Julia 1.6

ComposedFunction requires at least Julia 1.6. In earlier versions returns an anonymous function instead.

See also .

source
Base.splatFunction
splat(f)

Equivalent to

    my_splat(f) = args->f(args...)

i.e. given a function returns a new function that takes one argument and splats it into the original function. This is useful as an adaptor to pass a multi-argument function in a context that expects a single argument, but passes a tuple as that single argument.

Examples

julia> map(splat(+), zip(1:3,4:6))
+true
Julia 1.6

ComposedFunction requires at least Julia 1.6. In earlier versions returns an anonymous function instead.

See also .

source
Base.splatFunction
splat(f)

Equivalent to

    my_splat(f) = args->f(args...)

i.e. given a function returns a new function that takes one argument and splats it into the original function. This is useful as an adaptor to pass a multi-argument function in a context that expects a single argument, but passes a tuple as that single argument.

Examples

julia> map(splat(+), zip(1:3,4:6))
 3-element Vector{Int64}:
  5
  7
@@ -1251,7 +1251,7 @@
 splat(+)
 
 julia> my_add((1,2,3))
-6
source
Base.Fix1Type
Fix1(f, x)

A type representing a partially-applied version of the two-argument function f, with the first argument fixed to the value "x". In other words, Fix1(f, x) behaves similarly to y->f(x, y).

See also Fix2.

source
Base.Fix2Type
Fix2(f, x)

A type representing a partially-applied version of the two-argument function f, with the second argument fixed to the value "x". In other words, Fix2(f, x) behaves similarly to y->f(y, x).

source

Syntax

Core.evalFunction
Core.eval(m::Module, expr)

Evaluate an expression in the given module and return the result.

source
evalFunction
eval(expr)

Evaluate an expression in the global scope of the containing module. Every Module (except those defined with baremodule) has its own 1-argument definition of eval, which evaluates expressions in that module.

source
Base.@evalMacro
@eval [mod,] ex

Evaluate an expression with values interpolated into it using eval. If two arguments are provided, the first is the module to evaluate in.

source
Base.evalfileFunction
evalfile(path::AbstractString, args::Vector{String}=String[])

Load the file into an anonymous module using include, evaluate all expressions, and return the value of the last expression. The optional args argument can be used to set the input arguments of the script (i.e. the global ARGS variable). Note that definitions (e.g. methods, globals) are evaluated in the anonymous module and do not affect the current module.

Examples

julia> write("testfile.jl", """
+6
source
Base.Fix1Type
Fix1(f, x)

A type representing a partially-applied version of the two-argument function f, with the first argument fixed to the value "x". In other words, Fix1(f, x) behaves similarly to y->f(x, y).

See also Fix2.

source
Base.Fix2Type
Fix2(f, x)

A type representing a partially-applied version of the two-argument function f, with the second argument fixed to the value "x". In other words, Fix2(f, x) behaves similarly to y->f(y, x).

source

Syntax

Core.evalFunction
Core.eval(m::Module, expr)

Evaluate an expression in the given module and return the result.

source
evalFunction
eval(expr)

Evaluate an expression in the global scope of the containing module. Every Module (except those defined with baremodule) has its own 1-argument definition of eval, which evaluates expressions in that module.

source
Base.@evalMacro
@eval [mod,] ex

Evaluate an expression with values interpolated into it using eval. If two arguments are provided, the first is the module to evaluate in.

source
Base.evalfileFunction
evalfile(path::AbstractString, args::Vector{String}=String[])

Load the file into an anonymous module using include, evaluate all expressions, and return the value of the last expression. The optional args argument can be used to set the input arguments of the script (i.e. the global ARGS variable). Note that definitions (e.g. methods, globals) are evaluated in the anonymous module and do not affect the current module.

Examples

julia> write("testfile.jl", """
            @show ARGS
            1 + 1
        """);
@@ -1262,13 +1262,13 @@
 julia> x
 2
 
-julia> rm("testfile.jl")
source
Base.escFunction
esc(e)

Only valid in the context of an Expr returned from a macro. Prevents the macro hygiene pass from turning embedded variables into gensym variables. See the Macros section of the Metaprogramming chapter of the manual for more details and examples.

source
Base.@inboundsMacro
@inbounds(blk)

Eliminates array bounds checking within expressions.

In the example below the in-range check for referencing element i of array A is skipped to improve performance.

function sum(A::AbstractArray)
+julia> rm("testfile.jl")
source
Base.escFunction
esc(e)

Only valid in the context of an Expr returned from a macro. Prevents the macro hygiene pass from turning embedded variables into gensym variables. See the Macros section of the Metaprogramming chapter of the manual for more details and examples.

source
Base.@inboundsMacro
@inbounds(blk)

Eliminates array bounds checking within expressions.

In the example below the in-range check for referencing element i of array A is skipped to improve performance.

function sum(A::AbstractArray)
     r = zero(eltype(A))
     for i in eachindex(A)
         @inbounds r += A[i]
     end
     return r
-end
Warning

Using @inbounds may return incorrect results/crashes/corruption for out-of-bounds indices. The user is responsible for checking it manually. Only use @inbounds when it is certain from the information locally available that all accesses are in bounds. In particular, using 1:length(A) instead of eachindex(A) in a function like the one above is not safely inbounds because the first index of A may not be 1 for all user defined types that subtype AbstractArray.

source
Base.@boundscheckMacro
@boundscheck(blk)

Annotates the expression blk as a bounds checking block, allowing it to be elided by @inbounds.

Note

The function in which @boundscheck is written must be inlined into its caller in order for @inbounds to have effect.

Examples

julia> @inline function g(A, i)
+end
Warning

Using @inbounds may return incorrect results/crashes/corruption for out-of-bounds indices. The user is responsible for checking it manually. Only use @inbounds when it is certain from the information locally available that all accesses are in bounds. In particular, using 1:length(A) instead of eachindex(A) in a function like the one above is not safely inbounds because the first index of A may not be 1 for all user defined types that subtype AbstractArray.

source
Base.@boundscheckMacro
@boundscheck(blk)

Annotates the expression blk as a bounds checking block, allowing it to be elided by @inbounds.

Note

The function in which @boundscheck is written must be inlined into its caller in order for @inbounds to have effect.

Examples

julia> @inline function g(A, i)
            @boundscheck checkbounds(A, i)
            return "accessing ($A)[$i]"
        end;
@@ -1287,7 +1287,7 @@
  [5] top-level scope
 
 julia> f2()
-"accessing (1:2)[-1]"
Warning

The @boundscheck annotation allows you, as a library writer, to opt-in to allowing other code to remove your bounds checks with @inbounds. As noted there, the caller must verify—using information they can access—that their accesses are valid before using @inbounds. For indexing into your AbstractArray subclasses, for example, this involves checking the indices against its axes. Therefore, @boundscheck annotations should only be added to a getindex or setindex! implementation after you are certain its behavior is correct.

source
Base.@inlineMacro
@inline

Give a hint to the compiler that this function is worth inlining.

Small functions typically do not need the @inline annotation, as the compiler does it automatically. By using @inline on bigger functions, an extra nudge can be given to the compiler to inline it.

@inline can be applied immediately before a function definition or within a function body.

# annotate long-form definition
+"accessing (1:2)[-1]"
Warning

The @boundscheck annotation allows you, as a library writer, to opt-in to allowing other code to remove your bounds checks with @inbounds. As noted there, the caller must verify—using information they can access—that their accesses are valid before using @inbounds. For indexing into your AbstractArray subclasses, for example, this involves checking the indices against its axes. Therefore, @boundscheck annotations should only be added to a getindex or setindex! implementation after you are certain its behavior is correct.

source
Base.@inlineMacro
@inline

Give a hint to the compiler that this function is worth inlining.

Small functions typically do not need the @inline annotation, as the compiler does it automatically. By using @inline on bigger functions, an extra nudge can be given to the compiler to inline it.

@inline can be applied immediately before a function definition or within a function body.

# annotate long-form definition
 @inline function longdef(x)
     ...
 end
@@ -1313,7 +1313,7 @@
     a = @inline f(a0)  # the compiler will try to inline this call
     b = f(b0)          # the compiler will NOT try to inline this call
     return a, b
-end
Warning

Although a callsite annotation will try to force inlining in regardless of the cost model, there are still chances it can't succeed in it. Especially, recursive calls can not be inlined even if they are annotated as @inlined.

Julia 1.8

The callsite annotation requires at least Julia 1.8.

source
Base.@noinlineMacro
@noinline

Give a hint to the compiler that it should not inline a function.

Small functions are typically inlined automatically. By using @noinline on small functions, auto-inlining can be prevented.

@noinline can be applied immediately before a function definition or within a function body.

# annotate long-form definition
+end
Warning

Although a callsite annotation will try to force inlining in regardless of the cost model, there are still chances it can't succeed in it. Especially, recursive calls can not be inlined even if they are annotated as @inlined.

Julia 1.8

The callsite annotation requires at least Julia 1.8.

source
Base.@noinlineMacro
@noinline

Give a hint to the compiler that it should not inline a function.

Small functions are typically inlined automatically. By using @noinline on small functions, auto-inlining can be prevented.

@noinline can be applied immediately before a function definition or within a function body.

# annotate long-form definition
 @noinline function longdef(x)
     ...
 end
@@ -1339,7 +1339,7 @@
     a = @noinline f(a0)  # the compiler will NOT try to inline this call
     b = f(b0)            # the compiler will try to inline this call
     return a, b
-end
Julia 1.8

The callsite annotation requires at least Julia 1.8.


Note

If the function is trivial (for example returning a constant) it might get inlined anyway.

source
Base.@nospecializeMacro
@nospecialize

Applied to a function argument name, hints to the compiler that the method implementation should not be specialized for different types of that argument, but instead use the declared type for that argument. It can be applied to an argument within a formal argument list, or in the function body. When applied to an argument, the macro must wrap the entire argument expression, e.g., @nospecialize(x::Real) or @nospecialize(i::Integer...) rather than wrapping just the argument name. When used in a function body, the macro must occur in statement position and before any code.

When used without arguments, it applies to all arguments of the parent scope. In local scope, this means all arguments of the containing function. In global (top-level) scope, this means all methods subsequently defined in the current module.

Specialization can reset back to the default by using @specialize.

function example_function(@nospecialize x)
+end
Julia 1.8

The callsite annotation requires at least Julia 1.8.


Note

If the function is trivial (for example returning a constant) it might get inlined anyway.

source
Base.@nospecializeMacro
@nospecialize

Applied to a function argument name, hints to the compiler that the method implementation should not be specialized for different types of that argument, but instead use the declared type for that argument. It can be applied to an argument within a formal argument list, or in the function body. When applied to an argument, the macro must wrap the entire argument expression, e.g., @nospecialize(x::Real) or @nospecialize(i::Integer...) rather than wrapping just the argument name. When used in a function body, the macro must occur in statement position and before any code.

When used without arguments, it applies to all arguments of the parent scope. In local scope, this means all arguments of the containing function. In global (top-level) scope, this means all methods subsequently defined in the current module.

Specialization can reset back to the default by using @specialize.

function example_function(@nospecialize x)
     ...
 end
 
@@ -1364,7 +1364,7 @@
 CodeInfo(
 1 ─ %1 = invoke Main.g(_2::AbstractArray)::Float64
 └──      return %1
-) => Float64

Here, the @nospecialize annotation results in the equivalent of

f(A::AbstractArray) = invoke(g, Tuple{AbstractArray}, A)

ensuring that only one version of native code will be generated for g, one that is generic for any AbstractArray. However, the specific return type is still inferred for both g and f, and this is still used in optimizing the callers of f and g.

source
Base.@specializeMacro
@specialize

Reset the specialization hint for an argument back to the default. For details, see @nospecialize.

source
Base.@nospecializeinferMacro
Base.@nospecializeinfer function f(args...)
+) => Float64

Here, the @nospecialize annotation results in the equivalent of

f(A::AbstractArray) = invoke(g, Tuple{AbstractArray}, A)

ensuring that only one version of native code will be generated for g, one that is generic for any AbstractArray. However, the specific return type is still inferred for both g and f, and this is still used in optimizing the callers of f and g.

source
Base.@specializeMacro
@specialize

Reset the specialization hint for an argument back to the default. For details, see @nospecialize.

source
Base.@nospecializeinferMacro
Base.@nospecializeinfer function f(args...)
     @nospecialize ...
     ...
 end
@@ -1378,7 +1378,7 @@
 CodeInfo(
 1 ─ %1 = invoke Main.g(_2::AbstractArray)::Any
 └──      return %1
-) => Any

In this example, f will be inferred for each specific type of A, but g will only be inferred once with the declared argument type A::AbstractArray, meaning that the compiler will not likely see the excessive inference time on it while it can not infer the concrete return type of it. Without the @nospecializeinfer, f([1.0]) would infer the return type of g as Float64, indicating that inference ran for g(::Vector{Float64}) despite the prohibition on specialized code generation.

source
Base.@constpropMacro
Base.@constprop setting [ex]

Control the mode of interprocedural constant propagation for the annotated function.

Two settings are supported:

  • Base.@constprop :aggressive [ex]: apply constant propagation aggressively. For a method where the return type depends on the value of the arguments, this can yield improved inference results at the cost of additional compile time.
  • Base.@constprop :none [ex]: disable constant propagation. This can reduce compile times for functions that Julia might otherwise deem worthy of constant-propagation. Common cases are for functions with Bool- or Symbol-valued arguments or keyword arguments.

Base.@constprop can be applied immediately before a function definition or within a function body.

# annotate long-form definition
+) => Any

In this example, f will be inferred for each specific type of A, but g will only be inferred once with the declared argument type A::AbstractArray, meaning that the compiler will not likely see the excessive inference time on it while it can not infer the concrete return type of it. Without the @nospecializeinfer, f([1.0]) would infer the return type of g as Float64, indicating that inference ran for g(::Vector{Float64}) despite the prohibition on specialized code generation.

source
Base.@constpropMacro
Base.@constprop setting [ex]

Control the mode of interprocedural constant propagation for the annotated function.

Two settings are supported:

  • Base.@constprop :aggressive [ex]: apply constant propagation aggressively. For a method where the return type depends on the value of the arguments, this can yield improved inference results at the cost of additional compile time.
  • Base.@constprop :none [ex]: disable constant propagation. This can reduce compile times for functions that Julia might otherwise deem worthy of constant-propagation. Common cases are for functions with Bool- or Symbol-valued arguments or keyword arguments.

Base.@constprop can be applied immediately before a function definition or within a function body.

# annotate long-form definition
 Base.@constprop :aggressive function longdef(x)
     ...
 end
@@ -1390,7 +1390,7 @@
 f() do
     Base.@constprop :aggressive
     ...
-end
Julia 1.10

The usage within a function body requires at least Julia 1.10.

source
Base.gensymFunction
gensym([tag])

Generates a symbol which will not conflict with other variable names (in the same module).

source
Base.@gensymMacro
@gensym

Generates a gensym symbol for a variable. For example, @gensym x y is transformed into x = gensym("x"); y = gensym("y").

source
var"name"Keyword
var

The syntax var"#example#" refers to a variable named Symbol("#example#"), even though #example# is not a valid Julia identifier name.

This can be useful for interoperability with programming languages which have different rules for the construction of valid identifiers. For example, to refer to the R variable draw.segments, you can use var"draw.segments" in your Julia code.

It is also used to show julia source code which has gone through macro hygiene or otherwise contains variable names which can't be parsed normally.

Note that this syntax requires parser support so it is expanded directly by the parser rather than being implemented as a normal string macro @var_str.

Julia 1.3

This syntax requires at least Julia 1.3.

source
Base.@gotoMacro
@goto name

@goto name unconditionally jumps to the statement at the location @label name.

@label and @goto cannot create jumps to different top-level statements. Attempts cause an error. To still use @goto, enclose the @label and @goto in a block.

source
Base.@labelMacro
@label name

Labels a statement with the symbolic label name. The label marks the end-point of an unconditional jump with @goto name.

source
Base.SimdLoop.@simdMacro
@simd

Annotate a for loop to allow the compiler to take extra liberties to allow loop re-ordering

Warning

This feature is experimental and could change or disappear in future versions of Julia. Incorrect use of the @simd macro may cause unexpected results.

The object iterated over in a @simd for loop should be a one-dimensional range. By using @simd, you are asserting several properties of the loop:

  • It is safe to execute iterations in arbitrary or overlapping order, with special consideration for reduction variables.
  • Floating-point operations on reduction variables can be reordered or contracted, possibly causing different results than without @simd.

In many cases, Julia is able to automatically vectorize inner for loops without the use of @simd. Using @simd gives the compiler a little extra leeway to make it possible in more situations. In either case, your inner loop should have the following properties to allow vectorization:

  • The loop must be an innermost loop
  • The loop body must be straight-line code. Therefore, @inbounds is currently needed for all array accesses. The compiler can sometimes turn short &&, ||, and ?: expressions into straight-line code if it is safe to evaluate all operands unconditionally. Consider using the ifelse function instead of ?: in the loop if it is safe to do so.
  • Accesses must have a stride pattern and cannot be "gathers" (random-index reads) or "scatters" (random-index writes).
  • The stride should be unit stride.
Note

The @simd does not assert by default that the loop is completely free of loop-carried memory dependencies, which is an assumption that can easily be violated in generic code. If you are writing non-generic code, you can use @simd ivdep for ... end to also assert that:

  • There exists no loop-carried memory dependencies
  • No iteration ever waits on a previous iteration to make forward progress.
source
Base.@pollyMacro
@polly

Tells the compiler to apply the polyhedral optimizer Polly to a function.

source
Base.@generatedMacro
@generated f

@generated is used to annotate a function which will be generated. In the body of the generated function, only types of arguments can be read (not the values). The function returns a quoted expression evaluated when the function is called. The @generated macro should not be used on functions mutating the global scope or depending on mutable elements.

See Metaprogramming for further details.

Examples

julia> @generated function bar(x)
+end
Julia 1.10

The usage within a function body requires at least Julia 1.10.

source
Base.gensymFunction
gensym([tag])

Generates a symbol which will not conflict with other variable names (in the same module).

source
Base.@gensymMacro
@gensym

Generates a gensym symbol for a variable. For example, @gensym x y is transformed into x = gensym("x"); y = gensym("y").

source
var"name"Keyword
var

The syntax var"#example#" refers to a variable named Symbol("#example#"), even though #example# is not a valid Julia identifier name.

This can be useful for interoperability with programming languages which have different rules for the construction of valid identifiers. For example, to refer to the R variable draw.segments, you can use var"draw.segments" in your Julia code.

It is also used to show julia source code which has gone through macro hygiene or otherwise contains variable names which can't be parsed normally.

Note that this syntax requires parser support so it is expanded directly by the parser rather than being implemented as a normal string macro @var_str.

Julia 1.3

This syntax requires at least Julia 1.3.

source
Base.@gotoMacro
@goto name

@goto name unconditionally jumps to the statement at the location @label name.

@label and @goto cannot create jumps to different top-level statements. Attempts cause an error. To still use @goto, enclose the @label and @goto in a block.

source
Base.@labelMacro
@label name

Labels a statement with the symbolic label name. The label marks the end-point of an unconditional jump with @goto name.

source
Base.SimdLoop.@simdMacro
@simd

Annotate a for loop to allow the compiler to take extra liberties to allow loop re-ordering

Warning

This feature is experimental and could change or disappear in future versions of Julia. Incorrect use of the @simd macro may cause unexpected results.

The object iterated over in a @simd for loop should be a one-dimensional range. By using @simd, you are asserting several properties of the loop:

  • It is safe to execute iterations in arbitrary or overlapping order, with special consideration for reduction variables.
  • Floating-point operations on reduction variables can be reordered or contracted, possibly causing different results than without @simd.

In many cases, Julia is able to automatically vectorize inner for loops without the use of @simd. Using @simd gives the compiler a little extra leeway to make it possible in more situations. In either case, your inner loop should have the following properties to allow vectorization:

  • The loop must be an innermost loop
  • The loop body must be straight-line code. Therefore, @inbounds is currently needed for all array accesses. The compiler can sometimes turn short &&, ||, and ?: expressions into straight-line code if it is safe to evaluate all operands unconditionally. Consider using the ifelse function instead of ?: in the loop if it is safe to do so.
  • Accesses must have a stride pattern and cannot be "gathers" (random-index reads) or "scatters" (random-index writes).
  • The stride should be unit stride.
Note

The @simd does not assert by default that the loop is completely free of loop-carried memory dependencies, which is an assumption that can easily be violated in generic code. If you are writing non-generic code, you can use @simd ivdep for ... end to also assert that:

  • There exists no loop-carried memory dependencies
  • No iteration ever waits on a previous iteration to make forward progress.
source
Base.@pollyMacro
@polly

Tells the compiler to apply the polyhedral optimizer Polly to a function.

source
Base.@generatedMacro
@generated f

@generated is used to annotate a function which will be generated. In the body of the generated function, only types of arguments can be read (not the values). The function returns a quoted expression evaluated when the function is called. The @generated macro should not be used on functions mutating the global scope or depending on mutable elements.

See Metaprogramming for further details.

Examples

julia> @generated function bar(x)
            if x <: Integer
                return :(x ^ 2)
            else
@@ -1403,7 +1403,7 @@
 16
 
 julia> bar("baz")
-"baz"
source
Base.@assume_effectsMacro
Base.@assume_effects setting... [ex]

Override the compiler's effect modeling. This macro can be used in several contexts:

  1. Immediately before a method definition, to override the entire effect modeling of the applied method.
  2. Within a function body without any arguments, to override the entire effect modeling of the enclosing method.
  3. Applied to a code block, to override the local effect modeling of the applied code block.

Examples

julia> Base.@assume_effects :terminates_locally function fact(x)
+"baz"
source
Base.@assume_effectsMacro
Base.@assume_effects setting... [ex]

Override the compiler's effect modeling. This macro can be used in several contexts:

  1. Immediately before a method definition, to override the entire effect modeling of the applied method.
  2. Within a function body without any arguments, to override the entire effect modeling of the enclosing method.
  3. Applied to a code block, to override the local effect modeling of the applied code block.

Examples

julia> Base.@assume_effects :terminates_locally function fact(x)
            # usage 1:
            # this :terminates_locally allows `fact` to be constant-folded
            res = 1
@@ -1458,7 +1458,7 @@
        end |> only
 CodeInfo(
 1 ─     return (2, 6, 24)
-) => Tuple{Int64, Int64, Int64}
Julia 1.8

Using Base.@assume_effects requires Julia version 1.8.

Julia 1.10

The usage within a function body requires at least Julia 1.10.

Julia 1.11

The code block annotation requires at least Julia 1.11.

Warning

Improper use of this macro causes undefined behavior (including crashes, incorrect answers, or other hard to track bugs). Use with care and only as a last resort if absolutely required. Even in such a case, you SHOULD take all possible steps to minimize the strength of the effect assertion (e.g., do not use :total if :nothrow would have been sufficient).

In general, each setting value makes an assertion about the behavior of the function, without requiring the compiler to prove that this behavior is indeed true. These assertions are made for all world ages. It is thus advisable to limit the use of generic functions that may later be extended to invalidate the assumption (which would cause undefined behavior).

The following settings are supported.

  • :consistent
  • :effect_free
  • :nothrow
  • :terminates_globally
  • :terminates_locally
  • :notaskstate
  • :inaccessiblememonly
  • :noub
  • :noub_if_noinbounds
  • :foldable
  • :removable
  • :total

Extended help


:consistent

The :consistent setting asserts that for egal (===) inputs:

  • The manner of termination (return value, exception, non-termination) will always be the same.
  • If the method returns, the results will always be egal.
Note

This in particular implies that the method must not return a freshly allocated mutable object. Multiple allocations of mutable objects (even with identical contents) are not egal.

Note

The :consistent-cy assertion is made world-age wise. More formally, write $fᵢ$ for the evaluation of $f$ in world-age $i$, then we require:

\[∀ i, x, y: x ≡ y → fᵢ(x) ≡ fᵢ(y)\]

However, for two world ages $i$, $j$ s.t. $i ≠ j$, we may have $fᵢ(x) ≢ fⱼ(y)$.

A further implication is that :consistent functions may not make their return value dependent on the state of the heap or any other global state that is not constant for a given world age.

Note

The :consistent-cy includes all legal rewrites performed by the optimizer. For example, floating-point fastmath operations are not considered :consistent, because the optimizer may rewrite them causing the output to not be :consistent, even for the same world age (e.g. because one ran in the interpreter, while the other was optimized).

Note

If :consistent functions terminate by throwing an exception, that exception itself is not required to meet the egality requirement specified above.


:effect_free

The :effect_free setting asserts that the method is free of externally semantically visible side effects. The following is an incomplete list of externally semantically visible side effects:

  • Changing the value of a global variable.
  • Mutating the heap (e.g. an array or mutable value), except as noted below
  • Changing the method table (e.g. through calls to eval)
  • File/Network/etc. I/O
  • Task switching

However, the following are explicitly not semantically visible, even if they may be observable:

  • Memory allocations (both mutable and immutable)
  • Elapsed time
  • Garbage collection
  • Heap mutations of objects whose lifetime does not exceed the method (i.e. were allocated in the method and do not escape).
  • The returned value (which is externally visible, but not a side effect)

The rule of thumb here is that an externally visible side effect is anything that would affect the execution of the remainder of the program if the function were not executed.

Note

The :effect_free assertion is made both for the method itself and any code that is executed by the method. Keep in mind that the assertion must be valid for all world ages and limit use of this assertion accordingly.


:nothrow

The :nothrow settings asserts that this method does not throw an exception (i.e. will either always return a value or never return).

Note

It is permissible for :nothrow annotated methods to make use of exception handling internally as long as the exception is not rethrown out of the method itself.

Note

If the execution of a method may raise MethodErrors and similar exceptions, then the method is not considered as :nothrow. However, note that environment-dependent errors like StackOverflowError or InterruptException are not modeled by this effect and thus a method that may result in StackOverflowError does not necessarily need to be !:nothrow (although it should usually be !:terminates too).


:terminates_globally

The :terminates_globally settings asserts that this method will eventually terminate (either normally or abnormally), i.e. does not loop indefinitely.

Note

This :terminates_globally assertion covers any other methods called by the annotated method.

Note

The compiler will consider this a strong indication that the method will terminate relatively quickly and may (if otherwise legal) call this method at compile time. I.e. it is a bad idea to annotate this setting on a method that technically, but not practically, terminates.


:terminates_locally

The :terminates_locally setting is like :terminates_globally, except that it only applies to syntactic control flow within the annotated method. It is thus a much weaker (and thus safer) assertion that allows for the possibility of non-termination if the method calls some other method that does not terminate.

Note

:terminates_globally implies :terminates_locally.


:notaskstate

The :notaskstate setting asserts that the method does not use or modify the local task state (task local storage, RNG state, etc.) and may thus be safely moved between tasks without observable results.

Note

The implementation of exception handling makes use of state stored in the task object. However, this state is currently not considered to be within the scope of :notaskstate and is tracked separately using the :nothrow effect.

Note

The :notaskstate assertion concerns the state of the currently running task. If a reference to a Task object is obtained by some other means that does not consider which task is currently running, the :notaskstate effect need not be tainted. This is true, even if said task object happens to be === to the currently running task.

Note

Access to task state usually also results in the tainting of other effects, such as :effect_free (if task state is modified) or :consistent (if task state is used in the computation of the result). In particular, code that is not :notaskstate, but is :effect_free and :consistent may still be dead-code-eliminated and thus promoted to :total.


:inaccessiblememonly

The :inaccessiblememonly setting asserts that the method does not access or modify externally accessible mutable memory. This means the method can access or modify mutable memory for newly allocated objects that is not accessible by other methods or top-level execution before return from the method, but it can not access or modify any mutable global state or mutable memory pointed to by its arguments.

Note

Below is an incomplete list of examples that invalidate this assumption:

  • a global reference or getglobal call to access a mutable global variable
  • a global assignment or setglobal! call to perform assignment to a non-constant global variable
  • setfield! call that changes a field of a global mutable variable
Note

This :inaccessiblememonly assertion covers any other methods called by the annotated method.


:noub

The :noub setting asserts that the method will not execute any undefined behavior (for any input). Note that undefined behavior may technically cause the method to violate any other effect assertions (such as :consistent or :effect_free) as well, but we do not model this, and they assume the absence of undefined behavior.


:foldable

This setting is a convenient shortcut for the set of effects that the compiler requires to be guaranteed to constant fold a call at compile time. It is currently equivalent to the following settings:

  • :consistent
  • :effect_free
  • :terminates_globally
  • :noub
Note

This list in particular does not include :nothrow. The compiler will still attempt constant propagation and note any thrown error at compile time. Note however, that by the :consistent-cy requirements, any such annotated call must consistently throw given the same argument values.

Note

An explicit @inbounds annotation inside the function will also disable constant folding and not be overridden by :foldable.


:removable

This setting is a convenient shortcut for the set of effects that the compiler requires to be guaranteed to delete a call whose result is unused at compile time. It is currently equivalent to the following settings:

  • :effect_free
  • :nothrow
  • :terminates_globally

:total

This setting is the maximum possible set of effects. It currently implies the following other settings:

  • :consistent
  • :effect_free
  • :nothrow
  • :terminates_globally
  • :notaskstate
  • :inaccessiblememonly
  • :noub
Warning

:total is a very strong assertion and will likely gain additional semantics in future versions of Julia (e.g. if additional effects are added and included in the definition of :total). As a result, it should be used with care. Whenever possible, prefer to use the minimum possible set of specific effect assertions required for a particular application. In cases where a large number of effect overrides apply to a set of functions, a custom macro is recommended over the use of :total.


Negated effects

Effect names may be prefixed by ! to indicate that the effect should be removed from an earlier meta effect. For example, :total !:nothrow indicates that while the call is generally total, it may however throw.

source
Base.@deprecateMacro
@deprecate old new [export_old=true]

Deprecate method old and specify the replacement call new, defining a new method old with the specified signature in the process.

To prevent old from being exported, set export_old to false.

Julia 1.5

As of Julia 1.5, functions defined by @deprecate do not print warning when julia is run without the --depwarn=yes flag set, as the default value of --depwarn option is no. The warnings are printed from tests run by Pkg.test().

Examples

julia> @deprecate old_export(x) new(x)
+) => Tuple{Int64, Int64, Int64}
Julia 1.8

Using Base.@assume_effects requires Julia version 1.8.

Julia 1.10

The usage within a function body requires at least Julia 1.10.

Julia 1.11

The code block annotation requires at least Julia 1.11.

Warning

Improper use of this macro causes undefined behavior (including crashes, incorrect answers, or other hard to track bugs). Use with care and only as a last resort if absolutely required. Even in such a case, you SHOULD take all possible steps to minimize the strength of the effect assertion (e.g., do not use :total if :nothrow would have been sufficient).

In general, each setting value makes an assertion about the behavior of the function, without requiring the compiler to prove that this behavior is indeed true. These assertions are made for all world ages. It is thus advisable to limit the use of generic functions that may later be extended to invalidate the assumption (which would cause undefined behavior).

The following settings are supported.

  • :consistent
  • :effect_free
  • :nothrow
  • :terminates_globally
  • :terminates_locally
  • :notaskstate
  • :inaccessiblememonly
  • :noub
  • :noub_if_noinbounds
  • :foldable
  • :removable
  • :total

Extended help


:consistent

The :consistent setting asserts that for egal (===) inputs:

  • The manner of termination (return value, exception, non-termination) will always be the same.
  • If the method returns, the results will always be egal.
Note

This in particular implies that the method must not return a freshly allocated mutable object. Multiple allocations of mutable objects (even with identical contents) are not egal.

Note

The :consistent-cy assertion is made world-age wise. More formally, write $fᵢ$ for the evaluation of $f$ in world-age $i$, then we require:

\[∀ i, x, y: x ≡ y → fᵢ(x) ≡ fᵢ(y)\]

However, for two world ages $i$, $j$ s.t. $i ≠ j$, we may have $fᵢ(x) ≢ fⱼ(y)$.

A further implication is that :consistent functions may not make their return value dependent on the state of the heap or any other global state that is not constant for a given world age.

Note

The :consistent-cy includes all legal rewrites performed by the optimizer. For example, floating-point fastmath operations are not considered :consistent, because the optimizer may rewrite them causing the output to not be :consistent, even for the same world age (e.g. because one ran in the interpreter, while the other was optimized).

Note

If :consistent functions terminate by throwing an exception, that exception itself is not required to meet the egality requirement specified above.


:effect_free

The :effect_free setting asserts that the method is free of externally semantically visible side effects. The following is an incomplete list of externally semantically visible side effects:

  • Changing the value of a global variable.
  • Mutating the heap (e.g. an array or mutable value), except as noted below
  • Changing the method table (e.g. through calls to eval)
  • File/Network/etc. I/O
  • Task switching

However, the following are explicitly not semantically visible, even if they may be observable:

  • Memory allocations (both mutable and immutable)
  • Elapsed time
  • Garbage collection
  • Heap mutations of objects whose lifetime does not exceed the method (i.e. were allocated in the method and do not escape).
  • The returned value (which is externally visible, but not a side effect)

The rule of thumb here is that an externally visible side effect is anything that would affect the execution of the remainder of the program if the function were not executed.

Note

The :effect_free assertion is made both for the method itself and any code that is executed by the method. Keep in mind that the assertion must be valid for all world ages and limit use of this assertion accordingly.


:nothrow

The :nothrow settings asserts that this method does not throw an exception (i.e. will either always return a value or never return).

Note

It is permissible for :nothrow annotated methods to make use of exception handling internally as long as the exception is not rethrown out of the method itself.

Note

If the execution of a method may raise MethodErrors and similar exceptions, then the method is not considered as :nothrow. However, note that environment-dependent errors like StackOverflowError or InterruptException are not modeled by this effect and thus a method that may result in StackOverflowError does not necessarily need to be !:nothrow (although it should usually be !:terminates too).


:terminates_globally

The :terminates_globally settings asserts that this method will eventually terminate (either normally or abnormally), i.e. does not loop indefinitely.

Note

This :terminates_globally assertion covers any other methods called by the annotated method.

Note

The compiler will consider this a strong indication that the method will terminate relatively quickly and may (if otherwise legal) call this method at compile time. I.e. it is a bad idea to annotate this setting on a method that technically, but not practically, terminates.


:terminates_locally

The :terminates_locally setting is like :terminates_globally, except that it only applies to syntactic control flow within the annotated method. It is thus a much weaker (and thus safer) assertion that allows for the possibility of non-termination if the method calls some other method that does not terminate.

Note

:terminates_globally implies :terminates_locally.


:notaskstate

The :notaskstate setting asserts that the method does not use or modify the local task state (task local storage, RNG state, etc.) and may thus be safely moved between tasks without observable results.

Note

The implementation of exception handling makes use of state stored in the task object. However, this state is currently not considered to be within the scope of :notaskstate and is tracked separately using the :nothrow effect.

Note

The :notaskstate assertion concerns the state of the currently running task. If a reference to a Task object is obtained by some other means that does not consider which task is currently running, the :notaskstate effect need not be tainted. This is true, even if said task object happens to be === to the currently running task.

Note

Access to task state usually also results in the tainting of other effects, such as :effect_free (if task state is modified) or :consistent (if task state is used in the computation of the result). In particular, code that is not :notaskstate, but is :effect_free and :consistent may still be dead-code-eliminated and thus promoted to :total.


:inaccessiblememonly

The :inaccessiblememonly setting asserts that the method does not access or modify externally accessible mutable memory. This means the method can access or modify mutable memory for newly allocated objects that is not accessible by other methods or top-level execution before return from the method, but it can not access or modify any mutable global state or mutable memory pointed to by its arguments.

Note

Below is an incomplete list of examples that invalidate this assumption:

  • a global reference or getglobal call to access a mutable global variable
  • a global assignment or setglobal! call to perform assignment to a non-constant global variable
  • setfield! call that changes a field of a global mutable variable
Note

This :inaccessiblememonly assertion covers any other methods called by the annotated method.


:noub

The :noub setting asserts that the method will not execute any undefined behavior (for any input). Note that undefined behavior may technically cause the method to violate any other effect assertions (such as :consistent or :effect_free) as well, but we do not model this, and they assume the absence of undefined behavior.


:foldable

This setting is a convenient shortcut for the set of effects that the compiler requires to be guaranteed to constant fold a call at compile time. It is currently equivalent to the following settings:

  • :consistent
  • :effect_free
  • :terminates_globally
  • :noub
Note

This list in particular does not include :nothrow. The compiler will still attempt constant propagation and note any thrown error at compile time. Note however, that by the :consistent-cy requirements, any such annotated call must consistently throw given the same argument values.

Note

An explicit @inbounds annotation inside the function will also disable constant folding and not be overridden by :foldable.


:removable

This setting is a convenient shortcut for the set of effects that the compiler requires to be guaranteed to delete a call whose result is unused at compile time. It is currently equivalent to the following settings:

  • :effect_free
  • :nothrow
  • :terminates_globally

:total

This setting is the maximum possible set of effects. It currently implies the following other settings:

  • :consistent
  • :effect_free
  • :nothrow
  • :terminates_globally
  • :notaskstate
  • :inaccessiblememonly
  • :noub
Warning

:total is a very strong assertion and will likely gain additional semantics in future versions of Julia (e.g. if additional effects are added and included in the definition of :total). As a result, it should be used with care. Whenever possible, prefer to use the minimum possible set of specific effect assertions required for a particular application. In cases where a large number of effect overrides apply to a set of functions, a custom macro is recommended over the use of :total.


Negated effects

Effect names may be prefixed by ! to indicate that the effect should be removed from an earlier meta effect. For example, :total !:nothrow indicates that while the call is generally total, it may however throw.

source
Base.@deprecateMacro
@deprecate old new [export_old=true]

Deprecate method old and specify the replacement call new, defining a new method old with the specified signature in the process.

To prevent old from being exported, set export_old to false.

Julia 1.5

As of Julia 1.5, functions defined by @deprecate do not print warning when julia is run without the --depwarn=yes flag set, as the default value of --depwarn option is no. The warnings are printed from tests run by Pkg.test().

Examples

julia> @deprecate old_export(x) new(x)
 old_export (generic function with 1 method)
 
 julia> @deprecate old_public(x) new(x) false
@@ -1471,7 +1471,7 @@
 julia> methods(old)
 # 1 method for generic function "old" from Main:
  [1] old(x::Int64)
-     @ deprecated.jl:94

will define and deprecate a method old(x::Int) that mirrors new(x::Int) but will not define nor deprecate the method old(x::Float64).

source

Missing Values

Base.MissingType
Missing

A type with no fields whose singleton instance missing is used to represent missing values.

See also: skipmissing, nonmissingtype, Nothing.

source
Base.missingConstant
missing

The singleton instance of type Missing representing a missing value.

See also: NaN, skipmissing, nonmissingtype.

source
Base.coalesceFunction
coalesce(x...)

Return the first value in the arguments which is not equal to missing, if any. Otherwise return missing.

See also skipmissing, something, @coalesce.

Examples

julia> coalesce(missing, 1)
+     @ deprecated.jl:94

will define and deprecate a method old(x::Int) that mirrors new(x::Int) but will not define nor deprecate the method old(x::Float64).

source

Missing Values

Base.MissingType
Missing

A type with no fields whose singleton instance missing is used to represent missing values.

See also: skipmissing, nonmissingtype, Nothing.

source
Base.missingConstant
missing

The singleton instance of type Missing representing a missing value.

See also: NaN, skipmissing, nonmissingtype.

source
Base.coalesceFunction
coalesce(x...)

Return the first value in the arguments which is not equal to missing, if any. Otherwise return missing.

See also skipmissing, something, @coalesce.

Examples

julia> coalesce(missing, 1)
 1
 
 julia> coalesce(1, missing)
@@ -1480,7 +1480,7 @@
 julia> coalesce(nothing, 1)  # returns `nothing`
 
 julia> coalesce(missing, missing)
-missing
source
Base.@coalesceMacro
@coalesce(x...)

Short-circuiting version of coalesce.

Examples

julia> f(x) = (println("f($x)"); missing);
+missing
source
Base.@coalesceMacro
@coalesce(x...)

Short-circuiting version of coalesce.

Examples

julia> f(x) = (println("f($x)"); missing);
 
 julia> a = 1;
 
@@ -1493,7 +1493,7 @@
 f(2)
 f(3)
 ERROR: `b` is still missing
-[...]
Julia 1.7

This macro is available as of Julia 1.7.

source
Base.ismissingFunction
ismissing(x)

Indicate whether x is missing.

See also: skipmissing, isnothing, isnan.

source
Base.skipmissingFunction
skipmissing(itr)

Return an iterator over the elements in itr skipping missing values. The returned object can be indexed using indices of itr if the latter is indexable. Indices corresponding to missing values are not valid: they are skipped by keys and eachindex, and a MissingException is thrown when trying to use them.

Use collect to obtain an Array containing the non-missing values in itr. Note that even if itr is a multidimensional array, the result will always be a Vector since it is not possible to remove missings while preserving dimensions of the input.

See also coalesce, ismissing, something.

Examples

julia> x = skipmissing([1, missing, 2])
+[...]
Julia 1.7

This macro is available as of Julia 1.7.

source
Base.ismissingFunction
ismissing(x)

Indicate whether x is missing.

See also: skipmissing, isnothing, isnan.

source
Base.skipmissingFunction
skipmissing(itr)

Return an iterator over the elements in itr skipping missing values. The returned object can be indexed using indices of itr if the latter is indexable. Indices corresponding to missing values are not valid: they are skipped by keys and eachindex, and a MissingException is thrown when trying to use them.

Use collect to obtain an Array containing the non-missing values in itr. Note that even if itr is a multidimensional array, the result will always be a Vector since it is not possible to remove missings while preserving dimensions of the input.

See also coalesce, ismissing, something.

Examples

julia> x = skipmissing([1, missing, 2])
 skipmissing(Union{Missing, Int64}[1, missing, 2])
 
 julia> sum(x)
@@ -1522,17 +1522,17 @@
 julia> collect(skipmissing([1 missing; 2 missing]))
 2-element Vector{Int64}:
  1
- 2
source
Base.nonmissingtypeFunction
nonmissingtype(T::Type)

If T is a union of types containing Missing, return a new type with Missing removed.

Examples

julia> nonmissingtype(Union{Int64,Missing})
+ 2
source
Base.nonmissingtypeFunction
nonmissingtype(T::Type)

If T is a union of types containing Missing, return a new type with Missing removed.

Examples

julia> nonmissingtype(Union{Int64,Missing})
 Int64
 
 julia> nonmissingtype(Any)
-Any
Julia 1.3

This function is exported as of Julia 1.3.

source

System

Base.runFunction
run(command, args...; wait::Bool = true)

Run a command object, constructed with backticks (see the Running External Programs section in the manual). Throws an error if anything goes wrong, including the process exiting with a non-zero status (when wait is true).

The args... allow you to pass through file descriptors to the command, and are ordered like regular unix file descriptors (eg stdin, stdout, stderr, FD(3), FD(4)...).

If wait is false, the process runs asynchronously. You can later wait for it and check its exit status by calling success on the returned process object.

When wait is false, the process' I/O streams are directed to devnull. When wait is true, I/O streams are shared with the parent process. Use pipeline to control I/O redirection.

source
Base.devnullConstant
devnull

Used in a stream redirect to discard all data written to it. Essentially equivalent to /dev/null on Unix or NUL on Windows. Usage:

run(pipeline(`cat test.txt`, devnull))
source
Base.successFunction
success(command)

Run a command object, constructed with backticks (see the Running External Programs section in the manual), and tell whether it was successful (exited with a code of 0). An exception is raised if the process cannot be started.

source
Base.process_runningFunction
process_running(p::Process)

Determine whether a process is currently running.

source
Base.process_exitedFunction
process_exited(p::Process)

Determine whether a process has exited.

source
Base.killMethod
kill(p::Process, signum=Base.SIGTERM)

Send a signal to a process. The default is to terminate the process. Returns successfully if the process has already exited, but throws an error if killing the process failed for other reasons (e.g. insufficient permissions).

source
Base.Sys.set_process_titleFunction
Sys.set_process_title(title::AbstractString)

Set the process title. No-op on some operating systems.

source
Base.Sys.get_process_titleFunction
Sys.get_process_title()

Get the process title. On some systems, will always return an empty string.

source
Base.ignorestatusFunction
ignorestatus(command)

Mark a command object so that running it will not throw an error if the result code is non-zero.

source
Base.detachFunction
detach(command)

Mark a command object so that it will be run in a new process group, allowing it to outlive the julia process, and not have Ctrl-C interrupts passed to it.

source
Base.CmdType
Cmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)
-Cmd(exec::Vector{String})

Construct a new Cmd object, representing an external program and arguments, from cmd, while changing the settings of the optional keyword arguments:

  • ignorestatus::Bool: If true (defaults to false), then the Cmd will not throw an error if the return code is nonzero.
  • detach::Bool: If true (defaults to false), then the Cmd will be run in a new process group, allowing it to outlive the julia process and not have Ctrl-C passed to it.
  • windows_verbatim::Bool: If true (defaults to false), then on Windows the Cmd will send a command-line string to the process with no quoting or escaping of arguments, even arguments containing spaces. (On Windows, arguments are sent to a program as a single "command-line" string, and programs are responsible for parsing it into arguments. By default, empty arguments and arguments with spaces or tabs are quoted with double quotes " in the command line, and \ or " are preceded by backslashes. windows_verbatim=true is useful for launching programs that parse their command line in nonstandard ways.) Has no effect on non-Windows systems.
  • windows_hide::Bool: If true (defaults to false), then on Windows no new console window is displayed when the Cmd is executed. This has no effect if a console is already open or on non-Windows systems.
  • env: Set environment variables to use when running the Cmd. env is either a dictionary mapping strings to strings, an array of strings of the form "var=val", an array or tuple of "var"=>val pairs. In order to modify (rather than replace) the existing environment, initialize env with copy(ENV) and then set env["var"]=val as desired. To add to an environment block within a Cmd object without replacing all elements, use addenv() which will return a Cmd object with the updated environment.
  • dir::AbstractString: Specify a working directory for the command (instead of the current directory).

For any keywords that are not specified, the current settings from cmd are used.

Note that the Cmd(exec) constructor does not create a copy of exec. Any subsequent changes to exec will be reflected in the Cmd object.

The most common way to construct a Cmd object is with command literals (backticks), e.g.

`ls -l`

This can then be passed to the Cmd constructor to modify its settings, e.g.

Cmd(`echo "Hello world"`, ignorestatus=true, detach=false)
source
Base.setenvFunction
setenv(command::Cmd, env; dir)

Set environment variables to use when running the given command. env is either a dictionary mapping strings to strings, an array of strings of the form "var=val", or zero or more "var"=>val pair arguments. In order to modify (rather than replace) the existing environment, create env through copy(ENV) and then setting env["var"]=val as desired, or use addenv.

The dir keyword argument can be used to specify a working directory for the command. dir defaults to the currently set dir for command (which is the current working directory if not specified already).

See also Cmd, addenv, ENV, pwd.

source
Base.addenvFunction
addenv(command::Cmd, env...; inherit::Bool = true)

Merge new environment mappings into the given Cmd object, returning a new Cmd object. Duplicate keys are replaced. If command does not contain any environment values set already, it inherits the current environment at time of addenv() call if inherit is true. Keys with value nothing are deleted from the env.

See also Cmd, setenv, ENV.

Julia 1.6

This function requires Julia 1.6 or later.

source
Base.withenvFunction
withenv(f, kv::Pair...)

Execute f in an environment that is temporarily modified (not replaced as in setenv) by zero or more "var"=>val arguments kv. withenv is generally used via the withenv(kv...) do ... end syntax. A value of nothing can be used to temporarily unset an environment variable (if it is set). When withenv returns, the original environment has been restored.

Warning

Changing the environment is not thread-safe. For running external commands with a different environment from the parent process, prefer using addenv over withenv.

source
Base.setcpuaffinityFunction
setcpuaffinity(original_command::Cmd, cpus) -> command::Cmd

Set the CPU affinity of the command by a list of CPU IDs (1-based) cpus. Passing cpus = nothing means to unset the CPU affinity if the original_command has any.

This function is supported only in Linux and Windows. It is not supported in macOS because libuv does not support affinity setting.

Julia 1.8

This function requires at least Julia 1.8.

Examples

In Linux, the taskset command line program can be used to see how setcpuaffinity works.

julia> run(setcpuaffinity(`sh -c 'taskset -p $$'`, [1, 2, 5]));
+Any
Julia 1.3

This function is exported as of Julia 1.3.

source

System

Base.runFunction
run(command, args...; wait::Bool = true)

Run a command object, constructed with backticks (see the Running External Programs section in the manual). Throws an error if anything goes wrong, including the process exiting with a non-zero status (when wait is true).

The args... allow you to pass through file descriptors to the command, and are ordered like regular unix file descriptors (eg stdin, stdout, stderr, FD(3), FD(4)...).

If wait is false, the process runs asynchronously. You can later wait for it and check its exit status by calling success on the returned process object.

When wait is false, the process' I/O streams are directed to devnull. When wait is true, I/O streams are shared with the parent process. Use pipeline to control I/O redirection.

source
Base.devnullConstant
devnull

Used in a stream redirect to discard all data written to it. Essentially equivalent to /dev/null on Unix or NUL on Windows. Usage:

run(pipeline(`cat test.txt`, devnull))
source
Base.successFunction
success(command)

Run a command object, constructed with backticks (see the Running External Programs section in the manual), and tell whether it was successful (exited with a code of 0). An exception is raised if the process cannot be started.

source
Base.process_runningFunction
process_running(p::Process)

Determine whether a process is currently running.

source
Base.process_exitedFunction
process_exited(p::Process)

Determine whether a process has exited.

source
Base.killMethod
kill(p::Process, signum=Base.SIGTERM)

Send a signal to a process. The default is to terminate the process. Returns successfully if the process has already exited, but throws an error if killing the process failed for other reasons (e.g. insufficient permissions).

source
Base.Sys.set_process_titleFunction
Sys.set_process_title(title::AbstractString)

Set the process title. No-op on some operating systems.

source
Base.Sys.get_process_titleFunction
Sys.get_process_title()

Get the process title. On some systems, will always return an empty string.

source
Base.ignorestatusFunction
ignorestatus(command)

Mark a command object so that running it will not throw an error if the result code is non-zero.

source
Base.detachFunction
detach(command)

Mark a command object so that it will be run in a new process group, allowing it to outlive the julia process, and not have Ctrl-C interrupts passed to it.

source
Base.CmdType
Cmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)
+Cmd(exec::Vector{String})

Construct a new Cmd object, representing an external program and arguments, from cmd, while changing the settings of the optional keyword arguments:

  • ignorestatus::Bool: If true (defaults to false), then the Cmd will not throw an error if the return code is nonzero.
  • detach::Bool: If true (defaults to false), then the Cmd will be run in a new process group, allowing it to outlive the julia process and not have Ctrl-C passed to it.
  • windows_verbatim::Bool: If true (defaults to false), then on Windows the Cmd will send a command-line string to the process with no quoting or escaping of arguments, even arguments containing spaces. (On Windows, arguments are sent to a program as a single "command-line" string, and programs are responsible for parsing it into arguments. By default, empty arguments and arguments with spaces or tabs are quoted with double quotes " in the command line, and \ or " are preceded by backslashes. windows_verbatim=true is useful for launching programs that parse their command line in nonstandard ways.) Has no effect on non-Windows systems.
  • windows_hide::Bool: If true (defaults to false), then on Windows no new console window is displayed when the Cmd is executed. This has no effect if a console is already open or on non-Windows systems.
  • env: Set environment variables to use when running the Cmd. env is either a dictionary mapping strings to strings, an array of strings of the form "var=val", an array or tuple of "var"=>val pairs. In order to modify (rather than replace) the existing environment, initialize env with copy(ENV) and then set env["var"]=val as desired. To add to an environment block within a Cmd object without replacing all elements, use addenv() which will return a Cmd object with the updated environment.
  • dir::AbstractString: Specify a working directory for the command (instead of the current directory).

For any keywords that are not specified, the current settings from cmd are used.

Note that the Cmd(exec) constructor does not create a copy of exec. Any subsequent changes to exec will be reflected in the Cmd object.

The most common way to construct a Cmd object is with command literals (backticks), e.g.

`ls -l`

This can then be passed to the Cmd constructor to modify its settings, e.g.

Cmd(`echo "Hello world"`, ignorestatus=true, detach=false)
source
Base.setenvFunction
setenv(command::Cmd, env; dir)

Set environment variables to use when running the given command. env is either a dictionary mapping strings to strings, an array of strings of the form "var=val", or zero or more "var"=>val pair arguments. In order to modify (rather than replace) the existing environment, create env through copy(ENV) and then setting env["var"]=val as desired, or use addenv.

The dir keyword argument can be used to specify a working directory for the command. dir defaults to the currently set dir for command (which is the current working directory if not specified already).

See also Cmd, addenv, ENV, pwd.

source
Base.addenvFunction
addenv(command::Cmd, env...; inherit::Bool = true)

Merge new environment mappings into the given Cmd object, returning a new Cmd object. Duplicate keys are replaced. If command does not contain any environment values set already, it inherits the current environment at time of addenv() call if inherit is true. Keys with value nothing are deleted from the env.

See also Cmd, setenv, ENV.

Julia 1.6

This function requires Julia 1.6 or later.

source
Base.withenvFunction
withenv(f, kv::Pair...)

Execute f in an environment that is temporarily modified (not replaced as in setenv) by zero or more "var"=>val arguments kv. withenv is generally used via the withenv(kv...) do ... end syntax. A value of nothing can be used to temporarily unset an environment variable (if it is set). When withenv returns, the original environment has been restored.

Warning

Changing the environment is not thread-safe. For running external commands with a different environment from the parent process, prefer using addenv over withenv.

source
Base.setcpuaffinityFunction
setcpuaffinity(original_command::Cmd, cpus) -> command::Cmd

Set the CPU affinity of the command by a list of CPU IDs (1-based) cpus. Passing cpus = nothing means to unset the CPU affinity if the original_command has any.

This function is supported only in Linux and Windows. It is not supported in macOS because libuv does not support affinity setting.

Julia 1.8

This function requires at least Julia 1.8.

Examples

In Linux, the taskset command line program can be used to see how setcpuaffinity works.

julia> run(setcpuaffinity(`sh -c 'taskset -p $$'`, [1, 2, 5]));
 pid 2273's current affinity mask: 13

Note that the mask value 13 reflects that the first, second, and the fifth bits (counting from the least significant position) are turned on:

julia> 0b010011
-0x13
source
Base.pipelineMethod
pipeline(from, to, ...)

Create a pipeline from a data source to a destination. The source and destination can be commands, I/O streams, strings, or results of other pipeline calls. At least one argument must be a command. Strings refer to filenames. When called with more than two arguments, they are chained together from left to right. For example, pipeline(a,b,c) is equivalent to pipeline(pipeline(a,b),c). This provides a more concise way to specify multi-stage pipelines.

Examples:

run(pipeline(`ls`, `grep xyz`))
+0x13
source
Base.pipelineMethod
pipeline(from, to, ...)

Create a pipeline from a data source to a destination. The source and destination can be commands, I/O streams, strings, or results of other pipeline calls. At least one argument must be a command. Strings refer to filenames. When called with more than two arguments, they are chained together from left to right. For example, pipeline(a,b,c) is equivalent to pipeline(pipeline(a,b),c). This provides a more concise way to specify multi-stage pipelines.

Examples:

run(pipeline(`ls`, `grep xyz`))
 run(pipeline(`ls`, "out.txt"))
-run(pipeline("out.txt", `grep xyz`))
source
Base.pipelineMethod
pipeline(command; stdin, stdout, stderr, append=false)

Redirect I/O to or from the given command. Keyword arguments specify which of the command's streams should be redirected. append controls whether file output appends to the file. This is a more general version of the 2-argument pipeline function. pipeline(from, to) is equivalent to pipeline(from, stdout=to) when from is a command, and to pipeline(to, stdin=from) when from is another kind of data source.

Examples:

run(pipeline(`dothings`, stdout="out.txt", stderr="errs.txt"))
-run(pipeline(`update`, stdout="log.txt", append=true))
source
Base.Libc.gethostnameFunction
gethostname() -> String

Get the local machine's host name.

source
Base.Libc.getpidFunction
getpid() -> Int32

Get Julia's process ID.

source
getpid(process) -> Int32

Get the child process ID, if it still exists.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Libc.timeMethod
time() -> Float64

Get the system time in seconds since the epoch, with fairly high (typically, microsecond) resolution.

source
Base.time_nsFunction
time_ns() -> UInt64

Get the time in nanoseconds. The time corresponding to 0 is undefined, and wraps every 5.8 years.

source
Base.@timeMacro
@time expr
+run(pipeline("out.txt", `grep xyz`))
source
Base.pipelineMethod
pipeline(command; stdin, stdout, stderr, append=false)

Redirect I/O to or from the given command. Keyword arguments specify which of the command's streams should be redirected. append controls whether file output appends to the file. This is a more general version of the 2-argument pipeline function. pipeline(from, to) is equivalent to pipeline(from, stdout=to) when from is a command, and to pipeline(to, stdin=from) when from is another kind of data source.

Examples:

run(pipeline(`dothings`, stdout="out.txt", stderr="errs.txt"))
+run(pipeline(`update`, stdout="log.txt", append=true))
source
Base.Libc.gethostnameFunction
gethostname() -> String

Get the local machine's host name.

source
Base.Libc.getpidFunction
getpid() -> Int32

Get Julia's process ID.

source
getpid(process) -> Int32

Get the child process ID, if it still exists.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Libc.timeMethod
time() -> Float64

Get the system time in seconds since the epoch, with fairly high (typically, microsecond) resolution.

source
Base.time_nsFunction
time_ns() -> UInt64

Get the time in nanoseconds. The time corresponding to 0 is undefined, and wraps every 5.8 years.

source
Base.@timeMacro
@time expr
 @time "description" expr

A macro to execute an expression, printing the time it took to execute, the number of allocations, and the total number of bytes its execution caused to be allocated, before returning the value of the expression. Any time spent garbage collecting (gc), compiling new code, or recompiling invalidated code is shown as a percentage. Any lock conflicts where a ReentrantLock had to wait are shown as a count.

Optionally provide a description string to print before the time report.

In some cases the system will look inside the @time expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @time @eval ....

See also @showtime, @timev, @timed, @elapsed, @allocated, and @allocations.

Note

For more serious benchmarking, consider the @btime macro from the BenchmarkTools.jl package which among other things evaluates the function multiple times in order to reduce noise.

Julia 1.8

The option to add a description was introduced in Julia 1.8.

Recompilation time being shown separately from compilation time was introduced in Julia 1.8

Julia 1.11

The reporting of any lock conflicts was added in Julia 1.11.

julia> x = rand(10,10);
 
 julia> @time x * x;
@@ -1556,8 +1556,8 @@
         end
 1: 1.006760 seconds (5 allocations: 144 bytes)
 2: 1.001263 seconds (5 allocations: 144 bytes)
-3: 1.003676 seconds (5 allocations: 144 bytes)
source
Base.@showtimeMacro
@showtime expr

Like @time but also prints the expression being evaluated for reference.

Julia 1.8

This macro was added in Julia 1.8.

See also @time.

julia> @showtime sleep(1)
-sleep(1): 1.002164 seconds (4 allocations: 128 bytes)
source
Base.@timevMacro
@timev expr
+3: 1.003676 seconds (5 allocations: 144 bytes)
source
Base.@showtimeMacro
@showtime expr

Like @time but also prints the expression being evaluated for reference.

Julia 1.8

This macro was added in Julia 1.8.

See also @time.

julia> @showtime sleep(1)
+sleep(1): 1.002164 seconds (4 allocations: 128 bytes)
source
Base.@timevMacro
@timev expr
 @timev "description" expr

This is a verbose version of the @time macro. It first prints the same information as @time, then any non-zero memory allocation counters, and then returns the value of the expression.

Optionally provide a description string to print before the time report.

Julia 1.8

The option to add a description was introduced in Julia 1.8.

See also @time, @timed, @elapsed, @allocated, and @allocations.

julia> x = rand(10,10);
 
 julia> @timev x * x;
@@ -1575,7 +1575,7 @@
   0.000010 seconds (1 allocation: 896 bytes)
 elapsed time (ns): 9848
 bytes allocated:   896
-pool allocs:       1
source
Base.@timedMacro
@timed

A macro to execute an expression, and return the value of the expression, elapsed time in seconds, total bytes allocated, garbage collection time, an object with various memory allocation counters, compilation time in seconds, and recompilation time in seconds. Any lock conflicts where a ReentrantLock had to wait are shown as a count.

In some cases the system will look inside the @timed expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @timed @eval ....

See also @time, @timev, @elapsed, @allocated, @allocations, and @lock_conflicts.

julia> stats = @timed rand(10^6);
+pool allocs:       1
source
Base.@timedMacro
@timed

A macro to execute an expression, and return the value of the expression, elapsed time in seconds, total bytes allocated, garbage collection time, an object with various memory allocation counters, compilation time in seconds, and recompilation time in seconds. Any lock conflicts where a ReentrantLock had to wait are shown as a count.

In some cases the system will look inside the @timed expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @timed @eval ....

See also @time, @timev, @elapsed, @allocated, @allocations, and @lock_conflicts.

julia> stats = @timed rand(10^6);
 
 julia> stats.time
 0.006634834
@@ -1597,10 +1597,10 @@
 
 julia> stats.recompile_time
 0.0
-
Julia 1.5

The return type of this macro was changed from Tuple to NamedTuple in Julia 1.5.

Julia 1.11

The lock_conflicts, compile_time, and recompile_time fields were added in Julia 1.11.

source
Base.@elapsedMacro
@elapsed

A macro to evaluate an expression, discarding the resulting value, instead returning the number of seconds it took to execute as a floating-point number.

In some cases the system will look inside the @elapsed expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @elapsed @eval ....

See also @time, @timev, @timed, @allocated, and @allocations.

julia> @elapsed sleep(0.3)
-0.301391426
source
Base.@allocatedMacro
@allocated

A macro to evaluate an expression, discarding the resulting value, instead returning the total number of bytes allocated during evaluation of the expression.

See also @allocations, @time, @timev, @timed, and @elapsed.

julia> @allocated rand(10^6)
-8000080
source
Base.@allocationsMacro
@allocations

A macro to evaluate an expression, discard the resulting value, and instead return the total number of allocations during evaluation of the expression.

See also @allocated, @time, @timev, @timed, and @elapsed.

julia> @allocations rand(10^6)
-2
Julia 1.9

This macro was added in Julia 1.9.

source
Base.@lock_conflictsMacro
@lock_conflicts

A macro to evaluate an expression, discard the resulting value, and instead return the total number of lock conflicts during evaluation, where a lock attempt on a ReentrantLock resulted in a wait because the lock was already held.

See also @time, @timev and @timed.

julia> @lock_conflicts begin
+
Julia 1.5

The return type of this macro was changed from Tuple to NamedTuple in Julia 1.5.

Julia 1.11

The lock_conflicts, compile_time, and recompile_time fields were added in Julia 1.11.

source
Base.@elapsedMacro
@elapsed

A macro to evaluate an expression, discarding the resulting value, instead returning the number of seconds it took to execute as a floating-point number.

In some cases the system will look inside the @elapsed expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @elapsed @eval ....

See also @time, @timev, @timed, @allocated, and @allocations.

julia> @elapsed sleep(0.3)
+0.301391426
source
Base.@allocatedMacro
@allocated

A macro to evaluate an expression, discarding the resulting value, instead returning the total number of bytes allocated during evaluation of the expression.

See also @allocations, @time, @timev, @timed, and @elapsed.

julia> @allocated rand(10^6)
+8000080
source
Base.@allocationsMacro
@allocations

A macro to evaluate an expression, discard the resulting value, and instead return the total number of allocations during evaluation of the expression.

See also @allocated, @time, @timev, @timed, and @elapsed.

julia> @allocations rand(10^6)
+2
Julia 1.9

This macro was added in Julia 1.9.

source
Base.@lock_conflictsMacro
@lock_conflicts

A macro to evaluate an expression, discard the resulting value, and instead return the total number of lock conflicts during evaluation, where a lock attempt on a ReentrantLock resulted in a wait because the lock was already held.

See also @time, @timev and @timed.

julia> @lock_conflicts begin
     l = ReentrantLock()
     Threads.@threads for i in 1:Threads.nthreads()
         lock(l) do
@@ -1608,7 +1608,7 @@
         end
     end
 end
-5
Julia 1.11

This macro was added in Julia 1.11.

source
Base.EnvDictType
EnvDict() -> EnvDict

A singleton of this type provides a hash table interface to environment variables.

source
Base.ENVConstant
ENV

Reference to the singleton EnvDict, providing a dictionary interface to system environment variables.

(On Windows, system environment variables are case-insensitive, and ENV correspondingly converts all keys to uppercase for display, iteration, and copying. Portable code should not rely on the ability to distinguish variables by case, and should beware that setting an ostensibly lowercase variable may result in an uppercase ENV key.)

Warning

Mutating the environment is not thread-safe.

Examples

julia> ENV
+5
Julia 1.11

This macro was added in Julia 1.11.

source
Base.EnvDictType
EnvDict() -> EnvDict

A singleton of this type provides a hash table interface to environment variables.

source
Base.ENVConstant
ENV

Reference to the singleton EnvDict, providing a dictionary interface to system environment variables.

(On Windows, system environment variables are case-insensitive, and ENV correspondingly converts all keys to uppercase for display, iteration, and copying. Portable code should not rely on the ability to distinguish variables by case, and should beware that setting an ostensibly lowercase variable may result in an uppercase ENV key.)

Warning

Mutating the environment is not thread-safe.

Examples

julia> ENV
 Base.EnvDict with "50" entries:
   "SECURITYSESSIONID"            => "123"
   "USER"                         => "username"
@@ -1619,7 +1619,7 @@
 "vim"
 
 julia> ENV["JULIA_EDITOR"]
-"vim"

See also: withenv, addenv.

source
Base.Sys.STDLIBConstant
Sys.STDLIB::String

A string containing the full path to the directory containing the stdlib packages.

source
Base.Sys.isunixFunction
Sys.isunix([os])

Predicate for testing if the OS provides a Unix-like interface. See documentation in Handling Operating System Variation.

source
Base.Sys.isappleFunction
Sys.isapple([os])

Predicate for testing if the OS is a derivative of Apple Macintosh OS X or Darwin. See documentation in Handling Operating System Variation.

source
Base.Sys.islinuxFunction
Sys.islinux([os])

Predicate for testing if the OS is a derivative of Linux. See documentation in Handling Operating System Variation.

source
Base.Sys.isbsdFunction
Sys.isbsd([os])

Predicate for testing if the OS is a derivative of BSD. See documentation in Handling Operating System Variation.

Note

The Darwin kernel descends from BSD, which means that Sys.isbsd() is true on macOS systems. To exclude macOS from a predicate, use Sys.isbsd() && !Sys.isapple().

source
Base.Sys.isfreebsdFunction
Sys.isfreebsd([os])

Predicate for testing if the OS is a derivative of FreeBSD. See documentation in Handling Operating System Variation.

Note

Not to be confused with Sys.isbsd(), which is true on FreeBSD but also on other BSD-based systems. Sys.isfreebsd() refers only to FreeBSD.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Sys.isopenbsdFunction
Sys.isopenbsd([os])

Predicate for testing if the OS is a derivative of OpenBSD. See documentation in Handling Operating System Variation.

Note

Not to be confused with Sys.isbsd(), which is true on OpenBSD but also on other BSD-based systems. Sys.isopenbsd() refers only to OpenBSD.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Sys.isnetbsdFunction
Sys.isnetbsd([os])

Predicate for testing if the OS is a derivative of NetBSD. See documentation in Handling Operating System Variation.

Note

Not to be confused with Sys.isbsd(), which is true on NetBSD but also on other BSD-based systems. Sys.isnetbsd() refers only to NetBSD.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Sys.isdragonflyFunction
Sys.isdragonfly([os])

Predicate for testing if the OS is a derivative of DragonFly BSD. See documentation in Handling Operating System Variation.

Note

Not to be confused with Sys.isbsd(), which is true on DragonFly but also on other BSD-based systems. Sys.isdragonfly() refers only to DragonFly.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Sys.iswindowsFunction
Sys.iswindows([os])

Predicate for testing if the OS is a derivative of Microsoft Windows NT. See documentation in Handling Operating System Variation.

source
Base.Sys.windows_versionFunction
Sys.windows_version()

Return the version number for the Windows NT Kernel as a VersionNumber, i.e. v"major.minor.build", or v"0.0.0" if this is not running on Windows.

source
Base.Sys.free_memoryFunction
Sys.free_memory()

Get the total free memory in RAM in bytes.

source
Base.Sys.total_memoryFunction
Sys.total_memory()

Get the total memory in RAM (including that which is currently used) in bytes. This amount may be constrained, e.g., by Linux control groups. For the unconstrained amount, see Sys.total_physical_memory().

source
Base.Sys.free_physical_memoryFunction
Sys.free_physical_memory()

Get the free memory of the system in bytes. The entire amount may not be available to the current process; use Sys.free_memory() for the actually available amount.

source
Base.Sys.total_physical_memoryFunction
Sys.total_physical_memory()

Get the total memory in RAM (including that which is currently used) in bytes. The entire amount may not be available to the current process; see Sys.total_memory().

source
Base.Sys.uptimeFunction
Sys.uptime()

Gets the current system uptime in seconds.

source
Base.Sys.isjsvmFunction
Sys.isjsvm([os])

Predicate for testing if Julia is running in a JavaScript VM (JSVM), including e.g. a WebAssembly JavaScript embedding in a web browser.

Julia 1.2

This function requires at least Julia 1.2.

source
Base.Sys.loadavgFunction
Sys.loadavg()

Get the load average. See: https://en.wikipedia.org/wiki/Load_(computing).

source
Base.Sys.isexecutableFunction
isexecutable(path::String)

Return true if the given path has executable permissions.

Note

This permission may change before the user executes path, so it is recommended to execute the file and handle the error if that fails, rather than calling isexecutable first.

Note

Prior to Julia 1.6, this did not correctly interrogate filesystem ACLs on Windows, therefore it would return true for any file. From Julia 1.6 on, it correctly determines whether the file is marked as executable or not.

See also ispath, isreadable, iswritable.

source
Base.Sys.isreadableFunction
isreadable(path::String)

Return true if the access permissions for the given path permitted reading by the current user.

Note

This permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling isreadable first.

Note

Currently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.

Julia 1.11

This function requires at least Julia 1.11.

See also ispath, isexecutable, iswritable.

source
isreadable(io) -> Bool

Return false if the specified IO object is not readable.

Examples

julia> open("myfile.txt", "w") do io
+"vim"

See also: withenv, addenv.

source
Base.Sys.STDLIBConstant
Sys.STDLIB::String

A string containing the full path to the directory containing the stdlib packages.

source
Base.Sys.isunixFunction
Sys.isunix([os])

Predicate for testing if the OS provides a Unix-like interface. See documentation in Handling Operating System Variation.

source
Base.Sys.isappleFunction
Sys.isapple([os])

Predicate for testing if the OS is a derivative of Apple Macintosh OS X or Darwin. See documentation in Handling Operating System Variation.

source
Base.Sys.islinuxFunction
Sys.islinux([os])

Predicate for testing if the OS is a derivative of Linux. See documentation in Handling Operating System Variation.

source
Base.Sys.isbsdFunction
Sys.isbsd([os])

Predicate for testing if the OS is a derivative of BSD. See documentation in Handling Operating System Variation.

Note

The Darwin kernel descends from BSD, which means that Sys.isbsd() is true on macOS systems. To exclude macOS from a predicate, use Sys.isbsd() && !Sys.isapple().

source
Base.Sys.isfreebsdFunction
Sys.isfreebsd([os])

Predicate for testing if the OS is a derivative of FreeBSD. See documentation in Handling Operating System Variation.

Note

Not to be confused with Sys.isbsd(), which is true on FreeBSD but also on other BSD-based systems. Sys.isfreebsd() refers only to FreeBSD.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Sys.isopenbsdFunction
Sys.isopenbsd([os])

Predicate for testing if the OS is a derivative of OpenBSD. See documentation in Handling Operating System Variation.

Note

Not to be confused with Sys.isbsd(), which is true on OpenBSD but also on other BSD-based systems. Sys.isopenbsd() refers only to OpenBSD.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Sys.isnetbsdFunction
Sys.isnetbsd([os])

Predicate for testing if the OS is a derivative of NetBSD. See documentation in Handling Operating System Variation.

Note

Not to be confused with Sys.isbsd(), which is true on NetBSD but also on other BSD-based systems. Sys.isnetbsd() refers only to NetBSD.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Sys.isdragonflyFunction
Sys.isdragonfly([os])

Predicate for testing if the OS is a derivative of DragonFly BSD. See documentation in Handling Operating System Variation.

Note

Not to be confused with Sys.isbsd(), which is true on DragonFly but also on other BSD-based systems. Sys.isdragonfly() refers only to DragonFly.

Julia 1.1

This function requires at least Julia 1.1.

source
Base.Sys.iswindowsFunction
Sys.iswindows([os])

Predicate for testing if the OS is a derivative of Microsoft Windows NT. See documentation in Handling Operating System Variation.

source
Base.Sys.windows_versionFunction
Sys.windows_version()

Return the version number for the Windows NT Kernel as a VersionNumber, i.e. v"major.minor.build", or v"0.0.0" if this is not running on Windows.

source
Base.Sys.free_memoryFunction
Sys.free_memory()

Get the total free memory in RAM in bytes.

source
Base.Sys.total_memoryFunction
Sys.total_memory()

Get the total memory in RAM (including that which is currently used) in bytes. This amount may be constrained, e.g., by Linux control groups. For the unconstrained amount, see Sys.total_physical_memory().

source
Base.Sys.free_physical_memoryFunction
Sys.free_physical_memory()

Get the free memory of the system in bytes. The entire amount may not be available to the current process; use Sys.free_memory() for the actually available amount.

source
Base.Sys.total_physical_memoryFunction
Sys.total_physical_memory()

Get the total memory in RAM (including that which is currently used) in bytes. The entire amount may not be available to the current process; see Sys.total_memory().

source
Base.Sys.uptimeFunction
Sys.uptime()

Gets the current system uptime in seconds.

source
Base.Sys.isjsvmFunction
Sys.isjsvm([os])

Predicate for testing if Julia is running in a JavaScript VM (JSVM), including e.g. a WebAssembly JavaScript embedding in a web browser.

Julia 1.2

This function requires at least Julia 1.2.

source
Base.Sys.loadavgFunction
Sys.loadavg()

Get the load average. See: https://en.wikipedia.org/wiki/Load_(computing).

source
Base.Sys.isexecutableFunction
isexecutable(path::String)

Return true if the given path has executable permissions.

Note

This permission may change before the user executes path, so it is recommended to execute the file and handle the error if that fails, rather than calling isexecutable first.

Note

Prior to Julia 1.6, this did not correctly interrogate filesystem ACLs on Windows, therefore it would return true for any file. From Julia 1.6 on, it correctly determines whether the file is marked as executable or not.

See also ispath, isreadable, iswritable.

source
Base.Sys.isreadableFunction
isreadable(path::String)

Return true if the access permissions for the given path permitted reading by the current user.

Note

This permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling isreadable first.

Note

Currently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.

Julia 1.11

This function requires at least Julia 1.11.

See also ispath, isexecutable, iswritable.

source
isreadable(io) -> Bool

Return false if the specified IO object is not readable.

Examples

julia> open("myfile.txt", "w") do io
            print(io, "Hello world!");
            isreadable(io)
        end
@@ -1630,7 +1630,7 @@
        end
 true
 
-julia> rm("myfile.txt")
source
Base.Sys.iswritableFunction
iswritable(path::String)

Return true if the access permissions for the given path permitted writing by the current user.

Note

This permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling iswritable first.

Note

Currently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.

Julia 1.11

This function requires at least Julia 1.11.

See also ispath, isexecutable, isreadable.

source
iswritable(io) -> Bool

Return false if the specified IO object is not writable.

Examples

julia> open("myfile.txt", "w") do io
+julia> rm("myfile.txt")
source
Base.Sys.iswritableFunction
iswritable(path::String)

Return true if the access permissions for the given path permitted writing by the current user.

Note

This permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling iswritable first.

Note

Currently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.

Julia 1.11

This function requires at least Julia 1.11.

See also ispath, isexecutable, isreadable.

source
iswritable(io) -> Bool

Return false if the specified IO object is not writable.

Examples

julia> open("myfile.txt", "w") do io
            print(io, "Hello world!");
            iswritable(io)
        end
@@ -1641,7 +1641,7 @@
        end
 false
 
-julia> rm("myfile.txt")
source
Base.Sys.usernameFunction
Sys.username() -> String

Return the username for the current user. If the username cannot be determined or is empty, this function throws an error.

To retrieve a username that is overridable via an environment variable, e.g., USER, consider using

user = get(Sys.username, ENV, "USER")
Julia 1.11

This function requires at least Julia 1.11.

See also homedir.

source
Base.@staticMacro
@static

Partially evaluate an expression at parse time.

For example, @static Sys.iswindows() ? foo : bar will evaluate Sys.iswindows() and insert either foo or bar into the expression. This is useful in cases where a construct would be invalid on other platforms, such as a ccall to a non-existent function. @static if Sys.isapple() foo end and @static foo <&&,||> bar are also valid syntax.

source

Versioning

Base.VersionNumberType
VersionNumber

Version number type which follows the specifications of semantic versioning (semver), composed of major, minor and patch numeric values, followed by pre-release and build alphanumeric annotations.

VersionNumber objects can be compared with all of the standard comparison operators (==, <, <=, etc.), with the result following semver v2.0.0-rc.2 rules.

VersionNumber has the following public fields:

  • v.major::Integer
  • v.minor::Integer
  • v.patch::Integer
  • v.prerelease::Tuple{Vararg{Union{Integer, AbstractString}}}
  • v.build::Tuple{Vararg{Union{Integer, AbstractString}}}

See also @v_str to efficiently construct VersionNumber objects from semver-format literal strings, VERSION for the VersionNumber of Julia itself, and Version Number Literals in the manual.

Examples

julia> a = VersionNumber(1, 2, 3)
+julia> rm("myfile.txt")
source
Base.Sys.usernameFunction
Sys.username() -> String

Return the username for the current user. If the username cannot be determined or is empty, this function throws an error.

To retrieve a username that is overridable via an environment variable, e.g., USER, consider using

user = get(Sys.username, ENV, "USER")
Julia 1.11

This function requires at least Julia 1.11.

See also homedir.

source
Base.@staticMacro
@static

Partially evaluate an expression at parse time.

For example, @static Sys.iswindows() ? foo : bar will evaluate Sys.iswindows() and insert either foo or bar into the expression. This is useful in cases where a construct would be invalid on other platforms, such as a ccall to a non-existent function. @static if Sys.isapple() foo end and @static foo <&&,||> bar are also valid syntax.

source

Versioning

Base.VersionNumberType
VersionNumber

Version number type which follows the specifications of semantic versioning (semver), composed of major, minor and patch numeric values, followed by pre-release and build alphanumeric annotations.

VersionNumber objects can be compared with all of the standard comparison operators (==, <, <=, etc.), with the result following semver v2.0.0-rc.2 rules.

VersionNumber has the following public fields:

  • v.major::Integer
  • v.minor::Integer
  • v.patch::Integer
  • v.prerelease::Tuple{Vararg{Union{Integer, AbstractString}}}
  • v.build::Tuple{Vararg{Union{Integer, AbstractString}}}

See also @v_str to efficiently construct VersionNumber objects from semver-format literal strings, VERSION for the VersionNumber of Julia itself, and Version Number Literals in the manual.

Examples

julia> a = VersionNumber(1, 2, 3)
 v"1.2.3"
 
 julia> a >= v"1.2"
@@ -1651,14 +1651,14 @@
 v"2.0.1-rc1"
 
 julia> b >= v"2.0.1"
-false
source
Base.@v_strMacro
@v_str

String macro used to parse a string to a VersionNumber.

Examples

julia> v"1.2.3"
+false
source
Base.@v_strMacro
@v_str

String macro used to parse a string to a VersionNumber.

Examples

julia> v"1.2.3"
 v"1.2.3"
 
 julia> v"2.0.1-rc1"
-v"2.0.1-rc1"
source

Errors

Base.errorFunction
error(message::AbstractString)

Raise an ErrorException with the given message.

source
error(msg...)

Raise an ErrorException with a message constructed by string(msg...).

source
Core.throwFunction
throw(e)

Throw an object as an exception.

See also: rethrow, error.

source
Base.rethrowFunction
rethrow()

Rethrow the current exception from within a catch block. The rethrown exception will continue propagation as if it had not been caught.

Note

The alternative form rethrow(e) allows you to associate an alternative exception object e with the current backtrace. However this misrepresents the program state at the time of the error so you're encouraged to instead throw a new exception using throw(e). In Julia 1.1 and above, using throw(e) will preserve the root cause exception on the stack, as described in current_exceptions.

source
Base.backtraceFunction
backtrace()

Get a backtrace object for the current program point.

source
Base.catch_backtraceFunction
catch_backtrace()

Get the backtrace of the current exception, for use within catch blocks.

source
Base.current_exceptionsFunction
current_exceptions(task::Task=current_task(); [backtrace::Bool=true])

Get the stack of exceptions currently being handled. For nested catch blocks there may be more than one current exception in which case the most recently thrown exception is last in the stack. The stack is returned as an ExceptionStack which is an AbstractVector of named tuples (exception,backtrace). If backtrace is false, the backtrace in each pair will be set to nothing.

Explicitly passing task will return the current exception stack on an arbitrary task. This is useful for inspecting tasks which have failed due to uncaught exceptions.

Julia 1.7

This function went by the experimental name catch_stack() in Julia 1.1–1.6, and had a plain Vector-of-tuples as a return type.

source
Base.@assertMacro
@assert cond [text]

Throw an AssertionError if cond is false. This is the preferred syntax for writing assertions, which are conditions that are assumed to be true, but that the user might decide to check anyways, as an aid to debugging if they fail. The optional message text is displayed upon assertion failure.

Warning

An assert might be disabled at some optimization levels. Assert should therefore only be used as a debugging tool and not used for authentication verification (e.g., verifying passwords or checking array bounds). The code must not rely on the side effects of running cond for the correct behavior of a function.

Examples

julia> @assert iseven(3) "3 is an odd number!"
+v"2.0.1-rc1"
source

Errors

Base.errorFunction
error(message::AbstractString)

Raise an ErrorException with the given message.

source
error(msg...)

Raise an ErrorException with a message constructed by string(msg...).

source
Core.throwFunction
throw(e)

Throw an object as an exception.

See also: rethrow, error.

source
Base.rethrowFunction
rethrow()

Rethrow the current exception from within a catch block. The rethrown exception will continue propagation as if it had not been caught.

Note

The alternative form rethrow(e) allows you to associate an alternative exception object e with the current backtrace. However this misrepresents the program state at the time of the error so you're encouraged to instead throw a new exception using throw(e). In Julia 1.1 and above, using throw(e) will preserve the root cause exception on the stack, as described in current_exceptions.

source
Base.backtraceFunction
backtrace()

Get a backtrace object for the current program point.

source
Base.catch_backtraceFunction
catch_backtrace()

Get the backtrace of the current exception, for use within catch blocks.

source
Base.current_exceptionsFunction
current_exceptions(task::Task=current_task(); [backtrace::Bool=true])

Get the stack of exceptions currently being handled. For nested catch blocks there may be more than one current exception in which case the most recently thrown exception is last in the stack. The stack is returned as an ExceptionStack which is an AbstractVector of named tuples (exception,backtrace). If backtrace is false, the backtrace in each pair will be set to nothing.

Explicitly passing task will return the current exception stack on an arbitrary task. This is useful for inspecting tasks which have failed due to uncaught exceptions.

Julia 1.7

This function went by the experimental name catch_stack() in Julia 1.1–1.6, and had a plain Vector-of-tuples as a return type.

source
Base.@assertMacro
@assert cond [text]

Throw an AssertionError if cond is false. This is the preferred syntax for writing assertions, which are conditions that are assumed to be true, but that the user might decide to check anyways, as an aid to debugging if they fail. The optional message text is displayed upon assertion failure.

Warning

An assert might be disabled at some optimization levels. Assert should therefore only be used as a debugging tool and not used for authentication verification (e.g., verifying passwords or checking array bounds). The code must not rely on the side effects of running cond for the correct behavior of a function.

Examples

julia> @assert iseven(3) "3 is an odd number!"
 ERROR: AssertionError: 3 is an odd number!
 
-julia> @assert isodd(3) "What even are numbers?"
source
Base.Experimental.register_error_hintFunction
Experimental.register_error_hint(handler, exceptiontype)

Register a "hinting" function handler(io, exception) that can suggest potential ways for users to circumvent errors. handler should examine exception to see whether the conditions appropriate for a hint are met, and if so generate output to io. Packages should call register_error_hint from within their __init__ function.

For specific exception types, handler is required to accept additional arguments:

  • MethodError: provide handler(io, exc::MethodError, argtypes, kwargs), which splits the combined arguments into positional and keyword arguments.

When issuing a hint, the output should typically start with \n.

If you define custom exception types, your showerror method can support hints by calling Experimental.show_error_hints.

Examples

julia> module Hinter
+julia> @assert isodd(3) "What even are numbers?"
source
Base.Experimental.register_error_hintFunction
Experimental.register_error_hint(handler, exceptiontype)

Register a "hinting" function handler(io, exception) that can suggest potential ways for users to circumvent errors. handler should examine exception to see whether the conditions appropriate for a hint are met, and if so generate output to io. Packages should call register_error_hint from within their __init__ function.

For specific exception types, handler is required to accept additional arguments:

  • MethodError: provide handler(io, exc::MethodError, argtypes, kwargs), which splits the combined arguments into positional and keyword arguments.

When issuing a hint, the output should typically start with \n.

If you define custom exception types, your showerror method can support hints by calling Experimental.show_error_hints.

Examples

julia> module Hinter
 
        only_int(x::Int)      = 1
        any_number(x::Number) = 2
@@ -1678,8 +1678,8 @@
 The function `only_int` exists, but no method is defined for this combination of argument types.
 Did you mean to call `any_number`?
 Closest candidates are:
-    ...
Julia 1.5

Custom error hints are available as of Julia 1.5.

Warning

This interface is experimental and subject to change or removal without notice. To insulate yourself against changes, consider putting any registrations inside an if isdefined(Base.Experimental, :register_error_hint) ... end block.

source
Base.Experimental.show_error_hintsFunction
Experimental.show_error_hints(io, ex, args...)

Invoke all handlers from Experimental.register_error_hint for the particular exception type typeof(ex). args must contain any other arguments expected by the handler for that type.

Julia 1.5

Custom error hints are available as of Julia 1.5.

Warning

This interface is experimental and subject to change or removal without notice.

source
Core.ArgumentErrorType
ArgumentError(msg)

The arguments passed to a function are invalid. msg is a descriptive error message.

source
Core.AssertionErrorType
AssertionError([msg])

The asserted condition did not evaluate to true. Optional argument msg is a descriptive error string.

Examples

julia> @assert false "this is not true"
-ERROR: AssertionError: this is not true

AssertionError is usually thrown from @assert.

source
Core.BoundsErrorType
BoundsError([a],[i])

An indexing operation into an array, a, tried to access an out-of-bounds element at index i.

Examples

julia> A = fill(1.0, 7);
+    ...
Julia 1.5

Custom error hints are available as of Julia 1.5.

Warning

This interface is experimental and subject to change or removal without notice. To insulate yourself against changes, consider putting any registrations inside an if isdefined(Base.Experimental, :register_error_hint) ... end block.

source
Base.Experimental.show_error_hintsFunction
Experimental.show_error_hints(io, ex, args...)

Invoke all handlers from Experimental.register_error_hint for the particular exception type typeof(ex). args must contain any other arguments expected by the handler for that type.

Julia 1.5

Custom error hints are available as of Julia 1.5.

Warning

This interface is experimental and subject to change or removal without notice.

source
Core.ArgumentErrorType
ArgumentError(msg)

The arguments passed to a function are invalid. msg is a descriptive error message.

source
Core.AssertionErrorType
AssertionError([msg])

The asserted condition did not evaluate to true. Optional argument msg is a descriptive error string.

Examples

julia> @assert false "this is not true"
+ERROR: AssertionError: this is not true

AssertionError is usually thrown from @assert.

source
Core.BoundsErrorType
BoundsError([a],[i])

An indexing operation into an array, a, tried to access an out-of-bounds element at index i.

Examples

julia> A = fill(1.0, 7);
 
 julia> A[8]
 ERROR: BoundsError: attempt to access 7-element Vector{Float64} at index [8]
@@ -1693,24 +1693,24 @@
 
 julia> B[9]
 ERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [9]
-
source
Base.CompositeExceptionType
CompositeException

Wrap a Vector of exceptions thrown by a Task (e.g. generated from a remote worker over a channel or an asynchronously executing local I/O write or a remote worker under pmap) with information about the series of exceptions. For example, if a group of workers are executing several tasks, and multiple workers fail, the resulting CompositeException will contain a "bundle" of information from each worker indicating where and why the exception(s) occurred.

source
Base.DimensionMismatchType
DimensionMismatch([msg])

The objects called do not have matching dimensionality. Optional argument msg is a descriptive error string.

source
Core.DivideErrorType
DivideError()

Integer division was attempted with a denominator value of 0.

Examples

julia> 2/0
+
source
Base.CompositeExceptionType
CompositeException

Wrap a Vector of exceptions thrown by a Task (e.g. generated from a remote worker over a channel or an asynchronously executing local I/O write or a remote worker under pmap) with information about the series of exceptions. For example, if a group of workers are executing several tasks, and multiple workers fail, the resulting CompositeException will contain a "bundle" of information from each worker indicating where and why the exception(s) occurred.

source
Base.DimensionMismatchType
DimensionMismatch([msg])

The objects called do not have matching dimensionality. Optional argument msg is a descriptive error string.

source
Core.DivideErrorType
DivideError()

Integer division was attempted with a denominator value of 0.

Examples

julia> 2/0
 Inf
 
 julia> div(2, 0)
 ERROR: DivideError: integer division error
 Stacktrace:
-[...]
source
Core.DomainErrorType
DomainError(val)
+[...]
source
Core.DomainErrorType
DomainError(val)
 DomainError(val, msg)

The argument val to a function or constructor is outside the valid domain.

Examples

julia> sqrt(-1)
 ERROR: DomainError with -1.0:
 sqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
 Stacktrace:
-[...]
source
Base.EOFErrorType
EOFError()

No more data was available to read from a file or stream.

source
Core.ErrorExceptionType
ErrorException(msg)

Generic error type. The error message, in the .msg field, may provide more specific details.

Examples

julia> ex = ErrorException("I've done a bad thing");
+[...]
source
Base.EOFErrorType
EOFError()

No more data was available to read from a file or stream.

source
Core.ErrorExceptionType
ErrorException(msg)

Generic error type. The error message, in the .msg field, may provide more specific details.

Examples

julia> ex = ErrorException("I've done a bad thing");
 
 julia> ex.msg
-"I've done a bad thing"
source
Core.InexactErrorType
InexactError(name::Symbol, T, val)

Cannot exactly convert val to type T in a method of function name.

Examples

julia> convert(Float64, 1+2im)
+"I've done a bad thing"
source
Core.InexactErrorType
InexactError(name::Symbol, T, val)

Cannot exactly convert val to type T in a method of function name.

Examples

julia> convert(Float64, 1+2im)
 ERROR: InexactError: Float64(1 + 2im)
 Stacktrace:
-[...]
source
Core.InterruptExceptionType
InterruptException()

The process was stopped by a terminal interrupt (CTRL+C).

Note that, in Julia script started without -i (interactive) option, InterruptException is not thrown by default. Calling Base.exit_on_sigint(false) in the script can recover the behavior of the REPL. Alternatively, a Julia script can be started with

julia -e "include(popfirst!(ARGS))" script.jl

to let InterruptException be thrown by CTRL+C during the execution.

source
Base.KeyErrorType
KeyError(key)

An indexing operation into an AbstractDict (Dict) or Set like object tried to access or delete a non-existent element.

source
Core.LoadErrorType
LoadError(file::AbstractString, line::Int, error)

An error occurred while includeing, requireing, or using a file. The error specifics should be available in the .error field.

Julia 1.7

LoadErrors are no longer emitted by @macroexpand, @macroexpand1, and macroexpand as of Julia 1.7.

source
Core.MethodErrorType
MethodError(f, args)

A method with the required type signature does not exist in the given generic function. Alternatively, there is no unique most-specific method.

source
Base.MissingExceptionType
MissingException(msg)

Exception thrown when a missing value is encountered in a situation where it is not supported. The error message, in the msg field may provide more specific details.

source
Core.OutOfMemoryErrorType
OutOfMemoryError()

An operation allocated too much memory for either the system or the garbage collector to handle properly.

source
Core.ReadOnlyMemoryErrorType
ReadOnlyMemoryError()

An operation tried to write to memory that is read-only.

source
Core.OverflowErrorType
OverflowError(msg)

The result of an expression is too large for the specified type and will cause a wraparound.

source
Base.ProcessFailedExceptionType
ProcessFailedException

Indicates problematic exit status of a process. When running commands or pipelines, this is thrown to indicate a nonzero exit code was returned (i.e. that the invoked process failed).

source
Base.TaskFailedExceptionType
TaskFailedException

This exception is thrown by a wait(t) call when task t fails. TaskFailedException wraps the failed task t.

source
Core.StackOverflowErrorType
StackOverflowError()

The function call grew beyond the size of the call stack. This usually happens when a call recurses infinitely.

source
Base.SystemErrorType
SystemError(prefix::AbstractString, [errno::Int32])

A system call failed with an error code (in the errno global variable).

source
Core.TypeErrorType
TypeError(func::Symbol, context::AbstractString, expected::Type, got)

A type assertion failure, or calling an intrinsic function with an incorrect argument type.

source
Core.UndefKeywordErrorType
UndefKeywordError(var::Symbol)

The required keyword argument var was not assigned in a function call.

Examples

julia> function my_func(;my_arg)
+[...]
source
Core.InterruptExceptionType
InterruptException()

The process was stopped by a terminal interrupt (CTRL+C).

Note that, in Julia script started without -i (interactive) option, InterruptException is not thrown by default. Calling Base.exit_on_sigint(false) in the script can recover the behavior of the REPL. Alternatively, a Julia script can be started with

julia -e "include(popfirst!(ARGS))" script.jl

to let InterruptException be thrown by CTRL+C during the execution.

source
Base.KeyErrorType
KeyError(key)

An indexing operation into an AbstractDict (Dict) or Set like object tried to access or delete a non-existent element.

source
Core.LoadErrorType
LoadError(file::AbstractString, line::Int, error)

An error occurred while includeing, requireing, or using a file. The error specifics should be available in the .error field.

Julia 1.7

LoadErrors are no longer emitted by @macroexpand, @macroexpand1, and macroexpand as of Julia 1.7.

source
Core.MethodErrorType
MethodError(f, args)

A method with the required type signature does not exist in the given generic function. Alternatively, there is no unique most-specific method.

source
Base.MissingExceptionType
MissingException(msg)

Exception thrown when a missing value is encountered in a situation where it is not supported. The error message, in the msg field may provide more specific details.

source
Core.OutOfMemoryErrorType
OutOfMemoryError()

An operation allocated too much memory for either the system or the garbage collector to handle properly.

source
Core.ReadOnlyMemoryErrorType
ReadOnlyMemoryError()

An operation tried to write to memory that is read-only.

source
Core.OverflowErrorType
OverflowError(msg)

The result of an expression is too large for the specified type and will cause a wraparound.

source
Base.ProcessFailedExceptionType
ProcessFailedException

Indicates problematic exit status of a process. When running commands or pipelines, this is thrown to indicate a nonzero exit code was returned (i.e. that the invoked process failed).

source
Base.TaskFailedExceptionType
TaskFailedException

This exception is thrown by a wait(t) call when task t fails. TaskFailedException wraps the failed task t.

source
Core.StackOverflowErrorType
StackOverflowError()

The function call grew beyond the size of the call stack. This usually happens when a call recurses infinitely.

source
Base.SystemErrorType
SystemError(prefix::AbstractString, [errno::Int32])

A system call failed with an error code (in the errno global variable).

source
Core.TypeErrorType
TypeError(func::Symbol, context::AbstractString, expected::Type, got)

A type assertion failure, or calling an intrinsic function with an incorrect argument type.

source
Core.UndefKeywordErrorType
UndefKeywordError(var::Symbol)

The required keyword argument var was not assigned in a function call.

Examples

julia> function my_func(;my_arg)
            return my_arg + 1
        end
 my_func (generic function with 1 method)
@@ -1719,7 +1719,7 @@
 ERROR: UndefKeywordError: keyword argument `my_arg` not assigned
 Stacktrace:
  [1] my_func() at ./REPL[1]:2
- [2] top-level scope at REPL[2]:1
source
Core.UndefRefErrorType
UndefRefError()

The item or field is not defined for the given object.

Examples

julia> struct MyType
+ [2] top-level scope at REPL[2]:1
source
Core.UndefRefErrorType
UndefRefError()

The item or field is not defined for the given object.

Examples

julia> struct MyType
            a::Vector{Int}
            MyType() = new()
        end
@@ -1730,17 +1730,17 @@
 julia> A.a
 ERROR: UndefRefError: access to undefined reference
 Stacktrace:
-[...]
source
Core.UndefVarErrorType
UndefVarError(var::Symbol, [scope])

A symbol in the current scope is not defined.

Examples

julia> a
+[...]
source
Core.UndefVarErrorType
UndefVarError(var::Symbol, [scope])

A symbol in the current scope is not defined.

Examples

julia> a
 ERROR: UndefVarError: `a` not defined in `Main`
 
 julia> a = 1;
 
 julia> a
-1
source
Base.StringIndexErrorType
StringIndexError(str, i)

An error occurred when trying to access str at index i that is not valid.

source
Core.InitErrorType
InitError(mod::Symbol, error)

An error occurred when running a module's __init__ function. The actual error thrown is available in the .error field.

source
Base.retryFunction
retry(f;  delays=ExponentialBackOff(), check=nothing) -> Function

Return an anonymous function that calls function f. If an exception arises, f is repeatedly called again, each time check returns true, after waiting the number of seconds specified in delays. check should input delays's current state and the Exception.

Julia 1.2

Before Julia 1.2 this signature was restricted to f::Function.

Examples

retry(f, delays=fill(5.0, 3))
+1
source
Base.StringIndexErrorType
StringIndexError(str, i)

An error occurred when trying to access str at index i that is not valid.

source
Core.InitErrorType
InitError(mod::Symbol, error)

An error occurred when running a module's __init__ function. The actual error thrown is available in the .error field.

source
Base.retryFunction
retry(f;  delays=ExponentialBackOff(), check=nothing) -> Function

Return an anonymous function that calls function f. If an exception arises, f is repeatedly called again, each time check returns true, after waiting the number of seconds specified in delays. check should input delays's current state and the Exception.

Julia 1.2

Before Julia 1.2 this signature was restricted to f::Function.

Examples

retry(f, delays=fill(5.0, 3))
 retry(f, delays=rand(5:10, 2))
 retry(f, delays=Base.ExponentialBackOff(n=3, first_delay=5, max_delay=1000))
 retry(http_get, check=(s,e)->e.status == "503")(url)
-retry(read, check=(s,e)->isa(e, IOError))(io, 128; all=false)
source
Base.ExponentialBackOffType
ExponentialBackOff(; n=1, first_delay=0.05, max_delay=10.0, factor=5.0, jitter=0.1)

A Float64 iterator of length n whose elements exponentially increase at a rate in the interval factor * (1 ± jitter). The first element is first_delay and all elements are clamped to max_delay.

source

Events

Base.TimerMethod
Timer(callback::Function, delay; interval = 0)

Create a timer that runs the function callback at each timer expiration.

Waiting tasks are woken and the function callback is called after an initial delay of delay seconds, and then repeating with the given interval in seconds. If interval is equal to 0, the callback is only run once. The function callback is called with a single argument, the timer itself. Stop a timer by calling close. The callback may still be run one final time, if the timer has already expired.

Examples

Here the first number is printed after a delay of two seconds, then the following numbers are printed quickly.

julia> begin
+retry(read, check=(s,e)->isa(e, IOError))(io, 128; all=false)
source
Base.ExponentialBackOffType
ExponentialBackOff(; n=1, first_delay=0.05, max_delay=10.0, factor=5.0, jitter=0.1)

A Float64 iterator of length n whose elements exponentially increase at a rate in the interval factor * (1 ± jitter). The first element is first_delay and all elements are clamped to max_delay.

source

Events

Base.TimerMethod
Timer(callback::Function, delay; interval = 0)

Create a timer that runs the function callback at each timer expiration.

Waiting tasks are woken and the function callback is called after an initial delay of delay seconds, and then repeating with the given interval in seconds. If interval is equal to 0, the callback is only run once. The function callback is called with a single argument, the timer itself. Stop a timer by calling close. The callback may still be run one final time, if the timer has already expired.

Examples

Here the first number is printed after a delay of two seconds, then the following numbers are printed quickly.

julia> begin
            i = 0
            cb(timer) = (global i += 1; println(i))
            t = Timer(cb, 2, interval=0.2)
@@ -1750,12 +1750,12 @@
        end
 1
 2
-3
source
Base.TimerType
Timer(delay; interval = 0)

Create a timer that wakes up tasks waiting for it (by calling wait on the timer object).

Waiting tasks are woken after an initial delay of at least delay seconds, and then repeating after at least interval seconds again elapse. If interval is equal to 0, the timer is only triggered once. When the timer is closed (by close) waiting tasks are woken with an error. Use isopen to check whether a timer is still active.

Note

interval is subject to accumulating time skew. If you need precise events at a particular absolute time, create a new timer at each expiration with the difference to the next time computed.

Note

A Timer requires yield points to update its state. For instance, isopen(t::Timer) cannot be used to timeout a non-yielding while loop.

source
Base.AsyncConditionType
AsyncCondition()

Create a async condition that wakes up tasks waiting for it (by calling wait on the object) when notified from C by a call to uv_async_send. Waiting tasks are woken with an error when the object is closed (by close). Use isopen to check whether it is still active.

This provides an implicit acquire & release memory ordering between the sending and waiting threads.

source
Base.AsyncConditionMethod
AsyncCondition(callback::Function)

Create a async condition that calls the given callback function. The callback is passed one argument, the async condition object itself.

source

Reflection

Base.nameofMethod
nameof(m::Module) -> Symbol

Get the name of a Module as a Symbol.

Examples

julia> nameof(Base.Broadcast)
-:Broadcast
source
Base.parentmoduleFunction
parentmodule(m::Module) -> Module

Get a module's enclosing Module. Main is its own parent.

See also: names, nameof, fullname, @__MODULE__.

Examples

julia> parentmodule(Main)
+3
source
Base.TimerType
Timer(delay; interval = 0)

Create a timer that wakes up tasks waiting for it (by calling wait on the timer object).

Waiting tasks are woken after an initial delay of at least delay seconds, and then repeating after at least interval seconds again elapse. If interval is equal to 0, the timer is only triggered once. When the timer is closed (by close) waiting tasks are woken with an error. Use isopen to check whether a timer is still active.

Note

interval is subject to accumulating time skew. If you need precise events at a particular absolute time, create a new timer at each expiration with the difference to the next time computed.

Note

A Timer requires yield points to update its state. For instance, isopen(t::Timer) cannot be used to timeout a non-yielding while loop.

source
Base.AsyncConditionType
AsyncCondition()

Create a async condition that wakes up tasks waiting for it (by calling wait on the object) when notified from C by a call to uv_async_send. Waiting tasks are woken with an error when the object is closed (by close). Use isopen to check whether it is still active.

This provides an implicit acquire & release memory ordering between the sending and waiting threads.

source
Base.AsyncConditionMethod
AsyncCondition(callback::Function)

Create a async condition that calls the given callback function. The callback is passed one argument, the async condition object itself.

source

Reflection

Base.nameofMethod
nameof(m::Module) -> Symbol

Get the name of a Module as a Symbol.

Examples

julia> nameof(Base.Broadcast)
+:Broadcast
source
Base.parentmoduleFunction
parentmodule(m::Module) -> Module

Get a module's enclosing Module. Main is its own parent.

See also: names, nameof, fullname, @__MODULE__.

Examples

julia> parentmodule(Main)
 Main
 
 julia> parentmodule(Base.Broadcast)
-Base
source
parentmodule(t::DataType) -> Module

Determine the module containing the definition of a (potentially UnionAll-wrapped) DataType.

Examples

julia> module Foo
+Base
source
parentmodule(t::DataType) -> Module

Determine the module containing the definition of a (potentially UnionAll-wrapped) DataType.

Examples

julia> module Foo
            struct Int end
        end
 Foo
@@ -1764,11 +1764,11 @@
 Core
 
 julia> parentmodule(Foo.Int)
-Foo
source
parentmodule(f::Function) -> Module

Determine the module containing the (first) definition of a generic function.

source
parentmodule(f::Function, types) -> Module

Determine the module containing the first method of a generic function f matching the specified types.

source
parentmodule(m::Method) -> Module

Return the module in which the given method m is defined.

Julia 1.9

Passing a Method as an argument requires Julia 1.9 or later.

source
Base.pathofMethod
pathof(m::Module)

Return the path of the m.jl file that was used to import module m, or nothing if m was not imported from a package.

Use dirname to get the directory part and basename to get the file name part of the path.

See also pkgdir.

source
Base.pkgdirMethod
pkgdir(m::Module[, paths::String...])

Return the root directory of the package that declared module m, or nothing if m was not declared in a package. Optionally further path component strings can be provided to construct a path within the package root.

To get the root directory of the package that implements the current module the form pkgdir(@__MODULE__) can be used.

julia> pkgdir(Foo)
+Foo
source
parentmodule(f::Function) -> Module

Determine the module containing the (first) definition of a generic function.

source
parentmodule(f::Function, types) -> Module

Determine the module containing the first method of a generic function f matching the specified types.

source
parentmodule(m::Method) -> Module

Return the module in which the given method m is defined.

Julia 1.9

Passing a Method as an argument requires Julia 1.9 or later.

source
Base.pathofMethod
pathof(m::Module)

Return the path of the m.jl file that was used to import module m, or nothing if m was not imported from a package.

Use dirname to get the directory part and basename to get the file name part of the path.

See also pkgdir.

source
Base.pkgdirMethod
pkgdir(m::Module[, paths::String...])

Return the root directory of the package that declared module m, or nothing if m was not declared in a package. Optionally further path component strings can be provided to construct a path within the package root.

To get the root directory of the package that implements the current module the form pkgdir(@__MODULE__) can be used.

julia> pkgdir(Foo)
 "/path/to/Foo.jl"
 
 julia> pkgdir(Foo, "src", "file.jl")
-"/path/to/Foo.jl/src/file.jl"

See also pathof.

Julia 1.7

The optional argument paths requires at least Julia 1.7.

source
Base.pkgversionMethod
pkgversion(m::Module)

Return the version of the package that imported module m, or nothing if m was not imported from a package, or imported from a package without a version field set.

The version is read from the package's Project.toml during package load.

To get the version of the package that imported the current module the form pkgversion(@__MODULE__) can be used.

Julia 1.9

This function was introduced in Julia 1.9.

source
Base.modulerootFunction
moduleroot(m::Module) -> Module

Find the root module of a given module. This is the first module in the chain of parent modules of m which is either a registered root module or which is its own parent module.

source
__module__Keyword
__module__

The argument __module__ is only visible inside the macro, and it provides information (in the form of a Module object) about the expansion context of the macro invocation. See the manual section on Macro invocation for more information.

source
__source__Keyword
__source__

The argument __source__ is only visible inside the macro, and it provides information (in the form of a LineNumberNode object) about the parser location of the @ sign from the macro invocation. See the manual section on Macro invocation for more information.

source
Base.@__MODULE__Macro
@__MODULE__ -> Module

Get the Module of the toplevel eval, which is the Module code is currently being read from.

source
Base.@__FILE__Macro
@__FILE__ -> String

Expand to a string with the path to the file containing the macrocall, or an empty string if evaluated by julia -e <expr>. Return nothing if the macro was missing parser source information. Alternatively see PROGRAM_FILE.

source
Base.@__DIR__Macro
@__DIR__ -> String

Macro to obtain the absolute path of the current directory as a string.

If in a script, returns the directory of the script containing the @__DIR__ macrocall. If run from a REPL or if evaluated by julia -e <expr>, returns the current working directory.

Examples

The example illustrates the difference in the behaviors of @__DIR__ and pwd(), by creating a simple script in a different directory than the current working one and executing both commands:

julia> cd("/home/JuliaUser") # working directory
+"/path/to/Foo.jl/src/file.jl"

See also pathof.

Julia 1.7

The optional argument paths requires at least Julia 1.7.

source
Base.pkgversionMethod
pkgversion(m::Module)

Return the version of the package that imported module m, or nothing if m was not imported from a package, or imported from a package without a version field set.

The version is read from the package's Project.toml during package load.

To get the version of the package that imported the current module the form pkgversion(@__MODULE__) can be used.

Julia 1.9

This function was introduced in Julia 1.9.

source
Base.modulerootFunction
moduleroot(m::Module) -> Module

Find the root module of a given module. This is the first module in the chain of parent modules of m which is either a registered root module or which is its own parent module.

source
__module__Keyword
__module__

The argument __module__ is only visible inside the macro, and it provides information (in the form of a Module object) about the expansion context of the macro invocation. See the manual section on Macro invocation for more information.

source
__source__Keyword
__source__

The argument __source__ is only visible inside the macro, and it provides information (in the form of a LineNumberNode object) about the parser location of the @ sign from the macro invocation. See the manual section on Macro invocation for more information.

source
Base.@__MODULE__Macro
@__MODULE__ -> Module

Get the Module of the toplevel eval, which is the Module code is currently being read from.

source
Base.@__FILE__Macro
@__FILE__ -> String

Expand to a string with the path to the file containing the macrocall, or an empty string if evaluated by julia -e <expr>. Return nothing if the macro was missing parser source information. Alternatively see PROGRAM_FILE.

source
Base.@__DIR__Macro
@__DIR__ -> String

Macro to obtain the absolute path of the current directory as a string.

If in a script, returns the directory of the script containing the @__DIR__ macrocall. If run from a REPL or if evaluated by julia -e <expr>, returns the current working directory.

Examples

The example illustrates the difference in the behaviors of @__DIR__ and pwd(), by creating a simple script in a different directory than the current working one and executing both commands:

julia> cd("/home/JuliaUser") # working directory
 
 julia> # create script at /home/JuliaUser/Projects
        open("/home/JuliaUser/Projects/test.jl","w") do io
@@ -1781,11 +1781,11 @@
 julia> # outputs script directory and current working directory
        include("/home/JuliaUser/Projects/test.jl")
 @__DIR__ = /home/JuliaUser/Projects
-pwd() = /home/JuliaUser
source
Base.@__LINE__Macro
@__LINE__ -> Int

Expand to the line number of the location of the macrocall. Return 0 if the line number could not be determined.

source
Base.fullnameFunction
fullname(m::Module)

Get the fully-qualified name of a module as a tuple of symbols. For example,

Examples

julia> fullname(Base.Iterators)
+pwd() = /home/JuliaUser
source
Base.@__LINE__Macro
@__LINE__ -> Int

Expand to the line number of the location of the macrocall. Return 0 if the line number could not be determined.

source
Base.fullnameFunction
fullname(m::Module)

Get the fully-qualified name of a module as a tuple of symbols. For example,

Examples

julia> fullname(Base.Iterators)
 (:Base, :Iterators)
 
 julia> fullname(Main)
-(:Main,)
source
Base.namesFunction
names(x::Module; all::Bool = false, imported::Bool = false)

Get a vector of the public names of a Module, excluding deprecated names. If all is true, then the list also includes non-public names defined in the module, deprecated names, and compiler-generated names. If imported is true, then names explicitly imported from other modules are also included. Names are returned in sorted order.

As a special case, all names defined in Main are considered "public", since it is not idiomatic to explicitly mark names from Main as public.

Note

sym ∈ names(SomeModule) does not imply isdefined(SomeModule, sym). names will return symbols marked with public or export, even if they are not defined in the module.

See also: Base.isexported, Base.ispublic, Base.@locals, @__MODULE__.

source
Base.isexportedFunction
isexported(m::Module, s::Symbol) -> Bool

Returns whether a symbol is exported from a module.

See also: ispublic, names

julia> module Mod
+(:Main,)
source
Base.namesFunction
names(x::Module; all::Bool = false, imported::Bool = false)

Get a vector of the public names of a Module, excluding deprecated names. If all is true, then the list also includes non-public names defined in the module, deprecated names, and compiler-generated names. If imported is true, then names explicitly imported from other modules are also included. Names are returned in sorted order.

As a special case, all names defined in Main are considered "public", since it is not idiomatic to explicitly mark names from Main as public.

Note

sym ∈ names(SomeModule) does not imply isdefined(SomeModule, sym). names will return symbols marked with public or export, even if they are not defined in the module.

See also: Base.isexported, Base.ispublic, Base.@locals, @__MODULE__.

source
Base.isexportedFunction
isexported(m::Module, s::Symbol) -> Bool

Returns whether a symbol is exported from a module.

See also: ispublic, names

julia> module Mod
            export foo
            public bar
        end
@@ -1798,7 +1798,7 @@
 false
 
 julia> Base.isexported(Mod, :baz)
-false
source
Base.ispublicFunction
ispublic(m::Module, s::Symbol) -> Bool

Returns whether a symbol is marked as public in a module.

Exported symbols are considered public.

Julia 1.11

This function and the notion of publicity were added in Julia 1.11.

See also: isexported, names

julia> module Mod
+false
source
Base.ispublicFunction
ispublic(m::Module, s::Symbol) -> Bool

Returns whether a symbol is marked as public in a module.

Exported symbols are considered public.

Julia 1.11

This function and the notion of publicity were added in Julia 1.11.

See also: isexported, names

julia> module Mod
            export foo
            public bar
        end
@@ -1811,7 +1811,7 @@
 true
 
 julia> Base.ispublic(Mod, :baz)
-false
source
Base.nameofMethod
nameof(f::Function) -> Symbol

Get the name of a generic Function as a symbol. For anonymous functions, this is a compiler-generated name. For explicitly-declared subtypes of Function, it is the name of the function's type.

source
Base.functionlocMethod
functionloc(f::Function, types)

Return a tuple (filename,line) giving the location of a generic Function definition.

source
Base.functionlocMethod
functionloc(m::Method)

Return a tuple (filename,line) giving the location of a Method definition.

source
Base.@localsMacro
@locals()

Construct a dictionary of the names (as symbols) and values of all local variables defined as of the call site.

Julia 1.1

This macro requires at least Julia 1.1.

Examples

julia> let x = 1, y = 2
+false
source
Base.nameofMethod
nameof(f::Function) -> Symbol

Get the name of a generic Function as a symbol. For anonymous functions, this is a compiler-generated name. For explicitly-declared subtypes of Function, it is the name of the function's type.

source
Base.functionlocMethod
functionloc(f::Function, types)

Return a tuple (filename,line) giving the location of a generic Function definition.

source
Base.functionlocMethod
functionloc(m::Method)

Return a tuple (filename,line) giving the location of a Method definition.

source
Base.@localsMacro
@locals()

Construct a dictionary of the names (as symbols) and values of all local variables defined as of the call site.

Julia 1.1

This macro requires at least Julia 1.1.

Examples

julia> let x = 1, y = 2
            Base.@locals
        end
 Dict{Symbol, Any} with 2 entries:
@@ -1832,7 +1832,7 @@
 julia> f(42)
 Dict{Symbol, Any}(:x => 42)
 Dict{Symbol, Any}(:i => 1, :x => 42)
-Dict{Symbol, Any}(:y => 2, :x => 42)
source
Core.getglobalFunction
getglobal(module::Module, name::Symbol, [order::Symbol=:monotonic])

Retrieve the value of the binding name from the module module. Optionally, an atomic ordering can be defined for the operation, otherwise it defaults to monotonic.

While accessing module bindings using getfield is still supported to maintain compatibility, using getglobal should always be preferred since getglobal allows for control over atomic ordering (getfield is always monotonic) and better signifies the code's intent both to the user as well as the compiler.

Most users should not have to call this function directly – The getproperty function or corresponding syntax (i.e. module.name) should be preferred in all but few very specific use cases.

Julia 1.9

This function requires Julia 1.9 or later.

See also getproperty and setglobal!.

Examples

julia> a = 1
+Dict{Symbol, Any}(:y => 2, :x => 42)
source
Core.getglobalFunction
getglobal(module::Module, name::Symbol, [order::Symbol=:monotonic])

Retrieve the value of the binding name from the module module. Optionally, an atomic ordering can be defined for the operation, otherwise it defaults to monotonic.

While accessing module bindings using getfield is still supported to maintain compatibility, using getglobal should always be preferred since getglobal allows for control over atomic ordering (getfield is always monotonic) and better signifies the code's intent both to the user as well as the compiler.

Most users should not have to call this function directly – The getproperty function or corresponding syntax (i.e. module.name) should be preferred in all but few very specific use cases.

Julia 1.9

This function requires Julia 1.9 or later.

See also getproperty and setglobal!.

Examples

julia> a = 1
 1
 
 julia> module M
@@ -1843,7 +1843,7 @@
 1
 
 julia> getglobal(M, :a)
-2
source
Core.setglobal!Function
setglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])

Set or change the value of the binding name in the module module to x. No type conversion is performed, so if a type has already been declared for the binding, x must be of appropriate type or an error is thrown.

Additionally, an atomic ordering can be specified for this operation, otherwise it defaults to monotonic.

Users will typically access this functionality through the setproperty! function or corresponding syntax (i.e. module.name = x) instead, so this is intended only for very specific use cases.

Julia 1.9

This function requires Julia 1.9 or later.

See also setproperty! and getglobal

Examples

julia> module M end;
+2
source
Core.setglobal!Function
setglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])

Set or change the value of the binding name in the module module to x. No type conversion is performed, so if a type has already been declared for the binding, x must be of appropriate type or an error is thrown.

Additionally, an atomic ordering can be specified for this operation, otherwise it defaults to monotonic.

Users will typically access this functionality through the setproperty! function or corresponding syntax (i.e. module.name = x) instead, so this is intended only for very specific use cases.

Julia 1.9

This function requires Julia 1.9 or later.

See also setproperty! and getglobal

Examples

julia> module M end;
 
 julia> M.a  # same as `getglobal(M, :a)`
 ERROR: UndefVarError: `a` not defined in `M`
@@ -1853,9 +1853,9 @@
 1
 
 julia> M.a
-1
source
Core.modifyglobal!Function
modifyglobal!(module::Module, name::Symbol, op, x, [order::Symbol=:monotonic]) -> Pair

Atomically perform the operations to get and set a global after applying the function op.

Julia 1.11

This function requires Julia 1.11 or later.

See also modifyproperty! and setglobal!.

source
Core.swapglobal!Function
swapglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])

Atomically perform the operations to simultaneously get and set a global.

Julia 1.11

This function requires Julia 1.11 or later.

See also swapproperty! and setglobal!.

source
Core.setglobalonce!Function
setglobalonce!(module::Module, name::Symbol, value,
-              [success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool

Atomically perform the operations to set a global to a given value, only if it was previously not set.

Julia 1.11

This function requires Julia 1.11 or later.

See also setpropertyonce! and setglobal!.

source
Core.replaceglobal!Function
replaceglobal!(module::Module, name::Symbol, expected, desired,
-              [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)

Atomically perform the operations to get and conditionally set a global to a given value.

Julia 1.11

This function requires Julia 1.11 or later.

See also replaceproperty! and setglobal!.

source

Documentation

(See also the documentation chapter.)

Core.@docMacro

Documentation

Functions, methods and types can be documented by placing a string before the definition:

"""
+1
source
Core.modifyglobal!Function
modifyglobal!(module::Module, name::Symbol, op, x, [order::Symbol=:monotonic]) -> Pair

Atomically perform the operations to get and set a global after applying the function op.

Julia 1.11

This function requires Julia 1.11 or later.

See also modifyproperty! and setglobal!.

source
Core.swapglobal!Function
swapglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])

Atomically perform the operations to simultaneously get and set a global.

Julia 1.11

This function requires Julia 1.11 or later.

See also swapproperty! and setglobal!.

source
Core.setglobalonce!Function
setglobalonce!(module::Module, name::Symbol, value,
+              [success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool

Atomically perform the operations to set a global to a given value, only if it was previously not set.

Julia 1.11

This function requires Julia 1.11 or later.

See also setpropertyonce! and setglobal!.

source
Core.replaceglobal!Function
replaceglobal!(module::Module, name::Symbol, expected, desired,
+              [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)

Atomically perform the operations to get and conditionally set a global to a given value.

Julia 1.11

This function requires Julia 1.11 or later.

See also replaceproperty! and setglobal!.

source

Documentation

(See also the documentation chapter.)

Core.@docMacro

Documentation

Functions, methods and types can be documented by placing a string before the definition:

"""
 # The Foo Function
 `foo(x)`: Foo the living hell out of `x`.
 """
@@ -1863,21 +1863,21 @@
 function foo() ...

By default, documentation is written as Markdown, but any object can be used as the first argument.

Documenting objects separately from their definitions

You can document an object before or after its definition with

@doc "foo" function_to_doc
 @doc "bar" TypeToDoc

For macros, the syntax is @doc "macro doc" :(Module.@macro) or @doc "macro doc" :(string_macro"") for string macros. Without the quote :() the expansion of the macro will be documented.

Retrieving Documentation

You can retrieve docs for functions, macros and other objects as follows:

@doc foo
 @doc @time
-@doc md""

Functions & Methods

Placing documentation before a method definition (e.g. function foo() ... or foo() = ...) will cause that specific method to be documented, as opposed to the whole function. Method docs are concatenated together in the order they were defined to provide docs for the function.

source
Base.Docs.HTMLType

HTML(s): Create an object that renders s as html.

HTML("<div>foo</div>")

You can also use a stream for large amounts of data:

HTML() do io
+@doc md""

Functions & Methods

Placing documentation before a method definition (e.g. function foo() ... or foo() = ...) will cause that specific method to be documented, as opposed to the whole function. Method docs are concatenated together in the order they were defined to provide docs for the function.

source
Base.Docs.HTMLType

HTML(s): Create an object that renders s as html.

HTML("<div>foo</div>")

You can also use a stream for large amounts of data:

HTML() do io
   println(io, "<div>foo</div>")
-end
Warning

HTML is currently exported to maintain backwards compatibility, but this export is deprecated. It is recommended to use this type as Docs.HTML or to explicitly import it from Docs.

source
Base.Docs.TextType

Text(s): Create an object that renders s as plain text.

Text("foo")

You can also use a stream for large amounts of data:

Text() do io
+end
Warning

HTML is currently exported to maintain backwards compatibility, but this export is deprecated. It is recommended to use this type as Docs.HTML or to explicitly import it from Docs.

source
Base.Docs.TextType

Text(s): Create an object that renders s as plain text.

Text("foo")

You can also use a stream for large amounts of data:

Text() do io
   println(io, "foo")
-end
Warning

Text is currently exported to maintain backwards compatibility, but this export is deprecated. It is recommended to use this type as Docs.Text or to explicitly import it from Docs.

source
Base.Docs.hasdocFunction
Docs.hasdoc(mod::Module, sym::Symbol)::Bool

Return true if sym in mod has a docstring and false otherwise.

source
Base.Docs.undocumented_namesFunction
undocumented_names(mod::Module; private=false)

Return a sorted vector of undocumented symbols in module (that is, lacking docstrings). private=false (the default) returns only identifiers declared with public and/or export, whereas private=true returns all symbols in the module (excluding compiler-generated hidden symbols starting with #).

See also: names, Docs.hasdoc, Base.ispublic.

source

Code loading

Base.identify_packageFunction
Base.identify_package(name::String)::Union{PkgId, Nothing}
+end
Warning

Text is currently exported to maintain backwards compatibility, but this export is deprecated. It is recommended to use this type as Docs.Text or to explicitly import it from Docs.

source
Base.Docs.hasdocFunction
Docs.hasdoc(mod::Module, sym::Symbol)::Bool

Return true if sym in mod has a docstring and false otherwise.

source
Base.Docs.undocumented_namesFunction
undocumented_names(mod::Module; private=false)

Return a sorted vector of undocumented symbols in module (that is, lacking docstrings). private=false (the default) returns only identifiers declared with public and/or export, whereas private=true returns all symbols in the module (excluding compiler-generated hidden symbols starting with #).

See also: names, Docs.hasdoc, Base.ispublic.

source

Code loading

Base.identify_packageFunction
Base.identify_package(name::String)::Union{PkgId, Nothing}
 Base.identify_package(where::Union{Module,PkgId}, name::String)::Union{PkgId, Nothing}

Identify the package by its name from the current environment stack, returning its PkgId, or nothing if it cannot be found.

If only the name argument is provided, it searches each environment in the stack and its named direct dependencies.

The where argument provides the context from where to search for the package: in this case it first checks if the name matches the context itself, otherwise it searches all recursive dependencies (from the resolved manifest of each environment) until it locates the context where, and from there identifies the dependency with the corresponding name.

julia> Base.identify_package("Pkg") # Pkg is a dependency of the default environment
 Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]
 
 julia> using LinearAlgebra
 
-julia> Base.identify_package(LinearAlgebra, "Pkg") # Pkg is not a dependency of LinearAlgebra
source
Base.locate_packageFunction
Base.locate_package(pkg::PkgId)::Union{String, Nothing}

The path to the entry-point file for the package corresponding to the identifier pkg, or nothing if not found. See also identify_package.

julia> pkg = Base.identify_package("Pkg")
+julia> Base.identify_package(LinearAlgebra, "Pkg") # Pkg is not a dependency of LinearAlgebra
source
Base.locate_packageFunction
Base.locate_package(pkg::PkgId)::Union{String, Nothing}

The path to the entry-point file for the package corresponding to the identifier pkg, or nothing if not found. See also identify_package.

julia> pkg = Base.identify_package("Pkg")
 Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]
 
 julia> Base.locate_package(pkg)
-"/path/to/julia/stdlib/v1.12/Pkg/src/Pkg.jl"
source
Base.requireFunction
require(into::Module, module::Symbol)

This function is part of the implementation of using / import, if a module is not already defined in Main. It can also be called directly to force reloading a module, regardless of whether it has been loaded before (for example, when interactively developing libraries).

Loads a source file, in the context of the Main module, on every active node, searching standard locations for files. require is considered a top-level operation, so it sets the current include path but does not use it to search for files (see help for include). This function is typically used to load library code, and is implicitly called by using to load packages.

When searching for files, require first looks for package code in the global array LOAD_PATH. require is case-sensitive on all platforms, including those with case-insensitive filesystems like macOS and Windows.

For more details regarding code loading, see the manual sections on modules and parallel computing.

source
Base.compilecacheFunction
Base.compilecache(module::PkgId)

Creates a precompiled cache file for a module and all of its dependencies. This can be used to reduce package load times. Cache files are stored in DEPOT_PATH[1]/compiled. See Module initialization and precompilation for important notes.

source
Base.isprecompiledFunction
Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)

Returns whether a given PkgId within the active project is precompiled.

By default this check observes the same approach that code loading takes with respect to when different versions of dependencies are currently loaded to that which is expected. To ignore loaded modules and answer as if in a fresh julia session specify ignore_loaded=true.

Julia 1.10

This function requires at least Julia 1.10.

source
Base.get_extensionFunction
get_extension(parent::Module, extension::Symbol)

Return the module for extension of parent or return nothing if the extension is not loaded.

source

Internals

Base.GC.gcFunction
GC.gc([full=true])

Perform garbage collection. The argument full determines the kind of collection: a full collection (default) traverses all live objects (i.e. full mark) and should reclaim memory from all unreachable objects. An incremental collection only reclaims memory from young objects which are not reachable.

The GC may decide to perform a full collection even if an incremental collection was requested.

Warning

Excessive use will likely lead to poor performance.

source
Base.GC.enableFunction
GC.enable(on::Bool)

Control whether garbage collection is enabled using a boolean argument (true for enabled, false for disabled). Return previous GC state.

Warning

Disabling garbage collection should be used only with caution, as it can cause memory use to grow without bound.

source
Base.GC.@preserveMacro
GC.@preserve x1 x2 ... xn expr

Mark the objects x1, x2, ... as being in use during the evaluation of the expression expr. This is only required in unsafe code where expr implicitly uses memory or other resources owned by one of the xs.

Implicit use of x covers any indirect use of resources logically owned by x which the compiler cannot see. Some examples:

  • Accessing memory of an object directly via a Ptr
  • Passing a pointer to x to ccall
  • Using resources of x which would be cleaned up in the finalizer.

@preserve should generally not have any performance impact in typical use cases where it briefly extends object lifetime. In implementation, @preserve has effects such as protecting dynamically allocated objects from garbage collection.

Examples

When loading from a pointer with unsafe_load, the underlying object is implicitly used, for example x is implicitly used by unsafe_load(p) in the following:

julia> let
+"/path/to/julia/stdlib/v1.12/Pkg/src/Pkg.jl"
source
Base.requireFunction
require(into::Module, module::Symbol)

This function is part of the implementation of using / import, if a module is not already defined in Main. It can also be called directly to force reloading a module, regardless of whether it has been loaded before (for example, when interactively developing libraries).

Loads a source file, in the context of the Main module, on every active node, searching standard locations for files. require is considered a top-level operation, so it sets the current include path but does not use it to search for files (see help for include). This function is typically used to load library code, and is implicitly called by using to load packages.

When searching for files, require first looks for package code in the global array LOAD_PATH. require is case-sensitive on all platforms, including those with case-insensitive filesystems like macOS and Windows.

For more details regarding code loading, see the manual sections on modules and parallel computing.

source
Base.compilecacheFunction
Base.compilecache(module::PkgId)

Creates a precompiled cache file for a module and all of its dependencies. This can be used to reduce package load times. Cache files are stored in DEPOT_PATH[1]/compiled. See Module initialization and precompilation for important notes.

source
Base.isprecompiledFunction
Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)

Returns whether a given PkgId within the active project is precompiled.

By default this check observes the same approach that code loading takes with respect to when different versions of dependencies are currently loaded to that which is expected. To ignore loaded modules and answer as if in a fresh julia session specify ignore_loaded=true.

Julia 1.10

This function requires at least Julia 1.10.

source
Base.get_extensionFunction
get_extension(parent::Module, extension::Symbol)

Return the module for extension of parent or return nothing if the extension is not loaded.

source

Internals

Base.GC.gcFunction
GC.gc([full=true])

Perform garbage collection. The argument full determines the kind of collection: a full collection (default) traverses all live objects (i.e. full mark) and should reclaim memory from all unreachable objects. An incremental collection only reclaims memory from young objects which are not reachable.

The GC may decide to perform a full collection even if an incremental collection was requested.

Warning

Excessive use will likely lead to poor performance.

source
Base.GC.enableFunction
GC.enable(on::Bool)

Control whether garbage collection is enabled using a boolean argument (true for enabled, false for disabled). Return previous GC state.

Warning

Disabling garbage collection should be used only with caution, as it can cause memory use to grow without bound.

source
Base.GC.@preserveMacro
GC.@preserve x1 x2 ... xn expr

Mark the objects x1, x2, ... as being in use during the evaluation of the expression expr. This is only required in unsafe code where expr implicitly uses memory or other resources owned by one of the xs.

Implicit use of x covers any indirect use of resources logically owned by x which the compiler cannot see. Some examples:

  • Accessing memory of an object directly via a Ptr
  • Passing a pointer to x to ccall
  • Using resources of x which would be cleaned up in the finalizer.

@preserve should generally not have any performance impact in typical use cases where it briefly extends object lifetime. In implementation, @preserve has effects such as protecting dynamically allocated objects from garbage collection.

Examples

When loading from a pointer with unsafe_load, the underlying object is implicitly used, for example x is implicitly used by unsafe_load(p) in the following:

julia> let
            x = Ref{Int}(101)
            p = Base.unsafe_convert(Ptr{Int}, x)
            GC.@preserve x unsafe_load(p)
@@ -1889,7 +1889,7 @@
            # Preferred alternative
            Int(@ccall strlen(x::Cstring)::Csize_t)
        end
-5
source
Base.GC.safepointFunction
GC.safepoint()

Inserts a point in the program where garbage collection may run. This can be useful in rare cases in multi-threaded programs where some threads are allocating memory (and hence may need to run GC) but other threads are doing only simple operations (no allocation, task switches, or I/O). Calling this function periodically in non-allocating threads allows garbage collection to run.

Julia 1.4

This function is available as of Julia 1.4.

source
Base.GC.enable_loggingFunction
GC.enable_logging(on::Bool)

When turned on, print statistics about each GC to stderr.

source
Base.GC.logging_enabledFunction
GC.logging_enabled()

Return whether GC logging has been enabled via GC.enable_logging.

source
Base.Meta.lowerFunction
lower(m, x)

Takes the expression x and returns an equivalent expression in lowered form for executing in module m. See also code_lowered.

source
Base.Meta.@lowerMacro
@lower [m] x

Return lowered form of the expression x in module m. By default m is the module in which the macro is called. See also lower.

source
Base.Meta.parseMethod
parse(str, start; greedy=true, raise=true, depwarn=true, filename="none")

Parse the expression string and return an expression (which could later be passed to eval for execution). start is the code unit index into str of the first character to start parsing at (as with all string indexing, these are not character indices). If greedy is true (default), parse will try to consume as much input as it can; otherwise, it will stop as soon as it has parsed a valid expression. Incomplete but otherwise syntactically valid expressions will return Expr(:incomplete, "(error message)"). If raise is true (default), syntax errors other than incomplete expressions will raise an error. If raise is false, parse will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be suppressed. The filename argument is used to display diagnostics when an error is raised.

julia> Meta.parse("(α, β) = 3, 5", 1) # start of string
+5
source
Base.GC.safepointFunction
GC.safepoint()

Inserts a point in the program where garbage collection may run. This can be useful in rare cases in multi-threaded programs where some threads are allocating memory (and hence may need to run GC) but other threads are doing only simple operations (no allocation, task switches, or I/O). Calling this function periodically in non-allocating threads allows garbage collection to run.

Julia 1.4

This function is available as of Julia 1.4.

source
Base.GC.enable_loggingFunction
GC.enable_logging(on::Bool)

When turned on, print statistics about each GC to stderr.

source
Base.GC.logging_enabledFunction
GC.logging_enabled()

Return whether GC logging has been enabled via GC.enable_logging.

source
Base.Meta.lowerFunction
lower(m, x)

Takes the expression x and returns an equivalent expression in lowered form for executing in module m. See also code_lowered.

source
Base.Meta.@lowerMacro
@lower [m] x

Return lowered form of the expression x in module m. By default m is the module in which the macro is called. See also lower.

source
Base.Meta.parseMethod
parse(str, start; greedy=true, raise=true, depwarn=true, filename="none")

Parse the expression string and return an expression (which could later be passed to eval for execution). start is the code unit index into str of the first character to start parsing at (as with all string indexing, these are not character indices). If greedy is true (default), parse will try to consume as much input as it can; otherwise, it will stop as soon as it has parsed a valid expression. Incomplete but otherwise syntactically valid expressions will return Expr(:incomplete, "(error message)"). If raise is true (default), syntax errors other than incomplete expressions will raise an error. If raise is false, parse will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be suppressed. The filename argument is used to display diagnostics when an error is raised.

julia> Meta.parse("(α, β) = 3, 5", 1) # start of string
 (:((α, β) = (3, 5)), 16)
 
 julia> Meta.parse("(α, β) = 3, 5", 1, greedy=false)
@@ -1902,7 +1902,7 @@
 (:((3, 5)), 16)
 
 julia> Meta.parse("(α, β) = 3, 5", 11, greedy=false)
-(3, 13)
source
Base.Meta.parseMethod
parse(str; raise=true, depwarn=true, filename="none")

Parse the expression string greedily, returning a single expression. An error is thrown if there are additional characters after the first expression. If raise is true (default), syntax errors will raise an error; otherwise, parse will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be suppressed. The filename argument is used to display diagnostics when an error is raised.

julia> Meta.parse("x = 3")
+(3, 13)
source
Base.Meta.parseMethod
parse(str; raise=true, depwarn=true, filename="none")

Parse the expression string greedily, returning a single expression. An error is thrown if there are additional characters after the first expression. If raise is true (default), syntax errors will raise an error; otherwise, parse will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be suppressed. The filename argument is used to display diagnostics when an error is raised.

julia> Meta.parse("x = 3")
 :(x = 3)
 
 julia> Meta.parse("1.0.2")
@@ -1916,7 +1916,7 @@
 :($(Expr(:error, "invalid numeric constant "1.0."")))
 
 julia> Meta.parse("x = ")
-:($(Expr(:incomplete, "incomplete: premature end of input")))
source
Base.Meta.ParseErrorType
ParseError(msg)

The expression passed to the parse function could not be interpreted as a valid Julia expression.

source
Core.QuoteNodeType
QuoteNode

A quoted piece of code, that does not support interpolation. See the manual section about QuoteNodes for details.

source
Base.macroexpandFunction
macroexpand(m::Module, x; recursive=true)

Take the expression x and return an equivalent expression with all macros removed (expanded) for executing in module m. The recursive keyword controls whether deeper levels of nested macros are also expanded. This is demonstrated in the example below:

julia> module M
+:($(Expr(:incomplete, "incomplete: premature end of input")))
source
Base.Meta.ParseErrorType
ParseError(msg)

The expression passed to the parse function could not be interpreted as a valid Julia expression.

source
Core.QuoteNodeType
QuoteNode

A quoted piece of code, that does not support interpolation. See the manual section about QuoteNodes for details.

source
Base.macroexpandFunction
macroexpand(m::Module, x; recursive=true)

Take the expression x and return an equivalent expression with all macros removed (expanded) for executing in module m. The recursive keyword controls whether deeper levels of nested macros are also expanded. This is demonstrated in the example below:

julia> module M
            macro m1()
                42
            end
@@ -1930,7 +1930,7 @@
 42
 
 julia> macroexpand(M, :(@m2()), recursive=false)
-:(#= REPL[16]:6 =# M.@m1)
source
Base.@macroexpandMacro
@macroexpand [mod,] ex

Return equivalent expression with all macros removed (expanded). If two arguments are provided, the first is the module to evaluate in.

There are differences between @macroexpand and macroexpand.

  • While macroexpand takes a keyword argument recursive, @macroexpand is always recursive. For a non recursive macro version, see @macroexpand1.

  • While macroexpand has an explicit module argument, @macroexpand always expands with respect to the module in which it is called.

This is best seen in the following example:

julia> module M
+:(#= REPL[16]:6 =# M.@m1)
source
Base.@macroexpandMacro
@macroexpand [mod,] ex

Return equivalent expression with all macros removed (expanded). If two arguments are provided, the first is the module to evaluate in.

There are differences between @macroexpand and macroexpand.

  • While macroexpand takes a keyword argument recursive, @macroexpand is always recursive. For a non recursive macro version, see @macroexpand1.

  • While macroexpand has an explicit module argument, @macroexpand always expands with respect to the module in which it is called.

This is best seen in the following example:

julia> module M
            macro m()
                1
            end
@@ -1949,12 +1949,12 @@
 @m (macro with 1 method)
 
 julia> M.f()
-(1, 1, 2)

With @macroexpand the expression expands where @macroexpand appears in the code (module M in the example). With macroexpand the expression expands in the module given as the first argument.

Julia 1.11

The two-argument form requires at least Julia 1.11.

source
Base.@macroexpand1Macro
@macroexpand1 [mod,] ex

Non recursive version of @macroexpand.

source
Base.code_loweredFunction
code_lowered(f, types; generated=true, debuginfo=:default)

Return an array of the lowered forms (IR) for the methods matching the given generic function and type signature.

If generated is false, the returned CodeInfo instances will correspond to fallback implementations. An error is thrown if no fallback implementation exists. If generated is true, these CodeInfo instances will correspond to the method bodies yielded by expanding the generators.

The keyword debuginfo controls the amount of code metadata present in the output.

Note that an error will be thrown if types are not leaf types when generated is true and any of the corresponding methods are an @generated method.

source
Base.code_typedFunction
code_typed(f, types; kw...)

Returns an array of type-inferred lowered form (IR) for the methods matching the given generic function and type signature.

Keyword Arguments

  • optimize::Bool = true: optional, controls whether additional optimizations, such as inlining, are also applied.
  • debuginfo::Symbol = :default: optional, controls the amount of code metadata present in the output, possible options are :source or :none.

Internal Keyword Arguments

This section should be considered internal, and is only for who understands Julia compiler internals.

  • world::UInt = Base.get_world_counter(): optional, controls the world age to use when looking up methods, use current world age if not specified.
  • interp::Core.Compiler.AbstractInterpreter = Core.Compiler.NativeInterpreter(world): optional, controls the abstract interpreter to use, use the native interpreter if not specified.

Examples

One can put the argument types in a tuple to get the corresponding code_typed.

julia> code_typed(+, (Float64, Float64))
+(1, 1, 2)

With @macroexpand the expression expands where @macroexpand appears in the code (module M in the example). With macroexpand the expression expands in the module given as the first argument.

Julia 1.11

The two-argument form requires at least Julia 1.11.

source
Base.@macroexpand1Macro
@macroexpand1 [mod,] ex

Non recursive version of @macroexpand.

source
Base.code_loweredFunction
code_lowered(f, types; generated=true, debuginfo=:default)

Return an array of the lowered forms (IR) for the methods matching the given generic function and type signature.

If generated is false, the returned CodeInfo instances will correspond to fallback implementations. An error is thrown if no fallback implementation exists. If generated is true, these CodeInfo instances will correspond to the method bodies yielded by expanding the generators.

The keyword debuginfo controls the amount of code metadata present in the output.

Note that an error will be thrown if types are not leaf types when generated is true and any of the corresponding methods are an @generated method.

source
Base.code_typedFunction
code_typed(f, types; kw...)

Returns an array of type-inferred lowered form (IR) for the methods matching the given generic function and type signature.

Keyword Arguments

  • optimize::Bool = true: optional, controls whether additional optimizations, such as inlining, are also applied.
  • debuginfo::Symbol = :default: optional, controls the amount of code metadata present in the output, possible options are :source or :none.

Internal Keyword Arguments

This section should be considered internal, and is only for who understands Julia compiler internals.

  • world::UInt = Base.get_world_counter(): optional, controls the world age to use when looking up methods, use current world age if not specified.
  • interp::Core.Compiler.AbstractInterpreter = Core.Compiler.NativeInterpreter(world): optional, controls the abstract interpreter to use, use the native interpreter if not specified.

Examples

One can put the argument types in a tuple to get the corresponding code_typed.

julia> code_typed(+, (Float64, Float64))
 1-element Vector{Any}:
  CodeInfo(
 1 ─ %1 = Base.add_float(x, y)::Float64
 └──      return %1
-) => Float64
source
Base.precompileFunction
precompile(f, argtypes::Tuple{Vararg{Any}})

Compile the given function f for the argument tuple (of types) argtypes, but do not execute it.

source
precompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)

Precompile a specific method for the given argument types. This may be used to precompile a different method than the one that would ordinarily be chosen by dispatch, thus mimicking invoke.

source
Base.jit_total_bytesFunction
Base.jit_total_bytes()

Return the total amount (in bytes) allocated by the just-in-time compiler for e.g. native code and data.

source

Meta

Base.Meta.quotFunction
Meta.quot(ex)::Expr

Quote expression ex to produce an expression with head quote. This can for instance be used to represent objects of type Expr in the AST. See also the manual section about QuoteNode.

Examples

julia> eval(Meta.quot(:x))
+) => Float64
source
Base.precompileFunction
precompile(f, argtypes::Tuple{Vararg{Any}})

Compile the given function f for the argument tuple (of types) argtypes, but do not execute it.

source
precompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)

Precompile a specific method for the given argument types. This may be used to precompile a different method than the one that would ordinarily be chosen by dispatch, thus mimicking invoke.

source
Base.jit_total_bytesFunction
Base.jit_total_bytes()

Return the total amount (in bytes) allocated by the just-in-time compiler for e.g. native code and data.

source

Meta

Base.Meta.quotFunction
Meta.quot(ex)::Expr

Quote expression ex to produce an expression with head quote. This can for instance be used to represent objects of type Expr in the AST. See also the manual section about QuoteNode.

Examples

julia> eval(Meta.quot(:x))
 :x
 
 julia> dump(Meta.quot(:x))
@@ -1964,7 +1964,7 @@
     1: Symbol x
 
 julia> eval(Meta.quot(:(1+2)))
-:(1 + 2)
source
Base.isexprFunction
Meta.isexpr(ex, head[, n])::Bool

Return true if ex is an Expr with the given type head and optionally that the argument list is of length n. head may be a Symbol or collection of Symbols. For example, to check that a macro was passed a function call expression, you might use isexpr(ex, :call).

Examples

julia> ex = :(f(x))
+:(1 + 2)
source
Base.isexprFunction
Meta.isexpr(ex, head[, n])::Bool

Return true if ex is an Expr with the given type head and optionally that the argument list is of length n. head may be a Symbol or collection of Symbols. For example, to check that a macro was passed a function call expression, you might use isexpr(ex, :call).

Examples

julia> ex = :(f(x))
 :(f(x))
 
 julia> Meta.isexpr(ex, :block)
@@ -1980,9 +1980,9 @@
 false
 
 julia> Meta.isexpr(ex, :call, 2)
-true
source
Base.isidentifierFunction
 isidentifier(s) -> Bool

Return whether the symbol or string s contains characters that are parsed as a valid ordinary identifier (not a binary/unary operator) in Julia code; see also Base.isoperator.

Internally Julia allows any sequence of characters in a Symbol (except \0s), and macros automatically use variable names containing # in order to avoid naming collision with the surrounding code. In order for the parser to recognize a variable, it uses a limited set of characters (greatly extended by Unicode). isidentifier() makes it possible to query the parser directly whether a symbol contains valid characters.

Examples

julia> Meta.isidentifier(:x), Meta.isidentifier("1x")
-(true, false)
source
Base.isoperatorFunction
isoperator(s::Symbol)

Return true if the symbol can be used as an operator, false otherwise.

Examples

julia> Meta.isoperator(:+), Meta.isoperator(:f)
-(true, false)
source
Base.isunaryoperatorFunction
isunaryoperator(s::Symbol)

Return true if the symbol can be used as a unary (prefix) operator, false otherwise.

Examples

julia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)
-(true, true, false)
source
Base.isbinaryoperatorFunction
isbinaryoperator(s::Symbol)

Return true if the symbol can be used as a binary (infix) operator, false otherwise.

Examples

julia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)
-(true, false, false)
source
Base.Meta.show_sexprFunction
Meta.show_sexpr([io::IO,], ex)

Show expression ex as a lisp style S-expression.

Examples

julia> Meta.show_sexpr(:(f(x, g(y,z))))
-(:call, :f, :x, (:call, :g, :y, :z))
source
+true
source
Base.isidentifierFunction
 isidentifier(s) -> Bool

Return whether the symbol or string s contains characters that are parsed as a valid ordinary identifier (not a binary/unary operator) in Julia code; see also Base.isoperator.

Internally Julia allows any sequence of characters in a Symbol (except \0s), and macros automatically use variable names containing # in order to avoid naming collision with the surrounding code. In order for the parser to recognize a variable, it uses a limited set of characters (greatly extended by Unicode). isidentifier() makes it possible to query the parser directly whether a symbol contains valid characters.

Examples

julia> Meta.isidentifier(:x), Meta.isidentifier("1x")
+(true, false)
source
Base.isoperatorFunction
isoperator(s::Symbol)

Return true if the symbol can be used as an operator, false otherwise.

Examples

julia> Meta.isoperator(:+), Meta.isoperator(:f)
+(true, false)
source
Base.isunaryoperatorFunction
isunaryoperator(s::Symbol)

Return true if the symbol can be used as a unary (prefix) operator, false otherwise.

Examples

julia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)
+(true, true, false)
source
Base.isbinaryoperatorFunction
isbinaryoperator(s::Symbol)

Return true if the symbol can be used as a binary (infix) operator, false otherwise.

Examples

julia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)
+(true, false, false)
source
Base.Meta.show_sexprFunction
Meta.show_sexpr([io::IO,], ex)

Show expression ex as a lisp style S-expression.

Examples

julia> Meta.show_sexpr(:(f(x, g(y,z))))
+(:call, :f, :x, (:call, :g, :y, :z))
source
diff --git a/en/v1.12-dev/base/c/index.html b/en/v1.12-dev/base/c/index.html index 3c2577e5ac35..cc4a0f5c5b7a 100644 --- a/en/v1.12-dev/base/c/index.html +++ b/en/v1.12-dev/base/c/index.html @@ -9,32 +9,32 @@ # char *g_uri_escape_string(const char *unescaped, const char *reserved_chars_allowed, gboolean allow_utf8); const glib = "libglib-2.0" -@ccall glib.g_uri_escape_string(my_uri::Cstring, ":/"::Cstring, true::Cint)::Cstring

The string literal could also be used directly before the function name, if desired "libglib-2.0".g_uri_escape_string(...

source
ccallKeyword
ccall((function_name, library), returntype, (argtype1, ...), argvalue1, ...)
+@ccall glib.g_uri_escape_string(my_uri::Cstring, ":/"::Cstring, true::Cint)::Cstring

The string literal could also be used directly before the function name, if desired "libglib-2.0".g_uri_escape_string(...

source
ccallKeyword
ccall((function_name, library), returntype, (argtype1, ...), argvalue1, ...)
 ccall(function_name, returntype, (argtype1, ...), argvalue1, ...)
-ccall(function_pointer, returntype, (argtype1, ...), argvalue1, ...)

Call a function in a C-exported shared library, specified by the tuple (function_name, library), where each component is either a string or symbol. Instead of specifying a library, one can also use a function_name symbol or string, which is resolved in the current process. Alternatively, ccall may also be used to call a function pointer function_pointer, such as one returned by dlsym.

Note that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression.

Each argvalue to the ccall will be converted to the corresponding argtype, by automatic insertion of calls to unsafe_convert(argtype, cconvert(argtype, argvalue)). (See also the documentation for unsafe_convert and cconvert for further details.) In most cases, this simply results in a call to convert(argtype, argvalue).

source
Core.Intrinsics.cglobalFunction
cglobal((symbol, library) [, type=Cvoid])

Obtain a pointer to a global variable in a C-exported shared library, specified exactly as in ccall. Returns a Ptr{Type}, defaulting to Ptr{Cvoid} if no Type argument is supplied. The values can be read or written by unsafe_load or unsafe_store!, respectively.

source
Base.@cfunctionMacro
@cfunction(callable, ReturnType, (ArgumentTypes...,)) -> Ptr{Cvoid}
+ccall(function_pointer, returntype, (argtype1, ...), argvalue1, ...)

Call a function in a C-exported shared library, specified by the tuple (function_name, library), where each component is either a string or symbol. Instead of specifying a library, one can also use a function_name symbol or string, which is resolved in the current process. Alternatively, ccall may also be used to call a function pointer function_pointer, such as one returned by dlsym.

Note that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression.

Each argvalue to the ccall will be converted to the corresponding argtype, by automatic insertion of calls to unsafe_convert(argtype, cconvert(argtype, argvalue)). (See also the documentation for unsafe_convert and cconvert for further details.) In most cases, this simply results in a call to convert(argtype, argvalue).

source
Core.Intrinsics.cglobalFunction
cglobal((symbol, library) [, type=Cvoid])

Obtain a pointer to a global variable in a C-exported shared library, specified exactly as in ccall. Returns a Ptr{Type}, defaulting to Ptr{Cvoid} if no Type argument is supplied. The values can be read or written by unsafe_load or unsafe_store!, respectively.

source
Base.@cfunctionMacro
@cfunction(callable, ReturnType, (ArgumentTypes...,)) -> Ptr{Cvoid}
 @cfunction($callable, ReturnType, (ArgumentTypes...,)) -> CFunction

Generate a C-callable function pointer from the Julia function callable for the given type signature. To pass the return value to a ccall, use the argument type Ptr{Cvoid} in the signature.

Note that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression (although it can include a splat expression). And that these arguments will be evaluated in global scope during compile-time (not deferred until runtime). Adding a '$' in front of the function argument changes this to instead create a runtime closure over the local variable callable (this is not supported on all architectures).

See manual section on ccall and cfunction usage.

Examples

julia> function foo(x::Int, y::Int)
            return x + y
        end
 
 julia> @cfunction(foo, Int, (Int, Int))
-Ptr{Cvoid} @0x000000001b82fcd0
source
Base.CFunctionType
CFunction struct

Garbage-collection handle for the return value from @cfunction when the first argument is annotated with '$'. Like all cfunction handles, it should be passed to ccall as a Ptr{Cvoid}, and will be converted automatically at the call site to the appropriate type.

See @cfunction.

source
Base.unsafe_convertFunction
unsafe_convert(T, x)

Convert x to a C argument of type T where the input x must be the return value of cconvert(T, ...).

In cases where convert would need to take a Julia object and turn it into a Ptr, this function should be used to define and perform that conversion.

Be careful to ensure that a Julia reference to x exists as long as the result of this function will be used. Accordingly, the argument x to this function should never be an expression, only a variable name or field reference. For example, x=a.b.c is acceptable, but x=[a,b,c] is not.

The unsafe prefix on this function indicates that using the result of this function after the x argument to this function is no longer accessible to the program may cause undefined behavior, including program corruption or segfaults, at any later time.

See also cconvert

source
Base.cconvertFunction
cconvert(T,x)

Convert x to a value to be passed to C code as type T, typically by calling convert(T, x).

In cases where x cannot be safely converted to T, unlike convert, cconvert may return an object of a type different from T, which however is suitable for unsafe_convert to handle. The result of this function should be kept valid (for the GC) until the result of unsafe_convert is not needed anymore. This can be used to allocate memory that will be accessed by the ccall. If multiple objects need to be allocated, a tuple of the objects can be used as return value.

Neither convert nor cconvert should take a Julia object and turn it into a Ptr.

source
Base.unsafe_loadFunction
unsafe_load(p::Ptr{T}, i::Integer=1)
+Ptr{Cvoid} @0x000000001b82fcd0
source
Base.CFunctionType
CFunction struct

Garbage-collection handle for the return value from @cfunction when the first argument is annotated with '$'. Like all cfunction handles, it should be passed to ccall as a Ptr{Cvoid}, and will be converted automatically at the call site to the appropriate type.

See @cfunction.

source
Base.unsafe_convertFunction
unsafe_convert(T, x)

Convert x to a C argument of type T where the input x must be the return value of cconvert(T, ...).

In cases where convert would need to take a Julia object and turn it into a Ptr, this function should be used to define and perform that conversion.

Be careful to ensure that a Julia reference to x exists as long as the result of this function will be used. Accordingly, the argument x to this function should never be an expression, only a variable name or field reference. For example, x=a.b.c is acceptable, but x=[a,b,c] is not.

The unsafe prefix on this function indicates that using the result of this function after the x argument to this function is no longer accessible to the program may cause undefined behavior, including program corruption or segfaults, at any later time.

See also cconvert

source
Base.cconvertFunction
cconvert(T,x)

Convert x to a value to be passed to C code as type T, typically by calling convert(T, x).

In cases where x cannot be safely converted to T, unlike convert, cconvert may return an object of a type different from T, which however is suitable for unsafe_convert to handle. The result of this function should be kept valid (for the GC) until the result of unsafe_convert is not needed anymore. This can be used to allocate memory that will be accessed by the ccall. If multiple objects need to be allocated, a tuple of the objects can be used as return value.

Neither convert nor cconvert should take a Julia object and turn it into a Ptr.

source
Base.unsafe_loadFunction
unsafe_load(p::Ptr{T}, i::Integer=1)
 unsafe_load(p::Ptr{T}, order::Symbol)
-unsafe_load(p::Ptr{T}, i::Integer, order::Symbol)

Load a value of type T from the address of the ith element (1-indexed) starting at p. This is equivalent to the C expression p[i-1]. Optionally, an atomic memory ordering can be provided.

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program or return garbage answers. Unlike C, dereferencing memory region allocated as different type may be valid provided that the types are compatible.

Julia 1.10

The order argument is available as of Julia 1.10.

See also: atomic

source
Base.unsafe_store!Function
unsafe_store!(p::Ptr{T}, x, i::Integer=1)
+unsafe_load(p::Ptr{T}, i::Integer, order::Symbol)

Load a value of type T from the address of the ith element (1-indexed) starting at p. This is equivalent to the C expression p[i-1]. Optionally, an atomic memory ordering can be provided.

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program or return garbage answers. Unlike C, dereferencing memory region allocated as different type may be valid provided that the types are compatible.

Julia 1.10

The order argument is available as of Julia 1.10.

See also: atomic

source
Base.unsafe_store!Function
unsafe_store!(p::Ptr{T}, x, i::Integer=1)
 unsafe_store!(p::Ptr{T}, x, order::Symbol)
-unsafe_store!(p::Ptr{T}, x, i::Integer, order::Symbol)

Store a value of type T to the address of the ith element (1-indexed) starting at p. This is equivalent to the C expression p[i-1] = x. Optionally, an atomic memory ordering can be provided.

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program. Unlike C, storing memory region allocated as different type may be valid provided that that the types are compatible.

Julia 1.10

The order argument is available as of Julia 1.10.

See also: atomic

source
Base.unsafe_modify!Function
unsafe_modify!(p::Ptr{T}, op, x, [order::Symbol]) -> Pair

These atomically perform the operations to get and set a memory address after applying the function op. If supported by the hardware (for example, atomic increment), this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:

y = unsafe_load(p)
+unsafe_store!(p::Ptr{T}, x, i::Integer, order::Symbol)

Store a value of type T to the address of the ith element (1-indexed) starting at p. This is equivalent to the C expression p[i-1] = x. Optionally, an atomic memory ordering can be provided.

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program. Unlike C, storing memory region allocated as different type may be valid provided that that the types are compatible.

Julia 1.10

The order argument is available as of Julia 1.10.

See also: atomic

source
Base.unsafe_modify!Function
unsafe_modify!(p::Ptr{T}, op, x, [order::Symbol]) -> Pair

These atomically perform the operations to get and set a memory address after applying the function op. If supported by the hardware (for example, atomic increment), this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:

y = unsafe_load(p)
 z = op(y, x)
 unsafe_store!(p, z)
-return y => z

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.

Julia 1.10

This function requires at least Julia 1.10.

See also: modifyproperty!, atomic

source
Base.unsafe_replace!Function
unsafe_replace!(p::Ptr{T}, expected, desired,
+return y => z

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.

Julia 1.10

This function requires at least Julia 1.10.

See also: modifyproperty!, atomic

source
Base.unsafe_replace!Function
unsafe_replace!(p::Ptr{T}, expected, desired,
                [success_order::Symbol[, fail_order::Symbol=success_order]]) -> (; old, success::Bool)

These atomically perform the operations to get and conditionally set a memory address to a given value. If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:

y = unsafe_load(p, fail_order)
 ok = y === expected
 if ok
     unsafe_store!(p, desired, success_order)
 end
-return (; old = y, success = ok)

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.

Julia 1.10

This function requires at least Julia 1.10.

See also: replaceproperty!, atomic

source
Base.unsafe_swap!Function
unsafe_swap!(p::Ptr{T}, x, [order::Symbol])

These atomically perform the operations to simultaneously get and set a memory address. If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:

y = unsafe_load(p)
+return (; old = y, success = ok)

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.

Julia 1.10

This function requires at least Julia 1.10.

See also: replaceproperty!, atomic

source
Base.unsafe_swap!Function
unsafe_swap!(p::Ptr{T}, x, [order::Symbol])

These atomically perform the operations to simultaneously get and set a memory address. If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:

y = unsafe_load(p)
 unsafe_store!(p, x)
-return y

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.

Julia 1.10

This function requires at least Julia 1.10.

See also: swapproperty!, atomic

source
Base.unsafe_copyto!Method
unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)

Copy N elements from a source pointer to a destination, with no checking. The size of an element is determined by the type of the pointers.

The unsafe prefix on this function indicates that no validation is performed on the pointers dest and src to ensure that they are valid. Incorrect usage may corrupt or segfault your program, in the same manner as C.

source
Base.unsafe_copyto!Method
unsafe_copyto!(dest::Array, do, src::Array, so, N)

Copy N elements from a source array to a destination, starting at the linear index so in the source and do in the destination (1-indexed).

The unsafe prefix on this function indicates that no validation is performed to ensure that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in the same manner as C.

source
Base.copyto!Function
copyto!(B::AbstractMatrix, ir_dest::AbstractUnitRange, jr_dest::AbstractUnitRange,
+return y

The unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.

Julia 1.10

This function requires at least Julia 1.10.

See also: swapproperty!, atomic

source
Base.unsafe_copyto!Method
unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)

Copy N elements from a source pointer to a destination, with no checking. The size of an element is determined by the type of the pointers.

The unsafe prefix on this function indicates that no validation is performed on the pointers dest and src to ensure that they are valid. Incorrect usage may corrupt or segfault your program, in the same manner as C.

source
Base.unsafe_copyto!Method
unsafe_copyto!(dest::Array, do, src::Array, so, N)

Copy N elements from a source array to a destination, starting at the linear index so in the source and do in the destination (1-indexed).

The unsafe prefix on this function indicates that no validation is performed to ensure that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in the same manner as C.

source
Base.copyto!Function
copyto!(B::AbstractMatrix, ir_dest::AbstractUnitRange, jr_dest::AbstractUnitRange,
         tM::AbstractChar,
-        M::AbstractVecOrMat, ir_src::AbstractUnitRange, jr_src::AbstractUnitRange) -> B

Efficiently copy elements of matrix M to B conditioned on the character parameter tM as follows:

tMDestinationSource
'N'B[ir_dest, jr_dest]M[ir_src, jr_src]
'T'B[ir_dest, jr_dest]transpose(M)[ir_src, jr_src]
'C'B[ir_dest, jr_dest]adjoint(M)[ir_src, jr_src]

The elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(ir_src) and length(jr_dest) == length(jr_src).

See also copy_transpose! and copy_adjoint!.

copyto!(dest::AbstractMatrix, src::UniformScaling)

Copies a UniformScaling onto a matrix.

Julia 1.1

In Julia 1.0 this method only supported a square destination matrix. Julia 1.1. added support for a rectangular matrix.

copyto!(dest, do, src, so, N)

Copy N elements from collection src starting at the linear index so, to array dest starting at the index do. Return dest.

source
copyto!(dest::AbstractArray, src) -> dest

Copy all elements from collection src to array dest, whose length must be greater than or equal to the length n of src. The first n elements of dest are overwritten, the other elements are left untouched.

See also copy!, copy.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> x = [1., 0., 3., 0., 5.];
+        M::AbstractVecOrMat, ir_src::AbstractUnitRange, jr_src::AbstractUnitRange) -> B

Efficiently copy elements of matrix M to B conditioned on the character parameter tM as follows:

tMDestinationSource
'N'B[ir_dest, jr_dest]M[ir_src, jr_src]
'T'B[ir_dest, jr_dest]transpose(M)[ir_src, jr_src]
'C'B[ir_dest, jr_dest]adjoint(M)[ir_src, jr_src]

The elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(ir_src) and length(jr_dest) == length(jr_src).

See also copy_transpose! and copy_adjoint!.

copyto!(dest::AbstractMatrix, src::UniformScaling)

Copies a UniformScaling onto a matrix.

Julia 1.1

In Julia 1.0 this method only supported a square destination matrix. Julia 1.1. added support for a rectangular matrix.

copyto!(dest, do, src, so, N)

Copy N elements from collection src starting at the linear index so, to array dest starting at the index do. Return dest.

source
copyto!(dest::AbstractArray, src) -> dest

Copy all elements from collection src to array dest, whose length must be greater than or equal to the length n of src. The first n elements of dest are overwritten, the other elements are left untouched.

See also copy!, copy.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> x = [1., 0., 3., 0., 5.];
 
 julia> y = zeros(7);
 
@@ -48,7 +48,7 @@
  0.0
  5.0
  0.0
- 0.0
source
copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest

Copy the block of src in the range of Rsrc to the block of dest in the range of Rdest. The sizes of the two regions must match.

Examples

julia> A = zeros(5, 5);
+ 0.0
source
copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest

Copy the block of src in the range of Rsrc to the block of dest in the range of Rdest. The sizes of the two regions must match.

Examples

julia> A = zeros(5, 5);
 
 julia> B = [1 2; 3 4];
 
@@ -62,12 +62,12 @@
  0.0  1.0  2.0  0.0  0.0
  0.0  3.0  4.0  0.0  0.0
  0.0  0.0  0.0  0.0  0.0
- 0.0  0.0  0.0  0.0  0.0
source
Base.pointerFunction
pointer(array [, index])

Get the native address of an array or string, optionally at a given location index.

This function is "unsafe". Be careful to ensure that a Julia reference to array exists as long as this pointer will be used. The GC.@preserve macro should be used to protect the array argument from garbage collection within a given block of code.

Calling Ref(array[, index]) is generally preferable to this function as it guarantees validity.

source
Base.unsafe_wrapMethod
unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)

Wrap a Julia Array object around the data at the address given by pointer, without making a copy. The pointer element type T determines the array element type. dims is either an integer (for a 1d array) or a tuple of the array dimensions. own optionally specifies whether Julia should take ownership of the memory, calling free on the pointer when the array is no longer referenced.

This function is labeled "unsafe" because it will crash if pointer is not a valid memory address to data of the requested length. Unlike unsafe_load and unsafe_store!, the programmer is responsible also for ensuring that the underlying data is not accessed through two arrays of different element type, similar to the strict aliasing rule in C.

source
Base.pointer_from_objrefFunction
pointer_from_objref(x)

Get the memory address of a Julia object as a Ptr. The existence of the resulting Ptr will not protect the object from garbage collection, so you must ensure that the object remains referenced for the whole time that the Ptr will be used.

This function may not be called on immutable objects, since they do not have stable memory addresses.

See also unsafe_pointer_to_objref.

source
Base.unsafe_pointer_to_objrefFunction
unsafe_pointer_to_objref(p::Ptr)

Convert a Ptr to an object reference. Assumes the pointer refers to a valid heap-allocated Julia object. If this is not the case, undefined behavior results, hence this function is considered "unsafe" and should be used with care.

See also pointer_from_objref.

source
Base.disable_sigintFunction
disable_sigint(f::Function)

Disable Ctrl-C handler during execution of a function on the current task, for calling external code that may call julia code that is not interrupt safe. Intended to be called using do block syntax as follows:

disable_sigint() do
+ 0.0  0.0  0.0  0.0  0.0
source
Base.pointerFunction
pointer(array [, index])

Get the native address of an array or string, optionally at a given location index.

This function is "unsafe". Be careful to ensure that a Julia reference to array exists as long as this pointer will be used. The GC.@preserve macro should be used to protect the array argument from garbage collection within a given block of code.

Calling Ref(array[, index]) is generally preferable to this function as it guarantees validity.

source
Base.unsafe_wrapMethod
unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)

Wrap a Julia Array object around the data at the address given by pointer, without making a copy. The pointer element type T determines the array element type. dims is either an integer (for a 1d array) or a tuple of the array dimensions. own optionally specifies whether Julia should take ownership of the memory, calling free on the pointer when the array is no longer referenced.

This function is labeled "unsafe" because it will crash if pointer is not a valid memory address to data of the requested length. Unlike unsafe_load and unsafe_store!, the programmer is responsible also for ensuring that the underlying data is not accessed through two arrays of different element type, similar to the strict aliasing rule in C.

source
Base.pointer_from_objrefFunction
pointer_from_objref(x)

Get the memory address of a Julia object as a Ptr. The existence of the resulting Ptr will not protect the object from garbage collection, so you must ensure that the object remains referenced for the whole time that the Ptr will be used.

This function may not be called on immutable objects, since they do not have stable memory addresses.

See also unsafe_pointer_to_objref.

source
Base.unsafe_pointer_to_objrefFunction
unsafe_pointer_to_objref(p::Ptr)

Convert a Ptr to an object reference. Assumes the pointer refers to a valid heap-allocated Julia object. If this is not the case, undefined behavior results, hence this function is considered "unsafe" and should be used with care.

See also pointer_from_objref.

source
Base.disable_sigintFunction
disable_sigint(f::Function)

Disable Ctrl-C handler during execution of a function on the current task, for calling external code that may call julia code that is not interrupt safe. Intended to be called using do block syntax as follows:

disable_sigint() do
     # interrupt-unsafe code
     ...
-end

This is not needed on worker threads (Threads.threadid() != 1) since the InterruptException will only be delivered to the master thread. External functions that do not call julia code or julia runtime automatically disable sigint during their execution.

source
Base.reenable_sigintFunction
reenable_sigint(f::Function)

Re-enable Ctrl-C handler during execution of a function. Temporarily reverses the effect of disable_sigint.

source
Base.exit_on_sigintFunction
exit_on_sigint(on::Bool)

Set exit_on_sigint flag of the julia runtime. If false, Ctrl-C (SIGINT) is capturable as InterruptException in try block. This is the default behavior in REPL, any code run via -e and -E and in Julia script run with -i option.

If true, InterruptException is not thrown by Ctrl-C. Running code upon such event requires atexit. This is the default behavior in Julia script run without -i option.

Julia 1.5

Function exit_on_sigint requires at least Julia 1.5.

source
Base.systemerrorFunction
systemerror(sysfunc[, errno::Cint=Libc.errno()])
-systemerror(sysfunc, iftrue::Bool)

Raises a SystemError for errno with the descriptive string sysfunc if iftrue is true

source
Base.windowserrorFunction
windowserror(sysfunc[, code::UInt32=Libc.GetLastError()])
-windowserror(sysfunc, iftrue::Bool)

Like systemerror, but for Windows API functions that use GetLastError to return an error code instead of setting errno.

source
Core.PtrType
Ptr{T}

A memory address referring to data of type T. However, there is no guarantee that the memory is actually valid, or that it actually represents data of the specified type.

source
Core.RefType
Ref{T}

An object that safely references data of type T. This type is guaranteed to point to valid, Julia-allocated memory of the correct type. The underlying data is protected from freeing by the garbage collector as long as the Ref itself is referenced.

In Julia, Ref objects are dereferenced (loaded or stored) with [].

Creation of a Ref to a value x of type T is usually written Ref(x). Additionally, for creating interior pointers to containers (such as Array or Ptr), it can be written Ref(a, i) for creating a reference to the i-th element of a.

Ref{T}() creates a reference to a value of type T without initialization. For a bitstype T, the value will be whatever currently resides in the memory allocated. For a non-bitstype T, the reference will be undefined and attempting to dereference it will result in an error, "UndefRefError: access to undefined reference".

To check if a Ref is an undefined reference, use isassigned(ref::RefValue). For example, isassigned(Ref{T}()) is false if T is not a bitstype. If T is a bitstype, isassigned(Ref{T}()) will always be true.

When passed as a ccall argument (either as a Ptr or Ref type), a Ref object will be converted to a native pointer to the data it references. For most T, or when converted to a Ptr{Cvoid}, this is a pointer to the object data. When T is an isbits type, this value may be safely mutated, otherwise mutation is strictly undefined behavior.

As a special case, setting T = Any will instead cause the creation of a pointer to the reference itself when converted to a Ptr{Any} (a jl_value_t const* const* if T is immutable, else a jl_value_t *const *). When converted to a Ptr{Cvoid}, it will still return a pointer to the data region as for any other T.

A C_NULL instance of Ptr can be passed to a ccall Ref argument to initialize it.

Use in broadcasting

Ref is sometimes used in broadcasting in order to treat the referenced values as a scalar.

Examples

julia> r = Ref(5) # Create a Ref with an initial value
+end

This is not needed on worker threads (Threads.threadid() != 1) since the InterruptException will only be delivered to the master thread. External functions that do not call julia code or julia runtime automatically disable sigint during their execution.

source
Base.reenable_sigintFunction
reenable_sigint(f::Function)

Re-enable Ctrl-C handler during execution of a function. Temporarily reverses the effect of disable_sigint.

source
Base.exit_on_sigintFunction
exit_on_sigint(on::Bool)

Set exit_on_sigint flag of the julia runtime. If false, Ctrl-C (SIGINT) is capturable as InterruptException in try block. This is the default behavior in REPL, any code run via -e and -E and in Julia script run with -i option.

If true, InterruptException is not thrown by Ctrl-C. Running code upon such event requires atexit. This is the default behavior in Julia script run without -i option.

Julia 1.5

Function exit_on_sigint requires at least Julia 1.5.

source
Base.systemerrorFunction
systemerror(sysfunc[, errno::Cint=Libc.errno()])
+systemerror(sysfunc, iftrue::Bool)

Raises a SystemError for errno with the descriptive string sysfunc if iftrue is true

source
Base.windowserrorFunction
windowserror(sysfunc[, code::UInt32=Libc.GetLastError()])
+windowserror(sysfunc, iftrue::Bool)

Like systemerror, but for Windows API functions that use GetLastError to return an error code instead of setting errno.

source
Core.PtrType
Ptr{T}

A memory address referring to data of type T. However, there is no guarantee that the memory is actually valid, or that it actually represents data of the specified type.

source
Core.RefType
Ref{T}

An object that safely references data of type T. This type is guaranteed to point to valid, Julia-allocated memory of the correct type. The underlying data is protected from freeing by the garbage collector as long as the Ref itself is referenced.

In Julia, Ref objects are dereferenced (loaded or stored) with [].

Creation of a Ref to a value x of type T is usually written Ref(x). Additionally, for creating interior pointers to containers (such as Array or Ptr), it can be written Ref(a, i) for creating a reference to the i-th element of a.

Ref{T}() creates a reference to a value of type T without initialization. For a bitstype T, the value will be whatever currently resides in the memory allocated. For a non-bitstype T, the reference will be undefined and attempting to dereference it will result in an error, "UndefRefError: access to undefined reference".

To check if a Ref is an undefined reference, use isassigned(ref::RefValue). For example, isassigned(Ref{T}()) is false if T is not a bitstype. If T is a bitstype, isassigned(Ref{T}()) will always be true.

When passed as a ccall argument (either as a Ptr or Ref type), a Ref object will be converted to a native pointer to the data it references. For most T, or when converted to a Ptr{Cvoid}, this is a pointer to the object data. When T is an isbits type, this value may be safely mutated, otherwise mutation is strictly undefined behavior.

As a special case, setting T = Any will instead cause the creation of a pointer to the reference itself when converted to a Ptr{Any} (a jl_value_t const* const* if T is immutable, else a jl_value_t *const *). When converted to a Ptr{Cvoid}, it will still return a pointer to the data region as for any other T.

A C_NULL instance of Ptr can be passed to a ccall Ref argument to initialize it.

Use in broadcasting

Ref is sometimes used in broadcasting in order to treat the referenced values as a scalar.

Examples

julia> r = Ref(5) # Create a Ref with an initial value
 Base.RefValue{Int64}(5)
 
 julia> r[] # Getting a value from a Ref
@@ -98,7 +98,7 @@
 julia> Ref{Int64}()[]; # A reference to a bitstype refers to an undetermined value if not given
 
 julia> isassigned(Ref{Int64}()) # A reference to a bitstype is always assigned
-true
source
Base.isassignedMethod
isassigned(ref::RefValue) -> Bool

Test whether the given Ref is associated with a value. This is always true for a Ref of a bitstype object. Return false if the reference is undefined.

Examples

julia> ref = Ref{Function}()
+true
source
Base.isassignedMethod
isassigned(ref::RefValue) -> Bool

Test whether the given Ref is associated with a value. This is always true for a Ref of a bitstype object. Return false if the reference is undefined.

Examples

julia> ref = Ref{Function}()
 Base.RefValue{Function}(#undef)
 
 julia> isassigned(ref)
@@ -111,6 +111,6 @@
 true
 
 julia> isassigned(Ref{Int}())
-true
source
Base.CcharType
Cchar

Equivalent to the native char c-type.

source
Base.CucharType
Cuchar

Equivalent to the native unsigned char c-type (UInt8).

source
Base.CshortType
Cshort

Equivalent to the native signed short c-type (Int16).

source
Base.CstringType
Cstring

A C-style string composed of the native character type Cchars. Cstrings are NUL-terminated. For C-style strings composed of the native wide character type, see Cwstring. For more information about string interoperability with C, see the manual.

source
Base.CushortType
Cushort

Equivalent to the native unsigned short c-type (UInt16).

source
Base.CintType
Cint

Equivalent to the native signed int c-type (Int32).

source
Base.CuintType
Cuint

Equivalent to the native unsigned int c-type (UInt32).

source
Base.ClongType
Clong

Equivalent to the native signed long c-type.

source
Base.CulongType
Culong

Equivalent to the native unsigned long c-type.

source
Base.ClonglongType
Clonglong

Equivalent to the native signed long long c-type (Int64).

source
Base.CulonglongType
Culonglong

Equivalent to the native unsigned long long c-type (UInt64).

source
Base.Cintmax_tType
Cintmax_t

Equivalent to the native intmax_t c-type (Int64).

source
Base.Cuintmax_tType
Cuintmax_t

Equivalent to the native uintmax_t c-type (UInt64).

source
Base.Csize_tType
Csize_t

Equivalent to the native size_t c-type (UInt).

source
Base.Cssize_tType
Cssize_t

Equivalent to the native ssize_t c-type.

source
Base.Cptrdiff_tType
Cptrdiff_t

Equivalent to the native ptrdiff_t c-type (Int).

source
Base.Cwchar_tType
Cwchar_t

Equivalent to the native wchar_t c-type (Int32).

source
Base.CwstringType
Cwstring

A C-style string composed of the native wide character type Cwchar_ts. Cwstrings are NUL-terminated. For C-style strings composed of the native character type, see Cstring. For more information about string interoperability with C, see the manual.

source
Base.CfloatType
Cfloat

Equivalent to the native float c-type (Float32).

source
Base.CdoubleType
Cdouble

Equivalent to the native double c-type (Float64).

source

LLVM Interface

Core.Intrinsics.llvmcallFunction
llvmcall(fun_ir::String, returntype, Tuple{argtype1, ...}, argvalue1, ...)
+true
source
Base.CcharType
Cchar

Equivalent to the native char c-type.

source
Base.CucharType
Cuchar

Equivalent to the native unsigned char c-type (UInt8).

source
Base.CshortType
Cshort

Equivalent to the native signed short c-type (Int16).

source
Base.CstringType
Cstring

A C-style string composed of the native character type Cchars. Cstrings are NUL-terminated. For C-style strings composed of the native wide character type, see Cwstring. For more information about string interoperability with C, see the manual.

source
Base.CushortType
Cushort

Equivalent to the native unsigned short c-type (UInt16).

source
Base.CintType
Cint

Equivalent to the native signed int c-type (Int32).

source
Base.CuintType
Cuint

Equivalent to the native unsigned int c-type (UInt32).

source
Base.ClongType
Clong

Equivalent to the native signed long c-type.

source
Base.CulongType
Culong

Equivalent to the native unsigned long c-type.

source
Base.ClonglongType
Clonglong

Equivalent to the native signed long long c-type (Int64).

source
Base.CulonglongType
Culonglong

Equivalent to the native unsigned long long c-type (UInt64).

source
Base.Cintmax_tType
Cintmax_t

Equivalent to the native intmax_t c-type (Int64).

source
Base.Cuintmax_tType
Cuintmax_t

Equivalent to the native uintmax_t c-type (UInt64).

source
Base.Csize_tType
Csize_t

Equivalent to the native size_t c-type (UInt).

source
Base.Cssize_tType
Cssize_t

Equivalent to the native ssize_t c-type.

source
Base.Cptrdiff_tType
Cptrdiff_t

Equivalent to the native ptrdiff_t c-type (Int).

source
Base.Cwchar_tType
Cwchar_t

Equivalent to the native wchar_t c-type (Int32).

source
Base.CwstringType
Cwstring

A C-style string composed of the native wide character type Cwchar_ts. Cwstrings are NUL-terminated. For C-style strings composed of the native character type, see Cstring. For more information about string interoperability with C, see the manual.

source
Base.CfloatType
Cfloat

Equivalent to the native float c-type (Float32).

source
Base.CdoubleType
Cdouble

Equivalent to the native double c-type (Float64).

source

LLVM Interface

Core.Intrinsics.llvmcallFunction
llvmcall(fun_ir::String, returntype, Tuple{argtype1, ...}, argvalue1, ...)
 llvmcall((mod_ir::String, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)
-llvmcall((mod_bc::Vector{UInt8}, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)

Call the LLVM code provided in the first argument. There are several ways to specify this first argument:

  • as a literal string, representing function-level IR (similar to an LLVM define block), with arguments are available as consecutive unnamed SSA variables (%0, %1, etc.);
  • as a 2-element tuple, containing a string of module IR and a string representing the name of the entry-point function to call;
  • as a 2-element tuple, but with the module provided as an Vector{UInt8} with bitcode.

Note that contrary to ccall, the argument types must be specified as a tuple type, and not a tuple of types. All types, as well as the LLVM code, should be specified as literals, and not as variables or expressions (it may be necessary to use @eval to generate these literals).

Opaque pointers (written as ptr) are not allowed in the LLVM code.

See test/llvmcall.jl for usage examples.

source
+llvmcall((mod_bc::Vector{UInt8}, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)

Call the LLVM code provided in the first argument. There are several ways to specify this first argument:

Note that contrary to ccall, the argument types must be specified as a tuple type, and not a tuple of types. All types, as well as the LLVM code, should be specified as literals, and not as variables or expressions (it may be necessary to use @eval to generate these literals).

Opaque pointers (written as ptr) are not allowed in the LLVM code.

See test/llvmcall.jl for usage examples.

source diff --git a/en/v1.12-dev/base/collections/index.html b/en/v1.12-dev/base/collections/index.html index 9ba7f39d1bfb..e27d585300d6 100644 --- a/en/v1.12-dev/base/collections/index.html +++ b/en/v1.12-dev/base/collections/index.html @@ -10,12 +10,12 @@ (i, state) = next # body next = iterate(iter, state) -end

The state object may be anything, and should be chosen appropriately for each iterable type. See the manual section on the iteration interface for more details about defining a custom iterable type.

Base.iterateFunction
iterate(iter [, state]) -> Union{Nothing, Tuple{Any, Any}}

Advance the iterator to obtain the next element. If no elements remain, nothing should be returned. Otherwise, a 2-tuple of the next element and the new iteration state should be returned.

source
Base.IteratorSizeType
IteratorSize(itertype::Type) -> IteratorSize

Given the type of an iterator, return one of the following values:

  • SizeUnknown() if the length (number of elements) cannot be determined in advance.
  • HasLength() if there is a fixed, finite length.
  • HasShape{N}() if there is a known length plus a notion of multidimensional shape (as for an array). In this case N should give the number of dimensions, and the axes function is valid for the iterator.
  • IsInfinite() if the iterator yields values forever.

The default value (for iterators that do not define this function) is HasLength(). This means that most iterators are assumed to implement length.

This trait is generally used to select between algorithms that pre-allocate space for their result, and algorithms that resize their result incrementally.

julia> Base.IteratorSize(1:5)
+end

The state object may be anything, and should be chosen appropriately for each iterable type. See the manual section on the iteration interface for more details about defining a custom iterable type.

Base.iterateFunction
iterate(iter [, state]) -> Union{Nothing, Tuple{Any, Any}}

Advance the iterator to obtain the next element. If no elements remain, nothing should be returned. Otherwise, a 2-tuple of the next element and the new iteration state should be returned.

source
Base.IteratorSizeType
IteratorSize(itertype::Type) -> IteratorSize

Given the type of an iterator, return one of the following values:

  • SizeUnknown() if the length (number of elements) cannot be determined in advance.
  • HasLength() if there is a fixed, finite length.
  • HasShape{N}() if there is a known length plus a notion of multidimensional shape (as for an array). In this case N should give the number of dimensions, and the axes function is valid for the iterator.
  • IsInfinite() if the iterator yields values forever.

The default value (for iterators that do not define this function) is HasLength(). This means that most iterators are assumed to implement length.

This trait is generally used to select between algorithms that pre-allocate space for their result, and algorithms that resize their result incrementally.

julia> Base.IteratorSize(1:5)
 Base.HasShape{1}()
 
 julia> Base.IteratorSize((2,3))
-Base.HasLength()
source
Base.IteratorEltypeType
IteratorEltype(itertype::Type) -> IteratorEltype

Given the type of an iterator, return one of the following values:

  • EltypeUnknown() if the type of elements yielded by the iterator is not known in advance.
  • HasEltype() if the element type is known, and eltype would return a meaningful value.

HasEltype() is the default, since iterators are assumed to implement eltype.

This trait is generally used to select between algorithms that pre-allocate a specific type of result, and algorithms that pick a result type based on the types of yielded values.

julia> Base.IteratorEltype(1:5)
-Base.HasEltype()
source

Fully implemented by:

Constructors and Types

Base.OrdinalRangeType
OrdinalRange{T, S} <: AbstractRange{T}

Supertype for ordinal ranges with elements of type T with spacing(s) of type S. The steps should be always-exact multiples of oneunit, and T should be a "discrete" type, which cannot have values smaller than oneunit. For example, Integer or Date types would qualify, whereas Float64 would not (since this type can represent values smaller than oneunit(Float64). UnitRange, StepRange, and other types are subtypes of this.

source
Base.StepRangeType
StepRange{T, S} <: OrdinalRange{T, S}

Ranges with elements of type T with spacing of type S. The step between each element is constant, and the range is defined in terms of a start and stop of type T and a step of type S. Neither T nor S should be floating point types. The syntax a:b:c with b != 0 and a, b, and c all integers creates a StepRange.

Examples

julia> collect(StepRange(1, Int8(2), 10))
+Base.HasLength()
source
Base.IteratorEltypeType
IteratorEltype(itertype::Type) -> IteratorEltype

Given the type of an iterator, return one of the following values:

  • EltypeUnknown() if the type of elements yielded by the iterator is not known in advance.
  • HasEltype() if the element type is known, and eltype would return a meaningful value.

HasEltype() is the default, since iterators are assumed to implement eltype.

This trait is generally used to select between algorithms that pre-allocate a specific type of result, and algorithms that pick a result type based on the types of yielded values.

julia> Base.IteratorEltype(1:5)
+Base.HasEltype()
source

Fully implemented by:

Constructors and Types

Base.OrdinalRangeType
OrdinalRange{T, S} <: AbstractRange{T}

Supertype for ordinal ranges with elements of type T with spacing(s) of type S. The steps should be always-exact multiples of oneunit, and T should be a "discrete" type, which cannot have values smaller than oneunit. For example, Integer or Date types would qualify, whereas Float64 would not (since this type can represent values smaller than oneunit(Float64). UnitRange, StepRange, and other types are subtypes of this.

source
Base.StepRangeType
StepRange{T, S} <: OrdinalRange{T, S}

Ranges with elements of type T with spacing of type S. The step between each element is constant, and the range is defined in terms of a start and stop of type T and a step of type S. Neither T nor S should be floating point types. The syntax a:b:c with b != 0 and a, b, and c all integers creates a StepRange.

Examples

julia> collect(StepRange(1, Int8(2), 10))
 5-element Vector{Int64}:
  1
  3
@@ -27,14 +27,14 @@
 StepRange{Int64, Int8}
 
 julia> typeof(1:3:6)
-StepRange{Int64, Int64}
source
Base.UnitRangeType
UnitRange{T<:Real}

A range parameterized by a start and stop of type T, filled with elements spaced by 1 from start until stop is exceeded. The syntax a:b with a and b both Integers creates a UnitRange.

Examples

julia> collect(UnitRange(2.3, 5.2))
+StepRange{Int64, Int64}
source
Base.UnitRangeType
UnitRange{T<:Real}

A range parameterized by a start and stop of type T, filled with elements spaced by 1 from start until stop is exceeded. The syntax a:b with a and b both Integers creates a UnitRange.

Examples

julia> collect(UnitRange(2.3, 5.2))
 3-element Vector{Float64}:
  2.3
  3.3
  4.3
 
 julia> typeof(1:10)
-UnitRange{Int64}
source
Base.LinRangeType
LinRange{T,L}

A range with len linearly spaced elements between its start and stop. The size of the spacing is controlled by len, which must be an Integer.

Examples

julia> LinRange(1.5, 5.5, 9)
+UnitRange{Int64}
source
Base.LinRangeType
LinRange{T,L}

A range with len linearly spaced elements between its start and stop. The size of the spacing is controlled by len, which must be an Integer.

Examples

julia> LinRange(1.5, 5.5, 9)
 9-element LinRange{Float64, Int64}:
  1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5

Compared to using range, directly constructing a LinRange should have less overhead but won't try to correct for floating point errors:

julia> collect(range(-0.1, 0.3, length=5))
 5-element Vector{Float64}:
@@ -50,11 +50,11 @@
  -1.3877787807814457e-17
   0.09999999999999999
   0.19999999999999998
-  0.3

See also Logrange for logarithmically spaced points.

source

General Collections

Base.isemptyFunction
isempty(collection) -> Bool

Determine whether a collection is empty (has no elements).

Warning

isempty(itr) may consume the next element of a stateful iterator itr unless an appropriate Base.isdone(itr) method is defined. Stateful iterators should implement isdone, but you may want to avoid using isempty when writing generic code which should support any iterator type.

Examples

julia> isempty([])
+  0.3

See also Logrange for logarithmically spaced points.

source

General Collections

Base.isemptyFunction
isempty(collection) -> Bool

Determine whether a collection is empty (has no elements).

Warning

isempty(itr) may consume the next element of a stateful iterator itr unless an appropriate Base.isdone(itr) method is defined. Stateful iterators should implement isdone, but you may want to avoid using isempty when writing generic code which should support any iterator type.

Examples

julia> isempty([])
 true
 
 julia> isempty([1 2 3])
-false
source
isempty(condition)

Return true if no tasks are waiting on the condition, false otherwise.

source
Base.isdoneFunction
isdone(itr, [state]) -> Union{Bool, Missing}

This function provides a fast-path hint for iterator completion. This is useful for stateful iterators that want to avoid having elements consumed if they are not going to be exposed to the user (e.g. when checking for done-ness in isempty or zip).

Stateful iterators that want to opt into this feature should define an isdone method that returns true/false depending on whether the iterator is done or not. Stateless iterators need not implement this function.

If the result is missing, callers may go ahead and compute iterate(x, state) === nothing to compute a definite answer.

See also iterate, isempty

source
Base.empty!Function
empty!(collection) -> collection

Remove all elements from a collection.

Examples

julia> A = Dict("a" => 1, "b" => 2)
+false
source
isempty(condition)

Return true if no tasks are waiting on the condition, false otherwise.

source
Base.isdoneFunction
isdone(itr, [state]) -> Union{Bool, Missing}

This function provides a fast-path hint for iterator completion. This is useful for stateful iterators that want to avoid having elements consumed if they are not going to be exposed to the user (e.g. when checking for done-ness in isempty or zip).

Stateful iterators that want to opt into this feature should define an isdone method that returns true/false depending on whether the iterator is done or not. Stateless iterators need not implement this function.

If the result is missing, callers may go ahead and compute iterate(x, state) === nothing to compute a definite answer.

See also iterate, isempty

source
Base.empty!Function
empty!(collection) -> collection

Remove all elements from a collection.

Examples

julia> A = Dict("a" => 1, "b" => 2)
 Dict{String, Int64} with 2 entries:
   "b" => 2
   "a" => 1
@@ -62,14 +62,14 @@
 julia> empty!(A);
 
 julia> A
-Dict{String, Int64}()
source
empty!(c::Channel)

Empty a Channel c by calling empty! on the internal buffer. Return the empty channel.

source
Base.lengthFunction
length(collection) -> Integer

Return the number of elements in the collection.

Use lastindex to get the last valid index of an indexable collection.

See also: size, ndims, eachindex.

Examples

julia> length(1:5)
+Dict{String, Int64}()
source
empty!(c::Channel)

Empty a Channel c by calling empty! on the internal buffer. Return the empty channel.

source
Base.lengthFunction
length(collection) -> Integer

Return the number of elements in the collection.

Use lastindex to get the last valid index of an indexable collection.

See also: size, ndims, eachindex.

Examples

julia> length(1:5)
 5
 
 julia> length([1, 2, 3, 4])
 4
 
 julia> length([1 2; 3 4])
-4
source
Base.checked_lengthFunction
Base.checked_length(r)

Calculates length(r), but may check for overflow errors where applicable when the result doesn't fit into Union{Integer(eltype(r)),Int}.

source

Fully implemented by:

Iterable Collections

Base.checked_lengthFunction
Base.checked_length(r)

Calculates length(r), but may check for overflow errors where applicable when the result doesn't fit into Union{Integer(eltype(r)),Int}.

source

Fully implemented by:

Iterable Collections

Base.inFunction
in(item, collection) -> Bool
 ∈(item, collection) -> Bool

Determine whether an item is in the given collection, in the sense that it is == to one of the values generated by iterating over the collection. Return a Bool value, except if item is missing or collection contains missing but not item, in which case missing is returned (three-valued logic, matching the behavior of any and ==).

Some collections follow a slightly different definition. For example, Sets check whether the item isequal to one of the elements; Dicts look for key=>value pairs, and the key is compared using isequal.

To test for the presence of a key in a dictionary, use haskey or k in keys(dict). For the collections mentioned above, the result is always a Bool.

When broadcasting with in.(items, collection) or items .∈ collection, both items and collection are broadcasted over, which is often not what is intended. For example, if both arguments are vectors (and the dimensions match), the result is a vector indicating whether each value in collection items is in the value at the corresponding position in collection. To get a vector indicating whether each value in items is in collection, wrap collection in a tuple or a Ref like this: in.(items, Ref(collection)) or items .∈ Ref(collection).

See also: , insorted, contains, occursin, issubset.

Examples

julia> a = 1:3:20
 1:3:19
 
@@ -102,7 +102,7 @@
 julia> [1, 2] .∈ ([2, 3],)
 2-element BitVector:
  0
- 1
source
Base.:∉Function
∉(item, collection) -> Bool
 ∌(collection, item) -> Bool

Negation of and , i.e. checks that item is not in collection.

When broadcasting with items .∉ collection, both items and collection are broadcasted over, which is often not what is intended. For example, if both arguments are vectors (and the dimensions match), the result is a vector indicating whether each value in collection items is not in the value at the corresponding position in collection. To get a vector indicating whether each value in items is not in collection, wrap collection in a tuple or a Ref like this: items .∉ Ref(collection).

Examples

julia> 1 ∉ 2:4
 true
 
@@ -117,11 +117,11 @@
 julia> [1, 2] .∉ ([2, 3],)
 2-element BitVector:
  1
- 0
source
Base.hasfastinFunction
Base.hasfastin(T)

Determine whether the computation x ∈ collection where collection::T can be considered as a "fast" operation (typically constant or logarithmic complexity). The definition hasfastin(x) = hasfastin(typeof(x)) is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.

The default for hasfastin(T) is true for subtypes of AbstractSet, AbstractDict and AbstractRange and false otherwise.

source
Base.eltypeFunction
eltype(type)

Determine the type of the elements generated by iterating a collection of the given type. For dictionary types, this will be a Pair{KeyType,ValType}. The definition eltype(x) = eltype(typeof(x)) is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.

See also: keytype, typeof.

Examples

julia> eltype(fill(1f0, (2,2)))
+ 0
source
Base.hasfastinFunction
Base.hasfastin(T)

Determine whether the computation x ∈ collection where collection::T can be considered as a "fast" operation (typically constant or logarithmic complexity). The definition hasfastin(x) = hasfastin(typeof(x)) is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.

The default for hasfastin(T) is true for subtypes of AbstractSet, AbstractDict and AbstractRange and false otherwise.

source
Base.eltypeFunction
eltype(type)

Determine the type of the elements generated by iterating a collection of the given type. For dictionary types, this will be a Pair{KeyType,ValType}. The definition eltype(x) = eltype(typeof(x)) is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.

See also: keytype, typeof.

Examples

julia> eltype(fill(1f0, (2,2)))
 Float32
 
 julia> eltype(fill(0x1, (2,2)))
-UInt8
source
Base.indexinFunction
indexin(a, b)

Return an array containing the first index in b for each value in a that is a member of b. The output array contains nothing wherever a is not a member of b.

See also: sortperm, findfirst.

Examples

julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
+UInt8
source
Base.indexinFunction
indexin(a, b)

Return an array containing the first index in b for each value in a that is a member of b. The output array contains nothing wherever a is not a member of b.

See also: sortperm, findfirst.

Examples

julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
 
 julia> b = ['a', 'b', 'c'];
 
@@ -138,7 +138,7 @@
 3-element Vector{Union{Nothing, Int64}}:
  1
  2
- 3
source
Base.uniqueFunction
unique(itr)

Return an array containing only the unique elements of collection itr, as determined by isequal and hash, in the order that the first of each set of equivalent elements originally appears. The element type of the input is preserved.

See also: unique!, allunique, allequal.

Examples

julia> unique([1, 2, 6, 2])
+ 3
source
Base.uniqueFunction
unique(itr)

Return an array containing only the unique elements of collection itr, as determined by isequal and hash, in the order that the first of each set of equivalent elements originally appears. The element type of the input is preserved.

See also: unique!, allunique, allequal.

Examples

julia> unique([1, 2, 6, 2])
 3-element Vector{Int64}:
  1
  2
@@ -147,7 +147,7 @@
 julia> unique(Real[1, 1.0, 2])
 2-element Vector{Real}:
  1
- 2
source
unique(f, itr)

Return an array containing one value from itr for each unique value produced by f applied to elements of itr.

Examples

julia> unique(x -> x^2, [1, -1, 3, -3, 4])
+ 2
source
unique(f, itr)

Return an array containing one value from itr for each unique value produced by f applied to elements of itr.

Examples

julia> unique(x -> x^2, [1, -1, 3, -3, 4])
 3-element Vector{Int64}:
  1
  3
@@ -168,7 +168,7 @@
  1.7
 
 julia> a[i] == unique(a)
-true
source
unique(A::AbstractArray; dims::Int)

Return unique regions of A along dimension dims.

Examples

julia> A = map(isodd, reshape(Vector(1:8), (2,2,2)))
+true
source
unique(A::AbstractArray; dims::Int)

Return unique regions of A along dimension dims.

Examples

julia> A = map(isodd, reshape(Vector(1:8), (2,2,2)))
 2×2×2 Array{Bool, 3}:
 [:, :, 1] =
  1  1
@@ -197,7 +197,7 @@
 2×2×1 Array{Bool, 3}:
 [:, :, 1] =
  1  1
- 0  0
source
Base.unique!Function
unique!(f, A::AbstractVector)

Selects one value from A for each unique value produced by f applied to elements of A, then return the modified A.

Julia 1.1

This method is available as of Julia 1.1.

Examples

julia> unique!(x -> x^2, [1, -1, 3, -3, 4])
+ 0  0
source
Base.unique!Function
unique!(f, A::AbstractVector)

Selects one value from A for each unique value produced by f applied to elements of A, then return the modified A.

Julia 1.1

This method is available as of Julia 1.1.

Examples

julia> unique!(x -> x^2, [1, -1, 3, -3, 4])
 3-element Vector{Int64}:
  1
  3
@@ -212,7 +212,7 @@
 julia> unique!(iseven, [2, 3, 5, 7, 9])
 2-element Vector{Int64}:
  2
- 3
source
unique!(A::AbstractVector)

Remove duplicate items as determined by isequal and hash, then return the modified A. unique! will return the elements of A in the order that they occur. If you do not care about the order of the returned data, then calling (sort!(A); unique!(A)) will be much more efficient as long as the elements of A can be sorted.

Examples

julia> unique!([1, 1, 1])
+ 3
source
unique!(A::AbstractVector)

Remove duplicate items as determined by isequal and hash, then return the modified A. unique! will return the elements of A in the order that they occur. If you do not care about the order of the returned data, then calling (sort!(A); unique!(A)) will be much more efficient as long as the elements of A can be sorted.

Examples

julia> unique!([1, 1, 1])
 1-element Vector{Int64}:
  1
 
@@ -233,7 +233,7 @@
 3-element Vector{Int64}:
   6
   7
- 42
source
Base.alluniqueFunction
allunique(itr) -> Bool
 allunique(f, itr) -> Bool

Return true if all values from itr are distinct when compared with isequal. Or if all of [f(x) for x in itr] are distinct, for the second method.

Note that allunique(f, itr) may call f fewer than length(itr) times. The precise number of calls is regarded as an implementation detail.

allunique may use a specialized implementation when the input is sorted.

See also: unique, issorted, allequal.

Julia 1.11

The method allunique(f, itr) requires at least Julia 1.11.

Examples

julia> allunique([1, 2, 3])
 true
 
@@ -247,7 +247,7 @@
 false
 
 julia> allunique(abs, [1, -1, 2])
-false
source
Base.allequalFunction
allequal(itr) -> Bool
 allequal(f, itr) -> Bool

Return true if all values from itr are equal when compared with isequal. Or if all of [f(x) for x in itr] are equal, for the second method.

Note that allequal(f, itr) may call f fewer than length(itr) times. The precise number of calls is regarded as an implementation detail.

See also: unique, allunique.

Julia 1.8

The allequal function requires at least Julia 1.8.

Julia 1.11

The method allequal(f, itr) requires at least Julia 1.11.

Examples

julia> allequal([])
 true
 
@@ -264,11 +264,11 @@
 false
 
 julia> allequal(abs2, [1, -1])
-true
source
Base.reduceMethod
reduce(op, itr; [init])

Reduce the given collection itr with the given binary operator op. If provided, the initial value init must be a neutral element for op that will be returned for empty collections. It is unspecified whether init is used for non-empty collections.

For empty collections, providing init will be necessary, except for some special cases (e.g. when op is one of +, *, max, min, &, |) when Julia can determine the neutral element of op.

Reductions for certain commonly-used operators may have special implementations, and should be used instead: maximum(itr), minimum(itr), sum(itr), prod(itr), any(itr), all(itr). There are efficient methods for concatenating certain arrays of arrays by calling reduce(vcat, arr) or reduce(hcat, arr).

The associativity of the reduction is implementation dependent. This means that you can't use non-associative operations like - because it is undefined whether reduce(-,[1,2,3]) should be evaluated as (1-2)-3 or 1-(2-3). Use foldl or foldr instead for guaranteed left or right associativity.

Some operations accumulate error. Parallelism will be easier if the reduction can be executed in groups. Future versions of Julia might change the algorithm. Note that the elements are not reordered if you use an ordered collection.

Examples

julia> reduce(*, [2; 3; 4])
+true
source
Base.reduceMethod
reduce(op, itr; [init])

Reduce the given collection itr with the given binary operator op. If provided, the initial value init must be a neutral element for op that will be returned for empty collections. It is unspecified whether init is used for non-empty collections.

For empty collections, providing init will be necessary, except for some special cases (e.g. when op is one of +, *, max, min, &, |) when Julia can determine the neutral element of op.

Reductions for certain commonly-used operators may have special implementations, and should be used instead: maximum(itr), minimum(itr), sum(itr), prod(itr), any(itr), all(itr). There are efficient methods for concatenating certain arrays of arrays by calling reduce(vcat, arr) or reduce(hcat, arr).

The associativity of the reduction is implementation dependent. This means that you can't use non-associative operations like - because it is undefined whether reduce(-,[1,2,3]) should be evaluated as (1-2)-3 or 1-(2-3). Use foldl or foldr instead for guaranteed left or right associativity.

Some operations accumulate error. Parallelism will be easier if the reduction can be executed in groups. Future versions of Julia might change the algorithm. Note that the elements are not reordered if you use an ordered collection.

Examples

julia> reduce(*, [2; 3; 4])
 24
 
 julia> reduce(*, [2; 3; 4]; init=-1)
--24
source
Base.reduceMethod
reduce(f, A::AbstractArray; dims=:, [init])

Reduce 2-argument function f along dimensions of A. dims is a vector specifying the dimensions to reduce, and the keyword argument init is the initial value to use in the reductions. For +, *, max and min the init argument is optional.

The associativity of the reduction is implementation-dependent; if you need a particular associativity, e.g. left-to-right, you should write your own loop or consider using foldl or foldr. See documentation for reduce.

Examples

julia> a = reshape(Vector(1:16), (4,4))
+-24
source
Base.reduceMethod
reduce(f, A::AbstractArray; dims=:, [init])

Reduce 2-argument function f along dimensions of A. dims is a vector specifying the dimensions to reduce, and the keyword argument init is the initial value to use in the reductions. For +, *, max and min the init argument is optional.

The associativity of the reduction is implementation-dependent; if you need a particular associativity, e.g. left-to-right, you should write your own loop or consider using foldl or foldr. See documentation for reduce.

Examples

julia> a = reshape(Vector(1:16), (4,4))
 4×4 Matrix{Int64}:
  1  5   9  13
  2  6  10  14
@@ -284,25 +284,25 @@
 
 julia> reduce(max, a, dims=1)
 1×4 Matrix{Int64}:
- 4  8  12  16
source
Base.foldlMethod
foldl(op, itr; [init])

Like reduce, but with guaranteed left associativity. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.

See also mapfoldl, foldr, accumulate.

Examples

julia> foldl(=>, 1:4)
+ 4  8  12  16
source
Base.foldlMethod
foldl(op, itr; [init])

Like reduce, but with guaranteed left associativity. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.

See also mapfoldl, foldr, accumulate.

Examples

julia> foldl(=>, 1:4)
 ((1 => 2) => 3) => 4
 
 julia> foldl(=>, 1:4; init=0)
 (((0 => 1) => 2) => 3) => 4
 
 julia> accumulate(=>, (1,2,3,4))
-(1, 1 => 2, (1 => 2) => 3, ((1 => 2) => 3) => 4)
source
Base.foldrMethod
foldr(op, itr; [init])

Like reduce, but with guaranteed right associativity. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.

Examples

julia> foldr(=>, 1:4)
+(1, 1 => 2, (1 => 2) => 3, ((1 => 2) => 3) => 4)
source
Base.foldrMethod
foldr(op, itr; [init])

Like reduce, but with guaranteed right associativity. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.

Examples

julia> foldr(=>, 1:4)
 1 => (2 => (3 => 4))
 
 julia> foldr(=>, 1:4; init=0)
-1 => (2 => (3 => (4 => 0)))
source
Base.maximumFunction
maximum(f, itr; [init])

Return the largest result of calling function f on each element of itr.

The value returned for empty itr can be specified by init. It must be a neutral element for max (i.e. which is less than or equal to any other element) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> maximum(length, ["Julion", "Julia", "Jule"])
+1 => (2 => (3 => (4 => 0)))
source
Base.maximumFunction
maximum(f, itr; [init])

Return the largest result of calling function f on each element of itr.

The value returned for empty itr can be specified by init. It must be a neutral element for max (i.e. which is less than or equal to any other element) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> maximum(length, ["Julion", "Julia", "Jule"])
 6
 
 julia> maximum(length, []; init=-1)
 -1
 
 julia> maximum(sin, Real[]; init=-1.0)  # good, since output of sin is >= -1
--1.0
source
maximum(itr; [init])

Return the largest element in a collection.

The value returned for empty itr can be specified by init. It must be a neutral element for max (i.e. which is less than or equal to any other element) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> maximum(-20.5:10)
+-1.0
source
maximum(itr; [init])

Return the largest element in a collection.

The value returned for empty itr can be specified by init. It must be a neutral element for max (i.e. which is less than or equal to any other element) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> maximum(-20.5:10)
 9.5
 
 julia> maximum([1,2,3])
@@ -314,7 +314,7 @@
 [...]
 
 julia> maximum((); init=-Inf)
--Inf
source
maximum(A::AbstractArray; dims)

Compute the maximum value of an array over the given dimensions. See also the max(a,b) function to take the maximum of two or more arguments, which can be applied elementwise to arrays via max.(a,b).

See also: maximum!, extrema, findmax, argmax.

Examples

julia> A = [1 2; 3 4]
+-Inf
source
maximum(A::AbstractArray; dims)

Compute the maximum value of an array over the given dimensions. See also the max(a,b) function to take the maximum of two or more arguments, which can be applied elementwise to arrays via max.(a,b).

See also: maximum!, extrema, findmax, argmax.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -326,7 +326,7 @@
 julia> maximum(A, dims=2)
 2×1 Matrix{Int64}:
  2
- 4
source
maximum(f, A::AbstractArray; dims)

Compute the maximum value by calling the function f on each element of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
+ 4
source
maximum(f, A::AbstractArray; dims)

Compute the maximum value by calling the function f on each element of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -338,7 +338,7 @@
 julia> maximum(abs2, A, dims=2)
 2×1 Matrix{Int64}:
   4
- 16
source
Base.maximum!Function
maximum!(r, A)

Compute the maximum value of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1 2; 3 4]
+ 16
source
Base.maximum!Function
maximum!(r, A)

Compute the maximum value of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -350,14 +350,14 @@
 
 julia> maximum!([1 1], A)
 1×2 Matrix{Int64}:
- 3  4
source
Base.minimumFunction
minimum(f, itr; [init])

Return the smallest result of calling function f on each element of itr.

The value returned for empty itr can be specified by init. It must be a neutral element for min (i.e. which is greater than or equal to any other element) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> minimum(length, ["Julion", "Julia", "Jule"])
+ 3  4
source
Base.minimumFunction
minimum(f, itr; [init])

Return the smallest result of calling function f on each element of itr.

The value returned for empty itr can be specified by init. It must be a neutral element for min (i.e. which is greater than or equal to any other element) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> minimum(length, ["Julion", "Julia", "Jule"])
 4
 
 julia> minimum(length, []; init=typemax(Int64))
 9223372036854775807
 
 julia> minimum(sin, Real[]; init=1.0)  # good, since output of sin is <= 1
-1.0
source
minimum(itr; [init])

Return the smallest element in a collection.

The value returned for empty itr can be specified by init. It must be a neutral element for min (i.e. which is greater than or equal to any other element) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> minimum(-20.5:10)
+1.0
source
minimum(itr; [init])

Return the smallest element in a collection.

The value returned for empty itr can be specified by init. It must be a neutral element for min (i.e. which is greater than or equal to any other element) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> minimum(-20.5:10)
 -20.5
 
 julia> minimum([1,2,3])
@@ -369,7 +369,7 @@
 [...]
 
 julia> minimum([]; init=Inf)
-Inf
source
minimum(A::AbstractArray; dims)

Compute the minimum value of an array over the given dimensions. See also the min(a,b) function to take the minimum of two or more arguments, which can be applied elementwise to arrays via min.(a,b).

See also: minimum!, extrema, findmin, argmin.

Examples

julia> A = [1 2; 3 4]
+Inf
source
minimum(A::AbstractArray; dims)

Compute the minimum value of an array over the given dimensions. See also the min(a,b) function to take the minimum of two or more arguments, which can be applied elementwise to arrays via min.(a,b).

See also: minimum!, extrema, findmin, argmin.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -381,7 +381,7 @@
 julia> minimum(A, dims=2)
 2×1 Matrix{Int64}:
  1
- 3
source
minimum(f, A::AbstractArray; dims)

Compute the minimum value by calling the function f on each element of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
+ 3
source
minimum(f, A::AbstractArray; dims)

Compute the minimum value by calling the function f on each element of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -393,7 +393,7 @@
 julia> minimum(abs2, A, dims=2)
 2×1 Matrix{Int64}:
  1
- 9
source
Base.minimum!Function
minimum!(r, A)

Compute the minimum value of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1 2; 3 4]
+ 9
source
Base.minimum!Function
minimum!(r, A)

Compute the minimum value of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -405,18 +405,18 @@
 
 julia> minimum!([1 1], A)
 1×2 Matrix{Int64}:
- 1  2
source
Base.extremaFunction
extrema(itr; [init]) -> (mn, mx)

Compute both the minimum mn and maximum mx element in a single pass, and return them as a 2-tuple.

The value returned for empty itr can be specified by init. It must be a 2-tuple whose first and second elements are neutral elements for min and max respectively (i.e. which are greater/less than or equal to any other element). As a consequence, when itr is empty the returned (mn, mx) tuple will satisfy mn ≥ mx. When init is specified it may be used even for non-empty itr.

Julia 1.8

Keyword argument init requires Julia 1.8 or later.

Examples

julia> extrema(2:10)
+ 1  2
source
Base.extremaFunction
extrema(itr; [init]) -> (mn, mx)

Compute both the minimum mn and maximum mx element in a single pass, and return them as a 2-tuple.

The value returned for empty itr can be specified by init. It must be a 2-tuple whose first and second elements are neutral elements for min and max respectively (i.e. which are greater/less than or equal to any other element). As a consequence, when itr is empty the returned (mn, mx) tuple will satisfy mn ≥ mx. When init is specified it may be used even for non-empty itr.

Julia 1.8

Keyword argument init requires Julia 1.8 or later.

Examples

julia> extrema(2:10)
 (2, 10)
 
 julia> extrema([9,pi,4.5])
 (3.141592653589793, 9.0)
 
 julia> extrema([]; init = (Inf, -Inf))
-(Inf, -Inf)
source
extrema(f, itr; [init]) -> (mn, mx)

Compute both the minimum mn and maximum mx of f applied to each element in itr and return them as a 2-tuple. Only one pass is made over itr.

The value returned for empty itr can be specified by init. It must be a 2-tuple whose first and second elements are neutral elements for min and max respectively (i.e. which are greater/less than or equal to any other element). It is used for non-empty collections. Note: it implies that, for empty itr, the returned value (mn, mx) satisfies mn ≥ mx even though for non-empty itr it satisfies mn ≤ mx. This is a "paradoxical" but yet expected result.

Julia 1.2

This method requires Julia 1.2 or later.

Julia 1.8

Keyword argument init requires Julia 1.8 or later.

Examples

julia> extrema(sin, 0:π)
+(Inf, -Inf)
source
extrema(f, itr; [init]) -> (mn, mx)

Compute both the minimum mn and maximum mx of f applied to each element in itr and return them as a 2-tuple. Only one pass is made over itr.

The value returned for empty itr can be specified by init. It must be a 2-tuple whose first and second elements are neutral elements for min and max respectively (i.e. which are greater/less than or equal to any other element). It is used for non-empty collections. Note: it implies that, for empty itr, the returned value (mn, mx) satisfies mn ≥ mx even though for non-empty itr it satisfies mn ≤ mx. This is a "paradoxical" but yet expected result.

Julia 1.2

This method requires Julia 1.2 or later.

Julia 1.8

Keyword argument init requires Julia 1.8 or later.

Examples

julia> extrema(sin, 0:π)
 (0.0, 0.9092974268256817)
 
 julia> extrema(sin, Real[]; init = (1.0, -1.0))  # good, since -1 ≤ sin(::Real) ≤ 1
-(1.0, -1.0)
source
extrema(A::AbstractArray; dims) -> Array{Tuple}

Compute the minimum and maximum elements of an array over the given dimensions.

See also: minimum, maximum, extrema!.

Examples

julia> A = reshape(Vector(1:2:16), (2,2,2))
+(1.0, -1.0)
source
extrema(A::AbstractArray; dims) -> Array{Tuple}

Compute the minimum and maximum elements of an array over the given dimensions.

See also: minimum, maximum, extrema!.

Examples

julia> A = reshape(Vector(1:2:16), (2,2,2))
 2×2×2 Array{Int64, 3}:
 [:, :, 1] =
  1  5
@@ -432,7 +432,7 @@
  (1, 7)
 
 [:, :, 2] =
- (9, 15)
source
extrema(f, A::AbstractArray; dims) -> Array{Tuple}

Compute the minimum and maximum of f applied to each element in the given dimensions of A.

Julia 1.2

This method requires Julia 1.2 or later.

source
Base.extrema!Function
extrema!(r, A)

Compute the minimum and maximum value of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Julia 1.8

This method requires Julia 1.8 or later.

Examples

julia> A = [1 2; 3 4]
+ (9, 15)
source
extrema(f, A::AbstractArray; dims) -> Array{Tuple}

Compute the minimum and maximum of f applied to each element in the given dimensions of A.

Julia 1.2

This method requires Julia 1.2 or later.

source
Base.extrema!Function
extrema!(r, A)

Compute the minimum and maximum value of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Julia 1.8

This method requires Julia 1.8 or later.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -444,18 +444,18 @@
 
 julia> extrema!([(1, 1);; (1, 1)], A)
 1×2 Matrix{Tuple{Int64, Int64}}:
- (1, 3)  (2, 4)
source
Base.argmaxFunction
argmax(r::AbstractRange)

Ranges can have multiple maximal elements. In that case argmax will return a maximal index, but not necessarily the first one.

source
argmax(f, domain)

Return a value x from domain for which f(x) is maximised. If there are multiple maximal values for f(x) then the first one will be found.

domain must be a non-empty iterable.

Values are compared with isless.

Julia 1.7

This method requires Julia 1.7 or later.

See also argmin, findmax.

Examples

julia> argmax(abs, -10:5)
+ (1, 3)  (2, 4)
source
Base.argmaxFunction
argmax(r::AbstractRange)

Ranges can have multiple maximal elements. In that case argmax will return a maximal index, but not necessarily the first one.

source
argmax(f, domain)

Return a value x from domain for which f(x) is maximised. If there are multiple maximal values for f(x) then the first one will be found.

domain must be a non-empty iterable.

Values are compared with isless.

Julia 1.7

This method requires Julia 1.7 or later.

See also argmin, findmax.

Examples

julia> argmax(abs, -10:5)
 -10
 
 julia> argmax(cos, 0:π/2:2π)
-0.0
source
argmax(itr)

Return the index or key of the maximal element in a collection. If there are multiple maximal elements, then the first one will be returned.

The collection must not be empty.

Indices are of the same type as those returned by keys(itr) and pairs(itr).

Values are compared with isless.

See also: argmin, findmax.

Examples

julia> argmax([8, 0.1, -9, pi])
+0.0
source
argmax(itr)

Return the index or key of the maximal element in a collection. If there are multiple maximal elements, then the first one will be returned.

The collection must not be empty.

Indices are of the same type as those returned by keys(itr) and pairs(itr).

Values are compared with isless.

See also: argmin, findmax.

Examples

julia> argmax([8, 0.1, -9, pi])
 1
 
 julia> argmax([1, 7, 7, 6])
 2
 
 julia> argmax([1, 7, 7, NaN])
-4
source
argmax(A; dims) -> indices

For an array input, return the indices of the maximum elements over the given dimensions. NaN is treated as greater than all other values except missing.

Examples

julia> A = [1.0 2; 3 4]
+4
source
argmax(A; dims) -> indices

For an array input, return the indices of the maximum elements over the given dimensions. NaN is treated as greater than all other values except missing.

Examples

julia> A = [1.0 2; 3 4]
 2×2 Matrix{Float64}:
  1.0  2.0
  3.0  4.0
@@ -467,21 +467,21 @@
 julia> argmax(A, dims=2)
 2×1 Matrix{CartesianIndex{2}}:
  CartesianIndex(1, 2)
- CartesianIndex(2, 2)
source
Base.argminFunction
argmin(r::AbstractRange)

Ranges can have multiple minimal elements. In that case argmin will return a minimal index, but not necessarily the first one.

source
argmin(f, domain)

Return a value x from domain for which f(x) is minimised. If there are multiple minimal values for f(x) then the first one will be found.

domain must be a non-empty iterable.

NaN is treated as less than all other values except missing.

Julia 1.7

This method requires Julia 1.7 or later.

See also argmax, findmin.

Examples

julia> argmin(sign, -10:5)
+ CartesianIndex(2, 2)
source
Base.argminFunction
argmin(r::AbstractRange)

Ranges can have multiple minimal elements. In that case argmin will return a minimal index, but not necessarily the first one.

source
argmin(f, domain)

Return a value x from domain for which f(x) is minimised. If there are multiple minimal values for f(x) then the first one will be found.

domain must be a non-empty iterable.

NaN is treated as less than all other values except missing.

Julia 1.7

This method requires Julia 1.7 or later.

See also argmax, findmin.

Examples

julia> argmin(sign, -10:5)
 -10
 
 julia> argmin(x -> -x^3 + x^2 - 10, -5:5)
 5
 
 julia> argmin(acos, 0:0.1:1)
-1.0
source
argmin(itr)

Return the index or key of the minimal element in a collection. If there are multiple minimal elements, then the first one will be returned.

The collection must not be empty.

Indices are of the same type as those returned by keys(itr) and pairs(itr).

NaN is treated as less than all other values except missing.

See also: argmax, findmin.

Examples

julia> argmin([8, 0.1, -9, pi])
+1.0
source
argmin(itr)

Return the index or key of the minimal element in a collection. If there are multiple minimal elements, then the first one will be returned.

The collection must not be empty.

Indices are of the same type as those returned by keys(itr) and pairs(itr).

NaN is treated as less than all other values except missing.

See also: argmax, findmin.

Examples

julia> argmin([8, 0.1, -9, pi])
 3
 
 julia> argmin([7, 1, 1, 6])
 2
 
 julia> argmin([7, 1, 1, NaN])
-4
source
argmin(A; dims) -> indices

For an array input, return the indices of the minimum elements over the given dimensions. NaN is treated as less than all other values except missing.

Examples

julia> A = [1.0 2; 3 4]
+4
source
argmin(A; dims) -> indices

For an array input, return the indices of the minimum elements over the given dimensions. NaN is treated as less than all other values except missing.

Examples

julia> A = [1.0 2; 3 4]
 2×2 Matrix{Float64}:
  1.0  2.0
  3.0  4.0
@@ -493,7 +493,7 @@
 julia> argmin(A, dims=2)
 2×1 Matrix{CartesianIndex{2}}:
  CartesianIndex(1, 1)
- CartesianIndex(2, 1)
source
Base.findmaxFunction
findmax(f, domain) -> (f(x), index)

Return a pair of a value in the codomain (outputs of f) and the index or key of the corresponding value in the domain (inputs to f) such that f(x) is maximised. If there are multiple maximal points, then the first one will be returned.

domain must be a non-empty iterable supporting keys. Indices are of the same type as those returned by keys(domain).

Values are compared with isless.

Julia 1.7

This method requires Julia 1.7 or later.

Examples

julia> findmax(identity, 5:9)
+ CartesianIndex(2, 1)
source
Base.findmaxFunction
findmax(f, domain) -> (f(x), index)

Return a pair of a value in the codomain (outputs of f) and the index or key of the corresponding value in the domain (inputs to f) such that f(x) is maximised. If there are multiple maximal points, then the first one will be returned.

domain must be a non-empty iterable supporting keys. Indices are of the same type as those returned by keys(domain).

Values are compared with isless.

Julia 1.7

This method requires Julia 1.7 or later.

Examples

julia> findmax(identity, 5:9)
 (9, 5)
 
 julia> findmax(-, 1:10)
@@ -503,14 +503,14 @@
 (3, 2)
 
 julia> findmax(cos, 0:π/2:2π)
-(1.0, 1)
source
findmax(itr) -> (x, index)

Return the maximal element of the collection itr and its index or key. If there are multiple maximal elements, then the first one will be returned. Values are compared with isless.

Indices are of the same type as those returned by keys(itr) and pairs(itr).

See also: findmin, argmax, maximum.

Examples

julia> findmax([8, 0.1, -9, pi])
+(1.0, 1)
source
findmax(itr) -> (x, index)

Return the maximal element of the collection itr and its index or key. If there are multiple maximal elements, then the first one will be returned. Values are compared with isless.

Indices are of the same type as those returned by keys(itr) and pairs(itr).

See also: findmin, argmax, maximum.

Examples

julia> findmax([8, 0.1, -9, pi])
 (8.0, 1)
 
 julia> findmax([1, 7, 7, 6])
 (7, 2)
 
 julia> findmax([1, 7, 7, NaN])
-(NaN, 4)
source
findmax(A; dims) -> (maxval, index)

For an array input, returns the value and index of the maximum over the given dimensions. NaN is treated as greater than all other values except missing.

Examples

julia> A = [1.0 2; 3 4]
+(NaN, 4)
source
findmax(A; dims) -> (maxval, index)

For an array input, returns the value and index of the maximum over the given dimensions. NaN is treated as greater than all other values except missing.

Examples

julia> A = [1.0 2; 3 4]
 2×2 Matrix{Float64}:
  1.0  2.0
  3.0  4.0
@@ -519,7 +519,7 @@
 ([3.0 4.0], CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(2, 2)])
 
 julia> findmax(A, dims=2)
-([2.0; 4.0;;], CartesianIndex{2}[CartesianIndex(1, 2); CartesianIndex(2, 2);;])
source
findmax(f, A; dims) -> (f(x), index)

For an array input, returns the value in the codomain and index of the corresponding value which maximize f over the given dimensions.

Examples

julia> A = [-1.0 1; -0.5 2]
+([2.0; 4.0;;], CartesianIndex{2}[CartesianIndex(1, 2); CartesianIndex(2, 2);;])
source
findmax(f, A; dims) -> (f(x), index)

For an array input, returns the value in the codomain and index of the corresponding value which maximize f over the given dimensions.

Examples

julia> A = [-1.0 1; -0.5 2]
 2×2 Matrix{Float64}:
  -1.0  1.0
  -0.5  2.0
@@ -528,7 +528,7 @@
 ([1.0 4.0], CartesianIndex{2}[CartesianIndex(1, 1) CartesianIndex(2, 2)])
 
 julia> findmax(abs2, A, dims=2)
-([1.0; 4.0;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 2);;])
source
Base.findminFunction
findmin(f, domain) -> (f(x), index)

Return a pair of a value in the codomain (outputs of f) and the index or key of the corresponding value in the domain (inputs to f) such that f(x) is minimised. If there are multiple minimal points, then the first one will be returned.

domain must be a non-empty iterable.

Indices are of the same type as those returned by keys(domain) and pairs(domain).

NaN is treated as less than all other values except missing.

Julia 1.7

This method requires Julia 1.7 or later.

Examples

julia> findmin(identity, 5:9)
+([1.0; 4.0;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 2);;])
source
Base.findminFunction
findmin(f, domain) -> (f(x), index)

Return a pair of a value in the codomain (outputs of f) and the index or key of the corresponding value in the domain (inputs to f) such that f(x) is minimised. If there are multiple minimal points, then the first one will be returned.

domain must be a non-empty iterable.

Indices are of the same type as those returned by keys(domain) and pairs(domain).

NaN is treated as less than all other values except missing.

Julia 1.7

This method requires Julia 1.7 or later.

Examples

julia> findmin(identity, 5:9)
 (5, 1)
 
 julia> findmin(-, 1:10)
@@ -538,14 +538,14 @@
 (2, 1)
 
 julia> findmin(cos, 0:π/2:2π)
-(-1.0, 3)
source
findmin(itr) -> (x, index)

Return the minimal element of the collection itr and its index or key. If there are multiple minimal elements, then the first one will be returned. NaN is treated as less than all other values except missing.

Indices are of the same type as those returned by keys(itr) and pairs(itr).

See also: findmax, argmin, minimum.

Examples

julia> findmin([8, 0.1, -9, pi])
+(-1.0, 3)
source
findmin(itr) -> (x, index)

Return the minimal element of the collection itr and its index or key. If there are multiple minimal elements, then the first one will be returned. NaN is treated as less than all other values except missing.

Indices are of the same type as those returned by keys(itr) and pairs(itr).

See also: findmax, argmin, minimum.

Examples

julia> findmin([8, 0.1, -9, pi])
 (-9.0, 3)
 
 julia> findmin([1, 7, 7, 6])
 (1, 1)
 
 julia> findmin([1, 7, 7, NaN])
-(NaN, 4)
source
findmin(A; dims) -> (minval, index)

For an array input, returns the value and index of the minimum over the given dimensions. NaN is treated as less than all other values except missing.

Examples

julia> A = [1.0 2; 3 4]
+(NaN, 4)
source
findmin(A; dims) -> (minval, index)

For an array input, returns the value and index of the minimum over the given dimensions. NaN is treated as less than all other values except missing.

Examples

julia> A = [1.0 2; 3 4]
 2×2 Matrix{Float64}:
  1.0  2.0
  3.0  4.0
@@ -554,7 +554,7 @@
 ([1.0 2.0], CartesianIndex{2}[CartesianIndex(1, 1) CartesianIndex(1, 2)])
 
 julia> findmin(A, dims=2)
-([1.0; 3.0;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 1);;])
source
findmin(f, A; dims) -> (f(x), index)

For an array input, returns the value in the codomain and index of the corresponding value which minimize f over the given dimensions.

Examples

julia> A = [-1.0 1; -0.5 2]
+([1.0; 3.0;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 1);;])
source
findmin(f, A; dims) -> (f(x), index)

For an array input, returns the value in the codomain and index of the corresponding value which minimize f over the given dimensions.

Examples

julia> A = [-1.0 1; -0.5 2]
 2×2 Matrix{Float64}:
  -1.0  1.0
  -0.5  2.0
@@ -563,16 +563,16 @@
 ([0.25 1.0], CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(1, 2)])
 
 julia> findmin(abs2, A, dims=2)
-([1.0; 0.25;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 1);;])
source
Base.findmax!Function
findmax!(rval, rind, A) -> (maxval, index)

Find the maximum of A and the corresponding linear index along singleton dimensions of rval and rind, and store the results in rval and rind. NaN is treated as greater than all other values except missing.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.findmin!Function
findmin!(rval, rind, A) -> (minval, index)

Find the minimum of A and the corresponding linear index along singleton dimensions of rval and rind, and store the results in rval and rind. NaN is treated as less than all other values except missing.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.sumFunction
sum(f, itr; [init])

Sum the results of calling function f on each element of itr.

The return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.

The value returned for empty itr can be specified by init. It must be the additive identity (i.e. zero) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> sum(abs2, [2; 3; 4])
+([1.0; 0.25;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 1);;])
source
Base.findmax!Function
findmax!(rval, rind, A) -> (maxval, index)

Find the maximum of A and the corresponding linear index along singleton dimensions of rval and rind, and store the results in rval and rind. NaN is treated as greater than all other values except missing.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.findmin!Function
findmin!(rval, rind, A) -> (minval, index)

Find the minimum of A and the corresponding linear index along singleton dimensions of rval and rind, and store the results in rval and rind. NaN is treated as less than all other values except missing.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.sumFunction
sum(f, itr; [init])

Sum the results of calling function f on each element of itr.

The return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.

The value returned for empty itr can be specified by init. It must be the additive identity (i.e. zero) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> sum(abs2, [2; 3; 4])
 29

Note the important difference between sum(A) and reduce(+, A) for arrays with small integer eltype:

julia> sum(Int8[100, 28])
 128
 
 julia> reduce(+, Int8[100, 28])
--128

In the former case, the integers are widened to system word size and therefore the result is 128. In the latter case, no such widening happens and integer overflow results in -128.

source
sum(itr; [init])

Return the sum of all elements in a collection.

The return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.

The value returned for empty itr can be specified by init. It must be the additive identity (i.e. zero) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

See also: reduce, mapreduce, count, union.

Examples

julia> sum(1:20)
+-128

In the former case, the integers are widened to system word size and therefore the result is 128. In the latter case, no such widening happens and integer overflow results in -128.

source
sum(itr; [init])

Return the sum of all elements in a collection.

The return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.

The value returned for empty itr can be specified by init. It must be the additive identity (i.e. zero) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

See also: reduce, mapreduce, count, union.

Examples

julia> sum(1:20)
 210
 
 julia> sum(1:20; init = 0.0)
-210.0
source
sum(A::AbstractArray; dims)

Sum elements of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
+210.0
source
sum(A::AbstractArray; dims)

Sum elements of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -584,7 +584,7 @@
 julia> sum(A, dims=2)
 2×1 Matrix{Int64}:
  3
- 7
source
sum(f, A::AbstractArray; dims)

Sum the results of calling function f on each element of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
+ 7
source
sum(f, A::AbstractArray; dims)

Sum the results of calling function f on each element of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -596,7 +596,7 @@
 julia> sum(abs2, A, dims=2)
 2×1 Matrix{Int64}:
   5
- 25
source
Base.sum!Function
sum!(r, A)

Sum elements of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1 2; 3 4]
+ 25
source
Base.sum!Function
sum!(r, A)

Sum elements of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -608,12 +608,12 @@
 
 julia> sum!([1 1], A)
 1×2 Matrix{Int64}:
- 4  6
source
Base.prodFunction
prod(f, itr; [init])

Return the product of f applied to each element of itr.

The return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.

The value returned for empty itr can be specified by init. It must be the multiplicative identity (i.e. one) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> prod(abs2, [2; 3; 4])
-576
source
prod(itr; [init])

Return the product of all elements of a collection.

The return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.

The value returned for empty itr can be specified by init. It must be the multiplicative identity (i.e. one) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

See also: reduce, cumprod, any.

Examples

julia> prod(1:5)
+ 4  6
source
Base.prodFunction
prod(f, itr; [init])

Return the product of f applied to each element of itr.

The return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.

The value returned for empty itr can be specified by init. It must be the multiplicative identity (i.e. one) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

Examples

julia> prod(abs2, [2; 3; 4])
+576
source
prod(itr; [init])

Return the product of all elements of a collection.

The return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.

The value returned for empty itr can be specified by init. It must be the multiplicative identity (i.e. one) as it is unspecified whether init is used for non-empty collections.

Julia 1.6

Keyword argument init requires Julia 1.6 or later.

See also: reduce, cumprod, any.

Examples

julia> prod(1:5)
 120
 
 julia> prod(1:5; init = 1.0)
-120.0
source
prod(A::AbstractArray; dims)

Multiply elements of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
+120.0
source
prod(A::AbstractArray; dims)

Multiply elements of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -625,7 +625,7 @@
 julia> prod(A, dims=2)
 2×1 Matrix{Int64}:
   2
- 12
source
prod(f, A::AbstractArray; dims)

Multiply the results of calling the function f on each element of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
+ 12
source
prod(f, A::AbstractArray; dims)

Multiply the results of calling the function f on each element of an array over the given dimensions.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -637,7 +637,7 @@
 julia> prod(abs2, A, dims=2)
 2×1 Matrix{Int64}:
    4
- 144
source
Base.prod!Function
prod!(r, A)

Multiply elements of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1 2; 3 4]
+ 144
source
Base.prod!Function
prod!(r, A)

Multiply elements of A over the singleton dimensions of r, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -649,7 +649,7 @@
 
 julia> prod!([1 1], A)
 1×2 Matrix{Int64}:
- 3  8
source
Base.anyMethod
any(itr) -> Bool

Test whether any elements of a boolean collection are true, returning true as soon as the first true value in itr is encountered (short-circuiting). To short-circuit on false, use all.

If the input contains missing values, return missing if all non-missing values are false (or equivalently, if the input contains no true value), following three-valued logic.

See also: all, count, sum, |, , ||.

Examples

julia> a = [true,false,false,true]
+ 3  8
source
Base.anyMethod
any(itr) -> Bool

Test whether any elements of a boolean collection are true, returning true as soon as the first true value in itr is encountered (short-circuiting). To short-circuit on false, use all.

If the input contains missing values, return missing if all non-missing values are false (or equivalently, if the input contains no true value), following three-valued logic.

See also: all, count, sum, |, , ||.

Examples

julia> a = [true,false,false,true]
 4-element Vector{Bool}:
  1
  0
@@ -667,7 +667,7 @@
 true
 
 julia> any([false, missing])
-missing
source
Base.anyMethod
any(p, itr) -> Bool

Determine whether predicate p returns true for any elements of itr, returning true as soon as the first item in itr for which p returns true is encountered (short-circuiting). To short-circuit on false, use all.

If the input contains missing values, return missing if all non-missing values are false (or equivalently, if the input contains no true value), following three-valued logic.

Examples

julia> any(i->(4<=i<=6), [3,5,7])
+missing
source
Base.anyMethod
any(p, itr) -> Bool

Determine whether predicate p returns true for any elements of itr, returning true as soon as the first item in itr for which p returns true is encountered (short-circuiting). To short-circuit on false, use all.

If the input contains missing values, return missing if all non-missing values are false (or equivalently, if the input contains no true value), following three-valued logic.

Examples

julia> any(i->(4<=i<=6), [3,5,7])
 true
 
 julia> any(i -> (println(i); i > 3), 1:10)
@@ -684,7 +684,7 @@
 missing
 
 julia> any(i -> i > 0, [-1, 0])
-false
source
Base.any!Function
any!(r, A)

Test whether any values in A along the singleton dimensions of r are true, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [true false; true false]
+false
source
Base.any!Function
any!(r, A)

Test whether any values in A along the singleton dimensions of r are true, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [true false; true false]
 2×2 Matrix{Bool}:
  1  0
  1  0
@@ -696,7 +696,7 @@
 
 julia> any!([1 1], A)
 1×2 Matrix{Int64}:
- 1  0
source
Base.allMethod
all(itr) -> Bool

Test whether all elements of a boolean collection are true, returning false as soon as the first false value in itr is encountered (short-circuiting). To short-circuit on true, use any.

If the input contains missing values, return missing if all non-missing values are true (or equivalently, if the input contains no false value), following three-valued logic.

See also: all!, any, count, &, , &&, allunique.

Examples

julia> a = [true,false,false,true]
+ 1  0
source
Base.allMethod
all(itr) -> Bool

Test whether all elements of a boolean collection are true, returning false as soon as the first false value in itr is encountered (short-circuiting). To short-circuit on true, use any.

If the input contains missing values, return missing if all non-missing values are true (or equivalently, if the input contains no false value), following three-valued logic.

See also: all!, any, count, &, , &&, allunique.

Examples

julia> a = [true,false,false,true]
 4-element Vector{Bool}:
  1
  0
@@ -715,7 +715,7 @@
 false
 
 julia> all([true, missing])
-missing
source
Base.allMethod
all(p, itr) -> Bool

Determine whether predicate p returns true for all elements of itr, returning false as soon as the first item in itr for which p returns false is encountered (short-circuiting). To short-circuit on true, use any.

If the input contains missing values, return missing if all non-missing values are true (or equivalently, if the input contains no false value), following three-valued logic.

Examples

julia> all(i->(4<=i<=6), [4,5,6])
+missing
source
Base.allMethod
all(p, itr) -> Bool

Determine whether predicate p returns true for all elements of itr, returning false as soon as the first item in itr for which p returns false is encountered (short-circuiting). To short-circuit on true, use any.

If the input contains missing values, return missing if all non-missing values are true (or equivalently, if the input contains no false value), following three-valued logic.

Examples

julia> all(i->(4<=i<=6), [4,5,6])
 true
 
 julia> all(i -> (println(i); i < 3), 1:10)
@@ -731,7 +731,7 @@
 false
 
 julia> all(i -> i > 0, [1, 2])
-true
source
Base.all!Function
all!(r, A)

Test whether all values in A along the singleton dimensions of r are true, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [true false; true false]
+true
source
Base.all!Function
all!(r, A)

Test whether all values in A along the singleton dimensions of r are true, and write results to r.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> A = [true false; true false]
 2×2 Matrix{Bool}:
  1  0
  1  0
@@ -743,14 +743,14 @@
 
 julia> all!([1 1], A)
 1×2 Matrix{Int64}:
- 1  0
source
Base.countFunction
count([f=identity,] itr; init=0) -> Integer

Count the number of elements in itr for which the function f returns true. If f is omitted, count the number of true elements in itr (which should be a collection of boolean values). init optionally specifies the value to start counting from and therefore also determines the output type.

Julia 1.6

init keyword was added in Julia 1.6.

See also: any, sum.

Examples

julia> count(i->(4<=i<=6), [2,3,4,5,6])
+ 1  0
source
Base.countFunction
count([f=identity,] itr; init=0) -> Integer

Count the number of elements in itr for which the function f returns true. If f is omitted, count the number of true elements in itr (which should be a collection of boolean values). init optionally specifies the value to start counting from and therefore also determines the output type.

Julia 1.6

init keyword was added in Julia 1.6.

See also: any, sum.

Examples

julia> count(i->(4<=i<=6), [2,3,4,5,6])
 3
 
 julia> count([true, false, true, true])
 3
 
 julia> count(>(3), 1:7, init=0x03)
-0x07
source
count(
+0x07
source
count(
     pattern::Union{AbstractChar,AbstractString,AbstractPattern},
     string::AbstractString;
     overlap::Bool = false,
@@ -761,7 +761,7 @@
 3
 
 julia> count(r"a(.)a", "cabacabac")
-2
source
count([f=identity,] A::AbstractArray; dims=:)

Count the number of elements in A for which f returns true over the given dimensions.

Julia 1.5

dims keyword was added in Julia 1.5.

Julia 1.6

init keyword was added in Julia 1.6.

Examples

julia> A = [1 2; 3 4]
+2
source
count([f=identity,] A::AbstractArray; dims=:)

Count the number of elements in A for which f returns true over the given dimensions.

Julia 1.5

dims keyword was added in Julia 1.5.

Julia 1.6

init keyword was added in Julia 1.6.

Examples

julia> A = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -773,7 +773,7 @@
 julia> count(<=(2), A, dims=2)
 2×1 Matrix{Int64}:
  2
- 0
source
Base.foreachFunction
foreach(f, c...) -> Nothing

Call function f on each element of iterable c. For multiple iterable arguments, f is called elementwise, and iteration stops when any iterator is finished.

foreach should be used instead of map when the results of f are not needed, for example in foreach(println, array).

Examples

julia> tri = 1:3:7; res = Int[];
+ 0
source
Base.foreachFunction
foreach(f, c...) -> Nothing

Call function f on each element of iterable c. For multiple iterable arguments, f is called elementwise, and iteration stops when any iterator is finished.

foreach should be used instead of map when the results of f are not needed, for example in foreach(println, array).

Examples

julia> tri = 1:3:7; res = Int[];
 
 julia> foreach(x -> push!(res, x^2), tri)
 
@@ -786,7 +786,7 @@
 julia> foreach((x, y) -> println(x, " with ", y), tri, 'a':'z')
 1 with a
 4 with b
-7 with c
source
Base.mapFunction
map(f, c...) -> collection

Transform collection c by applying f to each element. For multiple collection arguments, apply f elementwise, and stop when any of them is exhausted.

See also map!, foreach, mapreduce, mapslices, zip, Iterators.map.

Examples

julia> map(x -> x * 2, [1, 2, 3])
+7 with c
source
Base.mapFunction
map(f, c...) -> collection

Transform collection c by applying f to each element. For multiple collection arguments, apply f elementwise, and stop when any of them is exhausted.

See also map!, foreach, mapreduce, mapslices, zip, Iterators.map.

Examples

julia> map(x -> x * 2, [1, 2, 3])
 3-element Vector{Int64}:
  2
  4
@@ -796,7 +796,7 @@
 3-element Vector{Int64}:
  11
  22
- 33
source
map(f, A::AbstractArray...) -> N-array

When acting on multi-dimensional arrays of the same ndims, they must all have the same axes, and the answer will too.

See also broadcast, which allows mismatched sizes.

Examples

julia> map(//, [1 2; 3 4], [4 3; 2 1])
+ 33
source
map(f, A::AbstractArray...) -> N-array

When acting on multi-dimensional arrays of the same ndims, they must all have the same axes, and the answer will too.

See also broadcast, which allows mismatched sizes.

Examples

julia> map(//, [1 2; 3 4], [4 3; 2 1])
 2×2 Matrix{Rational{Int64}}:
  1//4  2//3
  3//2  4//1
@@ -808,7 +808,7 @@
 3-element Vector{Float64}:
    2.0
   13.0
- 102.0
source
Base.map!Function
map!(function, destination, collection...)

Like map, but stores the result in destination rather than a new collection. destination must be at least as large as the smallest collection.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also: map, foreach, zip, copyto!.

Examples

julia> a = zeros(3);
+ 102.0
source
Base.map!Function
map!(function, destination, collection...)

Like map, but stores the result in destination rather than a new collection. destination must be at least as large as the smallest collection.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

See also: map, foreach, zip, copyto!.

Examples

julia> a = zeros(3);
 
 julia> map!(x -> x * 2, a, [1, 2, 3]);
 
@@ -824,7 +824,7 @@
  103
  105
    0
-   0
source
map!(f, values(dict::AbstractDict))

Modifies dict by transforming each value from val to f(val). Note that the type of dict cannot be changed: if f(val) is not an instance of the value type of dict then it will be converted to the value type if possible and otherwise raise an error.

Julia 1.2

map!(f, values(dict::AbstractDict)) requires Julia 1.2 or later.

Examples

julia> d = Dict(:a => 1, :b => 2)
+   0
source
map!(f, values(dict::AbstractDict))

Modifies dict by transforming each value from val to f(val). Note that the type of dict cannot be changed: if f(val) is not an instance of the value type of dict then it will be converted to the value type if possible and otherwise raise an error.

Julia 1.2

map!(f, values(dict::AbstractDict)) requires Julia 1.2 or later.

Examples

julia> d = Dict(:a => 1, :b => 2)
 Dict{Symbol, Int64} with 2 entries:
   :a => 1
   :b => 2
@@ -832,12 +832,12 @@
 julia> map!(v -> v-1, values(d))
 ValueIterator for a Dict{Symbol, Int64} with 2 entries. Values:
   0
-  1
source
Base.mapreduceMethod
mapreduce(f, op, itrs...; [init])

Apply function f to each element(s) in itrs, and then reduce the result using the binary function op. If provided, init must be a neutral element for op that will be returned for empty collections. It is unspecified whether init is used for non-empty collections. In general, it will be necessary to provide init to work with empty collections.

mapreduce is functionally equivalent to calling reduce(op, map(f, itr); init=init), but will in general execute faster since no intermediate collection needs to be created. See documentation for reduce and map.

Julia 1.2

mapreduce with multiple iterators requires Julia 1.2 or later.

Examples

julia> mapreduce(x->x^2, +, [1:3;]) # == 1 + 4 + 9
-14

The associativity of the reduction is implementation-dependent. Additionally, some implementations may reuse the return value of f for elements that appear multiple times in itr. Use mapfoldl or mapfoldr instead for guaranteed left or right associativity and invocation of f for every value.

source
Base.mapfoldlMethod
mapfoldl(f, op, itr; [init])

Like mapreduce, but with guaranteed left associativity, as in foldl. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.

source
Base.mapfoldrMethod
mapfoldr(f, op, itr; [init])

Like mapreduce, but with guaranteed right associativity, as in foldr. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.

source
Base.mapreduceMethod
mapreduce(f, op, itrs...; [init])

Apply function f to each element(s) in itrs, and then reduce the result using the binary function op. If provided, init must be a neutral element for op that will be returned for empty collections. It is unspecified whether init is used for non-empty collections. In general, it will be necessary to provide init to work with empty collections.

mapreduce is functionally equivalent to calling reduce(op, map(f, itr); init=init), but will in general execute faster since no intermediate collection needs to be created. See documentation for reduce and map.

Julia 1.2

mapreduce with multiple iterators requires Julia 1.2 or later.

Examples

julia> mapreduce(x->x^2, +, [1:3;]) # == 1 + 4 + 9
+14

The associativity of the reduction is implementation-dependent. Additionally, some implementations may reuse the return value of f for elements that appear multiple times in itr. Use mapfoldl or mapfoldr instead for guaranteed left or right associativity and invocation of f for every value.

source
Base.mapfoldlMethod
mapfoldl(f, op, itr; [init])

Like mapreduce, but with guaranteed left associativity, as in foldl. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.

source
Base.mapfoldrMethod
mapfoldr(f, op, itr; [init])

Like mapreduce, but with guaranteed right associativity, as in foldr. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.

source
Base.firstFunction
first(coll)

Get the first element of an iterable collection. Return the start point of an AbstractRange even if it is empty.

See also: only, firstindex, last.

Examples

julia> first(2:2:10)
 2
 
 julia> first([1; 2; 3; 4])
-1
source
first(itr, n::Integer)

Get the first n elements of the iterable collection itr, or fewer elements if itr is not long enough.

See also: startswith, Iterators.take.

Julia 1.6

This method requires at least Julia 1.6.

Examples

julia> first(["foo", "bar", "qux"], 2)
+1
source
first(itr, n::Integer)

Get the first n elements of the iterable collection itr, or fewer elements if itr is not long enough.

See also: startswith, Iterators.take.

Julia 1.6

This method requires at least Julia 1.6.

Examples

julia> first(["foo", "bar", "qux"], 2)
 2-element Vector{String}:
  "foo"
  "bar"
@@ -846,18 +846,18 @@
 1:6
 
 julia> first(Bool[], 1)
-Bool[]
source
first(s::AbstractString, n::Integer)

Get a string consisting of the first n characters of s.

Examples

julia> first("∀ϵ≠0: ϵ²>0", 0)
+Bool[]
source
first(s::AbstractString, n::Integer)

Get a string consisting of the first n characters of s.

Examples

julia> first("∀ϵ≠0: ϵ²>0", 0)
 ""
 
 julia> first("∀ϵ≠0: ϵ²>0", 1)
 "∀"
 
 julia> first("∀ϵ≠0: ϵ²>0", 3)
-"∀ϵ≠"
source
Base.lastFunction
last(coll)

Get the last element of an ordered collection, if it can be computed in O(1) time. This is accomplished by calling lastindex to get the last index. Return the end point of an AbstractRange even if it is empty.

See also first, endswith.

Examples

julia> last(1:2:10)
+"∀ϵ≠"
source
Base.lastFunction
last(coll)

Get the last element of an ordered collection, if it can be computed in O(1) time. This is accomplished by calling lastindex to get the last index. Return the end point of an AbstractRange even if it is empty.

See also first, endswith.

Examples

julia> last(1:2:10)
 9
 
 julia> last([1; 2; 3; 4])
-4
source
last(itr, n::Integer)

Get the last n elements of the iterable collection itr, or fewer elements if itr is not long enough.

Julia 1.6

This method requires at least Julia 1.6.

Examples

julia> last(["foo", "bar", "qux"], 2)
+4
source
last(itr, n::Integer)

Get the last n elements of the iterable collection itr, or fewer elements if itr is not long enough.

Julia 1.6

This method requires at least Julia 1.6.

Examples

julia> last(["foo", "bar", "qux"], 2)
 2-element Vector{String}:
  "bar"
  "qux"
@@ -866,22 +866,22 @@
 1:6
 
 julia> last(Float64[], 1)
-Float64[]
source
last(s::AbstractString, n::Integer)

Get a string consisting of the last n characters of s.

Examples

julia> last("∀ϵ≠0: ϵ²>0", 0)
+Float64[]
source
last(s::AbstractString, n::Integer)

Get a string consisting of the last n characters of s.

Examples

julia> last("∀ϵ≠0: ϵ²>0", 0)
 ""
 
 julia> last("∀ϵ≠0: ϵ²>0", 1)
 "0"
 
 julia> last("∀ϵ≠0: ϵ²>0", 3)
-"²>0"
source
Base.frontFunction
front(x::Tuple)::Tuple

Return a Tuple consisting of all but the last component of x.

See also: first, tail.

Examples

julia> Base.front((1,2,3))
+"²>0"
source
Base.frontFunction
front(x::Tuple)::Tuple

Return a Tuple consisting of all but the last component of x.

See also: first, tail.

Examples

julia> Base.front((1,2,3))
 (1, 2)
 
 julia> Base.front(())
-ERROR: ArgumentError: Cannot call front on an empty tuple.
source
Base.tailFunction
tail(x::Tuple)::Tuple

Return a Tuple consisting of all but the first component of x.

See also: front, rest, first, Iterators.peel.

Examples

julia> Base.tail((1,2,3))
+ERROR: ArgumentError: Cannot call front on an empty tuple.
source
Base.tailFunction
tail(x::Tuple)::Tuple

Return a Tuple consisting of all but the first component of x.

See also: front, rest, first, Iterators.peel.

Examples

julia> Base.tail((1,2,3))
 (2, 3)
 
 julia> Base.tail(())
-ERROR: ArgumentError: Cannot call tail on an empty tuple.
source
Base.stepFunction
step(r)

Get the step size of an AbstractRange object.

Examples

julia> step(1:10)
+ERROR: ArgumentError: Cannot call tail on an empty tuple.
source
Base.stepFunction
step(r)

Get the step size of an AbstractRange object.

Examples

julia> step(1:10)
 1
 
 julia> step(1:2:10)
@@ -891,7 +891,7 @@
 0.3
 
 julia> step(range(2.5, stop=10.9, length=85))
-0.1
source
Base.collectMethod
collect(collection)

Return an Array of all items in a collection or iterator. For dictionaries, returns a Vector of key=>value Pairs. If the argument is array-like or is an iterator with the HasShape trait, the result will have the same shape and number of dimensions as the argument.

Used by comprehensions to turn a generator expression into an Array. Thus, on generators, the square-brackets notation may be used instead of calling collect, see second example.

Examples

Collect items from a UnitRange{Int64} collection:

julia> collect(1:3)
+0.1
source
Base.collectMethod
collect(collection)

Return an Array of all items in a collection or iterator. For dictionaries, returns a Vector of key=>value Pairs. If the argument is array-like or is an iterator with the HasShape trait, the result will have the same shape and number of dimensions as the argument.

Used by comprehensions to turn a generator expression into an Array. Thus, on generators, the square-brackets notation may be used instead of calling collect, see second example.

Examples

Collect items from a UnitRange{Int64} collection:

julia> collect(1:3)
 3-element Vector{Int64}:
  1
  2
@@ -899,11 +899,11 @@
 3-element Vector{Int64}:
  1
  4
- 9
source
Base.collectMethod
collect(element_type, collection)

Return an Array with the given element type of all items in a collection or iterable. The result has the same shape and number of dimensions as collection.

Examples

julia> collect(Float64, 1:2:5)
+ 9
source
Base.collectMethod
collect(element_type, collection)

Return an Array with the given element type of all items in a collection or iterable. The result has the same shape and number of dimensions as collection.

Examples

julia> collect(Float64, 1:2:5)
 3-element Vector{Float64}:
  1.0
  3.0
- 5.0
source
Base.filterFunction
filter(f, a)

Return a copy of collection a, removing elements for which f is false. The function f is passed one argument.

Julia 1.4

Support for a as a tuple requires at least Julia 1.4.

See also: filter!, Iterators.filter.

Examples

julia> a = 1:10
+ 5.0
source
Base.filterFunction
filter(f, a)

Return a copy of collection a, removing elements for which f is false. The function f is passed one argument.

Julia 1.4

Support for a as a tuple requires at least Julia 1.4.

See also: filter!, Iterators.filter.

Examples

julia> a = 1:10
 1:10
 
 julia> filter(isodd, a)
@@ -912,34 +912,34 @@
  3
  5
  7
- 9
source
filter(f)

Create a function that filters its arguments with function f using filter, i.e. a function equivalent to x -> filter(f, x).

The returned function is of type Base.Fix1{typeof(filter)}, which can be used to implement specialized methods.

Examples

julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
+ 9
source
filter(f)

Create a function that filters its arguments with function f using filter, i.e. a function equivalent to x -> filter(f, x).

The returned function is of type Base.Fix1{typeof(filter)}, which can be used to implement specialized methods.

Examples

julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
 (1, 2, 4, 6)
 
 julia> map(filter(iseven), [1:3, 2:4, 3:5])
 3-element Vector{Vector{Int64}}:
  [2]
  [2, 4]
- [4]
Julia 1.9

This method requires at least Julia 1.9.

source
filter(f, d::AbstractDict)

Return a copy of d, removing elements for which f is false. The function f is passed key=>value pairs.

Examples

julia> d = Dict(1=>"a", 2=>"b")
+ [4]
Julia 1.9

This method requires at least Julia 1.9.

source
filter(f, d::AbstractDict)

Return a copy of d, removing elements for which f is false. The function f is passed key=>value pairs.

Examples

julia> d = Dict(1=>"a", 2=>"b")
 Dict{Int64, String} with 2 entries:
   2 => "b"
   1 => "a"
 
 julia> filter(p->isodd(p.first), d)
 Dict{Int64, String} with 1 entry:
-  1 => "a"
source
filter(f, itr::SkipMissing{<:AbstractArray})

Return a vector similar to the array wrapped by the given SkipMissing iterator but with all missing elements and those for which f returns false removed.

Julia 1.2

This method requires Julia 1.2 or later.

Examples

julia> x = [1 2; missing 4]
+  1 => "a"
source
filter(f, itr::SkipMissing{<:AbstractArray})

Return a vector similar to the array wrapped by the given SkipMissing iterator but with all missing elements and those for which f returns false removed.

Julia 1.2

This method requires Julia 1.2 or later.

Examples

julia> x = [1 2; missing 4]
 2×2 Matrix{Union{Missing, Int64}}:
  1         2
   missing  4
 
 julia> filter(isodd, skipmissing(x))
 1-element Vector{Int64}:
- 1
source
Base.filter!Function
filter!(f, a)

Update collection a, removing elements for which f is false. The function f is passed one argument.

Examples

julia> filter!(isodd, Vector(1:10))
+ 1
source
Base.filter!Function
filter!(f, a)

Update collection a, removing elements for which f is false. The function f is passed one argument.

Examples

julia> filter!(isodd, Vector(1:10))
 5-element Vector{Int64}:
  1
  3
  5
  7
- 9
source
filter!(f, d::AbstractDict)

Update d, removing elements for which f is false. The function f is passed key=>value pairs.

Examples

julia> d = Dict(1=>"a", 2=>"b", 3=>"c")
+ 9
source
filter!(f, d::AbstractDict)

Update d, removing elements for which f is false. The function f is passed key=>value pairs.

Examples

julia> d = Dict(1=>"a", 2=>"b", 3=>"c")
 Dict{Int64, String} with 3 entries:
   2 => "b"
   3 => "c"
@@ -948,7 +948,7 @@
 julia> filter!(p->isodd(p.first), d)
 Dict{Int64, String} with 2 entries:
   3 => "c"
-  1 => "a"
source
Base.replaceMethod
replace(A, old_new::Pair...; [count::Integer])

Return a copy of collection A where, for each pair old=>new in old_new, all occurrences of old are replaced by new. Equality is determined using isequal. If count is specified, then replace at most count occurrences in total.

The element type of the result is chosen using promotion (see promote_type) based on the element type of A and on the types of the new values in pairs. If count is omitted and the element type of A is a Union, the element type of the result will not include singleton types which are replaced with values of a different type: for example, Union{T,Missing} will become T if missing is replaced.

See also replace!, splice!, delete!, insert!.

Julia 1.7

Version 1.7 is required to replace elements of a Tuple.

Examples

julia> replace([1, 2, 1, 3], 1=>0, 2=>4, count=2)
+  1 => "a"
source
Base.replaceMethod
replace(A, old_new::Pair...; [count::Integer])

Return a copy of collection A where, for each pair old=>new in old_new, all occurrences of old are replaced by new. Equality is determined using isequal. If count is specified, then replace at most count occurrences in total.

The element type of the result is chosen using promotion (see promote_type) based on the element type of A and on the types of the new values in pairs. If count is omitted and the element type of A is a Union, the element type of the result will not include singleton types which are replaced with values of a different type: for example, Union{T,Missing} will become T if missing is replaced.

See also replace!, splice!, delete!, insert!.

Julia 1.7

Version 1.7 is required to replace elements of a Tuple.

Examples

julia> replace([1, 2, 1, 3], 1=>0, 2=>4, count=2)
 4-element Vector{Int64}:
  0
  4
@@ -958,7 +958,7 @@
 julia> replace([1, missing], missing=>0)
 2-element Vector{Int64}:
  1
- 0
source
Base.replaceMethod
replace(new::Union{Function, Type}, A; [count::Integer])

Return a copy of A where each value x in A is replaced by new(x). If count is specified, then replace at most count values in total (replacements being defined as new(x) !== x).

Julia 1.7

Version 1.7 is required to replace elements of a Tuple.

Examples

julia> replace(x -> isodd(x) ? 2x : x, [1, 2, 3, 4])
+ 0
source
Base.replaceMethod
replace(new::Union{Function, Type}, A; [count::Integer])

Return a copy of A where each value x in A is replaced by new(x). If count is specified, then replace at most count values in total (replacements being defined as new(x) !== x).

Julia 1.7

Version 1.7 is required to replace elements of a Tuple.

Examples

julia> replace(x -> isodd(x) ? 2x : x, [1, 2, 3, 4])
 4-element Vector{Int64}:
  2
  2
@@ -970,7 +970,7 @@
        end
 Dict{Int64, Int64} with 2 entries:
   3 => 4
-  1 => 3
source
Base.replace!Function
replace!(A, old_new::Pair...; [count::Integer])

For each pair old=>new in old_new, replace all occurrences of old in collection A by new. Equality is determined using isequal. If count is specified, then replace at most count occurrences in total. See also replace.

Examples

julia> replace!([1, 2, 1, 3], 1=>0, 2=>4, count=2)
+  1 => 3
source
Base.replace!Function
replace!(A, old_new::Pair...; [count::Integer])

For each pair old=>new in old_new, replace all occurrences of old in collection A by new. Equality is determined using isequal. If count is specified, then replace at most count occurrences in total. See also replace.

Examples

julia> replace!([1, 2, 1, 3], 1=>0, 2=>4, count=2)
 4-element Vector{Int64}:
  0
  4
@@ -981,7 +981,7 @@
 Set{Int64} with 3 elements:
   0
   2
-  3
source
replace!(new::Union{Function, Type}, A; [count::Integer])

Replace each element x in collection A by new(x). If count is specified, then replace at most count values in total (replacements being defined as new(x) !== x).

Examples

julia> replace!(x -> isodd(x) ? 2x : x, [1, 2, 3, 4])
+  3
source
replace!(new::Union{Function, Type}, A; [count::Integer])

Replace each element x in collection A by new(x). If count is specified, then replace at most count values in total (replacements being defined as new(x) !== x).

Examples

julia> replace!(x -> isodd(x) ? 2x : x, [1, 2, 3, 4])
 4-element Vector{Int64}:
  2
  2
@@ -998,7 +998,7 @@
 julia> replace!(x->2x, Set([3, 6]))
 Set{Int64} with 2 elements:
   6
-  12
source
Base.restFunction
Base.rest(collection[, itr_state])

Generic function for taking the tail of collection, starting from a specific iteration state itr_state. Return a Tuple, if collection itself is a Tuple, a subtype of AbstractVector, if collection is an AbstractArray, a subtype of AbstractString if collection is an AbstractString, and an arbitrary iterator, falling back to Iterators.rest(collection[, itr_state]), otherwise.

Can be overloaded for user-defined collection types to customize the behavior of slurping in assignments in final position, like a, b... = collection.

Julia 1.6

Base.rest requires at least Julia 1.6.

See also: first, Iterators.rest, Base.split_rest.

Examples

julia> a = [1 2; 3 4]
+  12
source
Base.restFunction
Base.rest(collection[, itr_state])

Generic function for taking the tail of collection, starting from a specific iteration state itr_state. Return a Tuple, if collection itself is a Tuple, a subtype of AbstractVector, if collection is an AbstractArray, a subtype of AbstractString if collection is an AbstractString, and an arbitrary iterator, falling back to Iterators.rest(collection[, itr_state]), otherwise.

Can be overloaded for user-defined collection types to customize the behavior of slurping in assignments in final position, like a, b... = collection.

Julia 1.6

Base.rest requires at least Julia 1.6.

See also: first, Iterators.rest, Base.split_rest.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1007,7 +1007,7 @@
 (1, 2)
 
 julia> first, Base.rest(a, state)
-(1, [3, 2, 4])
source
Base.split_restFunction
Base.split_rest(collection, n::Int[, itr_state]) -> (rest_but_n, last_n)

Generic function for splitting the tail of collection, starting from a specific iteration state itr_state. Returns a tuple of two new collections. The first one contains all elements of the tail but the n last ones, which make up the second collection.

The type of the first collection generally follows that of Base.rest, except that the fallback case is not lazy, but is collected eagerly into a vector.

Can be overloaded for user-defined collection types to customize the behavior of slurping in assignments in non-final position, like a, b..., c = collection.

Julia 1.9

Base.split_rest requires at least Julia 1.9.

See also: Base.rest.

Examples

julia> a = [1 2; 3 4]
+(1, [3, 2, 4])
source
Base.split_restFunction
Base.split_rest(collection, n::Int[, itr_state]) -> (rest_but_n, last_n)

Generic function for splitting the tail of collection, starting from a specific iteration state itr_state. Returns a tuple of two new collections. The first one contains all elements of the tail but the n last ones, which make up the second collection.

The type of the first collection generally follows that of Base.rest, except that the fallback case is not lazy, but is collected eagerly into a vector.

Can be overloaded for user-defined collection types to customize the behavior of slurping in assignments in non-final position, like a, b..., c = collection.

Julia 1.9

Base.split_rest requires at least Julia 1.9.

See also: Base.rest.

Examples

julia> a = [1 2; 3 4]
 2×2 Matrix{Int64}:
  1  2
  3  4
@@ -1016,36 +1016,36 @@
 (1, 2)
 
 julia> first, Base.split_rest(a, 1, state)
-(1, ([3, 2], [4]))
source

Indexable Collections

Base.getindexFunction
getindex(collection, key...)

Retrieve the value(s) stored at the given key or index within a collection. The syntax a[i,j,...] is converted by the compiler to getindex(a, i, j, ...).

See also get, keys, eachindex.

Examples

julia> A = Dict("a" => 1, "b" => 2)
+(1, ([3, 2], [4]))
source

Indexable Collections

Base.getindexFunction
getindex(collection, key...)

Retrieve the value(s) stored at the given key or index within a collection. The syntax a[i,j,...] is converted by the compiler to getindex(a, i, j, ...).

See also get, keys, eachindex.

Examples

julia> A = Dict("a" => 1, "b" => 2)
 Dict{String, Int64} with 2 entries:
   "b" => 2
   "a" => 1
 
 julia> getindex(A, "a")
-1
source
Base.setindex!Function
setindex!(collection, value, key...)

Store the given value at the given key or index within a collection. The syntax a[i,j,...] = x is converted by the compiler to (setindex!(a, x, i, j, ...); x).

Examples

julia> a = Dict("a"=>1)
+1
source
Base.setindex!Function
setindex!(collection, value, key...)

Store the given value at the given key or index within a collection. The syntax a[i,j,...] = x is converted by the compiler to (setindex!(a, x, i, j, ...); x).

Examples

julia> a = Dict("a"=>1)
 Dict{String, Int64} with 1 entry:
   "a" => 1
 
 julia> setindex!(a, 2, "b")
 Dict{String, Int64} with 2 entries:
   "b" => 2
-  "a" => 1
source
Base.firstindexFunction
firstindex(collection) -> Integer
 firstindex(collection, d) -> Integer

Return the first index of collection. If d is given, return the first index of collection along dimension d.

The syntaxes A[begin] and A[1, begin] lower to A[firstindex(A)] and A[1, firstindex(A, 2)], respectively.

See also: first, axes, lastindex, nextind.

Examples

julia> firstindex([1,2,4])
 1
 
 julia> firstindex(rand(3,4,5), 2)
-1
source
Base.lastindexFunction
lastindex(collection) -> Integer
 lastindex(collection, d) -> Integer

Return the last index of collection. If d is given, return the last index of collection along dimension d.

The syntaxes A[end] and A[end, end] lower to A[lastindex(A)] and A[lastindex(A, 1), lastindex(A, 2)], respectively.

See also: axes, firstindex, eachindex, prevind.

Examples

julia> lastindex([1,2,4])
 3
 
 julia> lastindex(rand(3,4,5), 2)
-4
source

Fully implemented by:

Partially implemented by:

Dictionaries

Dict is the standard dictionary. Its implementation uses hash as the hashing function for the key, and isequal to determine equality. Define these two functions for custom types to override how they are stored in a hash table.

IdDict is a special hash table where the keys are always object identities.

WeakKeyDict is a hash table implementation where the keys are weak references to objects, and thus may be garbage collected even when referenced in a hash table. Like Dict it uses hash for hashing and isequal for equality, unlike Dict it does not convert keys on insertion.

Dicts can be created by passing pair objects constructed with => to a Dict constructor: Dict("A"=>1, "B"=>2). This call will attempt to infer type information from the keys and values (i.e. this example creates a Dict{String, Int64}). To explicitly specify types use the syntax Dict{KeyType,ValueType}(...). For example, Dict{String,Int32}("A"=>1, "B"=>2).

Dictionaries may also be created with generators. For example, Dict(i => f(i) for i = 1:10).

Given a dictionary D, the syntax D[x] returns the value of key x (if it exists) or throws an error, and D[x] = y stores the key-value pair x => y in D (replacing any existing value for the key x). Multiple arguments to D[...] are converted to tuples; for example, the syntax D[x,y] is equivalent to D[(x,y)], i.e. it refers to the value keyed by the tuple (x,y).

Base.AbstractDictType
AbstractDict{K, V}

Supertype for dictionary-like types with keys of type K and values of type V. Dict, IdDict and other types are subtypes of this. An AbstractDict{K, V} should be an iterator of Pair{K, V}.

source
Base.DictType
Dict([itr])

Dict{K,V}() constructs a hash table with keys of type K and values of type V. Keys are compared with isequal and hashed with hash.

Given a single iterable argument, constructs a Dict whose key-value pairs are taken from 2-tuples (key,value) generated by the argument.

Examples

julia> Dict([("A", 1), ("B", 2)])
+4
source

Fully implemented by:

Partially implemented by:

Dictionaries

Dict is the standard dictionary. Its implementation uses hash as the hashing function for the key, and isequal to determine equality. Define these two functions for custom types to override how they are stored in a hash table.

IdDict is a special hash table where the keys are always object identities.

WeakKeyDict is a hash table implementation where the keys are weak references to objects, and thus may be garbage collected even when referenced in a hash table. Like Dict it uses hash for hashing and isequal for equality, unlike Dict it does not convert keys on insertion.

Dicts can be created by passing pair objects constructed with => to a Dict constructor: Dict("A"=>1, "B"=>2). This call will attempt to infer type information from the keys and values (i.e. this example creates a Dict{String, Int64}). To explicitly specify types use the syntax Dict{KeyType,ValueType}(...). For example, Dict{String,Int32}("A"=>1, "B"=>2).

Dictionaries may also be created with generators. For example, Dict(i => f(i) for i = 1:10).

Given a dictionary D, the syntax D[x] returns the value of key x (if it exists) or throws an error, and D[x] = y stores the key-value pair x => y in D (replacing any existing value for the key x). Multiple arguments to D[...] are converted to tuples; for example, the syntax D[x,y] is equivalent to D[(x,y)], i.e. it refers to the value keyed by the tuple (x,y).

Base.AbstractDictType
AbstractDict{K, V}

Supertype for dictionary-like types with keys of type K and values of type V. Dict, IdDict and other types are subtypes of this. An AbstractDict{K, V} should be an iterator of Pair{K, V}.

source
Base.DictType
Dict([itr])

Dict{K,V}() constructs a hash table with keys of type K and values of type V. Keys are compared with isequal and hashed with hash.

Given a single iterable argument, constructs a Dict whose key-value pairs are taken from 2-tuples (key,value) generated by the argument.

Examples

julia> Dict([("A", 1), ("B", 2)])
 Dict{String, Int64} with 2 entries:
   "B" => 2
   "A" => 1

Alternatively, a sequence of pair arguments may be passed.

julia> Dict("A"=>1, "B"=>2)
 Dict{String, Int64} with 2 entries:
   "B" => 2
-  "A" => 1
Warning

Keys are allowed to be mutable, but if you do mutate stored keys, the hash table may become internally inconsistent, in which case the Dict will not work properly. IdDict can be an alternative if you need to mutate keys.

source
Base.IdDictType
IdDict([itr])

IdDict{K,V}() constructs a hash table using objectid as hash and === as equality with keys of type K and values of type V. See Dict for further help and IdSet for the set version of this.

In the example below, the Dict keys are all isequal and therefore get hashed the same, so they get overwritten. The IdDict hashes by object-id, and thus preserves the 3 different keys.

Examples

julia> Dict(true => "yes", 1 => "no", 1.0 => "maybe")
+  "A" => 1
Warning

Keys are allowed to be mutable, but if you do mutate stored keys, the hash table may become internally inconsistent, in which case the Dict will not work properly. IdDict can be an alternative if you need to mutate keys.

source
Base.IdDictType
IdDict([itr])

IdDict{K,V}() constructs a hash table using objectid as hash and === as equality with keys of type K and values of type V. See Dict for further help and IdSet for the set version of this.

In the example below, the Dict keys are all isequal and therefore get hashed the same, so they get overwritten. The IdDict hashes by object-id, and thus preserves the 3 different keys.

Examples

julia> Dict(true => "yes", 1 => "no", 1.0 => "maybe")
 Dict{Real, String} with 1 entry:
   1.0 => "maybe"
 
@@ -1053,7 +1053,7 @@
 IdDict{Any, String} with 3 entries:
   true => "yes"
   1.0  => "maybe"
-  1    => "no"
source
Base.WeakKeyDictType
WeakKeyDict([itr])

WeakKeyDict() constructs a hash table where the keys are weak references to objects which may be garbage collected even when referenced in a hash table.

See Dict for further help. Note, unlike Dict, WeakKeyDict does not convert keys on insertion, as this would imply the key object was unreferenced anywhere before insertion.

See also WeakRef.

source
Base.ImmutableDictType
ImmutableDict

ImmutableDict is a dictionary implemented as an immutable linked list, which is optimal for small dictionaries that are constructed over many individual insertions. Note that it is not possible to remove a value, although it can be partially overridden and hidden by inserting a new value with the same key.

ImmutableDict(KV::Pair)

Create a new entry in the ImmutableDict for a key => value pair

  • use (key => value) in dict to see if this particular combination is in the properties set
  • use get(dict, key, default) to retrieve the most recent value for a particular key
source
Base.PersistentDictType
PersistentDict

PersistentDict is a dictionary implemented as an hash array mapped trie, which is optimal for situations where you need persistence, each operation returns a new dictionary separate from the previous one, but the underlying implementation is space-efficient and may share storage across multiple separate dictionaries.

Note

It behaves like an IdDict.

PersistentDict(KV::Pair)

Examples

julia> dict = Base.PersistentDict(:a=>1)
+  1    => "no"
source
Base.WeakKeyDictType
WeakKeyDict([itr])

WeakKeyDict() constructs a hash table where the keys are weak references to objects which may be garbage collected even when referenced in a hash table.

See Dict for further help. Note, unlike Dict, WeakKeyDict does not convert keys on insertion, as this would imply the key object was unreferenced anywhere before insertion.

See also WeakRef.

source
Base.ImmutableDictType
ImmutableDict

ImmutableDict is a dictionary implemented as an immutable linked list, which is optimal for small dictionaries that are constructed over many individual insertions. Note that it is not possible to remove a value, although it can be partially overridden and hidden by inserting a new value with the same key.

ImmutableDict(KV::Pair)

Create a new entry in the ImmutableDict for a key => value pair

  • use (key => value) in dict to see if this particular combination is in the properties set
  • use get(dict, key, default) to retrieve the most recent value for a particular key
source
Base.PersistentDictType
PersistentDict

PersistentDict is a dictionary implemented as an hash array mapped trie, which is optimal for situations where you need persistence, each operation returns a new dictionary separate from the previous one, but the underlying implementation is space-efficient and may share storage across multiple separate dictionaries.

Note

It behaves like an IdDict.

PersistentDict(KV::Pair)

Examples

julia> dict = Base.PersistentDict(:a=>1)
 Base.PersistentDict{Symbol, Int64} with 1 entry:
   :a => 1
 
@@ -1062,7 +1062,7 @@
 
 julia> dict3 = Base.PersistentDict(dict, :a=>2)
 Base.PersistentDict{Symbol, Int64} with 1 entry:
-  :a => 2
source
Base.haskeyFunction
haskey(collection, key) -> Bool

Determine whether a collection has a mapping for a given key.

Examples

julia> D = Dict('a'=>2, 'b'=>3)
+  :a => 2
source
Base.haskeyFunction
haskey(collection, key) -> Bool

Determine whether a collection has a mapping for a given key.

Examples

julia> D = Dict('a'=>2, 'b'=>3)
 Dict{Char, Int64} with 2 entries:
   'a' => 2
   'b' => 3
@@ -1071,16 +1071,16 @@
 true
 
 julia> haskey(D, 'c')
-false
source
Base.getFunction
get(collection, key, default)

Return the value stored for the given key, or the given default value if no mapping for the key is present.

Julia 1.7

For tuples and numbers, this function requires at least Julia 1.7.

Examples

julia> d = Dict("a"=>1, "b"=>2);
+false
source
Base.getFunction
get(collection, key, default)

Return the value stored for the given key, or the given default value if no mapping for the key is present.

Julia 1.7

For tuples and numbers, this function requires at least Julia 1.7.

Examples

julia> d = Dict("a"=>1, "b"=>2);
 
 julia> get(d, "a", 3)
 1
 
 julia> get(d, "c", 3)
-3
source
get(f::Union{Function, Type}, collection, key)

Return the value stored for the given key, or if no mapping for the key is present, return f(). Use get! to also store the default value in the dictionary.

This is intended to be called using do block syntax

get(dict, key) do
+3
source
get(f::Union{Function, Type}, collection, key)

Return the value stored for the given key, or if no mapping for the key is present, return f(). Use get! to also store the default value in the dictionary.

This is intended to be called using do block syntax

get(dict, key) do
     # default value calculated here
     time()
-end
source
Base.get!Function
get!(collection, key, default)

Return the value stored for the given key, or if no mapping for the key is present, store key => default, and return default.

Examples

julia> d = Dict("a"=>1, "b"=>2, "c"=>3);
+end
source
Base.get!Function
get!(collection, key, default)

Return the value stored for the given key, or if no mapping for the key is present, store key => default, and return default.

Examples

julia> d = Dict("a"=>1, "b"=>2, "c"=>3);
 
 julia> get!(d, "a", 5)
 1
@@ -1093,7 +1093,7 @@
   "c" => 3
   "b" => 2
   "a" => 1
-  "d" => 4
source
get!(f::Union{Function, Type}, collection, key)

Return the value stored for the given key, or if no mapping for the key is present, store key => f(), and return f().

This is intended to be called using do block syntax.

Examples

julia> squares = Dict{Int, Int}();
+  "d" => 4
source
get!(f::Union{Function, Type}, collection, key)

Return the value stored for the given key, or if no mapping for the key is present, store key => f(), and return f().

This is intended to be called using do block syntax.

Examples

julia> squares = Dict{Int, Int}();
 
 julia> function get_square!(d, i)
            get!(d, i) do
@@ -1107,7 +1107,7 @@
 
 julia> squares
 Dict{Int64, Int64} with 1 entry:
-  2 => 4
source
Base.getkeyFunction
getkey(collection, key, default)

Return the key matching argument key if one exists in collection, otherwise return default.

Examples

julia> D = Dict('a'=>2, 'b'=>3)
+  2 => 4
source
Base.getkeyFunction
getkey(collection, key, default)

Return the key matching argument key if one exists in collection, otherwise return default.

Examples

julia> D = Dict('a'=>2, 'b'=>3)
 Dict{Char, Int64} with 2 entries:
   'a' => 2
   'b' => 3
@@ -1116,7 +1116,7 @@
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
 
 julia> getkey(D, 'd', 'a')
-'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
source
Base.delete!Function
delete!(collection, key)

Delete the mapping for the given key in a collection, if any, and return the collection.

Examples

julia> d = Dict("a"=>1, "b"=>2)
+'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
source
Base.delete!Function
delete!(collection, key)

Delete the mapping for the given key in a collection, if any, and return the collection.

Examples

julia> d = Dict("a"=>1, "b"=>2)
 Dict{String, Int64} with 2 entries:
   "b" => 2
   "a" => 1
@@ -1127,7 +1127,7 @@
 
 julia> delete!(d, "b") # d is left unchanged
 Dict{String, Int64} with 1 entry:
-  "a" => 1
source
Base.pop!Method
pop!(collection, key[, default])

Delete and return the mapping for key if it exists in collection, otherwise return default, or throw an error if default is not specified.

Examples

julia> d = Dict("a"=>1, "b"=>2, "c"=>3);
+  "a" => 1
source
Base.pop!Method
pop!(collection, key[, default])

Delete and return the mapping for key if it exists in collection, otherwise return default, or throw an error if default is not specified.

Examples

julia> d = Dict("a"=>1, "b"=>2, "c"=>3);
 
 julia> pop!(d, "a")
 1
@@ -1138,7 +1138,7 @@
 [...]
 
 julia> pop!(d, "e", 4)
-4
source
Base.keysFunction
keys(iterator)

For an iterator or collection that has keys and values (e.g. arrays and dictionaries), return an iterator over the keys.

source
Base.valuesFunction
values(iterator)

For an iterator or collection that has keys and values, return an iterator over the values. This function simply returns its argument by default, since the elements of a general iterator are normally considered its "values".

Examples

julia> d = Dict("a"=>1, "b"=>2);
+4
source
Base.keysFunction
keys(iterator)

For an iterator or collection that has keys and values (e.g. arrays and dictionaries), return an iterator over the keys.

source
Base.valuesFunction
values(iterator)

For an iterator or collection that has keys and values, return an iterator over the values. This function simply returns its argument by default, since the elements of a general iterator are normally considered its "values".

Examples

julia> d = Dict("a"=>1, "b"=>2);
 
 julia> values(d)
 ValueIterator for a Dict{String, Int64} with 2 entries. Values:
@@ -1147,7 +1147,7 @@
 
 julia> values([2])
 1-element Vector{Int64}:
- 2
source
values(a::AbstractDict)

Return an iterator over all values in a collection. collect(values(a)) returns an array of values. When the values are stored internally in a hash table, as is the case for Dict, the order in which they are returned may vary. But keys(a) and values(a) both iterate a and return the elements in the same order.

Examples

julia> D = Dict('a'=>2, 'b'=>3)
+ 2
source
values(a::AbstractDict)

Return an iterator over all values in a collection. collect(values(a)) returns an array of values. When the values are stored internally in a hash table, as is the case for Dict, the order in which they are returned may vary. But keys(a) and values(a) both iterate a and return the elements in the same order.

Examples

julia> D = Dict('a'=>2, 'b'=>3)
 Dict{Char, Int64} with 2 entries:
   'a' => 2
   'b' => 3
@@ -1155,7 +1155,7 @@
 julia> collect(values(D))
 2-element Vector{Int64}:
  2
- 3
source
Base.pairsFunction
pairs(IndexLinear(), A)
 pairs(IndexCartesian(), A)
 pairs(IndexStyle(A), A)

An iterator that accesses each element of the array A, returning i => x, where i is the index for the element and x = A[i]. Identical to pairs(A), except that the style of index can be selected. Also similar to enumerate(A), except i will be a valid index for A, while enumerate always counts from 1 regardless of the indices of A.

Specifying IndexLinear() ensures that i will be an integer; specifying IndexCartesian() ensures that i will be a Base.CartesianIndex; specifying IndexStyle(A) chooses whichever has been defined as the native indexing style for array A.

Mutation of the bounds of the underlying array will invalidate this iterator.

Examples

julia> A = ["a" "d"; "b" "e"; "c" "f"];
 
@@ -1177,7 +1177,7 @@
 CartesianIndex(1, 1) a
 CartesianIndex(2, 1) b
 CartesianIndex(1, 2) d
-CartesianIndex(2, 2) e

See also IndexStyle, axes.

source
pairs(collection)

Return an iterator over key => value pairs for any collection that maps a set of keys to a set of values. This includes arrays, where the keys are the array indices.

Examples

julia> a = Dict(zip(["a", "b", "c"], [1, 2, 3]))
+CartesianIndex(2, 2) e

See also IndexStyle, axes.

source
pairs(collection)

Return an iterator over key => value pairs for any collection that maps a set of keys to a set of values. This includes arrays, where the keys are the array indices.

Examples

julia> a = Dict(zip(["a", "b", "c"], [1, 2, 3]))
 Dict{String, Int64} with 3 entries:
   "c" => 3
   "b" => 2
@@ -1204,7 +1204,7 @@
 3-element Vector{Int64}:
  1
  2
- 3
source
Base.mergeFunction
merge(initial::Face, others::Face...)

Merge the properties of the initial face and others, with later faces taking priority.

merge(d::AbstractDict, others::AbstractDict...)

Construct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of the merged collections. If the same key is present in another collection, the value for that key will be the value it has in the last collection listed. See also mergewith for custom handling of values with the same key.

Examples

julia> a = Dict("foo" => 0.0, "bar" => 42.0)
+ 3
source
Base.mergeFunction
merge(initial::Face, others::Face...)

Merge the properties of the initial face and others, with later faces taking priority.

merge(d::AbstractDict, others::AbstractDict...)

Construct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of the merged collections. If the same key is present in another collection, the value for that key will be the value it has in the last collection listed. See also mergewith for custom handling of values with the same key.

Examples

julia> a = Dict("foo" => 0.0, "bar" => 42.0)
 Dict{String, Float64} with 2 entries:
   "bar" => 42.0
   "foo" => 0.0
@@ -1224,10 +1224,10 @@
 Dict{String, Float64} with 3 entries:
   "bar" => 42.0
   "baz" => 17.0
-  "foo" => 0.0
source
merge(a::NamedTuple, bs::NamedTuple...)

Construct a new named tuple by merging two or more existing ones, in a left-associative manner. Merging proceeds left-to-right, between pairs of named tuples, and so the order of fields present in both the leftmost and rightmost named tuples take the same position as they are found in the leftmost named tuple. However, values are taken from matching fields in the rightmost named tuple that contains that field. Fields present in only the rightmost named tuple of a pair are appended at the end. A fallback is implemented for when only a single named tuple is supplied, with signature merge(a::NamedTuple).

Julia 1.1

Merging 3 or more NamedTuple requires at least Julia 1.1.

Examples

julia> merge((a=1, b=2, c=3), (b=4, d=5))
+  "foo" => 0.0
source
merge(a::NamedTuple, bs::NamedTuple...)

Construct a new named tuple by merging two or more existing ones, in a left-associative manner. Merging proceeds left-to-right, between pairs of named tuples, and so the order of fields present in both the leftmost and rightmost named tuples take the same position as they are found in the leftmost named tuple. However, values are taken from matching fields in the rightmost named tuple that contains that field. Fields present in only the rightmost named tuple of a pair are appended at the end. A fallback is implemented for when only a single named tuple is supplied, with signature merge(a::NamedTuple).

Julia 1.1

Merging 3 or more NamedTuple requires at least Julia 1.1.

Examples

julia> merge((a=1, b=2, c=3), (b=4, d=5))
 (a = 1, b = 4, c = 3, d = 5)
julia> merge((a=1, b=2), (b=3, c=(d=1,)), (c=(d=2,),))
-(a = 1, b = 3, c = (d = 2,))
source
merge(a::NamedTuple, iterable)

Interpret an iterable of key-value pairs as a named tuple, and perform a merge.

julia> merge((a=1, b=2, c=3), [:b=>4, :d=>5])
-(a = 1, b = 4, c = 3, d = 5)
source
Base.mergewithFunction
mergewith(combine, d::AbstractDict, others::AbstractDict...)
+(a = 1, b = 3, c = (d = 2,))
source
merge(a::NamedTuple, iterable)

Interpret an iterable of key-value pairs as a named tuple, and perform a merge.

julia> merge((a=1, b=2, c=3), [:b=>4, :d=>5])
+(a = 1, b = 4, c = 3, d = 5)
source
Base.mergewithFunction
mergewith(combine, d::AbstractDict, others::AbstractDict...)
 mergewith(combine)
 merge(combine, d::AbstractDict, others::AbstractDict...)

Construct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of the merged collections. Values with the same key will be combined using the combiner function. The curried form mergewith(combine) returns the function (args...) -> mergewith(combine, args...).

Method merge(combine::Union{Function,Type}, args...) as an alias of mergewith(combine, args...) is still available for backward compatibility.

Julia 1.5

mergewith requires Julia 1.5 or later.

Examples

julia> a = Dict("foo" => 0.0, "bar" => 42.0)
 Dict{String, Float64} with 2 entries:
@@ -1246,7 +1246,7 @@
   "foo" => 0.0
 
 julia> ans == mergewith(+)(a, b)
-true
source
Base.merge!Function
merge!(d::AbstractDict, others::AbstractDict...)

Update collection with pairs from the other collections. See also merge.

Examples

julia> d1 = Dict(1 => 2, 3 => 4);
+true
source
Base.merge!Function
merge!(d::AbstractDict, others::AbstractDict...)

Update collection with pairs from the other collections. See also merge.

Examples

julia> d1 = Dict(1 => 2, 3 => 4);
 
 julia> d2 = Dict(1 => 4, 4 => 5);
 
@@ -1256,7 +1256,7 @@
 Dict{Int64, Int64} with 3 entries:
   4 => 5
   3 => 4
-  1 => 4
source
Base.mergewith!Function
mergewith!(combine, d::AbstractDict, others::AbstractDict...) -> d
+  1 => 4
source
Base.mergewith!Function
mergewith!(combine, d::AbstractDict, others::AbstractDict...) -> d
 mergewith!(combine)
 merge!(combine, d::AbstractDict, others::AbstractDict...) -> d

Update collection with pairs from the other collections. Values with the same key will be combined using the combiner function. The curried form mergewith!(combine) returns the function (args...) -> mergewith!(combine, args...).

Method merge!(combine::Union{Function,Type}, args...) as an alias of mergewith!(combine, args...) is still available for backward compatibility.

Julia 1.5

mergewith! requires Julia 1.5 or later.

Examples

julia> d1 = Dict(1 => 2, 3 => 4);
 
@@ -1282,16 +1282,16 @@
 Dict{Int64, Int64} with 3 entries:
   4 => 5
   3 => 0
-  1 => 4
source
Base.sizehint!Function
sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s

Suggest that collection s reserve capacity for at least n elements. That is, if you expect that you're going to have to push a lot of values onto s, you can avoid the cost of incremental reallocation by doing it once up front; this can improve performance.

If first is true, then any additional space is reserved before the start of the collection. This way, subsequent calls to pushfirst! (instead of push!) may become faster. Supplying this keyword may result in an error if the collection is not ordered or if pushfirst! is not supported for this collection.

If shrink=true (the default), the collection's capacity may be reduced if its current capacity is greater than n.

See also resize!.

Notes on the performance model

For types that support sizehint!,

  1. push! and append! methods generally may (but are not required to) preallocate extra storage. For types implemented in Base, they typically do, using a heuristic optimized for a general use case.

  2. sizehint! may control this preallocation. Again, it typically does this for types in Base.

  3. empty! is nearly costless (and O(1)) for types that support this kind of preallocation.

Julia 1.11

The shrink and first arguments were added in Julia 1.11.

source
Base.sizehint!Function
sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s

Suggest that collection s reserve capacity for at least n elements. That is, if you expect that you're going to have to push a lot of values onto s, you can avoid the cost of incremental reallocation by doing it once up front; this can improve performance.

If first is true, then any additional space is reserved before the start of the collection. This way, subsequent calls to pushfirst! (instead of push!) may become faster. Supplying this keyword may result in an error if the collection is not ordered or if pushfirst! is not supported for this collection.

If shrink=true (the default), the collection's capacity may be reduced if its current capacity is greater than n.

See also resize!.

Notes on the performance model

For types that support sizehint!,

  1. push! and append! methods generally may (but are not required to) preallocate extra storage. For types implemented in Base, they typically do, using a heuristic optimized for a general use case.

  2. sizehint! may control this preallocation. Again, it typically does this for types in Base.

  3. empty! is nearly costless (and O(1)) for types that support this kind of preallocation.

Julia 1.11

The shrink and first arguments were added in Julia 1.11.

source
Base.keytypeFunction
keytype(T::Type{<:AbstractArray})
 keytype(A::AbstractArray)

Return the key type of an array. This is equal to the eltype of the result of keys(...), and is provided mainly for compatibility with the dictionary interface.

Examples

julia> keytype([1, 2, 3]) == Int
 true
 
 julia> keytype([1 2; 3 4])
-CartesianIndex{2}
Julia 1.2

For arrays, this function requires at least Julia 1.2.

source
keytype(type)

Get the key type of a dictionary type. Behaves similarly to eltype.

Examples

julia> keytype(Dict(Int32(1) => "foo"))
-Int32
source
Base.valtypeFunction
valtype(T::Type{<:AbstractArray})
+CartesianIndex{2}
Julia 1.2

For arrays, this function requires at least Julia 1.2.

source
keytype(type)

Get the key type of a dictionary type. Behaves similarly to eltype.

Examples

julia> keytype(Dict(Int32(1) => "foo"))
+Int32
source
Base.valtypeFunction
valtype(T::Type{<:AbstractArray})
 valtype(A::AbstractArray)

Return the value type of an array. This is identical to eltype and is provided mainly for compatibility with the dictionary interface.

Examples

julia> valtype(["one", "two", "three"])
-String
Julia 1.2

For arrays, this function requires at least Julia 1.2.

source
valtype(type)

Get the value type of a dictionary type. Behaves similarly to eltype.

Examples

julia> valtype(Dict(Int32(1) => "foo"))
-String
source

Fully implemented by:

Partially implemented by:

Set-Like Collections

Base.SetType
Set{T} <: AbstractSet{T}

Sets are mutable containers that provide fast membership testing.

Sets have efficient implementations of set operations such as in, union and intersect. Elements in a Set are unique, as determined by the elements' definition of isequal. The order of elements in a Set is an implementation detail and cannot be relied on.

See also: AbstractSet, BitSet, Dict, push!, empty!, union!, in, isequal

Examples

julia> s = Set("aaBca")
+String
Julia 1.2

For arrays, this function requires at least Julia 1.2.

source
valtype(type)

Get the value type of a dictionary type. Behaves similarly to eltype.

Examples

julia> valtype(Dict(Int32(1) => "foo"))
+String
source

Fully implemented by:

Partially implemented by:

Set-Like Collections

Base.SetType
Set{T} <: AbstractSet{T}

Sets are mutable containers that provide fast membership testing.

Sets have efficient implementations of set operations such as in, union and intersect. Elements in a Set are unique, as determined by the elements' definition of isequal. The order of elements in a Set is an implementation detail and cannot be relied on.

See also: AbstractSet, BitSet, Dict, push!, empty!, union!, in, isequal

Examples

julia> s = Set("aaBca")
 Set{Char} with 3 elements:
   'a'
   'c'
@@ -1310,8 +1310,8 @@
 false
 
 julia> NaN in s # isequal(NaN, NaN) is true
-true
source
Base.BitSetType
BitSet([itr])

Construct a sorted set of Ints generated by the given iterable object, or an empty set. Implemented as a bit string, and therefore designed for dense integer sets. If the set will be sparse (for example, holding a few very large integers), use Set instead.

source
Base.IdSetType
IdSet{T}([itr])
-IdSet()

IdSet{T}() constructs a set (see Set) using === as equality with values of type V.

In the example below, the values are all isequal so they get overwritten. The IdSet compares by === so preserves the 3 different keys.

Examples ≡≡≡≡≡≡≡≡

julia> Set(Any[true, 1, 1.0]) Set{Any} with 1 element: 1.0

julia> IdSet{Any}(Any[true, 1, 1.0]) IdSet{Any} with 3 elements: 1.0 1 true

source
Base.BitSetType
BitSet([itr])

Construct a sorted set of Ints generated by the given iterable object, or an empty set. Implemented as a bit string, and therefore designed for dense integer sets. If the set will be sparse (for example, holding a few very large integers), use Set instead.

source
Base.IdSetType
IdSet{T}([itr])
+IdSet()

IdSet{T}() constructs a set (see Set) using === as equality with values of type V.

In the example below, the values are all isequal so they get overwritten. The IdSet compares by === so preserves the 3 different keys.

Examples ≡≡≡≡≡≡≡≡

julia> Set(Any[true, 1, 1.0]) Set{Any} with 1 element: 1.0

julia> IdSet{Any}(Any[true, 1, 1.0]) IdSet{Any} with 3 elements: 1.0 1 true

source
Base.unionFunction
union(s, itrs...)
 ∪(s, itrs...)

Construct an object containing all distinct elements from all of the arguments.

The first argument controls what kind of container is returned. If this is an array, it maintains the order in which elements first appear.

Unicode can be typed by writing \cup then pressing tab in the Julia REPL, and in many editors. This is an infix operator, allowing s ∪ itr.

See also unique, intersect, isdisjoint, vcat, Iterators.flatten.

Examples

julia> union([1, 2], [3])
 3-element Vector{Int64}:
  1
@@ -1335,7 +1335,7 @@
 Set{Int64} with 3 elements:
   2
   3
-  1
source
Base.union!Function
union!(s::Union{AbstractSet,AbstractVector}, itrs...)

Construct the union of passed in sets and overwrite s with the result. Maintain order with arrays.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> a = Set([3, 4, 5]);
+  1
source
Base.union!Function
union!(s::Union{AbstractSet,AbstractVector}, itrs...)

Construct the union of passed in sets and overwrite s with the result. Maintain order with arrays.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> a = Set([3, 4, 5]);
 
 julia> union!(a, 1:2:7);
 
@@ -1345,7 +1345,7 @@
   4
   7
   3
-  1
source
Base.intersectFunction
intersect(s, itrs...)
 ∩(s, itrs...)

Construct the set containing those elements which appear in all of the arguments.

The first argument controls what kind of container is returned. If this is an array, it maintains the order in which elements first appear.

Unicode can be typed by writing \cap then pressing tab in the Julia REPL, and in many editors. This is an infix operator, allowing s ∩ itr.

See also setdiff, isdisjoint, issubset, issetequal.

Julia 1.8

As of Julia 1.8 intersect returns a result with the eltype of the type-promoted eltypes of the two inputs

Examples

julia> intersect([1, 2, 3], [3, 4, 5])
 1-element Vector{Int64}:
  3
@@ -1364,23 +1364,23 @@
 
 julia> intersect(Set([1, 2]), BitSet([2, 3]), 1.0:10.0)
 Set{Float64} with 1 element:
-  2.0
source
Base.setdiffFunction
setdiff(s, itrs...)

Construct the set of elements in s but not in any of the iterables in itrs. Maintain order with arrays.

See also setdiff!, union and intersect.

Examples

julia> setdiff([1,2,3], [3,4,5])
+  2.0
source
Base.setdiffFunction
setdiff(s, itrs...)

Construct the set of elements in s but not in any of the iterables in itrs. Maintain order with arrays.

See also setdiff!, union and intersect.

Examples

julia> setdiff([1,2,3], [3,4,5])
 2-element Vector{Int64}:
  1
- 2
source
Base.setdiff!Function
setdiff!(s, itrs...)

Remove from set s (in-place) each element of each iterable from itrs. Maintain order with arrays.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> a = Set([1, 3, 4, 5]);
+ 2
source
Base.setdiff!Function
setdiff!(s, itrs...)

Remove from set s (in-place) each element of each iterable from itrs. Maintain order with arrays.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> a = Set([1, 3, 4, 5]);
 
 julia> setdiff!(a, 1:2:6);
 
 julia> a
 Set{Int64} with 1 element:
-  4
source
Base.symdiffFunction
symdiff(s, itrs...)

Construct the symmetric difference of elements in the passed in sets. When s is not an AbstractSet, the order is maintained.

See also symdiff!, setdiff, union and intersect.

Examples

julia> symdiff([1,2,3], [3,4,5], [4,5,6])
+  4
source
Base.symdiffFunction
symdiff(s, itrs...)

Construct the symmetric difference of elements in the passed in sets. When s is not an AbstractSet, the order is maintained.

See also symdiff!, setdiff, union and intersect.

Examples

julia> symdiff([1,2,3], [3,4,5], [4,5,6])
 3-element Vector{Int64}:
  1
  2
  6
 
 julia> symdiff([1,2,1], [2, 1, 2])
-Int64[]
source
Base.symdiff!Function
symdiff!(s::Union{AbstractSet,AbstractVector}, itrs...)

Construct the symmetric difference of the passed in sets, and overwrite s with the result. When s is an array, the order is maintained. Note that in this case the multiplicity of elements matters.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.intersect!Function
intersect!(s::Union{AbstractSet,AbstractVector}, itrs...)

Intersect all passed in sets and overwrite s with the result. Maintain order with arrays.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.symdiff!Function
symdiff!(s::Union{AbstractSet,AbstractVector}, itrs...)

Construct the symmetric difference of the passed in sets, and overwrite s with the result. When s is an array, the order is maintained. Note that in this case the multiplicity of elements matters.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.intersect!Function
intersect!(s::Union{AbstractSet,AbstractVector}, itrs...)

Intersect all passed in sets and overwrite s with the result. Maintain order with arrays.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.issubsetFunction
issubset(a, b) -> Bool
 ⊆(a, b) -> Bool
 ⊇(b, a) -> Bool

Determine whether every element of a is also in b, using in.

See also , , , , contains.

Examples

julia> issubset([1, 2], [1, 2, 3])
 true
@@ -1389,7 +1389,7 @@
 false
 
 julia> [1, 2, 3] ⊇ [1, 2]
-true
source
Base.in!Function
in!(x, s::AbstractSet) -> Bool

If x is in s, return true. If not, push x into s and return false. This is equivalent to in(x, s) ? true : (push!(s, x); false), but may have a more efficient implementation.

See also: in, push!, Set

Julia 1.11

This function requires at least 1.11.

Examples

julia> s = Set{Any}([1, 2, 3]); in!(4, s)
+true
source
Base.in!Function
in!(x, s::AbstractSet) -> Bool

If x is in s, return true. If not, push x into s and return false. This is equivalent to in(x, s) ? true : (push!(s, x); false), but may have a more efficient implementation.

See also: in, push!, Set

Julia 1.11

This function requires at least 1.11.

Examples

julia> s = Set{Any}([1, 2, 3]); in!(4, s)
 false
 
 julia> length(s)
@@ -1403,32 +1403,32 @@
   4
   2
   3
-  1
source
Base.:⊈Function
⊈(a, b) -> Bool
 ⊉(b, a) -> Bool

Negation of and , i.e. checks that a is not a subset of b.

See also issubset (), .

Examples

julia> (1, 2) ⊈ (2, 3)
 true
 
 julia> (1, 2) ⊈ (1, 2, 3)
-false
source
Base.:⊊Function
⊊(a, b) -> Bool
 ⊋(b, a) -> Bool

Determines if a is a subset of, but not equal to, b.

See also issubset (), .

Examples

julia> (1, 2) ⊊ (1, 2, 3)
 true
 
 julia> (1, 2) ⊊ (1, 2)
-false
source
Base.issetequalFunction
issetequal(a, b) -> Bool

Determine whether a and b have the same elements. Equivalent to a ⊆ b && b ⊆ a but more efficient when possible.

See also: isdisjoint, union.

Examples

julia> issetequal([1, 2], [1, 2, 3])
+false
source
Base.issetequalFunction
issetequal(a, b) -> Bool

Determine whether a and b have the same elements. Equivalent to a ⊆ b && b ⊆ a but more efficient when possible.

See also: isdisjoint, union.

Examples

julia> issetequal([1, 2], [1, 2, 3])
 false
 
 julia> issetequal([1, 2], [2, 1])
-true
source
issetequal(x)

Create a function that compares its argument to x using issetequal, i.e. a function equivalent to y -> issetequal(y, x). The returned function is of type Base.Fix2{typeof(issetequal)}, which can be used to implement specialized methods.

Julia 1.11

This functionality requires at least Julia 1.11.

source
Base.isdisjointFunction
isdisjoint(a, b) -> Bool

Determine whether the collections a and b are disjoint. Equivalent to isempty(a ∩ b) but more efficient when possible.

See also: intersect, isempty, issetequal.

Julia 1.5

This function requires at least Julia 1.5.

Examples

julia> isdisjoint([1, 2], [2, 3, 4])
+true
source
issetequal(x)

Create a function that compares its argument to x using issetequal, i.e. a function equivalent to y -> issetequal(y, x). The returned function is of type Base.Fix2{typeof(issetequal)}, which can be used to implement specialized methods.

Julia 1.11

This functionality requires at least Julia 1.11.

source
Base.isdisjointFunction
isdisjoint(a, b) -> Bool

Determine whether the collections a and b are disjoint. Equivalent to isempty(a ∩ b) but more efficient when possible.

See also: intersect, isempty, issetequal.

Julia 1.5

This function requires at least Julia 1.5.

Examples

julia> isdisjoint([1, 2], [2, 3, 4])
 false
 
 julia> isdisjoint([3, 1], [2, 4])
-true
source
isdisjoint(x)

Create a function that compares its argument to x using isdisjoint, i.e. a function equivalent to y -> isdisjoint(y, x). The returned function is of type Base.Fix2{typeof(isdisjoint)}, which can be used to implement specialized methods.

Julia 1.11

This functionality requires at least Julia 1.11.

source

Fully implemented by:

Partially implemented by:

Dequeues

Base.push!Function
push!(collection, items...) -> collection

Insert one or more items in collection. If collection is an ordered container, the items are inserted at the end (in the given order).

Examples

julia> push!([1, 2, 3], 4, 5, 6)
+true
source
isdisjoint(x)

Create a function that compares its argument to x using isdisjoint, i.e. a function equivalent to y -> isdisjoint(y, x). The returned function is of type Base.Fix2{typeof(isdisjoint)}, which can be used to implement specialized methods.

Julia 1.11

This functionality requires at least Julia 1.11.

source

Fully implemented by:

Partially implemented by:

Dequeues

Base.push!Function
push!(collection, items...) -> collection

Insert one or more items in collection. If collection is an ordered container, the items are inserted at the end (in the given order).

Examples

julia> push!([1, 2, 3], 4, 5, 6)
 6-element Vector{Int64}:
  1
  2
  3
  4
  5
- 6

If collection is ordered, use append! to add all the elements of another collection to it. The result of the preceding example is equivalent to append!([1, 2, 3], [4, 5, 6]). For AbstractSet objects, union! can be used instead.

See sizehint! for notes about the performance model.

See also pushfirst!.

source
Base.pop!Function
pop!(collection) -> item

Remove an item in collection and return it. If collection is an ordered container, the last item is returned; for unordered containers, an arbitrary element is returned.

See also: popfirst!, popat!, delete!, deleteat!, splice!, and push!.

Examples

julia> A=[1, 2, 3]
+ 6

If collection is ordered, use append! to add all the elements of another collection to it. The result of the preceding example is equivalent to append!([1, 2, 3], [4, 5, 6]). For AbstractSet objects, union! can be used instead.

See sizehint! for notes about the performance model.

See also pushfirst!.

source
Base.pop!Function
pop!(collection) -> item

Remove an item in collection and return it. If collection is an ordered container, the last item is returned; for unordered containers, an arbitrary element is returned.

See also: popfirst!, popat!, delete!, deleteat!, splice!, and push!.

Examples

julia> A=[1, 2, 3]
 3-element Vector{Int64}:
  1
  2
@@ -1455,7 +1455,7 @@
   1
 
 julia> pop!(Dict(1=>2))
-1 => 2
source
pop!(collection, key[, default])

Delete and return the mapping for key if it exists in collection, otherwise return default, or throw an error if default is not specified.

Examples

julia> d = Dict("a"=>1, "b"=>2, "c"=>3);
+1 => 2
source
pop!(collection, key[, default])

Delete and return the mapping for key if it exists in collection, otherwise return default, or throw an error if default is not specified.

Examples

julia> d = Dict("a"=>1, "b"=>2, "c"=>3);
 
 julia> pop!(d, "a")
 1
@@ -1466,7 +1466,7 @@
 [...]
 
 julia> pop!(d, "e", 4)
-4
source
Base.popat!Function
popat!(a::Vector, i::Integer, [default])

Remove the item at the given i and return it. Subsequent items are shifted to fill the resulting gap. When i is not a valid index for a, return default, or throw an error if default is not specified.

See also: pop!, popfirst!, deleteat!, splice!.

Julia 1.5

This function is available as of Julia 1.5.

Examples

julia> a = [4, 3, 2, 1]; popat!(a, 2)
+4
source
Base.popat!Function
popat!(a::Vector, i::Integer, [default])

Remove the item at the given i and return it. Subsequent items are shifted to fill the resulting gap. When i is not a valid index for a, return default, or throw an error if default is not specified.

See also: pop!, popfirst!, deleteat!, splice!.

Julia 1.5

This function is available as of Julia 1.5.

Examples

julia> a = [4, 3, 2, 1]; popat!(a, 2)
 3
 
 julia> a
@@ -1480,14 +1480,14 @@
 
 julia> popat!(a, 4)
 ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
-[...]
source
Base.pushfirst!Function
pushfirst!(collection, items...) -> collection

Insert one or more items at the beginning of collection.

This function is called unshift in many other programming languages.

Examples

julia> pushfirst!([1, 2, 3, 4], 5, 6)
+[...]
source
Base.pushfirst!Function
pushfirst!(collection, items...) -> collection

Insert one or more items at the beginning of collection.

This function is called unshift in many other programming languages.

Examples

julia> pushfirst!([1, 2, 3, 4], 5, 6)
 6-element Vector{Int64}:
  5
  6
  1
  2
  3
- 4
source
Base.popfirst!Function
popfirst!(collection) -> item

Remove the first item from collection.

This function is called shift in many other programming languages.

See also: pop!, popat!, delete!.

Examples

julia> A = [1, 2, 3, 4, 5, 6]
+ 4
source
Base.popfirst!Function
popfirst!(collection) -> item

Remove the first item from collection.

This function is called shift in many other programming languages.

See also: pop!, popat!, delete!.

Examples

julia> A = [1, 2, 3, 4, 5, 6]
 6-element Vector{Int64}:
  1
  2
@@ -1505,7 +1505,7 @@
  3
  4
  5
- 6
source
Base.insert!Function
insert!(a::Vector, index::Integer, item)

Insert an item into a at the given index. index is the index of item in the resulting a.

See also: push!, replace, popat!, splice!.

Examples

julia> insert!(Any[1:6;], 3, "here")
+ 6
source
Base.insert!Function
insert!(a::Vector, index::Integer, item)

Insert an item into a at the given index. index is the index of item in the resulting a.

See also: push!, replace, popat!, splice!.

Examples

julia> insert!(Any[1:6;], 3, "here")
 7-element Vector{Any}:
  1
  2
@@ -1513,13 +1513,13 @@
  3
  4
  5
- 6
source
Base.deleteat!Function
deleteat!(a::Vector, i::Integer)

Remove the item at the given i and return the modified a. Subsequent items are shifted to fill the resulting gap.

See also: keepat!, delete!, popat!, splice!.

Examples

julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
+ 6
source
Base.deleteat!Function
deleteat!(a::Vector, i::Integer)

Remove the item at the given i and return the modified a. Subsequent items are shifted to fill the resulting gap.

See also: keepat!, delete!, popat!, splice!.

Examples

julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
 5-element Vector{Int64}:
  6
  4
  3
  2
- 1
source
deleteat!(a::Vector, inds)

Remove the items at the indices given by inds, and return the modified a. Subsequent items are shifted to fill the resulting gap.

inds can be either an iterator or a collection of sorted and unique integer indices, or a boolean vector of the same length as a with true indicating entries to delete.

Examples

julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
+ 1
source
deleteat!(a::Vector, inds)

Remove the items at the indices given by inds, and return the modified a. Subsequent items are shifted to fill the resulting gap.

inds can be either an iterator or a collection of sorted and unique integer indices, or a boolean vector of the same length as a with true indicating entries to delete.

Examples

julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
 3-element Vector{Int64}:
  5
  3
@@ -1534,12 +1534,12 @@
 julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
 ERROR: ArgumentError: indices must be unique and sorted
 Stacktrace:
-[...]
source
Base.keepat!Function
keepat!(a::Vector, inds)
 keepat!(a::BitVector, inds)

Remove the items at all the indices which are not given by inds, and return the modified a. Items which are kept are shifted to fill the resulting gaps.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

inds must be an iterator of sorted and unique integer indices. See also deleteat!.

Julia 1.7

This function is available as of Julia 1.7.

Examples

julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
 3-element Vector{Int64}:
  6
  4
- 2
source
keepat!(a::Vector, m::AbstractVector{Bool})
+ 2
source
keepat!(a::Vector, m::AbstractVector{Bool})
 keepat!(a::BitVector, m::AbstractVector{Bool})

The in-place version of logical indexing a = a[m]. That is, keepat!(a, m) on vectors of equal length a and m will remove all elements from a for which m at the corresponding index is false.

Examples

julia> a = [:a, :b, :c];
 
 julia> keepat!(a, [true, false, true])
@@ -1550,7 +1550,7 @@
 julia> a
 2-element Vector{Symbol}:
  :a
- :c
source
Base.splice!Function
splice!(a::Vector, index::Integer, [replacement]) -> item

Remove the item at the given index, and return the removed item. Subsequent items are shifted left to fill the resulting gap. If specified, replacement values from an ordered collection will be spliced in place of the removed item.

See also: replace, delete!, deleteat!, pop!, popat!.

Examples

julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
+ :c
source
Base.splice!Function
splice!(a::Vector, index::Integer, [replacement]) -> item

Remove the item at the given index, and return the removed item. Subsequent items are shifted left to fill the resulting gap. If specified, replacement values from an ordered collection will be spliced in place of the removed item.

See also: replace, delete!, deleteat!, pop!, popat!.

Examples

julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
 2
 
 julia> A
@@ -1583,7 +1583,7 @@
   5
   4
   3
- -1

To insert replacement before an index n without removing any items, use splice!(collection, n:n-1, replacement).

source
splice!(a::Vector, indices, [replacement]) -> items

Remove items at specified indices, and return a collection containing the removed items. Subsequent items are shifted left to fill the resulting gaps. If specified, replacement values from an ordered collection will be spliced in place of the removed items; in this case, indices must be a AbstractUnitRange.

To insert replacement before an index n without removing any items, use splice!(collection, n:n-1, replacement).

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Julia 1.5

Prior to Julia 1.5, indices must always be a UnitRange.

Julia 1.8

Prior to Julia 1.8, indices must be a UnitRange if splicing in replacement values.

Examples

julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
+ -1

To insert replacement before an index n without removing any items, use splice!(collection, n:n-1, replacement).

source
splice!(a::Vector, indices, [replacement]) -> items

Remove items at specified indices, and return a collection containing the removed items. Subsequent items are shifted left to fill the resulting gaps. If specified, replacement values from an ordered collection will be spliced in place of the removed items; in this case, indices must be a AbstractUnitRange.

To insert replacement before an index n without removing any items, use splice!(collection, n:n-1, replacement).

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Julia 1.5

Prior to Julia 1.5, indices must always be a UnitRange.

Julia 1.8

Prior to Julia 1.8, indices must be a UnitRange if splicing in replacement values.

Examples

julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
 Int64[]
 
 julia> A
@@ -1595,7 +1595,7 @@
   5
   4
   3
- -1
source
Base.resize!Function
resize!(a::Vector, n::Integer) -> Vector

Resize a to contain n elements. If n is smaller than the current collection length, the first n elements will be retained. If n is larger, the new elements are not guaranteed to be initialized.

Examples

julia> resize!([6, 5, 4, 3, 2, 1], 3)
+ -1
source
Base.resize!Function
resize!(a::Vector, n::Integer) -> Vector

Resize a to contain n elements. If n is smaller than the current collection length, the first n elements will be retained. If n is larger, the new elements are not guaranteed to be initialized.

Examples

julia> resize!([6, 5, 4, 3, 2, 1], 3)
 3-element Vector{Int64}:
  6
  5
@@ -1613,7 +1613,7 @@
  4
  3
  2
- 1
source
Base.append!Function
append!(collection, collections...) -> collection.

For an ordered container collection, add the elements of each collections to the end of it.

Julia 1.6

Specifying multiple collections to be appended requires at least Julia 1.6.

Examples

julia> append!([1], [2, 3])
+ 1
source
Base.append!Function
append!(collection, collections...) -> collection.

For an ordered container collection, add the elements of each collections to the end of it.

Julia 1.6

Specifying multiple collections to be appended requires at least Julia 1.6.

Examples

julia> append!([1], [2, 3])
 3-element Vector{Int64}:
  1
  2
@@ -1626,7 +1626,7 @@
  3
  4
  5
- 6

Use push! to add individual items to collection which are not already themselves in another collection. The result of the preceding example is equivalent to push!([1, 2, 3], 4, 5, 6).

See sizehint! for notes about the performance model.

See also vcat for vectors, union! for sets, and prepend! and pushfirst! for the opposite order.

source
Base.prepend!Function
prepend!(a::Vector, collections...) -> collection

Insert the elements of each collections to the beginning of a.

When collections specifies multiple collections, order is maintained: elements of collections[1] will appear leftmost in a, and so on.

Julia 1.6

Specifying multiple collections to be prepended requires at least Julia 1.6.

Examples

julia> prepend!([3], [1, 2])
+ 6

Use push! to add individual items to collection which are not already themselves in another collection. The result of the preceding example is equivalent to push!([1, 2, 3], 4, 5, 6).

See sizehint! for notes about the performance model.

See also vcat for vectors, union! for sets, and prepend! and pushfirst! for the opposite order.

source
Base.prepend!Function
prepend!(a::Vector, collections...) -> collection

Insert the elements of each collections to the beginning of a.

When collections specifies multiple collections, order is maintained: elements of collections[1] will appear leftmost in a, and so on.

Julia 1.6

Specifying multiple collections to be prepended requires at least Julia 1.6.

Examples

julia> prepend!([3], [1, 2])
 3-element Vector{Int64}:
  1
  2
@@ -1639,7 +1639,7 @@
  3
  4
  5
- 6
source

Fully implemented by:

  • Vector (a.k.a. 1-dimensional Array)
  • BitVector (a.k.a. 1-dimensional BitArray)

Utility Collections

Fully implemented by:

  • Vector (a.k.a. 1-dimensional Array)
  • BitVector (a.k.a. 1-dimensional BitArray)

Utility Collections

Core.PairType
Pair(x, y)
 x => y

Construct a Pair object with type Pair{typeof(x), typeof(y)}. The elements are stored in the fields first and second. They can also be accessed via iteration (but a Pair is treated as a single "scalar" for broadcasting operations).

See also Dict.

Examples

julia> p = "foo" => 7
 "foo" => 7
 
@@ -1658,4 +1658,4 @@
 julia> replace.(["xops", "oxps"], "x" => "o")
 2-element Vector{String}:
  "oops"
- "oops"
source
Base.PairsType
Base.Pairs(values, keys) <: AbstractDict{eltype(keys), eltype(values)}

Transforms an indexable container into a Dictionary-view of the same data. Modifying the key-space of the underlying data may invalidate this object.

source
+ "oops"source
Base.PairsType
Base.Pairs(values, keys) <: AbstractDict{eltype(keys), eltype(values)}

Transforms an indexable container into a Dictionary-view of the same data. Modifying the key-space of the underlying data may invalidate this object.

source
diff --git a/en/v1.12-dev/base/constants/index.html b/en/v1.12-dev/base/constants/index.html index 846d9b93c13b..a30e29900069 100644 --- a/en/v1.12-dev/base/constants/index.html +++ b/en/v1.12-dev/base/constants/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Constants

Base.PROGRAM_FILEConstant
PROGRAM_FILE

A string containing the script name passed to Julia from the command line. Note that the script name remains unchanged from within included files. Alternatively see @__FILE__.

source
Base.ARGSConstant
ARGS

An array of the command line arguments passed to Julia, as strings.

source
Base.C_NULLConstant
C_NULL

The C null pointer constant, sometimes used when calling external code.

source
Base.DEPOT_PATHConstant
DEPOT_PATH

A stack of "depot" locations where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, and configuration files. By default it includes:

  1. ~/.julia where ~ is the user home as appropriate on the system;
  2. an architecture-specific shared system directory, e.g. /usr/local/share/julia;
  3. an architecture-independent shared system directory, e.g. /usr/share/julia.

So DEPOT_PATH might be:

[joinpath(homedir(), ".julia"), "/usr/local/share/julia", "/usr/share/julia"]

The first entry is the "user depot" and should be writable by and owned by the current user. The user depot is where: registries are cloned, new package versions are installed, named environments are created and updated, package repos are cloned, newly compiled package image files are saved, log files are written, development packages are checked out by default, and global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and managed by system administrators.

DEPOT_PATH is populated based on the JULIA_DEPOT_PATH environment variable if set.

DEPOT_PATH contents

Each entry in DEPOT_PATH is a path to a directory which contains subdirectories used by Julia for various purposes. Here is an overview of some of the subdirectories that may exist in a depot:

  • artifacts: Contains content that packages use for which Pkg manages the installation of.
  • clones: Contains full clones of package repos. Maintained by Pkg.jl and used as a cache.
  • config: Contains julia-level configuration such as a startup.jl
  • compiled: Contains precompiled *.ji files for packages. Maintained by Julia.
  • dev: Default directory for Pkg.develop. Maintained by Pkg.jl and the user.
  • environments: Default package environments. For instance the global environment for a specific julia version. Maintained by Pkg.jl.
  • logs: Contains logs of Pkg and REPL operations. Maintained by Pkg.jl and Julia.
  • packages: Contains packages, some of which were explicitly installed and some which are implicit dependencies. Maintained by Pkg.jl.
  • registries: Contains package registries. By default only General. Maintained by Pkg.jl.
  • scratchspaces: Contains content that a package itself installs via the Scratch.jl package. Pkg.gc() will delete content that is known to be unused.
Note

Packages that want to store content should use the scratchspaces subdirectory via Scratch.jl instead of creating new subdirectories in the depot root.

See also JULIA_DEPOT_PATH, and Code Loading.

source
Base.LOAD_PATHConstant
LOAD_PATH

An array of paths for using and import statements to consider as project environments or package directories when loading code. It is populated based on the JULIA_LOAD_PATH environment variable if set; otherwise it defaults to ["@", "@v#.#", "@stdlib"]. Entries starting with @ have special meanings:

  • @ refers to the "current active environment", the initial value of which is initially determined by the JULIA_PROJECT environment variable or the --project command-line option.

  • @stdlib expands to the absolute path of the current Julia installation's standard library directory.

  • @name refers to a named environment, which are stored in depots (see JULIA_DEPOT_PATH) under the environments subdirectory. The user's named environments are stored in ~/.julia/environments so @name would refer to the environment in ~/.julia/environments/name if it exists and contains a Project.toml file. If name contains # characters, then they are replaced with the major, minor and patch components of the Julia version number. For example, if you are running Julia 1.2 then @v#.# expands to @v1.2 and will look for an environment by that name, typically at ~/.julia/environments/v1.2.

The fully expanded value of LOAD_PATH that is searched for projects and packages can be seen by calling the Base.load_path() function.

See also JULIA_LOAD_PATH, JULIA_PROJECT, JULIA_DEPOT_PATH, and Code Loading.

source
Base.Sys.BINDIRConstant
Sys.BINDIR::String

A string containing the full path to the directory containing the julia executable.

source
Base.Sys.CPU_THREADSConstant
Sys.CPU_THREADS::Int

The number of logical CPU cores available in the system, i.e. the number of threads that the CPU can run concurrently. Note that this is not necessarily the number of CPU cores, for example, in the presence of hyper-threading.

See Hwloc.jl or CpuId.jl for extended information, including number of physical cores.

source
Base.Sys.KERNELConstant
Sys.KERNEL::Symbol

A symbol representing the name of the operating system, as returned by uname of the build configuration.

source
Base.Sys.ARCHConstant
Sys.ARCH::Symbol

A symbol representing the architecture of the build configuration.

source

See also:

+

Constants

Base.PROGRAM_FILEConstant
PROGRAM_FILE

A string containing the script name passed to Julia from the command line. Note that the script name remains unchanged from within included files. Alternatively see @__FILE__.

source
Base.ARGSConstant
ARGS

An array of the command line arguments passed to Julia, as strings.

source
Base.C_NULLConstant
C_NULL

The C null pointer constant, sometimes used when calling external code.

source
Base.DEPOT_PATHConstant
DEPOT_PATH

A stack of "depot" locations where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, and configuration files. By default it includes:

  1. ~/.julia where ~ is the user home as appropriate on the system;
  2. an architecture-specific shared system directory, e.g. /usr/local/share/julia;
  3. an architecture-independent shared system directory, e.g. /usr/share/julia.

So DEPOT_PATH might be:

[joinpath(homedir(), ".julia"), "/usr/local/share/julia", "/usr/share/julia"]

The first entry is the "user depot" and should be writable by and owned by the current user. The user depot is where: registries are cloned, new package versions are installed, named environments are created and updated, package repos are cloned, newly compiled package image files are saved, log files are written, development packages are checked out by default, and global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and managed by system administrators.

DEPOT_PATH is populated based on the JULIA_DEPOT_PATH environment variable if set.

DEPOT_PATH contents

Each entry in DEPOT_PATH is a path to a directory which contains subdirectories used by Julia for various purposes. Here is an overview of some of the subdirectories that may exist in a depot:

  • artifacts: Contains content that packages use for which Pkg manages the installation of.
  • clones: Contains full clones of package repos. Maintained by Pkg.jl and used as a cache.
  • config: Contains julia-level configuration such as a startup.jl
  • compiled: Contains precompiled *.ji files for packages. Maintained by Julia.
  • dev: Default directory for Pkg.develop. Maintained by Pkg.jl and the user.
  • environments: Default package environments. For instance the global environment for a specific julia version. Maintained by Pkg.jl.
  • logs: Contains logs of Pkg and REPL operations. Maintained by Pkg.jl and Julia.
  • packages: Contains packages, some of which were explicitly installed and some which are implicit dependencies. Maintained by Pkg.jl.
  • registries: Contains package registries. By default only General. Maintained by Pkg.jl.
  • scratchspaces: Contains content that a package itself installs via the Scratch.jl package. Pkg.gc() will delete content that is known to be unused.
Note

Packages that want to store content should use the scratchspaces subdirectory via Scratch.jl instead of creating new subdirectories in the depot root.

See also JULIA_DEPOT_PATH, and Code Loading.

source
Base.LOAD_PATHConstant
LOAD_PATH

An array of paths for using and import statements to consider as project environments or package directories when loading code. It is populated based on the JULIA_LOAD_PATH environment variable if set; otherwise it defaults to ["@", "@v#.#", "@stdlib"]. Entries starting with @ have special meanings:

  • @ refers to the "current active environment", the initial value of which is initially determined by the JULIA_PROJECT environment variable or the --project command-line option.

  • @stdlib expands to the absolute path of the current Julia installation's standard library directory.

  • @name refers to a named environment, which are stored in depots (see JULIA_DEPOT_PATH) under the environments subdirectory. The user's named environments are stored in ~/.julia/environments so @name would refer to the environment in ~/.julia/environments/name if it exists and contains a Project.toml file. If name contains # characters, then they are replaced with the major, minor and patch components of the Julia version number. For example, if you are running Julia 1.2 then @v#.# expands to @v1.2 and will look for an environment by that name, typically at ~/.julia/environments/v1.2.

The fully expanded value of LOAD_PATH that is searched for projects and packages can be seen by calling the Base.load_path() function.

See also JULIA_LOAD_PATH, JULIA_PROJECT, JULIA_DEPOT_PATH, and Code Loading.

source
Base.Sys.BINDIRConstant
Sys.BINDIR::String

A string containing the full path to the directory containing the julia executable.

source
Base.Sys.CPU_THREADSConstant
Sys.CPU_THREADS::Int

The number of logical CPU cores available in the system, i.e. the number of threads that the CPU can run concurrently. Note that this is not necessarily the number of CPU cores, for example, in the presence of hyper-threading.

See Hwloc.jl or CpuId.jl for extended information, including number of physical cores.

source
Base.Sys.KERNELConstant
Sys.KERNEL::Symbol

A symbol representing the name of the operating system, as returned by uname of the build configuration.

source
Base.Sys.ARCHConstant
Sys.ARCH::Symbol

A symbol representing the architecture of the build configuration.

source

See also:

diff --git a/en/v1.12-dev/base/file/index.html b/en/v1.12-dev/base/file/index.html index 6c8594cfc6ad..2a33a50ae6df 100644 --- a/en/v1.12-dev/base/file/index.html +++ b/en/v1.12-dev/base/file/index.html @@ -3,13 +3,13 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Filesystem

Base.readMethod
read(filename::AbstractString)

Read the entire contents of a file as a Vector{UInt8}.

read(filename::AbstractString, String)

Read the entire contents of a file as a string.

read(filename::AbstractString, args...)

Open a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).

source
Base.writeMethod
write(filename::AbstractString, content)

Write the canonical binary representation of content to a file, which will be created if it does not exist yet or overwritten if it does exist.

Return the number of bytes written into the file.

source
Base.Filesystem.pwdFunction
pwd() -> String

Get the current working directory.

See also: cd, tempdir.

Examples

julia> pwd()
+

Filesystem

Base.readMethod
read(filename::AbstractString)

Read the entire contents of a file as a Vector{UInt8}.

read(filename::AbstractString, String)

Read the entire contents of a file as a string.

read(filename::AbstractString, args...)

Open a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).

source
Base.writeMethod
write(filename::AbstractString, content)

Write the canonical binary representation of content to a file, which will be created if it does not exist yet or overwritten if it does exist.

Return the number of bytes written into the file.

source
Base.Filesystem.pwdFunction
pwd() -> String

Get the current working directory.

See also: cd, tempdir.

Examples

julia> pwd()
 "/home/JuliaUser"
 
 julia> cd("/home/JuliaUser/Projects/julia")
 
 julia> pwd()
-"/home/JuliaUser/Projects/julia"
source
Base.Filesystem.cdMethod
cd(dir::AbstractString=homedir())

Set the current working directory.

See also: pwd, mkdir, mkpath, mktempdir.

Examples

julia> cd("/home/JuliaUser/Projects/julia")
 
 julia> pwd()
 "/home/JuliaUser/Projects/julia"
@@ -17,7 +17,7 @@
 julia> cd()
 
 julia> pwd()
-"/home/JuliaUser"
source
Base.Filesystem.cdMethod
cd(f::Function, dir::AbstractString=homedir())

Temporarily change the current working directory to dir, apply function f and finally return to the original directory.

Examples

julia> pwd()
+"/home/JuliaUser"
source
Base.Filesystem.cdMethod
cd(f::Function, dir::AbstractString=homedir())

Temporarily change the current working directory to dir, apply function f and finally return to the original directory.

Examples

julia> pwd()
 "/home/JuliaUser"
 
 julia> cd(readdir, "/home/JuliaUser/Projects/julia")
@@ -34,7 +34,7 @@
  "usr-staging"
 
 julia> pwd()
-"/home/JuliaUser"
source
Base.Filesystem.readdirFunction
readdir(dir::AbstractString=pwd();
     join::Bool = false,
     sort::Bool = true,
 ) -> Vector{String}

Return the names in the directory dir or the current working directory if not given. When join is false, readdir returns just the names in the directory as is; when join is true, it returns joinpath(dir, name) for each name so that the returned strings are full paths. If you want to get absolute paths back, call readdir with an absolute directory path and join set to true.

By default, readdir sorts the list of names it returns. If you want to skip sorting the names and get them in the order that the file system lists them, you can use readdir(dir, sort=false) to opt out of sorting.

See also: walkdir.

Julia 1.4

The join and sort keyword arguments require at least Julia 1.4.

Examples

julia> cd("/home/JuliaUser/dev/julia")
@@ -87,7 +87,7 @@
  ⋮
  "/home/JuliaUser/dev/julia/base/version_git.sh"
  "/home/JuliaUser/dev/julia/base/views.jl"
- "/home/JuliaUser/dev/julia/base/weakkeydict.jl"
source
Base.Filesystem.walkdirFunction
walkdir(dir; topdown=true, follow_symlinks=false, onerror=throw)

Return an iterator that walks the directory tree of a directory. The iterator returns a tuple containing (rootpath, dirs, files). The directory tree can be traversed top-down or bottom-up. If walkdir or stat encounters a IOError it will rethrow the error by default. A custom error handling function can be provided through onerror keyword argument. onerror is called with a IOError as argument.

See also: readdir.

Examples

for (root, dirs, files) in walkdir(".")
+ "/home/JuliaUser/dev/julia/base/weakkeydict.jl"
source
Base.Filesystem.walkdirFunction
walkdir(dir; topdown=true, follow_symlinks=false, onerror=throw)

Return an iterator that walks the directory tree of a directory. The iterator returns a tuple containing (rootpath, dirs, files). The directory tree can be traversed top-down or bottom-up. If walkdir or stat encounters a IOError it will rethrow the error by default. A custom error handling function can be provided through onerror keyword argument. onerror is called with a IOError as argument.

See also: readdir.

Examples

for (root, dirs, files) in walkdir(".")
     println("Directories in $root")
     for dir in dirs
         println(joinpath(root, dir)) # path to directories
@@ -107,13 +107,13 @@
 ("my/test", ["dir"], String[])
 
 julia> (root, dirs, files) = first(itr)
-("my/test/dir", String[], String[])
source
Base.Filesystem.mkdirFunction
mkdir(path::AbstractString; mode::Unsigned = 0o777)

Make a new directory with name path and permissions mode. mode defaults to 0o777, modified by the current file creation mask. This function never creates more than one directory. If the directory already exists, or some intermediate directories do not exist, this function throws an error. See mkpath for a function which creates all required intermediate directories. Return path.

Examples

julia> mkdir("testingdir")
+("my/test/dir", String[], String[])
source
Base.Filesystem.mkdirFunction
mkdir(path::AbstractString; mode::Unsigned = 0o777)

Make a new directory with name path and permissions mode. mode defaults to 0o777, modified by the current file creation mask. This function never creates more than one directory. If the directory already exists, or some intermediate directories do not exist, this function throws an error. See mkpath for a function which creates all required intermediate directories. Return path.

Examples

julia> mkdir("testingdir")
 "testingdir"
 
 julia> cd("testingdir")
 
 julia> pwd()
-"/home/JuliaUser/testingdir"
source
Base.Filesystem.mkpathFunction
mkpath(path::AbstractString; mode::Unsigned = 0o777)

Create all intermediate directories in the path as required. Directories are created with the permissions mode which defaults to 0o777 and is modified by the current file creation mask. Unlike mkdir, mkpath does not error if path (or parts of it) already exists. However, an error will be thrown if path (or parts of it) points to an existing file. Return path.

If path includes a filename you will probably want to use mkpath(dirname(path)) to avoid creating a directory using the filename.

Examples

julia> cd(mktempdir())
+"/home/JuliaUser/testingdir"
source
Base.Filesystem.mkpathFunction
mkpath(path::AbstractString; mode::Unsigned = 0o777)

Create all intermediate directories in the path as required. Directories are created with the permissions mode which defaults to 0o777 and is modified by the current file creation mask. Unlike mkdir, mkpath does not error if path (or parts of it) already exists. However, an error will be thrown if path (or parts of it) points to an existing file. Return path.

If path includes a filename you will probably want to use mkpath(dirname(path)) to avoid creating a directory using the filename.

Examples

julia> cd(mktempdir())
 
 julia> mkpath("my/test/dir") # creates three directories
 "my/test/dir"
@@ -137,7 +137,7 @@
 
 julia> isdir("intermediate_dir/actually_a_directory.txt")
 true
-
source
Base.Filesystem.hardlinkFunction
hardlink(src::AbstractString, dst::AbstractString)

Creates a hard link to an existing source file src with the name dst. The destination, dst, must not exist.

See also: symlink.

Julia 1.8

This method was added in Julia 1.8.

source
Base.Filesystem.symlinkFunction
symlink(target::AbstractString, link::AbstractString; dir_target = false)

Creates a symbolic link to target with the name link.

On Windows, symlinks must be explicitly declared as referring to a directory or not. If target already exists, by default the type of link will be auto- detected, however if target does not exist, this function defaults to creating a file symlink unless dir_target is set to true. Note that if the user sets dir_target but target exists and is a file, a directory symlink will still be created, but dereferencing the symlink will fail, just as if the user creates a file symlink (by calling symlink() with dir_target set to false before the directory is created) and tries to dereference it to a directory.

Additionally, there are two methods of making a link on Windows; symbolic links and junction points. Junction points are slightly more efficient, but do not support relative paths, so if a relative directory symlink is requested (as denoted by isabspath(target) returning false) a symlink will be used, else a junction point will be used. Best practice for creating symlinks on Windows is to create them only after the files/directories they reference are already created.

See also: hardlink.

Note

This function raises an error under operating systems that do not support soft symbolic links, such as Windows XP.

Julia 1.6

The dir_target keyword argument was added in Julia 1.6. Prior to this, symlinks to nonexistent paths on windows would always be file symlinks, and relative symlinks to directories were not supported.

source
Base.Filesystem.chmodFunction
chmod(path::AbstractString, mode::Integer; recursive::Bool=false)

Change the permissions mode of path to mode. Only integer modes (e.g. 0o777) are currently supported. If recursive=true and the path is a directory all permissions in that directory will be recursively changed. Return path.

Note

Prior to Julia 1.6, this did not correctly manipulate filesystem ACLs on Windows, therefore it would only set read-only bits on files. It now is able to manipulate ACLs.

source
Base.Filesystem.chownFunction
chown(path::AbstractString, owner::Integer, group::Integer=-1)

Change the owner and/or group of path to owner and/or group. If the value entered for owner or group is -1 the corresponding ID will not change. Only integer owners and groups are currently supported. Return path.

source
Base.Libc.RawFDType
RawFD

Primitive type which wraps the native OS file descriptor. RawFDs can be passed to methods like stat to discover information about the underlying file, and can also be used to open streams, with the RawFD describing the OS file backing the stream.

source
Base.statFunction
stat(file)

Return a structure whose fields contain information about the file. The fields of the structure are:

NameTypeDescription
descUnion{String, Base.OS_HANDLE}The path or OS file descriptor
sizeInt64The size (in bytes) of the file
deviceUIntID of the device that contains the file
inodeUIntThe inode number of the file
modeUIntThe protection mode of the file
nlinkIntThe number of hard links to the file
uidUIntThe user id of the owner of the file
gidUIntThe group id of the file owner
rdevUIntIf this file refers to a device, the ID of the device it refers to
blksizeInt64The file-system preferred block size for the file
blocksInt64The number of 512-byte blocks allocated
mtimeFloat64Unix timestamp of when the file was last modified
ctimeFloat64Unix timestamp of when the file's metadata was changed
source
Base.Filesystem.diskstatFunction
diskstat(path=pwd())

Returns statistics in bytes about the disk that contains the file or directory pointed at by path. If no argument is passed, statistics about the disk that contains the current working directory are returned.

Julia 1.8

This method was added in Julia 1.8.

source
Base.Filesystem.lstatFunction
lstat(file)

Like stat, but for symbolic links gets the info for the link itself rather than the file it refers to. This function must be called on a file path rather than a file object or a file descriptor.

source
Base.Filesystem.upermFunction
uperm(file)

Get the permissions of the owner of the file as a bitfield of

ValueDescription
01Execute Permission
02Write Permission
04Read Permission

For allowed arguments, see stat.

source
Base.Filesystem.opermFunction
operm(file)

Like uperm but gets the permissions for people who neither own the file nor are a member of the group owning the file

source
Base.Filesystem.cpFunction
cp(src::AbstractString, dst::AbstractString; force::Bool=false, follow_symlinks::Bool=false)

Copy the file, link, or directory from src to dst. force=true will first remove an existing dst.

If follow_symlinks=false, and src is a symbolic link, dst will be created as a symbolic link. If follow_symlinks=true and src is a symbolic link, dst will be a copy of the file or directory src refers to. Return dst.

Note

The cp function is different from the cp command. The cp function always operates on the assumption that dst is a file, while the command does different things depending on whether dst is a directory or a file. Using force=true when dst is a directory will result in loss of all the contents present in the dst directory, and dst will become a file that has the contents of src instead.

source
Base.downloadFunction
download(url::AbstractString, [path::AbstractString = tempname()]) -> path

Download a file from the given url, saving it to the location path, or if not specified, a temporary path. Returns the path of the downloaded file.

Note

Since Julia 1.6, this function is deprecated and is just a thin wrapper around Downloads.download. In new code, you should use that function directly instead of calling this.

source
Base.Filesystem.mvFunction
mv(src::AbstractString, dst::AbstractString; force::Bool=false)

Move the file, link, or directory from src to dst. force=true will first remove an existing dst. Return dst.

Examples

julia> write("hello.txt", "world");
+
source
Base.Filesystem.hardlinkFunction
hardlink(src::AbstractString, dst::AbstractString)

Creates a hard link to an existing source file src with the name dst. The destination, dst, must not exist.

See also: symlink.

Julia 1.8

This method was added in Julia 1.8.

source
Base.Filesystem.symlinkFunction
symlink(target::AbstractString, link::AbstractString; dir_target = false)

Creates a symbolic link to target with the name link.

On Windows, symlinks must be explicitly declared as referring to a directory or not. If target already exists, by default the type of link will be auto- detected, however if target does not exist, this function defaults to creating a file symlink unless dir_target is set to true. Note that if the user sets dir_target but target exists and is a file, a directory symlink will still be created, but dereferencing the symlink will fail, just as if the user creates a file symlink (by calling symlink() with dir_target set to false before the directory is created) and tries to dereference it to a directory.

Additionally, there are two methods of making a link on Windows; symbolic links and junction points. Junction points are slightly more efficient, but do not support relative paths, so if a relative directory symlink is requested (as denoted by isabspath(target) returning false) a symlink will be used, else a junction point will be used. Best practice for creating symlinks on Windows is to create them only after the files/directories they reference are already created.

See also: hardlink.

Note

This function raises an error under operating systems that do not support soft symbolic links, such as Windows XP.

Julia 1.6

The dir_target keyword argument was added in Julia 1.6. Prior to this, symlinks to nonexistent paths on windows would always be file symlinks, and relative symlinks to directories were not supported.

source
Base.Filesystem.chmodFunction
chmod(path::AbstractString, mode::Integer; recursive::Bool=false)

Change the permissions mode of path to mode. Only integer modes (e.g. 0o777) are currently supported. If recursive=true and the path is a directory all permissions in that directory will be recursively changed. Return path.

Note

Prior to Julia 1.6, this did not correctly manipulate filesystem ACLs on Windows, therefore it would only set read-only bits on files. It now is able to manipulate ACLs.

source
Base.Filesystem.chownFunction
chown(path::AbstractString, owner::Integer, group::Integer=-1)

Change the owner and/or group of path to owner and/or group. If the value entered for owner or group is -1 the corresponding ID will not change. Only integer owners and groups are currently supported. Return path.

source
Base.Libc.RawFDType
RawFD

Primitive type which wraps the native OS file descriptor. RawFDs can be passed to methods like stat to discover information about the underlying file, and can also be used to open streams, with the RawFD describing the OS file backing the stream.

source
Base.statFunction
stat(file)

Return a structure whose fields contain information about the file. The fields of the structure are:

NameTypeDescription
descUnion{String, Base.OS_HANDLE}The path or OS file descriptor
sizeInt64The size (in bytes) of the file
deviceUIntID of the device that contains the file
inodeUIntThe inode number of the file
modeUIntThe protection mode of the file
nlinkIntThe number of hard links to the file
uidUIntThe user id of the owner of the file
gidUIntThe group id of the file owner
rdevUIntIf this file refers to a device, the ID of the device it refers to
blksizeInt64The file-system preferred block size for the file
blocksInt64The number of 512-byte blocks allocated
mtimeFloat64Unix timestamp of when the file was last modified
ctimeFloat64Unix timestamp of when the file's metadata was changed
source
Base.Filesystem.diskstatFunction
diskstat(path=pwd())

Returns statistics in bytes about the disk that contains the file or directory pointed at by path. If no argument is passed, statistics about the disk that contains the current working directory are returned.

Julia 1.8

This method was added in Julia 1.8.

source
Base.Filesystem.lstatFunction
lstat(file)

Like stat, but for symbolic links gets the info for the link itself rather than the file it refers to. This function must be called on a file path rather than a file object or a file descriptor.

source
Base.Filesystem.upermFunction
uperm(file)

Get the permissions of the owner of the file as a bitfield of

ValueDescription
01Execute Permission
02Write Permission
04Read Permission

For allowed arguments, see stat.

source
Base.Filesystem.opermFunction
operm(file)

Like uperm but gets the permissions for people who neither own the file nor are a member of the group owning the file

source
Base.Filesystem.cpFunction
cp(src::AbstractString, dst::AbstractString; force::Bool=false, follow_symlinks::Bool=false)

Copy the file, link, or directory from src to dst. force=true will first remove an existing dst.

If follow_symlinks=false, and src is a symbolic link, dst will be created as a symbolic link. If follow_symlinks=true and src is a symbolic link, dst will be a copy of the file or directory src refers to. Return dst.

Note

The cp function is different from the cp command. The cp function always operates on the assumption that dst is a file, while the command does different things depending on whether dst is a directory or a file. Using force=true when dst is a directory will result in loss of all the contents present in the dst directory, and dst will become a file that has the contents of src instead.

source
Base.downloadFunction
download(url::AbstractString, [path::AbstractString = tempname()]) -> path

Download a file from the given url, saving it to the location path, or if not specified, a temporary path. Returns the path of the downloaded file.

Note

Since Julia 1.6, this function is deprecated and is just a thin wrapper around Downloads.download. In new code, you should use that function directly instead of calling this.

source
Base.Filesystem.mvFunction
mv(src::AbstractString, dst::AbstractString; force::Bool=false)

Move the file, link, or directory from src to dst. force=true will first remove an existing dst. Return dst.

Examples

julia> write("hello.txt", "world");
 
 julia> mv("hello.txt", "goodbye.txt")
 "goodbye.txt"
@@ -160,7 +160,7 @@
 "goodbye.txt"
 
 julia> rm("goodbye.txt");
-
source
Base.Filesystem.rmFunction
rm(path::AbstractString; force::Bool=false, recursive::Bool=false)

Delete the file, link, or empty directory at the given path. If force=true is passed, a non-existing path is not treated as error. If recursive=true is passed and the path is a directory, then all contents are removed recursively.

Examples

julia> mkpath("my/test/dir");
+
source
Base.Filesystem.rmFunction
rm(path::AbstractString; force::Bool=false, recursive::Bool=false)

Delete the file, link, or empty directory at the given path. If force=true is passed, a non-existing path is not treated as error. If recursive=true is passed and the path is a directory, then all contents are removed recursively.

Examples

julia> mkpath("my/test/dir");
 
 julia> rm("my", recursive=true)
 
@@ -169,7 +169,7 @@
 julia> rm("this_file_does_not_exist")
 ERROR: IOError: unlink("this_file_does_not_exist"): no such file or directory (ENOENT)
 Stacktrace:
-[...]
source
Base.Filesystem.touchFunction
Base.touch(::Pidfile.LockMonitor)

Update the mtime on the lock, to indicate it is still fresh.

See also the refresh keyword in the mkpidlock constructor.

touch(path::AbstractString)
+[...]
source
Base.Filesystem.touchFunction
Base.touch(::Pidfile.LockMonitor)

Update the mtime on the lock, to indicate it is still fresh.

See also the refresh keyword in the mkpidlock constructor.

touch(path::AbstractString)
 touch(fd::File)

Update the last-modified timestamp on a file to the current time.

If the file does not exist a new file is created.

Return path.

Examples

julia> write("my_little_file", 2);
 
 julia> mtime("my_little_file")
@@ -178,11 +178,11 @@
 julia> touch("my_little_file");
 
 julia> mtime("my_little_file")
-1.527381559163435e9

We can see the mtime has been modified by touch.

source
Base.Filesystem.tempnameFunction
tempname(parent=tempdir(); cleanup=true, suffix="") -> String

Generate a temporary file path. This function only returns a path; no file is created. The path is likely to be unique, but this cannot be guaranteed due to the very remote possibility of two simultaneous calls to tempname generating the same file name. The name is guaranteed to differ from all files already existing at the time of the call to tempname.

When called with no arguments, the temporary name will be an absolute path to a temporary name in the system temporary directory as given by tempdir(). If a parent directory argument is given, the temporary path will be in that directory instead. If a suffix is given the tempname will end with that suffix and be tested for uniqueness with that suffix.

The cleanup option controls whether the process attempts to delete the returned path automatically when the process exits. Note that the tempname function does not create any file or directory at the returned location, so there is nothing to cleanup unless you create a file or directory there. If you do and cleanup is true it will be deleted upon process termination.

Julia 1.4

The parent and cleanup arguments were added in 1.4. Prior to Julia 1.4 the path tempname would never be cleaned up at process termination.

Julia 1.12

The suffix keyword argument was added in Julia 1.12.

Warning

This can lead to security holes if another process obtains the same file name and creates the file before you are able to. Open the file with JL_O_EXCL if this is a concern. Using mktemp() is also recommended instead.

source
Base.Filesystem.tempdirFunction
tempdir()

Gets the path of the temporary directory. On Windows, tempdir() uses the first environment variable found in the ordered list TMP, TEMP, USERPROFILE. On all other operating systems, tempdir() uses the first environment variable found in the ordered list TMPDIR, TMP, TEMP, and TEMPDIR. If none of these are found, the path "/tmp" is used.

source
Base.Filesystem.mktempMethod
mktemp(parent=tempdir(); cleanup=true) -> (path, io)

Return (path, io), where path is the path of a new temporary file in parent and io is an open file object for this path. The cleanup option controls whether the temporary file is automatically deleted when the process exits.

Julia 1.3

The cleanup keyword argument was added in Julia 1.3. Relatedly, starting from 1.3, Julia will remove the temporary paths created by mktemp when the Julia process exits, unless cleanup is explicitly set to false.

source
Base.Filesystem.mktempdirMethod
mktempdir(parent=tempdir(); prefix="jl_", cleanup=true) -> path

Create a temporary directory in the parent directory with a name constructed from the given prefix and a random suffix, and return its path. Additionally, on some platforms, any trailing 'X' characters in prefix may be replaced with random characters. If parent does not exist, throw an error. The cleanup option controls whether the temporary directory is automatically deleted when the process exits.

Julia 1.2

The prefix keyword argument was added in Julia 1.2.

Julia 1.3

The cleanup keyword argument was added in Julia 1.3. Relatedly, starting from 1.3, Julia will remove the temporary paths created by mktempdir when the Julia process exits, unless cleanup is explicitly set to false.

See also: mktemp, mkdir.

source
Base.Filesystem.isdirFunction
isdir(path) -> Bool

Return true if path is a directory, false otherwise.

Examples

julia> isdir(homedir())
+1.527381559163435e9

We can see the mtime has been modified by touch.

source
Base.Filesystem.tempnameFunction
tempname(parent=tempdir(); cleanup=true, suffix="") -> String

Generate a temporary file path. This function only returns a path; no file is created. The path is likely to be unique, but this cannot be guaranteed due to the very remote possibility of two simultaneous calls to tempname generating the same file name. The name is guaranteed to differ from all files already existing at the time of the call to tempname.

When called with no arguments, the temporary name will be an absolute path to a temporary name in the system temporary directory as given by tempdir(). If a parent directory argument is given, the temporary path will be in that directory instead. If a suffix is given the tempname will end with that suffix and be tested for uniqueness with that suffix.

The cleanup option controls whether the process attempts to delete the returned path automatically when the process exits. Note that the tempname function does not create any file or directory at the returned location, so there is nothing to cleanup unless you create a file or directory there. If you do and cleanup is true it will be deleted upon process termination.

Julia 1.4

The parent and cleanup arguments were added in 1.4. Prior to Julia 1.4 the path tempname would never be cleaned up at process termination.

Julia 1.12

The suffix keyword argument was added in Julia 1.12.

Warning

This can lead to security holes if another process obtains the same file name and creates the file before you are able to. Open the file with JL_O_EXCL if this is a concern. Using mktemp() is also recommended instead.

source
Base.Filesystem.tempdirFunction
tempdir()

Gets the path of the temporary directory. On Windows, tempdir() uses the first environment variable found in the ordered list TMP, TEMP, USERPROFILE. On all other operating systems, tempdir() uses the first environment variable found in the ordered list TMPDIR, TMP, TEMP, and TEMPDIR. If none of these are found, the path "/tmp" is used.

source
Base.Filesystem.mktempMethod
mktemp(parent=tempdir(); cleanup=true) -> (path, io)

Return (path, io), where path is the path of a new temporary file in parent and io is an open file object for this path. The cleanup option controls whether the temporary file is automatically deleted when the process exits.

Julia 1.3

The cleanup keyword argument was added in Julia 1.3. Relatedly, starting from 1.3, Julia will remove the temporary paths created by mktemp when the Julia process exits, unless cleanup is explicitly set to false.

source
Base.Filesystem.mktempdirMethod
mktempdir(parent=tempdir(); prefix="jl_", cleanup=true) -> path

Create a temporary directory in the parent directory with a name constructed from the given prefix and a random suffix, and return its path. Additionally, on some platforms, any trailing 'X' characters in prefix may be replaced with random characters. If parent does not exist, throw an error. The cleanup option controls whether the temporary directory is automatically deleted when the process exits.

Julia 1.2

The prefix keyword argument was added in Julia 1.2.

Julia 1.3

The cleanup keyword argument was added in Julia 1.3. Relatedly, starting from 1.3, Julia will remove the temporary paths created by mktempdir when the Julia process exits, unless cleanup is explicitly set to false.

See also: mktemp, mkdir.

source
Base.Filesystem.isdirFunction
isdir(path) -> Bool

Return true if path is a directory, false otherwise.

Examples

julia> isdir(homedir())
 true
 
 julia> isdir("not/a/directory")
-false

See also isfile and ispath.

source
Base.Filesystem.isfileFunction
isfile(path) -> Bool

Return true if path is a regular file, false otherwise.

Examples

julia> isfile(homedir())
 false
 
 julia> filename = "test_file.txt";
@@ -195,41 +195,41 @@
 julia> rm(filename);
 
 julia> isfile(filename)
-false

See also isdir and ispath.

source
Base.Filesystem.dirnameFunction
dirname(path::AbstractString) -> String

Get the directory part of a path. Trailing characters ('/' or '\') in the path are counted as part of the path.

Examples

julia> dirname("/home/myuser")
+false

See also isdir and ispath.

source
Base.Filesystem.dirnameFunction
dirname(path::AbstractString) -> String

Get the directory part of a path. Trailing characters ('/' or '\') in the path are counted as part of the path.

Examples

julia> dirname("/home/myuser")
 "/home"
 
 julia> dirname("/home/myuser/")
-"/home/myuser"

See also basename.

source
Base.Filesystem.basenameFunction
basename(path::AbstractString) -> String

Get the file name part of a path.

Note

This function differs slightly from the Unix basename program, where trailing slashes are ignored, i.e. $ basename /foo/bar/ returns bar, whereas basename in Julia returns an empty string "".

Examples

julia> basename("/home/myuser/example.jl")
+"/home/myuser"

See also basename.

source
Base.Filesystem.basenameFunction
basename(path::AbstractString) -> String

Get the file name part of a path.

Note

This function differs slightly from the Unix basename program, where trailing slashes are ignored, i.e. $ basename /foo/bar/ returns bar, whereas basename in Julia returns an empty string "".

Examples

julia> basename("/home/myuser/example.jl")
 "example.jl"
 
 julia> basename("/home/myuser/")
-""

See also dirname.

source
Base.Filesystem.isabspathFunction
isabspath(path::AbstractString) -> Bool

Determine whether a path is absolute (begins at the root directory).

Examples

julia> isabspath("/home")
+""

See also dirname.

source
Base.Filesystem.isabspathFunction
isabspath(path::AbstractString) -> Bool

Determine whether a path is absolute (begins at the root directory).

Examples

julia> isabspath("/home")
 true
 
 julia> isabspath("home")
-false
source
Base.Filesystem.isdirpathFunction
isdirpath(path::AbstractString) -> Bool

Determine whether a path refers to a directory (for example, ends with a path separator).

Examples

julia> isdirpath("/home")
+false
source
Base.Filesystem.isdirpathFunction
isdirpath(path::AbstractString) -> Bool

Determine whether a path refers to a directory (for example, ends with a path separator).

Examples

julia> isdirpath("/home")
 false
 
 julia> isdirpath("/home/")
-true
source
Base.Filesystem.joinpathFunction
joinpath(parts::AbstractString...) -> String
 joinpath(parts::Vector{AbstractString}) -> String
 joinpath(parts::Tuple{AbstractString}) -> String

Join path components into a full path. If some argument is an absolute path or (on Windows) has a drive specification that doesn't match the drive computed for the join of the preceding paths, then prior components are dropped.

Note on Windows since there is a current directory for each drive, joinpath("c:", "foo") represents a path relative to the current directory on drive "c:" so this is equal to "c:foo", not "c:\foo". Furthermore, joinpath treats this as a non-absolute path and ignores the drive letter casing, hence joinpath("C:\A","c:b") = "C:\A\b".

Examples

julia> joinpath("/home/myuser", "example.jl")
 "/home/myuser/example.jl"
julia> joinpath(["/home/myuser", "example.jl"])
-"/home/myuser/example.jl"
source
Base.Filesystem.abspathFunction
abspath(path::AbstractString) -> String

Convert a path to an absolute path by adding the current directory if necessary. Also normalizes the path as in normpath.

Examples

If you are in a directory called JuliaExample and the data you are using is two levels up relative to the JuliaExample directory, you could write:

abspath("../../data")

Which gives a path like "/home/JuliaUser/data/".

See also joinpath, pwd, expanduser.

source
abspath(path::AbstractString, paths::AbstractString...) -> String

Convert a set of paths to an absolute path by joining them together and adding the current directory if necessary. Equivalent to abspath(joinpath(path, paths...)).

source
Base.Filesystem.normpathFunction
normpath(path::AbstractString) -> String

Normalize a path, removing "." and ".." entries and changing "/" to the canonical path separator for the system.

Examples

julia> normpath("/home/myuser/../example.jl")
+"/home/myuser/example.jl"
source
Base.Filesystem.abspathFunction
abspath(path::AbstractString) -> String

Convert a path to an absolute path by adding the current directory if necessary. Also normalizes the path as in normpath.

Examples

If you are in a directory called JuliaExample and the data you are using is two levels up relative to the JuliaExample directory, you could write:

abspath("../../data")

Which gives a path like "/home/JuliaUser/data/".

See also joinpath, pwd, expanduser.

source
abspath(path::AbstractString, paths::AbstractString...) -> String

Convert a set of paths to an absolute path by joining them together and adding the current directory if necessary. Equivalent to abspath(joinpath(path, paths...)).

source
Base.Filesystem.normpathFunction
normpath(path::AbstractString) -> String

Normalize a path, removing "." and ".." entries and changing "/" to the canonical path separator for the system.

Examples

julia> normpath("/home/myuser/../example.jl")
 "/home/example.jl"
 
 julia> normpath("Documents/Julia") == joinpath("Documents", "Julia")
-true
source
normpath(path::AbstractString, paths::AbstractString...) -> String

Convert a set of paths to a normalized path by joining them together and removing "." and ".." entries. Equivalent to normpath(joinpath(path, paths...)).

source
Base.Filesystem.realpathFunction
realpath(path::AbstractString) -> String

Canonicalize a path by expanding symbolic links and removing "." and ".." entries. On case-insensitive case-preserving filesystems (typically Mac and Windows), the filesystem's stored case for the path is returned.

(This function throws an exception if path does not exist in the filesystem.)

source
Base.Filesystem.relpathFunction
relpath(path::AbstractString, startpath::AbstractString = ".") -> String

Return a relative filepath to path either from the current directory or from an optional start directory. This is a path computation: the filesystem is not accessed to confirm the existence or nature of path or startpath.

On Windows, case sensitivity is applied to every part of the path except drive letters. If path and startpath refer to different drives, the absolute path of path is returned.

source
Base.Filesystem.expanduserFunction
expanduser(path::AbstractString) -> AbstractString

On Unix systems, replace a tilde character at the start of a path with the current user's home directory.

See also: contractuser.

source
Base.Filesystem.samefileFunction
samefile(path_a::AbstractString, path_b::AbstractString)

Check if the paths path_a and path_b refer to the same existing file or directory.

source
Base.Filesystem.splitdirFunction
splitdir(path::AbstractString) -> (AbstractString, AbstractString)

Split a path into a tuple of the directory name and file name.

Examples

julia> splitdir("/home/myuser")
-("/home", "myuser")
source
Base.Filesystem.splitdriveFunction
splitdrive(path::AbstractString) -> (AbstractString, AbstractString)

On Windows, split a path into the drive letter part and the path part. On Unix systems, the first component is always the empty string.

source
Base.Filesystem.splitextFunction
splitext(path::AbstractString) -> (String, String)

If the last component of a path contains one or more dots, split the path into everything before the last dot and everything including and after the dot. Otherwise, return a tuple of the argument unmodified and the empty string. "splitext" is short for "split extension".

Examples

julia> splitext("/home/myuser/example.jl")
+true
source
normpath(path::AbstractString, paths::AbstractString...) -> String

Convert a set of paths to a normalized path by joining them together and removing "." and ".." entries. Equivalent to normpath(joinpath(path, paths...)).

source
Base.Filesystem.realpathFunction
realpath(path::AbstractString) -> String

Canonicalize a path by expanding symbolic links and removing "." and ".." entries. On case-insensitive case-preserving filesystems (typically Mac and Windows), the filesystem's stored case for the path is returned.

(This function throws an exception if path does not exist in the filesystem.)

source
Base.Filesystem.relpathFunction
relpath(path::AbstractString, startpath::AbstractString = ".") -> String

Return a relative filepath to path either from the current directory or from an optional start directory. This is a path computation: the filesystem is not accessed to confirm the existence or nature of path or startpath.

On Windows, case sensitivity is applied to every part of the path except drive letters. If path and startpath refer to different drives, the absolute path of path is returned.

source
Base.Filesystem.expanduserFunction
expanduser(path::AbstractString) -> AbstractString

On Unix systems, replace a tilde character at the start of a path with the current user's home directory.

See also: contractuser.

source
Base.Filesystem.samefileFunction
samefile(path_a::AbstractString, path_b::AbstractString)

Check if the paths path_a and path_b refer to the same existing file or directory.

source
Base.Filesystem.splitdirFunction
splitdir(path::AbstractString) -> (AbstractString, AbstractString)

Split a path into a tuple of the directory name and file name.

Examples

julia> splitdir("/home/myuser")
+("/home", "myuser")
source
Base.Filesystem.splitdriveFunction
splitdrive(path::AbstractString) -> (AbstractString, AbstractString)

On Windows, split a path into the drive letter part and the path part. On Unix systems, the first component is always the empty string.

source
Base.Filesystem.splitextFunction
splitext(path::AbstractString) -> (String, String)

If the last component of a path contains one or more dots, split the path into everything before the last dot and everything including and after the dot. Otherwise, return a tuple of the argument unmodified and the empty string. "splitext" is short for "split extension".

Examples

julia> splitext("/home/myuser/example.jl")
 ("/home/myuser/example", ".jl")
 
 julia> splitext("/home/myuser/example.tar.gz")
 ("/home/myuser/example.tar", ".gz")
 
 julia> splitext("/home/my.user/example")
-("/home/my.user/example", "")
source
Base.Filesystem.splitpathFunction
splitpath(path::AbstractString) -> Vector{String}

Split a file path into all its path components. This is the opposite of joinpath. Returns an array of substrings, one for each directory or file in the path, including the root directory if present.

Julia 1.1

This function requires at least Julia 1.1.

Examples

julia> splitpath("/home/myuser/example.jl")
+("/home/my.user/example", "")
source
Base.Filesystem.splitpathFunction
splitpath(path::AbstractString) -> Vector{String}

Split a file path into all its path components. This is the opposite of joinpath. Returns an array of substrings, one for each directory or file in the path, including the root directory if present.

Julia 1.1

This function requires at least Julia 1.1.

Examples

julia> splitpath("/home/myuser/example.jl")
 4-element Vector{String}:
  "/"
  "home"
  "myuser"
- "example.jl"
source
+ "example.jl"
source
diff --git a/en/v1.12-dev/base/io-network/index.html b/en/v1.12-dev/base/io-network/index.html index 7a85a183479b..c4ad55503c73 100644 --- a/en/v1.12-dev/base/io-network/index.html +++ b/en/v1.12-dev/base/io-network/index.html @@ -3,12 +3,12 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

I/O and Network

General I/O

Base.stdoutConstant
stdout::IO

Global variable referring to the standard out stream.

source
Base.stderrConstant
stderr::IO

Global variable referring to the standard error stream.

source
Base.stdinConstant
stdin::IO

Global variable referring to the standard input stream.

source
Base.readMethod
read(filename::AbstractString)

Read the entire contents of a file as a Vector{UInt8}.

read(filename::AbstractString, String)

Read the entire contents of a file as a string.

read(filename::AbstractString, args...)

Open a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).

source
Base.writeMethod
write(filename::AbstractString, content)

Write the canonical binary representation of content to a file, which will be created if it does not exist yet or overwritten if it does exist.

Return the number of bytes written into the file.

source
Base.openFunction
open(f::Function, args...; kwargs...)

Apply the function f to the result of open(args...; kwargs...) and close the resulting file descriptor upon completion.

Examples

julia> write("myfile.txt", "Hello world!");
+

I/O and Network

General I/O

Base.stdoutConstant
stdout::IO

Global variable referring to the standard out stream.

source
Base.stderrConstant
stderr::IO

Global variable referring to the standard error stream.

source
Base.stdinConstant
stdin::IO

Global variable referring to the standard input stream.

source
Base.readMethod
read(filename::AbstractString)

Read the entire contents of a file as a Vector{UInt8}.

read(filename::AbstractString, String)

Read the entire contents of a file as a string.

read(filename::AbstractString, args...)

Open a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).

source
Base.writeMethod
write(filename::AbstractString, content)

Write the canonical binary representation of content to a file, which will be created if it does not exist yet or overwritten if it does exist.

Return the number of bytes written into the file.

source
Base.openFunction
open(f::Function, args...; kwargs...)

Apply the function f to the result of open(args...; kwargs...) and close the resulting file descriptor upon completion.

Examples

julia> write("myfile.txt", "Hello world!");
 
 julia> open(io->read(io, String), "myfile.txt")
 "Hello world!"
 
-julia> rm("myfile.txt")
source
open(filename::AbstractString; lock = true, keywords...) -> IOStream

Open a file in a mode specified by five boolean keyword arguments:

KeywordDescriptionDefault
readopen for reading!write
writeopen for writingtruncate | append
createcreate if non-existent!read & write | truncate | append
truncatetruncate to zero size!read & write
appendseek to endfalse

The default when no keywords are passed is to open files for reading only. Returns a stream for accessing the opened file.

The lock keyword argument controls whether operations will be locked for safe multi-threaded access.

Julia 1.5

The lock argument is available as of Julia 1.5.

source
open(filename::AbstractString, [mode::AbstractString]; lock = true) -> IOStream

Alternate syntax for open, where a string-based mode specifier is used instead of the five booleans. The values of mode correspond to those from fopen(3) or Perl open, and are equivalent to setting the following boolean groups:

ModeDescriptionKeywords
rreadnone
wwrite, create, truncatewrite = true
awrite, create, appendappend = true
r+read, writeread = true, write = true
w+read, write, create, truncatetruncate = true, read = true
a+read, write, create, appendappend = true, read = true

The lock keyword argument controls whether operations will be locked for safe multi-threaded access.

Examples

julia> io = open("myfile.txt", "w");
+julia> rm("myfile.txt")
source
open(filename::AbstractString; lock = true, keywords...) -> IOStream

Open a file in a mode specified by five boolean keyword arguments:

KeywordDescriptionDefault
readopen for reading!write
writeopen for writingtruncate | append
createcreate if non-existent!read & write | truncate | append
truncatetruncate to zero size!read & write
appendseek to endfalse

The default when no keywords are passed is to open files for reading only. Returns a stream for accessing the opened file.

The lock keyword argument controls whether operations will be locked for safe multi-threaded access.

Julia 1.5

The lock argument is available as of Julia 1.5.

source
open(filename::AbstractString, [mode::AbstractString]; lock = true) -> IOStream

Alternate syntax for open, where a string-based mode specifier is used instead of the five booleans. The values of mode correspond to those from fopen(3) or Perl open, and are equivalent to setting the following boolean groups:

ModeDescriptionKeywords
rreadnone
wwrite, create, truncatewrite = true
awrite, create, appendappend = true
r+read, writeread = true, write = true
w+read, write, create, truncatetruncate = true, read = true
a+read, write, create, appendappend = true, read = true

The lock keyword argument controls whether operations will be locked for safe multi-threaded access.

Examples

julia> io = open("myfile.txt", "w");
 
 julia> write(io, "Hello world!");
 
@@ -32,7 +32,7 @@
 
 julia> close(io)
 
-julia> rm("myfile.txt")
Julia 1.5

The lock argument is available as of Julia 1.5.

source
open(fd::OS_HANDLE) -> IO

Take a raw file descriptor wrap it in a Julia-aware IO type, and take ownership of the fd handle. Call open(Libc.dup(fd)) to avoid the ownership capture of the original handle.

Warning

Do not call this on a handle that's already owned by some other part of the system.

source
open(command, mode::AbstractString, stdio=devnull)

Run command asynchronously. Like open(command, stdio; read, write) except specifying the read and write flags via a mode string instead of keyword arguments. Possible mode strings are:

ModeDescriptionKeywords
rreadnone
wwritewrite = true
r+read, writeread = true, write = true
w+read, writeread = true, write = true
source
open(command, stdio=devnull; write::Bool = false, read::Bool = !write)

Start running command asynchronously, and return a process::IO object. If read is true, then reads from the process come from the process's standard output and stdio optionally specifies the process's standard input stream. If write is true, then writes go to the process's standard input and stdio optionally specifies the process's standard output stream. The process's standard error stream is connected to the current global stderr.

source
open(f::Function, command, args...; kwargs...)

Similar to open(command, args...; kwargs...), but calls f(stream) on the resulting process stream, then closes the input stream and waits for the process to complete. Return the value returned by f on success. Throw an error if the process failed, or if the process attempts to print anything to stdout.

source
Base.IOStreamType
IOStream

A buffered IO stream wrapping an OS file descriptor. Mostly used to represent files returned by open.

source
Base.IOBufferType
IOBuffer([data::AbstractVector{UInt8}]; keywords...) -> IOBuffer

Create an in-memory I/O stream, which may optionally operate on a pre-existing array.

It may take optional keyword arguments:

  • read, write, append: restricts operations to the buffer; see open for details.
  • truncate: truncates the buffer size to zero length.
  • maxsize: specifies a size beyond which the buffer may not be grown.
  • sizehint: suggests a capacity of the buffer (data must implement sizehint!(data, size)).

When data is not given, the buffer will be both readable and writable by default.

Examples

julia> io = IOBuffer();
+julia> rm("myfile.txt")
Julia 1.5

The lock argument is available as of Julia 1.5.

source
open(fd::OS_HANDLE) -> IO

Take a raw file descriptor wrap it in a Julia-aware IO type, and take ownership of the fd handle. Call open(Libc.dup(fd)) to avoid the ownership capture of the original handle.

Warning

Do not call this on a handle that's already owned by some other part of the system.

source
open(command, mode::AbstractString, stdio=devnull)

Run command asynchronously. Like open(command, stdio; read, write) except specifying the read and write flags via a mode string instead of keyword arguments. Possible mode strings are:

ModeDescriptionKeywords
rreadnone
wwritewrite = true
r+read, writeread = true, write = true
w+read, writeread = true, write = true
source
open(command, stdio=devnull; write::Bool = false, read::Bool = !write)

Start running command asynchronously, and return a process::IO object. If read is true, then reads from the process come from the process's standard output and stdio optionally specifies the process's standard input stream. If write is true, then writes go to the process's standard input and stdio optionally specifies the process's standard output stream. The process's standard error stream is connected to the current global stderr.

source
open(f::Function, command, args...; kwargs...)

Similar to open(command, args...; kwargs...), but calls f(stream) on the resulting process stream, then closes the input stream and waits for the process to complete. Return the value returned by f on success. Throw an error if the process failed, or if the process attempts to print anything to stdout.

source
Base.IOStreamType
IOStream

A buffered IO stream wrapping an OS file descriptor. Mostly used to represent files returned by open.

source
Base.IOBufferType
IOBuffer([data::AbstractVector{UInt8}]; keywords...) -> IOBuffer

Create an in-memory I/O stream, which may optionally operate on a pre-existing array.

It may take optional keyword arguments:

  • read, write, append: restricts operations to the buffer; see open for details.
  • truncate: truncates the buffer size to zero length.
  • maxsize: specifies a size beyond which the buffer may not be grown.
  • sizehint: suggests a capacity of the buffer (data must implement sizehint!(data, size)).

When data is not given, the buffer will be both readable and writable by default.

Examples

julia> io = IOBuffer();
 
 julia> write(io, "JuliaLang is a GitHub organization.", " It has many members.")
 56
@@ -62,19 +62,19 @@
 4
 
 julia> length(read(IOBuffer(b"data", read=true, truncate=true)))
-0
source
IOBuffer(string::String)

Create a read-only IOBuffer on the data underlying the given string.

Examples

julia> io = IOBuffer("Haho");
+0
source
IOBuffer(string::String)

Create a read-only IOBuffer on the data underlying the given string.

Examples

julia> io = IOBuffer("Haho");
 
 julia> String(take!(io))
 "Haho"
 
 julia> String(take!(io))
-"Haho"
source
Base.take!Method
take!(b::IOBuffer)

Obtain the contents of an IOBuffer as an array. Afterwards, the IOBuffer is reset to its initial state.

Examples

julia> io = IOBuffer();
+"Haho"
source
Base.take!Method
take!(b::IOBuffer)

Obtain the contents of an IOBuffer as an array. Afterwards, the IOBuffer is reset to its initial state.

Examples

julia> io = IOBuffer();
 
 julia> write(io, "JuliaLang is a GitHub organization.", " It has many members.")
 56
 
 julia> String(take!(io))
-"JuliaLang is a GitHub organization. It has many members."
source
Base.PipeType
Pipe()

Construct an uninitialized Pipe object, especially for IO communication between multiple processes.

The appropriate end of the pipe will be automatically initialized if the object is used in process spawning. This can be useful to easily obtain references in process pipelines, e.g.:

julia> err = Pipe()
+"JuliaLang is a GitHub organization. It has many members."
source
Base.PipeType
Pipe()

Construct an uninitialized Pipe object, especially for IO communication between multiple processes.

The appropriate end of the pipe will be automatically initialized if the object is used in process spawning. This can be useful to easily obtain references in process pipelines, e.g.:

julia> err = Pipe()
 
 # After this `err` will be initialized and you may read `foo`'s
 # stderr from the `err` pipe, or pass `err` to other pipelines.
@@ -84,7 +84,7 @@
 julia> closewrite(err)
 
 julia> read(err, String)
-"stderr messages"

See also Base.link_pipe!.

source
Base.link_pipe!Function
link_pipe!(pipe; reader_supports_async=false, writer_supports_async=false)

Initialize pipe and link the in endpoint to the out endpoint. The keyword arguments reader_supports_async/writer_supports_async correspond to OVERLAPPED on Windows and O_NONBLOCK on POSIX systems. They should be true unless they'll be used by an external program (e.g. the output of a command executed with run).

source
Base.fdioFunction
fdio([name::AbstractString, ]fd::Integer[, own::Bool=false]) -> IOStream

Create an IOStream object from an integer file descriptor. If own is true, closing this object will close the underlying descriptor. By default, an IOStream is closed when it is garbage collected. name allows you to associate the descriptor with a named file.

source
Base.flushFunction
flush(stream)

Commit all currently buffered writes to the given stream.

source
Base.closewriteFunction
closewrite(stream)

Shutdown the write half of a full-duplex I/O stream. Performs a flush first. Notify the other end that no more data will be written to the underlying file. This is not supported by all IO types.

If implemented, closewrite causes subsequent read or eof calls that would block to instead throw EOF or return true, respectively. If the stream is already closed, this is idempotent.

Examples

julia> io = Base.BufferStream(); # this never blocks, so we can read and write on the same Task
+"stderr messages"

See also Base.link_pipe!.

source
Base.link_pipe!Function
link_pipe!(pipe; reader_supports_async=false, writer_supports_async=false)

Initialize pipe and link the in endpoint to the out endpoint. The keyword arguments reader_supports_async/writer_supports_async correspond to OVERLAPPED on Windows and O_NONBLOCK on POSIX systems. They should be true unless they'll be used by an external program (e.g. the output of a command executed with run).

source
Base.fdioFunction
fdio([name::AbstractString, ]fd::Integer[, own::Bool=false]) -> IOStream

Create an IOStream object from an integer file descriptor. If own is true, closing this object will close the underlying descriptor. By default, an IOStream is closed when it is garbage collected. name allows you to associate the descriptor with a named file.

source
Base.flushFunction
flush(stream)

Commit all currently buffered writes to the given stream.

source
Base.closewriteFunction
closewrite(stream)

Shutdown the write half of a full-duplex I/O stream. Performs a flush first. Notify the other end that no more data will be written to the underlying file. This is not supported by all IO types.

If implemented, closewrite causes subsequent read or eof calls that would block to instead throw EOF or return true, respectively. If the stream is already closed, this is idempotent.

Examples

julia> io = Base.BufferStream(); # this never blocks, so we can read and write on the same Task
 
 julia> write(io, "request");
 
@@ -93,7 +93,7 @@
 julia> closewrite(io);
 
 julia> read(io, String)
-"request"
source
Base.writeFunction
write(io::IO, x)

Write the canonical binary representation of a value to the given I/O stream or file. Return the number of bytes written into the stream. See also print to write a text representation (with an encoding that may depend upon io).

The endianness of the written value depends on the endianness of the host system. Convert to/from a fixed endianness when writing/reading (e.g. using htol and ltoh) to get results that are consistent across platforms.

You can write multiple values with the same write call. i.e. the following are equivalent:

write(io, x, y...)
+"request"
source
Base.writeFunction
write(io::IO, x)

Write the canonical binary representation of a value to the given I/O stream or file. Return the number of bytes written into the stream. See also print to write a text representation (with an encoding that may depend upon io).

The endianness of the written value depends on the endianness of the host system. Convert to/from a fixed endianness when writing/reading (e.g. using htol and ltoh) to get results that are consistent across platforms.

You can write multiple values with the same write call. i.e. the following are equivalent:

write(io, x, y...)
 write(io, x) + write(io, y...)

Examples

Consistent serialization:

julia> fname = tempname(); # random temporary filename
 
 julia> open(fname,"w") do f
@@ -127,7 +127,7 @@
 8
 
 julia> seekstart(io); read!(io, Ref(MyStruct(NaN)))
-Base.RefValue{MyStruct}(MyStruct(42.0))
source
Base.readFunction
read(io::IO, T)

Read a single value of type T from io, in canonical binary representation.

Note that Julia does not convert the endianness for you. Use ntoh or ltoh for this purpose.

read(io::IO, String)

Read the entirety of io, as a String (see also readchomp).

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization");
+Base.RefValue{MyStruct}(MyStruct(42.0))
source
Base.readFunction
read(io::IO, T)

Read a single value of type T from io, in canonical binary representation.

Note that Julia does not convert the endianness for you. Use ntoh or ltoh for this purpose.

read(io::IO, String)

Read the entirety of io, as a String (see also readchomp).

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization");
 
 julia> read(io, Char)
 'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)
@@ -135,14 +135,14 @@
 julia> io = IOBuffer("JuliaLang is a GitHub organization");
 
 julia> read(io, String)
-"JuliaLang is a GitHub organization"
source
read(filename::AbstractString)

Read the entire contents of a file as a Vector{UInt8}.

read(filename::AbstractString, String)

Read the entire contents of a file as a string.

read(filename::AbstractString, args...)

Open a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).

source
read(s::IO, nb=typemax(Int))

Read at most nb bytes from s, returning a Vector{UInt8} of the bytes read.

source
read(s::IOStream, nb::Integer; all=true)

Read at most nb bytes from s, returning a Vector{UInt8} of the bytes read.

If all is true (the default), this function will block repeatedly trying to read all requested bytes, until an error or end-of-file occurs. If all is false, at most one read call is performed, and the amount of data returned is device-dependent. Note that not all stream types support the all option.

source
read(command::Cmd)

Run command and return the resulting output as an array of bytes.

source
read(command::Cmd, String)

Run command and return the resulting output as a String.

source
Base.read!Function
read!(stream::IO, array::AbstractArray)
-read!(filename::AbstractString, array::AbstractArray)

Read binary data from an I/O stream or file, filling in array.

source
Base.readbytes!Function
readbytes!(stream::IO, b::AbstractVector{UInt8}, nb=length(b))

Read at most nb bytes from stream into b, returning the number of bytes read. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.

source
readbytes!(stream::IOStream, b::AbstractVector{UInt8}, nb=length(b); all::Bool=true)

Read at most nb bytes from stream into b, returning the number of bytes read. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.

If all is true (the default), this function will block repeatedly trying to read all requested bytes, until an error or end-of-file occurs. If all is false, at most one read call is performed, and the amount of data returned is device-dependent. Note that not all stream types support the all option.

source
Base.unsafe_readFunction
unsafe_read(io::IO, ref, nbytes::UInt)

Copy nbytes from the IO stream object into ref (converted to a pointer).

It is recommended that subtypes T<:IO override the following method signature to provide more efficient implementations: unsafe_read(s::T, p::Ptr{UInt8}, n::UInt)

source
Base.unsafe_writeFunction
unsafe_write(io::IO, ref, nbytes::UInt)

Copy nbytes from ref (converted to a pointer) into the IO object.

It is recommended that subtypes T<:IO override the following method signature to provide more efficient implementations: unsafe_write(s::T, p::Ptr{UInt8}, n::UInt)

source
Base.readeachFunction
readeach(io::IO, T)

Return an iterable object yielding read(io, T).

See also skipchars, eachline, readuntil.

Julia 1.6

readeach requires Julia 1.6 or later.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.\n It has many members.\n");
+"JuliaLang is a GitHub organization"
source
read(filename::AbstractString)

Read the entire contents of a file as a Vector{UInt8}.

read(filename::AbstractString, String)

Read the entire contents of a file as a string.

read(filename::AbstractString, args...)

Open a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).

source
read(s::IO, nb=typemax(Int))

Read at most nb bytes from s, returning a Vector{UInt8} of the bytes read.

source
read(s::IOStream, nb::Integer; all=true)

Read at most nb bytes from s, returning a Vector{UInt8} of the bytes read.

If all is true (the default), this function will block repeatedly trying to read all requested bytes, until an error or end-of-file occurs. If all is false, at most one read call is performed, and the amount of data returned is device-dependent. Note that not all stream types support the all option.

source
read(command::Cmd)

Run command and return the resulting output as an array of bytes.

source
read(command::Cmd, String)

Run command and return the resulting output as a String.

source
Base.read!Function
read!(stream::IO, array::AbstractArray)
+read!(filename::AbstractString, array::AbstractArray)

Read binary data from an I/O stream or file, filling in array.

source
Base.readbytes!Function
readbytes!(stream::IO, b::AbstractVector{UInt8}, nb=length(b))

Read at most nb bytes from stream into b, returning the number of bytes read. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.

source
readbytes!(stream::IOStream, b::AbstractVector{UInt8}, nb=length(b); all::Bool=true)

Read at most nb bytes from stream into b, returning the number of bytes read. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.

If all is true (the default), this function will block repeatedly trying to read all requested bytes, until an error or end-of-file occurs. If all is false, at most one read call is performed, and the amount of data returned is device-dependent. Note that not all stream types support the all option.

source
Base.unsafe_readFunction
unsafe_read(io::IO, ref, nbytes::UInt)

Copy nbytes from the IO stream object into ref (converted to a pointer).

It is recommended that subtypes T<:IO override the following method signature to provide more efficient implementations: unsafe_read(s::T, p::Ptr{UInt8}, n::UInt)

source
Base.unsafe_writeFunction
unsafe_write(io::IO, ref, nbytes::UInt)

Copy nbytes from ref (converted to a pointer) into the IO object.

It is recommended that subtypes T<:IO override the following method signature to provide more efficient implementations: unsafe_write(s::T, p::Ptr{UInt8}, n::UInt)

source
Base.readeachFunction
readeach(io::IO, T)

Return an iterable object yielding read(io, T).

See also skipchars, eachline, readuntil.

Julia 1.6

readeach requires Julia 1.6 or later.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.\n It has many members.\n");
 
 julia> for c in readeach(io, Char)
            c == '\n' && break
            print(c)
        end
-JuliaLang is a GitHub organization.
source
Base.peekFunction
peek(stream[, T=UInt8])

Read and return a value of type T from a stream without advancing the current position in the stream. See also startswith(stream, char_or_string).

Examples

julia> b = IOBuffer("julia");
+JuliaLang is a GitHub organization.
source
Base.peekFunction
peek(stream[, T=UInt8])

Read and return a value of type T from a stream without advancing the current position in the stream. See also startswith(stream, char_or_string).

Examples

julia> b = IOBuffer("julia");
 
 julia> peek(b)
 0x6a
@@ -151,7 +151,7 @@
 0
 
 julia> peek(b, Char)
-'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase)
Julia 1.5

The method which accepts a type requires Julia 1.5 or later.

source
Base.positionFunction
position(l::Lexer)

Returns the current position.

source
position(s)

Get the current position of a stream.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.");
+'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase)
Julia 1.5

The method which accepts a type requires Julia 1.5 or later.

source
Base.positionFunction
position(l::Lexer)

Returns the current position.

source
position(s)

Get the current position of a stream.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.");
 
 julia> seek(io, 5);
 
@@ -166,12 +166,12 @@
 julia> seekend(io);
 
 julia> position(io)
-35
source
Base.seekFunction
seek(s, pos)

Seek a stream to the given position.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.");
+35
source
Base.seekFunction
seek(s, pos)

Seek a stream to the given position.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.");
 
 julia> seek(io, 5);
 
 julia> read(io, Char)
-'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)
source
Base.seekstartFunction
seekstart(s)

Seek a stream to its beginning.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.");
+'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)
source
Base.seekstartFunction
seekstart(s)

Seek a stream to its beginning.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.");
 
 julia> seek(io, 5);
 
@@ -181,14 +181,14 @@
 julia> seekstart(io);
 
 julia> read(io, Char)
-'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)
source
Base.skipFunction
skip(s, offset)

Seek a stream relative to the current position.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.");
+'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)
source
Base.skipFunction
skip(s, offset)

Seek a stream relative to the current position.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.");
 
 julia> seek(io, 5);
 
 julia> skip(io, 10);
 
 julia> read(io, Char)
-'G': ASCII/Unicode U+0047 (category Lu: Letter, uppercase)
source
Base.resetMethod
reset(s::IO)

Reset a stream s to a previously marked position, and remove the mark. Return the previously marked position. Throw an error if the stream is not marked.

See also mark, unmark, ismarked.

source
Base.eofFunction
eof(stream) -> Bool

Test whether an I/O stream is at end-of-file. If the stream is not yet exhausted, this function will block to wait for more data if necessary, and then return false. Therefore it is always safe to read one byte after seeing eof return false. eof will return false as long as buffered data is still available, even if the remote end of a connection is closed.

Examples

julia> b = IOBuffer("my buffer");
+'G': ASCII/Unicode U+0047 (category Lu: Letter, uppercase)
source
Base.resetMethod
reset(s::IO)

Reset a stream s to a previously marked position, and remove the mark. Return the previously marked position. Throw an error if the stream is not marked.

See also mark, unmark, ismarked.

source
Base.eofFunction
eof(stream) -> Bool

Test whether an I/O stream is at end-of-file. If the stream is not yet exhausted, this function will block to wait for more data if necessary, and then return false. Therefore it is always safe to read one byte after seeing eof return false. eof will return false as long as buffered data is still available, even if the remote end of a connection is closed.

Examples

julia> b = IOBuffer("my buffer");
 
 julia> eof(b)
 false
@@ -196,7 +196,7 @@
 julia> seekend(b);
 
 julia> eof(b)
-true
source
Base.isreadonlyFunction
isreadonly(io) -> Bool

Determine whether a stream is read-only.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization");
+true
source
Base.isreadonlyFunction
isreadonly(io) -> Bool

Determine whether a stream is read-only.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization");
 
 julia> isreadonly(io)
 true
@@ -204,7 +204,7 @@
 julia> io = IOBuffer();
 
 julia> isreadonly(io)
-false
source
Base.iswritableFunction
iswritable(path::String)

Return true if the access permissions for the given path permitted writing by the current user.

Note

This permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling iswritable first.

Note

Currently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.

Julia 1.11

This function requires at least Julia 1.11.

See also ispath, isexecutable, isreadable.

source
iswritable(io) -> Bool

Return false if the specified IO object is not writable.

Examples

julia> open("myfile.txt", "w") do io
+false
source
Base.iswritableFunction
iswritable(path::String)

Return true if the access permissions for the given path permitted writing by the current user.

Note

This permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling iswritable first.

Note

Currently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.

Julia 1.11

This function requires at least Julia 1.11.

See also ispath, isexecutable, isreadable.

source
iswritable(io) -> Bool

Return false if the specified IO object is not writable.

Examples

julia> open("myfile.txt", "w") do io
            print(io, "Hello world!");
            iswritable(io)
        end
@@ -215,7 +215,7 @@
        end
 false
 
-julia> rm("myfile.txt")
source
Base.isreadableFunction
isreadable(path::String)

Return true if the access permissions for the given path permitted reading by the current user.

Note

This permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling isreadable first.

Note

Currently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.

Julia 1.11

This function requires at least Julia 1.11.

See also ispath, isexecutable, iswritable.

source
isreadable(io) -> Bool

Return false if the specified IO object is not readable.

Examples

julia> open("myfile.txt", "w") do io
+julia> rm("myfile.txt")
source
Base.isreadableFunction
isreadable(path::String)

Return true if the access permissions for the given path permitted reading by the current user.

Note

This permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling isreadable first.

Note

Currently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.

Julia 1.11

This function requires at least Julia 1.11.

See also ispath, isexecutable, iswritable.

source
isreadable(io) -> Bool

Return false if the specified IO object is not readable.

Examples

julia> open("myfile.txt", "w") do io
            print(io, "Hello world!");
            isreadable(io)
        end
@@ -226,7 +226,7 @@
        end
 true
 
-julia> rm("myfile.txt")
source
Base.isexecutableFunction
isexecutable(path::String)

Return true if the given path has executable permissions.

Note

This permission may change before the user executes path, so it is recommended to execute the file and handle the error if that fails, rather than calling isexecutable first.

Note

Prior to Julia 1.6, this did not correctly interrogate filesystem ACLs on Windows, therefore it would return true for any file. From Julia 1.6 on, it correctly determines whether the file is marked as executable or not.

See also ispath, isreadable, iswritable.

source
Base.isopenFunction
isopen(object) -> Bool

Determine whether an object - such as a stream or timer – is not yet closed. Once an object is closed, it will never produce a new event. However, since a closed stream may still have data to read in its buffer, use eof to check for the ability to read data. Use the FileWatching package to be notified when a stream might be writable or readable.

Examples

julia> io = open("my_file.txt", "w+");
+julia> rm("myfile.txt")
source
Base.isexecutableFunction
isexecutable(path::String)

Return true if the given path has executable permissions.

Note

This permission may change before the user executes path, so it is recommended to execute the file and handle the error if that fails, rather than calling isexecutable first.

Note

Prior to Julia 1.6, this did not correctly interrogate filesystem ACLs on Windows, therefore it would return true for any file. From Julia 1.6 on, it correctly determines whether the file is marked as executable or not.

See also ispath, isreadable, iswritable.

source
Base.isopenFunction
isopen(object) -> Bool

Determine whether an object - such as a stream or timer – is not yet closed. Once an object is closed, it will never produce a new event. However, since a closed stream may still have data to read in its buffer, use eof to check for the ability to read data. Use the FileWatching package to be notified when a stream might be writable or readable.

Examples

julia> io = open("my_file.txt", "w+");
 
 julia> isopen(io)
 true
@@ -234,7 +234,7 @@
 julia> close(io)
 
 julia> isopen(io)
-false
source
Base.fdFunction
fd(stream)

Return the file descriptor backing the stream or file. Note that this function only applies to synchronous File's and IOStream's not to any of the asynchronous streams.

source
Base.redirect_stdioFunction
redirect_stdio(;stdin=stdin, stderr=stderr, stdout=stdout)

Redirect a subset of the streams stdin, stderr, stdout. Each argument must be an IOStream, TTY, Pipe, socket, or devnull.

Julia 1.7

redirect_stdio requires Julia 1.7 or later.

source
redirect_stdio(f; stdin=nothing, stderr=nothing, stdout=nothing)

Redirect a subset of the streams stdin, stderr, stdout, call f() and restore each stream.

Possible values for each stream are:

  • nothing indicating the stream should not be redirected.
  • path::AbstractString redirecting the stream to the file at path.
  • io an IOStream, TTY, Pipe, socket, or devnull.

Examples

julia> redirect_stdio(stdout="stdout.txt", stderr="stderr.txt") do
+false
source
Base.fdFunction
fd(stream)

Return the file descriptor backing the stream or file. Note that this function only applies to synchronous File's and IOStream's not to any of the asynchronous streams.

source
Base.redirect_stdioFunction
redirect_stdio(;stdin=stdin, stderr=stderr, stdout=stdout)

Redirect a subset of the streams stdin, stderr, stdout. Each argument must be an IOStream, TTY, Pipe, socket, or devnull.

Julia 1.7

redirect_stdio requires Julia 1.7 or later.

source
redirect_stdio(f; stdin=nothing, stderr=nothing, stdout=nothing)

Redirect a subset of the streams stdin, stderr, stdout, call f() and restore each stream.

Possible values for each stream are:

  • nothing indicating the stream should not be redirected.
  • path::AbstractString redirecting the stream to the file at path.
  • io an IOStream, TTY, Pipe, socket, or devnull.

Examples

julia> redirect_stdio(stdout="stdout.txt", stderr="stderr.txt") do
            print("hello stdout")
            print(stderr, "hello stderr")
        end
@@ -251,12 +251,12 @@
 
 julia> redirect_stdio(f, stdout=io1, stderr=io2) # not supported

Also the stdin argument may not be the same descriptor as stdout or stderr.

julia> io = open(...)
 
-julia> redirect_stdio(f, stdout=io, stdin=io) # not supported
Julia 1.7

redirect_stdio requires Julia 1.7 or later.

source
Base.redirect_stdoutFunction
redirect_stdout([stream]) -> stream

Create a pipe to which all C and Julia level stdout output will be redirected. Return a stream representing the pipe ends. Data written to stdout may now be read from the rd end of the pipe.

Note

stream must be a compatible objects, such as an IOStream, TTY, Pipe, socket, or devnull.

See also redirect_stdio.

source
Base.redirect_stdinMethod
redirect_stdin(f::Function, stream)

Run the function f while redirecting stdin to stream. Upon completion, stdin is restored to its prior setting.

source
Base.readchompFunction
readchomp(x)

Read the entirety of x as a string and remove a single trailing newline if there is one. Equivalent to chomp(read(x, String)).

Examples

julia> write("my_file.txt", "JuliaLang is a GitHub organization.\nIt has many members.\n");
+julia> redirect_stdio(f, stdout=io, stdin=io) # not supported
Julia 1.7

redirect_stdio requires Julia 1.7 or later.

source
Base.redirect_stdoutFunction
redirect_stdout([stream]) -> stream

Create a pipe to which all C and Julia level stdout output will be redirected. Return a stream representing the pipe ends. Data written to stdout may now be read from the rd end of the pipe.

Note

stream must be a compatible objects, such as an IOStream, TTY, Pipe, socket, or devnull.

See also redirect_stdio.

source
Base.redirect_stdinMethod
redirect_stdin(f::Function, stream)

Run the function f while redirecting stdin to stream. Upon completion, stdin is restored to its prior setting.

source
Base.readchompFunction
readchomp(x)

Read the entirety of x as a string and remove a single trailing newline if there is one. Equivalent to chomp(read(x, String)).

Examples

julia> write("my_file.txt", "JuliaLang is a GitHub organization.\nIt has many members.\n");
 
 julia> readchomp("my_file.txt")
 "JuliaLang is a GitHub organization.\nIt has many members."
 
-julia> rm("my_file.txt");
source
Base.truncateFunction
truncate(file, n)

Resize the file or buffer given by the first argument to exactly n bytes, filling previously unallocated space with '\0' if the file or buffer is grown.

Examples

julia> io = IOBuffer();
+julia> rm("my_file.txt");
source
Base.truncateFunction
truncate(file, n)

Resize the file or buffer given by the first argument to exactly n bytes, filling previously unallocated space with '\0' if the file or buffer is grown.

Examples

julia> io = IOBuffer();
 
 julia> write(io, "JuliaLang is a GitHub organization.")
 35
@@ -274,14 +274,14 @@
 julia> truncate(io, 40);
 
 julia> String(take!(io))
-"JuliaLang is a GitHub organization.\0\0\0\0\0"
source
Base.skipcharsFunction
skipchars(predicate, io::IO; linecomment=nothing)

Advance the stream io such that the next-read character will be the first remaining for which predicate returns false. If the keyword argument linecomment is specified, all characters from that character until the start of the next line are ignored.

Examples

julia> buf = IOBuffer("    text")
+"JuliaLang is a GitHub organization.\0\0\0\0\0"
source
Base.skipcharsFunction
skipchars(predicate, io::IO; linecomment=nothing)

Advance the stream io such that the next-read character will be the first remaining for which predicate returns false. If the keyword argument linecomment is specified, all characters from that character until the start of the next line are ignored.

Examples

julia> buf = IOBuffer("    text")
 IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=1, mark=-1)
 
 julia> skipchars(isspace, buf)
 IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=5, mark=-1)
 
 julia> String(readavailable(buf))
-"text"
source
Base.countlinesFunction
countlines(io::IO; eol::AbstractChar = '\n')
 countlines(filename::AbstractString; eol::AbstractChar = '\n')

Read io until the end of the stream/file and count the number of lines. To specify a file pass the filename as the first argument. EOL markers other than '\n' are supported by passing them as the second argument. The last non-empty line of io is counted even if it does not end with the EOL, matching the length returned by eachline and readlines.

To count lines of a String, countlines(IOBuffer(str)) can be used.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization.\n");
 
 julia> countlines(io)
@@ -308,7 +308,7 @@
 4
 
 julia> rm("my_file.txt")
-
source
Base.PipeBufferFunction
PipeBuffer(data::AbstractVector{UInt8}=UInt8[]; maxsize::Integer = typemax(Int))

An IOBuffer that allows reading and performs writes by appending. Seeking and truncating are not supported. See IOBuffer for the available constructors. If data is given, creates a PipeBuffer to operate on a data vector, optionally specifying a size beyond which the underlying Array may not be grown.

source
Base.readavailableFunction
readavailable(stream)

Read available buffered data from a stream. Actual I/O is performed only if no data has already been buffered. The result is a Vector{UInt8}.

Warning

The amount of data returned is implementation-dependent; for example it can depend on the internal choice of buffer size. Other functions such as read should generally be used instead.

source
Base.IOContextType
IOContext

IOContext provides a mechanism for passing output configuration settings among show methods.

In short, it is an immutable dictionary that is a subclass of IO. It supports standard dictionary operations such as getindex, and can also be used as an I/O stream.

source
Base.IOContextMethod
IOContext(io::IO, KV::Pair...)

Create an IOContext that wraps a given stream, adding the specified key=>value pairs to the properties of that stream (note that io can itself be an IOContext).

  • use (key => value) in io to see if this particular combination is in the properties set
  • use get(io, key, default) to retrieve the most recent value for a particular key

The following properties are in common use:

  • :compact: Boolean specifying that values should be printed more compactly, e.g. that numbers should be printed with fewer digits. This is set when printing array elements. :compact output should not contain line breaks.
  • :limit: Boolean specifying that containers should be truncated, e.g. showing in place of most elements.
  • :displaysize: A Tuple{Int,Int} giving the size in rows and columns to use for text output. This can be used to override the display size for called functions, but to get the size of the screen use the displaysize function.
  • :typeinfo: a Type characterizing the information already printed concerning the type of the object about to be displayed. This is mainly useful when displaying a collection of objects of the same type, so that redundant type information can be avoided (e.g. [Float16(0)] can be shown as "Float16[0.0]" instead of "Float16[Float16(0.0)]" : while displaying the elements of the array, the :typeinfo property will be set to Float16).
  • :color: Boolean specifying whether ANSI color/escape codes are supported/expected. By default, this is determined by whether io is a compatible terminal and by any --color command-line flag when julia was launched.

Examples

julia> io = IOBuffer();
+
source
Base.PipeBufferFunction
PipeBuffer(data::AbstractVector{UInt8}=UInt8[]; maxsize::Integer = typemax(Int))

An IOBuffer that allows reading and performs writes by appending. Seeking and truncating are not supported. See IOBuffer for the available constructors. If data is given, creates a PipeBuffer to operate on a data vector, optionally specifying a size beyond which the underlying Array may not be grown.

source
Base.readavailableFunction
readavailable(stream)

Read available buffered data from a stream. Actual I/O is performed only if no data has already been buffered. The result is a Vector{UInt8}.

Warning

The amount of data returned is implementation-dependent; for example it can depend on the internal choice of buffer size. Other functions such as read should generally be used instead.

source
Base.IOContextType
IOContext

IOContext provides a mechanism for passing output configuration settings among show methods.

In short, it is an immutable dictionary that is a subclass of IO. It supports standard dictionary operations such as getindex, and can also be used as an I/O stream.

source
Base.IOContextMethod
IOContext(io::IO, KV::Pair...)

Create an IOContext that wraps a given stream, adding the specified key=>value pairs to the properties of that stream (note that io can itself be an IOContext).

  • use (key => value) in io to see if this particular combination is in the properties set
  • use get(io, key, default) to retrieve the most recent value for a particular key

The following properties are in common use:

  • :compact: Boolean specifying that values should be printed more compactly, e.g. that numbers should be printed with fewer digits. This is set when printing array elements. :compact output should not contain line breaks.
  • :limit: Boolean specifying that containers should be truncated, e.g. showing in place of most elements.
  • :displaysize: A Tuple{Int,Int} giving the size in rows and columns to use for text output. This can be used to override the display size for called functions, but to get the size of the screen use the displaysize function.
  • :typeinfo: a Type characterizing the information already printed concerning the type of the object about to be displayed. This is mainly useful when displaying a collection of objects of the same type, so that redundant type information can be avoided (e.g. [Float16(0)] can be shown as "Float16[0.0]" instead of "Float16[Float16(0.0)]" : while displaying the elements of the array, the :typeinfo property will be set to Float16).
  • :color: Boolean specifying whether ANSI color/escape codes are supported/expected. By default, this is determined by whether io is a compatible terminal and by any --color command-line flag when julia was launched.

Examples

julia> io = IOBuffer();
 
 julia> printstyled(IOContext(io, :color => true), "string", color=:red)
 
@@ -333,22 +333,22 @@
 julia> f(stdout)
 loooooong
 julia> f(IOContext(stdout, :short => true))
-short
source
Base.IOContextMethod
IOContext(io::IO, context::IOContext)

Create an IOContext that wraps an alternate IO but inherits the properties of context.

source

Text I/O

Base.showMethod
show([io::IO = stdout], x)

Write a text representation of a value x to the output stream io. New types T should overload show(io::IO, x::T). The representation used by show generally includes Julia-specific formatting and type information, and should be parseable Julia code when possible.

repr returns the output of show as a string.

For a more verbose human-readable text output for objects of type T, define show(io::IO, ::MIME"text/plain", ::T) in addition. Checking the :compact IOContext key (often checked as get(io, :compact, false)::Bool) of io in such methods is recommended, since some containers show their elements by calling this method with :compact => true.

See also print, which writes un-decorated representations.

Examples

julia> show("Hello World!")
+short
source
Base.IOContextMethod
IOContext(io::IO, context::IOContext)

Create an IOContext that wraps an alternate IO but inherits the properties of context.

source

Text I/O

Base.showMethod
show([io::IO = stdout], x)

Write a text representation of a value x to the output stream io. New types T should overload show(io::IO, x::T). The representation used by show generally includes Julia-specific formatting and type information, and should be parseable Julia code when possible.

repr returns the output of show as a string.

For a more verbose human-readable text output for objects of type T, define show(io::IO, ::MIME"text/plain", ::T) in addition. Checking the :compact IOContext key (often checked as get(io, :compact, false)::Bool) of io in such methods is recommended, since some containers show their elements by calling this method with :compact => true.

See also print, which writes un-decorated representations.

Examples

julia> show("Hello World!")
 "Hello World!"
 julia> print("Hello World!")
-Hello World!
source
Base.summaryFunction
summary(io::IO, x)
 str = summary(x)

Print to a stream io, or return a string str, giving a brief description of a value. By default returns string(typeof(x)), e.g. Int64.

For arrays, returns a string of size and type info, e.g. 10-element Array{Int64,1}.

Examples

julia> summary(1)
 "Int64"
 
 julia> summary(zeros(2))
-"2-element Vector{Float64}"
source
Base.printFunction
print([io::IO], xs...)

Write to io (or to the default output stream stdout if io is not given) a canonical (un-decorated) text representation. The representation used by print includes minimal formatting and tries to avoid Julia-specific details.

print falls back to calling show, so most types should just define show. Define print if your type has a separate "plain" representation. For example, show displays strings with quotes, and print displays strings without quotes.

See also println, string, printstyled.

Examples

julia> print("Hello World!")
+"2-element Vector{Float64}"
source
Base.printFunction
print([io::IO], xs...)

Write to io (or to the default output stream stdout if io is not given) a canonical (un-decorated) text representation. The representation used by print includes minimal formatting and tries to avoid Julia-specific details.

print falls back to calling show, so most types should just define show. Define print if your type has a separate "plain" representation. For example, show displays strings with quotes, and print displays strings without quotes.

See also println, string, printstyled.

Examples

julia> print("Hello World!")
 Hello World!
 julia> io = IOBuffer();
 
 julia> print(io, "Hello", ' ', :World!)
 
 julia> String(take!(io))
-"Hello World!"
source
Base.printlnFunction
println([io::IO], xs...)

Print (using print) xs to io followed by a newline. If io is not supplied, prints to the default output stream stdout.

See also printstyled to add colors etc.

Examples

julia> println("Hello, world")
+"Hello World!"
source
Base.printlnFunction
println([io::IO], xs...)

Print (using print) xs to io followed by a newline. If io is not supplied, prints to the default output stream stdout.

See also printstyled to add colors etc.

Examples

julia> println("Hello, world")
 Hello, world
 
 julia> io = IOBuffer();
@@ -356,11 +356,11 @@
 julia> println(io, "Hello", ',', " world.")
 
 julia> String(take!(io))
-"Hello, world.\n"
source
Base.printstyledFunction
printstyled([io], xs...; bold::Bool=false, italic::Bool=false, underline::Bool=false, blink::Bool=false, reverse::Bool=false, hidden::Bool=false, color::Union{Symbol,Int}=:normal)

Print xs in a color specified as a symbol or integer, optionally in bold.

Keyword color may take any of the values :normal, :italic, :default, :bold, :black, :blink, :blue, :cyan, :green, :hidden, :light_black, :light_blue, :light_cyan, :light_green, :light_magenta, :light_red, :light_white, :light_yellow, :magenta, :nothing, :red, :reverse, :underline, :white, or :yellow or an integer between 0 and 255 inclusive. Note that not all terminals support 256 colors.

Keywords bold=true, italic=true, underline=true, blink=true are self-explanatory. Keyword reverse=true prints with foreground and background colors exchanged, and hidden=true should be invisible in the terminal but can still be copied. These properties can be used in any combination.

See also print, println, show.

Note

Not all terminals support italic output. Some terminals interpret italic as reverse or blink.

Julia 1.7

Keywords except color and bold were added in Julia 1.7.

Julia 1.10

Support for italic output was added in Julia 1.10.

source
Base.sprintFunction
sprint(f::Function, args...; context=nothing, sizehint=0)

Call the given function with an I/O stream and the supplied extra arguments. Everything written to this I/O stream is returned as a string. context can be an IOContext whose properties will be used, a Pair specifying a property and its value, or a tuple of Pair specifying multiple properties and their values. sizehint suggests the capacity of the buffer (in bytes).

The optional keyword argument context can be set to a :key=>value pair, a tuple of :key=>value pairs, or an IO or IOContext object whose attributes are used for the I/O stream passed to f. The optional sizehint is a suggested size (in bytes) to allocate for the buffer used to write the string.

Julia 1.7

Passing a tuple to keyword context requires Julia 1.7 or later.

Examples

julia> sprint(show, 66.66666; context=:compact => true)
+"Hello, world.\n"
source
Base.printstyledFunction
printstyled([io], xs...; bold::Bool=false, italic::Bool=false, underline::Bool=false, blink::Bool=false, reverse::Bool=false, hidden::Bool=false, color::Union{Symbol,Int}=:normal)

Print xs in a color specified as a symbol or integer, optionally in bold.

Keyword color may take any of the values :normal, :italic, :default, :bold, :black, :blink, :blue, :cyan, :green, :hidden, :light_black, :light_blue, :light_cyan, :light_green, :light_magenta, :light_red, :light_white, :light_yellow, :magenta, :nothing, :red, :reverse, :underline, :white, or :yellow or an integer between 0 and 255 inclusive. Note that not all terminals support 256 colors.

Keywords bold=true, italic=true, underline=true, blink=true are self-explanatory. Keyword reverse=true prints with foreground and background colors exchanged, and hidden=true should be invisible in the terminal but can still be copied. These properties can be used in any combination.

See also print, println, show.

Note

Not all terminals support italic output. Some terminals interpret italic as reverse or blink.

Julia 1.7

Keywords except color and bold were added in Julia 1.7.

Julia 1.10

Support for italic output was added in Julia 1.10.

source
Base.sprintFunction
sprint(f::Function, args...; context=nothing, sizehint=0)

Call the given function with an I/O stream and the supplied extra arguments. Everything written to this I/O stream is returned as a string. context can be an IOContext whose properties will be used, a Pair specifying a property and its value, or a tuple of Pair specifying multiple properties and their values. sizehint suggests the capacity of the buffer (in bytes).

The optional keyword argument context can be set to a :key=>value pair, a tuple of :key=>value pairs, or an IO or IOContext object whose attributes are used for the I/O stream passed to f. The optional sizehint is a suggested size (in bytes) to allocate for the buffer used to write the string.

Julia 1.7

Passing a tuple to keyword context requires Julia 1.7 or later.

Examples

julia> sprint(show, 66.66666; context=:compact => true)
 "66.6667"
 
 julia> sprint(showerror, BoundsError([1], 100))
-"BoundsError: attempt to access 1-element Vector{Int64} at index [100]"
source
Base.showerrorFunction
showerror(io, e)

Show a descriptive representation of an exception object e. This method is used to display the exception after a call to throw.

Examples

julia> struct MyException <: Exception
+"BoundsError: attempt to access 1-element Vector{Int64} at index [100]"
source
Base.showerrorFunction
showerror(io, e)

Show a descriptive representation of an exception object e. This method is used to display the exception after a call to throw.

Examples

julia> struct MyException <: Exception
            msg::String
        end
 
@@ -376,7 +376,7 @@
 "MyException: test exception"
 
 julia> throw(MyException("test exception"))
-ERROR: MyException: test exception
source
Base.dumpFunction
dump(x; maxdepth=8)

Show every part of the representation of a value. The depth of the output is truncated at maxdepth.

Examples

julia> struct MyStruct
+ERROR: MyException: test exception
source
Base.dumpFunction
dump(x; maxdepth=8)

Show every part of the representation of a value. The depth of the output is truncated at maxdepth.

Examples

julia> struct MyStruct
            x
            y
        end
@@ -393,7 +393,7 @@
 julia> dump(x; maxdepth = 1)
 MyStruct
   x: Int64 1
-  y: Tuple{Int64, Int64}
source
Base.readlineFunction
readline(io::IO=stdin; keep::Bool=false)
+  y: Tuple{Int64, Int64}
source
Base.readlineFunction
readline(io::IO=stdin; keep::Bool=false)
 readline(filename::AbstractString; keep::Bool=false)

Read a single line of text from the given I/O stream or file (defaults to stdin). When reading from a file, the text is assumed to be encoded in UTF-8. Lines in the input end with '\n' or "\r\n" or the end of an input stream. When keep is false (as it is by default), these trailing newline characters are removed from the line before it is returned. When keep is true, they are returned as part of the line.

Return a String. See also copyline to instead write in-place to another stream (which can be a preallocated IOBuffer).

See also readuntil for reading until more general delimiters.

Examples

julia> write("my_file.txt", "JuliaLang is a GitHub organization.\nIt has many members.\n");
 
 julia> readline("my_file.txt")
@@ -407,7 +407,7 @@
 
 julia> your_name = readline()
 Logan
-"Logan"
source
Base.readuntilFunction
readuntil(stream::IO, delim; keep::Bool = false)
 readuntil(filename::AbstractString, delim; keep::Bool = false)

Read a string from an I/O stream or a file, up to the given delimiter. The delimiter can be a UInt8, AbstractChar, string, or vector. Keyword argument keep controls whether the delimiter is included in the result. The text is assumed to be encoded in UTF-8.

Return a String if delim is an AbstractChar or a string or otherwise return a Vector{typeof(delim)}. See also copyuntil to instead write in-place to another stream (which can be a preallocated IOBuffer).

Examples

julia> write("my_file.txt", "JuliaLang is a GitHub organization.\nIt has many members.\n");
 
 julia> readuntil("my_file.txt", 'L')
@@ -416,7 +416,7 @@
 julia> readuntil("my_file.txt", '.', keep = true)
 "JuliaLang is a GitHub organization."
 
-julia> rm("my_file.txt")
source
Base.readlinesFunction
readlines(io::IO=stdin; keep::Bool=false)
+julia> rm("my_file.txt")
source
Base.readlinesFunction
readlines(io::IO=stdin; keep::Bool=false)
 readlines(filename::AbstractString; keep::Bool=false)

Read all lines of an I/O stream or a file as a vector of strings. Behavior is equivalent to saving the result of reading readline repeatedly with the same arguments and saving the resulting lines as a vector of strings. See also eachline to iterate over the lines without reading them all at once.

Examples

julia> write("my_file.txt", "JuliaLang is a GitHub organization.\nIt has many members.\n");
 
 julia> readlines("my_file.txt")
@@ -429,7 +429,7 @@
  "JuliaLang is a GitHub organization.\n"
  "It has many members.\n"
 
-julia> rm("my_file.txt")
source
Base.eachlineFunction
eachline(io::IO=stdin; keep::Bool=false)
+julia> rm("my_file.txt")
source
Base.eachlineFunction
eachline(io::IO=stdin; keep::Bool=false)
 eachline(filename::AbstractString; keep::Bool=false)

Create an iterable EachLine object that will yield each line from an I/O stream or a file. Iteration calls readline on the stream argument repeatedly with keep passed through, determining whether trailing end-of-line characters are retained. When called with a file name, the file is opened once at the beginning of iteration and closed at the end. If iteration is interrupted, the file will be closed when the EachLine object is garbage collected.

To iterate over each line of a String, eachline(IOBuffer(str)) can be used.

Iterators.reverse can be used on an EachLine object to read the lines in reverse order (for files, buffers, and other I/O streams supporting seek), and first or last can be used to extract the initial or final lines, respectively.

Examples

julia> write("my_file.txt", "JuliaLang is a GitHub organization.\n It has many members.\n");
 
 julia> for line in eachline("my_file.txt")
@@ -437,7 +437,7 @@
        end
 JuliaLang is a GitHub organization. It has many members.
 
-julia> rm("my_file.txt");
Julia 1.8

Julia 1.8 is required to use Iterators.reverse or last with eachline iterators.

source
Base.copylineFunction
copyline(out::IO, io::IO=stdin; keep::Bool=false)
+julia> rm("my_file.txt");
Julia 1.8

Julia 1.8 is required to use Iterators.reverse or last with eachline iterators.

source
Base.copylineFunction
copyline(out::IO, io::IO=stdin; keep::Bool=false)
 copyline(out::IO, filename::AbstractString; keep::Bool=false)

Copy a single line of text from an I/O stream or a file to the out stream, returning out.

When reading from a file, the text is assumed to be encoded in UTF-8. Lines in the input end with '\n' or "\r\n" or the end of an input stream. When keep is false (as it is by default), these trailing newline characters are removed from the line before it is returned. When keep is true, they are returned as part of the line.

Similar to readline, which returns a String; in contrast, copyline writes directly to out, without allocating a string. (This can be used, for example, to read data into a pre-allocated IOBuffer.)

See also copyuntil for reading until more general delimiters.

Examples

julia> write("my_file.txt", "JuliaLang is a GitHub organization.\nIt has many members.\n");
 
 julia> String(take!(copyline(IOBuffer(), "my_file.txt")))
@@ -446,7 +446,7 @@
 julia> String(take!(copyline(IOBuffer(), "my_file.txt", keep=true)))
 "JuliaLang is a GitHub organization.\n"
 
-julia> rm("my_file.txt")
source
Base.copyuntilFunction
copyuntil(out::IO, stream::IO, delim; keep::Bool = false)
+julia> rm("my_file.txt")
source
Base.copyuntilFunction
copyuntil(out::IO, stream::IO, delim; keep::Bool = false)
 copyuntil(out::IO, filename::AbstractString, delim; keep::Bool = false)

Copy a string from an I/O stream or a file, up to the given delimiter, to the out stream, returning out. The delimiter can be a UInt8, AbstractChar, string, or vector. Keyword argument keep controls whether the delimiter is included in the result. The text is assumed to be encoded in UTF-8.

Similar to readuntil, which returns a String; in contrast, copyuntil writes directly to out, without allocating a string. (This can be used, for example, to read data into a pre-allocated IOBuffer.)

Examples

julia> write("my_file.txt", "JuliaLang is a GitHub organization.\nIt has many members.\n");
 
 julia> String(take!(copyuntil(IOBuffer(), "my_file.txt", 'L')))
@@ -455,38 +455,38 @@
 julia> String(take!(copyuntil(IOBuffer(), "my_file.txt", '.', keep = true)))
 "JuliaLang is a GitHub organization."
 
-julia> rm("my_file.txt")
source
Base.displaysizeFunction
displaysize([io::IO]) -> (lines, columns)

Return the nominal size of the screen that may be used for rendering output to this IO object. If no input is provided, the environment variables LINES and COLUMNS are read. If those are not set, a default size of (24, 80) is returned.

Examples

julia> withenv("LINES" => 30, "COLUMNS" => 100) do
+julia> rm("my_file.txt")
source
Base.displaysizeFunction
displaysize([io::IO]) -> (lines, columns)

Return the nominal size of the screen that may be used for rendering output to this IO object. If no input is provided, the environment variables LINES and COLUMNS are read. If those are not set, a default size of (24, 80) is returned.

Examples

julia> withenv("LINES" => 30, "COLUMNS" => 100) do
            displaysize()
        end
 (30, 100)

To get your TTY size,

julia> displaysize(stdout)
-(34, 147)
source

Multimedia I/O

Just as text output is performed by print and user-defined types can indicate their textual representation by overloading show, Julia provides a standardized mechanism for rich multimedia output (such as images, formatted text, or even audio and video), consisting of three parts:

  • A function display(x) to request the richest available multimedia display of a Julia object x (with a plain-text fallback).
  • Overloading show allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types.
  • Multimedia-capable display backends may be registered by subclassing a generic AbstractDisplay type and pushing them onto a stack of display backends via pushdisplay.

The base Julia runtime provides only plain-text display, but richer displays may be enabled by loading external modules or by using graphical Julia environments (such as the IPython-based IJulia notebook).

Multimedia I/O

Just as text output is performed by print and user-defined types can indicate their textual representation by overloading show, Julia provides a standardized mechanism for rich multimedia output (such as images, formatted text, or even audio and video), consisting of three parts:

  • A function display(x) to request the richest available multimedia display of a Julia object x (with a plain-text fallback).
  • Overloading show allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types.
  • Multimedia-capable display backends may be registered by subclassing a generic AbstractDisplay type and pushing them onto a stack of display backends via pushdisplay.

The base Julia runtime provides only plain-text display, but richer displays may be enabled by loading external modules or by using graphical Julia environments (such as the IPython-based IJulia notebook).

Base.Multimedia.displayFunction
display(x)
 display(d::AbstractDisplay, x)
 display(mime, x)
-display(d::AbstractDisplay, mime, x)

Display x using the topmost applicable display in the display stack, typically using the richest supported multimedia output for x, with plain-text stdout output as a fallback. The display(d, x) variant attempts to display x on the given display d only, throwing a MethodError if d cannot display objects of this type.

In general, you cannot assume that display output goes to stdout (unlike print(x) or show(x)). For example, display(x) may open up a separate window with an image. display(x) means "show x in the best way you can for the current output device(s)." If you want REPL-like text output that is guaranteed to go to stdout, use show(stdout, "text/plain", x) instead.

There are also two variants with a mime argument (a MIME type string, such as "image/png"), which attempt to display x using the requested MIME type only, throwing a MethodError if this type is not supported by either the display(s) or by x. With these variants, one can also supply the "raw" data in the requested MIME type by passing x::AbstractString (for MIME types with text-based storage, such as text/html or application/postscript) or x::Vector{UInt8} (for binary MIME types).

To customize how instances of a type are displayed, overload show rather than display, as explained in the manual section on custom pretty-printing.

source
Base.Multimedia.redisplayFunction
redisplay(x)
+display(d::AbstractDisplay, mime, x)

Display x using the topmost applicable display in the display stack, typically using the richest supported multimedia output for x, with plain-text stdout output as a fallback. The display(d, x) variant attempts to display x on the given display d only, throwing a MethodError if d cannot display objects of this type.

In general, you cannot assume that display output goes to stdout (unlike print(x) or show(x)). For example, display(x) may open up a separate window with an image. display(x) means "show x in the best way you can for the current output device(s)." If you want REPL-like text output that is guaranteed to go to stdout, use show(stdout, "text/plain", x) instead.

There are also two variants with a mime argument (a MIME type string, such as "image/png"), which attempt to display x using the requested MIME type only, throwing a MethodError if this type is not supported by either the display(s) or by x. With these variants, one can also supply the "raw" data in the requested MIME type by passing x::AbstractString (for MIME types with text-based storage, such as text/html or application/postscript) or x::Vector{UInt8} (for binary MIME types).

To customize how instances of a type are displayed, overload show rather than display, as explained in the manual section on custom pretty-printing.

source
Base.Multimedia.redisplayFunction
redisplay(x)
 redisplay(d::AbstractDisplay, x)
 redisplay(mime, x)
-redisplay(d::AbstractDisplay, mime, x)

By default, the redisplay functions simply call display. However, some display backends may override redisplay to modify an existing display of x (if any). Using redisplay is also a hint to the backend that x may be redisplayed several times, and the backend may choose to defer the display until (for example) the next interactive prompt.

source
Base.Multimedia.displayableFunction
displayable(mime) -> Bool
-displayable(d::AbstractDisplay, mime) -> Bool

Return a boolean value indicating whether the given mime type (string) is displayable by any of the displays in the current display stack, or specifically by the display d in the second variant.

source
Base.showMethod
show(io::IO, mime, x)

The display functions ultimately call show in order to write an object x as a given mime type to a given I/O stream io (usually a memory buffer), if possible. In order to provide a rich multimedia representation of a user-defined type T, it is only necessary to define a new show method for T, via: show(io, ::MIME"mime", x::T) = ..., where mime is a MIME-type string and the function body calls write (or similar) to write that representation of x to io. (Note that the MIME"" notation only supports literal strings; to construct MIME types in a more flexible manner use MIME{Symbol("")}.)

For example, if you define a MyImage type and know how to write it to a PNG file, you could define a function show(io, ::MIME"image/png", x::MyImage) = ... to allow your images to be displayed on any PNG-capable AbstractDisplay (such as IJulia). As usual, be sure to import Base.show in order to add new methods to the built-in Julia function show.

Technically, the MIME"mime" macro defines a singleton type for the given mime string, which allows us to exploit Julia's dispatch mechanisms in determining how to display objects of any given type.

The default MIME type is MIME"text/plain". There is a fallback definition for text/plain output that calls show with 2 arguments, so it is not always necessary to add a method for that case. If a type benefits from custom human-readable output though, show(::IO, ::MIME"text/plain", ::T) should be defined. For example, the Day type uses 1 day as the output for the text/plain MIME type, and Day(1) as the output of 2-argument show.

Examples

julia> struct Day
+redisplay(d::AbstractDisplay, mime, x)

By default, the redisplay functions simply call display. However, some display backends may override redisplay to modify an existing display of x (if any). Using redisplay is also a hint to the backend that x may be redisplayed several times, and the backend may choose to defer the display until (for example) the next interactive prompt.

source
Base.Multimedia.displayableFunction
displayable(mime) -> Bool
+displayable(d::AbstractDisplay, mime) -> Bool

Return a boolean value indicating whether the given mime type (string) is displayable by any of the displays in the current display stack, or specifically by the display d in the second variant.

source
Base.showMethod
show(io::IO, mime, x)

The display functions ultimately call show in order to write an object x as a given mime type to a given I/O stream io (usually a memory buffer), if possible. In order to provide a rich multimedia representation of a user-defined type T, it is only necessary to define a new show method for T, via: show(io, ::MIME"mime", x::T) = ..., where mime is a MIME-type string and the function body calls write (or similar) to write that representation of x to io. (Note that the MIME"" notation only supports literal strings; to construct MIME types in a more flexible manner use MIME{Symbol("")}.)

For example, if you define a MyImage type and know how to write it to a PNG file, you could define a function show(io, ::MIME"image/png", x::MyImage) = ... to allow your images to be displayed on any PNG-capable AbstractDisplay (such as IJulia). As usual, be sure to import Base.show in order to add new methods to the built-in Julia function show.

Technically, the MIME"mime" macro defines a singleton type for the given mime string, which allows us to exploit Julia's dispatch mechanisms in determining how to display objects of any given type.

The default MIME type is MIME"text/plain". There is a fallback definition for text/plain output that calls show with 2 arguments, so it is not always necessary to add a method for that case. If a type benefits from custom human-readable output though, show(::IO, ::MIME"text/plain", ::T) should be defined. For example, the Day type uses 1 day as the output for the text/plain MIME type, and Day(1) as the output of 2-argument show.

Examples

julia> struct Day
            n::Int
        end
 
 julia> Base.show(io::IO, ::MIME"text/plain", d::Day) = print(io, d.n, " day")
 
 julia> Day(1)
-1 day

Container types generally implement 3-argument show by calling show(io, MIME"text/plain"(), x) for elements x, with :compact => true set in an IOContext passed as the first argument.

source
Base.Multimedia.showableFunction
showable(mime, x)

Return a boolean value indicating whether or not the object x can be written as the given mime type.

(By default, this is determined automatically by the existence of the corresponding show method for typeof(x). Some types provide custom showable methods; for example, if the available MIME formats depend on the value of x.)

Examples

julia> showable(MIME("text/plain"), rand(5))
+1 day

Container types generally implement 3-argument show by calling show(io, MIME"text/plain"(), x) for elements x, with :compact => true set in an IOContext passed as the first argument.

source
Base.Multimedia.showableFunction
showable(mime, x)

Return a boolean value indicating whether or not the object x can be written as the given mime type.

(By default, this is determined automatically by the existence of the corresponding show method for typeof(x). Some types provide custom showable methods; for example, if the available MIME formats depend on the value of x.)

Examples

julia> showable(MIME("text/plain"), rand(5))
 true
 
 julia> showable("image/png", rand(5))
-false
source
Base.reprMethod
repr(mime, x; context=nothing)

Return an AbstractString or Vector{UInt8} containing the representation of x in the requested mime type, as written by show(io, mime, x) (throwing a MethodError if no appropriate show is available). An AbstractString is returned for MIME types with textual representations (such as "text/html" or "application/postscript"), whereas binary data is returned as Vector{UInt8}. (The function istextmime(mime) returns whether or not Julia treats a given mime type as text.)

The optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to show.

As a special case, if x is an AbstractString (for textual MIME types) or a Vector{UInt8} (for binary MIME types), the repr function assumes that x is already in the requested mime format and simply returns x. This special case does not apply to the "text/plain" MIME type. This is useful so that raw data can be passed to display(m::MIME, x).

In particular, repr("text/plain", x) is typically a "pretty-printed" version of x designed for human consumption. See also repr(x) to instead return a string corresponding to show(x) that may be closer to how the value of x would be entered in Julia.

Examples

julia> A = [1 2; 3 4];
+false
source
Base.reprMethod
repr(mime, x; context=nothing)

Return an AbstractString or Vector{UInt8} containing the representation of x in the requested mime type, as written by show(io, mime, x) (throwing a MethodError if no appropriate show is available). An AbstractString is returned for MIME types with textual representations (such as "text/html" or "application/postscript"), whereas binary data is returned as Vector{UInt8}. (The function istextmime(mime) returns whether or not Julia treats a given mime type as text.)

The optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to show.

As a special case, if x is an AbstractString (for textual MIME types) or a Vector{UInt8} (for binary MIME types), the repr function assumes that x is already in the requested mime format and simply returns x. This special case does not apply to the "text/plain" MIME type. This is useful so that raw data can be passed to display(m::MIME, x).

In particular, repr("text/plain", x) is typically a "pretty-printed" version of x designed for human consumption. See also repr(x) to instead return a string corresponding to show(x) that may be closer to how the value of x would be entered in Julia.

Examples

julia> A = [1 2; 3 4];
 
 julia> repr("text/plain", A)
-"2×2 Matrix{Int64}:\n 1  2\n 3  4"
source
Base.Multimedia.MIMEType
MIME

A type representing a standard internet data format. "MIME" stands for "Multipurpose Internet Mail Extensions", since the standard was originally used to describe multimedia attachments to email messages.

A MIME object can be passed as the second argument to show to request output in that format.

Examples

julia> show(stdout, MIME("text/plain"), "hi")
-"hi"
source
Base.Multimedia.@MIME_strMacro
@MIME_str

A convenience macro for writing MIME types, typically used when adding methods to show. For example the syntax show(io::IO, ::MIME"text/html", x::MyType) = ... could be used to define how to write an HTML representation of MyType.

source

As mentioned above, one can also define new display backends. For example, a module that can display PNG images in a window can register this capability with Julia, so that calling display(x) on types with PNG representations will automatically display the image using the module's window.

In order to define a new display backend, one should first create a subtype D of the abstract class AbstractDisplay. Then, for each MIME type (mime string) that can be displayed on D, one should define a function display(d::D, ::MIME"mime", x) = ... that displays x as that MIME type, usually by calling show(io, mime, x) or repr(io, mime, x). A MethodError should be thrown if x cannot be displayed as that MIME type; this is automatic if one calls show or repr. Finally, one should define a function display(d::D, x) that queries showable(mime, x) for the mime types supported by D and displays the "best" one; a MethodError should be thrown if no supported MIME types are found for x. Similarly, some subtypes may wish to override redisplay(d::D, ...). (Again, one should import Base.display to add new methods to display.) The return values of these functions are up to the implementation (since in some cases it may be useful to return a display "handle" of some type). The display functions for D can then be called directly, but they can also be invoked automatically from display(x) simply by pushing a new display onto the display-backend stack with:

Base.Multimedia.pushdisplayFunction
pushdisplay(d::AbstractDisplay)

Pushes a new display d on top of the global display-backend stack. Calling display(x) or display(mime, x) will display x on the topmost compatible backend in the stack (i.e., the topmost backend that does not throw a MethodError).

source
Base.Multimedia.popdisplayFunction
popdisplay()
-popdisplay(d::AbstractDisplay)

Pop the topmost backend off of the display-backend stack, or the topmost copy of d in the second variant.

source
Base.Multimedia.TextDisplayType
TextDisplay(io::IO)

Return a TextDisplay <: AbstractDisplay, which displays any object as the text/plain MIME type (by default), writing the text representation to the given I/O stream. (This is how objects are printed in the Julia REPL.)

source
Base.Multimedia.istextmimeFunction
istextmime(m::MIME)

Determine whether a MIME type is text data. MIME types are assumed to be binary data except for a set of types known to be text data (possibly Unicode).

Examples

julia> istextmime(MIME("text/plain"))
+"2×2 Matrix{Int64}:\n 1  2\n 3  4"
source
Base.Multimedia.MIMEType
MIME

A type representing a standard internet data format. "MIME" stands for "Multipurpose Internet Mail Extensions", since the standard was originally used to describe multimedia attachments to email messages.

A MIME object can be passed as the second argument to show to request output in that format.

Examples

julia> show(stdout, MIME("text/plain"), "hi")
+"hi"
source
Base.Multimedia.@MIME_strMacro
@MIME_str

A convenience macro for writing MIME types, typically used when adding methods to show. For example the syntax show(io::IO, ::MIME"text/html", x::MyType) = ... could be used to define how to write an HTML representation of MyType.

source

As mentioned above, one can also define new display backends. For example, a module that can display PNG images in a window can register this capability with Julia, so that calling display(x) on types with PNG representations will automatically display the image using the module's window.

In order to define a new display backend, one should first create a subtype D of the abstract class AbstractDisplay. Then, for each MIME type (mime string) that can be displayed on D, one should define a function display(d::D, ::MIME"mime", x) = ... that displays x as that MIME type, usually by calling show(io, mime, x) or repr(io, mime, x). A MethodError should be thrown if x cannot be displayed as that MIME type; this is automatic if one calls show or repr. Finally, one should define a function display(d::D, x) that queries showable(mime, x) for the mime types supported by D and displays the "best" one; a MethodError should be thrown if no supported MIME types are found for x. Similarly, some subtypes may wish to override redisplay(d::D, ...). (Again, one should import Base.display to add new methods to display.) The return values of these functions are up to the implementation (since in some cases it may be useful to return a display "handle" of some type). The display functions for D can then be called directly, but they can also be invoked automatically from display(x) simply by pushing a new display onto the display-backend stack with:

Base.Multimedia.pushdisplayFunction
pushdisplay(d::AbstractDisplay)

Pushes a new display d on top of the global display-backend stack. Calling display(x) or display(mime, x) will display x on the topmost compatible backend in the stack (i.e., the topmost backend that does not throw a MethodError).

source
Base.Multimedia.popdisplayFunction
popdisplay()
+popdisplay(d::AbstractDisplay)

Pop the topmost backend off of the display-backend stack, or the topmost copy of d in the second variant.

source
Base.Multimedia.TextDisplayType
TextDisplay(io::IO)

Return a TextDisplay <: AbstractDisplay, which displays any object as the text/plain MIME type (by default), writing the text representation to the given I/O stream. (This is how objects are printed in the Julia REPL.)

source
Base.Multimedia.istextmimeFunction
istextmime(m::MIME)

Determine whether a MIME type is text data. MIME types are assumed to be binary data except for a set of types known to be text data (possibly Unicode).

Examples

julia> istextmime(MIME("text/plain"))
 true
 
 julia> istextmime(MIME("image/png"))
-false
source

Network I/O

Base.bytesavailableFunction
bytesavailable(io)

Return the number of bytes available for reading before a read from this stream or buffer will block.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization");
+false
source

Network I/O

Base.bytesavailableFunction
bytesavailable(io)

Return the number of bytes available for reading before a read from this stream or buffer will block.

Examples

julia> io = IOBuffer("JuliaLang is a GitHub organization");
 
 julia> bytesavailable(io)
-34
source
Base.ntohFunction
ntoh(x)

Convert the endianness of a value from Network byte order (big-endian) to that used by the Host.

source
Base.htonFunction
hton(x)

Convert the endianness of a value from that used by the Host to Network byte order (big-endian).

source
Base.ltohFunction
ltoh(x)

Convert the endianness of a value from Little-endian to that used by the Host.

source
Base.htolFunction
htol(x)

Convert the endianness of a value from that used by the Host to Little-endian.

source
Base.ENDIAN_BOMConstant
ENDIAN_BOM

The 32-bit byte-order-mark indicates the native byte order of the host machine. Little-endian machines will contain the value 0x04030201. Big-endian machines will contain the value 0x01020304.

source
+34
source
Base.ntohFunction
ntoh(x)

Convert the endianness of a value from Network byte order (big-endian) to that used by the Host.

source
Base.htonFunction
hton(x)

Convert the endianness of a value from that used by the Host to Network byte order (big-endian).

source
Base.ltohFunction
ltoh(x)

Convert the endianness of a value from Little-endian to that used by the Host.

source
Base.htolFunction
htol(x)

Convert the endianness of a value from that used by the Host to Little-endian.

source
Base.ENDIAN_BOMConstant
ENDIAN_BOM

The 32-bit byte-order-mark indicates the native byte order of the host machine. Little-endian machines will contain the value 0x04030201. Big-endian machines will contain the value 0x01020304.

source
diff --git a/en/v1.12-dev/base/iterators/index.html b/en/v1.12-dev/base/iterators/index.html index 4ea003f0890d..dc64f68f7bbb 100644 --- a/en/v1.12-dev/base/iterators/index.html +++ b/en/v1.12-dev/base/iterators/index.html @@ -34,7 +34,7 @@ 3 julia> sum(a) # Sum the remaining elements -7source
Base.Iterators.zipFunction
zip(iters...)

Run multiple iterators at the same time, until any of them is exhausted. The value type of the zip iterator is a tuple of values of its subiterators.

Note

zip orders the calls to its subiterators in such a way that stateful iterators will not advance when another iterator finishes in the current iteration.

Note

zip() with no arguments yields an infinite iterator of empty tuples.

See also: enumerate, Base.splat.

Examples

julia> a = 1:5
+7
source
Base.Iterators.zipFunction
zip(iters...)

Run multiple iterators at the same time, until any of them is exhausted. The value type of the zip iterator is a tuple of values of its subiterators.

Note

zip orders the calls to its subiterators in such a way that stateful iterators will not advance when another iterator finishes in the current iteration.

Note

zip() with no arguments yields an infinite iterator of empty tuples.

See also: enumerate, Base.splat.

Examples

julia> a = 1:5
 1:5
 
 julia> b = ["e","d","b","c","a"]
@@ -52,7 +52,7 @@
 5
 
 julia> first(c)
-(1, "e")
source
Base.Iterators.enumerateFunction
enumerate(iter)

An iterator that yields (i, x) where i is a counter starting at 1, and x is the ith value from the given iterator. It's useful when you need not only the values x over which you are iterating, but also the number of iterations so far.

Note that i may not be valid for indexing iter, or may index a different element. This will happen if iter has indices that do not start at 1, and may happen for strings, dictionaries, etc. See the pairs(IndexLinear(), iter) method if you want to ensure that i is an index.

Examples

julia> a = ["a", "b", "c"];
+(1, "e")
source
Base.Iterators.enumerateFunction
enumerate(iter)

An iterator that yields (i, x) where i is a counter starting at 1, and x is the ith value from the given iterator. It's useful when you need not only the values x over which you are iterating, but also the number of iterations so far.

Note that i may not be valid for indexing iter, or may index a different element. This will happen if iter has indices that do not start at 1, and may happen for strings, dictionaries, etc. See the pairs(IndexLinear(), iter) method if you want to ensure that i is an index.

Examples

julia> a = ["a", "b", "c"];
 
 julia> for (index, value) in enumerate(a)
            println("$index $value")
@@ -71,17 +71,17 @@
 i = 2, val = a, str[i] = 'a'
 i = 3, val = ï, str[i] = 'ï'
 i = 4, val = v, StringIndexError("naïve", 4)
-i = 5, val = e, str[i] = 'v'
source
Base.Iterators.restFunction
rest(iter, state)

An iterator that yields the same elements as iter, but starting at the given state.

See also: Iterators.drop, Iterators.peel, Base.rest.

Examples

julia> collect(Iterators.rest([1,2,3,4], 2))
+i = 5, val = e, str[i] = 'v'
source
Base.Iterators.restFunction
rest(iter, state)

An iterator that yields the same elements as iter, but starting at the given state.

See also: Iterators.drop, Iterators.peel, Base.rest.

Examples

julia> collect(Iterators.rest([1,2,3,4], 2))
 3-element Vector{Int64}:
  2
  3
- 4
source
Base.Iterators.countfromFunction
countfrom(start=1, step=1)

An iterator that counts forever, starting at start and incrementing by step.

Examples

julia> for v in Iterators.countfrom(5, 2)
+ 4
source
Base.Iterators.countfromFunction
countfrom(start=1, step=1)

An iterator that counts forever, starting at start and incrementing by step.

Examples

julia> for v in Iterators.countfrom(5, 2)
            v > 10 && break
            println(v)
        end
 5
 7
-9
source
Base.Iterators.takeFunction
take(iter, n)

An iterator that generates at most the first n elements of iter.

See also: drop, peel, first, Base.take!.

Examples

julia> a = 1:2:11
+9
source
Base.Iterators.takeFunction
take(iter, n)

An iterator that generates at most the first n elements of iter.

See also: drop, peel, first, Base.take!.

Examples

julia> a = 1:2:11
 1:2:11
 
 julia> collect(a)
@@ -97,7 +97,7 @@
 3-element Vector{Int64}:
  1
  3
- 5
source
Base.Iterators.takewhileFunction
takewhile(pred, iter)

An iterator that generates element from iter as long as predicate pred is true, afterwards, drops every element.

Julia 1.4

This function requires at least Julia 1.4.

Examples

julia> s = collect(1:5)
+ 5
source
Base.Iterators.takewhileFunction
takewhile(pred, iter)

An iterator that generates element from iter as long as predicate pred is true, afterwards, drops every element.

Julia 1.4

This function requires at least Julia 1.4.

Examples

julia> s = collect(1:5)
 5-element Vector{Int64}:
  1
  2
@@ -108,7 +108,7 @@
 julia> collect(Iterators.takewhile(<(3),s))
 2-element Vector{Int64}:
  1
- 2
source
Base.Iterators.dropFunction
drop(iter, n)

An iterator that generates all but the first n elements of iter.

Examples

julia> a = 1:2:11
+ 2
source
Base.Iterators.dropFunction
drop(iter, n)

An iterator that generates all but the first n elements of iter.

Examples

julia> a = 1:2:11
 1:2:11
 
 julia> collect(a)
@@ -123,7 +123,7 @@
 julia> collect(Iterators.drop(a,4))
 2-element Vector{Int64}:
   9
- 11
source
Base.Iterators.dropwhileFunction
dropwhile(pred, iter)

An iterator that drops element from iter as long as predicate pred is true, afterwards, returns every element.

Julia 1.4

This function requires at least Julia 1.4.

Examples

julia> s = collect(1:5)
+ 11
source
Base.Iterators.dropwhileFunction
dropwhile(pred, iter)

An iterator that drops element from iter as long as predicate pred is true, afterwards, returns every element.

Julia 1.4

This function requires at least Julia 1.4.

Examples

julia> s = collect(1:5)
 5-element Vector{Int64}:
  1
  2
@@ -135,7 +135,7 @@
 3-element Vector{Int64}:
  3
  4
- 5
source
Base.Iterators.cycleFunction
cycle(iter[, n::Int])

An iterator that cycles through iter forever. If n is specified, then it cycles through iter that many times. When iter is empty, so are cycle(iter) and cycle(iter, n).

Iterators.cycle(iter, n) is the lazy equivalent of Base.repeat(vector, n), while Iterators.repeated(iter, n) is the lazy Base.fill(item, n).

Julia 1.11

The method cycle(iter, n) was added in Julia 1.11.

Examples

julia> for (i, v) in enumerate(Iterators.cycle("hello"))
+ 5
source
Base.Iterators.cycleFunction
cycle(iter[, n::Int])

An iterator that cycles through iter forever. If n is specified, then it cycles through iter that many times. When iter is empty, so are cycle(iter) and cycle(iter, n).

Iterators.cycle(iter, n) is the lazy equivalent of Base.repeat(vector, n), while Iterators.repeated(iter, n) is the lazy Base.fill(item, n).

Julia 1.11

The method cycle(iter, n) was added in Julia 1.11.

Examples

julia> for (i, v) in enumerate(Iterators.cycle("hello"))
            print(v)
            i > 10 && break
        end
@@ -148,7 +148,7 @@
 true
 
 julia> fill([1,2,3], 4) == collect(Iterators.repeated([1,2,3], 4))
-true
source
Base.Iterators.repeatedFunction
repeated(x[, n::Int])

An iterator that generates the value x forever. If n is specified, generates x that many times (equivalent to take(repeated(x), n)).

See also fill, and compare Iterators.cycle.

Examples

julia> a = Iterators.repeated([1 2], 4);
+true
source
Base.Iterators.repeatedFunction
repeated(x[, n::Int])

An iterator that generates the value x forever. If n is specified, generates x that many times (equivalent to take(repeated(x), n)).

See also fill, and compare Iterators.cycle.

Examples

julia> a = Iterators.repeated([1 2], 4);
 
 julia> collect(a)
 4-element Vector{Matrix{Int64}}:
@@ -161,13 +161,13 @@
 true
 
 julia> Iterators.cycle([1 2], 4) |> collect |> println
-[1, 2, 1, 2, 1, 2, 1, 2]
source
Base.Iterators.productFunction
product(iters...)

Return an iterator over the product of several iterators. Each generated element is a tuple whose ith element comes from the ith argument iterator. The first iterator changes the fastest.

See also: zip, Iterators.flatten.

Examples

julia> collect(Iterators.product(1:2, 3:5))
+[1, 2, 1, 2, 1, 2, 1, 2]
source
Base.Iterators.productFunction
product(iters...)

Return an iterator over the product of several iterators. Each generated element is a tuple whose ith element comes from the ith argument iterator. The first iterator changes the fastest.

See also: zip, Iterators.flatten.

Examples

julia> collect(Iterators.product(1:2, 3:5))
 2×3 Matrix{Tuple{Int64, Int64}}:
  (1, 3)  (1, 4)  (1, 5)
  (2, 3)  (2, 4)  (2, 5)
 
 julia> ans == [(x,y) for x in 1:2, y in 3:5]  # collects a generator involving Iterators.product
-true
source
Base.Iterators.flattenFunction
flatten(iter)

Given an iterator that yields iterators, return an iterator that yields the elements of those iterators. Put differently, the elements of the argument iterator are concatenated.

Examples

julia> collect(Iterators.flatten((1:2, 8:9)))
+true
source
Base.Iterators.flattenFunction
flatten(iter)

Given an iterator that yields iterators, return an iterator that yields the elements of those iterators. Put differently, the elements of the argument iterator are concatenated.

Examples

julia> collect(Iterators.flatten((1:2, 8:9)))
 4-element Vector{Int64}:
  1
  2
@@ -181,7 +181,7 @@
  (0, 'c')
  (1, 'a')
  (1, 'b')
- (1, 'c')
source
Base.Iterators.flatmapFunction
Iterators.flatmap(f, iterators...)

Equivalent to flatten(map(f, iterators...)).

See also Iterators.flatten, Iterators.map.

Julia 1.9

This function was added in Julia 1.9.

Examples

julia> Iterators.flatmap(n -> -n:2:n, 1:3) |> collect
+ (1, 'c')
source
Base.Iterators.flatmapFunction
Iterators.flatmap(f, iterators...)

Equivalent to flatten(map(f, iterators...)).

See also Iterators.flatten, Iterators.map.

Julia 1.9

This function was added in Julia 1.9.

Examples

julia> Iterators.flatmap(n -> -n:2:n, 1:3) |> collect
 9-element Vector{Int64}:
  -1
   1
@@ -205,15 +205,15 @@
  20
 
 julia> ans == vec(stack(n -> (-n, 10n), 1:2))
-true
source
Base.Iterators.partitionFunction
partition(collection, n)

Iterate over a collection n elements at a time.

Examples

julia> collect(Iterators.partition([1,2,3,4,5], 2))
+true
source
Base.Iterators.partitionFunction
partition(collection, n)

Iterate over a collection n elements at a time.

Examples

julia> collect(Iterators.partition([1,2,3,4,5], 2))
 3-element Vector{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}:
  [1, 2]
  [3, 4]
- [5]
source
Base.Iterators.mapFunction
Iterators.map(f, iterators...)

Create a lazy mapping. This is another syntax for writing (f(args...) for args in zip(iterators...)).

Julia 1.6

This function requires at least Julia 1.6.

Examples

julia> collect(Iterators.map(x -> x^2, 1:3))
+ [5]
source
Base.Iterators.mapFunction
Iterators.map(f, iterators...)

Create a lazy mapping. This is another syntax for writing (f(args...) for args in zip(iterators...)).

Julia 1.6

This function requires at least Julia 1.6.

Examples

julia> collect(Iterators.map(x -> x^2, 1:3))
 3-element Vector{Int64}:
  1
  4
- 9
source
Base.Iterators.filterFunction
Iterators.filter(flt, itr)

Given a predicate function flt and an iterable object itr, return an iterable object which upon iteration yields the elements x of itr that satisfy flt(x). The order of the original iterator is preserved.

This function is lazy; that is, it is guaranteed to return in $Θ(1)$ time and use $Θ(1)$ additional space, and flt will not be called by an invocation of filter. Calls to flt will be made when iterating over the returned iterable object. These calls are not cached and repeated calls will be made when reiterating.

Warning

Subsequent lazy transformations on the iterator returned from filter, such as those performed by Iterators.reverse or cycle, will also delay calls to flt until collecting or iterating over the returned iterable object. If the filter predicate is nondeterministic or its return values depend on the order of iteration over the elements of itr, composition with lazy transformations may result in surprising behavior. If this is undesirable, either ensure that flt is a pure function or collect intermediate filter iterators before further transformations.

See Base.filter for an eager implementation of filtering for arrays.

Examples

julia> f = Iterators.filter(isodd, [1, 2, 3, 4, 5])
+ 9
source
Base.Iterators.filterFunction
Iterators.filter(flt, itr)

Given a predicate function flt and an iterable object itr, return an iterable object which upon iteration yields the elements x of itr that satisfy flt(x). The order of the original iterator is preserved.

This function is lazy; that is, it is guaranteed to return in $Θ(1)$ time and use $Θ(1)$ additional space, and flt will not be called by an invocation of filter. Calls to flt will be made when iterating over the returned iterable object. These calls are not cached and repeated calls will be made when reiterating.

Warning

Subsequent lazy transformations on the iterator returned from filter, such as those performed by Iterators.reverse or cycle, will also delay calls to flt until collecting or iterating over the returned iterable object. If the filter predicate is nondeterministic or its return values depend on the order of iteration over the elements of itr, composition with lazy transformations may result in surprising behavior. If this is undesirable, either ensure that flt is a pure function or collect intermediate filter iterators before further transformations.

See Base.filter for an eager implementation of filtering for arrays.

Examples

julia> f = Iterators.filter(isodd, [1, 2, 3, 4, 5])
 Base.Iterators.Filter{typeof(isodd), Vector{Int64}}(isodd, [1, 2, 3, 4, 5])
 
 julia> foreach(println, f)
@@ -225,7 +225,7 @@
 3-element Vector{Int64}:
  1
  3
- 5
source
Base.Iterators.accumulateFunction
Iterators.accumulate(f, itr; [init])

Given a 2-argument function f and an iterator itr, return a new iterator that successively applies f to the previous value and the next element of itr.

This is effectively a lazy version of Base.accumulate.

Julia 1.5

Keyword argument init is added in Julia 1.5.

Examples

julia> a = Iterators.accumulate(+, [1,2,3,4]);
+ 5
source
Base.Iterators.accumulateFunction
Iterators.accumulate(f, itr; [init])

Given a 2-argument function f and an iterator itr, return a new iterator that successively applies f to the previous value and the next element of itr.

This is effectively a lazy version of Base.accumulate.

Julia 1.5

Keyword argument init is added in Julia 1.5.

Examples

julia> a = Iterators.accumulate(+, [1,2,3,4]);
 
 julia> foreach(println, a)
 1
@@ -240,12 +240,12 @@
  50.0
  10.0
   5.0
-  1.0
source
Base.Iterators.reverseFunction
Iterators.reverse(itr)

Given an iterator itr, then reverse(itr) is an iterator over the same collection but in the reverse order. This iterator is "lazy" in that it does not make a copy of the collection in order to reverse it; see Base.reverse for an eager implementation.

(By default, this returns an Iterators.Reverse object wrapping itr, which is iterable if the corresponding iterate methods are defined, but some itr types may implement more specialized Iterators.reverse behaviors.)

Not all iterator types T support reverse-order iteration. If T doesn't, then iterating over Iterators.reverse(itr::T) will throw a MethodError because of the missing iterate methods for Iterators.Reverse{T}. (To implement these methods, the original iterator itr::T can be obtained from an r::Iterators.Reverse{T} object by r.itr; more generally, one can use Iterators.reverse(r).)

Examples

julia> foreach(println, Iterators.reverse(1:5))
+  1.0
source
Base.Iterators.reverseFunction
Iterators.reverse(itr)

Given an iterator itr, then reverse(itr) is an iterator over the same collection but in the reverse order. This iterator is "lazy" in that it does not make a copy of the collection in order to reverse it; see Base.reverse for an eager implementation.

(By default, this returns an Iterators.Reverse object wrapping itr, which is iterable if the corresponding iterate methods are defined, but some itr types may implement more specialized Iterators.reverse behaviors.)

Not all iterator types T support reverse-order iteration. If T doesn't, then iterating over Iterators.reverse(itr::T) will throw a MethodError because of the missing iterate methods for Iterators.Reverse{T}. (To implement these methods, the original iterator itr::T can be obtained from an r::Iterators.Reverse{T} object by r.itr; more generally, one can use Iterators.reverse(r).)

Examples

julia> foreach(println, Iterators.reverse(1:5))
 5
 4
 3
 2
-1
source
Base.Iterators.onlyFunction
only(x)

Return the one and only element of collection x, or throw an ArgumentError if the collection has zero or multiple elements.

See also first, last.

Julia 1.4

This method requires at least Julia 1.4.

Examples

julia> only(["a"])
+1
source
Base.Iterators.onlyFunction
only(x)

Return the one and only element of collection x, or throw an ArgumentError if the collection has zero or multiple elements.

See also first, last.

Julia 1.4

This method requires at least Julia 1.4.

Examples

julia> only(["a"])
 "a"
 
 julia> only("a")
@@ -259,7 +259,7 @@
 julia> only(('a', 'b'))
 ERROR: ArgumentError: Tuple contains 2 elements, must contain exactly 1 element
 Stacktrace:
-[...]
source
Base.Iterators.peelFunction
peel(iter)

Returns the first element and an iterator over the remaining elements.

If the iterator is empty return nothing (like iterate).

Julia 1.7

Prior versions throw a BoundsError if the iterator is empty.

See also: Iterators.drop, Iterators.take.

Examples

julia> (a, rest) = Iterators.peel("abc");
+[...]
source
Base.Iterators.peelFunction
peel(iter)

Returns the first element and an iterator over the remaining elements.

If the iterator is empty return nothing (like iterate).

Julia 1.7

Prior versions throw a BoundsError if the iterator is empty.

See also: Iterators.drop, Iterators.take.

Examples

julia> (a, rest) = Iterators.peel("abc");
 
 julia> a
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
@@ -267,4 +267,4 @@
 julia> collect(rest)
 2-element Vector{Char}:
  'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
- 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
source
+ 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)source diff --git a/en/v1.12-dev/base/libc/index.html b/en/v1.12-dev/base/libc/index.html index 23af0b8f8a2d..f795f8fceb1e 100644 --- a/en/v1.12-dev/base/libc/index.html +++ b/en/v1.12-dev/base/libc/index.html @@ -3,7 +3,7 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

C Standard Library

Base.Libc.mallocFunction
malloc(size::Integer) -> Ptr{Cvoid}

Call malloc from the C standard library.

source
Base.Libc.callocFunction
calloc(num::Integer, size::Integer) -> Ptr{Cvoid}

Call calloc from the C standard library.

source
Base.Libc.reallocFunction
realloc(addr::Ptr, size::Integer) -> Ptr{Cvoid}

Call realloc from the C standard library.

See warning in the documentation for free regarding only using this on memory originally obtained from malloc.

source
Base.memcpyFunction
memcpy(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid}

Call memcpy from the C standard library.

Julia 1.10

Support for memcpy requires at least Julia 1.10.

source
Base.memmoveFunction
memmove(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid}

Call memmove from the C standard library.

Julia 1.10

Support for memmove requires at least Julia 1.10.

source
Base.memsetFunction
memset(dst::Ptr, val, n::Integer) -> Ptr{Cvoid}

Call memset from the C standard library.

Julia 1.10

Support for memset requires at least Julia 1.10.

source
Base.memcmpFunction
memcmp(a::Ptr, b::Ptr, n::Integer) -> Int

Call memcmp from the C standard library.

Julia 1.10

Support for memcmp requires at least Julia 1.9.

source
Base.Libc.freeFunction
free(addr::Ptr)

Call free from the C standard library. Only use this on memory obtained from malloc, not on pointers retrieved from other C libraries. Ptr objects obtained from C libraries should be freed by the free functions defined in that library, to avoid assertion failures if multiple libc libraries exist on the system.

source
Base.Libc.errnoFunction
errno([code])

Get the value of the C library's errno. If an argument is specified, it is used to set the value of errno.

The value of errno is only valid immediately after a ccall to a C library routine that sets it. Specifically, you cannot call errno at the next prompt in a REPL, because lots of code is executed between prompts.

source
Base.Libc.FormatMessageFunction
FormatMessage(n=GetLastError())

Convert a Win32 system call error code to a descriptive string [only available on Windows].

source
Base.Libc.timeMethod
time(t::TmStruct) -> Float64

Converts a TmStruct struct to a number of seconds since the epoch.

source
Base.Libc.strftimeFunction
strftime([format], time)

Convert time, given as a number of seconds since the epoch or a TmStruct, to a formatted string using the given format. Supported formats are the same as those in the standard C library.

source
Base.Libc.strptimeFunction
strptime([format], timestr)

Parse a formatted time string into a TmStruct giving the seconds, minute, hour, date, etc. Supported formats are the same as those in the standard C library. On some platforms, timezones will not be parsed correctly. If the result of this function will be passed to time to convert it to seconds since the epoch, the isdst field should be filled in manually. Setting it to -1 will tell the C library to use the current system settings to determine the timezone.

source
Base.Libc.TmStructType
TmStruct([seconds])

Convert a number of seconds since the epoch to broken-down format, with fields sec, min, hour, mday, month, year, wday, yday, and isdst.

source
Base.Libc.FILEType
FILE(::Ptr)
+

C Standard Library

Base.Libc.mallocFunction
malloc(size::Integer) -> Ptr{Cvoid}

Call malloc from the C standard library.

source
Base.Libc.callocFunction
calloc(num::Integer, size::Integer) -> Ptr{Cvoid}

Call calloc from the C standard library.

source
Base.Libc.reallocFunction
realloc(addr::Ptr, size::Integer) -> Ptr{Cvoid}

Call realloc from the C standard library.

See warning in the documentation for free regarding only using this on memory originally obtained from malloc.

source
Base.memcpyFunction
memcpy(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid}

Call memcpy from the C standard library.

Julia 1.10

Support for memcpy requires at least Julia 1.10.

source
Base.memmoveFunction
memmove(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid}

Call memmove from the C standard library.

Julia 1.10

Support for memmove requires at least Julia 1.10.

source
Base.memsetFunction
memset(dst::Ptr, val, n::Integer) -> Ptr{Cvoid}

Call memset from the C standard library.

Julia 1.10

Support for memset requires at least Julia 1.10.

source
Base.memcmpFunction
memcmp(a::Ptr, b::Ptr, n::Integer) -> Int

Call memcmp from the C standard library.

Julia 1.10

Support for memcmp requires at least Julia 1.9.

source
Base.Libc.freeFunction
free(addr::Ptr)

Call free from the C standard library. Only use this on memory obtained from malloc, not on pointers retrieved from other C libraries. Ptr objects obtained from C libraries should be freed by the free functions defined in that library, to avoid assertion failures if multiple libc libraries exist on the system.

source
Base.Libc.errnoFunction
errno([code])

Get the value of the C library's errno. If an argument is specified, it is used to set the value of errno.

The value of errno is only valid immediately after a ccall to a C library routine that sets it. Specifically, you cannot call errno at the next prompt in a REPL, because lots of code is executed between prompts.

source
Base.Libc.FormatMessageFunction
FormatMessage(n=GetLastError())

Convert a Win32 system call error code to a descriptive string [only available on Windows].

source
Base.Libc.timeMethod
time(t::TmStruct) -> Float64

Converts a TmStruct struct to a number of seconds since the epoch.

source
Base.Libc.strftimeFunction
strftime([format], time)

Convert time, given as a number of seconds since the epoch or a TmStruct, to a formatted string using the given format. Supported formats are the same as those in the standard C library.

source
Base.Libc.strptimeFunction
strptime([format], timestr)

Parse a formatted time string into a TmStruct giving the seconds, minute, hour, date, etc. Supported formats are the same as those in the standard C library. On some platforms, timezones will not be parsed correctly. If the result of this function will be passed to time to convert it to seconds since the epoch, the isdst field should be filled in manually. Setting it to -1 will tell the C library to use the current system settings to determine the timezone.

source
Base.Libc.TmStructType
TmStruct([seconds])

Convert a number of seconds since the epoch to broken-down format, with fields sec, min, hour, mday, month, year, wday, yday, and isdst.

source
Base.Libc.FILEType
FILE(::Ptr)
 FILE(::IO)

A libc FILE*, representing an opened file.

It can be passed as a Ptr{FILE} argument to ccall and also supports seek, position and close.

A FILE can be constructed from an ordinary IO object, provided it is an open file. It must be closed afterward.

Examples

julia> using Base.Libc
 
 julia> mktemp() do _, io
@@ -15,4 +15,4 @@
            seek(io, 0)
            read(io, String)
        end
-"hello world"
source
Base.Libc.flush_cstdioFunction
flush_cstdio()

Flushes the C stdout and stderr streams (which may have been written to by external C code).

source
Base.Libc.systemsleepFunction
systemsleep(s::Real)

Suspends execution for s seconds. This function does not yield to Julia's scheduler and therefore blocks the Julia thread that it is running on for the duration of the sleep time.

See also sleep.

source
Base.Libc.mkfifoFunction
mkfifo(path::AbstractString, [mode::Integer]) -> path

Make a FIFO special file (a named pipe) at path. Return path as-is on success.

mkfifo is supported only in Unix platforms.

Julia 1.11

mkfifo requires at least Julia 1.11.

source
+"hello world"
source
Base.Libc.flush_cstdioFunction
flush_cstdio()

Flushes the C stdout and stderr streams (which may have been written to by external C code).

source
Base.Libc.systemsleepFunction
systemsleep(s::Real)

Suspends execution for s seconds. This function does not yield to Julia's scheduler and therefore blocks the Julia thread that it is running on for the duration of the sleep time.

See also sleep.

source
Base.Libc.mkfifoFunction
mkfifo(path::AbstractString, [mode::Integer]) -> path

Make a FIFO special file (a named pipe) at path. Return path as-is on success.

mkfifo is supported only in Unix platforms.

Julia 1.11

mkfifo requires at least Julia 1.11.

source
diff --git a/en/v1.12-dev/base/math/index.html b/en/v1.12-dev/base/math/index.html index 6314c539910e..46220ce16de7 100644 --- a/en/v1.12-dev/base/math/index.html +++ b/en/v1.12-dev/base/math/index.html @@ -18,7 +18,7 @@ -1 julia> -(0x003) -0xfffdsource
Base.:+Function
dt::Date + t::Time -> DateTime

The addition of a Date with a Time produces a DateTime. The hour, minute, second, and millisecond parts of the Time are used along with the year, month, and day of the Date to create the new DateTime. Non-zero microseconds or nanoseconds in the Time type will result in an InexactError being thrown.

+(x, y...)

Addition operator.

Infix x+y+z+... calls this function with all arguments, i.e. +(x, y, z, ...), which by default then calls (x+y) + z + ... starting from the left.

Note that overflow is possible for most integer types, including the default Int, when adding large numbers.

Examples

julia> 1 + 20 + 4
+0xfffd
source
Base.:+Function
dt::Date + t::Time -> DateTime

The addition of a Date with a Time produces a DateTime. The hour, minute, second, and millisecond parts of the Time are used along with the year, month, and day of the Date to create the new DateTime. Non-zero microseconds or nanoseconds in the Time type will result in an InexactError being thrown.

+(x, y...)

Addition operator.

Infix x+y+z+... calls this function with all arguments, i.e. +(x, y, z, ...), which by default then calls (x+y) + z + ... starting from the left.

Note that overflow is possible for most integer types, including the default Int, when adding large numbers.

Examples

julia> 1 + 20 + 4
 25
 
 julia> +(1, 20, 4)
@@ -30,11 +30,11 @@
  6
 
 julia> typemax(Int) + 1 < 0
-true
source
Base.:-Method
-(x, y)

Subtraction operator.

Examples

julia> 2 - 3
+true
source
Base.:-Method
-(x, y)

Subtraction operator.

Examples

julia> 2 - 3
 -1
 
 julia> -(2, 4.5)
--2.5
source
Base.:*Method
*(x, y...)

Multiplication operator.

Infix x*y*z*... calls this function with all arguments, i.e. *(x, y, z, ...), which by default then calls (x*y) * z * ... starting from the left.

Juxtaposition such as 2pi also calls *(2, pi). Note that this operation has higher precedence than a literal *. Note also that juxtaposition "0x..." (integer zero times a variable whose name starts with x) is forbidden as it clashes with unsigned integer literals: 0x01 isa UInt8.

Note that overflow is possible for most integer types, including the default Int, when multiplying large numbers.

Examples

julia> 2 * 7 * 8
+-2.5
source
Base.:*Method
*(x, y...)

Multiplication operator.

Infix x*y*z*... calls this function with all arguments, i.e. *(x, y, z, ...), which by default then calls (x*y) * z * ... starting from the left.

Juxtaposition such as 2pi also calls *(2, pi). Note that this operation has higher precedence than a literal *. Note also that juxtaposition "0x..." (integer zero times a variable whose name starts with x) is forbidden as it clashes with unsigned integer literals: 0x01 isa UInt8.

Note that overflow is possible for most integer types, including the default Int, when multiplying large numbers.

Examples

julia> 2 * 7 * 8
 112
 
 julia> *(2, 7, 8)
@@ -49,14 +49,14 @@
 (0.15915494309189535, 1.5707963267948966)
 
 julia> x = [1, 2]; x'x  # adjoint vector * vector
-5
source
Base.:/Function
/(x, y)

Right division operator: multiplication of x by the inverse of y on the right.

Gives floating-point results for integer arguments. See ÷ for integer division, or // for Rational results.

Examples

julia> 1/2
+5
source
Base.:/Function
/(x, y)

Right division operator: multiplication of x by the inverse of y on the right.

Gives floating-point results for integer arguments. See ÷ for integer division, or // for Rational results.

Examples

julia> 1/2
 0.5
 
 julia> 4/2
 2.0
 
 julia> 4.5/2
-2.25
source
A / B

Matrix right-division: A / B is equivalent to (B' \ A')' where \ is the left-division operator. For square matrices, the result X is such that A == X*B.

See also: rdiv!.

Examples

julia> A = Float64[1 4 5; 3 9 2]; B = Float64[1 4 2; 3 4 2; 8 7 1];
+2.25
source
A / B

Matrix right-division: A / B is equivalent to (B' \ A')' where \ is the left-division operator. For square matrices, the result X is such that A == X*B.

See also: rdiv!.

Examples

julia> A = Float64[1 4 5; 3 9 2]; B = Float64[1 4 2; 3 4 2; 8 7 1];
 
 julia> X = A / B
 2×3 Matrix{Float64}:
@@ -83,7 +83,7 @@
 julia> inv(A) * x
 2-element Vector{Float64}:
   6.5
- -7.0
source
Base.:^Method
^(x, y)

Exponentiation operator.

If x and y are integers, the result may overflow. To enter numbers in scientific notation, use Float64 literals such as 1.2e3 rather than 1.2 * 10^3.

If y is an Int literal (e.g. 2 in x^2 or -3 in x^-3), the Julia code x^y is transformed by the compiler to Base.literal_pow(^, x, Val(y)), to enable compile-time specialization on the value of the exponent. (As a default fallback we have Base.literal_pow(^, x, Val(y)) = ^(x,y), where usually ^ == Base.^ unless ^ has been defined in the calling namespace.) If y is a negative integer literal, then Base.literal_pow transforms the operation to inv(x)^-y by default, where -y is positive.

See also exp2, <<.

Examples

julia> 3^5
+ -7.0
source
Base.:^Method
^(x, y)

Exponentiation operator.

If x and y are integers, the result may overflow. To enter numbers in scientific notation, use Float64 literals such as 1.2e3 rather than 1.2 * 10^3.

If y is an Int literal (e.g. 2 in x^2 or -3 in x^-3), the Julia code x^y is transformed by the compiler to Base.literal_pow(^, x, Val(y)), to enable compile-time specialization on the value of the exponent. (As a default fallback we have Base.literal_pow(^, x, Val(y)) = ^(x,y), where usually ^ == Base.^ unless ^ has been defined in the calling namespace.) If y is a negative integer literal, then Base.literal_pow transforms the operation to inv(x)^-y by default, where -y is positive.

See also exp2, <<.

Examples

julia> 3^5
 243
 
 julia> 3^-1  # uses Base.literal_pow
@@ -103,11 +103,11 @@
 false
 
 julia> big(10)^19 == 1e19
-true
source
Base.fmaFunction
fma(x, y, z)

Computes x*y+z without rounding the intermediate result x*y. On some systems this is significantly more expensive than x*y+z. fma is used to improve accuracy in certain algorithms. See muladd.

source
Base.muladdFunction
muladd(x, y, z)

Combined multiply-add: computes x*y+z, but allowing the add and multiply to be merged with each other or with surrounding operations for performance. For example, this may be implemented as an fma if the hardware supports it efficiently. The result can be different on different machines and can also be different on the same machine due to constant propagation or other optimizations. See fma.

Examples

julia> muladd(3, 2, 1)
+true
source
Base.fmaFunction
fma(x, y, z)

Computes x*y+z without rounding the intermediate result x*y. On some systems this is significantly more expensive than x*y+z. fma is used to improve accuracy in certain algorithms. See muladd.

source
Base.muladdFunction
muladd(x, y, z)

Combined multiply-add: computes x*y+z, but allowing the add and multiply to be merged with each other or with surrounding operations for performance. For example, this may be implemented as an fma if the hardware supports it efficiently. The result can be different on different machines and can also be different on the same machine due to constant propagation or other optimizations. See fma.

Examples

julia> muladd(3, 2, 1)
 7
 
 julia> 3 * 2 + 1
-7
source
muladd(A, y, z)

Combined multiply-add, A*y .+ z, for matrix-matrix or matrix-vector multiplication. The result is always the same size as A*y, but z may be smaller, or a scalar.

Julia 1.6

These methods require Julia 1.6 or later.

Examples

julia> A=[1.0 2.0; 3.0 4.0]; B=[1.0 1.0; 1.0 1.0]; z=[0, 100];
+7
source
muladd(A, y, z)

Combined multiply-add, A*y .+ z, for matrix-matrix or matrix-vector multiplication. The result is always the same size as A*y, but z may be smaller, or a scalar.

Julia 1.6

These methods require Julia 1.6 or later.

Examples

julia> A=[1.0 2.0; 3.0 4.0]; B=[1.0 1.0; 1.0 1.0]; z=[0, 100];
 
 julia> muladd(A, B, z)
 2×2 Matrix{Float64}:
@@ -122,7 +122,7 @@
 1.0 + 0.0im
 
 julia> inv(2//3)
-3//2
Julia 1.2

inv(::Missing) requires at least Julia 1.2.

source
Base.divFunction
div(x, y)
+3//2
Julia 1.2

inv(::Missing) requires at least Julia 1.2.

source
Base.divFunction
div(x, y)
 ÷(x, y)

The quotient from Euclidean (integer) division. Generally equivalent to a mathematical operation x/y without a fractional part.

See also: cld, fld, rem, divrem.

Examples

julia> 9 ÷ 4
 2
 
@@ -134,7 +134,7 @@
 
 julia> div.(-5:5, 3)'
 1×11 adjoint(::Vector{Int64}) with eltype Int64:
- -1  -1  -1  0  0  0  0  0  1  1  1
source
Base.divMethod
div(x, y, r::RoundingMode=RoundToZero)

The quotient from Euclidean (integer) division. Computes x / y, rounded to an integer according to the rounding mode r. In other words, the quantity

round(x / y, r)

without any intermediate rounding.

Julia 1.4

The three-argument method taking a RoundingMode requires Julia 1.4 or later.

See also fld and cld, which are special cases of this function.

Julia 1.9

RoundFromZero requires at least Julia 1.9.

Examples:

julia> div(4, 3, RoundToZero) # Matches div(4, 3)
+ -1  -1  -1  0  0  0  0  0  1  1  1
source
Base.divMethod
div(x, y, r::RoundingMode=RoundToZero)

The quotient from Euclidean (integer) division. Computes x / y, rounded to an integer according to the rounding mode r. In other words, the quantity

round(x / y, r)

without any intermediate rounding.

Julia 1.4

The three-argument method taking a RoundingMode requires Julia 1.4 or later.

See also fld and cld, which are special cases of this function.

Julia 1.9

RoundFromZero requires at least Julia 1.9.

Examples:

julia> div(4, 3, RoundToZero) # Matches div(4, 3)
 1
 julia> div(4, 3, RoundDown) # Matches fld(4, 3)
 1
@@ -153,7 +153,7 @@
 julia> div(4, 3, RoundFromZero)
 2
 julia> div(-4, 3, RoundFromZero)
--2
source
Base.fldFunction
fld(x, y)

Largest integer less than or equal to x / y. Equivalent to div(x, y, RoundDown).

See also div, cld, fld1.

Examples

julia> fld(7.3, 5.5)
+-2
source
Base.fldFunction
fld(x, y)

Largest integer less than or equal to x / y. Equivalent to div(x, y, RoundDown).

See also div, cld, fld1.

Examples

julia> fld(7.3, 5.5)
 1.0
 
 julia> fld.(-5:5, 3)'
@@ -163,16 +163,16 @@
 julia> 6.0 / 0.1
 60.0
 julia> 6.0 / big(0.1)
-59.99999999999999666933092612453056361837965690217069245739573412231113406246995

What is happening here is that the true value of the floating-point number written as 0.1 is slightly larger than the numerical value 1/10 while 6.0 represents the number 6 precisely. Therefore the true value of 6.0 / 0.1 is slightly less than 60. When doing division, this is rounded to precisely 60.0, but fld(6.0, 0.1) always takes the floor of the true value, so the result is 59.0.

source
Base.cldFunction
cld(x, y)

Smallest integer larger than or equal to x / y. Equivalent to div(x, y, RoundUp).

See also div, fld.

Examples

julia> cld(5.5, 2.2)
+59.99999999999999666933092612453056361837965690217069245739573412231113406246995

What is happening here is that the true value of the floating-point number written as 0.1 is slightly larger than the numerical value 1/10 while 6.0 represents the number 6 precisely. Therefore the true value of 6.0 / 0.1 is slightly less than 60. When doing division, this is rounded to precisely 60.0, but fld(6.0, 0.1) always takes the floor of the true value, so the result is 59.0.

source
Base.cldFunction
cld(x, y)

Smallest integer larger than or equal to x / y. Equivalent to div(x, y, RoundUp).

See also div, fld.

Examples

julia> cld(5.5, 2.2)
 3.0
 
 julia> cld.(-5:5, 3)'
 1×11 adjoint(::Vector{Int64}) with eltype Int64:
- -1  -1  -1  0  0  0  1  1  1  2  2
source
Base.modFunction
mod(x::Integer, r::AbstractUnitRange)

Find y in the range r such that $x ≡ y (mod n)$, where n = length(r), i.e. y = mod(x - first(r), n) + first(r).

See also mod1.

Examples

julia> mod(0, Base.OneTo(3))  # mod1(0, 3)
+ -1  -1  -1  0  0  0  1  1  1  2  2
source
Base.modFunction
mod(x::Integer, r::AbstractUnitRange)

Find y in the range r such that $x ≡ y (mod n)$, where n = length(r), i.e. y = mod(x - first(r), n) + first(r).

See also mod1.

Examples

julia> mod(0, Base.OneTo(3))  # mod1(0, 3)
 3
 
 julia> mod(3, 0:2)  # mod(3, 3)
-0
Julia 1.3

This method requires at least Julia 1.3.

source
mod(x, y)
+0
Julia 1.3

This method requires at least Julia 1.3.

source
mod(x, y)
 rem(x, y, RoundDown)

The reduction of x modulo y, or equivalently, the remainder of x after floored division by y, i.e. x - y*fld(x,y) if computed without intermediate rounding.

The result will have the same sign as y, and magnitude less than abs(y) (with some exceptions, see note below).

Note

When used with floating point values, the exact result may not be representable by the type, and so rounding error may occur. In particular, if the exact result is very close to y, then it may be rounded to y.

See also: rem, div, fld, mod1, invmod.

julia> mod(8, 3)
 2
 
@@ -190,7 +190,7 @@
 
 julia> mod.(-5:5, 3)'
 1×11 adjoint(::Vector{Int64}) with eltype Int64:
- 1  2  0  1  2  0  1  2  0  1  2
source
rem(x::Integer, T::Type{<:Integer}) -> T
+ 1  2  0  1  2  0  1  2  0  1  2
source
rem(x::Integer, T::Type{<:Integer}) -> T
 mod(x::Integer, T::Type{<:Integer}) -> T
 %(x::Integer, T::Type{<:Integer}) -> T

Find y::T such that xy (mod n), where n is the number of integers representable in T, and y is an integer in [typemin(T),typemax(T)]. If T can represent any integer (e.g. T == BigInt), then this operation corresponds to a conversion to T.

Examples

julia> x = 129 % Int8
 -127
@@ -202,7 +202,7 @@
 129
 
 julia> typeof(x)
-BigInt
source
Base.remFunction
rem(x, y)
+BigInt
source
Base.remFunction
rem(x, y)
 %(x, y)

Remainder from Euclidean division, returning a value of the same sign as x, and smaller in magnitude than y. This value is always exact.

See also: div, mod, mod1, divrem.

Examples

julia> x = 15; y = 4;
 
 julia> x % y
@@ -213,7 +213,7 @@
 
 julia> rem.(-5:5, 3)'
 1×11 adjoint(::Vector{Int64}) with eltype Int64:
- -2  -1  0  -2  -1  0  1  2  0  1  2
source
Base.remMethod
rem(x, y, r::RoundingMode=RoundToZero)

Compute the remainder of x after integer division by y, with the quotient rounded according to the rounding mode r. In other words, the quantity

x - y * round(x / y, r)

without any intermediate rounding.

  • if r == RoundNearest, then the result is exact, and in the interval $[-|y| / 2, |y| / 2]$. See also RoundNearest.

  • if r == RoundToZero (default), then the result is exact, and in the interval $[0, |y|)$ if x is positive, or $(-|y|, 0]$ otherwise. See also RoundToZero.

  • if r == RoundDown, then the result is in the interval $[0, y)$ if y is positive, or $(y, 0]$ otherwise. The result may not be exact if x and y have different signs, and abs(x) < abs(y). See also RoundDown.

  • if r == RoundUp, then the result is in the interval $(-y, 0]$ if y is positive, or $[0, -y)$ otherwise. The result may not be exact if x and y have the same sign, and abs(x) < abs(y). See also RoundUp.

  • if r == RoundFromZero, then the result is in the interval $(-y, 0]$ if y is positive, or $[0, -y)$ otherwise. The result may not be exact if x and y have the same sign, and abs(x) < abs(y). See also RoundFromZero.

Julia 1.9

RoundFromZero requires at least Julia 1.9.

Examples:

julia> x = 9; y = 4;
+ -2  -1  0  -2  -1  0  1  2  0  1  2
source
Base.remMethod
rem(x, y, r::RoundingMode=RoundToZero)

Compute the remainder of x after integer division by y, with the quotient rounded according to the rounding mode r. In other words, the quantity

x - y * round(x / y, r)

without any intermediate rounding.

  • if r == RoundNearest, then the result is exact, and in the interval $[-|y| / 2, |y| / 2]$. See also RoundNearest.

  • if r == RoundToZero (default), then the result is exact, and in the interval $[0, |y|)$ if x is positive, or $(-|y|, 0]$ otherwise. See also RoundToZero.

  • if r == RoundDown, then the result is in the interval $[0, y)$ if y is positive, or $(y, 0]$ otherwise. The result may not be exact if x and y have different signs, and abs(x) < abs(y). See also RoundDown.

  • if r == RoundUp, then the result is in the interval $(-y, 0]$ if y is positive, or $[0, -y)$ otherwise. The result may not be exact if x and y have the same sign, and abs(x) < abs(y). See also RoundUp.

  • if r == RoundFromZero, then the result is in the interval $(-y, 0]$ if y is positive, or $[0, -y)$ otherwise. The result may not be exact if x and y have the same sign, and abs(x) < abs(y). See also RoundFromZero.

Julia 1.9

RoundFromZero requires at least Julia 1.9.

Examples:

julia> x = 9; y = 4;
 
 julia> x % y  # same as rem(x, y)
 1
@@ -222,16 +222,16 @@
 2
 
 julia> x == div(x, y) * y + rem(x, y)
-true
source
Base.Math.rem2piFunction
rem2pi(x, r::RoundingMode)

Compute the remainder of x after integer division by , with the quotient rounded according to the rounding mode r. In other words, the quantity

x - 2π*round(x/(2π),r)

without any intermediate rounding. This internally uses a high precision approximation of 2π, and so will give a more accurate result than rem(x,2π,r)

  • if r == RoundNearest, then the result is in the interval $[-π, π]$. This will generally be the most accurate result. See also RoundNearest.

  • if r == RoundToZero, then the result is in the interval $[0, 2π]$ if x is positive,. or $[-2π, 0]$ otherwise. See also RoundToZero.

  • if r == RoundDown, then the result is in the interval $[0, 2π]$. See also RoundDown.

  • if r == RoundUp, then the result is in the interval $[-2π, 0]$. See also RoundUp.

Examples

julia> rem2pi(7pi/4, RoundNearest)
+true
source
Base.Math.rem2piFunction
rem2pi(x, r::RoundingMode)

Compute the remainder of x after integer division by , with the quotient rounded according to the rounding mode r. In other words, the quantity

x - 2π*round(x/(2π),r)

without any intermediate rounding. This internally uses a high precision approximation of 2π, and so will give a more accurate result than rem(x,2π,r)

  • if r == RoundNearest, then the result is in the interval $[-π, π]$. This will generally be the most accurate result. See also RoundNearest.

  • if r == RoundToZero, then the result is in the interval $[0, 2π]$ if x is positive,. or $[-2π, 0]$ otherwise. See also RoundToZero.

  • if r == RoundDown, then the result is in the interval $[0, 2π]$. See also RoundDown.

  • if r == RoundUp, then the result is in the interval $[-2π, 0]$. See also RoundUp.

Examples

julia> rem2pi(7pi/4, RoundNearest)
 -0.7853981633974485
 
 julia> rem2pi(7pi/4, RoundDown)
-5.497787143782138
source
Base.Math.mod2piFunction
mod2pi(x)

Modulus after division by , returning in the range $[0,2π)$.

This function computes a floating point representation of the modulus after division by numerically exact , and is therefore not exactly the same as mod(x,2π), which would compute the modulus of x relative to division by the floating-point number .

Note

Depending on the format of the input value, the closest representable value to 2π may be less than 2π. For example, the expression mod2pi(2π) will not return 0, because the intermediate value of 2*π is a Float64 and 2*Float64(π) < 2*big(π). See rem2pi for more refined control of this behavior.

Examples

julia> mod2pi(9*pi/4)
-0.7853981633974481
source
Base.divremFunction
divrem(x, y, r::RoundingMode=RoundToZero)

The quotient and remainder from Euclidean division. Equivalent to (div(x, y, r), rem(x, y, r)). Equivalently, with the default value of r, this call is equivalent to (x ÷ y, x % y).

See also: fldmod, cld.

Examples

julia> divrem(3, 7)
+5.497787143782138
source
Base.Math.mod2piFunction
mod2pi(x)

Modulus after division by , returning in the range $[0,2π)$.

This function computes a floating point representation of the modulus after division by numerically exact , and is therefore not exactly the same as mod(x,2π), which would compute the modulus of x relative to division by the floating-point number .

Note

Depending on the format of the input value, the closest representable value to 2π may be less than 2π. For example, the expression mod2pi(2π) will not return 0, because the intermediate value of 2*π is a Float64 and 2*Float64(π) < 2*big(π). See rem2pi for more refined control of this behavior.

Examples

julia> mod2pi(9*pi/4)
+0.7853981633974481
source
Base.divremFunction
divrem(x, y, r::RoundingMode=RoundToZero)

The quotient and remainder from Euclidean division. Equivalent to (div(x, y, r), rem(x, y, r)). Equivalently, with the default value of r, this call is equivalent to (x ÷ y, x % y).

See also: fldmod, cld.

Examples

julia> divrem(3, 7)
 (0, 3)
 
 julia> divrem(7, 3)
-(2, 1)
source
Base.fldmodFunction
fldmod(x, y)

The floored quotient and modulus after division. A convenience wrapper for divrem(x, y, RoundDown). Equivalent to (fld(x, y), mod(x, y)).

See also: fld, cld, fldmod1.

source
Base.fld1Function
fld1(x, y)

Flooring division, returning a value consistent with mod1(x,y)

See also mod1, fldmod1.

Examples

julia> x = 15; y = 4;
+(2, 1)
source
Base.fldmodFunction
fldmod(x, y)

The floored quotient and modulus after division. A convenience wrapper for divrem(x, y, RoundDown). Equivalent to (fld(x, y), mod(x, y)).

See also: fld, cld, fldmod1.

source
Base.fld1Function
fld1(x, y)

Flooring division, returning a value consistent with mod1(x,y)

See also mod1, fldmod1.

Examples

julia> x = 15; y = 4;
 
 julia> fld1(x, y)
 4
@@ -240,7 +240,7 @@
 true
 
 julia> x == (fld1(x, y) - 1) * y + mod1(x, y)
-true
source
Base.mod1Function
mod1(x, y)

Modulus after flooring division, returning a value r such that mod(r, y) == mod(x, y) in the range $(0, y]$ for positive y and in the range $[y,0)$ for negative y.

With integer arguments and positive y, this is equal to mod(x, 1:y), and hence natural for 1-based indexing. By comparison, mod(x, y) == mod(x, 0:y-1) is natural for computations with offsets or strides.

See also mod, fld1, fldmod1.

Examples

julia> mod1(4, 2)
+true
source
Base.mod1Function
mod1(x, y)

Modulus after flooring division, returning a value r such that mod(r, y) == mod(x, y) in the range $(0, y]$ for positive y and in the range $[y,0)$ for negative y.

With integer arguments and positive y, this is equal to mod(x, 1:y), and hence natural for 1-based indexing. By comparison, mod(x, y) == mod(x, 0:y-1) is natural for computations with offsets or strides.

See also mod, fld1, fldmod1.

Examples

julia> mod1(4, 2)
 2
 
 julia> mod1.(-5:5, 3)'
@@ -249,7 +249,7 @@
 
 julia> mod1.([-0.1, 0, 0.1, 1, 2, 2.9, 3, 3.1]', 3)
 1×8 Matrix{Float64}:
- 2.9  3.0  0.1  1.0  2.0  2.9  3.0  0.1
source
Base.fldmod1Function
fldmod1(x, y)

Return (fld1(x,y), mod1(x,y)).

See also fld1, mod1.

source
Base.://Function
//(num, den)

Divide two integers or rational numbers, giving a Rational result. More generally, // can be used for exact rational division of other numeric types with integer or rational components, such as complex numbers with integer components.

Note that floating-point (AbstractFloat) arguments are not permitted by // (even if the values are rational). The arguments must be subtypes of Integer, Rational, or composites thereof.

Examples

julia> 3 // 5
+ 2.9  3.0  0.1  1.0  2.0  2.9  3.0  0.1
source
Base.fldmod1Function
fldmod1(x, y)

Return (fld1(x,y), mod1(x,y)).

See also fld1, mod1.

source
Base.://Function
//(num, den)

Divide two integers or rational numbers, giving a Rational result. More generally, // can be used for exact rational division of other numeric types with integer or rational components, such as complex numbers with integer components.

Note that floating-point (AbstractFloat) arguments are not permitted by // (even if the values are rational). The arguments must be subtypes of Integer, Rational, or composites thereof.

Examples

julia> 3 // 5
 3//5
 
 julia> (3 // 5) // (2 // 1)
@@ -260,29 +260,29 @@
 
 julia> 1.0 // 2
 ERROR: MethodError: no method matching //(::Float64, ::Int64)
-[...]
source
Base.rationalizeFunction
rationalize([T<:Integer=Int,] x; tol::Real=eps(x))

Approximate floating point number x as a Rational number with components of the given integer type. The result will differ from x by no more than tol.

Examples

julia> rationalize(5.6)
+[...]
source
Base.rationalizeFunction
rationalize([T<:Integer=Int,] x; tol::Real=eps(x))

Approximate floating point number x as a Rational number with components of the given integer type. The result will differ from x by no more than tol.

Examples

julia> rationalize(5.6)
 28//5
 
 julia> a = rationalize(BigInt, 10.3)
 103//10
 
 julia> typeof(numerator(a))
-BigInt
source
Base.numeratorFunction
numerator(x)

Numerator of the rational representation of x.

Examples

julia> numerator(2//3)
+BigInt
source
Base.numeratorFunction
numerator(x)

Numerator of the rational representation of x.

Examples

julia> numerator(2//3)
 2
 
 julia> numerator(4)
-4
source
Base.denominatorFunction
denominator(x)

Denominator of the rational representation of x.

Examples

julia> denominator(2//3)
+4
source
Base.denominatorFunction
denominator(x)

Denominator of the rational representation of x.

Examples

julia> denominator(2//3)
 3
 
 julia> denominator(4)
-1
source
Base.:<<Function
<<(x, n)

Left bit shift operator, x << n. For n >= 0, the result is x shifted left by n bits, filling with 0s. This is equivalent to x * 2^n. For n < 0, this is equivalent to x >> -n.

Examples

julia> Int8(3) << 2
+1
source
Base.:<<Function
<<(x, n)

Left bit shift operator, x << n. For n >= 0, the result is x shifted left by n bits, filling with 0s. This is equivalent to x * 2^n. For n < 0, this is equivalent to x >> -n.

Examples

julia> Int8(3) << 2
 12
 
 julia> bitstring(Int8(3))
 "00000011"
 
 julia> bitstring(Int8(12))
-"00001100"

See also >>, >>>, exp2, ldexp.

source
<<(B::BitVector, n) -> BitVector

Left bit shift operator, B << n. For n >= 0, the result is B with elements shifted n positions backwards, filling with false values. If n < 0, elements are shifted forwards. Equivalent to B >> -n.

Examples

julia> B = BitVector([true, false, true, false, false])
+"00001100"

See also >>, >>>, exp2, ldexp.

source
<<(B::BitVector, n) -> BitVector

Left bit shift operator, B << n. For n >= 0, the result is B with elements shifted n positions backwards, filling with false values. If n < 0, elements are shifted forwards. Equivalent to B >> -n.

Examples

julia> B = BitVector([true, false, true, false, false])
 5-element BitVector:
  1
  0
@@ -304,7 +304,7 @@
  1
  0
  1
- 0
source
Base.:>>Function
>>(x, n)

Right bit shift operator, x >> n. For n >= 0, the result is x shifted right by n bits, filling with 0s if x >= 0, 1s if x < 0, preserving the sign of x. This is equivalent to fld(x, 2^n). For n < 0, this is equivalent to x << -n.

Examples

julia> Int8(13) >> 2
+ 0
source
Base.:>>Function
>>(x, n)

Right bit shift operator, x >> n. For n >= 0, the result is x shifted right by n bits, filling with 0s if x >= 0, 1s if x < 0, preserving the sign of x. This is equivalent to fld(x, 2^n). For n < 0, this is equivalent to x << -n.

Examples

julia> Int8(13) >> 2
 3
 
 julia> bitstring(Int8(13))
@@ -320,7 +320,7 @@
 "11110010"
 
 julia> bitstring(Int8(-4))
-"11111100"

See also >>>, <<.

source
>>(B::BitVector, n) -> BitVector

Right bit shift operator, B >> n. For n >= 0, the result is B with elements shifted n positions forward, filling with false values. If n < 0, elements are shifted backwards. Equivalent to B << -n.

Examples

julia> B = BitVector([true, false, true, false, false])
+"11111100"

See also >>>, <<.

source
>>(B::BitVector, n) -> BitVector

Right bit shift operator, B >> n. For n >= 0, the result is B with elements shifted n positions forward, filling with false values. If n < 0, elements are shifted backwards. Equivalent to B << -n.

Examples

julia> B = BitVector([true, false, true, false, false])
 5-element BitVector:
  1
  0
@@ -342,14 +342,14 @@
  1
  0
  0
- 0
source
Base.:>>>Function
>>>(x, n)

Unsigned right bit shift operator, x >>> n. For n >= 0, the result is x shifted right by n bits, filling with 0s. For n < 0, this is equivalent to x << -n.

For Unsigned integer types, this is equivalent to >>. For Signed integer types, this is equivalent to signed(unsigned(x) >> n).

Examples

julia> Int8(-14) >>> 2
+ 0
source
Base.:>>>Function
>>>(x, n)

Unsigned right bit shift operator, x >>> n. For n >= 0, the result is x shifted right by n bits, filling with 0s. For n < 0, this is equivalent to x << -n.

For Unsigned integer types, this is equivalent to >>. For Signed integer types, this is equivalent to signed(unsigned(x) >> n).

Examples

julia> Int8(-14) >>> 2
 60
 
 julia> bitstring(Int8(-14))
 "11110010"
 
 julia> bitstring(Int8(60))
-"00111100"

BigInts are treated as if having infinite size, so no filling is required and this is equivalent to >>.

See also >>, <<.

source
>>>(B::BitVector, n) -> BitVector

Unsigned right bitshift operator, B >>> n. Equivalent to B >> n. See >> for details and examples.

source
Base.bitrotateFunction
bitrotate(x::Base.BitInteger, k::Integer)

bitrotate(x, k) implements bitwise rotation. It returns the value of x with its bits rotated left k times. A negative value of k will rotate to the right instead.

Julia 1.5

This function requires Julia 1.5 or later.

See also: <<, circshift, BitArray.

julia> bitrotate(UInt8(114), 2)
+"00111100"

BigInts are treated as if having infinite size, so no filling is required and this is equivalent to >>.

See also >>, <<.

source
>>>(B::BitVector, n) -> BitVector

Unsigned right bitshift operator, B >>> n. Equivalent to B >> n. See >> for details and examples.

source
Base.bitrotateFunction
bitrotate(x::Base.BitInteger, k::Integer)

bitrotate(x, k) implements bitwise rotation. It returns the value of x with its bits rotated left k times. A negative value of k will rotate to the right instead.

Julia 1.5

This function requires Julia 1.5 or later.

See also: <<, circshift, BitArray.

julia> bitrotate(UInt8(114), 2)
 0xc9
 
 julia> bitstring(bitrotate(0b01110010, 2))
@@ -359,7 +359,7 @@
 "10011100"
 
 julia> bitstring(bitrotate(0b01110010, 8))
-"01110010"
source
Base.::Function
:expr

Quote an expression expr, returning the abstract syntax tree (AST) of expr. The AST may be of type Expr, Symbol, or a literal value. The syntax :identifier evaluates to a Symbol.

See also: Expr, Symbol, Meta.parse

Examples

julia> expr = :(a = b + 2*x)
+"01110010"
source
Base.::Function
:expr

Quote an expression expr, returning the abstract syntax tree (AST) of expr. The AST may be of type Expr, Symbol, or a literal value. The syntax :identifier evaluates to a Symbol.

See also: Expr, Symbol, Meta.parse

Examples

julia> expr = :(a = b + 2*x)
 :(a = b + 2x)
 
 julia> sym = :some_identifier
@@ -369,7 +369,7 @@
 0xff
 
 julia> typeof((expr, sym, value))
-Tuple{Expr, Symbol, UInt8}
source
Base.rangeFunction
range(start, stop, length)
+Tuple{Expr, Symbol, UInt8}
source
Base.rangeFunction
range(start, stop, length)
 range(start, stop; length, step)
 range(start; length, stop, step)
 range(;start, length, stop, step)

Construct a specialized array with evenly spaced elements and optimized storage (an AbstractRange) from the arguments. Mathematically a range is uniquely determined by any three of start, step, stop and length. Valid invocations of range are:

  • Call range with any three of start, step, stop, length.
  • Call range with two of start, stop, length. In this case step will be assumed to be one. If both arguments are Integers, a UnitRange will be returned.
  • Call range with one of stop or length. start and step will be assumed to be one.

See Extended Help for additional details on the returned type. See also logrange for logarithmically spaced points.

Examples

julia> range(1, length=100)
@@ -407,9 +407,9 @@
 
 julia> range(; stop = 6.5)
 1.0:1.0:6.0

If length is not specified and stop - start is not an integer multiple of step, a range that ends before stop will be produced.

julia> range(1, 3.5, step=2)
-1.0:2.0:3.0

Special care is taken to ensure intermediate values are computed rationally. To avoid this induced overhead, see the LinRange constructor.

Julia 1.1

stop as a positional argument requires at least Julia 1.1.

Julia 1.7

The versions without keyword arguments and start as a keyword argument require at least Julia 1.7.

Julia 1.8

The versions with stop as a sole keyword argument, or length as a sole keyword argument require at least Julia 1.8.

Extended Help

range will produce a Base.OneTo when the arguments are Integers and

  • Only length is provided
  • Only stop is provided

range will produce a UnitRange when the arguments are Integers and

  • Only start and stop are provided
  • Only length and stop are provided

A UnitRange is not produced if step is provided even if specified as one.

source
Base.OneToType
Base.OneTo(n)

Define an AbstractUnitRange that behaves like 1:n, with the added distinction that the lower limit is guaranteed (by the type system) to be 1.

source
Base.StepRangeLenType
StepRangeLen(         ref::R, step::S, len, [offset=1]) where {  R,S}
+1.0:2.0:3.0

Special care is taken to ensure intermediate values are computed rationally. To avoid this induced overhead, see the LinRange constructor.

Julia 1.1

stop as a positional argument requires at least Julia 1.1.

Julia 1.7

The versions without keyword arguments and start as a keyword argument require at least Julia 1.7.

Julia 1.8

The versions with stop as a sole keyword argument, or length as a sole keyword argument require at least Julia 1.8.

Extended Help

range will produce a Base.OneTo when the arguments are Integers and

  • Only length is provided
  • Only stop is provided

range will produce a UnitRange when the arguments are Integers and

  • Only start and stop are provided
  • Only length and stop are provided

A UnitRange is not produced if step is provided even if specified as one.

source
Base.OneToType
Base.OneTo(n)

Define an AbstractUnitRange that behaves like 1:n, with the added distinction that the lower limit is guaranteed (by the type system) to be 1.

source
Base.StepRangeLenType
StepRangeLen(         ref::R, step::S, len, [offset=1]) where {  R,S}
 StepRangeLen{T,R,S}(  ref::R, step::S, len, [offset=1]) where {T,R,S}
-StepRangeLen{T,R,S,L}(ref::R, step::S, len, [offset=1]) where {T,R,S,L}

A range r where r[i] produces values of type T (in the first form, T is deduced automatically), parameterized by a reference value, a step, and the length. By default ref is the starting value r[1], but alternatively you can supply it as the value of r[offset] for some other index 1 <= offset <= len. The syntax a:b or a:b:c, where any of a, b, or c are floating-point numbers, creates a StepRangeLen.

Julia 1.7

The 4th type parameter L requires at least Julia 1.7.

source
Base.lograngeFunction
logrange(start, stop, length)
+StepRangeLen{T,R,S,L}(ref::R, step::S, len, [offset=1]) where {T,R,S,L}

A range r where r[i] produces values of type T (in the first form, T is deduced automatically), parameterized by a reference value, a step, and the length. By default ref is the starting value r[1], but alternatively you can supply it as the value of r[offset] for some other index 1 <= offset <= len. The syntax a:b or a:b:c, where any of a, b, or c are floating-point numbers, creates a StepRangeLen.

Julia 1.7

The 4th type parameter L requires at least Julia 1.7.

source
Base.lograngeFunction
logrange(start, stop, length)
 logrange(start, stop; length)

Construct a specialized array whose elements are spaced logarithmically between the given endpoints. That is, the ratio of successive elements is a constant, calculated from the length.

This is similar to geomspace in Python. Unlike PowerRange in Mathematica, you specify the number of elements not the ratio. Unlike logspace in Python and Matlab, the start and stop arguments are always the first and last elements of the result, not powers applied to some base.

Examples

julia> logrange(10, 4000, length=3)
 3-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}:
  10.0, 200.0, 4000.0
@@ -425,7 +425,7 @@
  1.0, 1.41421, 2.0, 2.82843, 4.0, 5.65685, 8.0, 11.3137, 16.0, 22.6274, 32.0
 
 julia> logrange(1, 1000, length=4) ≈ 10 .^ (0:3)
-true

See the LogRange type for further details.

See also range for linearly spaced points.

Julia 1.11

This function requires at least Julia 1.11.

source
Base.LogRangeType
LogRange{T}(start, stop, len) <: AbstractVector{T}

A range whose elements are spaced logarithmically between start and stop, with spacing controlled by len. Returned by logrange.

Like LinRange, the first and last elements will be exactly those provided, but intermediate values may have small floating-point errors. These are calculated using the logs of the endpoints, which are stored on construction, often in higher precision than T.

Examples

julia> logrange(1, 4, length=5)
+true

See the LogRange type for further details.

See also range for linearly spaced points.

Julia 1.11

This function requires at least Julia 1.11.

source
Base.LogRangeType
LogRange{T}(start, stop, len) <: AbstractVector{T}

A range whose elements are spaced logarithmically between start and stop, with spacing controlled by len. Returned by logrange.

Like LinRange, the first and last elements will be exactly those provided, but intermediate values may have small floating-point errors. These are calculated using the logs of the endpoints, which are stored on construction, often in higher precision than T.

Examples

julia> logrange(1, 4, length=5)
 5-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}:
  1.0, 1.41421, 2.0, 2.82843, 4.0
 
@@ -448,26 +448,26 @@
  1.0, 8.0, 64.0, 512.0
 
 julia> 2 .^ (0:3:9) |> println
-[1, 8, 64, 512]
Julia 1.11

This type requires at least Julia 1.11.

source
Base.:==Function
==(x, y)

Generic equality operator. Falls back to ===. Should be implemented for all types with a notion of equality, based on the abstract value that an instance represents. For example, all numeric types are compared by numeric value, ignoring type. Strings are compared as sequences of characters, ignoring encoding. Collections of the same type generally compare their key sets, and if those are ==, then compare the values for each of those keys, returning true if all such pairs are ==. Other properties are typically not taken into account (such as the exact type).

This operator follows IEEE semantics for floating-point numbers: 0.0 == -0.0 and NaN != NaN.

The result is of type Bool, except when one of the operands is missing, in which case missing is returned (three-valued logic). Collections generally implement three-valued logic akin to all, returning missing if any operands contain missing values and all other pairs are equal. Use isequal or === to always get a Bool result.

Implementation

New numeric types should implement this function for two arguments of the new type, and handle comparison to other types via promotion rules where possible.

isequal falls back to ==, so new methods of == will be used by the Dict type to compare keys. If your type will be used as a dictionary key, it should therefore also implement hash.

If some type defines ==, isequal, and isless then it should also implement < to ensure consistency of comparisons.

source
Base.:!=Function
!=(x, y)
+[1, 8, 64, 512]
Julia 1.11

This type requires at least Julia 1.11.

source
Base.:==Function
==(x, y)

Generic equality operator. Falls back to ===. Should be implemented for all types with a notion of equality, based on the abstract value that an instance represents. For example, all numeric types are compared by numeric value, ignoring type. Strings are compared as sequences of characters, ignoring encoding. Collections of the same type generally compare their key sets, and if those are ==, then compare the values for each of those keys, returning true if all such pairs are ==. Other properties are typically not taken into account (such as the exact type).

This operator follows IEEE semantics for floating-point numbers: 0.0 == -0.0 and NaN != NaN.

The result is of type Bool, except when one of the operands is missing, in which case missing is returned (three-valued logic). Collections generally implement three-valued logic akin to all, returning missing if any operands contain missing values and all other pairs are equal. Use isequal or === to always get a Bool result.

Implementation

New numeric types should implement this function for two arguments of the new type, and handle comparison to other types via promotion rules where possible.

isequal falls back to ==, so new methods of == will be used by the Dict type to compare keys. If your type will be used as a dictionary key, it should therefore also implement hash.

If some type defines ==, isequal, and isless then it should also implement < to ensure consistency of comparisons.

source
Base.:!=Function
!=(x, y)
 ≠(x,y)

Not-equals comparison operator. Always gives the opposite answer as ==.

Implementation

New types should generally not implement this, and rely on the fallback definition !=(x,y) = !(x==y) instead.

Examples

julia> 3 != 2
 true
 
 julia> "foo" ≠ "foo"
-false
source
!=(x)

Create a function that compares its argument to x using !=, i.e. a function equivalent to y -> y != x. The returned function is of type Base.Fix2{typeof(!=)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.:!==Function
!==(x, y)
+false
source
!=(x)

Create a function that compares its argument to x using !=, i.e. a function equivalent to y -> y != x. The returned function is of type Base.Fix2{typeof(!=)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.:!==Function
!==(x, y)
 ≢(x,y)

Always gives the opposite answer as ===.

Examples

julia> a = [1, 2]; b = [1, 2];
 
 julia> a ≢ b
 true
 
 julia> a ≢ a
-false
source
Base.:<Function
<(x, y)

Less-than comparison operator. Falls back to isless. Because of the behavior of floating-point NaN values, this operator implements a partial order.

Implementation

New types with a canonical partial order should implement this function for two arguments of the new type. Types with a canonical total order should implement isless instead.

See also isunordered.

Examples

julia> 'a' < 'b'
+false
source
Base.:<Function
<(x, y)

Less-than comparison operator. Falls back to isless. Because of the behavior of floating-point NaN values, this operator implements a partial order.

Implementation

New types with a canonical partial order should implement this function for two arguments of the new type. Types with a canonical total order should implement isless instead.

See also isunordered.

Examples

julia> 'a' < 'b'
 true
 
 julia> "abc" < "abd"
 true
 
 julia> 5 < 3
-false
source
<(x)

Create a function that compares its argument to x using <, i.e. a function equivalent to y -> y < x. The returned function is of type Base.Fix2{typeof(<)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.:<=Function
<=(x, y)
+false
source
<(x)

Create a function that compares its argument to x using <, i.e. a function equivalent to y -> y < x. The returned function is of type Base.Fix2{typeof(<)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.:<=Function
<=(x, y)
 ≤(x,y)

Less-than-or-equals comparison operator. Falls back to (x < y) | (x == y).

Examples

julia> 'a' <= 'b'
 true
 
@@ -478,7 +478,7 @@
 true
 
 julia> 5 <= 3
-false
source
<=(x)

Create a function that compares its argument to x using <=, i.e. a function equivalent to y -> y <= x. The returned function is of type Base.Fix2{typeof(<=)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.:>Function
>(x, y)

Greater-than comparison operator. Falls back to y < x.

Implementation

Generally, new types should implement < instead of this function, and rely on the fallback definition >(x, y) = y < x.

Examples

julia> 'a' > 'b'
+false
source
<=(x)

Create a function that compares its argument to x using <=, i.e. a function equivalent to y -> y <= x. The returned function is of type Base.Fix2{typeof(<=)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.:>Function
>(x, y)

Greater-than comparison operator. Falls back to y < x.

Implementation

Generally, new types should implement < instead of this function, and rely on the fallback definition >(x, y) = y < x.

Examples

julia> 'a' > 'b'
 false
 
 julia> 7 > 3 > 1
@@ -488,7 +488,7 @@
 false
 
 julia> 5 > 3
-true
source
>(x)

Create a function that compares its argument to x using >, i.e. a function equivalent to y -> y > x. The returned function is of type Base.Fix2{typeof(>)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.:>=Function
>=(x, y)
+true
source
>(x)

Create a function that compares its argument to x using >, i.e. a function equivalent to y -> y > x. The returned function is of type Base.Fix2{typeof(>)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.:>=Function
>=(x, y)
 ≥(x,y)

Greater-than-or-equals comparison operator. Falls back to y <= x.

Examples

julia> 'a' >= 'b'
 false
 
@@ -499,7 +499,7 @@
 true
 
 julia> 5 >= 3
-true
source
>=(x)

Create a function that compares its argument to x using >=, i.e. a function equivalent to y -> y >= x. The returned function is of type Base.Fix2{typeof(>=)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.cmpFunction
cmp(x,y)

Return -1, 0, or 1 depending on whether x is less than, equal to, or greater than y, respectively. Uses the total order implemented by isless.

Examples

julia> cmp(1, 2)
+true
source
>=(x)

Create a function that compares its argument to x using >=, i.e. a function equivalent to y -> y >= x. The returned function is of type Base.Fix2{typeof(>=)}, which can be used to implement specialized methods.

Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.cmpFunction
cmp(x,y)

Return -1, 0, or 1 depending on whether x is less than, equal to, or greater than y, respectively. Uses the total order implemented by isless.

Examples

julia> cmp(1, 2)
 -1
 
 julia> cmp(2, 1)
@@ -507,7 +507,7 @@
 
 julia> cmp(2+im, 3-im)
 ERROR: MethodError: no method matching isless(::Complex{Int64}, ::Complex{Int64})
-[...]
source
cmp(<, x, y)

Return -1, 0, or 1 depending on whether x is less than, equal to, or greater than y, respectively. The first argument specifies a less-than comparison function to use.

source
cmp(a::AbstractString, b::AbstractString) -> Int

Compare two strings. Return 0 if both strings have the same length and the character at each index is the same in both strings. Return -1 if a is a prefix of b, or if a comes before b in alphabetical order. Return 1 if b is a prefix of a, or if b comes before a in alphabetical order (technically, lexicographical order by Unicode code points).

Examples

julia> cmp("abc", "abc")
+[...]
source
cmp(<, x, y)

Return -1, 0, or 1 depending on whether x is less than, equal to, or greater than y, respectively. The first argument specifies a less-than comparison function to use.

source
cmp(a::AbstractString, b::AbstractString) -> Int

Compare two strings. Return 0 if both strings have the same length and the character at each index is the same in both strings. Return -1 if a is a prefix of b, or if a comes before b in alphabetical order. Return 1 if b is a prefix of a, or if b comes before a in alphabetical order (technically, lexicographical order by Unicode code points).

Examples

julia> cmp("abc", "abc")
 0
 
 julia> cmp("ab", "abc")
@@ -526,14 +526,14 @@
 1
 
 julia> cmp("b", "β")
--1
source
Base.:~Function
~(x)

Bitwise not.

See also: !, &, |.

Examples

julia> ~4
+-1
source
Base.:~Function
~(x)

Bitwise not.

See also: !, &, |.

Examples

julia> ~4
 -5
 
 julia> ~10
 -11
 
 julia> ~true
-false
source
Base.:&Function
x & y

Bitwise and. Implements three-valued logic, returning missing if one operand is missing and the other is true. Add parentheses for function application form: (&)(x, y).

See also: |, xor, &&.

Examples

julia> 4 & 10
+false
source
Base.:&Function
x & y

Bitwise and. Implements three-valued logic, returning missing if one operand is missing and the other is true. Add parentheses for function application form: (&)(x, y).

See also: |, xor, &&.

Examples

julia> 4 & 10
 0
 
 julia> 4 & 12
@@ -543,7 +543,7 @@
 missing
 
 julia> false & missing
-false
source
Base.:|Function
x | y

Bitwise or. Implements three-valued logic, returning missing if one operand is missing and the other is false.

See also: &, xor, ||.

Examples

julia> 4 | 10
+false
source
Base.:|Function
x | y

Bitwise or. Implements three-valued logic, returning missing if one operand is missing and the other is false.

See also: &, xor, ||.

Examples

julia> 4 | 10
 14
 
 julia> 4 | 1
@@ -553,7 +553,7 @@
 true
 
 julia> false | missing
-missing
source
Base.xorFunction
xor(x, y)
+missing
source
Base.xorFunction
xor(x, y)
 ⊻(x, y)

Bitwise exclusive or of x and y. Implements three-valued logic, returning missing if one of the arguments is missing.

The infix operation a ⊻ b is a synonym for xor(a,b), and can be typed by tab-completing \xor or \veebar in the Julia REPL.

Examples

julia> xor(true, false)
 true
 
@@ -570,7 +570,7 @@
 3-element BitVector:
  0
  1
- 0
source
Base.nandFunction
nand(x, y)
+ 0
source
Base.nandFunction
nand(x, y)
 ⊼(x, y)

Bitwise nand (not and) of x and y. Implements three-valued logic, returning missing if one of the arguments is missing.

The infix operation a ⊼ b is a synonym for nand(a,b), and can be typed by tab-completing \nand or \barwedge in the Julia REPL.

Examples

julia> nand(true, false)
 true
 
@@ -587,7 +587,7 @@
 3-element BitVector:
  0
  1
- 1
source
Base.norFunction
nor(x, y)
+ 1
source
Base.norFunction
nor(x, y)
 ⊽(x, y)

Bitwise nor (not or) of x and y. Implements three-valued logic, returning missing if one of the arguments is missing and the other is not true.

The infix operation a ⊽ b is a synonym for nor(a,b), and can be typed by tab-completing \nor or \barvee in the Julia REPL.

Examples

julia> nor(true, false)
 false
 
@@ -607,7 +607,7 @@
 3-element BitVector:
  0
  0
- 1
source
Base.:!Function
!(x)

Boolean not. Implements three-valued logic, returning missing if x is missing.

See also ~ for bitwise not.

Examples

julia> !true
+ 1
source
Base.:!Function
!(x)

Boolean not. Implements three-valued logic, returning missing if x is missing.

See also ~ for bitwise not.

Examples

julia> !true
 false
 
 julia> !false
@@ -618,24 +618,24 @@
 
 julia> .![true false true]
 1×3 BitMatrix:
- 0  1  0
source
!f::Function

Predicate function negation: when the argument of ! is a function, it returns a composed function which computes the boolean negation of f.

See also .

Examples

julia> str = "∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
+ 0  1  0
source
!f::Function

Predicate function negation: when the argument of ! is a function, it returns a composed function which computes the boolean negation of f.

See also .

Examples

julia> str = "∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
 "∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
 
 julia> filter(isletter, str)
 "εδxyδfxfyε"
 
 julia> filter(!isletter, str)
-"∀  > 0, ∃  > 0: |-| <  ⇒ |()-()| < "
Julia 1.9

Starting with Julia 1.9, !f returns a ComposedFunction instead of an anonymous function.

source
&&Keyword
x && y

Short-circuiting boolean AND.

See also &, the ternary operator ? :, and the manual section on control flow.

Examples

julia> x = 3;
+"∀  > 0, ∃  > 0: |-| <  ⇒ |()-()| < "
Julia 1.9

Starting with Julia 1.9, !f returns a ComposedFunction instead of an anonymous function.

source
&&Keyword
x && y

Short-circuiting boolean AND.

See also &, the ternary operator ? :, and the manual section on control flow.

Examples

julia> x = 3;
 
 julia> x > 1 && x < 10 && x isa Int
 true
 
 julia> x < 0 && error("expected positive x")
-false
source
||Keyword
x || y

Short-circuiting boolean OR.

See also: |, xor, &&.

Examples

julia> pi < 3 || ℯ < 3
+false
source
||Keyword
x || y

Short-circuiting boolean OR.

See also: |, xor, &&.

Examples

julia> pi < 3 || ℯ < 3
 true
 
 julia> false || true || println("neither is true!")
-true
source

Mathematical Functions

Base.isapproxFunction
isapprox(x, y; atol::Real=0, rtol::Real=atol>0 ? 0 : √eps, nans::Bool=false[, norm::Function])

Inexact equality comparison. Two numbers compare equal if their relative distance or their absolute distance is within tolerance bounds: isapprox returns true if norm(x-y) <= max(atol, rtol*max(norm(x), norm(y))). The default atol (absolute tolerance) is zero and the default rtol (relative tolerance) depends on the types of x and y. The keyword argument nans determines whether or not NaN values are considered equal (defaults to false).

For real or complex floating-point values, if an atol > 0 is not specified, rtol defaults to the square root of eps of the type of x or y, whichever is bigger (least precise). This corresponds to requiring equality of about half of the significant digits. Otherwise, e.g. for integer arguments or if an atol > 0 is supplied, rtol defaults to zero.

The norm keyword defaults to abs for numeric (x,y) and to LinearAlgebra.norm for arrays (where an alternative norm choice is sometimes useful). When x and y are arrays, if norm(x-y) is not finite (i.e. ±Inf or NaN), the comparison falls back to checking whether all elements of x and y are approximately equal component-wise.

The binary operator is equivalent to isapprox with the default arguments, and x ≉ y is equivalent to !isapprox(x,y).

Note that x ≈ 0 (i.e., comparing to zero with the default tolerances) is equivalent to x == 0 since the default atol is 0. In such cases, you should either supply an appropriate atol (or use norm(x) ≤ atol) or rearrange your code (e.g. use x ≈ y rather than x - y ≈ 0). It is not possible to pick a nonzero atol automatically because it depends on the overall scaling (the "units") of your problem: for example, in x - y ≈ 0, atol=1e-9 is an absurdly small tolerance if x is the radius of the Earth in meters, but an absurdly large tolerance if x is the radius of a Hydrogen atom in meters.

Julia 1.6

Passing the norm keyword argument when comparing numeric (non-array) arguments requires Julia 1.6 or later.

Examples

julia> isapprox(0.1, 0.15; atol=0.05)
+true
source

Mathematical Functions

Base.isapproxFunction
isapprox(x, y; atol::Real=0, rtol::Real=atol>0 ? 0 : √eps, nans::Bool=false[, norm::Function])

Inexact equality comparison. Two numbers compare equal if their relative distance or their absolute distance is within tolerance bounds: isapprox returns true if norm(x-y) <= max(atol, rtol*max(norm(x), norm(y))). The default atol (absolute tolerance) is zero and the default rtol (relative tolerance) depends on the types of x and y. The keyword argument nans determines whether or not NaN values are considered equal (defaults to false).

For real or complex floating-point values, if an atol > 0 is not specified, rtol defaults to the square root of eps of the type of x or y, whichever is bigger (least precise). This corresponds to requiring equality of about half of the significant digits. Otherwise, e.g. for integer arguments or if an atol > 0 is supplied, rtol defaults to zero.

The norm keyword defaults to abs for numeric (x,y) and to LinearAlgebra.norm for arrays (where an alternative norm choice is sometimes useful). When x and y are arrays, if norm(x-y) is not finite (i.e. ±Inf or NaN), the comparison falls back to checking whether all elements of x and y are approximately equal component-wise.

The binary operator is equivalent to isapprox with the default arguments, and x ≉ y is equivalent to !isapprox(x,y).

Note that x ≈ 0 (i.e., comparing to zero with the default tolerances) is equivalent to x == 0 since the default atol is 0. In such cases, you should either supply an appropriate atol (or use norm(x) ≤ atol) or rearrange your code (e.g. use x ≈ y rather than x - y ≈ 0). It is not possible to pick a nonzero atol automatically because it depends on the overall scaling (the "units") of your problem: for example, in x - y ≈ 0, atol=1e-9 is an absurdly small tolerance if x is the radius of the Earth in meters, but an absurdly large tolerance if x is the radius of a Hydrogen atom in meters.

Julia 1.6

Passing the norm keyword argument when comparing numeric (non-array) arguments requires Julia 1.6 or later.

Examples

julia> isapprox(0.1, 0.15; atol=0.05)
 true
 
 julia> isapprox(0.1, 0.15; rtol=0.34)
@@ -654,7 +654,7 @@
 true
 
 julia> isapprox([10.0^9, 1.0], [10.0^9, 2.0]) # using `norm`
-true
source
isapprox(x; kwargs...) / ≈(x; kwargs...)

Create a function that compares its argument to x using , i.e. a function equivalent to y -> y ≈ x.

The keyword arguments supported here are the same as those in the 2-argument isapprox.

Julia 1.5

This method requires Julia 1.5 or later.

source
Base.sinMethod
sin(x::T) where {T <: Number} -> float(T)

Compute sine of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also sind, sinpi, sincos, cis, asin.

Examples

julia> round.(sin.(range(0, 2pi, length=9)'), digits=3)
+true
source
isapprox(x; kwargs...) / ≈(x; kwargs...)

Create a function that compares its argument to x using , i.e. a function equivalent to y -> y ≈ x.

The keyword arguments supported here are the same as those in the 2-argument isapprox.

Julia 1.5

This method requires Julia 1.5 or later.

source
Base.sinMethod
sin(x::T) where {T <: Number} -> float(T)

Compute sine of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also sind, sinpi, sincos, cis, asin.

Examples

julia> round.(sin.(range(0, 2pi, length=9)'), digits=3)
 1×9 Matrix{Float64}:
  0.0  0.707  1.0  0.707  0.0  -0.707  -1.0  -0.707  -0.0
 
@@ -671,7 +671,7 @@
 0.866 + 0.5im
 
 julia> round(exp(im*pi/6), digits=3)
-0.866 + 0.5im
source
Base.cosMethod
cos(x::T) where {T <: Number} -> float(T)

Compute cosine of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also cosd, cospi, sincos, cis.

source
Base.Math.sincosMethod
sincos(x::T) where T -> float(T)

Simultaneously compute the sine and cosine of x, where x is in radians, returning a tuple (sine, cosine).

Throw a DomainError if isinf(x), return a (T(NaN), T(NaN)) if isnan(x).

See also cis, sincospi, sincosd.

source
Base.tanMethod
tan(x::T) where {T <: Number} -> float(T)

Compute tangent of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also tanh.

source
Base.Math.sindFunction
sind(x::T) where T -> float(T)

Compute sine of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.cosdFunction
cosd(x::T) where T -> float(T)

Compute cosine of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.tandFunction
tand(x::T) where T -> float(T)

Compute tangent of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.sincosdFunction
sincosd(x::T) where T -> float(T)

Simultaneously compute the sine and cosine of x, where x is in degrees.

Throw a DomainError if isinf(x), return a (T(NaN), T(NaN)) tuple if isnan(x).

Julia 1.3

This function requires at least Julia 1.3.

source
Base.Math.sinpiFunction
sinpi(x::T) where T -> float(T)

Compute $\sin(\pi x)$ more accurately than sin(pi*x), especially for large x.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also sind, cospi, sincospi.

source
Base.Math.cospiFunction
cospi(x::T) where T -> float(T)

Compute $\cos(\pi x)$ more accurately than cos(pi*x), especially for large x.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also: cispi, sincosd, cospi.

source
Base.Math.sincospiFunction
sincospi(x::T) where T -> float(T)

Simultaneously compute sinpi(x) and cospi(x) (the sine and cosine of π*x, where x is in radians), returning a tuple (sine, cosine).

Throw a DomainError if isinf(x), return a (T(NaN), T(NaN)) tuple if isnan(x).

Julia 1.6

This function requires Julia 1.6 or later.

See also: cispi, sincosd, sinpi.

source
Base.sinhMethod
sinh(x)

Compute hyperbolic sine of x.

See also sin.

source
Base.coshMethod
cosh(x)

Compute hyperbolic cosine of x.

See also cos.

source
Base.tanhMethod
tanh(x)

Compute hyperbolic tangent of x.

See also tan, atanh.

Examples

julia> tanh.(-3:3f0)  # Here 3f0 isa Float32
+0.866 + 0.5im
source
Base.cosMethod
cos(x::T) where {T <: Number} -> float(T)

Compute cosine of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also cosd, cospi, sincos, cis.

source
Base.Math.sincosMethod
sincos(x::T) where T -> float(T)

Simultaneously compute the sine and cosine of x, where x is in radians, returning a tuple (sine, cosine).

Throw a DomainError if isinf(x), return a (T(NaN), T(NaN)) if isnan(x).

See also cis, sincospi, sincosd.

source
Base.tanMethod
tan(x::T) where {T <: Number} -> float(T)

Compute tangent of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also tanh.

source
Base.Math.sindFunction
sind(x::T) where T -> float(T)

Compute sine of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.cosdFunction
cosd(x::T) where T -> float(T)

Compute cosine of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.tandFunction
tand(x::T) where T -> float(T)

Compute tangent of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.sincosdFunction
sincosd(x::T) where T -> float(T)

Simultaneously compute the sine and cosine of x, where x is in degrees.

Throw a DomainError if isinf(x), return a (T(NaN), T(NaN)) tuple if isnan(x).

Julia 1.3

This function requires at least Julia 1.3.

source
Base.Math.sinpiFunction
sinpi(x::T) where T -> float(T)

Compute $\sin(\pi x)$ more accurately than sin(pi*x), especially for large x.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also sind, cospi, sincospi.

source
Base.Math.cospiFunction
cospi(x::T) where T -> float(T)

Compute $\cos(\pi x)$ more accurately than cos(pi*x), especially for large x.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

See also: cispi, sincosd, cospi.

source
Base.Math.sincospiFunction
sincospi(x::T) where T -> float(T)

Simultaneously compute sinpi(x) and cospi(x) (the sine and cosine of π*x, where x is in radians), returning a tuple (sine, cosine).

Throw a DomainError if isinf(x), return a (T(NaN), T(NaN)) tuple if isnan(x).

Julia 1.6

This function requires Julia 1.6 or later.

See also: cispi, sincosd, sinpi.

source
Base.sinhMethod
sinh(x)

Compute hyperbolic sine of x.

See also sin.

source
Base.coshMethod
cosh(x)

Compute hyperbolic cosine of x.

See also cos.

source
Base.tanhMethod
tanh(x)

Compute hyperbolic tangent of x.

See also tan, atanh.

Examples

julia> tanh.(-3:3f0)  # Here 3f0 isa Float32
 7-element Vector{Float32}:
  -0.9950548
  -0.9640276
@@ -685,11 +685,11 @@
 3-element Vector{ComplexF64}:
  0.0 + 0.7615941559557649im
  0.0 + 0.9640275800758169im
- 0.0 + 0.9950547536867306im
source
Base.asinMethod
asin(x::T) where {T <: Number} -> float(T)

Compute the inverse sine of x, where the output is in radians.

Return a T(NaN) if isnan(x).

See also asind for output in degrees.

Examples

julia> asin.((0, 1/2, 1))
+ 0.0 + 0.9950547536867306im
source
Base.asinMethod
asin(x::T) where {T <: Number} -> float(T)

Compute the inverse sine of x, where the output is in radians.

Return a T(NaN) if isnan(x).

See also asind for output in degrees.

Examples

julia> asin.((0, 1/2, 1))
 (0.0, 0.5235987755982989, 1.5707963267948966)
 
 julia> asind.((0, 1/2, 1))
-(0.0, 30.000000000000004, 90.0)
source
Base.acosMethod
acos(x::T) where {T <: Number} -> float(T)

Compute the inverse cosine of x, where the output is in radians

Return a T(NaN) if isnan(x).

source
Base.atanMethod
atan(y)
+(0.0, 30.000000000000004, 90.0)
source
Base.acosMethod
acos(x::T) where {T <: Number} -> float(T)

Compute the inverse cosine of x, where the output is in radians

Return a T(NaN) if isnan(x).

source
Base.atanMethod
atan(y)
 atan(y, x)

Compute the inverse tangent of y or y/x, respectively.

For one real argument, this is the angle in radians between the positive x-axis and the point (1, y), returning a value in the interval $[-\pi/2, \pi/2]$.

For two arguments, this is the angle in radians between the positive x-axis and the point (x, y), returning a value in the interval $[-\pi, \pi]$. This corresponds to a standard atan2 function. Note that by convention atan(0.0,x) is defined as $\pi$ and atan(-0.0,x) is defined as $-\pi$ when x < 0.

See also atand for degrees.

Examples

julia> rad2deg(atan(-1/√3))
 -30.000000000000004
 
@@ -697,11 +697,11 @@
 -30.000000000000004
 
 julia> rad2deg(atan(1, -√3))
-150.0
source
Base.Math.asindFunction
asind(x)

Compute the inverse sine of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.acosdFunction
acosd(x)

Compute the inverse cosine of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.atandFunction
atand(y::T) where T -> float(T)
+150.0
source
Base.Math.asindFunction
asind(x)

Compute the inverse sine of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.acosdFunction
acosd(x)

Compute the inverse cosine of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.atandFunction
atand(y::T) where T -> float(T)
 atand(y::T, x::S) where {T,S} -> promote_type(T,S)
-atand(y::AbstractMatrix{T}) where T -> AbstractMatrix{Complex{float(T)}}

Compute the inverse tangent of y or y/x, respectively, where the output is in degrees.

Return a NaN if isnan(y) or isnan(x). The returned NaN is either a T in the single argument version, or a promote_type(T,S) in the two argument version.

Julia 1.7

The one-argument method supports square matrix arguments as of Julia 1.7.

source
Base.Math.secMethod
sec(x::T) where {T <: Number} -> float(T)

Compute the secant of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.cscMethod
csc(x::T) where {T <: Number} -> float(T)

Compute the cosecant of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.cotMethod
cot(x::T) where {T <: Number} -> float(T)

Compute the cotangent of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.secdFunction
secd(x::T) where {T <: Number} -> float(T)

Compute the secant of x, where x is in degrees.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.cscdFunction
cscd(x::T) where {T <: Number} -> float(T)

Compute the cosecant of x, where x is in degrees.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.cotdFunction
cotd(x::T) where {T <: Number} -> float(T)

Compute the cotangent of x, where x is in degrees.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.asecMethod
asec(x::T) where {T <: Number} -> float(T)

Compute the inverse secant of x, where the output is in radians.

source
Base.Math.acscMethod
acsc(x::T) where {T <: Number} -> float(T)

Compute the inverse cosecant of x, where the output is in radians.

source
Base.Math.acotMethod
acot(x::T) where {T <: Number} -> float(T)

Compute the inverse cotangent of x, where the output is in radians.

source
Base.Math.asecdFunction
asecd(x)

Compute the inverse secant of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.acscdFunction
acscd(x)

Compute the inverse cosecant of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.acotdFunction
acotd(x)

Compute the inverse cotangent of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.sechMethod
sech(x::T) where {T <: Number} -> float(T)

Compute the hyperbolic secant of x.

Return a T(NaN) if isnan(x).

source
Base.Math.cschMethod
csch(x::T) where {T <: Number} -> float(T)

Compute the hyperbolic cosecant of x.

Return a T(NaN) if isnan(x).

source
Base.Math.cothMethod
coth(x::T) where {T <: Number} -> float(T)

Compute the hyperbolic cotangent of x.

Return a T(NaN) if isnan(x).

source
Base.asinhMethod
asinh(x)

Compute the inverse hyperbolic sine of x.

source
Base.acoshMethod
acosh(x)

Compute the inverse hyperbolic cosine of x.

source
Base.atanhMethod
atanh(x)

Compute the inverse hyperbolic tangent of x.

source
Base.Math.asechMethod
asech(x::T) where {T <: Number} -> float(T)

Compute the inverse hyperbolic secant of x.

source
Base.Math.acschMethod
acsch(x::T) where {T <: Number} -> float(T)

Compute the inverse hyperbolic cosecant of x.

source
Base.Math.acothMethod
acoth(x::T) where {T <: Number} -> float(T)

Compute the inverse hyperbolic cotangent of x.

source
Base.Math.sincFunction
sinc(x::T) where {T <: Number} -> float(T)

Compute normalized sinc function $\operatorname{sinc}(x) = \sin(\pi x) / (\pi x)$ if $x \neq 0$, and $1$ if $x = 0$.

Return a T(NaN) if isnan(x).

See also cosc, its derivative.

source
Base.Math.coscFunction
cosc(x::T) where {T <: Number} -> float(T)

Compute $\cos(\pi x) / x - \sin(\pi x) / (\pi x^2)$ if $x \neq 0$, and $0$ if $x = 0$. This is the derivative of sinc(x).

Return a T(NaN) if isnan(x).

See also sinc.

source
Base.Math.deg2radFunction
deg2rad(x)

Convert x from degrees to radians.

See also rad2deg, sind, pi.

Examples

julia> deg2rad(90)
-1.5707963267948966
source
Base.Math.rad2degFunction
rad2deg(x)

Convert x from radians to degrees.

See also deg2rad.

Examples

julia> rad2deg(pi)
-180.0
source
Base.Math.hypotFunction
hypot(x, y)

Compute the hypotenuse $\sqrt{|x|^2+|y|^2}$ avoiding overflow and underflow.

This code is an implementation of the algorithm described in: An Improved Algorithm for hypot(a,b) by Carlos F. Borges The article is available online at arXiv at the link https://arxiv.org/abs/1904.09481

hypot(x...)

Compute the hypotenuse $\sqrt{\sum |x_i|^2}$ avoiding overflow and underflow.

See also norm in the LinearAlgebra standard library.

Examples

julia> a = Int64(10)^10;
+atand(y::AbstractMatrix{T}) where T -> AbstractMatrix{Complex{float(T)}}

Compute the inverse tangent of y or y/x, respectively, where the output is in degrees.

Return a NaN if isnan(y) or isnan(x). The returned NaN is either a T in the single argument version, or a promote_type(T,S) in the two argument version.

Julia 1.7

The one-argument method supports square matrix arguments as of Julia 1.7.

source
Base.Math.secMethod
sec(x::T) where {T <: Number} -> float(T)

Compute the secant of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.cscMethod
csc(x::T) where {T <: Number} -> float(T)

Compute the cosecant of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.cotMethod
cot(x::T) where {T <: Number} -> float(T)

Compute the cotangent of x, where x is in radians.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.secdFunction
secd(x::T) where {T <: Number} -> float(T)

Compute the secant of x, where x is in degrees.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.cscdFunction
cscd(x::T) where {T <: Number} -> float(T)

Compute the cosecant of x, where x is in degrees.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.cotdFunction
cotd(x::T) where {T <: Number} -> float(T)

Compute the cotangent of x, where x is in degrees.

Throw a DomainError if isinf(x), return a T(NaN) if isnan(x).

source
Base.Math.asecMethod
asec(x::T) where {T <: Number} -> float(T)

Compute the inverse secant of x, where the output is in radians.

source
Base.Math.acscMethod
acsc(x::T) where {T <: Number} -> float(T)

Compute the inverse cosecant of x, where the output is in radians.

source
Base.Math.acotMethod
acot(x::T) where {T <: Number} -> float(T)

Compute the inverse cotangent of x, where the output is in radians.

source
Base.Math.asecdFunction
asecd(x)

Compute the inverse secant of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.acscdFunction
acscd(x)

Compute the inverse cosecant of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.acotdFunction
acotd(x)

Compute the inverse cotangent of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.

Julia 1.7

Matrix arguments require Julia 1.7 or later.

source
Base.Math.sechMethod
sech(x::T) where {T <: Number} -> float(T)

Compute the hyperbolic secant of x.

Return a T(NaN) if isnan(x).

source
Base.Math.cschMethod
csch(x::T) where {T <: Number} -> float(T)

Compute the hyperbolic cosecant of x.

Return a T(NaN) if isnan(x).

source
Base.Math.cothMethod
coth(x::T) where {T <: Number} -> float(T)

Compute the hyperbolic cotangent of x.

Return a T(NaN) if isnan(x).

source
Base.asinhMethod
asinh(x)

Compute the inverse hyperbolic sine of x.

source
Base.acoshMethod
acosh(x)

Compute the inverse hyperbolic cosine of x.

source
Base.atanhMethod
atanh(x)

Compute the inverse hyperbolic tangent of x.

source
Base.Math.asechMethod
asech(x::T) where {T <: Number} -> float(T)

Compute the inverse hyperbolic secant of x.

source
Base.Math.acschMethod
acsch(x::T) where {T <: Number} -> float(T)

Compute the inverse hyperbolic cosecant of x.

source
Base.Math.acothMethod
acoth(x::T) where {T <: Number} -> float(T)

Compute the inverse hyperbolic cotangent of x.

source
Base.Math.sincFunction
sinc(x::T) where {T <: Number} -> float(T)

Compute normalized sinc function $\operatorname{sinc}(x) = \sin(\pi x) / (\pi x)$ if $x \neq 0$, and $1$ if $x = 0$.

Return a T(NaN) if isnan(x).

See also cosc, its derivative.

source
Base.Math.coscFunction
cosc(x::T) where {T <: Number} -> float(T)

Compute $\cos(\pi x) / x - \sin(\pi x) / (\pi x^2)$ if $x \neq 0$, and $0$ if $x = 0$. This is the derivative of sinc(x).

Return a T(NaN) if isnan(x).

See also sinc.

source
Base.Math.deg2radFunction
deg2rad(x)

Convert x from degrees to radians.

See also rad2deg, sind, pi.

Examples

julia> deg2rad(90)
+1.5707963267948966
source
Base.Math.rad2degFunction
rad2deg(x)

Convert x from radians to degrees.

See also deg2rad.

Examples

julia> rad2deg(pi)
+180.0
source
Base.Math.hypotFunction
hypot(x, y)

Compute the hypotenuse $\sqrt{|x|^2+|y|^2}$ avoiding overflow and underflow.

This code is an implementation of the algorithm described in: An Improved Algorithm for hypot(a,b) by Carlos F. Borges The article is available online at arXiv at the link https://arxiv.org/abs/1904.09481

hypot(x...)

Compute the hypotenuse $\sqrt{\sum |x_i|^2}$ avoiding overflow and underflow.

See also norm in the LinearAlgebra standard library.

Examples

julia> a = Int64(10)^10;
 
 julia> hypot(a, a)
 1.4142135623730951e10
@@ -724,7 +724,7 @@
 julia> using LinearAlgebra
 
 julia> norm([a, a, a, a]) == hypot(a, a, a, a)
-true
source
Base.logMethod
log(x)

Compute the natural logarithm of x.

Throw a DomainError for negative Real arguments. Use Complex arguments to obtain Complex results.

Branch cut

log has a branch cut along the negative real axis; -0.0im is taken to be below the axis.

See also , log1p, log2, log10.

Examples

julia> log(2)
+true
source
Base.logMethod
log(x)

Compute the natural logarithm of x.

Throw a DomainError for negative Real arguments. Use Complex arguments to obtain Complex results.

Branch cut

log has a branch cut along the negative real axis; -0.0im is taken to be below the axis.

See also , log1p, log2, log10.

Examples

julia> log(2)
 0.6931471805599453
 
 julia> log(-3)
@@ -744,7 +744,7 @@
 3-element Vector{Float64}:
  -1.0
   0.0
-  1.0
source
Base.logMethod
log(b,x)

Compute the base b logarithm of x. Throw a DomainError for negative Real arguments.

Examples

julia> log(4,8)
+  1.0
source
Base.logMethod
log(b,x)

Compute the base b logarithm of x. Throw a DomainError for negative Real arguments.

Examples

julia> log(4,8)
 1.5
 
 julia> log(4,2)
@@ -766,7 +766,7 @@
 2.9999999999999996
 
 julia> log10(1000000)/2
-3.0
source
Base.log2Function
log2(x)

Compute the logarithm of x to base 2. Throw a DomainError for negative Real arguments.

See also: exp2, ldexp, ispow2.

Examples

julia> log2(4)
+3.0
source
Base.log2Function
log2(x)

Compute the logarithm of x to base 2. Throw a DomainError for negative Real arguments.

See also: exp2, ldexp, ispow2.

Examples

julia> log2(4)
 2.0
 
 julia> log2(10)
@@ -783,7 +783,7 @@
 3-element Vector{Float64}:
  -1.0
   0.0
-  1.0
source
Base.log10Function
log10(x)

Compute the logarithm of x to base 10. Throw a DomainError for negative Real arguments.

Examples

julia> log10(100)
+  1.0
source
Base.log10Function
log10(x)

Compute the logarithm of x to base 10. Throw a DomainError for negative Real arguments.

Examples

julia> log10(100)
 2.0
 
 julia> log10(2)
@@ -794,7 +794,7 @@
 log10 was called with a negative real argument but will only return a complex result if called with a complex argument. Try log10(Complex(x)).
 Stacktrace:
  [1] throw_complex_domainerror(f::Symbol, x::Float64) at ./math.jl:31
-[...]
source
Base.log1pFunction
log1p(x)

Accurate natural logarithm of 1+x. Throw a DomainError for Real arguments less than -1.

Examples

julia> log1p(-0.5)
+[...]
source
Base.log1pFunction
log1p(x)

Accurate natural logarithm of 1+x. Throw a DomainError for Real arguments less than -1.

Examples

julia> log1p(-0.5)
 -0.6931471805599453
 
 julia> log1p(0)
@@ -805,38 +805,38 @@
 log1p was called with a real argument < -1 but will only return a complex result if called with a complex argument. Try log1p(Complex(x)).
 Stacktrace:
  [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31
-[...]
source
Base.Math.frexpFunction
frexp(val)

Return (x,exp) such that x has a magnitude in the interval $[1/2, 1)$ or 0, and val is equal to $x \times 2^{exp}$.

See also significand, exponent, ldexp.

Examples

julia> frexp(6.0)
+[...]
source
Base.Math.frexpFunction
frexp(val)

Return (x,exp) such that x has a magnitude in the interval $[1/2, 1)$ or 0, and val is equal to $x \times 2^{exp}$.

See also significand, exponent, ldexp.

Examples

julia> frexp(6.0)
 (0.75, 3)
 
 julia> significand(6.0), exponent(6.0)  # interval [1, 2) instead
 (1.5, 2)
 
 julia> frexp(0.0), frexp(NaN), frexp(-Inf)  # exponent would give an error
-((0.0, 0), (NaN, 0), (-Inf, 0))
source
Base.expMethod
exp(x)

Compute the natural base exponential of x, in other words $ℯ^x$.

See also exp2, exp10 and cis.

Examples

julia> exp(1.0)
+((0.0, 0), (NaN, 0), (-Inf, 0))
source
Base.expMethod
exp(x)

Compute the natural base exponential of x, in other words $ℯ^x$.

See also exp2, exp10 and cis.

Examples

julia> exp(1.0)
 2.718281828459045
 
 julia> exp(im * pi) ≈ cis(pi)
-true
source
Base.exp2Function
exp2(x)

Compute the base 2 exponential of x, in other words $2^x$.

See also ldexp, <<.

Examples

julia> exp2(5)
+true
source
Base.exp2Function
exp2(x)

Compute the base 2 exponential of x, in other words $2^x$.

See also ldexp, <<.

Examples

julia> exp2(5)
 32.0
 
 julia> 2^5
 32
 
 julia> exp2(63) > typemax(Int)
-true
source
Base.exp10Function
exp10(x)

Compute the base 10 exponential of x, in other words $10^x$.

Examples

julia> exp10(2)
+true
source
Base.exp10Function
exp10(x)

Compute the base 10 exponential of x, in other words $10^x$.

Examples

julia> exp10(2)
 100.0
 
 julia> 10^2
-100
source
Base.Math.ldexpFunction
ldexp(x, n)

Compute $x \times 2^n$.

See also frexp, exponent.

Examples

julia> ldexp(5.0, 2)
-20.0
source
Base.Math.modfFunction
modf(x)

Return a tuple (fpart, ipart) of the fractional and integral parts of a number. Both parts have the same sign as the argument.

Examples

julia> modf(3.5)
+100
source
Base.Math.ldexpFunction
ldexp(x, n)

Compute $x \times 2^n$.

See also frexp, exponent.

Examples

julia> ldexp(5.0, 2)
+20.0
source
Base.Math.modfFunction
modf(x)

Return a tuple (fpart, ipart) of the fractional and integral parts of a number. Both parts have the same sign as the argument.

Examples

julia> modf(3.5)
 (0.5, 3.0)
 
 julia> modf(-3.5)
-(-0.5, -3.0)
source
Base.expm1Function
expm1(x)

Accurately compute $e^x-1$. It avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small values of x.

Examples

julia> expm1(1e-16)
+(-0.5, -3.0)
source
Base.expm1Function
expm1(x)

Accurately compute $e^x-1$. It avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small values of x.

Examples

julia> expm1(1e-16)
 1.0e-16
 
 julia> exp(1e-16) - 1
-0.0
source
Base.roundFunction
round([T,] x, [r::RoundingMode])
+0.0
source
Base.roundFunction
round([T,] x, [r::RoundingMode])
 round(x, [r::RoundingMode]; digits::Integer=0, base = 10)
 round(x, [r::RoundingMode]; sigdigits::Integer, base = 10)

Rounds the number x.

Without keyword arguments, x is rounded to an integer value, returning a value of type T, or of the same type of x if no T is provided. An InexactError will be thrown if the value is not representable by T, similar to convert.

If the digits keyword argument is provided, it rounds to the specified number of digits after the decimal place (or before if negative), in base base.

If the sigdigits keyword argument is provided, it rounds to the specified number of significant digits, in base base.

The RoundingMode r controls the direction of the rounding; the default is RoundNearest, which rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer. Note that round may give incorrect results if the global rounding mode is changed (see rounding).

Examples

julia> round(1.7)
 2.0
@@ -870,8 +870,8 @@
 true
 
 julia> round(x, digits=1)
-1.2

Extensions

To extend round to new numeric types, it is typically sufficient to define Base.round(x::NewType, r::RoundingMode).

source
Base.Rounding.RoundingModeType
RoundingMode

A type used for controlling the rounding mode of floating point operations (via rounding/setrounding functions), or as optional arguments for rounding to the nearest integer (via the round function).

Currently supported rounding modes are:

Julia 1.9

RoundFromZero requires at least Julia 1.9. Prior versions support RoundFromZero for BigFloats only.

source
Base.Rounding.RoundNearestConstant
RoundNearest

The default rounding mode. Rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer.

source
Base.Rounding.RoundNearestTiesAwayConstant
RoundNearestTiesAway

Rounds to nearest integer, with ties rounded away from zero (C/C++ round behaviour).

source
Base.Rounding.RoundNearestTiesUpConstant
RoundNearestTiesUp

Rounds to nearest integer, with ties rounded toward positive infinity (Java/JavaScript round behaviour).

source
Base.Rounding.RoundToZeroConstant
RoundToZero

round using this rounding mode is an alias for trunc.

source
Base.Rounding.RoundFromZeroConstant
RoundFromZero

Rounds away from zero.

Julia 1.9

RoundFromZero requires at least Julia 1.9. Prior versions support RoundFromZero for BigFloats only.

Examples

julia> BigFloat("1.0000000000000001", 5, RoundFromZero)
-1.06
source
Base.Rounding.RoundUpConstant
RoundUp

round using this rounding mode is an alias for ceil.

source
Base.Rounding.RoundDownConstant
RoundDown

round using this rounding mode is an alias for floor.

source
Base.roundMethod
round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]])
+1.2

Extensions

To extend round to new numeric types, it is typically sufficient to define Base.round(x::NewType, r::RoundingMode).

source
Base.Rounding.RoundingModeType
RoundingMode

A type used for controlling the rounding mode of floating point operations (via rounding/setrounding functions), or as optional arguments for rounding to the nearest integer (via the round function).

Currently supported rounding modes are:

Julia 1.9

RoundFromZero requires at least Julia 1.9. Prior versions support RoundFromZero for BigFloats only.

source
Base.Rounding.RoundNearestConstant
RoundNearest

The default rounding mode. Rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer.

source
Base.Rounding.RoundNearestTiesAwayConstant
RoundNearestTiesAway

Rounds to nearest integer, with ties rounded away from zero (C/C++ round behaviour).

source
Base.Rounding.RoundNearestTiesUpConstant
RoundNearestTiesUp

Rounds to nearest integer, with ties rounded toward positive infinity (Java/JavaScript round behaviour).

source
Base.Rounding.RoundToZeroConstant
RoundToZero

round using this rounding mode is an alias for trunc.

source
Base.Rounding.RoundFromZeroConstant
RoundFromZero

Rounds away from zero.

Julia 1.9

RoundFromZero requires at least Julia 1.9. Prior versions support RoundFromZero for BigFloats only.

Examples

julia> BigFloat("1.0000000000000001", 5, RoundFromZero)
+1.06
source
Base.Rounding.RoundUpConstant
RoundUp

round using this rounding mode is an alias for ceil.

source
Base.Rounding.RoundDownConstant
RoundDown

round using this rounding mode is an alias for floor.

source
Base.roundMethod
round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]])
 round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]; digits=0, base=10)
 round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]; sigdigits, base=10)

Return the nearest integral value of the same type as the complex-valued z to z, breaking ties using the specified RoundingModes. The first RoundingMode is used for rounding the real components while the second is used for rounding the imaginary components.

RoundingModeReal and RoundingModeImaginary default to RoundNearest, which rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer.

Examples

julia> round(3.14 + 4.5im)
 3.0 + 4.0im
@@ -883,11 +883,11 @@
 3.1 + 4.5im
 
 julia> round(3.14159 + 4.512im; sigdigits = 3)
-3.14 + 4.51im
source
Base.ceilFunction
ceil([T,] x)
+3.14 + 4.51im
source
Base.ceilFunction
ceil([T,] x)
 ceil(x; digits::Integer= [, base = 10])
-ceil(x; sigdigits::Integer= [, base = 10])

ceil(x) returns the nearest integral value of the same type as x that is greater than or equal to x.

ceil(T, x) converts the result to type T, throwing an InexactError if the ceiled value is not representable as a T.

Keywords digits, sigdigits and base work as for round.

To support ceil for a new type, define Base.round(x::NewType, ::RoundingMode{:Up}).

source
Base.floorFunction
floor([T,] x)
+ceil(x; sigdigits::Integer= [, base = 10])

ceil(x) returns the nearest integral value of the same type as x that is greater than or equal to x.

ceil(T, x) converts the result to type T, throwing an InexactError if the ceiled value is not representable as a T.

Keywords digits, sigdigits and base work as for round.

To support ceil for a new type, define Base.round(x::NewType, ::RoundingMode{:Up}).

source
Base.floorFunction
floor([T,] x)
 floor(x; digits::Integer= [, base = 10])
-floor(x; sigdigits::Integer= [, base = 10])

floor(x) returns the nearest integral value of the same type as x that is less than or equal to x.

floor(T, x) converts the result to type T, throwing an InexactError if the floored value is not representable a T.

Keywords digits, sigdigits and base work as for round.

To support floor for a new type, define Base.round(x::NewType, ::RoundingMode{:Down}).

source
Base.truncFunction
trunc([T,] x)
+floor(x; sigdigits::Integer= [, base = 10])

floor(x) returns the nearest integral value of the same type as x that is less than or equal to x.

floor(T, x) converts the result to type T, throwing an InexactError if the floored value is not representable a T.

Keywords digits, sigdigits and base work as for round.

To support floor for a new type, define Base.round(x::NewType, ::RoundingMode{:Down}).

source
Base.truncFunction
trunc([T,] x)
 trunc(x; digits::Integer= [, base = 10])
 trunc(x; sigdigits::Integer= [, base = 10])

trunc(x) returns the nearest integral value of the same type as x whose absolute value is less than or equal to the absolute value of x.

trunc(T, x) converts the result to type T, throwing an InexactError if the truncated value is not representable a T.

Keywords digits, sigdigits and base work as for round.

To support trunc for a new type, define Base.round(x::NewType, ::RoundingMode{:ToZero}).

See also: %, floor, unsigned, unsafe_trunc.

Examples

julia> trunc(2.22)
 2.0
@@ -896,20 +896,20 @@
 -2.2
 
 julia> trunc(Int, -2.22)
--2
source
Base.unsafe_truncFunction
unsafe_trunc(T, x)

Return the nearest integral value of type T whose absolute value is less than or equal to the absolute value of x. If the value is not representable by T, an arbitrary value will be returned. See also trunc.

Examples

julia> unsafe_trunc(Int, -2.2)
+-2
source
Base.unsafe_truncFunction
unsafe_trunc(T, x)

Return the nearest integral value of type T whose absolute value is less than or equal to the absolute value of x. If the value is not representable by T, an arbitrary value will be returned. See also trunc.

Examples

julia> unsafe_trunc(Int, -2.2)
 -2
 
 julia> unsafe_trunc(Int, NaN)
--9223372036854775808
source
Base.minFunction
min(x, y, ...)

Return the minimum of the arguments, with respect to isless. If any of the arguments is missing, return missing. See also the minimum function to take the minimum element from a collection.

Examples

julia> min(2, 5, 1)
+-9223372036854775808
source
Base.minFunction
min(x, y, ...)

Return the minimum of the arguments, with respect to isless. If any of the arguments is missing, return missing. See also the minimum function to take the minimum element from a collection.

Examples

julia> min(2, 5, 1)
 1
 
 julia> min(4, missing, 6)
-missing
source
Base.maxFunction
max(x, y, ...)

Return the maximum of the arguments, with respect to isless. If any of the arguments is missing, return missing. See also the maximum function to take the maximum element from a collection.

Examples

julia> max(2, 5, 1)
+missing
source
Base.maxFunction
max(x, y, ...)

Return the maximum of the arguments, with respect to isless. If any of the arguments is missing, return missing. See also the maximum function to take the maximum element from a collection.

Examples

julia> max(2, 5, 1)
 5
 
 julia> max(5, missing, 6)
-missing
source
Base.minmaxFunction
minmax(x, y)

Return (min(x,y), max(x,y)).

See also extrema that returns (minimum(x), maximum(x)).

Examples

julia> minmax('c','b')
-('b', 'c')
source
Base.Math.clampFunction
clamp(x, lo, hi)

Return x if lo <= x <= hi. If x > hi, return hi. If x < lo, return lo. Arguments are promoted to a common type.

See also clamp!, min, max.

Julia 1.3

missing as the first argument requires at least Julia 1.3.

Examples

julia> clamp.([pi, 1.0, big(10)], 2.0, 9.0)
+missing
source
Base.minmaxFunction
minmax(x, y)

Return (min(x,y), max(x,y)).

See also extrema that returns (minimum(x), maximum(x)).

Examples

julia> minmax('c','b')
+('b', 'c')
source
Base.Math.clampFunction
clamp(x, lo, hi)

Return x if lo <= x <= hi. If x > hi, return hi. If x < lo, return lo. Arguments are promoted to a common type.

See also clamp!, min, max.

Julia 1.3

missing as the first argument requires at least Julia 1.3.

Examples

julia> clamp.([pi, 1.0, big(10)], 2.0, 9.0)
 3-element Vector{BigFloat}:
  3.141592653589793238462643383279502884197169399375105820974944592307816406286198
  2.0
@@ -919,14 +919,14 @@
 3-element Vector{Int64}:
   6
   6
- 10
source
clamp(x, T)::T

Clamp x between typemin(T) and typemax(T) and convert the result to type T.

See also trunc.

Examples

julia> clamp(200, Int8)
+ 10
source
clamp(x, T)::T

Clamp x between typemin(T) and typemax(T) and convert the result to type T.

See also trunc.

Examples

julia> clamp(200, Int8)
 127
 
 julia> clamp(-200, Int8)
 -128
 
 julia> trunc(Int, 4pi^2)
-39
source
clamp(x::Integer, r::AbstractUnitRange)

Clamp x to lie within range r.

Julia 1.6

This method requires at least Julia 1.6.

source
Base.Math.clamp!Function
clamp!(array::AbstractArray, lo, hi)

Restrict values in array to the specified range, in-place. See also clamp.

Julia 1.3

missing entries in array require at least Julia 1.3.

Examples

julia> row = collect(-4:4)';
+39
source
clamp(x::Integer, r::AbstractUnitRange)

Clamp x to lie within range r.

Julia 1.6

This method requires at least Julia 1.6.

source
Base.Math.clamp!Function
clamp!(array::AbstractArray, lo, hi)

Restrict values in array to the specified range, in-place. See also clamp.

Julia 1.3

missing entries in array require at least Julia 1.3.

Examples

julia> row = collect(-4:4)';
 
 julia> clamp!(row, 0, Inf)
 1×9 adjoint(::Vector{Int64}) with eltype Int64:
@@ -934,7 +934,7 @@
 
 julia> clamp.((-4:4)', 0, Inf)
 1×9 Matrix{Float64}:
- 0.0  0.0  0.0  0.0  0.0  1.0  2.0  3.0  4.0
source
Base.absFunction
abs(x)

The absolute value of x.

When abs is applied to signed integers, overflow may occur, resulting in the return of a negative value. This overflow occurs only when abs is applied to the minimum representable value of a signed integer. That is, when x == typemin(typeof(x)), abs(x) == x < 0, not -x as might be expected.

See also: abs2, unsigned, sign.

Examples

julia> abs(-3)
+ 0.0  0.0  0.0  0.0  0.0  1.0  2.0  3.0  4.0
source
Base.absFunction
abs(x)

The absolute value of x.

When abs is applied to signed integers, overflow may occur, resulting in the return of a negative value. This overflow occurs only when abs is applied to the minimum representable value of a signed integer. That is, when x == typemin(typeof(x)), abs(x) == x < 0, not -x as might be expected.

See also: abs2, unsigned, sign.

Examples

julia> abs(-3)
 3
 
 julia> abs(1 + im)
@@ -945,18 +945,18 @@
  -128  127  126  0  126  127
 
 julia> maximum(abs, [1, -2, 3, -4])
-4
source
Base.CheckedModule
Checked

The Checked module provides arithmetic functions for the built-in signed and unsigned Integer types which throw an error when an overflow occurs. They are named like checked_sub, checked_div, etc. In addition, add_with_overflow, sub_with_overflow, mul_with_overflow return both the unchecked results and a boolean value denoting the presence of an overflow.

source
Base.Checked.checked_absFunction
Base.checked_abs(x)

Calculates abs(x), checking for overflow errors where applicable. For example, standard two's complement signed integers (e.g. Int) cannot represent abs(typemin(Int)), thus leading to an overflow.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_negFunction
Base.checked_neg(x)

Calculates -x, checking for overflow errors where applicable. For example, standard two's complement signed integers (e.g. Int) cannot represent -typemin(Int), thus leading to an overflow.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_addFunction
Base.checked_add(x, y)

Calculates x+y, checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_subFunction
Base.checked_sub(x, y)

Calculates x-y, checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_mulFunction
Base.checked_mul(x, y)

Calculates x*y, checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_divFunction
Base.checked_div(x, y)

Calculates div(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_remFunction
Base.checked_rem(x, y)

Calculates x%y, checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_fldFunction
Base.checked_fld(x, y)

Calculates fld(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_modFunction
Base.checked_mod(x, y)

Calculates mod(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_cldFunction
Base.checked_cld(x, y)

Calculates cld(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_powFunction
Base.checked_pow(x, y)

Calculates ^(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.add_with_overflowFunction
Base.add_with_overflow(x, y) -> (r, f)

Calculates r = x+y, with the flag f indicating whether overflow has occurred.

source
Base.Checked.sub_with_overflowFunction
Base.sub_with_overflow(x, y) -> (r, f)

Calculates r = x-y, with the flag f indicating whether overflow has occurred.

source
Base.Checked.mul_with_overflowFunction
Base.mul_with_overflow(x, y) -> (r, f)

Calculates r = x*y, with the flag f indicating whether overflow has occurred.

source
Base.abs2Function
abs2(x)

Squared absolute value of x.

This can be faster than abs(x)^2, especially for complex numbers where abs(x) requires a square root via hypot.

See also abs, conj, real.

Examples

julia> abs2(-3)
+4
source
Base.CheckedModule
Checked

The Checked module provides arithmetic functions for the built-in signed and unsigned Integer types which throw an error when an overflow occurs. They are named like checked_sub, checked_div, etc. In addition, add_with_overflow, sub_with_overflow, mul_with_overflow return both the unchecked results and a boolean value denoting the presence of an overflow.

source
Base.Checked.checked_absFunction
Base.checked_abs(x)

Calculates abs(x), checking for overflow errors where applicable. For example, standard two's complement signed integers (e.g. Int) cannot represent abs(typemin(Int)), thus leading to an overflow.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_negFunction
Base.checked_neg(x)

Calculates -x, checking for overflow errors where applicable. For example, standard two's complement signed integers (e.g. Int) cannot represent -typemin(Int), thus leading to an overflow.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_addFunction
Base.checked_add(x, y)

Calculates x+y, checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_subFunction
Base.checked_sub(x, y)

Calculates x-y, checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_mulFunction
Base.checked_mul(x, y)

Calculates x*y, checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_divFunction
Base.checked_div(x, y)

Calculates div(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_remFunction
Base.checked_rem(x, y)

Calculates x%y, checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_fldFunction
Base.checked_fld(x, y)

Calculates fld(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_modFunction
Base.checked_mod(x, y)

Calculates mod(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_cldFunction
Base.checked_cld(x, y)

Calculates cld(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.checked_powFunction
Base.checked_pow(x, y)

Calculates ^(x,y), checking for overflow errors where applicable.

The overflow protection may impose a perceptible performance penalty.

source
Base.Checked.add_with_overflowFunction
Base.add_with_overflow(x, y) -> (r, f)

Calculates r = x+y, with the flag f indicating whether overflow has occurred.

source
Base.Checked.sub_with_overflowFunction
Base.sub_with_overflow(x, y) -> (r, f)

Calculates r = x-y, with the flag f indicating whether overflow has occurred.

source
Base.Checked.mul_with_overflowFunction
Base.mul_with_overflow(x, y) -> (r, f)

Calculates r = x*y, with the flag f indicating whether overflow has occurred.

source
Base.abs2Function
abs2(x)

Squared absolute value of x.

This can be faster than abs(x)^2, especially for complex numbers where abs(x) requires a square root via hypot.

See also abs, conj, real.

Examples

julia> abs2(-3)
 9
 
 julia> abs2(3.0 + 4.0im)
 25.0
 
 julia> sum(abs2, [1+2im, 3+4im])  # LinearAlgebra.norm(x)^2
-30
source
Base.copysignFunction
copysign(x, y) -> z

Return z which has the magnitude of x and the same sign as y.

Examples

julia> copysign(1, -2)
+30
source
Base.copysignFunction
copysign(x, y) -> z

Return z which has the magnitude of x and the same sign as y.

Examples

julia> copysign(1, -2)
 -1
 
 julia> copysign(-1, 2)
-1
source
Base.signFunction
sign(x)

Return zero if x==0 and $x/|x|$ otherwise (i.e., ±1 for real x).

See also signbit, zero, copysign, flipsign.

Examples

julia> sign(-4.0)
+1
source
Base.signFunction
sign(x)

Return zero if x==0 and $x/|x|$ otherwise (i.e., ±1 for real x).

See also signbit, zero, copysign, flipsign.

Examples

julia> sign(-4.0)
 -1.0
 
 julia> sign(99)
@@ -966,7 +966,7 @@
 -0.0
 
 julia> sign(0 + im)
-0.0 + 1.0im
source
Base.signbitFunction
signbit(x)

Return true if the value of the sign of x is negative, otherwise false.

See also sign and copysign.

Examples

julia> signbit(-4)
+0.0 + 1.0im
source
Base.signbitFunction
signbit(x)

Return true if the value of the sign of x is negative, otherwise false.

See also sign and copysign.

Examples

julia> signbit(-4)
 true
 
 julia> signbit(5)
@@ -976,11 +976,11 @@
 false
 
 julia> signbit(-4.1)
-true
source
Base.flipsignFunction
flipsign(x, y)

Return x with its sign flipped if y is negative. For example abs(x) = flipsign(x,x).

Examples

julia> flipsign(5, 3)
+true
source
Base.flipsignFunction
flipsign(x, y)

Return x with its sign flipped if y is negative. For example abs(x) = flipsign(x,x).

Examples

julia> flipsign(5, 3)
 5
 
 julia> flipsign(5, -3)
--5
source
Base.sqrtMethod
sqrt(x)

Return $\sqrt{x}$.

Throw a DomainError for negative Real arguments. Use Complex negative arguments instead to obtain a Complex result.

The prefix operator is equivalent to sqrt.

Branch cut

sqrt has a branch cut along the negative real axis; -0.0im is taken to be below the axis.

See also: hypot.

Examples

julia> sqrt(big(81))
+-5
source
Base.sqrtMethod
sqrt(x)

Return $\sqrt{x}$.

Throw a DomainError for negative Real arguments. Use Complex negative arguments instead to obtain a Complex result.

The prefix operator is equivalent to sqrt.

Branch cut

sqrt has a branch cut along the negative real axis; -0.0im is taken to be below the axis.

See also: hypot.

Examples

julia> sqrt(big(81))
 9.0
 
 julia> sqrt(big(-81))
@@ -1001,17 +1001,17 @@
  1.0
  1.4142135623730951
  1.7320508075688772
- 2.0
source
Base.isqrtFunction
isqrt(n::Integer)

Integer square root: the largest integer m such that m*m <= n.

julia> isqrt(5)
-2
source
Base.Math.cbrtMethod
cbrt(x::Real)

Return the cube root of x, i.e. $x^{1/3}$. Negative values are accepted (returning the negative real root when $x < 0$).

The prefix operator is equivalent to cbrt.

Examples

julia> cbrt(big(27))
+ 2.0
source
Base.isqrtFunction
isqrt(n::Integer)

Integer square root: the largest integer m such that m*m <= n.

julia> isqrt(5)
+2
source
Base.Math.cbrtMethod
cbrt(x::Real)

Return the cube root of x, i.e. $x^{1/3}$. Negative values are accepted (returning the negative real root when $x < 0$).

The prefix operator is equivalent to cbrt.

Examples

julia> cbrt(big(27))
 3.0
 
 julia> cbrt(big(-27))
--3.0
source
Base.realFunction
real(z)

Return the real part of the complex number z.

See also: imag, reim, complex, isreal, Real.

Examples

julia> real(1 + 3im)
-1
source
real(T::Type)

Return the type that represents the real part of a value of type T. e.g: for T == Complex{R}, returns R. Equivalent to typeof(real(zero(T))).

Examples

julia> real(Complex{Int})
+-3.0
source
Base.realFunction
real(z)

Return the real part of the complex number z.

See also: imag, reim, complex, isreal, Real.

Examples

julia> real(1 + 3im)
+1
source
real(T::Type)

Return the type that represents the real part of a value of type T. e.g: for T == Complex{R}, returns R. Equivalent to typeof(real(zero(T))).

Examples

julia> real(Complex{Int})
 Int64
 
 julia> real(Float64)
-Float64
source
real(A::AbstractArray)

Return an array containing the real part of each entry in array A.

Equivalent to real.(A), except that when eltype(A) <: Real A is returned without copying, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).

Examples

julia> real([1, 2im, 3 + 4im])
+Float64
source
real(A::AbstractArray)

Return an array containing the real part of each entry in array A.

Equivalent to real.(A), except that when eltype(A) <: Real A is returned without copying, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).

Examples

julia> real([1, 2im, 3 + 4im])
 3-element Vector{Int64}:
  1
  0
@@ -1019,8 +1019,8 @@
 
 julia> real(fill(2 - im))
 0-dimensional Array{Int64, 0}:
-2
source
Base.imagFunction
imag(z)

Return the imaginary part of the complex number z.

See also: conj, reim, adjoint, angle.

Examples

julia> imag(1 + 3im)
-3
source
imag(A::AbstractArray)

Return an array containing the imaginary part of each entry in array A.

Equivalent to imag.(A), except that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).

Examples

julia> imag([1, 2im, 3 + 4im])
+2
source
Base.imagFunction
imag(z)

Return the imaginary part of the complex number z.

See also: conj, reim, adjoint, angle.

Examples

julia> imag(1 + 3im)
+3
source
imag(A::AbstractArray)

Return an array containing the imaginary part of each entry in array A.

Equivalent to imag.(A), except that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).

Examples

julia> imag([1, 2im, 3 + 4im])
 3-element Vector{Int64}:
  0
  2
@@ -1028,13 +1028,13 @@
 
 julia> imag(fill(2 - im))
 0-dimensional Array{Int64, 0}:
--1
source
Base.reimFunction
reim(z)

Return a tuple of the real and imaginary parts of the complex number z.

Examples

julia> reim(1 + 3im)
-(1, 3)
source
reim(A::AbstractArray)

Return a tuple of two arrays containing respectively the real and the imaginary part of each entry in A.

Equivalent to (real.(A), imag.(A)), except that when eltype(A) <: Real A is returned without copying to represent the real part, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).

Examples

julia> reim([1, 2im, 3 + 4im])
+-1
source
Base.reimFunction
reim(z)

Return a tuple of the real and imaginary parts of the complex number z.

Examples

julia> reim(1 + 3im)
+(1, 3)
source
reim(A::AbstractArray)

Return a tuple of two arrays containing respectively the real and the imaginary part of each entry in A.

Equivalent to (real.(A), imag.(A)), except that when eltype(A) <: Real A is returned without copying to represent the real part, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).

Examples

julia> reim([1, 2im, 3 + 4im])
 ([1, 0, 3], [0, 2, 4])
 
 julia> reim(fill(2 - im))
-(fill(2), fill(-1))
source
Base.conjFunction
conj(z)

Compute the complex conjugate of a complex number z.

See also: angle, adjoint.

Examples

julia> conj(1 + 3im)
-1 - 3im
source
conj(A::AbstractArray)

Return an array containing the complex conjugate of each entry in array A.

Equivalent to conj.(A), except that when eltype(A) <: Real A is returned without copying, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).

Examples

julia> conj([1, 2im, 3 + 4im])
+(fill(2), fill(-1))
source
Base.conjFunction
conj(z)

Compute the complex conjugate of a complex number z.

See also: angle, adjoint.

Examples

julia> conj(1 + 3im)
+1 - 3im
source
conj(A::AbstractArray)

Return an array containing the complex conjugate of each entry in array A.

Equivalent to conj.(A), except that when eltype(A) <: Real A is returned without copying, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).

Examples

julia> conj([1, 2im, 3 + 4im])
 3-element Vector{Complex{Int64}}:
  1 + 0im
  0 - 2im
@@ -1042,7 +1042,7 @@
 
 julia> conj(fill(2 - im))
 0-dimensional Array{Complex{Int64}, 0}:
-2 + 1im
source
Base.angleFunction
angle(z)

Compute the phase angle in radians of a complex number z.

Returns a number -pi ≤ angle(z) ≤ pi, and is thus discontinuous along the negative real axis.

See also: atan, cis, rad2deg.

Examples

julia> rad2deg(angle(1 + im))
+2 + 1im
source
Base.angleFunction
angle(z)

Compute the phase angle in radians of a complex number z.

Returns a number -pi ≤ angle(z) ≤ pi, and is thus discontinuous along the negative real axis.

See also: atan, cis, rad2deg.

Examples

julia> rad2deg(angle(1 + im))
 45.0
 
 julia> rad2deg(angle(1 - im))
@@ -1052,19 +1052,19 @@
 180.0
 
 julia> rad2deg(angle(-1 - 1e-20im))
--180.0
source
Base.cisFunction
cis(x)

More efficient method for exp(im*x) by using Euler's formula: $\cos(x) + i \sin(x) = \exp(i x)$.

See also cispi, sincos, exp, angle.

Examples

julia> cis(π) ≈ -1
-true
source
Base.cispiFunction
cispi(x)

More accurate method for cis(pi*x) (especially for large x).

See also cis, sincospi, exp, angle.

Examples

julia> cispi(10000)
+-180.0
source
Base.cisFunction
cis(x)

More efficient method for exp(im*x) by using Euler's formula: $\cos(x) + i \sin(x) = \exp(i x)$.

See also cispi, sincos, exp, angle.

Examples

julia> cis(π) ≈ -1
+true
source
Base.cispiFunction
cispi(x)

More accurate method for cis(pi*x) (especially for large x).

See also cis, sincospi, exp, angle.

Examples

julia> cispi(10000)
 1.0 + 0.0im
 
 julia> cispi(0.25 + 1im)
-0.030556854645954562 + 0.03055685464595456im
Julia 1.6

This function requires Julia 1.6 or later.

source
Base.binomialFunction
binomial(n::Integer, k::Integer)

The binomial coefficient $\binom{n}{k}$, being the coefficient of the $k$th term in the polynomial expansion of $(1+x)^n$.

If $n$ is non-negative, then it is the number of ways to choose k out of n items:

\[\binom{n}{k} = \frac{n!}{k! (n-k)!}\]

where $n!$ is the factorial function.

If $n$ is negative, then it is defined in terms of the identity

\[\binom{n}{k} = (-1)^k \binom{k-n-1}{k}\]

See also factorial.

Examples

julia> binomial(5, 3)
+0.030556854645954562 + 0.03055685464595456im
Julia 1.6

This function requires Julia 1.6 or later.

source
Base.binomialFunction
binomial(n::Integer, k::Integer)

The binomial coefficient $\binom{n}{k}$, being the coefficient of the $k$th term in the polynomial expansion of $(1+x)^n$.

If $n$ is non-negative, then it is the number of ways to choose k out of n items:

\[\binom{n}{k} = \frac{n!}{k! (n-k)!}\]

where $n!$ is the factorial function.

If $n$ is negative, then it is defined in terms of the identity

\[\binom{n}{k} = (-1)^k \binom{k-n-1}{k}\]

See also factorial.

Examples

julia> binomial(5, 3)
 10
 
 julia> factorial(5) ÷ (factorial(5-3) * factorial(3))
 10
 
 julia> binomial(-5, 3)
--35

External links

source
binomial(x::Number, k::Integer)

The generalized binomial coefficient, defined for k ≥ 0 by the polynomial

\[\frac{1}{k!} \prod_{j=0}^{k-1} (x - j)\]

When k < 0 it returns zero.

For the case of integer x, this is equivalent to the ordinary integer binomial coefficient

\[\binom{n}{k} = \frac{n!}{k! (n-k)!}\]

Further generalizations to non-integer k are mathematically possible, but involve the Gamma function and/or the beta function, which are not provided by the Julia standard library but are available in external packages such as SpecialFunctions.jl.

External links

source
Base.factorialFunction
factorial(n::Integer)

Factorial of n. If n is an Integer, the factorial is computed as an integer (promoted to at least 64 bits). Note that this may overflow if n is not small, but you can use factorial(big(n)) to compute the result exactly in arbitrary precision.

See also binomial.

Examples

julia> factorial(6)
+-35

External links

source
binomial(x::Number, k::Integer)

The generalized binomial coefficient, defined for k ≥ 0 by the polynomial

\[\frac{1}{k!} \prod_{j=0}^{k-1} (x - j)\]

When k < 0 it returns zero.

For the case of integer x, this is equivalent to the ordinary integer binomial coefficient

\[\binom{n}{k} = \frac{n!}{k! (n-k)!}\]

Further generalizations to non-integer k are mathematically possible, but involve the Gamma function and/or the beta function, which are not provided by the Julia standard library but are available in external packages such as SpecialFunctions.jl.

External links

source
Base.factorialFunction
factorial(n::Integer)

Factorial of n. If n is an Integer, the factorial is computed as an integer (promoted to at least 64 bits). Note that this may overflow if n is not small, but you can use factorial(big(n)) to compute the result exactly in arbitrary precision.

See also binomial.

Examples

julia> factorial(6)
 720
 
 julia> factorial(21)
@@ -1073,7 +1073,7 @@
 [...]
 
 julia> factorial(big(21))
-51090942171709440000

External links

source
Base.gcdFunction
gcd(x, y...)

Greatest common (positive) divisor (or zero if all arguments are zero). The arguments may be integer and rational numbers.

Julia 1.4

Rational arguments require Julia 1.4 or later.

Examples

julia> gcd(6, 9)
+51090942171709440000

External links

source
Base.gcdFunction
gcd(x, y...)

Greatest common (positive) divisor (or zero if all arguments are zero). The arguments may be integer and rational numbers.

Julia 1.4

Rational arguments require Julia 1.4 or later.

Examples

julia> gcd(6, 9)
 3
 
 julia> gcd(6, -9)
@@ -1095,7 +1095,7 @@
 1//3
 
 julia> gcd(0, 0, 10, 15)
-5
source
Base.lcmFunction
lcm(x, y...)

Least common (positive) multiple (or zero if any argument is zero). The arguments may be integer and rational numbers.

Julia 1.4

Rational arguments require Julia 1.4 or later.

Examples

julia> lcm(2, 3)
+5
source
Base.lcmFunction
lcm(x, y...)

Least common (positive) multiple (or zero if any argument is zero). The arguments may be integer and rational numbers.

Julia 1.4

Rational arguments require Julia 1.4 or later.

Examples

julia> lcm(2, 3)
 6
 
 julia> lcm(-2, 3)
@@ -1117,11 +1117,11 @@
 2//1
 
 julia> lcm(1, 3, 5, 7)
-105
source
Base.gcdxFunction
gcdx(a, b)

Computes the greatest common (positive) divisor of a and b and their Bézout coefficients, i.e. the integer coefficients u and v that satisfy $ua+vb = d = gcd(a, b)$. $gcdx(a, b)$ returns $(d, u, v)$.

The arguments may be integer and rational numbers.

Julia 1.4

Rational arguments require Julia 1.4 or later.

Examples

julia> gcdx(12, 42)
+105
source
Base.gcdxFunction
gcdx(a, b)

Computes the greatest common (positive) divisor of a and b and their Bézout coefficients, i.e. the integer coefficients u and v that satisfy $ua+vb = d = gcd(a, b)$. $gcdx(a, b)$ returns $(d, u, v)$.

The arguments may be integer and rational numbers.

Julia 1.4

Rational arguments require Julia 1.4 or later.

Examples

julia> gcdx(12, 42)
 (6, -3, 1)
 
 julia> gcdx(240, 46)
-(2, -9, 47)
Note

Bézout coefficients are not uniquely defined. gcdx returns the minimal Bézout coefficients that are computed by the extended Euclidean algorithm. (Ref: D. Knuth, TAoCP, 2/e, p. 325, Algorithm X.) For signed integers, these coefficients u and v are minimal in the sense that $|u| < |b/d|$ and $|v| < |a/d|$. Furthermore, the signs of u and v are chosen so that d is positive. For unsigned integers, the coefficients u and v might be near their typemax, and the identity then holds only via the unsigned integers' modulo arithmetic.

source
Base.ispow2Function
ispow2(n::Number) -> Bool

Test whether n is an integer power of two.

See also count_ones, prevpow, nextpow.

Examples

julia> ispow2(4)
+(2, -9, 47)
Note

Bézout coefficients are not uniquely defined. gcdx returns the minimal Bézout coefficients that are computed by the extended Euclidean algorithm. (Ref: D. Knuth, TAoCP, 2/e, p. 325, Algorithm X.) For signed integers, these coefficients u and v are minimal in the sense that $|u| < |b/d|$ and $|v| < |a/d|$. Furthermore, the signs of u and v are chosen so that d is positive. For unsigned integers, the coefficients u and v might be near their typemax, and the identity then holds only via the unsigned integers' modulo arithmetic.

source
Base.ispow2Function
ispow2(n::Number) -> Bool

Test whether n is an integer power of two.

See also count_ones, prevpow, nextpow.

Examples

julia> ispow2(4)
 true
 
 julia> ispow2(5)
@@ -1134,7 +1134,7 @@
 true
 
 julia> ispow2(1//8)
-true
Julia 1.6

Support for non-Integer arguments was added in Julia 1.6.

source
Base.nextpowFunction
nextpow(a, x)

The smallest a^n not less than x, where n is a non-negative integer. a must be greater than 1, and x must be greater than 0.

See also prevpow.

Examples

julia> nextpow(2, 7)
+true
Julia 1.6

Support for non-Integer arguments was added in Julia 1.6.

source
Base.nextpowFunction
nextpow(a, x)

The smallest a^n not less than x, where n is a non-negative integer. a must be greater than 1, and x must be greater than 0.

See also prevpow.

Examples

julia> nextpow(2, 7)
 8
 
 julia> nextpow(2, 9)
@@ -1144,7 +1144,7 @@
 25
 
 julia> nextpow(4, 16)
-16
source
Base.prevpowFunction
prevpow(a, x)

The largest a^n not greater than x, where n is a non-negative integer. a must be greater than 1, and x must not be less than 1.

See also nextpow, isqrt.

Examples

julia> prevpow(2, 7)
+16
source
Base.prevpowFunction
prevpow(a, x)

The largest a^n not greater than x, where n is a non-negative integer. a must be greater than 1, and x must not be less than 1.

See also nextpow, isqrt.

Examples

julia> prevpow(2, 7)
 4
 
 julia> prevpow(2, 9)
@@ -1154,21 +1154,21 @@
 5
 
 julia> prevpow(4, 16)
-16
source
Base.nextprodFunction
nextprod(factors::Union{Tuple,AbstractVector}, n)

Next integer greater than or equal to n that can be written as $\prod k_i^{p_i}$ for integers $p_1$, $p_2$, etcetera, for factors $k_i$ in factors.

Examples

julia> nextprod((2, 3), 105)
+16
source
Base.nextprodFunction
nextprod(factors::Union{Tuple,AbstractVector}, n)

Next integer greater than or equal to n that can be written as $\prod k_i^{p_i}$ for integers $p_1$, $p_2$, etcetera, for factors $k_i$ in factors.

Examples

julia> nextprod((2, 3), 105)
 108
 
 julia> 2^2 * 3^3
-108
Julia 1.6

The method that accepts a tuple requires Julia 1.6 or later.

source
Base.invmodFunction
invmod(n::Integer, m::Integer)

Take the inverse of n modulo m: y such that $n y = 1 \pmod m$, and $div(y,m) = 0$. This will throw an error if $m = 0$, or if $gcd(n,m) \neq 1$.

Examples

julia> invmod(2, 5)
+108
Julia 1.6

The method that accepts a tuple requires Julia 1.6 or later.

source
Base.invmodFunction
invmod(n::Integer, m::Integer)

Take the inverse of n modulo m: y such that $n y = 1 \pmod m$, and $div(y,m) = 0$. This will throw an error if $m = 0$, or if $gcd(n,m) \neq 1$.

Examples

julia> invmod(2, 5)
 3
 
 julia> invmod(2, 3)
 2
 
 julia> invmod(5, 6)
-5
source
invmod(n::Integer, T) where {T <: Base.BitInteger}
+5
source
invmod(n::Integer, T) where {T <: Base.BitInteger}
 invmod(n::T) where {T <: Base.BitInteger}

Compute the modular inverse of n in the integer ring of type T, i.e. modulo 2^N where N = 8*sizeof(T) (e.g. N = 32 for Int32). In other words these methods satisfy the following identities:

n * invmod(n) == 1
 (n * invmod(n, T)) % T == 1
-(n % T) * invmod(n, T) == 1

Note that * here is modular multiplication in the integer ring, T.

Specifying the modulus implied by an integer type as an explicit value is often inconvenient since the modulus is by definition too big to be represented by the type.

The modular inverse is computed much more efficiently than the general case using the algorithm described in https://arxiv.org/pdf/2204.04342.pdf.

Julia 1.11

The invmod(n) and invmod(n, T) methods require Julia 1.11 or later.

source
Base.powermodFunction
powermod(x::Integer, p::Integer, m)

Compute $x^p \pmod m$.

Examples

julia> powermod(2, 6, 5)
+(n % T) * invmod(n, T) == 1

Note that * here is modular multiplication in the integer ring, T.

Specifying the modulus implied by an integer type as an explicit value is often inconvenient since the modulus is by definition too big to be represented by the type.

The modular inverse is computed much more efficiently than the general case using the algorithm described in https://arxiv.org/pdf/2204.04342.pdf.

Julia 1.11

The invmod(n) and invmod(n, T) methods require Julia 1.11 or later.

source
Base.powermodFunction
powermod(x::Integer, p::Integer, m)

Compute $x^p \pmod m$.

Examples

julia> powermod(2, 6, 5)
 4
 
 julia> mod(2^6, 5)
@@ -1181,7 +1181,7 @@
 6
 
 julia> powermod(5, 3, 19)
-11
source
Base.ndigitsFunction
ndigits(n::Integer; base::Integer=10, pad::Integer=1)

Compute the number of digits in integer n written in base base (base must not be in [-1, 0, 1]), optionally padded with zeros to a specified size (the result will never be less than pad).

See also digits, count_ones.

Examples

julia> ndigits(0)
+11
source
Base.ndigitsFunction
ndigits(n::Integer; base::Integer=10, pad::Integer=1)

Compute the number of digits in integer n written in base base (base must not be in [-1, 0, 1]), optionally padded with zeros to a specified size (the result will never be less than pad).

See also digits, count_ones.

Examples

julia> ndigits(0)
 1
 
 julia> ndigits(12345)
@@ -1197,23 +1197,23 @@
 5
 
 julia> ndigits(-123)
-3
source
Base.add_sumFunction
Base.add_sum(x, y)

The reduction operator used in sum. The main difference from + is that small integers are promoted to Int/UInt.

source
Base.widemulFunction
widemul(x, y)

Multiply x and y, giving the result as a larger type.

See also promote, Base.add_sum.

Examples

julia> widemul(Float32(3.0), 4.0) isa BigFloat
+3
source
Base.add_sumFunction
Base.add_sum(x, y)

The reduction operator used in sum. The main difference from + is that small integers are promoted to Int/UInt.

source
Base.widemulFunction
widemul(x, y)

Multiply x and y, giving the result as a larger type.

See also promote, Base.add_sum.

Examples

julia> widemul(Float32(3.0), 4.0) isa BigFloat
 true
 
 julia> typemax(Int8) * typemax(Int8)
 1
 
 julia> widemul(typemax(Int8), typemax(Int8))  # == 127^2
-16129
source
Base.Math.evalpolyFunction
evalpoly(x, p)

Evaluate the polynomial $\sum_k x^{k-1} p[k]$ for the coefficients p[1], p[2], ...; that is, the coefficients are given in ascending order by power of x. Loops are unrolled at compile time if the number of coefficients is statically known, i.e. when p is a Tuple. This function generates efficient code using Horner's method if x is real, or using a Goertzel-like [DK62] algorithm if x is complex.

Julia 1.4

This function requires Julia 1.4 or later.

Examples

julia> evalpoly(2, (1, 2, 3))
-17
source
Base.Math.@evalpolyMacro
@evalpoly(z, c...)

Evaluate the polynomial $\sum_k z^{k-1} c[k]$ for the coefficients c[1], c[2], ...; that is, the coefficients are given in ascending order by power of z. This macro expands to efficient inline code that uses either Horner's method or, for complex z, a more efficient Goertzel-like algorithm.

See also evalpoly.

Examples

julia> @evalpoly(3, 1, 0, 1)
+16129
source
Base.Math.evalpolyFunction
evalpoly(x, p)

Evaluate the polynomial $\sum_k x^{k-1} p[k]$ for the coefficients p[1], p[2], ...; that is, the coefficients are given in ascending order by power of x. Loops are unrolled at compile time if the number of coefficients is statically known, i.e. when p is a Tuple. This function generates efficient code using Horner's method if x is real, or using a Goertzel-like [DK62] algorithm if x is complex.

Julia 1.4

This function requires Julia 1.4 or later.

Examples

julia> evalpoly(2, (1, 2, 3))
+17
source
Base.Math.@evalpolyMacro
@evalpoly(z, c...)

Evaluate the polynomial $\sum_k z^{k-1} c[k]$ for the coefficients c[1], c[2], ...; that is, the coefficients are given in ascending order by power of z. This macro expands to efficient inline code that uses either Horner's method or, for complex z, a more efficient Goertzel-like algorithm.

See also evalpoly.

Examples

julia> @evalpoly(3, 1, 0, 1)
 10
 
 julia> @evalpoly(2, 1, 0, 1)
 5
 
 julia> @evalpoly(2, 1, 1, 1)
-7
source
Base.FastMath.@fastmathMacro
@fastmath expr

Execute a transformed version of the expression, which calls functions that may violate strict IEEE semantics. This allows the fastest possible operation, but results are undefined – be careful when doing this, as it may change numerical results.

This sets the LLVM Fast-Math flags, and corresponds to the -ffast-math option in clang. See the notes on performance annotations for more details.

Examples

julia> @fastmath 1+2
+7
source
Base.FastMath.@fastmathMacro
@fastmath expr

Execute a transformed version of the expression, which calls functions that may violate strict IEEE semantics. This allows the fastest possible operation, but results are undefined – be careful when doing this, as it may change numerical results.

This sets the LLVM Fast-Math flags, and corresponds to the -ffast-math option in clang. See the notes on performance annotations for more details.

Examples

julia> @fastmath 1+2
 3
 
 julia> @fastmath(sin(3))
-0.1411200080598672
source

Customizable binary operators

Some unicode characters can be used to define new binary operators that support infix notation. For example ⊗(x,y) = kron(x,y) defines the (otimes) function to be the Kronecker product, and one can call it as binary operator using infix syntax: C = A ⊗ B as well as with the usual prefix syntax C = ⊗(A,B).

Other characters that support such extensions include \odot and \oplus

The complete list is in the parser code: https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm

Those that are parsed like * (in terms of precedence) include * / ÷ % & ⋅ ∘ × |\\| ∩ ∧ ⊗ ⊘ ⊙ ⊚ ⊛ ⊠ ⊡ ⊓ ∗ ∙ ∤ ⅋ ≀ ⊼ ⋄ ⋆ ⋇ ⋉ ⋊ ⋋ ⋌ ⋏ ⋒ ⟑ ⦸ ⦼ ⦾ ⦿ ⧶ ⧷ ⨇ ⨰ ⨱ ⨲ ⨳ ⨴ ⨵ ⨶ ⨷ ⨸ ⨻ ⨼ ⨽ ⩀ ⩃ ⩄ ⩋ ⩍ ⩎ ⩑ ⩓ ⩕ ⩘ ⩚ ⩜ ⩞ ⩟ ⩠ ⫛ ⊍ ▷ ⨝ ⟕ ⟖ ⟗ and those that are parsed like + include + - |\|| ⊕ ⊖ ⊞ ⊟ |++| ∪ ∨ ⊔ ± ∓ ∔ ∸ ≏ ⊎ ⊻ ⊽ ⋎ ⋓ ⟇ ⧺ ⧻ ⨈ ⨢ ⨣ ⨤ ⨥ ⨦ ⨧ ⨨ ⨩ ⨪ ⨫ ⨬ ⨭ ⨮ ⨹ ⨺ ⩁ ⩂ ⩅ ⩊ ⩌ ⩏ ⩐ ⩒ ⩔ ⩖ ⩗ ⩛ ⩝ ⩡ ⩢ ⩣ There are many others that are related to arrows, comparisons, and powers.

+0.1411200080598672source

Customizable binary operators

Some unicode characters can be used to define new binary operators that support infix notation. For example ⊗(x,y) = kron(x,y) defines the (otimes) function to be the Kronecker product, and one can call it as binary operator using infix syntax: C = A ⊗ B as well as with the usual prefix syntax C = ⊗(A,B).

Other characters that support such extensions include \odot and \oplus

The complete list is in the parser code: https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm

Those that are parsed like * (in terms of precedence) include * / ÷ % & ⋅ ∘ × |\\| ∩ ∧ ⊗ ⊘ ⊙ ⊚ ⊛ ⊠ ⊡ ⊓ ∗ ∙ ∤ ⅋ ≀ ⊼ ⋄ ⋆ ⋇ ⋉ ⋊ ⋋ ⋌ ⋏ ⋒ ⟑ ⦸ ⦼ ⦾ ⦿ ⧶ ⧷ ⨇ ⨰ ⨱ ⨲ ⨳ ⨴ ⨵ ⨶ ⨷ ⨸ ⨻ ⨼ ⨽ ⩀ ⩃ ⩄ ⩋ ⩍ ⩎ ⩑ ⩓ ⩕ ⩘ ⩚ ⩜ ⩞ ⩟ ⩠ ⫛ ⊍ ▷ ⨝ ⟕ ⟖ ⟗ and those that are parsed like + include + - |\|| ⊕ ⊖ ⊞ ⊟ |++| ∪ ∨ ⊔ ± ∓ ∔ ∸ ≏ ⊎ ⊻ ⊽ ⋎ ⋓ ⟇ ⧺ ⧻ ⨈ ⨢ ⨣ ⨤ ⨥ ⨦ ⨧ ⨨ ⨩ ⨪ ⨫ ⨬ ⨭ ⨮ ⨹ ⨺ ⩁ ⩂ ⩅ ⩊ ⩌ ⩏ ⩐ ⩒ ⩔ ⩖ ⩗ ⩛ ⩝ ⩡ ⩢ ⩣ There are many others that are related to arrows, comparisons, and powers.

diff --git a/en/v1.12-dev/base/multi-threading/index.html b/en/v1.12-dev/base/multi-threading/index.html index 8188c57914ac..e18446163a35 100644 --- a/en/v1.12-dev/base/multi-threading/index.html +++ b/en/v1.12-dev/base/multi-threading/index.html @@ -23,7 +23,7 @@ busywait(1) end end -2.012056 seconds (16.05 k allocations: 883.919 KiB, 0.66% compilation time)

The :dynamic example takes 2 seconds since one of the non-occupied threads is able to run two of the 1-second iterations to complete the for loop.

source
Base.Threads.foreachFunction
Threads.foreach(f, channel::Channel;
+2.012056 seconds (16.05 k allocations: 883.919 KiB, 0.66% compilation time)

The :dynamic example takes 2 seconds since one of the non-occupied threads is able to run two of the 1-second iterations to complete the for loop.

source
Base.Threads.foreachFunction
Threads.foreach(f, channel::Channel;
                 schedule::Threads.AbstractSchedule=Threads.FairSchedule(),
                 ntasks=Threads.threadpoolsize())

Similar to foreach(f, channel), but iteration over channel and calls to f are split across ntasks tasks spawned by Threads.@spawn. This function will wait for all internally spawned tasks to complete before returning.

If schedule isa FairSchedule, Threads.foreach will attempt to spawn tasks in a manner that enables Julia's scheduler to more freely load-balance work items across threads. This approach generally has higher per-item overhead, but may perform better than StaticSchedule in concurrence with other multithreaded workloads.

If schedule isa StaticSchedule, Threads.foreach will spawn tasks in a manner that incurs lower per-item overhead than FairSchedule, but is less amenable to load-balancing. This approach thus may be more suitable for fine-grained, uniform workloads, but may perform worse than FairSchedule in concurrence with other multithreaded workloads.

Examples

julia> n = 20
 
@@ -35,13 +35,13 @@
        end
 
 julia> collect(d)
-collect(d) = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400]
Julia 1.6

This function requires Julia 1.6 or later.

source
Base.Threads.@spawnMacro
Threads.@spawn [:default|:interactive] expr

Create a Task and schedule it to run on any available thread in the specified threadpool (:default if unspecified). The task is allocated to a thread once one becomes available. To wait for the task to finish, call wait on the result of this macro, or call fetch to wait and then obtain its return value.

Values can be interpolated into @spawn via $, which copies the value directly into the constructed underlying closure. This allows you to insert the value of a variable, isolating the asynchronous code from changes to the variable's value in the current task.

Note

The thread that the task runs on may change if the task yields, therefore threadid() should not be treated as constant for a task. See Task Migration, and the broader multi-threading manual for further important caveats. See also the chapter on threadpools.

Julia 1.3

This macro is available as of Julia 1.3.

Julia 1.4

Interpolating values via $ is available as of Julia 1.4.

Julia 1.9

A threadpool may be specified as of Julia 1.9.

Examples

julia> t() = println("Hello from ", Threads.threadid());
+collect(d) = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400]
Julia 1.6

This function requires Julia 1.6 or later.

source
Base.Threads.@spawnMacro
Threads.@spawn [:default|:interactive] expr

Create a Task and schedule it to run on any available thread in the specified threadpool (:default if unspecified). The task is allocated to a thread once one becomes available. To wait for the task to finish, call wait on the result of this macro, or call fetch to wait and then obtain its return value.

Values can be interpolated into @spawn via $, which copies the value directly into the constructed underlying closure. This allows you to insert the value of a variable, isolating the asynchronous code from changes to the variable's value in the current task.

Note

The thread that the task runs on may change if the task yields, therefore threadid() should not be treated as constant for a task. See Task Migration, and the broader multi-threading manual for further important caveats. See also the chapter on threadpools.

Julia 1.3

This macro is available as of Julia 1.3.

Julia 1.4

Interpolating values via $ is available as of Julia 1.4.

Julia 1.9

A threadpool may be specified as of Julia 1.9.

Examples

julia> t() = println("Hello from ", Threads.threadid());
 
 julia> tasks = fetch.([Threads.@spawn t() for i in 1:4]);
 Hello from 1
 Hello from 1
 Hello from 3
-Hello from 4
source
Base.Threads.threadidFunction
Threads.threadid() -> Int

Get the ID number of the current thread of execution. The master thread has ID 1.

Examples

julia> Threads.threadid()
+Hello from 4
source
Base.Threads.threadidFunction
Threads.threadid() -> Int

Get the ID number of the current thread of execution. The master thread has ID 1.

Examples

julia> Threads.threadid()
 1
 
 julia> Threads.@threads for i in 1:4
@@ -50,7 +50,7 @@
 4
 2
 5
-4
Note

The thread that a task runs on may change if the task yields, which is known as Task Migration. For this reason in most cases it is not safe to use threadid() to index into, say, a vector of buffer or stateful objects.

source
Base.Threads.maxthreadidFunction
Threads.maxthreadid() -> Int

Get a lower bound on the number of threads (across all thread pools) available to the Julia process, with atomic-acquire semantics. The result will always be greater than or equal to threadid() as well as threadid(task) for any task you were able to observe before calling maxthreadid.

source
Base.Threads.nthreadsFunction
Threads.nthreads(:default | :interactive) -> Int

Get the current number of threads within the specified thread pool. The threads in :interactive have id numbers 1:nthreads(:interactive), and the threads in :default have id numbers in nthreads(:interactive) .+ (1:nthreads(:default)).

See also BLAS.get_num_threads and BLAS.set_num_threads in the LinearAlgebra standard library, and nprocs() in the Distributed standard library and Threads.maxthreadid().

source
Base.Threads.threadpoolFunction
Threads.threadpool(tid = threadid()) -> Symbol

Returns the specified thread's threadpool; either :default, :interactive, or :foreign.

source
Base.Threads.nthreadpoolsFunction
Threads.nthreadpools() -> Int

Returns the number of threadpools currently configured.

source
Base.Threads.threadpoolsizeFunction
Threads.threadpoolsize(pool::Symbol = :default) -> Int

Get the number of threads available to the default thread pool (or to the specified thread pool).

See also: BLAS.get_num_threads and BLAS.set_num_threads in the LinearAlgebra standard library, and nprocs() in the Distributed standard library.

source
Base.Threads.ngcthreadsFunction
Threads.ngcthreads() -> Int

Returns the number of GC threads currently configured. This includes both mark threads and concurrent sweep threads.

source

See also Multi-Threading.

Atomic operations

atomicKeyword

Unsafe pointer operations are compatible with loading and storing pointers declared with _Atomic and std::atomic type in C11 and C++23 respectively. An error may be thrown if there is not support for atomically loading the Julia type T.

See also: unsafe_load, unsafe_modify!, unsafe_replace!, unsafe_store!, unsafe_swap!

source
Base.@atomicMacro
@atomic var
+4
Note

The thread that a task runs on may change if the task yields, which is known as Task Migration. For this reason in most cases it is not safe to use threadid() to index into, say, a vector of buffer or stateful objects.

source
Base.Threads.maxthreadidFunction
Threads.maxthreadid() -> Int

Get a lower bound on the number of threads (across all thread pools) available to the Julia process, with atomic-acquire semantics. The result will always be greater than or equal to threadid() as well as threadid(task) for any task you were able to observe before calling maxthreadid.

source
Base.Threads.nthreadsFunction
Threads.nthreads(:default | :interactive) -> Int

Get the current number of threads within the specified thread pool. The threads in :interactive have id numbers 1:nthreads(:interactive), and the threads in :default have id numbers in nthreads(:interactive) .+ (1:nthreads(:default)).

See also BLAS.get_num_threads and BLAS.set_num_threads in the LinearAlgebra standard library, and nprocs() in the Distributed standard library and Threads.maxthreadid().

source
Base.Threads.threadpoolFunction
Threads.threadpool(tid = threadid()) -> Symbol

Returns the specified thread's threadpool; either :default, :interactive, or :foreign.

source
Base.Threads.nthreadpoolsFunction
Threads.nthreadpools() -> Int

Returns the number of threadpools currently configured.

source
Base.Threads.threadpoolsizeFunction
Threads.threadpoolsize(pool::Symbol = :default) -> Int

Get the number of threads available to the default thread pool (or to the specified thread pool).

See also: BLAS.get_num_threads and BLAS.set_num_threads in the LinearAlgebra standard library, and nprocs() in the Distributed standard library.

source
Base.Threads.ngcthreadsFunction
Threads.ngcthreads() -> Int

Returns the number of GC threads currently configured. This includes both mark threads and concurrent sweep threads.

source

See also Multi-Threading.

Atomic operations

atomicKeyword

Unsafe pointer operations are compatible with loading and storing pointers declared with _Atomic and std::atomic type in C11 and C++23 respectively. An error may be thrown if there is not support for atomically loading the Julia type T.

See also: unsafe_load, unsafe_modify!, unsafe_replace!, unsafe_store!, unsafe_swap!

source
Base.@atomicMacro
@atomic var
 @atomic order ex

Mark var or ex as being performed atomically, if ex is a supported expression. If no order is specified it defaults to :sequentially_consistent.

@atomic a.b.x = new
 @atomic a.b.x += addend
 @atomic :release a.b.x = new
@@ -83,7 +83,7 @@
 4 => 10
 
 julia> @atomic a.x max 5 # again change field x of a to the max value, with sequential consistency
-10 => 10
Julia 1.7

This functionality requires at least Julia 1.7.

source
Base.@atomicswapMacro
@atomicswap a.b.x = new
+10 => 10
Julia 1.7

This functionality requires at least Julia 1.7.

source
Base.@atomicswapMacro
@atomicswap a.b.x = new
 @atomicswap :sequentially_consistent a.b.x = new

Stores new into a.b.x and returns the old value of a.b.x.

This operation translates to a swapproperty!(a.b, :x, new) call.

See Per-field atomics section in the manual for more details.

Examples

julia> mutable struct Atomic{T}; @atomic x::T; end
 
 julia> a = Atomic(1)
@@ -93,7 +93,7 @@
 1
 
 julia> @atomic a.x # fetch field x of a, with sequential consistency
-4
Julia 1.7

This functionality requires at least Julia 1.7.

source
Base.@atomicreplaceMacro
@atomicreplace a.b.x expected => desired
+4
Julia 1.7

This functionality requires at least Julia 1.7.

source
Base.@atomicreplaceMacro
@atomicreplace a.b.x expected => desired
 @atomicreplace :sequentially_consistent a.b.x expected => desired
 @atomicreplace :sequentially_consistent :monotonic a.b.x expected => desired

Perform the conditional replacement expressed by the pair atomically, returning the values (old, success::Bool). Where success indicates whether the replacement was completed.

This operation translates to a replaceproperty!(a.b, :x, expected, desired) call.

See Per-field atomics section in the manual for more details.

Examples

julia> mutable struct Atomic{T}; @atomic x::T; end
 
@@ -115,7 +115,7 @@
 (old = 2, success = true)
 
 julia> @atomic a.x # fetch field x of a, with sequential consistency
-0
Julia 1.7

This functionality requires at least Julia 1.7.

source
Base.@atomiconceMacro
@atomiconce a.b.x = value
+0
Julia 1.7

This functionality requires at least Julia 1.7.

source
Base.@atomiconceMacro
@atomiconce a.b.x = value
 @atomiconce :sequentially_consistent a.b.x = value
 @atomiconce :sequentially_consistent :monotonic a.b.x = value

Perform the conditional assignment of value atomically if it was previously unset, returning the value success::Bool. Where success indicates whether the assignment was completed.

This operation translates to a setpropertyonce!(a.b, :x, value) call.

See Per-field atomics section in the manual for more details.

Examples

julia> mutable struct AtomicOnce
            @atomic x
@@ -132,14 +132,14 @@
 1
 
 julia> @atomiconce a.x = 1 # set field x of a to 1, if unset, with sequential consistency
-false
Julia 1.11

This functionality requires at least Julia 1.11.

source
Core.AtomicMemoryType
AtomicMemory{T} == GenericMemory{:atomic, T, Core.CPU}

One-dimensional dense array with elements of type T, where each element is independently atomic when accessed, and cannot be set non-atomically.

Julia 1.11

This type requires Julia 1.11 or later.

source

There are also optional memory ordering parameters for the unsafe set of functions, that select the C/C++-compatible versions of these atomic operations, if that parameter is specified to unsafe_load, unsafe_store!, unsafe_swap!, unsafe_replace!, and unsafe_modify!.

Warning

The following APIs are deprecated, though support for them is likely to remain for several releases.

Base.Threads.AtomicType
Threads.Atomic{T}

Holds a reference to an object of type T, ensuring that it is only accessed atomically, i.e. in a thread-safe manner.

Only certain "simple" types can be used atomically, namely the primitive boolean, integer, and float-point types. These are Bool, Int8...Int128, UInt8...UInt128, and Float16...Float64.

New atomic objects can be created from a non-atomic values; if none is specified, the atomic object is initialized with zero.

Atomic objects can be accessed using the [] notation:

Examples

julia> x = Threads.Atomic{Int}(3)
+false
Julia 1.11

This functionality requires at least Julia 1.11.

source
Core.AtomicMemoryType
AtomicMemory{T} == GenericMemory{:atomic, T, Core.CPU}

One-dimensional dense array with elements of type T, where each element is independently atomic when accessed, and cannot be set non-atomically.

Julia 1.11

This type requires Julia 1.11 or later.

source

There are also optional memory ordering parameters for the unsafe set of functions, that select the C/C++-compatible versions of these atomic operations, if that parameter is specified to unsafe_load, unsafe_store!, unsafe_swap!, unsafe_replace!, and unsafe_modify!.

Warning

The following APIs are deprecated, though support for them is likely to remain for several releases.

Base.Threads.AtomicType
Threads.Atomic{T}

Holds a reference to an object of type T, ensuring that it is only accessed atomically, i.e. in a thread-safe manner.

Only certain "simple" types can be used atomically, namely the primitive boolean, integer, and float-point types. These are Bool, Int8...Int128, UInt8...UInt128, and Float16...Float64.

New atomic objects can be created from a non-atomic values; if none is specified, the atomic object is initialized with zero.

Atomic objects can be accessed using the [] notation:

Examples

julia> x = Threads.Atomic{Int}(3)
 Base.Threads.Atomic{Int64}(3)
 
 julia> x[] = 1
 1
 
 julia> x[]
-1

Atomic operations use an atomic_ prefix, such as atomic_add!, atomic_xchg!, etc.

source
Base.Threads.atomic_cas!Function
Threads.atomic_cas!(x::Atomic{T}, cmp::T, newval::T) where T

Atomically compare-and-set x

Atomically compares the value in x with cmp. If equal, write newval to x. Otherwise, leaves x unmodified. Returns the old value in x. By comparing the returned value to cmp (via ===) one knows whether x was modified and now holds the new value newval.

For further details, see LLVM's cmpxchg instruction.

This function can be used to implement transactional semantics. Before the transaction, one records the value in x. After the transaction, the new value is stored only if x has not been modified in the mean time.

Examples

julia> x = Threads.Atomic{Int}(3)
+1

Atomic operations use an atomic_ prefix, such as atomic_add!, atomic_xchg!, etc.

source
Base.Threads.atomic_cas!Function
Threads.atomic_cas!(x::Atomic{T}, cmp::T, newval::T) where T

Atomically compare-and-set x

Atomically compares the value in x with cmp. If equal, write newval to x. Otherwise, leaves x unmodified. Returns the old value in x. By comparing the returned value to cmp (via ===) one knows whether x was modified and now holds the new value newval.

For further details, see LLVM's cmpxchg instruction.

This function can be used to implement transactional semantics. Before the transaction, one records the value in x. After the transaction, the new value is stored only if x has not been modified in the mean time.

Examples

julia> x = Threads.Atomic{Int}(3)
 Base.Threads.Atomic{Int64}(3)
 
 julia> Threads.atomic_cas!(x, 4, 2);
@@ -150,67 +150,67 @@
 julia> Threads.atomic_cas!(x, 3, 2);
 
 julia> x
-Base.Threads.Atomic{Int64}(2)
source
Base.Threads.atomic_xchg!Function
Threads.atomic_xchg!(x::Atomic{T}, newval::T) where T

Atomically exchange the value in x

Atomically exchanges the value in x with newval. Returns the old value.

For further details, see LLVM's atomicrmw xchg instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
+Base.Threads.Atomic{Int64}(2)
source
Base.Threads.atomic_xchg!Function
Threads.atomic_xchg!(x::Atomic{T}, newval::T) where T

Atomically exchange the value in x

Atomically exchanges the value in x with newval. Returns the old value.

For further details, see LLVM's atomicrmw xchg instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
 Base.Threads.Atomic{Int64}(3)
 
 julia> Threads.atomic_xchg!(x, 2)
 3
 
 julia> x[]
-2
source
Base.Threads.atomic_add!Function
Threads.atomic_add!(x::Atomic{T}, val::T) where T <: ArithmeticTypes

Atomically add val to x

Performs x[] += val atomically. Returns the old value. Not defined for Atomic{Bool}.

For further details, see LLVM's atomicrmw add instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
+2
source
Base.Threads.atomic_add!Function
Threads.atomic_add!(x::Atomic{T}, val::T) where T <: ArithmeticTypes

Atomically add val to x

Performs x[] += val atomically. Returns the old value. Not defined for Atomic{Bool}.

For further details, see LLVM's atomicrmw add instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
 Base.Threads.Atomic{Int64}(3)
 
 julia> Threads.atomic_add!(x, 2)
 3
 
 julia> x[]
-5
source
Base.Threads.atomic_sub!Function
Threads.atomic_sub!(x::Atomic{T}, val::T) where T <: ArithmeticTypes

Atomically subtract val from x

Performs x[] -= val atomically. Returns the old value. Not defined for Atomic{Bool}.

For further details, see LLVM's atomicrmw sub instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
+5
source
Base.Threads.atomic_sub!Function
Threads.atomic_sub!(x::Atomic{T}, val::T) where T <: ArithmeticTypes

Atomically subtract val from x

Performs x[] -= val atomically. Returns the old value. Not defined for Atomic{Bool}.

For further details, see LLVM's atomicrmw sub instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
 Base.Threads.Atomic{Int64}(3)
 
 julia> Threads.atomic_sub!(x, 2)
 3
 
 julia> x[]
-1
source
Base.Threads.atomic_and!Function
Threads.atomic_and!(x::Atomic{T}, val::T) where T

Atomically bitwise-and x with val

Performs x[] &= val atomically. Returns the old value.

For further details, see LLVM's atomicrmw and instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
+1
source
Base.Threads.atomic_and!Function
Threads.atomic_and!(x::Atomic{T}, val::T) where T

Atomically bitwise-and x with val

Performs x[] &= val atomically. Returns the old value.

For further details, see LLVM's atomicrmw and instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
 Base.Threads.Atomic{Int64}(3)
 
 julia> Threads.atomic_and!(x, 2)
 3
 
 julia> x[]
-2
source
Base.Threads.atomic_nand!Function
Threads.atomic_nand!(x::Atomic{T}, val::T) where T

Atomically bitwise-nand (not-and) x with val

Performs x[] = ~(x[] & val) atomically. Returns the old value.

For further details, see LLVM's atomicrmw nand instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
+2
source
Base.Threads.atomic_nand!Function
Threads.atomic_nand!(x::Atomic{T}, val::T) where T

Atomically bitwise-nand (not-and) x with val

Performs x[] = ~(x[] & val) atomically. Returns the old value.

For further details, see LLVM's atomicrmw nand instruction.

Examples

julia> x = Threads.Atomic{Int}(3)
 Base.Threads.Atomic{Int64}(3)
 
 julia> Threads.atomic_nand!(x, 2)
 3
 
 julia> x[]
--3
source
Base.Threads.atomic_or!Function
Threads.atomic_or!(x::Atomic{T}, val::T) where T

Atomically bitwise-or x with val

Performs x[] |= val atomically. Returns the old value.

For further details, see LLVM's atomicrmw or instruction.

Examples

julia> x = Threads.Atomic{Int}(5)
+-3
source
Base.Threads.atomic_or!Function
Threads.atomic_or!(x::Atomic{T}, val::T) where T

Atomically bitwise-or x with val

Performs x[] |= val atomically. Returns the old value.

For further details, see LLVM's atomicrmw or instruction.

Examples

julia> x = Threads.Atomic{Int}(5)
 Base.Threads.Atomic{Int64}(5)
 
 julia> Threads.atomic_or!(x, 7)
 5
 
 julia> x[]
-7
source
Base.Threads.atomic_xor!Function
Threads.atomic_xor!(x::Atomic{T}, val::T) where T

Atomically bitwise-xor (exclusive-or) x with val

Performs x[] $= val atomically. Returns the old value.

For further details, see LLVM's atomicrmw xor instruction.

Examples

julia> x = Threads.Atomic{Int}(5)
+7
source
Base.Threads.atomic_xor!Function
Threads.atomic_xor!(x::Atomic{T}, val::T) where T

Atomically bitwise-xor (exclusive-or) x with val

Performs x[] $= val atomically. Returns the old value.

For further details, see LLVM's atomicrmw xor instruction.

Examples

julia> x = Threads.Atomic{Int}(5)
 Base.Threads.Atomic{Int64}(5)
 
 julia> Threads.atomic_xor!(x, 7)
 5
 
 julia> x[]
-2
source
Base.Threads.atomic_max!Function
Threads.atomic_max!(x::Atomic{T}, val::T) where T

Atomically store the maximum of x and val in x

Performs x[] = max(x[], val) atomically. Returns the old value.

For further details, see LLVM's atomicrmw max instruction.

Examples

julia> x = Threads.Atomic{Int}(5)
+2
source
Base.Threads.atomic_max!Function
Threads.atomic_max!(x::Atomic{T}, val::T) where T

Atomically store the maximum of x and val in x

Performs x[] = max(x[], val) atomically. Returns the old value.

For further details, see LLVM's atomicrmw max instruction.

Examples

julia> x = Threads.Atomic{Int}(5)
 Base.Threads.Atomic{Int64}(5)
 
 julia> Threads.atomic_max!(x, 7)
 5
 
 julia> x[]
-7
source
Base.Threads.atomic_min!Function
Threads.atomic_min!(x::Atomic{T}, val::T) where T

Atomically store the minimum of x and val in x

Performs x[] = min(x[], val) atomically. Returns the old value.

For further details, see LLVM's atomicrmw min instruction.

Examples

julia> x = Threads.Atomic{Int}(7)
+7
source
Base.Threads.atomic_min!Function
Threads.atomic_min!(x::Atomic{T}, val::T) where T

Atomically store the minimum of x and val in x

Performs x[] = min(x[], val) atomically. Returns the old value.

For further details, see LLVM's atomicrmw min instruction.

Examples

julia> x = Threads.Atomic{Int}(7)
 Base.Threads.Atomic{Int64}(7)
 
 julia> Threads.atomic_min!(x, 5)
 7
 
 julia> x[]
-5
source
Base.Threads.atomic_fenceFunction
Threads.atomic_fence()

Insert a sequential-consistency memory fence

Inserts a memory fence with sequentially-consistent ordering semantics. There are algorithms where this is needed, i.e. where an acquire/release ordering is insufficient.

This is likely a very expensive operation. Given that all other atomic operations in Julia already have acquire/release semantics, explicit fences should not be necessary in most cases.

For further details, see LLVM's fence instruction.

source

ccall using a libuv threadpool (Experimental)

Base.@threadcallMacro
@threadcall((cfunc, clib), rettype, (argtypes...), argvals...)

The @threadcall macro is called in the same way as ccall but does the work in a different thread. This is useful when you want to call a blocking C function without causing the current julia thread to become blocked. Concurrency is limited by size of the libuv thread pool, which defaults to 4 threads but can be increased by setting the UV_THREADPOOL_SIZE environment variable and restarting the julia process.

Note that the called function should never call back into Julia.

source

Low-level synchronization primitives

These building blocks are used to create the regular synchronization objects.

Base.Threads.SpinLockType
SpinLock()

Create a non-reentrant, test-and-test-and-set spin lock. Recursive use will result in a deadlock. This kind of lock should only be used around code that takes little time to execute and does not block (e.g. perform I/O). In general, ReentrantLock should be used instead.

Each lock must be matched with an unlock. If !islocked(lck::SpinLock) holds, trylock(lck) succeeds unless there are other tasks attempting to hold the lock "at the same time."

Test-and-test-and-set spin locks are quickest up to about 30ish contending threads. If you have more contention than that, different synchronization approaches should be considered.

source
+5source
Base.Threads.atomic_fenceFunction
Threads.atomic_fence()

Insert a sequential-consistency memory fence

Inserts a memory fence with sequentially-consistent ordering semantics. There are algorithms where this is needed, i.e. where an acquire/release ordering is insufficient.

This is likely a very expensive operation. Given that all other atomic operations in Julia already have acquire/release semantics, explicit fences should not be necessary in most cases.

For further details, see LLVM's fence instruction.

source

ccall using a libuv threadpool (Experimental)

Base.@threadcallMacro
@threadcall((cfunc, clib), rettype, (argtypes...), argvals...)

The @threadcall macro is called in the same way as ccall but does the work in a different thread. This is useful when you want to call a blocking C function without causing the current julia thread to become blocked. Concurrency is limited by size of the libuv thread pool, which defaults to 4 threads but can be increased by setting the UV_THREADPOOL_SIZE environment variable and restarting the julia process.

Note that the called function should never call back into Julia.

source

Low-level synchronization primitives

These building blocks are used to create the regular synchronization objects.

Base.Threads.SpinLockType
SpinLock()

Create a non-reentrant, test-and-test-and-set spin lock. Recursive use will result in a deadlock. This kind of lock should only be used around code that takes little time to execute and does not block (e.g. perform I/O). In general, ReentrantLock should be used instead.

Each lock must be matched with an unlock. If !islocked(lck::SpinLock) holds, trylock(lck) succeeds unless there are other tasks attempting to hold the lock "at the same time."

Test-and-test-and-set spin locks are quickest up to about 30ish contending threads. If you have more contention than that, different synchronization approaches should be considered.

source
diff --git a/en/v1.12-dev/base/numbers/index.html b/en/v1.12-dev/base/numbers/index.html index 4e4a7b91843c..c9a0a454bc2c 100644 --- a/en/v1.12-dev/base/numbers/index.html +++ b/en/v1.12-dev/base/numbers/index.html @@ -28,21 +28,21 @@ │ └─ UInt128 ├─ Rational └─ AbstractIrrational (Abstract Type) - └─ Irrational

Abstract number types

Core.NumberType
Number

Abstract supertype for all number types.

source
Core.RealType
Real <: Number

Abstract supertype for all real numbers.

source
Core.AbstractFloatType
AbstractFloat <: Real

Abstract supertype for all floating point numbers.

source
Core.IntegerType
Integer <: Real

Abstract supertype for all integers (e.g. Signed, Unsigned, and Bool).

See also isinteger, trunc, div.

Examples

julia> 42 isa Integer
+      └─ Irrational

Abstract number types

Core.RealType
Real <: Number

Abstract supertype for all real numbers.

source
Core.SignedType
Signed <: Integer

Abstract supertype for all signed integers.

source
Core.UnsignedType
Unsigned <: Integer

Abstract supertype for all unsigned integers.

Built-in unsigned integers are printed in hexadecimal, with prefix 0x, and can be entered in the same way.

Examples

julia> typemax(UInt8)
+true
source
Core.SignedType
Signed <: Integer

Abstract supertype for all signed integers.

source
Core.UnsignedType
Unsigned <: Integer

Abstract supertype for all unsigned integers.

Built-in unsigned integers are printed in hexadecimal, with prefix 0x, and can be entered in the same way.

Examples

julia> typemax(UInt8)
 0xff
 
 julia> Int(0x00d)
 13
 
 julia> unsigned(true)
-0x0000000000000001
source
Base.AbstractIrrationalType
AbstractIrrational <: Real

Number type representing an exact irrational value, which is automatically rounded to the correct precision in arithmetic operations with other numeric quantities.

Subtypes MyIrrational <: AbstractIrrational should implement at least ==(::MyIrrational, ::MyIrrational), hash(x::MyIrrational, h::UInt), and convert(::Type{F}, x::MyIrrational) where {F <: Union{BigFloat,Float32,Float64}}.

If a subtype is used to represent values that may occasionally be rational (e.g. a square-root type that represents √n for integers n will give a rational result when n is a perfect square), then it should also implement isinteger, iszero, isone, and == with Real values (since all of these default to false for AbstractIrrational types), as well as defining hash to equal that of the corresponding Rational.

source

Concrete number types

Core.Float16Type
Float16 <: AbstractFloat <: Real

16-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 5 exponent, 10 fraction bits.

source
Core.Float32Type
Float32 <: AbstractFloat <: Real

32-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 8 exponent, 23 fraction bits.

The exponent for scientific notation should be entered as lower-case f, thus 2f3 === 2.0f0 * 10^3 === Float32(2_000). For array literals and comprehensions, the element type can be specified before the square brackets: Float32[1,4,9] == Float32[i^2 for i in 1:3].

See also Inf32, NaN32, Float16, exponent, frexp.

source
Core.Float64Type
Float64 <: AbstractFloat <: Real

64-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 11 exponent, 52 fraction bits. See bitstring, signbit, exponent, frexp, and significand to access various bits.

This is the default for floating point literals, 1.0 isa Float64, and for many operations such as 1/2, 2pi, log(2), range(0,90,length=4). Unlike integers, this default does not change with Sys.WORD_SIZE.

The exponent for scientific notation can be entered as e or E, thus 2e3 === 2.0E3 === 2.0 * 10^3. Doing so is strongly preferred over 10^n because integers overflow, thus 2.0 * 10^19 < 0 but 2e19 > 0.

See also Inf, NaN, floatmax, Float32, Complex.

source
Core.BoolType
Bool <: Integer

Boolean type, containing the values true and false.

Bool is a kind of number: false is numerically equal to 0 and true is numerically equal to 1. Moreover, false acts as a multiplicative "strong zero" against NaN and Inf:

julia> [true, false] == [1, 0]
+0x0000000000000001
source
Base.AbstractIrrationalType
AbstractIrrational <: Real

Number type representing an exact irrational value, which is automatically rounded to the correct precision in arithmetic operations with other numeric quantities.

Subtypes MyIrrational <: AbstractIrrational should implement at least ==(::MyIrrational, ::MyIrrational), hash(x::MyIrrational, h::UInt), and convert(::Type{F}, x::MyIrrational) where {F <: Union{BigFloat,Float32,Float64}}.

If a subtype is used to represent values that may occasionally be rational (e.g. a square-root type that represents √n for integers n will give a rational result when n is a perfect square), then it should also implement isinteger, iszero, isone, and == with Real values (since all of these default to false for AbstractIrrational types), as well as defining hash to equal that of the corresponding Rational.

source

Concrete number types

Core.Float16Type
Float16 <: AbstractFloat <: Real

16-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 5 exponent, 10 fraction bits.

source
Core.Float32Type
Float32 <: AbstractFloat <: Real

32-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 8 exponent, 23 fraction bits.

The exponent for scientific notation should be entered as lower-case f, thus 2f3 === 2.0f0 * 10^3 === Float32(2_000). For array literals and comprehensions, the element type can be specified before the square brackets: Float32[1,4,9] == Float32[i^2 for i in 1:3].

See also Inf32, NaN32, Float16, exponent, frexp.

source
Core.Float64Type
Float64 <: AbstractFloat <: Real

64-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 11 exponent, 52 fraction bits. See bitstring, signbit, exponent, frexp, and significand to access various bits.

This is the default for floating point literals, 1.0 isa Float64, and for many operations such as 1/2, 2pi, log(2), range(0,90,length=4). Unlike integers, this default does not change with Sys.WORD_SIZE.

The exponent for scientific notation can be entered as e or E, thus 2e3 === 2.0E3 === 2.0 * 10^3. Doing so is strongly preferred over 10^n because integers overflow, thus 2.0 * 10^19 < 0 but 2e19 > 0.

See also Inf, NaN, floatmax, Float32, Complex.

source
Core.BoolType
Bool <: Integer

Boolean type, containing the values true and false.

Bool is a kind of number: false is numerically equal to 0 and true is numerically equal to 1. Moreover, false acts as a multiplicative "strong zero" against NaN and Inf:

julia> [true, false] == [1, 0]
 true
 
 julia> 42.0 + true
@@ -58,7 +58,7 @@
 
 julia> map(>(pi), [1 2 3 4 5])
 1×5 Matrix{Bool}:
- 0  0  0  1  1

See also trues, falses, ifelse.

source
Core.Int8Type
Int8 <: Signed <: Integer

8-bit signed integer type.

Represents numbers n ∈ -128:127. Note that such integers overflow without warning, thus typemax(Int8) + Int8(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt8Type
UInt8 <: Unsigned <: Integer

8-bit unsigned integer type.

Printed in hexadecimal, thus 0x07 == 7.

source
Core.Int16Type
Int16 <: Signed <: Integer

16-bit signed integer type.

Represents numbers n ∈ -32768:32767. Note that such integers overflow without warning, thus typemax(Int16) + Int16(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt16Type
UInt16 <: Unsigned <: Integer

16-bit unsigned integer type.

Printed in hexadecimal, thus 0x000f == 15.

source
Core.Int32Type
Int32 <: Signed <: Integer

32-bit signed integer type.

Note that such integers overflow without warning, thus typemax(Int32) + Int32(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt32Type
UInt32 <: Unsigned <: Integer

32-bit unsigned integer type.

Printed in hexadecimal, thus 0x0000001f == 31.

source
Core.Int64Type
Int64 <: Signed <: Integer

64-bit signed integer type.

Note that such integers overflow without warning, thus typemax(Int64) + Int64(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt64Type
UInt64 <: Unsigned <: Integer

64-bit unsigned integer type.

Printed in hexadecimal, thus 0x000000000000003f == 63.

source
Core.Int128Type
Int128 <: Signed <: Integer

128-bit signed integer type.

Note that such integers overflow without warning, thus typemax(Int128) + Int128(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt128Type
UInt128 <: Unsigned <: Integer

128-bit unsigned integer type.

Printed in hexadecimal, thus 0x0000000000000000000000000000007f == 127.

source
Core.IntType
Int

Sys.WORD_SIZE-bit signed integer type, Int <: Signed <: Integer <: Real.

This is the default type of most integer literals and is an alias for either Int32 or Int64, depending on Sys.WORD_SIZE. It is the type returned by functions such as length, and the standard type for indexing arrays.

Note that integers overflow without warning, thus typemax(Int) + 1 < 0 and 10^19 < 0. Overflow can be avoided by using BigInt. Very large integer literals will use a wider type, for instance 10_000_000_000_000_000_000 isa Int128.

Integer division is div alias ÷, whereas / acting on integers returns Float64.

See also Int64, widen, typemax, bitstring.

source
Core.UIntType
UInt

Sys.WORD_SIZE-bit unsigned integer type, UInt <: Unsigned <: Integer.

Like Int, the alias UInt may point to either UInt32 or UInt64, according to the value of Sys.WORD_SIZE on a given computer.

Printed and parsed in hexadecimal: UInt(15) === 0x000000000000000f.

source
Base.ComplexType
Complex{T<:Real} <: Number

Complex number type with real and imaginary part of type T.

ComplexF16, ComplexF32 and ComplexF64 are aliases for Complex{Float16}, Complex{Float32} and Complex{Float64} respectively.

See also: Real, complex, real.

source
Base.RationalType
Rational{T<:Integer} <: Real

Rational number type, with numerator and denominator of type T. Rationals are checked for overflow.

source

Data Formats

Base.digitsFunction
digits([T<:Integer], n::Integer; base::T = 10, pad::Integer = 1)

Return an array with element type T (default Int) of the digits of n in the given base, optionally padded with zeros to a specified size. More significant digits are at higher indices, such that n == sum(digits[k]*base^(k-1) for k=1:length(digits)).

See also ndigits, digits!, and for base 2 also bitstring, count_ones.

Examples

julia> digits(10)
+ 0  0  0  1  1

See also trues, falses, ifelse.

source
Core.Int8Type
Int8 <: Signed <: Integer

8-bit signed integer type.

Represents numbers n ∈ -128:127. Note that such integers overflow without warning, thus typemax(Int8) + Int8(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt8Type
UInt8 <: Unsigned <: Integer

8-bit unsigned integer type.

Printed in hexadecimal, thus 0x07 == 7.

source
Core.Int16Type
Int16 <: Signed <: Integer

16-bit signed integer type.

Represents numbers n ∈ -32768:32767. Note that such integers overflow without warning, thus typemax(Int16) + Int16(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt16Type
UInt16 <: Unsigned <: Integer

16-bit unsigned integer type.

Printed in hexadecimal, thus 0x000f == 15.

source
Core.Int32Type
Int32 <: Signed <: Integer

32-bit signed integer type.

Note that such integers overflow without warning, thus typemax(Int32) + Int32(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt32Type
UInt32 <: Unsigned <: Integer

32-bit unsigned integer type.

Printed in hexadecimal, thus 0x0000001f == 31.

source
Core.Int64Type
Int64 <: Signed <: Integer

64-bit signed integer type.

Note that such integers overflow without warning, thus typemax(Int64) + Int64(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt64Type
UInt64 <: Unsigned <: Integer

64-bit unsigned integer type.

Printed in hexadecimal, thus 0x000000000000003f == 63.

source
Core.Int128Type
Int128 <: Signed <: Integer

128-bit signed integer type.

Note that such integers overflow without warning, thus typemax(Int128) + Int128(1) < 0.

See also Int, widen, BigInt.

source
Core.UInt128Type
UInt128 <: Unsigned <: Integer

128-bit unsigned integer type.

Printed in hexadecimal, thus 0x0000000000000000000000000000007f == 127.

source
Core.IntType
Int

Sys.WORD_SIZE-bit signed integer type, Int <: Signed <: Integer <: Real.

This is the default type of most integer literals and is an alias for either Int32 or Int64, depending on Sys.WORD_SIZE. It is the type returned by functions such as length, and the standard type for indexing arrays.

Note that integers overflow without warning, thus typemax(Int) + 1 < 0 and 10^19 < 0. Overflow can be avoided by using BigInt. Very large integer literals will use a wider type, for instance 10_000_000_000_000_000_000 isa Int128.

Integer division is div alias ÷, whereas / acting on integers returns Float64.

See also Int64, widen, typemax, bitstring.

source
Core.UIntType
UInt

Sys.WORD_SIZE-bit unsigned integer type, UInt <: Unsigned <: Integer.

Like Int, the alias UInt may point to either UInt32 or UInt64, according to the value of Sys.WORD_SIZE on a given computer.

Printed and parsed in hexadecimal: UInt(15) === 0x000000000000000f.

source
Base.ComplexType
Complex{T<:Real} <: Number

Complex number type with real and imaginary part of type T.

ComplexF16, ComplexF32 and ComplexF64 are aliases for Complex{Float16}, Complex{Float32} and Complex{Float64} respectively.

See also: Real, complex, real.

source
Base.RationalType
Rational{T<:Integer} <: Real

Rational number type, with numerator and denominator of type T. Rationals are checked for overflow.

source

Data Formats

Base.digitsFunction
digits([T<:Integer], n::Integer; base::T = 10, pad::Integer = 1)

Return an array with element type T (default Int) of the digits of n in the given base, optionally padded with zeros to a specified size. More significant digits are at higher indices, such that n == sum(digits[k]*base^(k-1) for k=1:length(digits)).

See also ndigits, digits!, and for base 2 also bitstring, count_ones.

Examples

julia> digits(10)
 2-element Vector{Int64}:
  0
  1
@@ -81,7 +81,7 @@
 julia> n = rand(-999:999);
 
 julia> n == evalpoly(13, digits(n, base = 13))
-true
source
Base.digits!Function
digits!(array, n::Integer; base::Integer = 10)

Fills an array of the digits of n in the given base. More significant digits are at higher indices. If the array length is insufficient, the least significant digits are filled up to the array length. If the array length is excessive, the excess portion is filled with zeros.

Examples

julia> digits!([2, 2, 2, 2], 10, base = 2)
+true
source
Base.digits!Function
digits!(array, n::Integer; base::Integer = 10)

Fills an array of the digits of n in the given base. More significant digits are at higher indices. If the array length is insufficient, the least significant digits are filled up to the array length. If the array length is excessive, the excess portion is filled with zeros.

Examples

julia> digits!([2, 2, 2, 2], 10, base = 2)
 4-element Vector{Int64}:
  0
  1
@@ -95,11 +95,11 @@
  0
  1
  0
- 0
source
Base.bitstringFunction
bitstring(n)

A string giving the literal bit representation of a primitive type.

See also count_ones, count_zeros, digits.

Examples

julia> bitstring(Int32(4))
 "00000000000000000000000000000100"
 
 julia> bitstring(2.2)
-"0100000000000001100110011001100110011001100110011001100110011010"
source
Base.parseFunction
parse(::Type{SimpleColor}, rgb::String)

An analogue of tryparse(SimpleColor, rgb::String) (which see), that raises an error instead of returning nothing.

parse(::Type{Platform}, triplet::AbstractString)

Parses a string platform triplet back into a Platform object.

source
parse(type, str; base)

Parse a string as a number. For Integer types, a base can be specified (the default is 10). For floating-point types, the string is parsed as a decimal floating-point number. Complex types are parsed from decimal strings of the form "R±Iim" as a Complex(R,I) of the requested type; "i" or "j" can also be used instead of "im", and "R" or "Iim" are also permitted. If the string does not contain a valid number, an error is raised.

Julia 1.1

parse(Bool, str) requires at least Julia 1.1.

Examples

julia> parse(Int, "1234")
+"0100000000000001100110011001100110011001100110011001100110011010"
source
Base.parseFunction
parse(::Type{SimpleColor}, rgb::String)

An analogue of tryparse(SimpleColor, rgb::String) (which see), that raises an error instead of returning nothing.

parse(::Type{Platform}, triplet::AbstractString)

Parses a string platform triplet back into a Platform object.

source
parse(type, str; base)

Parse a string as a number. For Integer types, a base can be specified (the default is 10). For floating-point types, the string is parsed as a decimal floating-point number. Complex types are parsed from decimal strings of the form "R±Iim" as a Complex(R,I) of the requested type; "i" or "j" can also be used instead of "im", and "R" or "Iim" are also permitted. If the string does not contain a valid number, an error is raised.

Julia 1.1

parse(Bool, str) requires at least Julia 1.1.

Examples

julia> parse(Int, "1234")
 1234
 
 julia> parse(Int, "1234", base = 5)
@@ -112,23 +112,23 @@
 0.0012
 
 julia> parse(Complex{Float64}, "3.2e-1 + 4.5im")
-0.32 + 4.5im
source
Base.tryparseFunction
tryparse(::Type{SimpleColor}, rgb::String)

Attempt to parse rgb as a SimpleColor. If rgb starts with # and has a length of 7, it is converted into a RGBTuple-backed SimpleColor. If rgb starts with a-z, rgb is interpreted as a color name and converted to a Symbol-backed SimpleColor.

Otherwise, nothing is returned.

Examples

julia> tryparse(SimpleColor, "blue")
+0.32 + 4.5im
source
Base.tryparseFunction
tryparse(::Type{SimpleColor}, rgb::String)

Attempt to parse rgb as a SimpleColor. If rgb starts with # and has a length of 7, it is converted into a RGBTuple-backed SimpleColor. If rgb starts with a-z, rgb is interpreted as a color name and converted to a Symbol-backed SimpleColor.

Otherwise, nothing is returned.

Examples

julia> tryparse(SimpleColor, "blue")
 SimpleColor(blue)
 
 julia> tryparse(SimpleColor, "#9558b2")
 SimpleColor(#9558b2)
 
-julia> tryparse(SimpleColor, "#nocolor")
tryparse(type, str; base)

Like parse, but returns either a value of the requested type, or nothing if the string does not contain a valid number.

source
Base.bigFunction
big(x)

Convert a number to a maximum precision representation (typically BigInt or BigFloat). See BigFloat for information about some pitfalls with floating-point numbers.

source
Base.signedFunction
signed(T::Integer)

Convert an integer bitstype to the signed type of the same size.

Examples

julia> signed(UInt16)
+julia> tryparse(SimpleColor, "#nocolor")
tryparse(type, str; base)

Like parse, but returns either a value of the requested type, or nothing if the string does not contain a valid number.

source
Base.bigFunction
big(x)

Convert a number to a maximum precision representation (typically BigInt or BigFloat). See BigFloat for information about some pitfalls with floating-point numbers.

source
Base.signedFunction
signed(T::Integer)

Convert an integer bitstype to the signed type of the same size.

Examples

julia> signed(UInt16)
 Int16
 julia> signed(UInt64)
-Int64
source
signed(x)

Convert a number to a signed integer. If the argument is unsigned, it is reinterpreted as signed without checking for overflow.

See also: unsigned, sign, signbit.

source
Base.unsignedFunction
unsigned(T::Integer)

Convert an integer bitstype to the unsigned type of the same size.

Examples

julia> unsigned(Int16)
+Int64
source
signed(x)

Convert a number to a signed integer. If the argument is unsigned, it is reinterpreted as signed without checking for overflow.

See also: unsigned, sign, signbit.

source
Base.unsignedFunction
unsigned(T::Integer)

Convert an integer bitstype to the unsigned type of the same size.

Examples

julia> unsigned(Int16)
 UInt16
 julia> unsigned(UInt64)
-UInt64
source
Base.floatMethod
float(x)

Convert a number or array to a floating point data type.

See also: complex, oftype, convert.

Examples

julia> float(1:1000)
 1.0:1.0:1000.0
 
 julia> float(typemax(Int32))
-2.147483647e9
source
Base.Math.significandFunction
significand(x)

Extract the significand (a.k.a. mantissa) of a floating-point number. If x is a non-zero finite number, then the result will be a number of the same type and sign as x, and whose absolute value is on the interval $[1,2)$. Otherwise x is returned.

See also frexp, exponent.

Examples

julia> significand(15.2)
+2.147483647e9
source
Base.Math.significandFunction
significand(x)

Extract the significand (a.k.a. mantissa) of a floating-point number. If x is a non-zero finite number, then the result will be a number of the same type and sign as x, and whose absolute value is on the interval $[1,2)$. Otherwise x is returned.

See also frexp, exponent.

Examples

julia> significand(15.2)
 1.9
 
 julia> significand(-15.2)
@@ -138,7 +138,7 @@
 -15.2
 
 julia> significand(-Inf), significand(Inf), significand(NaN)
-(-Inf, Inf, NaN)
source
Base.Math.exponentFunction
exponent(x::Real) -> Int

Return the largest integer y such that 2^y ≤ abs(x). For a normalized floating-point number x, this corresponds to the exponent of x.

Throws a DomainError when x is zero, infinite, or NaN. For any other non-subnormal floating-point number x, this corresponds to the exponent bits of x.

See also signbit, significand, frexp, issubnormal, log2, ldexp.

Examples

julia> exponent(8)
+(-Inf, Inf, NaN)
source
Base.Math.exponentFunction
exponent(x::Real) -> Int

Return the largest integer y such that 2^y ≤ abs(x). For a normalized floating-point number x, this corresponds to the exponent of x.

Throws a DomainError when x is zero, infinite, or NaN. For any other non-subnormal floating-point number x, this corresponds to the exponent bits of x.

See also signbit, significand, frexp, issubnormal, log2, ldexp.

Examples

julia> exponent(8)
 3
 
 julia> exponent(6.5)
@@ -156,14 +156,14 @@
 julia> exponent(0.0)
 ERROR: DomainError with 0.0:
 Cannot be ±0.0.
-[...]
source
Base.complexMethod
complex(r, [i])

Convert real numbers or arrays to complex. i defaults to zero.

Examples

julia> complex(7)
+[...]
source
Base.complexMethod
complex(r, [i])

Convert real numbers or arrays to complex. i defaults to zero.

Examples

julia> complex(7)
 7 + 0im
 
 julia> complex([1, 2, 3])
 3-element Vector{Complex{Int64}}:
  1 + 0im
  2 + 0im
- 3 + 0im
source
Base.bswapFunction
bswap(n)

Reverse the byte order of n.

(See also ntoh and hton to convert between the current native byte order and big-endian order.)

Examples

julia> a = bswap(0x10203040)
+ 3 + 0im
source
Base.bswapFunction
bswap(n)

Reverse the byte order of n.

(See also ntoh and hton to convert between the current native byte order and big-endian order.)

Examples

julia> a = bswap(0x10203040)
 0x40302010
 
 julia> bswap(a)
@@ -173,7 +173,7 @@
 "1"
 
 julia> string(bswap(1), base = 2)
-"100000000000000000000000000000000000000000000000000000000"
source
Base.hex2bytesFunction
hex2bytes(itr)

Given an iterable itr of ASCII codes for a sequence of hexadecimal digits, returns a Vector{UInt8} of bytes corresponding to the binary representation: each successive pair of hexadecimal digits in itr gives the value of one byte in the return vector.

The length of itr must be even, and the returned array has half of the length of itr. See also hex2bytes! for an in-place version, and bytes2hex for the inverse.

Julia 1.7

Calling hex2bytes with iterators producing UInt8 values requires Julia 1.7 or later. In earlier versions, you can collect the iterator before calling hex2bytes.

Examples

julia> s = string(12345, base = 16)
+"100000000000000000000000000000000000000000000000000000000"
source
Base.hex2bytesFunction
hex2bytes(itr)

Given an iterable itr of ASCII codes for a sequence of hexadecimal digits, returns a Vector{UInt8} of bytes corresponding to the binary representation: each successive pair of hexadecimal digits in itr gives the value of one byte in the return vector.

The length of itr must be even, and the returned array has half of the length of itr. See also hex2bytes! for an in-place version, and bytes2hex for the inverse.

Julia 1.7

Calling hex2bytes with iterators producing UInt8 values requires Julia 1.7 or later. In earlier versions, you can collect the iterator before calling hex2bytes.

Examples

julia> s = string(12345, base = 16)
 "3039"
 
 julia> hex2bytes(s)
@@ -194,7 +194,7 @@
 3-element Vector{UInt8}:
  0x01
  0xab
- 0xef
source
Base.hex2bytes!Function
hex2bytes!(dest::AbstractVector{UInt8}, itr)

Convert an iterable itr of bytes representing a hexadecimal string to its binary representation, similar to hex2bytes except that the output is written in-place to dest. The length of dest must be half the length of itr.

Julia 1.7

Calling hex2bytes! with iterators producing UInt8 requires version 1.7. In earlier versions, you can collect the iterable before calling instead.

source
Base.hex2bytes!Function
hex2bytes!(dest::AbstractVector{UInt8}, itr)

Convert an iterable itr of bytes representing a hexadecimal string to its binary representation, similar to hex2bytes except that the output is written in-place to dest. The length of dest must be half the length of itr.

Julia 1.7

Calling hex2bytes! with iterators producing UInt8 requires version 1.7. In earlier versions, you can collect the iterable before calling instead.

source
Base.bytes2hexFunction
bytes2hex(itr) -> String
 bytes2hex(io::IO, itr)

Convert an iterator itr of bytes to its hexadecimal string representation, either returning a String via bytes2hex(itr) or writing the string to an io stream via bytes2hex(io, itr). The hexadecimal characters are all lowercase.

Julia 1.7

Calling bytes2hex with arbitrary iterators producing UInt8 values requires Julia 1.7 or later. In earlier versions, you can collect the iterator before calling bytes2hex.

Examples

julia> a = string(12345, base = 16)
 "3039"
 
@@ -204,7 +204,7 @@
  0x39
 
 julia> bytes2hex(b)
-"3039"
source

General Number Functions and Constants

General Number Functions and Constants

Base.oneFunction
one(x)
 one(T::type)

Return a multiplicative identity for x: a value such that one(x)*x == x*one(x) == x. If the multiplicative identity can be deduced from the type alone, then a type may be given as an argument to one (e.g. one(Int) will work because the multiplicative identity is the same for all instances of Int, but one(Matrix{Int}) is not defined because matrices of different shapes have different multiplicative identities.)

If possible, one(x) returns a value of the same type as x, and one(T) returns a value of type T. However, this may not be the case for types representing dimensionful quantities (e.g. time in days), since the multiplicative identity must be dimensionless. In that case, one(x) should return an identity value of the same precision (and shape, for matrices) as x.

If you want a quantity that is of the same type as x, or of type T, even if x is dimensionful, use oneunit instead.

See also the identity function, and I in LinearAlgebra for the identity matrix.

Examples

julia> one(3.7)
 1.0
 
@@ -212,12 +212,12 @@
 1
 
 julia> import Dates; one(Dates.Day(1))
-1
source
Base.oneunitFunction
oneunit(x::T)
 oneunit(T::Type)

Return T(one(x)), where T is either the type of the argument, or the argument itself in cases where the oneunit can be deduced from the type alone. This differs from one for dimensionful quantities: one is dimensionless (a multiplicative identity) while oneunit is dimensionful (of the same type as x, or of type T).

Examples

julia> oneunit(3.7)
 1.0
 
 julia> import Dates; oneunit(Dates.Day)
-1 day
source
Base.zeroFunction
zero(x)
 zero(::Type)

Get the additive identity element for x. If the additive identity can be deduced from the type alone, then a type may be given as an argument to zero.

For example, zero(Int) will work because the additive identity is the same for all instances of Int, but zero(Vector{Int}) is not defined because vectors of different lengths have different additive identities.

See also iszero, one, oneunit, oftype.

Examples

julia> zero(1)
 0
 
@@ -227,16 +227,16 @@
 julia> zero(rand(2,2))
 2×2 Matrix{Float64}:
  0.0  0.0
- 0.0  0.0
source
Base.imConstant
im

The imaginary unit.

See also: imag, angle, complex.

Examples

julia> im * im
 -1 + 0im
 
 julia> (2.0 + 3im)^2
--5.0 + 12.0im
source
Base.MathConstants.piConstant
π
 pi

The constant pi.

Unicode π can be typed by writing \pi then pressing tab in the Julia REPL, and in many editors.

See also: sinpi, sincospi, deg2rad.

Examples

julia> pi
 π = 3.1415926535897...
 
 julia> 1/2pi
-0.15915494309189535
source
Base.MathConstants.ℯConstant
ℯ
 e

The constant ℯ.

Unicode can be typed by writing \euler and pressing tab in the Julia REPL, and in many editors.

See also: exp, cis, cispi.

Examples

julia> ℯ
 ℯ = 2.7182818284590...
 
@@ -244,37 +244,37 @@
 1
 
 julia> ℯ^(im)π ≈ -1
-true
source
Base.MathConstants.catalanConstant
catalan

Catalan's constant.

Examples

julia> Base.MathConstants.catalan
 catalan = 0.9159655941772...
 
 julia> sum(log(x)/(1+x^2) for x in 1:0.01:10^6) * 0.01
-0.9159466120554123
source
Base.MathConstants.eulergammaConstant
γ
 eulergamma

Euler's constant.

Examples

julia> Base.MathConstants.eulergamma
 γ = 0.5772156649015...
 
 julia> dx = 10^-6;
 
 julia> sum(-exp(-x) * log(x) for x in dx:dx:100) * dx
-0.5772078382499133
source
Base.MathConstants.goldenConstant
φ
 golden

The golden ratio.

Examples

julia> Base.MathConstants.golden
 φ = 1.6180339887498...
 
 julia> (2ans - 1)^2 ≈ 5
-true
source
Base.NaNConstant
NaN, NaN64

A not-a-number value of type Float64.

See also: isnan, missing, NaN32, Inf.

Examples

julia> 0/0
 NaN
 
 julia> Inf - Inf
@@ -288,7 +288,7 @@
 NaN32
 
 julia> NaN32p1 === NaN32, isequal(NaN32p1, NaN32), isnan(NaN32p1)
-(false, true, true)
source
Base.NaN64Constant
NaN, NaN64

A not-a-number value of type Float64.

See also: isnan, missing, NaN32, Inf.

Examples

julia> 0/0
+(false, true, true)
source
Base.NaN64Constant
NaN, NaN64

A not-a-number value of type Float64.

See also: isnan, missing, NaN32, Inf.

Examples

julia> 0/0
 NaN
 
 julia> Inf - Inf
@@ -302,33 +302,33 @@
 NaN32
 
 julia> NaN32p1 === NaN32, isequal(NaN32p1, NaN32), isnan(NaN32p1)
-(false, true, true)
source
Base.NaN32Constant
NaN32

A not-a-number value of type Float32.

See also: NaN.

source
Base.NaN16Constant
NaN16

A not-a-number value of type Float16.

See also: NaN.

source
Base.issubnormalFunction
issubnormal(f) -> Bool

Test whether a floating point number is subnormal.

An IEEE floating point number is subnormal when its exponent bits are zero and its significand is not zero.

Examples

julia> floatmin(Float32)
+(false, true, true)
source
Base.NaN32Constant
NaN32

A not-a-number value of type Float32.

See also: NaN.

source
Base.NaN16Constant
NaN16

A not-a-number value of type Float16.

See also: NaN.

source
Base.issubnormalFunction
issubnormal(f) -> Bool

Test whether a floating point number is subnormal.

An IEEE floating point number is subnormal when its exponent bits are zero and its significand is not zero.

Examples

julia> floatmin(Float32)
 1.1754944f-38
 
 julia> issubnormal(1.0f-37)
 false
 
 julia> issubnormal(1.0f-38)
-true
source
Base.isfiniteFunction
isfinite(f) -> Bool

Test whether a number is finite.

Examples

julia> isfinite(5)
+true
source
Base.isfiniteFunction
isfinite(f) -> Bool

Test whether a number is finite.

Examples

julia> isfinite(5)
 true
 
 julia> isfinite(NaN32)
-false
source
Base.isinfFunction
isinf(f) -> Bool

Test whether a number is infinite.

See also: Inf, iszero, isfinite, isnan.

source
Base.isnanFunction
isnan(f) -> Bool

Test whether a number value is a NaN, an indeterminate value which is neither an infinity nor a finite number ("not a number").

See also: iszero, isone, isinf, ismissing.

source
Base.iszeroFunction
iszero(x)

Return true if x == zero(x); if x is an array, this checks whether all of the elements of x are zero.

See also: isone, isinteger, isfinite, isnan.

Examples

julia> iszero(0.0)
+false
source
Base.isinfFunction
isinf(f) -> Bool

Test whether a number is infinite.

See also: Inf, iszero, isfinite, isnan.

source
Base.isnanFunction
isnan(f) -> Bool

Test whether a number value is a NaN, an indeterminate value which is neither an infinity nor a finite number ("not a number").

See also: iszero, isone, isinf, ismissing.

source
Base.iszeroFunction
iszero(x)

Return true if x == zero(x); if x is an array, this checks whether all of the elements of x are zero.

See also: isone, isinteger, isfinite, isnan.

Examples

julia> iszero(0.0)
 true
 
 julia> iszero([1, 9, 0])
 false
 
 julia> iszero([false, 0, 0])
-true
source
Base.isoneFunction
isone(x)

Return true if x == one(x); if x is an array, this checks whether x is an identity matrix.

Examples

julia> isone(1.0)
+true
source
Base.isoneFunction
isone(x)

Return true if x == one(x); if x is an array, this checks whether x is an identity matrix.

Examples

julia> isone(1.0)
 true
 
 julia> isone([1 0; 0 2])
 false
 
 julia> isone([1 0; 0 true])
-true
source
Base.nextfloatFunction
nextfloat(x::AbstractFloat, n::Integer)

The result of n iterative applications of nextfloat to x if n >= 0, or -n applications of prevfloat if n < 0.

source
nextfloat(x::AbstractFloat)

Return the smallest floating point number y of the same type as x such x < y. If no such y exists (e.g. if x is Inf or NaN), then return x.

See also: prevfloat, eps, issubnormal.

source
Base.prevfloatFunction
prevfloat(x::AbstractFloat, n::Integer)

The result of n iterative applications of prevfloat to x if n >= 0, or -n applications of nextfloat if n < 0.

source
prevfloat(x::AbstractFloat)

Return the largest floating point number y of the same type as x such y < x. If no such y exists (e.g. if x is -Inf or NaN), then return x.

source
Base.isintegerFunction
isinteger(x) -> Bool

Test whether x is numerically equal to some integer.

Examples

julia> isinteger(4.0)
-true
source
Base.isrealFunction
isreal(x) -> Bool

Test whether x or all its elements are numerically equal to some real number including infinities and NaNs. isreal(x) is true if isequal(x, real(x)) is true.

Examples

julia> isreal(5.)
+true
source
Base.nextfloatFunction
nextfloat(x::AbstractFloat, n::Integer)

The result of n iterative applications of nextfloat to x if n >= 0, or -n applications of prevfloat if n < 0.

source
nextfloat(x::AbstractFloat)

Return the smallest floating point number y of the same type as x such x < y. If no such y exists (e.g. if x is Inf or NaN), then return x.

See also: prevfloat, eps, issubnormal.

source
Base.prevfloatFunction
prevfloat(x::AbstractFloat, n::Integer)

The result of n iterative applications of prevfloat to x if n >= 0, or -n applications of nextfloat if n < 0.

source
prevfloat(x::AbstractFloat)

Return the largest floating point number y of the same type as x such y < x. If no such y exists (e.g. if x is -Inf or NaN), then return x.

source
Base.isintegerFunction
isinteger(x) -> Bool

Test whether x is numerically equal to some integer.

Examples

julia> isinteger(4.0)
+true
source
Base.isrealFunction
isreal(x) -> Bool

Test whether x or all its elements are numerically equal to some real number including infinities and NaNs. isreal(x) is true if isequal(x, real(x)) is true.

Examples

julia> isreal(5.)
 true
 
 julia> isreal(1 - 3im)
@@ -338,48 +338,48 @@
 true
 
 julia> isreal([4.; complex(0,1)])
-false
source
Core.Float32Method
Float32(x [, mode::RoundingMode])

Create a Float32 from x. If x is not exactly representable then mode determines how x is rounded.

Examples

julia> Float32(1/3, RoundDown)
+false
source
Core.Float32Method
Float32(x [, mode::RoundingMode])

Create a Float32 from x. If x is not exactly representable then mode determines how x is rounded.

Examples

julia> Float32(1/3, RoundDown)
 0.3333333f0
 
 julia> Float32(1/3, RoundUp)
-0.33333334f0

See RoundingMode for available rounding modes.

source
Core.Float64Method
Float64(x [, mode::RoundingMode])

Create a Float64 from x. If x is not exactly representable then mode determines how x is rounded.

Examples

julia> Float64(pi, RoundDown)
+0.33333334f0

See RoundingMode for available rounding modes.

source
Core.Float64Method
Float64(x [, mode::RoundingMode])

Create a Float64 from x. If x is not exactly representable then mode determines how x is rounded.

Examples

julia> Float64(pi, RoundDown)
 3.141592653589793
 
 julia> Float64(pi, RoundUp)
-3.1415926535897936

See RoundingMode for available rounding modes.

source
Base.Rounding.roundingFunction
rounding(T)

Get the current floating point rounding mode for type T, controlling the rounding of basic arithmetic functions (+, -, *, / and sqrt) and type conversion.

See RoundingMode for available modes.

source
Base.Rounding.setroundingMethod
setrounding(T, mode)

Set the rounding mode of floating point type T, controlling the rounding of basic arithmetic functions (+, -, *, / and sqrt) and type conversion. Other numerical functions may give incorrect or invalid values when using rounding modes other than the default RoundNearest.

Note that this is currently only supported for T == BigFloat.

Warning

This function is not thread-safe. It will affect code running on all threads, but its behavior is undefined if called concurrently with computations that use the setting.

source
Base.Rounding.setroundingMethod
setrounding(f::Function, T, mode)

Change the rounding mode of floating point type T for the duration of f. It is logically equivalent to:

old = rounding(T)
+3.1415926535897936

See RoundingMode for available rounding modes.

source
Base.Rounding.roundingFunction
rounding(T)

Get the current floating point rounding mode for type T, controlling the rounding of basic arithmetic functions (+, -, *, / and sqrt) and type conversion.

See RoundingMode for available modes.

source
Base.Rounding.setroundingMethod
setrounding(T, mode)

Set the rounding mode of floating point type T, controlling the rounding of basic arithmetic functions (+, -, *, / and sqrt) and type conversion. Other numerical functions may give incorrect or invalid values when using rounding modes other than the default RoundNearest.

Note that this is currently only supported for T == BigFloat.

Warning

This function is not thread-safe. It will affect code running on all threads, but its behavior is undefined if called concurrently with computations that use the setting.

source
Base.Rounding.setroundingMethod
setrounding(f::Function, T, mode)

Change the rounding mode of floating point type T for the duration of f. It is logically equivalent to:

old = rounding(T)
 setrounding(T, mode)
 f()
-setrounding(T, old)

See RoundingMode for available rounding modes.

source
Base.Rounding.get_zero_subnormalsFunction
get_zero_subnormals() -> Bool

Return false if operations on subnormal floating-point values ("denormals") obey rules for IEEE arithmetic, and true if they might be converted to zeros.

Warning

This function only affects the current thread.

source
Base.Rounding.set_zero_subnormalsFunction
set_zero_subnormals(yes::Bool) -> Bool

If yes is false, subsequent floating-point operations follow rules for IEEE arithmetic on subnormal values ("denormals"). Otherwise, floating-point operations are permitted (but not required) to convert subnormal inputs or outputs to zero. Returns true unless yes==true but the hardware does not support zeroing of subnormal numbers.

set_zero_subnormals(true) can speed up some computations on some hardware. However, it can break identities such as (x-y==0) == (x==y).

Warning

This function only affects the current thread.

source

Integers

Base.count_onesFunction
count_ones(x::Integer) -> Integer

Number of ones in the binary representation of x.

Examples

julia> count_ones(7)
+setrounding(T, old)

See RoundingMode for available rounding modes.

source
Base.Rounding.get_zero_subnormalsFunction
get_zero_subnormals() -> Bool

Return false if operations on subnormal floating-point values ("denormals") obey rules for IEEE arithmetic, and true if they might be converted to zeros.

Warning

This function only affects the current thread.

source
Base.Rounding.set_zero_subnormalsFunction
set_zero_subnormals(yes::Bool) -> Bool

If yes is false, subsequent floating-point operations follow rules for IEEE arithmetic on subnormal values ("denormals"). Otherwise, floating-point operations are permitted (but not required) to convert subnormal inputs or outputs to zero. Returns true unless yes==true but the hardware does not support zeroing of subnormal numbers.

set_zero_subnormals(true) can speed up some computations on some hardware. However, it can break identities such as (x-y==0) == (x==y).

Warning

This function only affects the current thread.

source

Integers

Base.count_onesFunction
count_ones(x::Integer) -> Integer

Number of ones in the binary representation of x.

Examples

julia> count_ones(7)
 3
 
 julia> count_ones(Int32(-1))
-32
source
Base.count_zerosFunction
count_zeros(x::Integer) -> Integer

Number of zeros in the binary representation of x.

Examples

julia> count_zeros(Int32(2 ^ 16 - 1))
+32
source
Base.count_zerosFunction
count_zeros(x::Integer) -> Integer

Number of zeros in the binary representation of x.

Examples

julia> count_zeros(Int32(2 ^ 16 - 1))
 16
 
 julia> count_zeros(-1)
-0
source
Base.leading_zerosFunction
leading_zeros(x::Integer) -> Integer

Number of zeros leading the binary representation of x.

Examples

julia> leading_zeros(Int32(1))
-31
source
Base.leading_onesFunction
leading_ones(x::Integer) -> Integer

Number of ones leading the binary representation of x.

Examples

julia> leading_ones(UInt32(2 ^ 32 - 2))
-31
source
Base.trailing_zerosFunction
trailing_zeros(x::Integer) -> Integer

Number of zeros trailing the binary representation of x.

Examples

julia> trailing_zeros(2)
-1
source
Base.trailing_onesFunction
trailing_ones(x::Integer) -> Integer

Number of ones trailing the binary representation of x.

Examples

julia> trailing_ones(3)
-2
source
Base.isoddFunction
isodd(x::Number) -> Bool

Return true if x is an odd integer (that is, an integer not divisible by 2), and false otherwise.

Julia 1.7

Non-Integer arguments require Julia 1.7 or later.

Examples

julia> isodd(9)
+0
source
Base.leading_zerosFunction
leading_zeros(x::Integer) -> Integer

Number of zeros leading the binary representation of x.

Examples

julia> leading_zeros(Int32(1))
+31
source
Base.leading_onesFunction
leading_ones(x::Integer) -> Integer

Number of ones leading the binary representation of x.

Examples

julia> leading_ones(UInt32(2 ^ 32 - 2))
+31
source
Base.trailing_zerosFunction
trailing_zeros(x::Integer) -> Integer

Number of zeros trailing the binary representation of x.

Examples

julia> trailing_zeros(2)
+1
source
Base.trailing_onesFunction
trailing_ones(x::Integer) -> Integer

Number of ones trailing the binary representation of x.

Examples

julia> trailing_ones(3)
+2
source
Base.isoddFunction
isodd(x::Number) -> Bool

Return true if x is an odd integer (that is, an integer not divisible by 2), and false otherwise.

Julia 1.7

Non-Integer arguments require Julia 1.7 or later.

Examples

julia> isodd(9)
 true
 
 julia> isodd(10)
-false
source
Base.isevenFunction
iseven(x::Number) -> Bool

Return true if x is an even integer (that is, an integer divisible by 2), and false otherwise.

Julia 1.7

Non-Integer arguments require Julia 1.7 or later.

Examples

julia> iseven(9)
+false
source
Base.isevenFunction
iseven(x::Number) -> Bool

Return true if x is an even integer (that is, an integer divisible by 2), and false otherwise.

Julia 1.7

Non-Integer arguments require Julia 1.7 or later.

Examples

julia> iseven(9)
 false
 
 julia> iseven(10)
-true
source
Core.@int128_strMacro
@int128_str str

Parse str as an Int128. Throw an ArgumentError if the string is not a valid integer.

Examples

julia> int128"123456789123"
+true
source
Core.@int128_strMacro
@int128_str str

Parse str as an Int128. Throw an ArgumentError if the string is not a valid integer.

Examples

julia> int128"123456789123"
 123456789123
 
 julia> int128"123456789123.4"
 ERROR: LoadError: ArgumentError: invalid base 10 digit '.' in "123456789123.4"
-[...]
source
Core.@uint128_strMacro
@uint128_str str

Parse str as an UInt128. Throw an ArgumentError if the string is not a valid integer.

Examples

julia> uint128"123456789123"
+[...]
source
Core.@uint128_strMacro
@uint128_str str

Parse str as an UInt128. Throw an ArgumentError if the string is not a valid integer.

Examples

julia> uint128"123456789123"
 0x00000000000000000000001cbe991a83
 
 julia> uint128"-123456789123"
 ERROR: LoadError: ArgumentError: invalid base 10 digit '-' in "-123456789123"
-[...]
source

BigFloats and BigInts

The BigFloat and BigInt types implements arbitrary-precision floating point and integer arithmetic, respectively. For BigFloat the GNU MPFR library is used, and for BigInt the GNU Multiple Precision Arithmetic Library (GMP) is used.

Base.MPFR.BigFloatMethod
BigFloat(x::Union{Real, AbstractString} [, rounding::RoundingMode=rounding(BigFloat)]; [precision::Integer=precision(BigFloat)])

Create an arbitrary precision floating point number from x, with precision precision. The rounding argument specifies the direction in which the result should be rounded if the conversion cannot be done exactly. If not provided, these are set by the current global values.

BigFloat(x::Real) is the same as convert(BigFloat,x), except if x itself is already BigFloat, in which case it will return a value with the precision set to the current global precision; convert will always return x.

BigFloat(x::AbstractString) is identical to parse. This is provided for convenience since decimal literals are converted to Float64 when parsed, so BigFloat(2.1) may not yield what you expect.

See also:

Julia 1.1

precision as a keyword argument requires at least Julia 1.1. In Julia 1.0 precision is the second positional argument (BigFloat(x, precision)).

Examples

julia> BigFloat(2.1) # 2.1 here is a Float64
+[...]
source

BigFloats and BigInts

The BigFloat and BigInt types implements arbitrary-precision floating point and integer arithmetic, respectively. For BigFloat the GNU MPFR library is used, and for BigInt the GNU Multiple Precision Arithmetic Library (GMP) is used.

Base.MPFR.BigFloatMethod
BigFloat(x::Union{Real, AbstractString} [, rounding::RoundingMode=rounding(BigFloat)]; [precision::Integer=precision(BigFloat)])

Create an arbitrary precision floating point number from x, with precision precision. The rounding argument specifies the direction in which the result should be rounded if the conversion cannot be done exactly. If not provided, these are set by the current global values.

BigFloat(x::Real) is the same as convert(BigFloat,x), except if x itself is already BigFloat, in which case it will return a value with the precision set to the current global precision; convert will always return x.

BigFloat(x::AbstractString) is identical to parse. This is provided for convenience since decimal literals are converted to Float64 when parsed, so BigFloat(2.1) may not yield what you expect.

See also:

Julia 1.1

precision as a keyword argument requires at least Julia 1.1. In Julia 1.0 precision is the second positional argument (BigFloat(x, precision)).

Examples

julia> BigFloat(2.1) # 2.1 here is a Float64
 2.100000000000000088817841970012523233890533447265625
 
 julia> BigFloat("2.1") # the closest BigFloat to 2.1
@@ -389,18 +389,18 @@
 2.100000000000000000000000000000000000000000000000000000000000000000000000000021
 
 julia> BigFloat("2.1", RoundUp, precision=128)
-2.100000000000000000000000000000000000007
source
Base.precisionFunction
precision(num::AbstractFloat; base::Integer=2)
-precision(T::Type; base::Integer=2)

Get the precision of a floating point number, as defined by the effective number of bits in the significand, or the precision of a floating-point type T (its current default, if T is a variable-precision type like BigFloat).

If base is specified, then it returns the maximum corresponding number of significand digits in that base.

Julia 1.8

The base keyword requires at least Julia 1.8.

source
Base.MPFR.setprecisionFunction
setprecision([T=BigFloat,] precision::Int; base=2)

Set the precision (in bits, by default) to be used for T arithmetic. If base is specified, then the precision is the minimum required to give at least precision digits in the given base.

Warning

This function is not thread-safe. It will affect code running on all threads, but its behavior is undefined if called concurrently with computations that use the setting.

Julia 1.8

The base keyword requires at least Julia 1.8.

source
setprecision(f::Function, [T=BigFloat,] precision::Integer; base=2)

Change the T arithmetic precision (in the given base) for the duration of f. It is logically equivalent to:

old = precision(BigFloat)
+2.100000000000000000000000000000000000007
source
Base.precisionFunction
precision(num::AbstractFloat; base::Integer=2)
+precision(T::Type; base::Integer=2)

Get the precision of a floating point number, as defined by the effective number of bits in the significand, or the precision of a floating-point type T (its current default, if T is a variable-precision type like BigFloat).

If base is specified, then it returns the maximum corresponding number of significand digits in that base.

Julia 1.8

The base keyword requires at least Julia 1.8.

source
Base.MPFR.setprecisionFunction
setprecision([T=BigFloat,] precision::Int; base=2)

Set the precision (in bits, by default) to be used for T arithmetic. If base is specified, then the precision is the minimum required to give at least precision digits in the given base.

Warning

This function is not thread-safe. It will affect code running on all threads, but its behavior is undefined if called concurrently with computations that use the setting.

Julia 1.8

The base keyword requires at least Julia 1.8.

source
setprecision(f::Function, [T=BigFloat,] precision::Integer; base=2)

Change the T arithmetic precision (in the given base) for the duration of f. It is logically equivalent to:

old = precision(BigFloat)
 setprecision(BigFloat, precision)
 f()
-setprecision(BigFloat, old)

Often used as setprecision(T, precision) do ... end

Note: nextfloat(), prevfloat() do not use the precision mentioned by setprecision.

Julia 1.8

The base keyword requires at least Julia 1.8.

source
Base.GMP.BigIntMethod
BigInt(x)

Create an arbitrary precision integer. x may be an Int (or anything that can be converted to an Int). The usual mathematical operators are defined for this type, and results are promoted to a BigInt.

Instances can be constructed from strings via parse, or using the big string literal.

Examples

julia> parse(BigInt, "42")
+setprecision(BigFloat, old)

Often used as setprecision(T, precision) do ... end

Note: nextfloat(), prevfloat() do not use the precision mentioned by setprecision.

Julia 1.8

The base keyword requires at least Julia 1.8.

source
Base.GMP.BigIntMethod
BigInt(x)

Create an arbitrary precision integer. x may be an Int (or anything that can be converted to an Int). The usual mathematical operators are defined for this type, and results are promoted to a BigInt.

Instances can be constructed from strings via parse, or using the big string literal.

Examples

julia> parse(BigInt, "42")
 42
 
 julia> big"313"
 313
 
 julia> BigInt(10)^19
-10000000000000000000
source
Core.@big_strMacro
@big_str str

Parse a string into a BigInt or BigFloat, and throw an ArgumentError if the string is not a valid number. For integers _ is allowed in the string as a separator.

Examples

julia> big"123_456"
+10000000000000000000
source
Core.@big_strMacro
@big_str str

Parse a string into a BigInt or BigFloat, and throw an ArgumentError if the string is not a valid number. For integers _ is allowed in the string as a separator.

Examples

julia> big"123_456"
 123456
 
 julia> big"7891.5"
@@ -408,4 +408,4 @@
 
 julia> big"_"
 ERROR: ArgumentError: invalid number format _ for BigInt or BigFloat
-[...]
Warning

Using @big_str for constructing BigFloat values may not result in the behavior that might be naively expected: as a macro, @big_str obeys the global precision (setprecision) and rounding mode (setrounding) settings as they are at load time. Thus, a function like () -> precision(big"0.3") returns a constant whose value depends on the value of the precision at the point when the function is defined, not at the precision at the time when the function is called.

source
+[...]
Warning

Using @big_str for constructing BigFloat values may not result in the behavior that might be naively expected: as a macro, @big_str obeys the global precision (setprecision) and rounding mode (setrounding) settings as they are at load time. Thus, a function like () -> precision(big"0.3") returns a constant whose value depends on the value of the precision at the point when the function is defined, not at the precision at the time when the function is called.

source diff --git a/en/v1.12-dev/base/parallel/index.html b/en/v1.12-dev/base/parallel/index.html index e53da9c6d8ce..1fcbe976c8fc 100644 --- a/en/v1.12-dev/base/parallel/index.html +++ b/en/v1.12-dev/base/parallel/index.html @@ -5,7 +5,7 @@ gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash});

Tasks

Core.TaskType
Task(func)

Create a Task (i.e. coroutine) to execute the given function func (which must be callable with no arguments). The task exits when this function returns. The task will run in the "world age" from the parent at construction when scheduled.

Warning

By default tasks will have the sticky bit set to true t.sticky. This models the historic default for @async. Sticky tasks can only be run on the worker thread they are first scheduled on. To obtain the behavior of Threads.@spawn set the sticky bit manually to false.

Examples

julia> a() = sum(i for i in 1:1000);
 
-julia> b = Task(a);

In this example, b is a runnable Task that hasn't started yet.

source
Base.@taskMacro
@task

Wrap an expression in a Task without executing it, and return the Task. This only creates a task, and does not run it.

Examples

julia> a1() = sum(i for i in 1:1000);
+julia> b = Task(a);

In this example, b is a runnable Task that hasn't started yet.

source
Base.@taskMacro
@task

Wrap an expression in a Task without executing it, and return the Task. This only creates a task, and does not run it.

Examples

julia> a1() = sum(i for i in 1:1000);
 
 julia> b = @task a1();
 
@@ -17,7 +17,7 @@
 julia> yield();
 
 julia> istaskdone(b)
-true
source
Base.@asyncMacro
@async

Wrap an expression in a Task and add it to the local machine's scheduler queue.

Values can be interpolated into @async via $, which copies the value directly into the constructed underlying closure. This allows you to insert the value of a variable, isolating the asynchronous code from changes to the variable's value in the current task.

Warning

It is strongly encouraged to favor Threads.@spawn over @async always even when no parallelism is required especially in publicly distributed libraries. This is because a use of @async disables the migration of the parent task across worker threads in the current implementation of Julia. Thus, seemingly innocent use of @async in a library function can have a large impact on the performance of very different parts of user applications.

Julia 1.4

Interpolating values via $ is available as of Julia 1.4.

source
Base.asyncmapFunction
asyncmap(f, c...; ntasks=0, batch_size=nothing)

Uses multiple concurrent tasks to map f over a collection (or multiple equal length collections). For multiple collection arguments, f is applied elementwise.

ntasks specifies the number of tasks to run concurrently. Depending on the length of the collections, if ntasks is unspecified, up to 100 tasks will be used for concurrent mapping.

ntasks can also be specified as a zero-arg function. In this case, the number of tasks to run in parallel is checked before processing every element and a new task started if the value of ntasks_func is greater than the current number of tasks.

If batch_size is specified, the collection is processed in batch mode. f must then be a function that must accept a Vector of argument tuples and must return a vector of results. The input vector will have a length of batch_size or less.

The following examples highlight execution in different tasks by returning the objectid of the tasks in which the mapping function is executed.

First, with ntasks undefined, each element is processed in a different task.

julia> tskoid() = objectid(current_task());
+true
source
Base.@asyncMacro
@async

Wrap an expression in a Task and add it to the local machine's scheduler queue.

Values can be interpolated into @async via $, which copies the value directly into the constructed underlying closure. This allows you to insert the value of a variable, isolating the asynchronous code from changes to the variable's value in the current task.

Warning

It is strongly encouraged to favor Threads.@spawn over @async always even when no parallelism is required especially in publicly distributed libraries. This is because a use of @async disables the migration of the parent task across worker threads in the current implementation of Julia. Thus, seemingly innocent use of @async in a library function can have a large impact on the performance of very different parts of user applications.

Julia 1.4

Interpolating values via $ is available as of Julia 1.4.

source
Base.asyncmapFunction
asyncmap(f, c...; ntasks=0, batch_size=nothing)

Uses multiple concurrent tasks to map f over a collection (or multiple equal length collections). For multiple collection arguments, f is applied elementwise.

ntasks specifies the number of tasks to run concurrently. Depending on the length of the collections, if ntasks is unspecified, up to 100 tasks will be used for concurrent mapping.

ntasks can also be specified as a zero-arg function. In this case, the number of tasks to run in parallel is checked before processing every element and a new task started if the value of ntasks_func is greater than the current number of tasks.

If batch_size is specified, the collection is processed in batch mode. f must then be a function that must accept a Vector of argument tuples and must return a vector of results. The input vector will have a length of batch_size or less.

The following examples highlight execution in different tasks by returning the objectid of the tasks in which the mapping function is executed.

First, with ntasks undefined, each element is processed in a different task.

julia> tskoid() = objectid(current_task());
 
 julia> asyncmap(x->tskoid(), 1:5)
 5-element Array{UInt64,1}:
@@ -46,7 +46,7 @@
  "args_tuple: (2,), element_val: 2, task: 4904288162898683522"
  "args_tuple: (3,), element_val: 3, task: 9118321258196414413"
  "args_tuple: (4,), element_val: 4, task: 4904288162898683522"
- "args_tuple: (5,), element_val: 5, task: 9118321258196414413"
source
Base.asyncmap!Function
asyncmap!(f, results, c...; ntasks=0, batch_size=nothing)

Like asyncmap, but stores output in results rather than returning a collection.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.istaskdoneFunction
istaskdone(t::Task) -> Bool

Determine whether a task has exited.

Examples

julia> a2() = sum(i for i in 1:1000);
+ "args_tuple: (5,), element_val: 5, task: 9118321258196414413"
source
Base.asyncmap!Function
asyncmap!(f, results, c...; ntasks=0, batch_size=nothing)

Like asyncmap, but stores output in results rather than returning a collection.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

source
Base.istaskdoneFunction
istaskdone(t::Task) -> Bool

Determine whether a task has exited.

Examples

julia> a2() = sum(i for i in 1:1000);
 
 julia> b = Task(a2);
 
@@ -58,12 +58,12 @@
 julia> yield();
 
 julia> istaskdone(b)
-true
source
Base.istaskstartedFunction
istaskstarted(t::Task) -> Bool

Determine whether a task has started executing.

Examples

julia> a3() = sum(i for i in 1:1000);
+true
source
Base.istaskstartedFunction
istaskstarted(t::Task) -> Bool

Determine whether a task has started executing.

Examples

julia> a3() = sum(i for i in 1:1000);
 
 julia> b = Task(a3);
 
 julia> istaskstarted(b)
-false
source
Base.istaskfailedFunction
istaskfailed(t::Task) -> Bool

Determine whether a task has exited because an exception was thrown.

Examples

julia> a4() = error("task failed");
+false
source
Base.istaskfailedFunction
istaskfailed(t::Task) -> Bool

Determine whether a task has exited because an exception was thrown.

Examples

julia> a4() = error("task failed");
 
 julia> b = Task(a4);
 
@@ -75,7 +75,7 @@
 julia> yield();
 
 julia> istaskfailed(b)
-true
Julia 1.3

This function requires at least Julia 1.3.

source
Base.task_local_storageMethod
task_local_storage(body, key, value)

Call the function body with a modified task-local storage, in which value is assigned to key; the previous value of key, or lack thereof, is restored afterwards. Useful for emulating dynamic scoping.

source

Scheduling

Base.yieldFunction
yield()

Switch to the scheduler to allow another scheduled task to run. A task that calls this function is still runnable, and will be restarted immediately if there are no other runnable tasks.

source
yield(t::Task, arg = nothing)

A fast, unfair-scheduling version of schedule(t, arg); yield() which immediately yields to t before calling the scheduler.

source
Base.yieldtoFunction
yieldto(t::Task, arg = nothing)

Switch to the given task. The first time a task is switched to, the task's function is called with no arguments. On subsequent switches, arg is returned from the task's last call to yieldto. This is a low-level call that only switches tasks, not considering states or scheduling in any way. Its use is discouraged.

source
Base.sleepFunction
sleep(seconds)

Block the current task for a specified number of seconds. The minimum sleep time is 1 millisecond or input of 0.001.

source
Base.scheduleFunction
schedule(t::Task, [val]; error=false)

Add a Task to the scheduler's queue. This causes the task to run constantly when the system is otherwise idle, unless the task performs a blocking operation such as wait.

If a second argument val is provided, it will be passed to the task (via the return value of yieldto) when it runs again. If error is true, the value is raised as an exception in the woken task.

Warning

It is incorrect to use schedule on an arbitrary Task that has already been started. See the API reference for more information.

Examples

julia> a5() = sum(i for i in 1:1000);
+true
Julia 1.3

This function requires at least Julia 1.3.

source
Base.task_local_storageMethod
task_local_storage(body, key, value)

Call the function body with a modified task-local storage, in which value is assigned to key; the previous value of key, or lack thereof, is restored afterwards. Useful for emulating dynamic scoping.

source

Scheduling

Base.yieldFunction
yield()

Switch to the scheduler to allow another scheduled task to run. A task that calls this function is still runnable, and will be restarted immediately if there are no other runnable tasks.

source
yield(t::Task, arg = nothing)

A fast, unfair-scheduling version of schedule(t, arg); yield() which immediately yields to t before calling the scheduler.

source
Base.yieldtoFunction
yieldto(t::Task, arg = nothing)

Switch to the given task. The first time a task is switched to, the task's function is called with no arguments. On subsequent switches, arg is returned from the task's last call to yieldto. This is a low-level call that only switches tasks, not considering states or scheduling in any way. Its use is discouraged.

source
Base.sleepFunction
sleep(seconds)

Block the current task for a specified number of seconds. The minimum sleep time is 1 millisecond or input of 0.001.

source
Base.scheduleFunction
schedule(t::Task, [val]; error=false)

Add a Task to the scheduler's queue. This causes the task to run constantly when the system is otherwise idle, unless the task performs a blocking operation such as wait.

If a second argument val is provided, it will be passed to the task (via the return value of yieldto) when it runs again. If error is true, the value is raised as an exception in the woken task.

Warning

It is incorrect to use schedule on an arbitrary Task that has already been started. See the API reference for more information.

Examples

julia> a5() = sum(i for i in 1:1000);
 
 julia> b = Task(a5);
 
@@ -90,10 +90,10 @@
 true
 
 julia> istaskdone(b)
-true
source

Synchronization

Base.errormonitorFunction
errormonitor(t::Task)

Print an error log to stderr if task t fails.

Examples

julia> Base._wait(errormonitor(Threads.@spawn error("task failed")))
+true
source

Synchronization

Base.errormonitorFunction
errormonitor(t::Task)

Print an error log to stderr if task t fails.

Examples

julia> Base._wait(errormonitor(Threads.@spawn error("task failed")))
 Unhandled Task ERROR: task failed
 Stacktrace:
-[...]
source
Base.@syncMacro
@sync

Wait until all lexically-enclosed uses of @async, @spawn, Distributed.@spawnat and Distributed.@distributed are complete. All exceptions thrown by enclosed async operations are collected and thrown as a CompositeException.

Examples

julia> Threads.nthreads()
+[...]
source
Base.@syncMacro
@sync

Wait until all lexically-enclosed uses of @async, @spawn, Distributed.@spawnat and Distributed.@distributed are complete. All exceptions thrown by enclosed async operations are collected and thrown as a CompositeException.

Examples

julia> Threads.nthreads()
 4
 
 julia> @sync begin
@@ -101,7 +101,7 @@
            Threads.@spawn println("Thread-id $(Threads.threadid()), task 2")
        end;
 Thread-id 3, task 1
-Thread-id 1, task 2
source
Base.waitFunction

Special note for Threads.Condition:

The caller must be holding the lock that owns a Threads.Condition before calling this method. The calling task will be blocked until some other task wakes it, usually by calling notify on the same Threads.Condition object. The lock will be atomically released when blocking (even if it was locked recursively), and will be reacquired before returning.

source
wait(r::Future)

Wait for a value to become available for the specified Future.

wait(r::RemoteChannel, args...)

Wait for a value to become available on the specified RemoteChannel.

wait([x])

Block the current task until some event occurs, depending on the type of the argument:

  • Channel: Wait for a value to be appended to the channel.
  • Condition: Wait for notify on a condition and return the val parameter passed to notify. Waiting on a condition additionally allows passing first=true which results in the waiter being put first in line to wake up on notify instead of the usual first-in-first-out behavior.
  • Process: Wait for a process or process chain to exit. The exitcode field of a process can be used to determine success or failure.
  • Task: Wait for a Task to finish. If the task fails with an exception, a TaskFailedException (which wraps the failed task) is thrown. Waiting on a task additionally allows passing throw=false which prevents throwing a TaskFailedException when the task fails.
  • RawFD: Wait for changes on a file descriptor (see the FileWatching package).

If no argument is passed, the task blocks for an undefined period. A task can only be restarted by an explicit call to schedule or yieldto.

Often wait is called within a while loop to ensure a waited-for condition is met before proceeding.

source
wait(c::Channel)

Blocks until the Channel isready.

julia> c = Channel(1);
+Thread-id 1, task 2
source
Base.waitFunction

Special note for Threads.Condition:

The caller must be holding the lock that owns a Threads.Condition before calling this method. The calling task will be blocked until some other task wakes it, usually by calling notify on the same Threads.Condition object. The lock will be atomically released when blocking (even if it was locked recursively), and will be reacquired before returning.

source
wait(r::Future)

Wait for a value to become available for the specified Future.

wait(r::RemoteChannel, args...)

Wait for a value to become available on the specified RemoteChannel.

wait([x])

Block the current task until some event occurs, depending on the type of the argument:

  • Channel: Wait for a value to be appended to the channel.
  • Condition: Wait for notify on a condition and return the val parameter passed to notify. Waiting on a condition additionally allows passing first=true which results in the waiter being put first in line to wake up on notify instead of the usual first-in-first-out behavior.
  • Process: Wait for a process or process chain to exit. The exitcode field of a process can be used to determine success or failure.
  • Task: Wait for a Task to finish. If the task fails with an exception, a TaskFailedException (which wraps the failed task) is thrown. Waiting on a task additionally allows passing throw=false which prevents throwing a TaskFailedException when the task fails.
  • RawFD: Wait for changes on a file descriptor (see the FileWatching package).

If no argument is passed, the task blocks for an undefined period. A task can only be restarted by an explicit call to schedule or yieldto.

Often wait is called within a while loop to ensure a waited-for condition is met before proceeding.

source
wait(c::Channel)

Blocks until the Channel isready.

julia> c = Channel(1);
 
 julia> isready(c)
 false
@@ -116,7 +116,7 @@
 julia> put!(c, 1);
 
 julia> istaskdone(task)  # task is now unblocked
-true
source
Base.waitanyFunction
waitany(tasks; throw=true) -> (done_tasks, remaining_tasks)

Wait until at least one of the given tasks have been completed.

If throw is true, throw CompositeException when one of the completed tasks completes with an exception.

The return value consists of two task vectors. The first one consists of completed tasks, and the other consists of uncompleted tasks.

Warning

This may scale poorly compared to writing code that uses multiple individual tasks that each runs serially, since this needs to scan the list of tasks each time and synchronize with each one every time this is called. Or consider using waitall(tasks; failfast=true) instead.

source
Base.waitallFunction
waitall(tasks; failfast=true, throw=true) -> (done_tasks, remaining_tasks)

Wait until all the given tasks have been completed.

If failfast is true, the function will return when at least one of the given tasks is finished by exception. If throw is true, throw CompositeException when one of the completed tasks has failed.

failfast and throw keyword arguments work independently; when only throw=true is specified, this function waits for all the tasks to complete.

The return value consists of two task vectors. The first one consists of completed tasks, and the other consists of uncompleted tasks.

source
Base.fetchMethod
fetch(t::Task)

Wait for a Task to finish, then return its result value. If the task fails with an exception, a TaskFailedException (which wraps the failed task) is thrown.

source
Base.timedwaitFunction
timedwait(testcb, timeout::Real; pollint::Real=0.1)

Wait until testcb() returns true or timeout seconds have passed, whichever is earlier. The test function is polled every pollint seconds. The minimum value for pollint is 0.001 seconds, that is, 1 millisecond.

Return :ok or :timed_out.

Examples

julia> cb() = (sleep(5); return);
+true
source
Base.waitanyFunction
waitany(tasks; throw=true) -> (done_tasks, remaining_tasks)

Wait until at least one of the given tasks have been completed.

If throw is true, throw CompositeException when one of the completed tasks completes with an exception.

The return value consists of two task vectors. The first one consists of completed tasks, and the other consists of uncompleted tasks.

Warning

This may scale poorly compared to writing code that uses multiple individual tasks that each runs serially, since this needs to scan the list of tasks each time and synchronize with each one every time this is called. Or consider using waitall(tasks; failfast=true) instead.

source
Base.waitallFunction
waitall(tasks; failfast=true, throw=true) -> (done_tasks, remaining_tasks)

Wait until all the given tasks have been completed.

If failfast is true, the function will return when at least one of the given tasks is finished by exception. If throw is true, throw CompositeException when one of the completed tasks has failed.

failfast and throw keyword arguments work independently; when only throw=true is specified, this function waits for all the tasks to complete.

The return value consists of two task vectors. The first one consists of completed tasks, and the other consists of uncompleted tasks.

source
Base.fetchMethod
fetch(t::Task)

Wait for a Task to finish, then return its result value. If the task fails with an exception, a TaskFailedException (which wraps the failed task) is thrown.

source
Base.timedwaitFunction
timedwait(testcb, timeout::Real; pollint::Real=0.1)

Wait until testcb() returns true or timeout seconds have passed, whichever is earlier. The test function is polled every pollint seconds. The minimum value for pollint is 0.001 seconds, that is, 1 millisecond.

Return :ok or :timed_out.

Examples

julia> cb() = (sleep(5); return);
 
 julia> t = @async cb();
 
@@ -124,21 +124,21 @@
 :timed_out
 
 julia> timedwait(()->istaskdone(t), 6.5)
-:ok
source
Base.ConditionType
Condition()

Create an edge-triggered event source that tasks can wait for. Tasks that call wait on a Condition are suspended and queued. Tasks are woken up when notify is later called on the Condition. Waiting on a condition can return a value or raise an error if the optional arguments of notify are used. Edge triggering means that only tasks waiting at the time notify is called can be woken up. For level-triggered notifications, you must keep extra state to keep track of whether a notification has happened. The Channel and Threads.Event types do this, and can be used for level-triggered events.

This object is NOT thread-safe. See Threads.Condition for a thread-safe version.

source
Base.Threads.ConditionType
Threads.Condition([lock])

A thread-safe version of Base.Condition.

To call wait or notify on a Threads.Condition, you must first call lock on it. When wait is called, the lock is atomically released during blocking, and will be reacquired before wait returns. Therefore idiomatic use of a Threads.Condition c looks like the following:

lock(c)
+:ok
source
Base.ConditionType
Condition()

Create an edge-triggered event source that tasks can wait for. Tasks that call wait on a Condition are suspended and queued. Tasks are woken up when notify is later called on the Condition. Waiting on a condition can return a value or raise an error if the optional arguments of notify are used. Edge triggering means that only tasks waiting at the time notify is called can be woken up. For level-triggered notifications, you must keep extra state to keep track of whether a notification has happened. The Channel and Threads.Event types do this, and can be used for level-triggered events.

This object is NOT thread-safe. See Threads.Condition for a thread-safe version.

source
Base.Threads.ConditionType
Threads.Condition([lock])

A thread-safe version of Base.Condition.

To call wait or notify on a Threads.Condition, you must first call lock on it. When wait is called, the lock is atomically released during blocking, and will be reacquired before wait returns. Therefore idiomatic use of a Threads.Condition c looks like the following:

lock(c)
 try
     while !thing_we_are_waiting_for
         wait(c)
     end
 finally
     unlock(c)
-end
Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.EventType
Event([autoreset=false])

Create a level-triggered event source. Tasks that call wait on an Event are suspended and queued until notify is called on the Event. After notify is called, the Event remains in a signaled state and tasks will no longer block when waiting for it, until reset is called.

If autoreset is true, at most one task will be released from wait for each call to notify.

This provides an acquire & release memory ordering on notify/wait.

Julia 1.1

This functionality requires at least Julia 1.1.

Julia 1.8

The autoreset functionality and memory ordering guarantee requires at least Julia 1.8.

source
Base.notifyFunction
notify(condition, val=nothing; all=true, error=false)

Wake up tasks waiting for a condition, passing them val. If all is true (the default), all waiting tasks are woken, otherwise only one is. If error is true, the passed value is raised as an exception in the woken tasks.

Return the count of tasks woken up. Return 0 if no tasks are waiting on condition.

source
Base.resetMethod
reset(::Event)

Reset an Event back into an un-set state. Then any future calls to wait will block until notify is called again.

source
Base.SemaphoreType
Semaphore(sem_size)

Create a counting semaphore that allows at most sem_size acquires to be in use at any time. Each acquire must be matched with a release.

This provides a acquire & release memory ordering on acquire/release calls.

source
Base.acquireFunction
acquire(s::Semaphore)

Wait for one of the sem_size permits to be available, blocking until one can be acquired.

source
acquire(f, s::Semaphore)

Execute f after acquiring from Semaphore s, and release on completion or error.

For example, a do-block form that ensures only 2 calls of foo will be active at the same time:

s = Base.Semaphore(2)
+end
Julia 1.2

This functionality requires at least Julia 1.2.

source
Base.EventType
Event([autoreset=false])

Create a level-triggered event source. Tasks that call wait on an Event are suspended and queued until notify is called on the Event. After notify is called, the Event remains in a signaled state and tasks will no longer block when waiting for it, until reset is called.

If autoreset is true, at most one task will be released from wait for each call to notify.

This provides an acquire & release memory ordering on notify/wait.

Julia 1.1

This functionality requires at least Julia 1.1.

Julia 1.8

The autoreset functionality and memory ordering guarantee requires at least Julia 1.8.

source
Base.notifyFunction
notify(condition, val=nothing; all=true, error=false)

Wake up tasks waiting for a condition, passing them val. If all is true (the default), all waiting tasks are woken, otherwise only one is. If error is true, the passed value is raised as an exception in the woken tasks.

Return the count of tasks woken up. Return 0 if no tasks are waiting on condition.

source
Base.resetMethod
reset(::Event)

Reset an Event back into an un-set state. Then any future calls to wait will block until notify is called again.

source
Base.SemaphoreType
Semaphore(sem_size)

Create a counting semaphore that allows at most sem_size acquires to be in use at any time. Each acquire must be matched with a release.

This provides a acquire & release memory ordering on acquire/release calls.

source
Base.acquireFunction
acquire(s::Semaphore)

Wait for one of the sem_size permits to be available, blocking until one can be acquired.

source
acquire(f, s::Semaphore)

Execute f after acquiring from Semaphore s, and release on completion or error.

For example, a do-block form that ensures only 2 calls of foo will be active at the same time:

s = Base.Semaphore(2)
 @sync for _ in 1:100
     Threads.@spawn begin
         Base.acquire(s) do
             foo()
         end
     end
-end
Julia 1.8

This method requires at least Julia 1.8.

source
Base.releaseFunction
release(s::Semaphore)

Return one permit to the pool, possibly allowing another task to acquire it and resume execution.

source
Base.lockFunction
lock(lock)

Acquire the lock when it becomes available. If the lock is already locked by a different task/thread, wait for it to become available.

Each lock must be matched by an unlock.

source
lock(f::Function, lock)

Acquire the lock, execute f with the lock held, and release the lock when f returns. If the lock is already locked by a different task/thread, wait for it to become available.

When this function returns, the lock has been released, so the caller should not attempt to unlock it.

See also: @lock.

Julia 1.7

Using a Channel as the second argument requires Julia 1.7 or later.

source

lock(f::Function, l::Lockable)

Acquire the lock associated with l, execute f with the lock held, and release the lock when f returns. f will receive one positional argument: the value wrapped by l. If the lock is already locked by a different task/thread, wait for it to become available. When this function returns, the lock has been released, so the caller should not attempt to unlock it.

Julia 1.11

Requires at least Julia 1.11.

source
Base.unlockFunction
unlock(lock)

Releases ownership of the lock.

If this is a recursive lock which has been acquired before, decrement an internal counter and return immediately.

source
Base.trylockFunction
trylock(lock) -> Success (Boolean)

Acquire the lock if it is available, and return true if successful. If the lock is already locked by a different task/thread, return false.

Each successful trylock must be matched by an unlock.

Function trylock combined with islocked can be used for writing the test-and-test-and-set or exponential backoff algorithms if it is supported by the typeof(lock) (read its documentation).

source
Base.islockedFunction
islocked(lock) -> Status (Boolean)

Check whether the lock is held by any task/thread. This function alone should not be used for synchronization. However, islocked combined with trylock can be used for writing the test-and-test-and-set or exponential backoff algorithms if it is supported by the typeof(lock) (read its documentation).

Extended help

For example, an exponential backoff can be implemented as follows if the lock implementation satisfied the properties documented below.

nspins = 0
+end
Julia 1.8

This method requires at least Julia 1.8.

source
Base.releaseFunction
release(s::Semaphore)

Return one permit to the pool, possibly allowing another task to acquire it and resume execution.

source
Base.lockFunction
lock(lock)

Acquire the lock when it becomes available. If the lock is already locked by a different task/thread, wait for it to become available.

Each lock must be matched by an unlock.

source
lock(f::Function, lock)

Acquire the lock, execute f with the lock held, and release the lock when f returns. If the lock is already locked by a different task/thread, wait for it to become available.

When this function returns, the lock has been released, so the caller should not attempt to unlock it.

See also: @lock.

Julia 1.7

Using a Channel as the second argument requires Julia 1.7 or later.

source

lock(f::Function, l::Lockable)

Acquire the lock associated with l, execute f with the lock held, and release the lock when f returns. f will receive one positional argument: the value wrapped by l. If the lock is already locked by a different task/thread, wait for it to become available. When this function returns, the lock has been released, so the caller should not attempt to unlock it.

Julia 1.11

Requires at least Julia 1.11.

source
Base.unlockFunction
unlock(lock)

Releases ownership of the lock.

If this is a recursive lock which has been acquired before, decrement an internal counter and return immediately.

source
Base.trylockFunction
trylock(lock) -> Success (Boolean)

Acquire the lock if it is available, and return true if successful. If the lock is already locked by a different task/thread, return false.

Each successful trylock must be matched by an unlock.

Function trylock combined with islocked can be used for writing the test-and-test-and-set or exponential backoff algorithms if it is supported by the typeof(lock) (read its documentation).

source
Base.islockedFunction
islocked(lock) -> Status (Boolean)

Check whether the lock is held by any task/thread. This function alone should not be used for synchronization. However, islocked combined with trylock can be used for writing the test-and-test-and-set or exponential backoff algorithms if it is supported by the typeof(lock) (read its documentation).

Extended help

For example, an exponential backoff can be implemented as follows if the lock implementation satisfied the properties documented below.

nspins = 0
 while true
     while islocked(lock)
         GC.safepoint()
@@ -147,24 +147,24 @@
     end
     trylock(lock) && break
     backoff()
-end

Implementation

A lock implementation is advised to define islocked with the following properties and note it in its docstring.

  • islocked(lock) is data-race-free.
  • If islocked(lock) returns false, an immediate invocation of trylock(lock) must succeed (returns true) if there is no interference from other tasks.
source
Base.ReentrantLockType
ReentrantLock()

Creates a re-entrant lock for synchronizing Tasks. The same task can acquire the lock as many times as required (this is what the "Reentrant" part of the name means). Each lock must be matched with an unlock.

Calling lock will also inhibit running of finalizers on that thread until the corresponding unlock. Use of the standard lock pattern illustrated below should naturally be supported, but beware of inverting the try/lock order or missing the try block entirely (e.g. attempting to return with the lock still held):

This provides a acquire/release memory ordering on lock/unlock calls.

lock(l)
+end

Implementation

A lock implementation is advised to define islocked with the following properties and note it in its docstring.

  • islocked(lock) is data-race-free.
  • If islocked(lock) returns false, an immediate invocation of trylock(lock) must succeed (returns true) if there is no interference from other tasks.
source
Base.ReentrantLockType
ReentrantLock()

Creates a re-entrant lock for synchronizing Tasks. The same task can acquire the lock as many times as required (this is what the "Reentrant" part of the name means). Each lock must be matched with an unlock.

Calling lock will also inhibit running of finalizers on that thread until the corresponding unlock. Use of the standard lock pattern illustrated below should naturally be supported, but beware of inverting the try/lock order or missing the try block entirely (e.g. attempting to return with the lock still held):

This provides a acquire/release memory ordering on lock/unlock calls.

lock(l)
 try
     <atomic work>
 finally
     unlock(l)
-end

If !islocked(lck::ReentrantLock) holds, trylock(lck) succeeds unless there are other tasks attempting to hold the lock "at the same time."

source
Base.@lockMacro
@lock l expr

Macro version of lock(f, l::AbstractLock) but with expr instead of f function. Expands to:

lock(l)
 try
     expr
 finally
     unlock(l)
-end

This is similar to using lock with a do block, but avoids creating a closure and thus can improve the performance.

Compat

@lock was added in Julia 1.3, and exported in Julia 1.10.

source
Base.LockableType

Lockable(value, lock = ReentrantLock())

Creates a Lockable object that wraps value and associates it with the provided lock. This object supports @lock, lock, trylock, unlock. To access the value, index the lockable object while holding the lock.

Julia 1.11

Requires at least Julia 1.11.

Example

julia> locked_list = Base.Lockable(Int[]);
+end

This is similar to using lock with a do block, but avoids creating a closure and thus can improve the performance.

Compat

@lock was added in Julia 1.3, and exported in Julia 1.10.

source
Base.LockableType

Lockable(value, lock = ReentrantLock())

Creates a Lockable object that wraps value and associates it with the provided lock. This object supports @lock, lock, trylock, unlock. To access the value, index the lockable object while holding the lock.

Julia 1.11

Requires at least Julia 1.11.

Example

julia> locked_list = Base.Lockable(Int[]);
 
 julia> @lock(locked_list, push!(locked_list[], 1)) # must hold the lock to access the value
 1-element Vector{Int64}:
  1
 
 julia> lock(summary, locked_list)
-"1-element Vector{Int64}"
source

Channels

Base.ChannelType
Channel{T=Any}(size::Int=0)

Constructs a Channel with an internal buffer that can hold a maximum of size objects of type T. put! calls on a full channel block until an object is removed with take!.

Channel(0) constructs an unbuffered channel. put! blocks until a matching take! is called. And vice-versa.

Other constructors:

  • Channel(): default constructor, equivalent to Channel{Any}(0)
  • Channel(Inf): equivalent to Channel{Any}(typemax(Int))
  • Channel(sz): equivalent to Channel{Any}(sz)
Julia 1.3

The default constructor Channel() and default size=0 were added in Julia 1.3.

source
Base.ChannelMethod
Channel{T=Any}(func::Function, size=0; taskref=nothing, spawn=false, threadpool=nothing)

Create a new task from func, bind it to a new channel of type T and size size, and schedule the task, all in a single call. The channel is automatically closed when the task terminates.

func must accept the bound channel as its only argument.

If you need a reference to the created task, pass a Ref{Task} object via the keyword argument taskref.

If spawn=true, the Task created for func may be scheduled on another thread in parallel, equivalent to creating a task via Threads.@spawn.

If spawn=true and the threadpool argument is not set, it defaults to :default.

If the threadpool argument is set (to :default or :interactive), this implies that spawn=true and the new Task is spawned to the specified threadpool.

Return a Channel.

Examples

julia> chnl = Channel() do ch
+"1-element Vector{Int64}"
source

Channels

Base.ChannelType
Channel{T=Any}(size::Int=0)

Constructs a Channel with an internal buffer that can hold a maximum of size objects of type T. put! calls on a full channel block until an object is removed with take!.

Channel(0) constructs an unbuffered channel. put! blocks until a matching take! is called. And vice-versa.

Other constructors:

  • Channel(): default constructor, equivalent to Channel{Any}(0)
  • Channel(Inf): equivalent to Channel{Any}(typemax(Int))
  • Channel(sz): equivalent to Channel{Any}(sz)
Julia 1.3

The default constructor Channel() and default size=0 were added in Julia 1.3.

source
Base.ChannelMethod
Channel{T=Any}(func::Function, size=0; taskref=nothing, spawn=false, threadpool=nothing)

Create a new task from func, bind it to a new channel of type T and size size, and schedule the task, all in a single call. The channel is automatically closed when the task terminates.

func must accept the bound channel as its only argument.

If you need a reference to the created task, pass a Ref{Task} object via the keyword argument taskref.

If spawn=true, the Task created for func may be scheduled on another thread in parallel, equivalent to creating a task via Threads.@spawn.

If spawn=true and the threadpool argument is not set, it defaults to :default.

If the threadpool argument is set (to :default or :interactive), this implies that spawn=true and the new Task is spawned to the specified threadpool.

Return a Channel.

Examples

julia> chnl = Channel() do ch
            foreach(i -> put!(ch, i), 1:4)
        end;
 
@@ -198,7 +198,7 @@
 Channel{Char}(1) (2 items available)
 
 julia> String(collect(chnl))
-"hello world"
source
Base.put!Method
put!(c::Channel, v)

Append an item v to the channel c. Blocks if the channel is full.

For unbuffered channels, blocks until a take! is performed by a different task.

Julia 1.1

v now gets converted to the channel's type with convert as put! is called.

source
Base.take!Method
take!(c::Channel)

Removes and returns a value from a Channel in order. Blocks until data is available. For unbuffered channels, blocks until a put! is performed by a different task.

Examples

Buffered channel:

julia> c = Channel(1);
+"hello world"
source
Base.put!Method
put!(c::Channel, v)

Append an item v to the channel c. Blocks if the channel is full.

For unbuffered channels, blocks until a take! is performed by a different task.

Julia 1.1

v now gets converted to the channel's type with convert as put! is called.

source
Base.take!Method
take!(c::Channel)

Removes and returns a value from a Channel in order. Blocks until data is available. For unbuffered channels, blocks until a put! is performed by a different task.

Examples

Buffered channel:

julia> c = Channel(1);
 
 julia> put!(c, 1);
 
@@ -210,7 +210,7 @@
 julia> schedule(task);
 
 julia> take!(c)
-1
source
Base.isfullMethod
isfull(c::Channel)

Determines if a Channel is full, in the sense that calling put!(c, some_value) would have blocked. Returns immediately, does not block.

Note that it may frequently be the case that put! will not block after this returns true. Users must take precautions not to accidentally create live-lock bugs in their code by calling this method, as these are generally harder to debug than deadlocks. It is also possible that put! will block after this call returns false, if there are multiple producer tasks calling put! in parallel.

Examples

Buffered channel:

julia> c = Channel(1); # capacity = 1
+1
source
Base.isfullMethod
isfull(c::Channel)

Determines if a Channel is full, in the sense that calling put!(c, some_value) would have blocked. Returns immediately, does not block.

Note that it may frequently be the case that put! will not block after this returns true. Users must take precautions not to accidentally create live-lock bugs in their code by calling this method, as these are generally harder to debug than deadlocks. It is also possible that put! will block after this call returns false, if there are multiple producer tasks calling put! in parallel.

Examples

Buffered channel:

julia> c = Channel(1); # capacity = 1
 
 julia> isfull(c)
 false
@@ -221,7 +221,7 @@
 true

Unbuffered channel:

julia> c = Channel(); # capacity = 0
 
 julia> isfull(c) # unbuffered channel is always full
-true
source
Base.isreadyMethod
isready(c::Channel)

Determines whether a Channel has a value stored in it. Returns immediately, does not block.

For unbuffered channels, return true if there are tasks waiting on a put!.

Examples

Buffered channel:

julia> c = Channel(1);
+true
source
Base.isreadyMethod
isready(c::Channel)

Determines whether a Channel has a value stored in it. Returns immediately, does not block.

For unbuffered channels, return true if there are tasks waiting on a put!.

Examples

Buffered channel:

julia> c = Channel(1);
 
 julia> isready(c)
 false
@@ -239,7 +239,7 @@
 julia> schedule(task);  # schedule a put! task
 
 julia> isready(c)
-true
source
Base.fetchMethod
fetch(c::Channel)

Waits for and returns (without removing) the first available item from the Channel. Note: fetch is unsupported on an unbuffered (0-size) Channel.

Examples

Buffered channel:

julia> c = Channel(3) do ch
+true
source
Base.fetchMethod
fetch(c::Channel)

Waits for and returns (without removing) the first available item from the Channel. Note: fetch is unsupported on an unbuffered (0-size) Channel.

Examples

Buffered channel:

julia> c = Channel(3) do ch
            foreach(i -> put!(ch, i), 1:3)
        end;
 
@@ -250,7 +250,7 @@
 3-element Vector{Any}:
  1
  2
- 3
source
Base.closeMethod
close(c::Channel[, excp::Exception])

Close a channel. An exception (optionally given by excp), is thrown by:

source
Base.bindMethod
bind(chnl::Channel, task::Task)

Associate the lifetime of chnl with a task. Channel chnl is automatically closed when the task terminates. Any uncaught exception in the task is propagated to all waiters on chnl.

The chnl object can be explicitly closed independent of task termination. Terminating tasks have no effect on already closed Channel objects.

When a channel is bound to multiple tasks, the first task to terminate will close the channel. When multiple channels are bound to the same task, termination of the task will close all of the bound channels.

Examples

julia> c = Channel(0);
+ 3
source
Base.closeMethod
close(c::Channel[, excp::Exception])

Close a channel. An exception (optionally given by excp), is thrown by:

source
Base.bindMethod
bind(chnl::Channel, task::Task)

Associate the lifetime of chnl with a task. Channel chnl is automatically closed when the task terminates. Any uncaught exception in the task is propagated to all waiters on chnl.

The chnl object can be explicitly closed independent of task termination. Terminating tasks have no effect on already closed Channel objects.

When a channel is bound to multiple tasks, the first task to terminate will close the channel. When multiple channels are bound to the same task, termination of the task will close all of the bound channels.

Examples

julia> c = Channel(0);
 
 julia> task = @async foreach(i->put!(c, i), 1:4);
 
@@ -279,7 +279,7 @@
 Stacktrace:
 [...]
     nested task error: foo
-[...]
source

Low-level synchronization using schedule and wait

The easiest correct use of schedule is on a Task that is not started (scheduled) yet. However, it is possible to use schedule and wait as a very low-level building block for constructing synchronization interfaces. A crucial pre-condition of calling schedule(task) is that the caller must "own" the task; i.e., it must know that the call to wait in the given task is happening at the locations known to the code calling schedule(task). One strategy for ensuring such pre-condition is to use atomics, as demonstrated in the following example:

@enum OWEState begin
+[...]
source

Low-level synchronization using schedule and wait

The easiest correct use of schedule is on a Task that is not started (scheduled) yet. However, it is possible to use schedule and wait as a very low-level building block for constructing synchronization interfaces. A crucial pre-condition of calling schedule(task) is that the caller must "own" the task; i.e., it must know that the call to wait in the given task is happening at the locations known to the code calling schedule(task). One strategy for ensuring such pre-condition is to use atomics, as demonstrated in the following example:

@enum OWEState begin
     OWE_EMPTY
     OWE_WAITING
     OWE_NOTIFYING
@@ -344,4 +344,4 @@
 
 # output
 notifying...
-done

OneWayEvent lets one task to wait for another task's notify. It is a limited communication interface since wait can only be used once from a single task (note the non-atomic assignment of ev.task)

In this example, notify(ev::OneWayEvent) is allowed to call schedule(ev.task) if and only if it modifies the state from OWE_WAITING to OWE_NOTIFYING. This lets us know that the task executing wait(ev::OneWayEvent) is now in the ok branch and that there cannot be other tasks that tries to schedule(ev.task) since their @atomicreplace(ev.state, state => OWE_NOTIFYING) will fail.

+done

OneWayEvent lets one task to wait for another task's notify. It is a limited communication interface since wait can only be used once from a single task (note the non-atomic assignment of ev.task)

In this example, notify(ev::OneWayEvent) is allowed to call schedule(ev.task) if and only if it modifies the state from OWE_WAITING to OWE_NOTIFYING. This lets us know that the task executing wait(ev::OneWayEvent) is now in the ok branch and that there cannot be other tasks that tries to schedule(ev.task) since their @atomicreplace(ev.state, state => OWE_NOTIFYING) will fail.

diff --git a/en/v1.12-dev/base/punctuation/index.html b/en/v1.12-dev/base/punctuation/index.html index 610732831565..a4d885476d48 100644 --- a/en/v1.12-dev/base/punctuation/index.html +++ b/en/v1.12-dev/base/punctuation/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Punctuation

Extended documentation for mathematical symbols & functions is here.

symbolmeaning
@the at-sign marks a macro invocation; optionally followed by an argument list
!an exclamation mark is a prefix operator for logical negation ("not")
a!function names that end with an exclamation mark modify one or more of their arguments by convention
#the number sign (or hash or pound) character begins single line comments
#=when followed by an equals sign, it begins a multi-line comment (these are nestable)
=#end a multi-line comment by immediately preceding the number sign with an equals sign
$the dollar sign is used for string and expression interpolation
%the percent symbol is the remainder operator
^the caret is the exponentiation operator
&single ampersand is bitwise and
&&double ampersands is short-circuiting boolean and
|single pipe character is bitwise or
||double pipe characters is short-circuiting boolean or
the unicode xor character is bitwise exclusive or
~the tilde is an operator for bitwise not
'a trailing apostrophe is the adjoint (that is, the complex transpose) operator Aᴴ
*the asterisk is used for multiplication, including matrix multiplication and string concatenation
/forward slash divides the argument on its left by the one on its right
\backslash operator divides the argument on its right by the one on its left, commonly used to solve matrix equations
()parentheses with no arguments constructs an empty Tuple
(a,...)parentheses with comma-separated arguments constructs a tuple containing its arguments
(a=1,...)parentheses with comma-separated assignments constructs a NamedTuple
(x;y)parentheses can also be used to group one or more semicolon separated expressions
a[]array indexing (calling getindex or setindex!)
[,]vector literal constructor (calling vect)
[;]vertical concatenation (calling vcat or hvcat)
[ ]with space-separated expressions, horizontal concatenation (calling hcat or hvcat)
T{ }curly braces following a type list that type's parameters
{}curly braces can also be used to group multiple where expressions in function declarations
;semicolons separate statements, begin a list of keyword arguments in function declarations or calls, or are used to separate array literals for vertical concatenation
,commas separate function arguments or tuple or array components
?the question mark delimits the ternary conditional operator (used like: conditional ? if_true : if_false)
" "the single double-quote character delimits String literals
""" """three double-quote characters delimits string literals that may contain " and ignore leading indentation
' 'the single-quote character delimits Char (that is, character) literals
` `the backtick character delimits external process (Cmd) literals
A...triple periods are a postfix operator that "splat" their arguments' contents into many arguments of a function call or declare a varargs function that "slurps" up many arguments into a single tuple
a.bsingle periods access named fields in objects/modules (calling getproperty or setproperty!)
f.()periods may also prefix parentheses (like f.(...)) or infix operators (like .+) to perform the function element-wise (calling broadcast)
a:bcolons (:) used as a binary infix operator construct a range from a to b (inclusive) with fixed step size 1
a:s:bcolons (:) used as a ternary infix operator construct a range from a to b (inclusive) with step size s
:when used by themselves, Colons represent all indices within a dimension, frequently combined with indexing
::double-colons represent a type annotation or typeassert, depending on context, frequently used when declaring function arguments
:( )quoted expression
:aSymbol a
<:subtype operator
>:supertype operator (reverse of subtype operator)
=single equals sign is assignment
==double equals sign is value equality comparison
===triple equals sign is programmatically identical equality comparison
=>right arrow using an equals sign defines a Pair typically used to populate dictionaries
->right arrow using a hyphen defines an anonymous function on a single line
|>pipe operator passes output from the left argument to input of the right argument, usually a function
function composition operator (typed with \circ{tab}) combines two functions as though they are a single larger function
_underscores may be assigned values which will not be saved, often used to ignore multiple return values or create repetitive comprehensions
+

Punctuation

Extended documentation for mathematical symbols & functions is here.

symbolmeaning
@the at-sign marks a macro invocation; optionally followed by an argument list
!an exclamation mark is a prefix operator for logical negation ("not")
a!function names that end with an exclamation mark modify one or more of their arguments by convention
#the number sign (or hash or pound) character begins single line comments
#=when followed by an equals sign, it begins a multi-line comment (these are nestable)
=#end a multi-line comment by immediately preceding the number sign with an equals sign
$the dollar sign is used for string and expression interpolation
%the percent symbol is the remainder operator
^the caret is the exponentiation operator
&single ampersand is bitwise and
&&double ampersands is short-circuiting boolean and
|single pipe character is bitwise or
||double pipe characters is short-circuiting boolean or
the unicode xor character is bitwise exclusive or
~the tilde is an operator for bitwise not
'a trailing apostrophe is the adjoint (that is, the complex transpose) operator Aᴴ
*the asterisk is used for multiplication, including matrix multiplication and string concatenation
/forward slash divides the argument on its left by the one on its right
\backslash operator divides the argument on its right by the one on its left, commonly used to solve matrix equations
()parentheses with no arguments constructs an empty Tuple
(a,...)parentheses with comma-separated arguments constructs a tuple containing its arguments
(a=1,...)parentheses with comma-separated assignments constructs a NamedTuple
(x;y)parentheses can also be used to group one or more semicolon separated expressions
a[]array indexing (calling getindex or setindex!)
[,]vector literal constructor (calling vect)
[;]vertical concatenation (calling vcat or hvcat)
[ ]with space-separated expressions, horizontal concatenation (calling hcat or hvcat)
T{ }curly braces following a type list that type's parameters
{}curly braces can also be used to group multiple where expressions in function declarations
;semicolons separate statements, begin a list of keyword arguments in function declarations or calls, or are used to separate array literals for vertical concatenation
,commas separate function arguments or tuple or array components
?the question mark delimits the ternary conditional operator (used like: conditional ? if_true : if_false)
" "the single double-quote character delimits String literals
""" """three double-quote characters delimits string literals that may contain " and ignore leading indentation
' 'the single-quote character delimits Char (that is, character) literals
` `the backtick character delimits external process (Cmd) literals
A...triple periods are a postfix operator that "splat" their arguments' contents into many arguments of a function call or declare a varargs function that "slurps" up many arguments into a single tuple
a.bsingle periods access named fields in objects/modules (calling getproperty or setproperty!)
f.()periods may also prefix parentheses (like f.(...)) or infix operators (like .+) to perform the function element-wise (calling broadcast)
a:bcolons (:) used as a binary infix operator construct a range from a to b (inclusive) with fixed step size 1
a:s:bcolons (:) used as a ternary infix operator construct a range from a to b (inclusive) with step size s
:when used by themselves, Colons represent all indices within a dimension, frequently combined with indexing
::double-colons represent a type annotation or typeassert, depending on context, frequently used when declaring function arguments
:( )quoted expression
:aSymbol a
<:subtype operator
>:supertype operator (reverse of subtype operator)
=single equals sign is assignment
==double equals sign is value equality comparison
===triple equals sign is programmatically identical equality comparison
=>right arrow using an equals sign defines a Pair typically used to populate dictionaries
->right arrow using a hyphen defines an anonymous function on a single line
|>pipe operator passes output from the left argument to input of the right argument, usually a function
function composition operator (typed with \circ{tab}) combines two functions as though they are a single larger function
_underscores may be assigned values which will not be saved, often used to ignore multiple return values or create repetitive comprehensions
diff --git a/en/v1.12-dev/base/reflection/index.html b/en/v1.12-dev/base/reflection/index.html index b3bcb2860f51..8956874baf8f 100644 --- a/en/v1.12-dev/base/reflection/index.html +++ b/en/v1.12-dev/base/reflection/index.html @@ -36,4 +36,4 @@ @ int.jl:87 within `+` 1 ─ %1 = Base.add_int(x, y)::Int64 └── return %1 -) => Int64

Possible values for debuginfo are: :none, :source, and :default. Per default debug information is not printed, but that can be changed by setting Base.IRShow.default_debuginfo[] = :source.

+) => Int64

Possible values for debuginfo are: :none, :source, and :default. Per default debug information is not printed, but that can be changed by setting Base.IRShow.default_debuginfo[] = :source.

diff --git a/en/v1.12-dev/base/scopedvalues/index.html b/en/v1.12-dev/base/scopedvalues/index.html index 116be5151021..1df9d5164c1e 100644 --- a/en/v1.12-dev/base/scopedvalues/index.html +++ b/en/v1.12-dev/base/scopedvalues/index.html @@ -153,7 +153,7 @@ 2 julia> sval[] -1
Julia 1.11

Scoped values were introduced in Julia 1.11. In Julia 1.8+ a compatible implementation is available from the package ScopedValues.jl.

source
Base.ScopedValues.withFunction
with(f, (var::ScopedValue{T} => val)...)

Execute f in a new dynamic scope with var set to val. val will be converted to type T.

See also: ScopedValues.@with, ScopedValues.ScopedValue, ScopedValues.get.

Examples

julia> using Base.ScopedValues
+1
Julia 1.11

Scoped values were introduced in Julia 1.11. In Julia 1.8+ a compatible implementation is available from the package ScopedValues.jl.

source
Base.ScopedValues.withFunction
with(f, (var::ScopedValue{T} => val)...)

Execute f in a new dynamic scope with var set to val. val will be converted to type T.

See also: ScopedValues.@with, ScopedValues.ScopedValue, ScopedValues.get.

Examples

julia> using Base.ScopedValues
 
 julia> a = ScopedValue(1);
 
@@ -180,7 +180,7 @@
 60
 
 julia> with(() -> a[] * b[], a=>3, b=>4)
-12
source
Base.ScopedValues.@withMacro
@with (var::ScopedValue{T} => val)... expr

Macro version of with. The expression @with var=>val expr evaluates expr in a new dynamic scope with var set to val. val will be converted to type T. @with var=>val expr is equivalent to with(var=>val) do expr end, but @with avoids creating a closure.

See also: ScopedValues.with, ScopedValues.ScopedValue, ScopedValues.get.

Examples

julia> using Base.ScopedValues
+12
source
Base.ScopedValues.@withMacro
@with (var::ScopedValue{T} => val)... expr

Macro version of with. The expression @with var=>val expr evaluates expr in a new dynamic scope with var set to val. val will be converted to type T. @with var=>val expr is equivalent to with(var=>val) do expr end, but @with avoids creating a closure.

See also: ScopedValues.with, ScopedValues.ScopedValue, ScopedValues.get.

Examples

julia> using Base.ScopedValues
 
 julia> const a = ScopedValue(1);
 
@@ -193,7 +193,7 @@
            x = 100
            f(x)
        end
-103
source
Base.isassignedMethod
isassigned(val::ScopedValue)

Test whether a ScopedValue has an assigned value.

See also: ScopedValues.with, ScopedValues.@with, ScopedValues.get.

Examples

julia> using Base.ScopedValues
+103
source
Base.isassignedMethod
isassigned(val::ScopedValue)

Test whether a ScopedValue has an assigned value.

See also: ScopedValues.with, ScopedValues.@with, ScopedValues.get.

Examples

julia> using Base.ScopedValues
 
 julia> a = ScopedValue(1); b = ScopedValue{Int}();
 
@@ -201,7 +201,7 @@
 true
 
 julia> isassigned(b)
-false
source
Base.ScopedValues.getFunction
get(val::ScopedValue{T})::Union{Nothing, Some{T}}

If the scoped value isn't set and doesn't have a default value, return nothing. Otherwise returns Some{T} with the current value.

See also: ScopedValues.with, ScopedValues.@with, ScopedValues.ScopedValue.

Examples

julia> using Base.ScopedValues
+false
source
Base.ScopedValues.getFunction
get(val::ScopedValue{T})::Union{Nothing, Some{T}}

If the scoped value isn't set and doesn't have a default value, return nothing. Otherwise returns Some{T} with the current value.

See also: ScopedValues.with, ScopedValues.@with, ScopedValues.ScopedValue.

Examples

julia> using Base.ScopedValues
 
 julia> a = ScopedValue(42); b = ScopedValue{Int}();
 
@@ -209,4 +209,4 @@
 Some(42)
 
 julia> isnothing(ScopedValues.get(b))
-true
source

Implementation notes and performance

Scopes use a persistent dictionary. Lookup and insertion is O(log(32, n)), upon dynamic scope entry a small amount of data is copied and the unchanged data is shared among other scopes.

The Scope object itself is not user-facing and may be changed in a future version of Julia.

Design inspiration

This design was heavily inspired by JEPS-429, which in turn was inspired by dynamically scoped free variables in many Lisp dialects. In particular Interlisp-D and its deep binding strategy.

A prior design discussed was context variables ala PEPS-567 and implemented in Julia as ContextVariablesX.jl.

+truesource

Implementation notes and performance

Scopes use a persistent dictionary. Lookup and insertion is O(log(32, n)), upon dynamic scope entry a small amount of data is copied and the unchanged data is shared among other scopes.

The Scope object itself is not user-facing and may be changed in a future version of Julia.

Design inspiration

This design was heavily inspired by JEPS-429, which in turn was inspired by dynamically scoped free variables in many Lisp dialects. In particular Interlisp-D and its deep binding strategy.

A prior design discussed was context variables ala PEPS-567 and implemented in Julia as ContextVariablesX.jl.

diff --git a/en/v1.12-dev/base/simd-types/index.html b/en/v1.12-dev/base/simd-types/index.html index 5586ba5bb1da..118b77aa77cc 100644 --- a/en/v1.12-dev/base/simd-types/index.html +++ b/en/v1.12-dev/base/simd-types/index.html @@ -16,4 +16,4 @@ triple(c::m128) = add(add(c,c),c) -code_native(triple,(m128,))

However, since the automatic vectorization cannot be relied upon, future use will mostly be via libraries that use llvmcall.

+code_native(triple,(m128,))

However, since the automatic vectorization cannot be relied upon, future use will mostly be via libraries that use llvmcall.

diff --git a/en/v1.12-dev/base/sort/index.html b/en/v1.12-dev/base/sort/index.html index 1af5079ca2b9..c0193060acf0 100644 --- a/en/v1.12-dev/base/sort/index.html +++ b/en/v1.12-dev/base/sort/index.html @@ -104,7 +104,7 @@ NaN 1.0 NaN - 3.0source
sort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Sort the multidimensional array A along dimension dims. See the one-dimensional version of sort! for a description of possible keyword arguments.

To sort slices of an array, refer to sortslices.

Julia 1.1

This function requires at least Julia 1.1.

Examples

julia> A = [4 3; 1 2]
+   3.0
source
sort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Sort the multidimensional array A along dimension dims. See the one-dimensional version of sort! for a description of possible keyword arguments.

To sort slices of an array, refer to sortslices.

Julia 1.1

This function requires at least Julia 1.1.

Examples

julia> A = [4 3; 1 2]
 2×2 Matrix{Int64}:
  4  3
  1  2
@@ -117,7 +117,7 @@
 julia> sort!(A, dims = 2); A
 2×2 Matrix{Int64}:
  1  2
- 3  4
source
Base.sortFunction
sort(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Variant of sort! that returns a sorted copy of v leaving v itself unmodified.

Examples

julia> v = [3, 1, 2];
+ 3  4
source
Base.sortFunction
sort(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Variant of sort! that returns a sorted copy of v leaving v itself unmodified.

Examples

julia> v = [3, 1, 2];
 
 julia> sort(v)
 3-element Vector{Int64}:
@@ -129,7 +129,7 @@
 3-element Vector{Int64}:
  3
  1
- 2
source
sort(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Sort a multidimensional array A along the given dimension. See sort! for a description of possible keyword arguments.

To sort slices of an array, refer to sortslices.

Examples

julia> A = [4 3; 1 2]
+ 2
source
sort(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Sort a multidimensional array A along the given dimension. See sort! for a description of possible keyword arguments.

To sort slices of an array, refer to sortslices.

Examples

julia> A = [4 3; 1 2]
 2×2 Matrix{Int64}:
  4  3
  1  2
@@ -142,7 +142,7 @@
 julia> sort(A, dims = 2)
 2×2 Matrix{Int64}:
  3  4
- 1  2
source
Base.sortpermFunction
sortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])

Return a permutation vector or array I that puts A[I] in sorted order along the given dimension. If A has more than one dimension, then the dims keyword argument must be specified. The order is specified using the same keywords as sort!. The permutation is guaranteed to be stable even if the sorting algorithm is unstable: the indices of equal elements will appear in ascending order.

See also sortperm!, partialsortperm, invperm, indexin. To sort slices of an array, refer to sortslices.

Julia 1.9

The method accepting dims requires at least Julia 1.9.

Examples

julia> v = [3, 1, 2];
+ 1  2
source
Base.sortpermFunction
sortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])

Return a permutation vector or array I that puts A[I] in sorted order along the given dimension. If A has more than one dimension, then the dims keyword argument must be specified. The order is specified using the same keywords as sort!. The permutation is guaranteed to be stable even if the sorting algorithm is unstable: the indices of equal elements will appear in ascending order.

See also sortperm!, partialsortperm, invperm, indexin. To sort slices of an array, refer to sortslices.

Julia 1.9

The method accepting dims requires at least Julia 1.9.

Examples

julia> v = [3, 1, 2];
 
 julia> p = sortperm(v)
 3-element Vector{Int64}:
@@ -169,7 +169,7 @@
 julia> sortperm(A, dims = 2)
 2×2 Matrix{Int64}:
  3  1
- 2  4
source
Base.Sort.InsertionSortConstant
InsertionSort

Use the insertion sort algorithm.

Insertion sort traverses the collection one element at a time, inserting each element into its correct, sorted position in the output vector.

Characteristics:

  • stable: preserves the ordering of elements that compare equal

(e.g. "a" and "A" in a sort of letters that ignores case).

  • in-place in memory.
  • quadratic performance in the number of elements to be sorted:

it is well-suited to small collections but should not be used for large ones.

source
Base.Sort.MergeSortConstant
MergeSort

Indicate that a sorting function should use the merge sort algorithm. Merge sort divides the collection into subcollections and repeatedly merges them, sorting each subcollection at each step, until the entire collection has been recombined in sorted form.

Characteristics:

  • stable: preserves the ordering of elements that compare equal (e.g. "a" and "A" in a sort of letters that ignores case).
  • not in-place in memory.
  • divide-and-conquer sort strategy.
  • good performance for large collections but typically not quite as fast as QuickSort.
source
Base.Sort.QuickSortConstant
QuickSort

Indicate that a sorting function should use the quick sort algorithm, which is not stable.

Characteristics:

  • not stable: does not preserve the ordering of elements that compare equal (e.g. "a" and "A" in a sort of letters that ignores case).
  • in-place in memory.
  • divide-and-conquer: sort strategy similar to MergeSort.
  • good performance for large collections.
source
Base.Sort.PartialQuickSortType
PartialQuickSort{T <: Union{Integer,OrdinalRange}}

Indicate that a sorting function should use the partial quick sort algorithm. PartialQuickSort(k) is like QuickSort, but is only required to find and sort the elements that would end up in v[k] were v fully sorted.

Characteristics:

  • not stable: does not preserve the ordering of elements that compare equal (e.g. "a" and "A" in a sort of letters that ignores case).
  • in-place in memory.
  • divide-and-conquer: sort strategy similar to MergeSort.

Note that PartialQuickSort(k) does not necessarily sort the whole array. For example,

julia> x = rand(100);
+ 2  4
source
Base.Sort.InsertionSortConstant
InsertionSort

Use the insertion sort algorithm.

Insertion sort traverses the collection one element at a time, inserting each element into its correct, sorted position in the output vector.

Characteristics:

  • stable: preserves the ordering of elements that compare equal

(e.g. "a" and "A" in a sort of letters that ignores case).

  • in-place in memory.
  • quadratic performance in the number of elements to be sorted:

it is well-suited to small collections but should not be used for large ones.

source
Base.Sort.MergeSortConstant
MergeSort

Indicate that a sorting function should use the merge sort algorithm. Merge sort divides the collection into subcollections and repeatedly merges them, sorting each subcollection at each step, until the entire collection has been recombined in sorted form.

Characteristics:

  • stable: preserves the ordering of elements that compare equal (e.g. "a" and "A" in a sort of letters that ignores case).
  • not in-place in memory.
  • divide-and-conquer sort strategy.
  • good performance for large collections but typically not quite as fast as QuickSort.
source
Base.Sort.QuickSortConstant
QuickSort

Indicate that a sorting function should use the quick sort algorithm, which is not stable.

Characteristics:

  • not stable: does not preserve the ordering of elements that compare equal (e.g. "a" and "A" in a sort of letters that ignores case).
  • in-place in memory.
  • divide-and-conquer: sort strategy similar to MergeSort.
  • good performance for large collections.
source
Base.Sort.PartialQuickSortType
PartialQuickSort{T <: Union{Integer,OrdinalRange}}

Indicate that a sorting function should use the partial quick sort algorithm. PartialQuickSort(k) is like QuickSort, but is only required to find and sort the elements that would end up in v[k] were v fully sorted.

Characteristics:

  • not stable: does not preserve the ordering of elements that compare equal (e.g. "a" and "A" in a sort of letters that ignores case).
  • in-place in memory.
  • divide-and-conquer: sort strategy similar to MergeSort.

Note that PartialQuickSort(k) does not necessarily sort the whole array. For example,

julia> x = rand(100);
 
 julia> k = 50:100;
 
@@ -184,7 +184,7 @@
 (true, true)
 
 julia> s1[k] == s2[k]
-true
source
Base.Sort.sortperm!Function
sortperm!(ix, A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])

Like sortperm, but accepts a preallocated index vector or array ix with the same axes as A. ix is initialized to contain the values LinearIndices(A).

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Julia 1.9

The method accepting dims requires at least Julia 1.9.

Examples

julia> v = [3, 1, 2]; p = zeros(Int, 3);
+true
source
Base.Sort.sortperm!Function
sortperm!(ix, A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])

Like sortperm, but accepts a preallocated index vector or array ix with the same axes as A. ix is initialized to contain the values LinearIndices(A).

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Julia 1.9

The method accepting dims requires at least Julia 1.9.

Examples

julia> v = [3, 1, 2]; p = zeros(Int, 3);
 
 julia> sortperm!(p, v); p
 3-element Vector{Int64}:
@@ -208,7 +208,7 @@
 julia> sortperm!(p, A; dims=2); p
 2×2 Matrix{Int64}:
  3  1
- 2  4
source
Base.sortslicesFunction
sortslices(A; dims, alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Sort slices of an array A. The required keyword argument dims must be either an integer or a tuple of integers. It specifies the dimension(s) over which the slices are sorted.

E.g., if A is a matrix, dims=1 will sort rows, dims=2 will sort columns. Note that the default comparison function on one dimensional slices sorts lexicographically.

For the remaining keyword arguments, see the documentation of sort!.

Examples

julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1) # Sort rows
+ 2  4
source
Base.sortslicesFunction
sortslices(A; dims, alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Sort slices of an array A. The required keyword argument dims must be either an integer or a tuple of integers. It specifies the dimension(s) over which the slices are sorted.

E.g., if A is a matrix, dims=1 will sort rows, dims=2 will sort columns. Note that the default comparison function on one dimensional slices sorts lexicographically.

For the remaining keyword arguments, see the documentation of sort!.

Examples

julia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1) # Sort rows
 3×3 Matrix{Int64}:
  -1   6  4
   7   3  5
@@ -287,7 +287,7 @@
  4
 
 [:, :, 5] =
- 5
source
Base.issortedFunction
issorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Test whether a collection is in sorted order. The keywords modify what order is considered sorted, as described in the sort! documentation.

Examples

julia> issorted([1, 2, 3])
+ 5
source
Base.issortedFunction
issorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Test whether a collection is in sorted order. The keywords modify what order is considered sorted, as described in the sort! documentation.

Examples

julia> issorted([1, 2, 3])
 true
 
 julia> issorted([(1, "b"), (2, "a")], by = x -> x[1])
@@ -300,7 +300,7 @@
 true
 
 julia> issorted([1, 2, -2, 3], by=abs)
-true
source
Base.Sort.searchsortedFunction
searchsorted(v, x; by=identity, lt=isless, rev=false)

Return the range of indices in v where values are equivalent to x, or an empty range located at the insertion point if v does not contain values equivalent to x. The vector v must be sorted according to the order defined by the keywords. Refer to sort! for the meaning of the keywords and the definition of equivalence. Note that the by function is applied to the searched value x as well as the values in v.

The range is generally found using binary search, but there are optimized implementations for some inputs.

See also: searchsortedfirst, sort!, insorted, findall.

Examples

julia> searchsorted([1, 2, 4, 5, 5, 7], 4) # single match
+true
source
Base.Sort.searchsortedFunction
searchsorted(v, x; by=identity, lt=isless, rev=false)

Return the range of indices in v where values are equivalent to x, or an empty range located at the insertion point if v does not contain values equivalent to x. The vector v must be sorted according to the order defined by the keywords. Refer to sort! for the meaning of the keywords and the definition of equivalence. Note that the by function is applied to the searched value x as well as the values in v.

The range is generally found using binary search, but there are optimized implementations for some inputs.

See also: searchsortedfirst, sort!, insorted, findall.

Examples

julia> searchsorted([1, 2, 4, 5, 5, 7], 4) # single match
 3:3
 
 julia> searchsorted([1, 2, 4, 5, 5, 7], 5) # multiple matches
@@ -316,7 +316,7 @@
 1:0
 
 julia> searchsorted([1=>"one", 2=>"two", 2=>"two", 4=>"four"], 2=>"two", by=first) # compare the keys of the pairs
-2:3
source
Base.Sort.searchsortedfirstFunction
searchsortedfirst(v, x; by=identity, lt=isless, rev=false)

Return the index of the first value in v that is not ordered before x. If all values in v are ordered before x, return lastindex(v) + 1.

The vector v must be sorted according to the order defined by the keywords. insert!ing x at the returned index will maintain the sorted order. Refer to sort! for the meaning and use of the keywords. Note that the by function is applied to the searched value x as well as the values in v.

The index is generally found using binary search, but there are optimized implementations for some inputs.

See also: searchsortedlast, searchsorted, findfirst.

Examples

julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 4) # single match
+2:3
source
Base.Sort.searchsortedfirstFunction
searchsortedfirst(v, x; by=identity, lt=isless, rev=false)

Return the index of the first value in v that is not ordered before x. If all values in v are ordered before x, return lastindex(v) + 1.

The vector v must be sorted according to the order defined by the keywords. insert!ing x at the returned index will maintain the sorted order. Refer to sort! for the meaning and use of the keywords. Note that the by function is applied to the searched value x as well as the values in v.

The index is generally found using binary search, but there are optimized implementations for some inputs.

See also: searchsortedlast, searchsorted, findfirst.

Examples

julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 4) # single match
 3
 
 julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 5) # multiple matches
@@ -332,7 +332,7 @@
 1
 
 julia> searchsortedfirst([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # compare the keys of the pairs
-3
source
Base.Sort.searchsortedlastFunction
searchsortedlast(v, x; by=identity, lt=isless, rev=false)

Return the index of the last value in v that is not ordered after x. If all values in v are ordered after x, return firstindex(v) - 1.

The vector v must be sorted according to the order defined by the keywords. insert!ing x immediately after the returned index will maintain the sorted order. Refer to sort! for the meaning and use of the keywords. Note that the by function is applied to the searched value x as well as the values in v.

The index is generally found using binary search, but there are optimized implementations for some inputs

Examples

julia> searchsortedlast([1, 2, 4, 5, 5, 7], 4) # single match
+3
source
Base.Sort.searchsortedlastFunction
searchsortedlast(v, x; by=identity, lt=isless, rev=false)

Return the index of the last value in v that is not ordered after x. If all values in v are ordered after x, return firstindex(v) - 1.

The vector v must be sorted according to the order defined by the keywords. insert!ing x immediately after the returned index will maintain the sorted order. Refer to sort! for the meaning and use of the keywords. Note that the by function is applied to the searched value x as well as the values in v.

The index is generally found using binary search, but there are optimized implementations for some inputs

Examples

julia> searchsortedlast([1, 2, 4, 5, 5, 7], 4) # single match
 3
 
 julia> searchsortedlast([1, 2, 4, 5, 5, 7], 5) # multiple matches
@@ -348,7 +348,7 @@
 0
 
 julia> searchsortedlast([1=>"one", 2=>"two", 4=>"four"], 3=>"three", by=first) # compare the keys of the pairs
-2
source
Base.Sort.insortedFunction
insorted(x, v; by=identity, lt=isless, rev=false) -> Bool

Determine whether a vector v contains any value equivalent to x. The vector v must be sorted according to the order defined by the keywords. Refer to sort! for the meaning of the keywords and the definition of equivalence. Note that the by function is applied to the searched value x as well as the values in v.

The check is generally done using binary search, but there are optimized implementations for some inputs.

See also in.

Examples

julia> insorted(4, [1, 2, 4, 5, 5, 7]) # single match
+2
source
Base.Sort.insortedFunction
insorted(x, v; by=identity, lt=isless, rev=false) -> Bool

Determine whether a vector v contains any value equivalent to x. The vector v must be sorted according to the order defined by the keywords. Refer to sort! for the meaning of the keywords and the definition of equivalence. Note that the by function is applied to the searched value x as well as the values in v.

The check is generally done using binary search, but there are optimized implementations for some inputs.

See also in.

Examples

julia> insorted(4, [1, 2, 4, 5, 5, 7]) # single match
 true
 
 julia> insorted(5, [1, 2, 4, 5, 5, 7]) # multiple matches
@@ -364,7 +364,7 @@
 false
 
 julia> insorted(2=>"TWO", [1=>"one", 2=>"two", 4=>"four"], by=first) # compare the keys of the pairs
-true
Julia 1.6

insorted was added in Julia 1.6.

source
Base.Sort.partialsort!Function
partialsort!(v, k; by=identity, lt=isless, rev=false)

Partially sort the vector v in place so that the value at index k (or range of adjacent values if k is a range) occurs at the position where it would appear if the array were fully sorted. If k is a single index, that value is returned; if k is a range, an array of values at those indices is returned. Note that partialsort! may not fully sort the input array.

For the keyword arguments, see the documentation of sort!.

Examples

julia> a = [1, 2, 4, 3, 4]
+true
Julia 1.6

insorted was added in Julia 1.6.

source
Base.Sort.partialsort!Function
partialsort!(v, k; by=identity, lt=isless, rev=false)

Partially sort the vector v in place so that the value at index k (or range of adjacent values if k is a range) occurs at the position where it would appear if the array were fully sorted. If k is a single index, that value is returned; if k is a range, an array of values at those indices is returned. Note that partialsort! may not fully sort the input array.

For the keyword arguments, see the documentation of sort!.

Examples

julia> a = [1, 2, 4, 3, 4]
 5-element Vector{Int64}:
  1
  2
@@ -400,7 +400,7 @@
  4
  3
  2
- 1
source
Base.Sort.partialsortFunction
partialsort(v, k, by=identity, lt=isless, rev=false)

Variant of partialsort! that copies v before partially sorting it, thereby returning the same thing as partialsort! but leaving v unmodified.

source
Base.Sort.partialsortpermFunction
partialsortperm(v, k; by=ientity, lt=isless, rev=false)

Return a partial permutation I of the vector v, so that v[I] returns values of a fully sorted version of v at index k. If k is a range, a vector of indices is returned; if k is an integer, a single index is returned. The order is specified using the same keywords as sort!. The permutation is stable: the indices of equal elements will appear in ascending order.

This function is equivalent to, but more efficient than, calling sortperm(...)[k].

Examples

julia> v = [3, 1, 2, 1];
+ 1
source
Base.Sort.partialsortFunction
partialsort(v, k, by=identity, lt=isless, rev=false)

Variant of partialsort! that copies v before partially sorting it, thereby returning the same thing as partialsort! but leaving v unmodified.

source
Base.Sort.partialsortpermFunction
partialsortperm(v, k; by=ientity, lt=isless, rev=false)

Return a partial permutation I of the vector v, so that v[I] returns values of a fully sorted version of v at index k. If k is a range, a vector of indices is returned; if k is an integer, a single index is returned. The order is specified using the same keywords as sort!. The permutation is stable: the indices of equal elements will appear in ascending order.

This function is equivalent to, but more efficient than, calling sortperm(...)[k].

Examples

julia> v = [3, 1, 2, 1];
 
 julia> v[partialsortperm(v, 1)]
 1
@@ -415,7 +415,7 @@
 3-element Vector{Int64}:
  1
  1
- 2
source
Base.Sort.partialsortperm!Function
partialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)

Like partialsortperm, but accepts a preallocated index vector ix the same size as v, which is used to store (a permutation of) the indices of v.

ix is initialized to contain the indices of v.

(Typically, the indices of v will be 1:length(v), although if v has an alternative array type with non-one-based indices, such as an OffsetArray, ix must share those same indices)

Upon return, ix is guaranteed to have the indices k in their sorted positions, such that

partialsortperm!(ix, v, k);
+ 2
source
Base.Sort.partialsortperm!Function
partialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)

Like partialsortperm, but accepts a preallocated index vector ix the same size as v, which is used to store (a permutation of) the indices of v.

ix is initialized to contain the indices of v.

(Typically, the indices of v will be 1:length(v), although if v has an alternative array type with non-one-based indices, such as an OffsetArray, ix must share those same indices)

Upon return, ix is guaranteed to have the indices k in their sorted positions, such that

partialsortperm!(ix, v, k);
 v[ix[k]] == partialsort(v, k)

The return value is the kth element of ix if k is an integer, or view into ix if k is a range.

Warning

Behavior can be unexpected when any mutated argument shares memory with any other argument.

Examples

julia> v = [3, 1, 2, 1];
 
 julia> ix = Vector{Int}(undef, 4);
@@ -428,4 +428,4 @@
 julia> partialsortperm!(ix, v, 2:3)
 2-element view(::Vector{Int64}, 2:3) with eltype Int64:
  4
- 3
source

Sorting Algorithms

There are currently four sorting algorithms publicly available in base Julia:

By default, the sort family of functions uses stable sorting algorithms that are fast on most inputs. The exact algorithm choice is an implementation detail to allow for future performance improvements. Currently, a hybrid of RadixSort, ScratchQuickSort, InsertionSort, and CountingSort is used based on input type, size, and composition. Implementation details are subject to change but currently available in the extended help of ??Base.DEFAULT_STABLE and the docstrings of internal sorting algorithms listed there.

You can explicitly specify your preferred algorithm with the alg keyword (e.g. sort!(v, alg=PartialQuickSort(10:20))) or reconfigure the default sorting algorithm for custom types by adding a specialized method to the Base.Sort.defalg function. For example, InlineStrings.jl defines the following method:

Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSort
Julia 1.9

The default sorting algorithm (returned by Base.Sort.defalg) is guaranteed to be stable since Julia 1.9. Previous versions had unstable edge cases when sorting numeric arrays.

Alternate Orderings

By default, sort, searchsorted, and related functions use isless to compare two elements in order to determine which should come first. The Base.Order.Ordering abstract type provides a mechanism for defining alternate orderings on the same set of elements: when calling a sorting function like sort!, an instance of Ordering can be provided with the keyword argument order.

Instances of Ordering define an order through the Base.Order.lt function, which works as a generalization of isless. This function's behavior on custom Orderings must satisfy all the conditions of a strict weak order. See sort! for details and examples of valid and invalid lt functions.

Base.Order.OrderingType
Base.Order.Ordering

Abstract type which represents a strict weak order on some set of elements. See sort! for more.

Use Base.Order.lt to compare two elements according to the ordering.

source
Base.Order.ltFunction
lt(o::Ordering, a, b) -> Bool

Test whether a is less than b according to the ordering o.

source
Base.Order.ordFunction
ord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)

Construct an Ordering object from the same arguments used by sort!. Elements are first transformed by the function by (which may be identity) and are then compared according to either the function lt or an existing ordering order. lt should be isless or a function that obeys the same rules as the lt parameter of sort!. Finally, the resulting order is reversed if rev=true.

Passing an lt other than isless along with an order other than Base.Order.Forward or Base.Order.Reverse is not permitted, otherwise all options are independent and can be used together in all possible combinations.

source
Base.Order.ForwardConstant
Base.Order.Forward

Default ordering according to isless.

source
Base.Order.ReverseOrderingType
ReverseOrdering(fwd::Ordering=Forward)

A wrapper which reverses an ordering.

For a given Ordering o, the following holds for all a, b:

lt(ReverseOrdering(o), a, b) == lt(o, b, a)
source
Base.Order.ReverseConstant
Base.Order.Reverse

Reverse ordering according to isless.

source
Base.Order.ByType
By(by, order::Ordering=Forward)

Ordering which applies order to elements after they have been transformed by the function by.

source
Base.Order.LtType
Lt(lt)

Ordering that calls lt(a, b) to compare elements. lt must obey the same rules as the lt parameter of sort!.

source
Base.Order.PermType
Perm(order::Ordering, data::AbstractVector)

Ordering on the indices of data where i is less than j if data[i] is less than data[j] according to order. In the case that data[i] and data[j] are equal, i and j are compared by numeric value.

source
+ 3
source

Sorting Algorithms

There are currently four sorting algorithms publicly available in base Julia:

By default, the sort family of functions uses stable sorting algorithms that are fast on most inputs. The exact algorithm choice is an implementation detail to allow for future performance improvements. Currently, a hybrid of RadixSort, ScratchQuickSort, InsertionSort, and CountingSort is used based on input type, size, and composition. Implementation details are subject to change but currently available in the extended help of ??Base.DEFAULT_STABLE and the docstrings of internal sorting algorithms listed there.

You can explicitly specify your preferred algorithm with the alg keyword (e.g. sort!(v, alg=PartialQuickSort(10:20))) or reconfigure the default sorting algorithm for custom types by adding a specialized method to the Base.Sort.defalg function. For example, InlineStrings.jl defines the following method:

Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSort
Julia 1.9

The default sorting algorithm (returned by Base.Sort.defalg) is guaranteed to be stable since Julia 1.9. Previous versions had unstable edge cases when sorting numeric arrays.

Alternate Orderings

By default, sort, searchsorted, and related functions use isless to compare two elements in order to determine which should come first. The Base.Order.Ordering abstract type provides a mechanism for defining alternate orderings on the same set of elements: when calling a sorting function like sort!, an instance of Ordering can be provided with the keyword argument order.

Instances of Ordering define an order through the Base.Order.lt function, which works as a generalization of isless. This function's behavior on custom Orderings must satisfy all the conditions of a strict weak order. See sort! for details and examples of valid and invalid lt functions.

Base.Order.OrderingType
Base.Order.Ordering

Abstract type which represents a strict weak order on some set of elements. See sort! for more.

Use Base.Order.lt to compare two elements according to the ordering.

source
Base.Order.ltFunction
lt(o::Ordering, a, b) -> Bool

Test whether a is less than b according to the ordering o.

source
Base.Order.ordFunction
ord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)

Construct an Ordering object from the same arguments used by sort!. Elements are first transformed by the function by (which may be identity) and are then compared according to either the function lt or an existing ordering order. lt should be isless or a function that obeys the same rules as the lt parameter of sort!. Finally, the resulting order is reversed if rev=true.

Passing an lt other than isless along with an order other than Base.Order.Forward or Base.Order.Reverse is not permitted, otherwise all options are independent and can be used together in all possible combinations.

source
Base.Order.ForwardConstant
Base.Order.Forward

Default ordering according to isless.

source
Base.Order.ReverseOrderingType
ReverseOrdering(fwd::Ordering=Forward)

A wrapper which reverses an ordering.

For a given Ordering o, the following holds for all a, b:

lt(ReverseOrdering(o), a, b) == lt(o, b, a)
source
Base.Order.ReverseConstant
Base.Order.Reverse

Reverse ordering according to isless.

source
Base.Order.ByType
By(by, order::Ordering=Forward)

Ordering which applies order to elements after they have been transformed by the function by.

source
Base.Order.LtType
Lt(lt)

Ordering that calls lt(a, b) to compare elements. lt must obey the same rules as the lt parameter of sort!.

source
Base.Order.PermType
Perm(order::Ordering, data::AbstractVector)

Ordering on the indices of data where i is less than j if data[i] is less than data[j] according to order. In the case that data[i] and data[j] are equal, i and j are compared by numeric value.

source
diff --git a/en/v1.12-dev/base/stacktraces/index.html b/en/v1.12-dev/base/stacktraces/index.html index c7e5d013f842..3f7463903b54 100644 --- a/en/v1.12-dev/base/stacktraces/index.html +++ b/en/v1.12-dev/base/stacktraces/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

StackTraces

Base.StackTraces.StackFrameType
StackFrame

Stack information representing execution context, with the following fields:

  • func::Symbol

    The name of the function containing the execution context.

  • linfo::Union{Method, Core.MethodInstance, Core.CodeInfo, Nothing}

    The Method, MethodInstance, or CodeInfo containing the execution context (if it could be found), or nothing (for example, if the inlining was a result of macro expansion).

  • file::Symbol

    The path to the file containing the execution context.

  • line::Int

    The line number in the file containing the execution context.

  • from_c::Bool

    True if the code is from C.

  • inlined::Bool

    True if the code is from an inlined frame.

  • pointer::UInt64

    Representation of the pointer to the execution context as returned by backtrace.

source
Base.StackTraces.stacktraceFunction
stacktrace([trace::Vector{Ptr{Cvoid}},] [c_funcs::Bool=false]) -> StackTrace

Return a stack trace in the form of a vector of StackFrames. (By default stacktrace doesn't return C functions, but this can be enabled.) When called without specifying a trace, stacktrace first calls backtrace.

source

The following methods and types in Base.StackTraces are not exported and need to be called e.g. as StackTraces.lookup(ptr).

Base.StackTraces.lookupFunction
lookup(pointer::Ptr{Cvoid}) -> Vector{StackFrame}

Given a pointer to an execution context (usually generated by a call to backtrace), looks up stack frame context information. Returns an array of frame information for all functions inlined at that point, innermost function first.

source
Base.StackTraces.remove_frames!Function
remove_frames!(stack::StackTrace, name::Symbol)

Takes a StackTrace (a vector of StackFrames) and a function name (a Symbol) and removes the StackFrame specified by the function name from the StackTrace (also removing all frames above the specified function). Primarily used to remove StackTraces functions from the StackTrace prior to returning it.

source
remove_frames!(stack::StackTrace, m::Module)

Return the StackTrace with all StackFrames from the provided Module removed.

source
+

StackTraces

Base.StackTraces.StackFrameType
StackFrame

Stack information representing execution context, with the following fields:

  • func::Symbol

    The name of the function containing the execution context.

  • linfo::Union{Method, Core.MethodInstance, Core.CodeInfo, Nothing}

    The Method, MethodInstance, or CodeInfo containing the execution context (if it could be found), or nothing (for example, if the inlining was a result of macro expansion).

  • file::Symbol

    The path to the file containing the execution context.

  • line::Int

    The line number in the file containing the execution context.

  • from_c::Bool

    True if the code is from C.

  • inlined::Bool

    True if the code is from an inlined frame.

  • pointer::UInt64

    Representation of the pointer to the execution context as returned by backtrace.

source
Base.StackTraces.stacktraceFunction
stacktrace([trace::Vector{Ptr{Cvoid}},] [c_funcs::Bool=false]) -> StackTrace

Return a stack trace in the form of a vector of StackFrames. (By default stacktrace doesn't return C functions, but this can be enabled.) When called without specifying a trace, stacktrace first calls backtrace.

source

The following methods and types in Base.StackTraces are not exported and need to be called e.g. as StackTraces.lookup(ptr).

Base.StackTraces.lookupFunction
lookup(pointer::Ptr{Cvoid}) -> Vector{StackFrame}

Given a pointer to an execution context (usually generated by a call to backtrace), looks up stack frame context information. Returns an array of frame information for all functions inlined at that point, innermost function first.

source
Base.StackTraces.remove_frames!Function
remove_frames!(stack::StackTrace, name::Symbol)

Takes a StackTrace (a vector of StackFrames) and a function name (a Symbol) and removes the StackFrame specified by the function name from the StackTrace (also removing all frames above the specified function). Primarily used to remove StackTraces functions from the StackTrace prior to returning it.

source
remove_frames!(stack::StackTrace, m::Module)

Return the StackTrace with all StackFrames from the provided Module removed.

source
diff --git a/en/v1.12-dev/base/strings/index.html b/en/v1.12-dev/base/strings/index.html index 06e0bc085724..ea394b2cd5eb 100644 --- a/en/v1.12-dev/base/strings/index.html +++ b/en/v1.12-dev/base/strings/index.html @@ -3,25 +3,25 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Strings

Core.AbstractStringType

The AbstractString type is the supertype of all string implementations in Julia. Strings are encodings of sequences of Unicode code points as represented by the AbstractChar type. Julia makes a few assumptions about strings:

  • Strings are encoded in terms of fixed-size "code units"
    • Code units can be extracted with codeunit(s, i)
    • The first code unit has index 1
    • The last code unit has index ncodeunits(s)
    • Any index i such that 1 ≤ i ≤ ncodeunits(s) is in bounds
  • String indexing is done in terms of these code units:
    • Characters are extracted by s[i] with a valid string index i
    • Each AbstractChar in a string is encoded by one or more code units
    • Only the index of the first code unit of an AbstractChar is a valid index
    • The encoding of an AbstractChar is independent of what precedes or follows it
    • String encodings are self-synchronizing – i.e. isvalid(s, i) is O(1)

Some string functions that extract code units, characters or substrings from strings error if you pass them out-of-bounds or invalid string indices. This includes codeunit(s, i) and s[i]. Functions that do string index arithmetic take a more relaxed approach to indexing and give you the closest valid string index when in-bounds, or when out-of-bounds, behave as if there were an infinite number of characters padding each side of the string. Usually these imaginary padding characters have code unit length 1 but string types may choose different "imaginary" character sizes as makes sense for their implementations (e.g. substrings may pass index arithmetic through to the underlying string they provide a view into). Relaxed indexing functions include those intended for index arithmetic: thisind, nextind and prevind. This model allows index arithmetic to work with out-of-bounds indices as intermediate values so long as one never uses them to retrieve a character, which often helps avoid needing to code around edge cases.

See also codeunit, ncodeunits, thisind, nextind, prevind.

source
Core.AbstractCharType

The AbstractChar type is the supertype of all character implementations in Julia. A character represents a Unicode code point, and can be converted to an integer via the codepoint function in order to obtain the numerical value of the code point, or constructed from the same integer. These numerical values determine how characters are compared with < and ==, for example. New T <: AbstractChar types should define a codepoint(::T) method and a T(::UInt32) constructor, at minimum.

A given AbstractChar subtype may be capable of representing only a subset of Unicode, in which case conversion from an unsupported UInt32 value may throw an error. Conversely, the built-in Char type represents a superset of Unicode (in order to losslessly encode invalid byte streams), in which case conversion of a non-Unicode value to UInt32 throws an error. The isvalid function can be used to check which codepoints are representable in a given AbstractChar type.

Internally, an AbstractChar type may use a variety of encodings. Conversion via codepoint(char) will not reveal this encoding because it always returns the Unicode value of the character. print(io, c) of any c::AbstractChar produces an encoding determined by io (UTF-8 for all built-in IO types), via conversion to Char if necessary.

write(io, c), in contrast, may emit an encoding depending on typeof(c), and read(io, typeof(c)) should read the same encoding as write. New AbstractChar types must provide their own implementations of write and read.

source
Core.CharType
Char(c::Union{Number,AbstractChar})

Char is a 32-bit AbstractChar type that is the default representation of characters in Julia. Char is the type used for character literals like 'x' and it is also the element type of String.

In order to losslessly represent arbitrary byte streams stored in a String, a Char value may store information that cannot be converted to a Unicode codepoint — converting such a Char to UInt32 will throw an error. The isvalid(c::Char) function can be used to query whether c represents a valid Unicode character.

source
Base.codepointFunction
codepoint(c::AbstractChar) -> Integer

Return the Unicode codepoint (an unsigned integer) corresponding to the character c (or throw an exception if c does not represent a valid character). For Char, this is a UInt32 value, but AbstractChar types that represent only a subset of Unicode may return a different-sized integer (e.g. UInt8).

source
Base.lengthMethod
length(s::AbstractString) -> Int
+

Strings

Core.AbstractStringType

The AbstractString type is the supertype of all string implementations in Julia. Strings are encodings of sequences of Unicode code points as represented by the AbstractChar type. Julia makes a few assumptions about strings:

  • Strings are encoded in terms of fixed-size "code units"
    • Code units can be extracted with codeunit(s, i)
    • The first code unit has index 1
    • The last code unit has index ncodeunits(s)
    • Any index i such that 1 ≤ i ≤ ncodeunits(s) is in bounds
  • String indexing is done in terms of these code units:
    • Characters are extracted by s[i] with a valid string index i
    • Each AbstractChar in a string is encoded by one or more code units
    • Only the index of the first code unit of an AbstractChar is a valid index
    • The encoding of an AbstractChar is independent of what precedes or follows it
    • String encodings are self-synchronizing – i.e. isvalid(s, i) is O(1)

Some string functions that extract code units, characters or substrings from strings error if you pass them out-of-bounds or invalid string indices. This includes codeunit(s, i) and s[i]. Functions that do string index arithmetic take a more relaxed approach to indexing and give you the closest valid string index when in-bounds, or when out-of-bounds, behave as if there were an infinite number of characters padding each side of the string. Usually these imaginary padding characters have code unit length 1 but string types may choose different "imaginary" character sizes as makes sense for their implementations (e.g. substrings may pass index arithmetic through to the underlying string they provide a view into). Relaxed indexing functions include those intended for index arithmetic: thisind, nextind and prevind. This model allows index arithmetic to work with out-of-bounds indices as intermediate values so long as one never uses them to retrieve a character, which often helps avoid needing to code around edge cases.

See also codeunit, ncodeunits, thisind, nextind, prevind.

source
Core.AbstractCharType

The AbstractChar type is the supertype of all character implementations in Julia. A character represents a Unicode code point, and can be converted to an integer via the codepoint function in order to obtain the numerical value of the code point, or constructed from the same integer. These numerical values determine how characters are compared with < and ==, for example. New T <: AbstractChar types should define a codepoint(::T) method and a T(::UInt32) constructor, at minimum.

A given AbstractChar subtype may be capable of representing only a subset of Unicode, in which case conversion from an unsupported UInt32 value may throw an error. Conversely, the built-in Char type represents a superset of Unicode (in order to losslessly encode invalid byte streams), in which case conversion of a non-Unicode value to UInt32 throws an error. The isvalid function can be used to check which codepoints are representable in a given AbstractChar type.

Internally, an AbstractChar type may use a variety of encodings. Conversion via codepoint(char) will not reveal this encoding because it always returns the Unicode value of the character. print(io, c) of any c::AbstractChar produces an encoding determined by io (UTF-8 for all built-in IO types), via conversion to Char if necessary.

write(io, c), in contrast, may emit an encoding depending on typeof(c), and read(io, typeof(c)) should read the same encoding as write. New AbstractChar types must provide their own implementations of write and read.

source
Core.CharType
Char(c::Union{Number,AbstractChar})

Char is a 32-bit AbstractChar type that is the default representation of characters in Julia. Char is the type used for character literals like 'x' and it is also the element type of String.

In order to losslessly represent arbitrary byte streams stored in a String, a Char value may store information that cannot be converted to a Unicode codepoint — converting such a Char to UInt32 will throw an error. The isvalid(c::Char) function can be used to query whether c represents a valid Unicode character.

source
Base.codepointFunction
codepoint(c::AbstractChar) -> Integer

Return the Unicode codepoint (an unsigned integer) corresponding to the character c (or throw an exception if c does not represent a valid character). For Char, this is a UInt32 value, but AbstractChar types that represent only a subset of Unicode may return a different-sized integer (e.g. UInt8).

source
Base.lengthMethod
length(s::AbstractString) -> Int
 length(s::AbstractString, i::Integer, j::Integer) -> Int

Return the number of characters in string s from indices i through j.

This is computed as the number of code unit indices from i to j which are valid character indices. With only a single string argument, this computes the number of characters in the entire string. With i and j arguments it computes the number of indices between i and j inclusive that are valid indices in the string s. In addition to in-bounds values, i may take the out-of-bounds value ncodeunits(s) + 1 and j may take the out-of-bounds value 0.

Note

The time complexity of this operation is linear in general. That is, it will take the time proportional to the number of bytes or characters in the string because it counts the value on the fly. This is in contrast to the method for arrays, which is a constant-time operation.

See also isvalid, ncodeunits, lastindex, thisind, nextind, prevind.

Examples

julia> length("jμΛIα")
-5
source
Base.sizeofMethod
sizeof(str::AbstractString)

Size, in bytes, of the string str. Equal to the number of code units in str multiplied by the size, in bytes, of one code unit in str.

Examples

julia> sizeof("")
+5
source
Base.sizeofMethod
sizeof(str::AbstractString)

Size, in bytes, of the string str. Equal to the number of code units in str multiplied by the size, in bytes, of one code unit in str.

Examples

julia> sizeof("")
 0
 
 julia> sizeof("∀")
-3
source
Base.:*Method
*(s::Union{AbstractString, AbstractChar}, t::Union{AbstractString, AbstractChar}...) -> AbstractString

Concatenate strings and/or characters, producing a String or AnnotatedString (as appropriate). This is equivalent to calling the string or annotatedstring function on the arguments. Concatenation of built-in string types always produces a value of type String but other string types may choose to return a string of a different type as appropriate.

Examples

julia> "Hello " * "world"
+3
source
Base.:*Method
*(s::Union{AbstractString, AbstractChar}, t::Union{AbstractString, AbstractChar}...) -> AbstractString

Concatenate strings and/or characters, producing a String or AnnotatedString (as appropriate). This is equivalent to calling the string or annotatedstring function on the arguments. Concatenation of built-in string types always produces a value of type String but other string types may choose to return a string of a different type as appropriate.

Examples

julia> "Hello " * "world"
 "Hello world"
 
 julia> 'j' * "ulia"
-"julia"
source
Base.:^Method
^(s::Union{AbstractString,AbstractChar}, n::Integer) -> AbstractString

Repeat a string or character n times. This can also be written as repeat(s, n).

See also repeat.

Examples

julia> "Test "^3
-"Test Test Test "
source
Base.stringFunction
string(n::Integer; base::Integer = 10, pad::Integer = 1)

Convert an integer n to a string in the given base, optionally specifying a number of digits to pad to.

See also digits, bitstring, count_zeros.

Examples

julia> string(5, base = 13, pad = 4)
+"julia"
source
Base.:^Method
^(s::Union{AbstractString,AbstractChar}, n::Integer) -> AbstractString

Repeat a string or character n times. This can also be written as repeat(s, n).

See also repeat.

Examples

julia> "Test "^3
+"Test Test Test "
source
Base.stringFunction
string(n::Integer; base::Integer = 10, pad::Integer = 1)

Convert an integer n to a string in the given base, optionally specifying a number of digits to pad to.

See also digits, bitstring, count_zeros.

Examples

julia> string(5, base = 13, pad = 4)
 "0005"
 
 julia> string(-13, base = 5, pad = 4)
-"-0023"
source
string(xs...)

Create a string from any values using the print function.

string should usually not be defined directly. Instead, define a method print(io::IO, x::MyType). If string(x) for a certain type needs to be highly efficient, then it may make sense to add a method to string and define print(io::IO, x::MyType) = print(io, string(x)) to ensure the functions are consistent.

See also: String, repr, sprint, show.

Examples

julia> string("a", 1, true)
-"a1true"
source
Base.repeatMethod
repeat(s::AbstractString, r::Integer)

Repeat a string r times. This can be written as s^r.

See also ^.

Examples

julia> repeat("ha", 3)
-"hahaha"
source
Base.repeatMethod
repeat(c::AbstractChar, r::Integer) -> String

Repeat a character r times. This can equivalently be accomplished by calling c^r.

Examples

julia> repeat('A', 3)
-"AAA"
source
Base.reprMethod
repr(x; context=nothing)

Create a string from any value using the show function. You should not add methods to repr; define a show method instead.

The optional keyword argument context can be set to a :key=>value pair, a tuple of :key=>value pairs, or an IO or IOContext object whose attributes are used for the I/O stream passed to show.

Note that repr(x) is usually similar to how the value of x would be entered in Julia. See also repr(MIME("text/plain"), x) to instead return a "pretty-printed" version of x designed more for human consumption, equivalent to the REPL display of x.

Julia 1.7

Passing a tuple to keyword context requires Julia 1.7 or later.

Examples

julia> repr(1)
+"-0023"
source
string(xs...)

Create a string from any values using the print function.

string should usually not be defined directly. Instead, define a method print(io::IO, x::MyType). If string(x) for a certain type needs to be highly efficient, then it may make sense to add a method to string and define print(io::IO, x::MyType) = print(io, string(x)) to ensure the functions are consistent.

See also: String, repr, sprint, show.

Examples

julia> string("a", 1, true)
+"a1true"
source
Base.repeatMethod
repeat(s::AbstractString, r::Integer)

Repeat a string r times. This can be written as s^r.

See also ^.

Examples

julia> repeat("ha", 3)
+"hahaha"
source
Base.repeatMethod
repeat(c::AbstractChar, r::Integer) -> String

Repeat a character r times. This can equivalently be accomplished by calling c^r.

Examples

julia> repeat('A', 3)
+"AAA"
source
Base.reprMethod
repr(x; context=nothing)

Create a string from any value using the show function. You should not add methods to repr; define a show method instead.

The optional keyword argument context can be set to a :key=>value pair, a tuple of :key=>value pairs, or an IO or IOContext object whose attributes are used for the I/O stream passed to show.

Note that repr(x) is usually similar to how the value of x would be entered in Julia. See also repr(MIME("text/plain"), x) to instead return a "pretty-printed" version of x designed more for human consumption, equivalent to the REPL display of x.

Julia 1.7

Passing a tuple to keyword context requires Julia 1.7 or later.

Examples

julia> repr(1)
 "1"
 
 julia> repr(zeros(3))
@@ -32,7 +32,7 @@
 
 julia> repr(big(1/3), context=:compact => true)
 "0.333333"
-
source
Core.StringMethod
String(s::AbstractString)

Create a new String from an existing AbstractString.

source
Core.StringMethod
String(s::AbstractString)

Create a new String from an existing AbstractString.

source
Base.SubStringType
SubString(s::AbstractString, i::Integer, j::Integer=lastindex(s))
 SubString(s::AbstractString, r::UnitRange{<:Integer})

Like getindex, but returns a view into the parent string s within range i:j or r respectively instead of making a copy.

The @views macro converts any string slices s[i:j] into substrings SubString(s, i, j) in a block of code.

Examples

julia> SubString("abc", 1, 2)
 "ab"
 
@@ -40,12 +40,12 @@
 "ab"
 
 julia> SubString("abc", 2)
-"bc"
source
Base.LazyStringType
LazyString <: AbstractString

A lazy representation of string interpolation. This is useful when a string needs to be constructed in a context where performing the actual interpolation and string construction is unnecessary or undesirable (e.g. in error paths of functions).

This type is designed to be cheap to construct at runtime, trying to offload as much work as possible to either the macro or later printing operations.

Examples

julia> n = 5; str = LazyString("n is ", n)
-"n is 5"

See also @lazy_str.

Julia 1.8

LazyString requires Julia 1.8 or later.

Extended help

Safety properties for concurrent programs

A lazy string itself does not introduce any concurrency problems even if it is printed in multiple Julia tasks. However, if print methods on a captured value can have a concurrency issue when invoked without synchronizations, printing the lazy string may cause an issue. Furthermore, the print methods on the captured values may be invoked multiple times, though only exactly one result will be returned.

Julia 1.9

LazyString is safe in the above sense in Julia 1.9 and later.

source
Base.@lazy_strMacro
lazy"str"

Create a LazyString using regular string interpolation syntax. Note that interpolations are evaluated at LazyString construction time, but printing is delayed until the first access to the string.

See LazyString documentation for the safety properties for concurrent programs.

Examples

julia> n = 5; str = lazy"n is $n"
+"bc"
source
Base.LazyStringType
LazyString <: AbstractString

A lazy representation of string interpolation. This is useful when a string needs to be constructed in a context where performing the actual interpolation and string construction is unnecessary or undesirable (e.g. in error paths of functions).

This type is designed to be cheap to construct at runtime, trying to offload as much work as possible to either the macro or later printing operations.

Examples

julia> n = 5; str = LazyString("n is ", n)
+"n is 5"

See also @lazy_str.

Julia 1.8

LazyString requires Julia 1.8 or later.

Extended help

Safety properties for concurrent programs

A lazy string itself does not introduce any concurrency problems even if it is printed in multiple Julia tasks. However, if print methods on a captured value can have a concurrency issue when invoked without synchronizations, printing the lazy string may cause an issue. Furthermore, the print methods on the captured values may be invoked multiple times, though only exactly one result will be returned.

Julia 1.9

LazyString is safe in the above sense in Julia 1.9 and later.

source
Base.@lazy_strMacro
lazy"str"

Create a LazyString using regular string interpolation syntax. Note that interpolations are evaluated at LazyString construction time, but printing is delayed until the first access to the string.

See LazyString documentation for the safety properties for concurrent programs.

Examples

julia> n = 5; str = lazy"n is $n"
 "n is 5"
 
 julia> typeof(str)
-LazyString
Julia 1.8

lazy"str" requires Julia 1.8 or later.

source
Base.AnnotatedStringType
AnnotatedString{S <: AbstractString} <: AbstractString

A string with metadata, in the form of annotated regions.

More specifically, this is a simple wrapper around any other AbstractString that allows for regions of the wrapped string to be annotated with labeled values.

                           C
+LazyString
Julia 1.8

lazy"str" requires Julia 1.8 or later.

source
Base.AnnotatedStringType
AnnotatedString{S <: AbstractString} <: AbstractString

A string with metadata, in the form of annotated regions.

More specifically, this is a simple wrapper around any other AbstractString that allows for regions of the wrapped string to be annotated with labeled values.

                           C
                     ┌──────┸─────────┐
   "this is an example annotated string"
   └──┰────────┼─────┘         │
@@ -53,16 +53,16 @@
                     B

The above diagram represents a AnnotatedString where three ranges have been annotated (labeled A, B, and C). Each annotation holds a label (Symbol) and a value (Any), paired together as a Pair{Symbol, <:Any}.

Labels do not need to be unique, the same region can hold multiple annotations with the same label.

See also AnnotatedChar, annotatedstring, annotations, and annotate!.

Warning

While the constructors are part of the Base public API, the fields of AnnotatedString are not. This is to allow for potential future changes in the implementation of this type. Instead use the annotations, and annotate! getter/setter functions.

Constructors

AnnotatedString(s::S<:AbstractString) -> AnnotatedString{S}
 AnnotatedString(s::S<:AbstractString, annotations::Vector{Tuple{UnitRange{Int}, Pair{Symbol, <:Any}}})

A AnnotatedString can also be created with annotatedstring, which acts much like string but preserves any annotations present in the arguments.

Examples

julia> AnnotatedString("this is an example annotated string",
                     [(1:18, :A => 1), (12:28, :B => 2), (18:35, :C => 3)])
-"this is an example annotated string"
source
Base.AnnotatedCharType
AnnotatedChar{S <: AbstractChar} <: AbstractChar

A Char with annotations.

More specifically, this is a simple wrapper around any other AbstractChar, which holds a list of arbitrary labeled annotations (Pair{Symbol, <:Any}) with the wrapped character.

See also: AnnotatedString, annotatedstring, annotations, and annotate!.

Warning

While the constructors are part of the Base public API, the fields of AnnotatedChar are not. This it to allow for potential future changes in the implementation of this type. Instead use the annotations, and annotate! getter/setter functions.

Constructors

AnnotatedChar(s::S) -> AnnotatedChar{S}
+"this is an example annotated string"
source
Base.AnnotatedCharType
AnnotatedChar{S <: AbstractChar} <: AbstractChar

A Char with annotations.

More specifically, this is a simple wrapper around any other AbstractChar, which holds a list of arbitrary labeled annotations (Pair{Symbol, <:Any}) with the wrapped character.

See also: AnnotatedString, annotatedstring, annotations, and annotate!.

Warning

While the constructors are part of the Base public API, the fields of AnnotatedChar are not. This it to allow for potential future changes in the implementation of this type. Instead use the annotations, and annotate! getter/setter functions.

Constructors

AnnotatedChar(s::S) -> AnnotatedChar{S}
 AnnotatedChar(s::S, annotations::Vector{Pair{Symbol, <:Any}})

Examples

julia> AnnotatedChar('j', :label => 1)
-'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase)
source
Base.annotatedstringFunction
annotatedstring(values...)

Create a AnnotatedString from any number of values using their printed representation.

This acts like string, but takes care to preserve any annotations present (in the form of AnnotatedString or AnnotatedChar values).

See also AnnotatedString and AnnotatedChar.

Examples

julia> annotatedstring("now a AnnotatedString")
 "now a AnnotatedString"
 
 julia> annotatedstring(AnnotatedString("annotated", [(1:9, :label => 1)]), ", and unannotated")
-"annotated, and unannotated"
source
Base.annotationsFunction
annotations(str::Union{AnnotatedString, SubString{AnnotatedString}},
+"annotated, and unannotated"
source
Base.annotationsFunction
annotations(str::Union{AnnotatedString, SubString{AnnotatedString}},
             [position::Union{Integer, UnitRange}]) ->
-    Vector{Tuple{UnitRange{Int}, Pair{Symbol, Any}}}

Get all annotations that apply to str. Should position be provided, only annotations that overlap with position will be returned.

Annotations are provided together with the regions they apply to, in the form of a vector of region–annotation tuples.

See also: annotate!.

source
annotations(chr::AnnotatedChar) -> Vector{Pair{Symbol, Any}}

Get all annotations of chr, in the form of a vector of annotation pairs.

source
Base.annotate!Function
annotate!(str::AnnotatedString, [range::UnitRange{Int}], label::Symbol => value)
-annotate!(str::SubString{AnnotatedString}, [range::UnitRange{Int}], label::Symbol => value)

Annotate a range of str (or the entire string) with a labeled value (label => value). To remove existing label annotations, use a value of nothing.

source
annotate!(char::AnnotatedChar, label::Symbol => value)

Annotate char with the pair label => value.

source
Base.transcodeFunction
transcode(T, src)

Convert string data between Unicode encodings. src is either a String or a Vector{UIntXX} of UTF-XX code units, where XX is 8, 16, or 32. T indicates the encoding of the return value: String to return a (UTF-8 encoded) String or UIntXX to return a Vector{UIntXX} of UTF-XX data. (The alias Cwchar_t can also be used as the integer type, for converting wchar_t* strings used by external C libraries.)

The transcode function succeeds as long as the input data can be reasonably represented in the target encoding; it always succeeds for conversions between UTF-XX encodings, even for invalid Unicode data.

Only conversion to/from UTF-8 is currently supported.

Examples

julia> str = "αβγ"
+    Vector{Tuple{UnitRange{Int}, Pair{Symbol, Any}}}

Get all annotations that apply to str. Should position be provided, only annotations that overlap with position will be returned.

Annotations are provided together with the regions they apply to, in the form of a vector of region–annotation tuples.

See also: annotate!.

source
annotations(chr::AnnotatedChar) -> Vector{Pair{Symbol, Any}}

Get all annotations of chr, in the form of a vector of annotation pairs.

source
Base.annotate!Function
annotate!(str::AnnotatedString, [range::UnitRange{Int}], label::Symbol => value)
+annotate!(str::SubString{AnnotatedString}, [range::UnitRange{Int}], label::Symbol => value)

Annotate a range of str (or the entire string) with a labeled value (label => value). To remove existing label annotations, use a value of nothing.

source
annotate!(char::AnnotatedChar, label::Symbol => value)

Annotate char with the pair label => value.

source
Base.transcodeFunction
transcode(T, src)

Convert string data between Unicode encodings. src is either a String or a Vector{UIntXX} of UTF-XX code units, where XX is 8, 16, or 32. T indicates the encoding of the return value: String to return a (UTF-8 encoded) String or UIntXX to return a Vector{UIntXX} of UTF-XX data. (The alias Cwchar_t can also be used as the integer type, for converting wchar_t* strings used by external C libraries.)

The transcode function succeeds as long as the input data can be reasonably represented in the target encoding; it always succeeds for conversions between UTF-XX encodings, even for invalid Unicode data.

Only conversion to/from UTF-8 is currently supported.

Examples

julia> str = "αβγ"
 "αβγ"
 
 julia> transcode(UInt16, str)
@@ -72,42 +72,42 @@
  0x03b3
 
 julia> transcode(String, transcode(UInt16, str))
-"αβγ"
source
Base.unsafe_stringFunction
unsafe_string(p::Ptr{UInt8}, [length::Integer])

Copy a string from the address of a C-style (NUL-terminated) string encoded as UTF-8. (The pointer can be safely freed afterwards.) If length is specified (the length of the data in bytes), the string does not have to be NUL-terminated.

This function is labeled "unsafe" because it will crash if p is not a valid memory address to data of the requested length.

source
Base.ncodeunitsMethod
ncodeunits(s::AbstractString) -> Int

Return the number of code units in a string. Indices that are in bounds to access this string must satisfy 1 ≤ i ≤ ncodeunits(s). Not all such indices are valid – they may not be the start of a character, but they will return a code unit value when calling codeunit(s,i).

Examples

julia> ncodeunits("The Julia Language")
+"αβγ"
source
Base.unsafe_stringFunction
unsafe_string(p::Ptr{UInt8}, [length::Integer])

Copy a string from the address of a C-style (NUL-terminated) string encoded as UTF-8. (The pointer can be safely freed afterwards.) If length is specified (the length of the data in bytes), the string does not have to be NUL-terminated.

This function is labeled "unsafe" because it will crash if p is not a valid memory address to data of the requested length.

source
Base.ncodeunitsMethod
ncodeunits(s::AbstractString) -> Int

Return the number of code units in a string. Indices that are in bounds to access this string must satisfy 1 ≤ i ≤ ncodeunits(s). Not all such indices are valid – they may not be the start of a character, but they will return a code unit value when calling codeunit(s,i).

Examples

julia> ncodeunits("The Julia Language")
 18
 
 julia> ncodeunits("∫eˣ")
 6
 
 julia> ncodeunits('∫'), ncodeunits('e'), ncodeunits('ˣ')
-(3, 1, 2)

See also codeunit, checkbounds, sizeof, length, lastindex.

source
Base.codeunitFunction
codeunit(s::AbstractString) -> Type{<:Union{UInt8, UInt16, UInt32}}

Return the code unit type of the given string object. For ASCII, Latin-1, or UTF-8 encoded strings, this would be UInt8; for UCS-2 and UTF-16 it would be UInt16; for UTF-32 it would be UInt32. The code unit type need not be limited to these three types, but it's hard to think of widely used string encodings that don't use one of these units. codeunit(s) is the same as typeof(codeunit(s,1)) when s is a non-empty string.

See also ncodeunits.

source
codeunit(s::AbstractString, i::Integer) -> Union{UInt8, UInt16, UInt32}

Return the code unit value in the string s at index i. Note that

codeunit(s, i) :: codeunit(s)

I.e. the value returned by codeunit(s, i) is of the type returned by codeunit(s).

Examples

julia> a = codeunit("Hello", 2)
+(3, 1, 2)

See also codeunit, checkbounds, sizeof, length, lastindex.

source
Base.codeunitFunction
codeunit(s::AbstractString) -> Type{<:Union{UInt8, UInt16, UInt32}}

Return the code unit type of the given string object. For ASCII, Latin-1, or UTF-8 encoded strings, this would be UInt8; for UCS-2 and UTF-16 it would be UInt16; for UTF-32 it would be UInt32. The code unit type need not be limited to these three types, but it's hard to think of widely used string encodings that don't use one of these units. codeunit(s) is the same as typeof(codeunit(s,1)) when s is a non-empty string.

See also ncodeunits.

source
codeunit(s::AbstractString, i::Integer) -> Union{UInt8, UInt16, UInt32}

Return the code unit value in the string s at index i. Note that

codeunit(s, i) :: codeunit(s)

I.e. the value returned by codeunit(s, i) is of the type returned by codeunit(s).

Examples

julia> a = codeunit("Hello", 2)
 0x65
 
 julia> typeof(a)
-UInt8

See also ncodeunits, checkbounds.

source
Base.codeunitsFunction
codeunits(s::AbstractString)

Obtain a vector-like object containing the code units of a string. Returns a CodeUnits wrapper by default, but codeunits may optionally be defined for new string types if necessary.

Examples

julia> codeunits("Juλia")
+UInt8

See also ncodeunits, checkbounds.

source
Base.codeunitsFunction
codeunits(s::AbstractString)

Obtain a vector-like object containing the code units of a string. Returns a CodeUnits wrapper by default, but codeunits may optionally be defined for new string types if necessary.

Examples

julia> codeunits("Juλia")
 6-element Base.CodeUnits{UInt8, String}:
  0x4a
  0x75
  0xce
  0xbb
  0x69
- 0x61
source
Base.asciiFunction
ascii(s::AbstractString)

Convert a string to String type and check that it contains only ASCII data, otherwise throwing an ArgumentError indicating the position of the first non-ASCII byte.

See also the isascii predicate to filter or replace non-ASCII characters.

Examples

julia> ascii("abcdeγfgh")
+ 0x61
source
Base.asciiFunction
ascii(s::AbstractString)

Convert a string to String type and check that it contains only ASCII data, otherwise throwing an ArgumentError indicating the position of the first non-ASCII byte.

See also the isascii predicate to filter or replace non-ASCII characters.

Examples

julia> ascii("abcdeγfgh")
 ERROR: ArgumentError: invalid ASCII at index 6 in "abcdeγfgh"
 Stacktrace:
 [...]
 
 julia> ascii("abcdefgh")
-"abcdefgh"
source
Base.RegexType
Regex(pattern[, flags]) <: AbstractPattern

A type representing a regular expression. Regex objects can be used to match strings with match.

Regex objects can be created using the @r_str string macro. The Regex(pattern[, flags]) constructor is usually used if the pattern string needs to be interpolated. See the documentation of the string macro for details on flags.

Note

To escape interpolated variables use \Q and \E (e.g. Regex("\\Q$x\\E"))

source
Base.@r_strMacro
@r_str -> Regex

Construct a regex, such as r"^[a-z]*$", without interpolation and unescaping (except for quotation mark " which still has to be escaped). The regex also accepts one or more flags, listed after the ending quote, to change its behaviour:

  • i enables case-insensitive matching
  • m treats the ^ and $ tokens as matching the start and end of individual lines, as opposed to the whole string.
  • s allows the . modifier to match newlines.
  • x enables "free-spacing mode": whitespace between regex tokens is ignored except when escaped with \, and # in the regex is treated as starting a comment (which is ignored to the line ending).
  • a enables ASCII mode (disables UTF and UCP modes). By default \B, \b, \D, \d, \S, \s, \W, \w, etc. match based on Unicode character properties. With this option, these sequences only match ASCII characters. This includes \u also, which will emit the specified character value directly as a single byte, and not attempt to encode it into UTF-8. Importantly, this option allows matching against invalid UTF-8 strings, by treating both matcher and target as simple bytes (as if they were ISO/IEC 8859-1 / Latin-1 bytes) instead of as character encodings. In this case, this option is often combined with s. This option can be further refined by starting the pattern with (UCP) or (UTF).

See Regex if interpolation is needed.

Examples

julia> match(r"a+.*b+.*?d$"ism, "Goodbye,\nOh, angry,\nBad world\n")
-RegexMatch("angry,\nBad world")

This regex has the first three flags enabled.

source
Base.SubstitutionStringType
SubstitutionString(substr) <: AbstractString

Stores the given string substr as a SubstitutionString, for use in regular expression substitutions. Most commonly constructed using the @s_str macro.

Examples

julia> SubstitutionString("Hello \\g<name>, it's \\1")
+"abcdefgh"
source
Base.RegexType
Regex(pattern[, flags]) <: AbstractPattern

A type representing a regular expression. Regex objects can be used to match strings with match.

Regex objects can be created using the @r_str string macro. The Regex(pattern[, flags]) constructor is usually used if the pattern string needs to be interpolated. See the documentation of the string macro for details on flags.

Note

To escape interpolated variables use \Q and \E (e.g. Regex("\\Q$x\\E"))

source
Base.@r_strMacro
@r_str -> Regex

Construct a regex, such as r"^[a-z]*$", without interpolation and unescaping (except for quotation mark " which still has to be escaped). The regex also accepts one or more flags, listed after the ending quote, to change its behaviour:

  • i enables case-insensitive matching
  • m treats the ^ and $ tokens as matching the start and end of individual lines, as opposed to the whole string.
  • s allows the . modifier to match newlines.
  • x enables "free-spacing mode": whitespace between regex tokens is ignored except when escaped with \, and # in the regex is treated as starting a comment (which is ignored to the line ending).
  • a enables ASCII mode (disables UTF and UCP modes). By default \B, \b, \D, \d, \S, \s, \W, \w, etc. match based on Unicode character properties. With this option, these sequences only match ASCII characters. This includes \u also, which will emit the specified character value directly as a single byte, and not attempt to encode it into UTF-8. Importantly, this option allows matching against invalid UTF-8 strings, by treating both matcher and target as simple bytes (as if they were ISO/IEC 8859-1 / Latin-1 bytes) instead of as character encodings. In this case, this option is often combined with s. This option can be further refined by starting the pattern with (UCP) or (UTF).

See Regex if interpolation is needed.

Examples

julia> match(r"a+.*b+.*?d$"ism, "Goodbye,\nOh, angry,\nBad world\n")
+RegexMatch("angry,\nBad world")

This regex has the first three flags enabled.

source
Base.SubstitutionStringType
SubstitutionString(substr) <: AbstractString

Stores the given string substr as a SubstitutionString, for use in regular expression substitutions. Most commonly constructed using the @s_str macro.

Examples

julia> SubstitutionString("Hello \\g<name>, it's \\1")
 s"Hello \g<name>, it's \1"
 
 julia> subst = s"Hello \g<name>, it's \1"
 s"Hello \g<name>, it's \1"
 
 julia> typeof(subst)
-SubstitutionString{String}
source
Base.@s_strMacro
@s_str -> SubstitutionString

Construct a substitution string, used for regular expression substitutions. Within the string, sequences of the form \N refer to the Nth capture group in the regex, and \g<groupname> refers to a named capture group with name groupname.

Examples

julia> msg = "#Hello# from Julia";
+SubstitutionString{String}
source
Base.@s_strMacro
@s_str -> SubstitutionString

Construct a substitution string, used for regular expression substitutions. Within the string, sequences of the form \N refer to the Nth capture group in the regex, and \g<groupname> refers to a named capture group with name groupname.

Examples

julia> msg = "#Hello# from Julia";
 
 julia> replace(msg, r"#(.+)# from (?<from>\w+)" => s"FROM: \g<from>; MESSAGE: \1")
-"FROM: Julia; MESSAGE: Hello"
source
Base.@raw_strMacro
@raw_str -> String

Create a raw string without interpolation and unescaping. The exception is that quotation marks still must be escaped. Backslashes escape both quotation marks and other backslashes, but only when a sequence of backslashes precedes a quote character. Thus, 2n backslashes followed by a quote encodes n backslashes and the end of the literal while 2n+1 backslashes followed by a quote encodes n backslashes followed by a quote character.

Examples

julia> println(raw"\ $x")
+"FROM: Julia; MESSAGE: Hello"
source
Base.@raw_strMacro
@raw_str -> String

Create a raw string without interpolation and unescaping. The exception is that quotation marks still must be escaped. Backslashes escape both quotation marks and other backslashes, but only when a sequence of backslashes precedes a quote character. Thus, 2n backslashes followed by a quote encodes n backslashes and the end of the literal while 2n+1 backslashes followed by a quote encodes n backslashes followed by a quote character.

Examples

julia> println(raw"\ $x")
 \ $x
 
 julia> println(raw"\"")
@@ -117,7 +117,7 @@
 \"
 
 julia> println(raw"\\x \\\"")
-\\x \"
source
Base.@b_strMacro
@b_str

Create an immutable byte (UInt8) vector using string syntax.

Examples

julia> v = b"12\x01\x02"
+\\x \"
source
Base.@b_strMacro
@b_str

Create an immutable byte (UInt8) vector using string syntax.

Examples

julia> v = b"12\x01\x02"
 4-element Base.CodeUnits{UInt8, String}:
  0x31
  0x32
@@ -125,23 +125,23 @@
  0x02
 
 julia> v[2]
-0x32
source
Base.Docs.@html_strMacro
@html_str -> Docs.HTML

Create an HTML object from a literal string.

Examples

julia> html"Julia"
-HTML{String}("Julia")
source
Base.Docs.@text_strMacro
@text_str -> Docs.Text

Create a Text object from a literal string.

Examples

julia> text"Julia"
-Julia
source
Base.isvalidMethod
isvalid(value) -> Bool

Return true if the given value is valid for its type, which currently can be either AbstractChar or String or SubString{String}.

Examples

julia> isvalid(Char(0xd800))
+0x32
source
Base.Docs.@html_strMacro
@html_str -> Docs.HTML

Create an HTML object from a literal string.

Examples

julia> html"Julia"
+HTML{String}("Julia")
source
Base.Docs.@text_strMacro
@text_str -> Docs.Text

Create a Text object from a literal string.

Examples

julia> text"Julia"
+Julia
source
Base.isvalidMethod
isvalid(value) -> Bool

Return true if the given value is valid for its type, which currently can be either AbstractChar or String or SubString{String}.

Examples

julia> isvalid(Char(0xd800))
 false
 
 julia> isvalid(SubString(String(UInt8[0xfe,0x80,0x80,0x80,0x80,0x80]),1,2))
 false
 
 julia> isvalid(Char(0xd799))
-true
source
Base.isvalidMethod
isvalid(T, value) -> Bool

Return true if the given value is valid for that type. Types currently can be either AbstractChar or String. Values for AbstractChar can be of type AbstractChar or UInt32. Values for String can be of that type, SubString{String}, Vector{UInt8}, or a contiguous subarray thereof.

Examples

julia> isvalid(Char, 0xd800)
+true
source
Base.isvalidMethod
isvalid(T, value) -> Bool

Return true if the given value is valid for that type. Types currently can be either AbstractChar or String. Values for AbstractChar can be of type AbstractChar or UInt32. Values for String can be of that type, SubString{String}, Vector{UInt8}, or a contiguous subarray thereof.

Examples

julia> isvalid(Char, 0xd800)
 false
 
 julia> isvalid(String, SubString("thisisvalid",1,5))
 true
 
 julia> isvalid(Char, 0xd799)
-true
Julia 1.6

Support for subarray values was added in Julia 1.6.

source
Base.isvalidMethod
isvalid(s::AbstractString, i::Integer) -> Bool

Predicate indicating whether the given index is the start of the encoding of a character in s or not. If isvalid(s, i) is true then s[i] will return the character whose encoding starts at that index, if it's false, then s[i] will raise an invalid index error or a bounds error depending on if i is in bounds. In order for isvalid(s, i) to be an O(1) function, the encoding of s must be self-synchronizing. This is a basic assumption of Julia's generic string support.

See also getindex, iterate, thisind, nextind, prevind, length.

Examples

julia> str = "αβγdef";
+true
Julia 1.6

Support for subarray values was added in Julia 1.6.

source
Base.isvalidMethod
isvalid(s::AbstractString, i::Integer) -> Bool

Predicate indicating whether the given index is the start of the encoding of a character in s or not. If isvalid(s, i) is true then s[i] will return the character whose encoding starts at that index, if it's false, then s[i] will raise an invalid index error or a bounds error depending on if i is in bounds. In order for isvalid(s, i) to be an O(1) function, the encoding of s must be self-synchronizing. This is a basic assumption of Julia's generic string support.

See also getindex, iterate, thisind, nextind, prevind, length.

Examples

julia> str = "αβγdef";
 
 julia> isvalid(str, 1)
 true
@@ -155,7 +155,7 @@
 julia> str[2]
 ERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'α', [3]=>'β'
 Stacktrace:
-[...]
source
Base.matchFunction
match(r::Regex, s::AbstractString[, idx::Integer[, addopts]])

Search for the first match of the regular expression r in s and return a RegexMatch object containing the match, or nothing if the match failed. The optional idx argument specifies an index at which to start the search. The matching substring can be retrieved by accessing m.match, the captured sequences can be retrieved by accessing m.captures. The resulting RegexMatch object can be used to construct other collections: e.g. Tuple(m), NamedTuple(m).

Julia 1.11

Constructing NamedTuples and Dicts requires Julia 1.11

Examples

julia> rx = r"a(.)a"
+[...]
source
Base.matchFunction
match(r::Regex, s::AbstractString[, idx::Integer[, addopts]])

Search for the first match of the regular expression r in s and return a RegexMatch object containing the match, or nothing if the match failed. The optional idx argument specifies an index at which to start the search. The matching substring can be retrieved by accessing m.match, the captured sequences can be retrieved by accessing m.captures. The resulting RegexMatch object can be used to construct other collections: e.g. Tuple(m), NamedTuple(m).

Julia 1.11

Constructing NamedTuples and Dicts requires Julia 1.11

Examples

julia> rx = r"a(.)a"
 r"a(.)a"
 
 julia> m = match(rx, "cabac")
@@ -169,7 +169,7 @@
 "aba"
 
 julia> match(rx, "cabac", 3) === nothing
-true
source
Base.eachmatchFunction
eachmatch(r::Regex, s::AbstractString; overlap::Bool=false)

Search for all matches of the regular expression r in s and return an iterator over the matches. If overlap is true, the matching sequences are allowed to overlap indices in the original string, otherwise they must be from distinct character ranges.

Examples

julia> rx = r"a.a"
+true
source
Base.eachmatchFunction
eachmatch(r::Regex, s::AbstractString; overlap::Bool=false)

Search for all matches of the regular expression r in s and return an iterator over the matches. If overlap is true, the matching sequences are allowed to overlap indices in the original string, otherwise they must be from distinct character ranges.

Examples

julia> rx = r"a.a"
 r"a.a"
 
 julia> m = eachmatch(rx, "a1a2a3a")
@@ -184,7 +184,7 @@
 3-element Vector{RegexMatch}:
  RegexMatch("a1a")
  RegexMatch("a2a")
- RegexMatch("a3a")
source
Base.RegexMatchType
RegexMatch <: AbstractMatch

A type representing a single match to a Regex found in a string. Typically created from the match function.

The match field stores the substring of the entire matched string. The captures field stores the substrings for each capture group, indexed by number. To index by capture group name, the entire match object should be indexed instead, as shown in the examples. The location of the start of the match is stored in the offset field. The offsets field stores the locations of the start of each capture group, with 0 denoting a group that was not captured.

This type can be used as an iterator over the capture groups of the Regex, yielding the substrings captured in each group. Because of this, the captures of a match can be destructured. If a group was not captured, nothing will be yielded instead of a substring.

Methods that accept a RegexMatch object are defined for iterate, length, eltype, keys, haskey, and getindex, where keys are the names or numbers of a capture group. See keys for more information.

Tuple(m), NamedTuple(m), and Dict(m) can be used to construct more flexible collection types from RegexMatch objects.

Julia 1.11

Constructing NamedTuples and Dicts from RegexMatches requires Julia 1.11

Examples

julia> m = match(r"(?<hour>\d+):(?<minute>\d+)(am|pm)?", "11:30 in the morning")
+ RegexMatch("a3a")
source
Base.RegexMatchType
RegexMatch <: AbstractMatch

A type representing a single match to a Regex found in a string. Typically created from the match function.

The match field stores the substring of the entire matched string. The captures field stores the substrings for each capture group, indexed by number. To index by capture group name, the entire match object should be indexed instead, as shown in the examples. The location of the start of the match is stored in the offset field. The offsets field stores the locations of the start of each capture group, with 0 denoting a group that was not captured.

This type can be used as an iterator over the capture groups of the Regex, yielding the substrings captured in each group. Because of this, the captures of a match can be destructured. If a group was not captured, nothing will be yielded instead of a substring.

Methods that accept a RegexMatch object are defined for iterate, length, eltype, keys, haskey, and getindex, where keys are the names or numbers of a capture group. See keys for more information.

Tuple(m), NamedTuple(m), and Dict(m) can be used to construct more flexible collection types from RegexMatch objects.

Julia 1.11

Constructing NamedTuples and Dicts from RegexMatches requires Julia 1.11

Examples

julia> m = match(r"(?<hour>\d+):(?<minute>\d+)(am|pm)?", "11:30 in the morning")
 RegexMatch("11:30", hour="11", minute="30", 3=nothing)
 
 julia> m.match
@@ -209,22 +209,22 @@
 Dict{Any, Union{Nothing, SubString{String}}} with 3 entries:
   "hour"   => "11"
   3        => nothing
-  "minute" => "30"
source
Base.keysMethod
keys(m::RegexMatch) -> Vector

Return a vector of keys for all capture groups of the underlying regex. A key is included even if the capture group fails to match. That is, idx will be in the return value even if m[idx] == nothing.

Unnamed capture groups will have integer keys corresponding to their index. Named capture groups will have string keys.

Julia 1.7

This method was added in Julia 1.7

Examples

julia> keys(match(r"(?<hour>\d+):(?<minute>\d+)(am|pm)?", "11:30"))
+  "minute" => "30"
source
Base.keysMethod
keys(m::RegexMatch) -> Vector

Return a vector of keys for all capture groups of the underlying regex. A key is included even if the capture group fails to match. That is, idx will be in the return value even if m[idx] == nothing.

Unnamed capture groups will have integer keys corresponding to their index. Named capture groups will have string keys.

Julia 1.7

This method was added in Julia 1.7

Examples

julia> keys(match(r"(?<hour>\d+):(?<minute>\d+)(am|pm)?", "11:30"))
 3-element Vector{Any}:
   "hour"
   "minute"
- 3
source
Base.islessMethod
isless(a::AbstractString, b::AbstractString) -> Bool

Test whether string a comes before string b in alphabetical order (technically, in lexicographical order by Unicode code points).

Examples

julia> isless("a", "b")
+ 3
source
Base.islessMethod
isless(a::AbstractString, b::AbstractString) -> Bool

Test whether string a comes before string b in alphabetical order (technically, in lexicographical order by Unicode code points).

Examples

julia> isless("a", "b")
 true
 
 julia> isless("β", "α")
 false
 
 julia> isless("a", "a")
-false
source
Base.:==Method
==(a::AbstractString, b::AbstractString) -> Bool

Test whether two strings are equal character by character (technically, Unicode code point by code point). Should either string be a AnnotatedString the string properties must match too.

Examples

julia> "abc" == "abc"
+false
source
Base.:==Method
==(a::AbstractString, b::AbstractString) -> Bool

Test whether two strings are equal character by character (technically, Unicode code point by code point). Should either string be a AnnotatedString the string properties must match too.

Examples

julia> "abc" == "abc"
 true
 
 julia> "abc" == "αβγ"
-false
source
Base.cmpMethod
cmp(a::AbstractString, b::AbstractString) -> Int

Compare two strings. Return 0 if both strings have the same length and the character at each index is the same in both strings. Return -1 if a is a prefix of b, or if a comes before b in alphabetical order. Return 1 if b is a prefix of a, or if b comes before a in alphabetical order (technically, lexicographical order by Unicode code points).

Examples

julia> cmp("abc", "abc")
+false
source
Base.cmpMethod
cmp(a::AbstractString, b::AbstractString) -> Int

Compare two strings. Return 0 if both strings have the same length and the character at each index is the same in both strings. Return -1 if a is a prefix of b, or if a comes before b in alphabetical order. Return 1 if b is a prefix of a, or if b comes before a in alphabetical order (technically, lexicographical order by Unicode code points).

Examples

julia> cmp("abc", "abc")
 0
 
 julia> cmp("ab", "abc")
@@ -243,13 +243,13 @@
 1
 
 julia> cmp("b", "β")
--1
source
Base.lpadFunction
lpad(s, n::Integer, p::Union{AbstractChar,AbstractString}=' ') -> String

Stringify s and pad the resulting string on the left with p to make it n characters (in textwidth) long. If s is already n characters long, an equal string is returned. Pad with spaces by default.

Examples

julia> lpad("March", 10)
-"     March"
Julia 1.7

In Julia 1.7, this function was changed to use textwidth rather than a raw character (codepoint) count.

source
Base.rpadFunction
rpad(s, n::Integer, p::Union{AbstractChar,AbstractString}=' ') -> String

Stringify s and pad the resulting string on the right with p to make it n characters (in textwidth) long. If s is already n characters long, an equal string is returned. Pad with spaces by default.

Examples

julia> rpad("March", 20)
-"March               "
Julia 1.7

In Julia 1.7, this function was changed to use textwidth rather than a raw character (codepoint) count.

source
Base.lpadFunction
lpad(s, n::Integer, p::Union{AbstractChar,AbstractString}=' ') -> String

Stringify s and pad the resulting string on the left with p to make it n characters (in textwidth) long. If s is already n characters long, an equal string is returned. Pad with spaces by default.

Examples

julia> lpad("March", 10)
+"     March"
Julia 1.7

In Julia 1.7, this function was changed to use textwidth rather than a raw character (codepoint) count.

source
Base.rpadFunction
rpad(s, n::Integer, p::Union{AbstractChar,AbstractString}=' ') -> String

Stringify s and pad the resulting string on the right with p to make it n characters (in textwidth) long. If s is already n characters long, an equal string is returned. Pad with spaces by default.

Examples

julia> rpad("March", 20)
+"March               "
Julia 1.7

In Julia 1.7, this function was changed to use textwidth rather than a raw character (codepoint) count.

source
Base.findfirstMethod
findfirst(pattern::AbstractString, string::AbstractString)
 findfirst(pattern::AbstractPattern, string::String)

Find the first occurrence of pattern in string. Equivalent to findnext(pattern, string, firstindex(s)).

Examples

julia> findfirst("z", "Hello to the world") # returns nothing, but not printed in the REPL
 
 julia> findfirst("Julia", "JuliaLang")
-1:5
source
Base.findnextMethod
findnext(pattern::AbstractString, string::AbstractString, start::Integer)
+1:5
source
Base.findnextMethod
findnext(pattern::AbstractString, string::AbstractString, start::Integer)
 findnext(pattern::AbstractPattern, string::String, start::Integer)

Find the next occurrence of pattern in string starting at position start. pattern can be either a string, or a regular expression, in which case string must be of type String.

The return value is a range of indices where the matching sequence is found, such that s[findnext(x, s, i)] == x:

findnext("substring", string, i) == start:stop such that string[start:stop] == "substring" and i <= start, or nothing if unmatched.

Examples

julia> findnext("z", "Hello to the world", 1) === nothing
 true
 
@@ -257,26 +257,26 @@
 8:8
 
 julia> findnext("Lang", "JuliaLang", 2)
-6:9
source
Base.findnextMethod
findnext(ch::AbstractChar, string::AbstractString, start::Integer)

Find the next occurrence of character ch in string starting at position start.

Julia 1.3

This method requires at least Julia 1.3.

Examples

julia> findnext('z', "Hello to the world", 1) === nothing
+6:9
source
Base.findnextMethod
findnext(ch::AbstractChar, string::AbstractString, start::Integer)

Find the next occurrence of character ch in string starting at position start.

Julia 1.3

This method requires at least Julia 1.3.

Examples

julia> findnext('z', "Hello to the world", 1) === nothing
 true
 
 julia> findnext('o', "Hello to the world", 6)
-8
source
Base.findlastMethod
findlast(ch::AbstractChar, string::AbstractString)

Find the last occurrence of character ch in string.

Julia 1.3

This method requires at least Julia 1.3.

Examples

julia> findlast('p', "happy")
+1:5
source
Base.findlastMethod
findlast(ch::AbstractChar, string::AbstractString)

Find the last occurrence of character ch in string.

Julia 1.3

This method requires at least Julia 1.3.

Examples

julia> findlast('p', "happy")
 4
 
 julia> findlast('z', "happy") === nothing
-true
source
Base.findprevMethod
findprev(pattern::AbstractString, string::AbstractString, start::Integer)

Find the previous occurrence of pattern in string starting at position start.

The return value is a range of indices where the matching sequence is found, such that s[findprev(x, s, i)] == x:

findprev("substring", string, i) == start:stop such that string[start:stop] == "substring" and stop <= i, or nothing if unmatched.

Examples

julia> findprev("z", "Hello to the world", 18) === nothing
+true
source
Base.findprevMethod
findprev(pattern::AbstractString, string::AbstractString, start::Integer)

Find the previous occurrence of pattern in string starting at position start.

The return value is a range of indices where the matching sequence is found, such that s[findprev(x, s, i)] == x:

findprev("substring", string, i) == start:stop such that string[start:stop] == "substring" and stop <= i, or nothing if unmatched.

Examples

julia> findprev("z", "Hello to the world", 18) === nothing
 true
 
 julia> findprev("o", "Hello to the world", 18)
 15:15
 
 julia> findprev("Julia", "JuliaLang", 6)
-1:5
source
Base.occursinFunction
occursin(needle::Union{AbstractString,AbstractPattern,AbstractChar}, haystack::AbstractString)

Determine whether the first argument is a substring of the second. If needle is a regular expression, checks whether haystack contains a match.

Examples

julia> occursin("Julia", "JuliaLang is pretty cool!")
+1:5
source
Base.occursinFunction
occursin(needle::Union{AbstractString,AbstractPattern,AbstractChar}, haystack::AbstractString)

Determine whether the first argument is a substring of the second. If needle is a regular expression, checks whether haystack contains a match.

Examples

julia> occursin("Julia", "JuliaLang is pretty cool!")
 true
 
 julia> occursin('a', "JuliaLang is pretty cool!")
@@ -286,20 +286,20 @@
 true
 
 julia> occursin(r"a.a", "abba")
-false

See also contains.

source
occursin(haystack)

Create a function that checks whether its argument occurs in haystack, i.e. a function equivalent to needle -> occursin(needle, haystack).

The returned function is of type Base.Fix2{typeof(occursin)}.

Julia 1.6

This method requires Julia 1.6 or later.

Examples

julia> search_f = occursin("JuliaLang is a programming language");
+false

See also contains.

source
occursin(haystack)

Create a function that checks whether its argument occurs in haystack, i.e. a function equivalent to needle -> occursin(needle, haystack).

The returned function is of type Base.Fix2{typeof(occursin)}.

Julia 1.6

This method requires Julia 1.6 or later.

Examples

julia> search_f = occursin("JuliaLang is a programming language");
 
 julia> search_f("JuliaLang")
 true
 
 julia> search_f("Python")
-false
source
Base.reverseMethod
reverse(s::AbstractString) -> AbstractString

Reverses a string. Technically, this function reverses the codepoints in a string and its main utility is for reversed-order string processing, especially for reversed regular-expression searches. See also reverseind to convert indices in s to indices in reverse(s) and vice-versa, and graphemes from module Unicode to operate on user-visible "characters" (graphemes) rather than codepoints. See also Iterators.reverse for reverse-order iteration without making a copy. Custom string types must implement the reverse function themselves and should typically return a string with the same type and encoding. If they return a string with a different encoding, they must also override reverseind for that string type to satisfy s[reverseind(s,i)] == reverse(s)[i].

Examples

julia> reverse("JuliaLang")
+false
source
Base.reverseMethod
reverse(s::AbstractString) -> AbstractString

Reverses a string. Technically, this function reverses the codepoints in a string and its main utility is for reversed-order string processing, especially for reversed regular-expression searches. See also reverseind to convert indices in s to indices in reverse(s) and vice-versa, and graphemes from module Unicode to operate on user-visible "characters" (graphemes) rather than codepoints. See also Iterators.reverse for reverse-order iteration without making a copy. Custom string types must implement the reverse function themselves and should typically return a string with the same type and encoding. If they return a string with a different encoding, they must also override reverseind for that string type to satisfy s[reverseind(s,i)] == reverse(s)[i].

Examples

julia> reverse("JuliaLang")
 "gnaLailuJ"
Note

The examples below may be rendered differently on different systems. The comments indicate how they're supposed to be rendered

Combining characters can lead to surprising results:

julia> reverse("ax̂e") # hat is above x in the input, above e in the output
 "êxa"
 
 julia> using Unicode
 
 julia> join(reverse(collect(graphemes("ax̂e")))) # reverses graphemes; hat is above x in both in- and output
-"ex̂a"
source
Base.replaceMethod
replace([io::IO], s::AbstractString, pat=>r, [pat2=>r2, ...]; [count::Integer])

Search for the given pattern pat in s, and replace each occurrence with r. If count is provided, replace at most count occurrences. pat may be a single character, a vector or a set of characters, a string, or a regular expression. If r is a function, each occurrence is replaced with r(s) where s is the matched substring (when pat is a AbstractPattern or AbstractString) or character (when pat is an AbstractChar or a collection of AbstractChar). If pat is a regular expression and r is a SubstitutionString, then capture group references in r are replaced with the corresponding matched text. To remove instances of pat from string, set r to the empty String ("").

The return value is a new string after the replacements. If the io::IO argument is supplied, the transformed string is instead written to io (returning io). (For example, this can be used in conjunction with an IOBuffer to re-use a pre-allocated buffer array in-place.)

Multiple patterns can be specified, and they will be applied left-to-right simultaneously, so only one pattern will be applied to any character, and the patterns will only be applied to the input text, not the replacements.

Julia 1.7

Support for multiple patterns requires version 1.7.

Julia 1.10

The io::IO argument requires version 1.10.

Examples

julia> replace("Python is a programming language.", "Python" => "Julia")
+"ex̂a"
source
Base.replaceMethod
replace([io::IO], s::AbstractString, pat=>r, [pat2=>r2, ...]; [count::Integer])

Search for the given pattern pat in s, and replace each occurrence with r. If count is provided, replace at most count occurrences. pat may be a single character, a vector or a set of characters, a string, or a regular expression. If r is a function, each occurrence is replaced with r(s) where s is the matched substring (when pat is a AbstractPattern or AbstractString) or character (when pat is an AbstractChar or a collection of AbstractChar). If pat is a regular expression and r is a SubstitutionString, then capture group references in r are replaced with the corresponding matched text. To remove instances of pat from string, set r to the empty String ("").

The return value is a new string after the replacements. If the io::IO argument is supplied, the transformed string is instead written to io (returning io). (For example, this can be used in conjunction with an IOBuffer to re-use a pre-allocated buffer array in-place.)

Multiple patterns can be specified, and they will be applied left-to-right simultaneously, so only one pattern will be applied to any character, and the patterns will only be applied to the input text, not the replacements.

Julia 1.7

Support for multiple patterns requires version 1.7.

Julia 1.10

The io::IO argument requires version 1.10.

Examples

julia> replace("Python is a programming language.", "Python" => "Julia")
 "Julia is a programming language."
 
 julia> replace("The quick foxes run quickly.", "quick" => "slow", count=1)
@@ -312,7 +312,7 @@
 "The quick buses run quickly."
 
 julia> replace("abcabc", "a" => "b", "b" => "c", r".+" => "a")
-"bca"
source
Base.eachsplitFunction
eachsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)
+"bca"
source
Base.eachsplitFunction
eachsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)
 eachsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false)

Split str on occurrences of the delimiter(s) dlm and return an iterator over the substrings. dlm can be any of the formats allowed by findnext's first argument (i.e. as a string, regular expression or a function), or as a single character or collection of characters.

If dlm is omitted, it defaults to isspace.

The optional keyword arguments are:

  • limit: the maximum size of the result. limit=0 implies no maximum (default)
  • keepempty: whether empty fields should be kept in the result. Default is false without a dlm argument, true with a dlm argument.

See also split.

Julia 1.8

The eachsplit function requires at least Julia 1.8.

Examples

julia> a = "Ma.rch"
 "Ma.rch"
 
@@ -322,21 +322,21 @@
 julia> collect(b)
 2-element Vector{SubString{String}}:
  "Ma"
- "rch"
source
Base.eachrsplitFunction
eachrsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)
+ "rch"
source
Base.eachrsplitFunction
eachrsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)
 eachrsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false)

Return an iterator over SubStrings of str, produced when splitting on the delimiter(s) dlm, and yielded in reverse order (from right to left). dlm can be any of the formats allowed by findprev's first argument (i.e. a string, a single character or a function), or a collection of characters.

If dlm is omitted, it defaults to isspace, and keepempty default to false.

The optional keyword arguments are:

  • If limit > 0, the iterator will split at most limit - 1 times before returning the rest of the string unsplit. limit < 1 implies no cap to splits (default).
  • keepempty: whether empty fields should be returned when iterating Default is false without a dlm argument, true with a dlm argument.

Note that unlike split, rsplit and eachsplit, this function iterates the substrings right to left as they occur in the input.

See also eachsplit, rsplit.

Julia 1.11

This function requires Julia 1.11 or later.

Examples

julia> a = "Ma.r.ch";
 
 julia> collect(eachrsplit(a, ".")) == ["ch", "r", "Ma"]
 true
 
 julia> collect(eachrsplit(a, "."; limit=2)) == ["ch", "Ma.r"]
-true
source
Base.splitFunction
split(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)
+true
source
Base.splitFunction
split(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)
 split(str::AbstractString; limit::Integer=0, keepempty::Bool=false)

Split str into an array of substrings on occurrences of the delimiter(s) dlm. dlm can be any of the formats allowed by findnext's first argument (i.e. as a string, regular expression or a function), or as a single character or collection of characters.

If dlm is omitted, it defaults to isspace.

The optional keyword arguments are:

  • limit: the maximum size of the result. limit=0 implies no maximum (default)
  • keepempty: whether empty fields should be kept in the result. Default is false without a dlm argument, true with a dlm argument.

See also rsplit, eachsplit.

Examples

julia> a = "Ma.rch"
 "Ma.rch"
 
 julia> split(a, ".")
 2-element Vector{SubString{String}}:
  "Ma"
- "rch"
source
Base.rsplitFunction
rsplit(s::AbstractString; limit::Integer=0, keepempty::Bool=false)
+ "rch"
source
Base.rsplitFunction
rsplit(s::AbstractString; limit::Integer=0, keepempty::Bool=false)
 rsplit(s::AbstractString, chars; limit::Integer=0, keepempty::Bool=true)

Similar to split, but starting from the end of the string.

Examples

julia> a = "M.a.r.c.h"
 "M.a.r.c.h"
 
@@ -355,31 +355,31 @@
 julia> rsplit(a, "."; limit=2)
 2-element Vector{SubString{String}}:
  "M.a.r.c"
- "h"
source
Base.stripFunction
strip([pred=isspace,] str::AbstractString) -> SubString
+ "h"
source
Base.stripFunction
strip([pred=isspace,] str::AbstractString) -> SubString
 strip(str::AbstractString, chars) -> SubString

Remove leading and trailing characters from str, either those specified by chars or those for which the function pred returns true.

The default behaviour is to remove leading and trailing whitespace and delimiters: see isspace for precise details.

The optional chars argument specifies which characters to remove: it can be a single character, vector or set of characters.

See also lstrip and rstrip.

Julia 1.2

The method which accepts a predicate function requires Julia 1.2 or later.

Examples

julia> strip("{3, 5}\n", ['{', '}', '\n'])
-"3, 5"
source
Base.lstripFunction
lstrip([pred=isspace,] str::AbstractString) -> SubString
+"3, 5"
source
Base.lstripFunction
lstrip([pred=isspace,] str::AbstractString) -> SubString
 lstrip(str::AbstractString, chars) -> SubString

Remove leading characters from str, either those specified by chars or those for which the function pred returns true.

The default behaviour is to remove leading whitespace and delimiters: see isspace for precise details.

The optional chars argument specifies which characters to remove: it can be a single character, or a vector or set of characters.

See also strip and rstrip.

Examples

julia> a = lpad("March", 20)
 "               March"
 
 julia> lstrip(a)
-"March"
source
Base.rstripFunction
rstrip([pred=isspace,] str::AbstractString) -> SubString
+"March"
source
Base.rstripFunction
rstrip([pred=isspace,] str::AbstractString) -> SubString
 rstrip(str::AbstractString, chars) -> SubString

Remove trailing characters from str, either those specified by chars or those for which the function pred returns true.

The default behaviour is to remove trailing whitespace and delimiters: see isspace for precise details.

The optional chars argument specifies which characters to remove: it can be a single character, or a vector or set of characters.

See also strip and lstrip.

Examples

julia> a = rpad("March", 20)
 "March               "
 
 julia> rstrip(a)
-"March"
source
Base.startswithFunction
startswith(s::AbstractString, prefix::Union{AbstractString,Base.Chars})

Return true if s starts with prefix, which can be a string, a character, or a tuple/vector/set of characters. If prefix is a tuple/vector/set of characters, test whether the first character of s belongs to that set.

See also endswith, contains.

Examples

julia> startswith("JuliaLang", "Julia")
-true
source
startswith(io::IO, prefix::Union{AbstractString,Base.Chars})

Check if an IO object starts with a prefix, which can be either a string, a character, or a tuple/vector/set of characters. See also peek.

source
startswith(prefix)

Create a function that checks whether its argument starts with prefix, i.e. a function equivalent to y -> startswith(y, prefix).

The returned function is of type Base.Fix2{typeof(startswith)}, which can be used to implement specialized methods.

Julia 1.5

The single argument startswith(prefix) requires at least Julia 1.5.

Examples

julia> startswith("Julia")("JuliaLang")
+"March"
source
Base.startswithFunction
startswith(s::AbstractString, prefix::Union{AbstractString,Base.Chars})

Return true if s starts with prefix, which can be a string, a character, or a tuple/vector/set of characters. If prefix is a tuple/vector/set of characters, test whether the first character of s belongs to that set.

See also endswith, contains.

Examples

julia> startswith("JuliaLang", "Julia")
+true
source
startswith(io::IO, prefix::Union{AbstractString,Base.Chars})

Check if an IO object starts with a prefix, which can be either a string, a character, or a tuple/vector/set of characters. See also peek.

source
startswith(prefix)

Create a function that checks whether its argument starts with prefix, i.e. a function equivalent to y -> startswith(y, prefix).

The returned function is of type Base.Fix2{typeof(startswith)}, which can be used to implement specialized methods.

Julia 1.5

The single argument startswith(prefix) requires at least Julia 1.5.

Examples

julia> startswith("Julia")("JuliaLang")
 true
 
 julia> startswith("Julia")("Ends with Julia")
-false
source
startswith(s::AbstractString, prefix::Regex)

Return true if s starts with the regex pattern, prefix.

Note

startswith does not compile the anchoring into the regular expression, but instead passes the anchoring as match_option to PCRE. If compile time is amortized, occursin(r"^...", s) is faster than startswith(s, r"...").

See also occursin and endswith.

Julia 1.2

This method requires at least Julia 1.2.

Examples

julia> startswith("JuliaLang", r"Julia|Romeo")
-true
source
Base.endswithFunction
endswith(s::AbstractString, suffix::Union{AbstractString,Base.Chars})

Return true if s ends with suffix, which can be a string, a character, or a tuple/vector/set of characters. If suffix is a tuple/vector/set of characters, test whether the last character of s belongs to that set.

See also startswith, contains.

Examples

julia> endswith("Sunday", "day")
-true
source
endswith(suffix)

Create a function that checks whether its argument ends with suffix, i.e. a function equivalent to y -> endswith(y, suffix).

The returned function is of type Base.Fix2{typeof(endswith)}, which can be used to implement specialized methods.

Julia 1.5

The single argument endswith(suffix) requires at least Julia 1.5.

Examples

julia> endswith("Julia")("Ends with Julia")
+false
source
startswith(s::AbstractString, prefix::Regex)

Return true if s starts with the regex pattern, prefix.

Note

startswith does not compile the anchoring into the regular expression, but instead passes the anchoring as match_option to PCRE. If compile time is amortized, occursin(r"^...", s) is faster than startswith(s, r"...").

See also occursin and endswith.

Julia 1.2

This method requires at least Julia 1.2.

Examples

julia> startswith("JuliaLang", r"Julia|Romeo")
+true
source
Base.endswithFunction
endswith(s::AbstractString, suffix::Union{AbstractString,Base.Chars})

Return true if s ends with suffix, which can be a string, a character, or a tuple/vector/set of characters. If suffix is a tuple/vector/set of characters, test whether the last character of s belongs to that set.

See also startswith, contains.

Examples

julia> endswith("Sunday", "day")
+true
source
endswith(suffix)

Create a function that checks whether its argument ends with suffix, i.e. a function equivalent to y -> endswith(y, suffix).

The returned function is of type Base.Fix2{typeof(endswith)}, which can be used to implement specialized methods.

Julia 1.5

The single argument endswith(suffix) requires at least Julia 1.5.

Examples

julia> endswith("Julia")("Ends with Julia")
 true
 
 julia> endswith("Julia")("JuliaLang")
-false
source
endswith(s::AbstractString, suffix::Regex)

Return true if s ends with the regex pattern, suffix.

Note

endswith does not compile the anchoring into the regular expression, but instead passes the anchoring as match_option to PCRE. If compile time is amortized, occursin(r"...$", s) is faster than endswith(s, r"...").

See also occursin and startswith.

Julia 1.2

This method requires at least Julia 1.2.

Examples

julia> endswith("JuliaLang", r"Lang|Roberts")
-true
source
Base.containsFunction
contains(haystack::AbstractString, needle)

Return true if haystack contains needle. This is the same as occursin(needle, haystack), but is provided for consistency with startswith(haystack, needle) and endswith(haystack, needle).

See also occursin, in, issubset.

Examples

julia> contains("JuliaLang is pretty cool!", "Julia")
+false
source
endswith(s::AbstractString, suffix::Regex)

Return true if s ends with the regex pattern, suffix.

Note

endswith does not compile the anchoring into the regular expression, but instead passes the anchoring as match_option to PCRE. If compile time is amortized, occursin(r"...$", s) is faster than endswith(s, r"...").

See also occursin and startswith.

Julia 1.2

This method requires at least Julia 1.2.

Examples

julia> endswith("JuliaLang", r"Lang|Roberts")
+true
source
Base.containsFunction
contains(haystack::AbstractString, needle)

Return true if haystack contains needle. This is the same as occursin(needle, haystack), but is provided for consistency with startswith(haystack, needle) and endswith(haystack, needle).

See also occursin, in, issubset.

Examples

julia> contains("JuliaLang is pretty cool!", "Julia")
 true
 
 julia> contains("JuliaLang is pretty cool!", 'a')
@@ -389,51 +389,51 @@
 true
 
 julia> contains("abba", r"a.a")
-false
Julia 1.5

The contains function requires at least Julia 1.5.

source
contains(needle)

Create a function that checks whether its argument contains needle, i.e. a function equivalent to haystack -> contains(haystack, needle).

The returned function is of type Base.Fix2{typeof(contains)}, which can be used to implement specialized methods.

source
Base.firstMethod
first(s::AbstractString, n::Integer)

Get a string consisting of the first n characters of s.

Examples

julia> first("∀ϵ≠0: ϵ²>0", 0)
+false
Julia 1.5

The contains function requires at least Julia 1.5.

source
contains(needle)

Create a function that checks whether its argument contains needle, i.e. a function equivalent to haystack -> contains(haystack, needle).

The returned function is of type Base.Fix2{typeof(contains)}, which can be used to implement specialized methods.

source
Base.firstMethod
first(s::AbstractString, n::Integer)

Get a string consisting of the first n characters of s.

Examples

julia> first("∀ϵ≠0: ϵ²>0", 0)
 ""
 
 julia> first("∀ϵ≠0: ϵ²>0", 1)
 "∀"
 
 julia> first("∀ϵ≠0: ϵ²>0", 3)
-"∀ϵ≠"
source
Base.lastMethod
last(s::AbstractString, n::Integer)

Get a string consisting of the last n characters of s.

Examples

julia> last("∀ϵ≠0: ϵ²>0", 0)
+"∀ϵ≠"
source
Base.lastMethod
last(s::AbstractString, n::Integer)

Get a string consisting of the last n characters of s.

Examples

julia> last("∀ϵ≠0: ϵ²>0", 0)
 ""
 
 julia> last("∀ϵ≠0: ϵ²>0", 1)
 "0"
 
 julia> last("∀ϵ≠0: ϵ²>0", 3)
-"²>0"
source
Base.Unicode.uppercaseFunction
uppercase(c::AbstractChar)

Convert c to uppercase.

See also lowercase, titlecase.

Examples

julia> uppercase('a')
 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
 
 julia> uppercase('ê')
-'Ê': Unicode U+00CA (category Lu: Letter, uppercase)
source
uppercase(s::AbstractString)

Return s with all characters converted to uppercase.

See also lowercase, titlecase, uppercasefirst.

Examples

julia> uppercase("Julia")
-"JULIA"
source
Base.Unicode.lowercaseFunction
lowercase(c::AbstractChar)

Convert c to lowercase.

See also uppercase, titlecase.

Examples

julia> lowercase('A')
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
 
 julia> lowercase('Ö')
-'ö': Unicode U+00F6 (category Ll: Letter, lowercase)
source
lowercase(s::AbstractString)

Return s with all characters converted to lowercase.

See also uppercase, titlecase, lowercasefirst.

Examples

julia> lowercase("STRINGS AND THINGS")
-"strings and things"
source
Base.Unicode.titlecaseFunction
titlecase(c::AbstractChar)

Convert c to titlecase. This may differ from uppercase for digraphs, compare the example below.

See also uppercase, lowercase.

Examples

julia> titlecase('a')
+'ö': Unicode U+00F6 (category Ll: Letter, lowercase)
source
lowercase(s::AbstractString)

Return s with all characters converted to lowercase.

See also uppercase, titlecase, lowercasefirst.

Examples

julia> lowercase("STRINGS AND THINGS")
+"strings and things"
source
Base.Unicode.titlecaseFunction
titlecase(c::AbstractChar)

Convert c to titlecase. This may differ from uppercase for digraphs, compare the example below.

See also uppercase, lowercase.

Examples

julia> titlecase('a')
 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
 
 julia> titlecase('dž')
 'Dž': Unicode U+01C5 (category Lt: Letter, titlecase)
 
 julia> uppercase('dž')
-'DŽ': Unicode U+01C4 (category Lu: Letter, uppercase)
source
titlecase(s::AbstractString; [wordsep::Function], strict::Bool=true) -> String

Capitalize the first character of each word in s; if strict is true, every other character is converted to lowercase, otherwise they are left unchanged. By default, all non-letters beginning a new grapheme are considered as word separators; a predicate can be passed as the wordsep keyword to determine which characters should be considered as word separators. See also uppercasefirst to capitalize only the first character in s.

See also uppercase, lowercase, uppercasefirst.

Examples

julia> titlecase("the JULIA programming language")
+'DŽ': Unicode U+01C4 (category Lu: Letter, uppercase)
source
titlecase(s::AbstractString; [wordsep::Function], strict::Bool=true) -> String

Capitalize the first character of each word in s; if strict is true, every other character is converted to lowercase, otherwise they are left unchanged. By default, all non-letters beginning a new grapheme are considered as word separators; a predicate can be passed as the wordsep keyword to determine which characters should be considered as word separators. See also uppercasefirst to capitalize only the first character in s.

See also uppercase, lowercase, uppercasefirst.

Examples

julia> titlecase("the JULIA programming language")
 "The Julia Programming Language"
 
 julia> titlecase("ISS - international space station", strict=false)
 "ISS - International Space Station"
 
 julia> titlecase("a-a b-b", wordsep = c->c==' ')
-"A-a B-b"
source
Base.joinFunction
join([io::IO,] iterator [, delim [, last]])

Join any iterator into a single string, inserting the given delimiter (if any) between adjacent items. If last is given, it will be used instead of delim between the last two items. Each item of iterator is converted to a string via print(io::IOBuffer, x). If io is given, the result is written to io rather than returned as a String.

Examples

julia> join(["apples", "bananas", "pineapples"], ", ", " and ")
+"A-a B-b"
source
Base.joinFunction
join([io::IO,] iterator [, delim [, last]])

Join any iterator into a single string, inserting the given delimiter (if any) between adjacent items. If last is given, it will be used instead of delim between the last two items. Each item of iterator is converted to a string via print(io::IOBuffer, x). If io is given, the result is written to io rather than returned as a String.

Examples

julia> join(["apples", "bananas", "pineapples"], ", ", " and ")
 "apples, bananas and pineapples"
 
 julia> join([1,2,3,4,5])
-"12345"
source
Base.chopFunction
chop(s::AbstractString; head::Integer = 0, tail::Integer = 1)

Remove the first head and the last tail characters from s. The call chop(s) removes the last character from s. If it is requested to remove more characters than length(s) then an empty string is returned.

See also chomp, startswith, first.

Examples

julia> a = "March"
+"12345"
source
Base.chopFunction
chop(s::AbstractString; head::Integer = 0, tail::Integer = 1)

Remove the first head and the last tail characters from s. The call chop(s) removes the last character from s. If it is requested to remove more characters than length(s) then an empty string is returned.

See also chomp, startswith, first.

Examples

julia> a = "March"
 "March"
 
 julia> chop(a)
@@ -443,16 +443,16 @@
 "ar"
 
 julia> chop(a, head = 5, tail = 5)
-""
source
Base.chopprefixFunction
chopprefix(s::AbstractString, prefix::Union{AbstractString,Regex}) -> SubString

Remove the prefix prefix from s. If s does not start with prefix, a string equal to s is returned.

See also chopsuffix.

Julia 1.8

This function is available as of Julia 1.8.

Examples

julia> chopprefix("Hamburger", "Ham")
+""
source
Base.chopprefixFunction
chopprefix(s::AbstractString, prefix::Union{AbstractString,Regex}) -> SubString

Remove the prefix prefix from s. If s does not start with prefix, a string equal to s is returned.

See also chopsuffix.

Julia 1.8

This function is available as of Julia 1.8.

Examples

julia> chopprefix("Hamburger", "Ham")
 "burger"
 
 julia> chopprefix("Hamburger", "hotdog")
-"Hamburger"
source
Base.chopsuffixFunction
chopsuffix(s::AbstractString, suffix::Union{AbstractString,Regex}) -> SubString

Remove the suffix suffix from s. If s does not end with suffix, a string equal to s is returned.

See also chopprefix.

Julia 1.8

This function is available as of Julia 1.8.

Examples

julia> chopsuffix("Hamburger", "er")
+"Hamburger"
source
Base.chopsuffixFunction
chopsuffix(s::AbstractString, suffix::Union{AbstractString,Regex}) -> SubString

Remove the suffix suffix from s. If s does not end with suffix, a string equal to s is returned.

See also chopprefix.

Julia 1.8

This function is available as of Julia 1.8.

Examples

julia> chopsuffix("Hamburger", "er")
 "Hamburg"
 
 julia> chopsuffix("Hamburger", "hotdog")
-"Hamburger"
source
Base.chompFunction
chomp(s::AbstractString) -> SubString

Remove a single trailing newline from a string.

See also chop.

Examples

julia> chomp("Hello\n")
-"Hello"
source
Base.thisindFunction
thisind(s::AbstractString, i::Integer) -> Int

If i is in bounds in s return the index of the start of the character whose encoding code unit i is part of. In other words, if i is the start of a character, return i; if i is not the start of a character, rewind until the start of a character and return that index. If i is equal to 0 or ncodeunits(s)+1 return i. In all other cases throw BoundsError.

Examples

julia> thisind("α", 0)
+"Hamburger"
source
Base.chompFunction
chomp(s::AbstractString) -> SubString

Remove a single trailing newline from a string.

See also chop.

Examples

julia> chomp("Hello\n")
+"Hello"
source
Base.thisindFunction
thisind(s::AbstractString, i::Integer) -> Int

If i is in bounds in s return the index of the start of the character whose encoding code unit i is part of. In other words, if i is the start of a character, return i; if i is not the start of a character, rewind until the start of a character and return that index. If i is equal to 0 or ncodeunits(s)+1 return i. In all other cases throw BoundsError.

Examples

julia> thisind("α", 0)
 0
 
 julia> thisind("α", 1)
@@ -470,7 +470,7 @@
 
 julia> thisind("α", -1)
 ERROR: BoundsError: attempt to access 2-codeunit String at index [-1]
-[...]
source
Base.nextindMethod
nextind(str::AbstractString, i::Integer, n::Integer=1) -> Int
  • Case n == 1

    If i is in bounds in s return the index of the start of the character whose encoding starts after index i. In other words, if i is the start of a character, return the start of the next character; if i is not the start of a character, move forward until the start of a character and return that index. If i is equal to 0 return 1. If i is in bounds but greater or equal to lastindex(str) return ncodeunits(str)+1. Otherwise throw BoundsError.

  • Case n > 1

    Behaves like applying n times nextind for n==1. The only difference is that if n is so large that applying nextind would reach ncodeunits(str)+1 then each remaining iteration increases the returned value by 1. This means that in this case nextind can return a value greater than ncodeunits(str)+1.

  • Case n == 0

    Return i only if i is a valid index in s or is equal to 0. Otherwise StringIndexError or BoundsError is thrown.

Examples

julia> nextind("α", 0)
+[...]
source
Base.nextindMethod
nextind(str::AbstractString, i::Integer, n::Integer=1) -> Int
  • Case n == 1

    If i is in bounds in s return the index of the start of the character whose encoding starts after index i. In other words, if i is the start of a character, return the start of the next character; if i is not the start of a character, move forward until the start of a character and return that index. If i is equal to 0 return 1. If i is in bounds but greater or equal to lastindex(str) return ncodeunits(str)+1. Otherwise throw BoundsError.

  • Case n > 1

    Behaves like applying n times nextind for n==1. The only difference is that if n is so large that applying nextind would reach ncodeunits(str)+1 then each remaining iteration increases the returned value by 1. This means that in this case nextind can return a value greater than ncodeunits(str)+1.

  • Case n == 0

    Return i only if i is a valid index in s or is equal to 0. Otherwise StringIndexError or BoundsError is thrown.

Examples

julia> nextind("α", 0)
 1
 
 julia> nextind("α", 1)
@@ -484,7 +484,7 @@
 3
 
 julia> nextind("α", 1, 2)
-4
source
Base.previndMethod
prevind(str::AbstractString, i::Integer, n::Integer=1) -> Int
  • Case n == 1

    If i is in bounds in s return the index of the start of the character whose encoding starts before index i. In other words, if i is the start of a character, return the start of the previous character; if i is not the start of a character, rewind until the start of a character and return that index. If i is equal to 1 return 0. If i is equal to ncodeunits(str)+1 return lastindex(str). Otherwise throw BoundsError.

  • Case n > 1

    Behaves like applying n times prevind for n==1. The only difference is that if n is so large that applying prevind would reach 0 then each remaining iteration decreases the returned value by 1. This means that in this case prevind can return a negative value.

  • Case n == 0

    Return i only if i is a valid index in str or is equal to ncodeunits(str)+1. Otherwise StringIndexError or BoundsError is thrown.

Examples

julia> prevind("α", 3)
+4
source
Base.previndMethod
prevind(str::AbstractString, i::Integer, n::Integer=1) -> Int
  • Case n == 1

    If i is in bounds in s return the index of the start of the character whose encoding starts before index i. In other words, if i is the start of a character, return the start of the previous character; if i is not the start of a character, rewind until the start of a character and return that index. If i is equal to 1 return 0. If i is equal to ncodeunits(str)+1 return lastindex(str). Otherwise throw BoundsError.

  • Case n > 1

    Behaves like applying n times prevind for n==1. The only difference is that if n is so large that applying prevind would reach 0 then each remaining iteration decreases the returned value by 1. This means that in this case prevind can return a negative value.

  • Case n == 0

    Return i only if i is a valid index in str or is equal to ncodeunits(str)+1. Otherwise StringIndexError or BoundsError is thrown.

Examples

julia> prevind("α", 3)
 1
 
 julia> prevind("α", 1)
@@ -498,12 +498,12 @@
 0
 
 julia> prevind("α", 2, 3)
--1
source
Base.Unicode.textwidthFunction
textwidth(c)

Give the number of columns needed to print a character.

Examples

julia> textwidth('α')
+-1
source
Base.Unicode.textwidthFunction
textwidth(c)

Give the number of columns needed to print a character.

Examples

julia> textwidth('α')
 1
 
 julia> textwidth('⛵')
-2
source
textwidth(s::AbstractString)

Give the number of columns needed to print a string.

Examples

julia> textwidth("March")
-5
source
Base.isasciiFunction
isascii(c::Union{AbstractChar,AbstractString}) -> Bool

Test whether a character belongs to the ASCII character set, or whether this is true for all elements of a string.

Examples

julia> isascii('a')
+2
source
textwidth(s::AbstractString)

Give the number of columns needed to print a string.

Examples

julia> textwidth("March")
+5
source
Base.isasciiFunction
isascii(c::Union{AbstractChar,AbstractString}) -> Bool

Test whether a character belongs to the ASCII character set, or whether this is true for all elements of a string.

Examples

julia> isascii('a')
 true
 
 julia> isascii('α')
@@ -517,32 +517,32 @@
 "abcdefgh"
 
 julia> replace("abcdeγfgh", !isascii=>' ') # replace non-ASCII chars with spaces
-"abcde fgh"
source
isascii(cu::AbstractVector{CU}) where {CU <: Integer} -> Bool

Test whether all values in the vector belong to the ASCII character set (0x00 to 0x7f). This function is intended to be used by other string implementations that need a fast ASCII check.

source
Base.Unicode.iscntrlFunction
iscntrl(c::AbstractChar) -> Bool

Tests whether a character is a control character. Control characters are the non-printing characters of the Latin-1 subset of Unicode.

Examples

julia> iscntrl('\x01')
+"abcde fgh"
source
isascii(cu::AbstractVector{CU}) where {CU <: Integer} -> Bool

Test whether all values in the vector belong to the ASCII character set (0x00 to 0x7f). This function is intended to be used by other string implementations that need a fast ASCII check.

source
Base.Unicode.iscntrlFunction
iscntrl(c::AbstractChar) -> Bool

Tests whether a character is a control character. Control characters are the non-printing characters of the Latin-1 subset of Unicode.

Examples

julia> iscntrl('\x01')
 true
 
 julia> iscntrl('a')
-false
source
Base.Unicode.isdigitFunction
isdigit(c::AbstractChar) -> Bool

Tests whether a character is a decimal digit (0-9).

See also: isletter.

Examples

julia> isdigit('❤')
+false
source
Base.Unicode.isdigitFunction
isdigit(c::AbstractChar) -> Bool

Tests whether a character is a decimal digit (0-9).

See also: isletter.

Examples

julia> isdigit('❤')
 false
 
 julia> isdigit('9')
 true
 
 julia> isdigit('α')
-false
source
Base.Unicode.isletterFunction
isletter(c::AbstractChar) -> Bool

Test whether a character is a letter. A character is classified as a letter if it belongs to the Unicode general category Letter, i.e. a character whose category code begins with 'L'.

See also: isdigit.

Examples

julia> isletter('❤')
+false
source
Base.Unicode.isletterFunction
isletter(c::AbstractChar) -> Bool

Test whether a character is a letter. A character is classified as a letter if it belongs to the Unicode general category Letter, i.e. a character whose category code begins with 'L'.

See also: isdigit.

Examples

julia> isletter('❤')
 false
 
 julia> isletter('α')
 true
 
 julia> isletter('9')
-false
source
Base.Unicode.islowercaseFunction
islowercase(c::AbstractChar) -> Bool

Tests whether a character is a lowercase letter (according to the Unicode standard's Lowercase derived property).

See also isuppercase.

Examples

julia> islowercase('α')
+false
source
Base.Unicode.islowercaseFunction
islowercase(c::AbstractChar) -> Bool

Tests whether a character is a lowercase letter (according to the Unicode standard's Lowercase derived property).

See also isuppercase.

Examples

julia> islowercase('α')
 true
 
 julia> islowercase('Γ')
 false
 
 julia> islowercase('❤')
-false
source
Base.Unicode.isnumericFunction
isnumeric(c::AbstractChar) -> Bool

Tests whether a character is numeric. A character is classified as numeric if it belongs to the Unicode general category Number, i.e. a character whose category code begins with 'N'.

Note that this broad category includes characters such as ¾ and ௰. Use isdigit to check whether a character is a decimal digit between 0 and 9.

Examples

julia> isnumeric('௰')
+false
source
Base.Unicode.isnumericFunction
isnumeric(c::AbstractChar) -> Bool

Tests whether a character is numeric. A character is classified as numeric if it belongs to the Unicode general category Number, i.e. a character whose category code begins with 'N'.

Note that this broad category includes characters such as ¾ and ௰. Use isdigit to check whether a character is a decimal digit between 0 and 9.

Examples

julia> isnumeric('௰')
 true
 
 julia> isnumeric('9')
@@ -552,18 +552,18 @@
 false
 
 julia> isnumeric('❤')
-false
source
Base.Unicode.isprintFunction
isprint(c::AbstractChar) -> Bool

Tests whether a character is printable, including spaces, but not a control character.

Examples

julia> isprint('\x01')
+false
source
Base.Unicode.isprintFunction
isprint(c::AbstractChar) -> Bool

Tests whether a character is printable, including spaces, but not a control character.

Examples

julia> isprint('\x01')
 false
 
 julia> isprint('A')
-true
source
Base.Unicode.ispunctFunction
ispunct(c::AbstractChar) -> Bool

Tests whether a character belongs to the Unicode general category Punctuation, i.e. a character whose category code begins with 'P'.

Examples

julia> ispunct('α')
+true
source
Base.Unicode.ispunctFunction
ispunct(c::AbstractChar) -> Bool

Tests whether a character belongs to the Unicode general category Punctuation, i.e. a character whose category code begins with 'P'.

Examples

julia> ispunct('α')
 false
 
 julia> ispunct('/')
 true
 
 julia> ispunct(';')
-true
source
Base.Unicode.isspaceFunction
isspace(c::AbstractChar) -> Bool

Tests whether a character is any whitespace character. Includes ASCII characters '\t', '\n', '\v', '\f', '\r', and ' ', Latin-1 character U+0085, and characters in Unicode category Zs.

Examples

julia> isspace('\n')
+true
source
Base.Unicode.isspaceFunction
isspace(c::AbstractChar) -> Bool

Tests whether a character is any whitespace character. Includes ASCII characters '\t', '\n', '\v', '\f', '\r', and ' ', Latin-1 character U+0085, and characters in Unicode category Zs.

Examples

julia> isspace('\n')
 true
 
 julia> isspace('\r')
@@ -573,18 +573,18 @@
 true
 
 julia> isspace('\x20')
-true
source
Base.Unicode.isuppercaseFunction
isuppercase(c::AbstractChar) -> Bool

Tests whether a character is an uppercase letter (according to the Unicode standard's Uppercase derived property).

See also islowercase.

Examples

julia> isuppercase('γ')
+true
source
Base.Unicode.isuppercaseFunction
isuppercase(c::AbstractChar) -> Bool

Tests whether a character is an uppercase letter (according to the Unicode standard's Uppercase derived property).

See also islowercase.

Examples

julia> isuppercase('γ')
 false
 
 julia> isuppercase('Γ')
 true
 
 julia> isuppercase('❤')
-false
source
Base.Unicode.isxdigitFunction
isxdigit(c::AbstractChar) -> Bool

Test whether a character is a valid hexadecimal digit. Note that this does not include x (as in the standard 0x prefix).

Examples

julia> isxdigit('a')
+false
source
Base.Unicode.isxdigitFunction
isxdigit(c::AbstractChar) -> Bool

Test whether a character is a valid hexadecimal digit. Note that this does not include x (as in the standard 0x prefix).

Examples

julia> isxdigit('a')
 true
 
 julia> isxdigit('x')
-false
source
Base.escape_stringFunction
escape_string(str::AbstractString[, esc]; keep = ())::AbstractString
 escape_string(io, str::AbstractString[, esc]; keep = ())::Nothing

General escaping of traditional C and Unicode escape sequences. The first form returns the escaped string, the second prints the result to io.

Backslashes (\) are escaped with a double-backslash ("\\"). Non-printable characters are escaped either with their standard C escape codes, "\0" for NUL (if unambiguous), unicode code point ("\u" prefix) or hex ("\x" prefix).

The optional esc argument specifies any additional characters that should also be escaped by a prepending backslash (" is also escaped by default in the first form).

The argument keep specifies a collection of characters which are to be kept as they are. Notice that esc has precedence here.

See also unescape_string for the reverse operation.

Julia 1.7

The keep argument is available as of Julia 1.7.

Examples

julia> escape_string("aaa\nbbb")
 "aaa\\nbbb"
 
@@ -598,8 +598,8 @@
 "ℵ\\0"
 
 julia> escape_string(string('\u2135','\0','0')) # \0 would be ambiguous
-"ℵ\\x000"
source
Base.escape_raw_stringFunction
escape_raw_string(s::AbstractString, delim='"') -> AbstractString
-escape_raw_string(io, s::AbstractString, delim='"')

Escape a string in the manner used for parsing raw string literals. For each double-quote (") character in input string s (or delim if specified), this function counts the number n of preceding backslash (\) characters, and then increases there the number of backslashes from n to 2n+1 (even for n = 0). It also doubles a sequence of backslashes at the end of the string.

This escaping convention is used in raw strings and other non-standard string literals. (It also happens to be the escaping convention expected by the Microsoft C/C++ compiler runtime when it parses a command-line string into the argv[] array.)

See also escape_string.

source
Base.escape_raw_stringFunction
escape_raw_string(s::AbstractString, delim='"') -> AbstractString
+escape_raw_string(io, s::AbstractString, delim='"')

Escape a string in the manner used for parsing raw string literals. For each double-quote (") character in input string s (or delim if specified), this function counts the number n of preceding backslash (\) characters, and then increases there the number of backslashes from n to 2n+1 (even for n = 0). It also doubles a sequence of backslashes at the end of the string.

This escaping convention is used in raw strings and other non-standard string literals. (It also happens to be the escaping convention expected by the Microsoft C/C++ compiler runtime when it parses a command-line string into the argv[] array.)

See also escape_string.

source
Base.unescape_stringFunction
unescape_string(str::AbstractString, keep = ())::AbstractString
 unescape_string(io, s::AbstractString, keep = ())::Nothing

General unescaping of traditional C and Unicode escape sequences. The first form returns the escaped string, the second prints the result to io. The argument keep specifies a collection of characters which (along with backlashes) are to be kept as they are.

The following escape sequences are recognised:

  • Escaped backslash (\\)
  • Escaped double-quote (\")
  • Standard C escape sequences (\a, \b, \t, \n, \v, \f, \r, \e)
  • Unicode BMP code points (\u with 1-4 trailing hex digits)
  • All Unicode code points (\U with 1-8 trailing hex digits; max value = 0010ffff)
  • Hex bytes (\x with 1-2 trailing hex digits)
  • Octal bytes (\ with 1-3 trailing octal digits)

See also escape_string.

Examples

julia> unescape_string("aaa\\nbbb") # C escape sequence
 "aaa\nbbb"
 
@@ -610,4 +610,4 @@
 "A"
 
 julia> unescape_string("aaa \\g \\n", ['g']) # using `keep` argument
-"aaa \\g \n"
source
+"aaa \\g \n"
source
diff --git a/en/v1.12-dev/devdocs/EscapeAnalysis/index.html b/en/v1.12-dev/devdocs/EscapeAnalysis/index.html index 14f7dc9bf7d1..b8f611935c96 100644 --- a/en/v1.12-dev/devdocs/EscapeAnalysis/index.html +++ b/en/v1.12-dev/devdocs/EscapeAnalysis/index.html @@ -463,4 +463,4 @@ ◌ └─── goto #14 ◌ 13 ─ Main.throw(%18)::Union{}└─── unreachable -◌ 14 ─ return %21

Analysis Usage

analyze_escapes is the entry point to analyze escape information of SSA-IR elements.

Most optimizations like SROA (sroa_pass!) are more effective when applied to an optimized source that the inlining pass (ssa_inlining_pass!) has simplified by resolving inter-procedural calls and expanding callee sources. Accordingly, analyze_escapes is also able to analyze post-inlining IR and collect escape information that is useful for certain memory-related optimizations.

However, since certain optimization passes like inlining can change control flows and eliminate dead code, they can break the inter-procedural validity of escape information. In particularity, in order to collect inter-procedurally valid escape information, we need to analyze a pre-inlining IR.

Because of this reason, analyze_escapes can analyze IRCode at any Julia-level optimization stage, and especially, it is supposed to be used at the following two stages:

Escape information derived by IPO EA is transformed to the ArgEscapeCache data structure and cached globally. By passing an appropriate get_escape_cache callback to analyze_escapes, the escape analysis can improve analysis accuracy by utilizing cached inter-procedural information of non-inlined callees that has been derived by previous IPO EA. More interestingly, it is also valid to use IPO EA escape information for type inference, e.g., inference accuracy can be improved by forming Const/PartialStruct/MustAlias of mutable object.

Core.Compiler.EscapeAnalysis.analyze_escapesFunction
analyze_escapes(ir::IRCode, nargs::Int, get_escape_cache) -> estate::EscapeState

Analyzes escape information in ir:

  • nargs: the number of actual arguments of the analyzed call
  • get_escape_cache(::MethodInstance) -> Union{Bool,ArgEscapeCache}: retrieves cached argument escape information
source
Core.Compiler.EscapeAnalysis.EscapeStateType
estate::EscapeState

Extended lattice that maps arguments and SSA values to escape information represented as EscapeInfo. Escape information imposed on SSA IR element x can be retrieved by estate[x].

source
Core.Compiler.EscapeAnalysis.EscapeInfoType
x::EscapeInfo

A lattice for escape information, which holds the following properties:

  • x.Analyzed::Bool: not formally part of the lattice, only indicates whether x has been analyzed
  • x.ReturnEscape::Bool: indicates x can escape to the caller via return
  • x.ThrownEscape::BitSet: records SSA statement numbers where x can be thrown as exception:
    • isempty(x.ThrownEscape): x will never be thrown in this call frame (the bottom)
    • pc ∈ x.ThrownEscape: x may be thrown at the SSA statement at pc
    • -1 ∈ x.ThrownEscape: x may be thrown at arbitrary points of this call frame (the top)
    This information will be used by escape_exception! to propagate potential escapes via exception.
  • x.AliasInfo::Union{Bool,IndexableFields,IndexableElements,Unindexable}: maintains all possible values that can be aliased to fields or array elements of x:
    • x.AliasInfo === false indicates the fields/elements of x aren't analyzed yet
    • x.AliasInfo === true indicates the fields/elements of x can't be analyzed, e.g. the type of x is not known or is not concrete and thus its fields/elements can't be known precisely
    • x.AliasInfo::IndexableFields records all the possible values that can be aliased to fields of object x with precise index information
    • x.AliasInfo::IndexableElements records all the possible values that can be aliased to elements of array x with precise index information
    • x.AliasInfo::Unindexable records all the possible values that can be aliased to fields/elements of x without precise index information
  • x.Liveness::BitSet: records SSA statement numbers where x should be live, e.g. to be used as a call argument, to be returned to a caller, or preserved for :foreigncall:
    • isempty(x.Liveness): x is never be used in this call frame (the bottom)
    • 0 ∈ x.Liveness also has the special meaning that it's a call argument of the currently analyzed call frame (and thus it's visible from the caller immediately).
    • pc ∈ x.Liveness: x may be used at the SSA statement at pc
    • -1 ∈ x.Liveness: x may be used at arbitrary points of this call frame (the top)

There are utility constructors to create common EscapeInfos, e.g.,

  • NoEscape(): the bottom(-like) element of this lattice, meaning it won't escape to anywhere
  • AllEscape(): the topmost element of this lattice, meaning it will escape to everywhere

analyze_escapes will transition these elements from the bottom to the top, in the same direction as Julia's native type inference routine. An abstract state will be initialized with the bottom(-like) elements:

  • the call arguments are initialized as ArgEscape(), whose Liveness property includes 0 to indicate that it is passed as a call argument and visible from a caller immediately
  • the other states are initialized as NotAnalyzed(), which is a special lattice element that is slightly lower than NoEscape, but at the same time doesn't represent any meaning other than it's not analyzed yet (thus it's not formally part of the lattice)
source

+◌ 14 ─ return %21

Analysis Usage

analyze_escapes is the entry point to analyze escape information of SSA-IR elements.

Most optimizations like SROA (sroa_pass!) are more effective when applied to an optimized source that the inlining pass (ssa_inlining_pass!) has simplified by resolving inter-procedural calls and expanding callee sources. Accordingly, analyze_escapes is also able to analyze post-inlining IR and collect escape information that is useful for certain memory-related optimizations.

However, since certain optimization passes like inlining can change control flows and eliminate dead code, they can break the inter-procedural validity of escape information. In particularity, in order to collect inter-procedurally valid escape information, we need to analyze a pre-inlining IR.

Because of this reason, analyze_escapes can analyze IRCode at any Julia-level optimization stage, and especially, it is supposed to be used at the following two stages:

Escape information derived by IPO EA is transformed to the ArgEscapeCache data structure and cached globally. By passing an appropriate get_escape_cache callback to analyze_escapes, the escape analysis can improve analysis accuracy by utilizing cached inter-procedural information of non-inlined callees that has been derived by previous IPO EA. More interestingly, it is also valid to use IPO EA escape information for type inference, e.g., inference accuracy can be improved by forming Const/PartialStruct/MustAlias of mutable object.

Core.Compiler.EscapeAnalysis.analyze_escapesFunction
analyze_escapes(ir::IRCode, nargs::Int, get_escape_cache) -> estate::EscapeState

Analyzes escape information in ir:

  • nargs: the number of actual arguments of the analyzed call
  • get_escape_cache(::MethodInstance) -> Union{Bool,ArgEscapeCache}: retrieves cached argument escape information
source
Core.Compiler.EscapeAnalysis.EscapeStateType
estate::EscapeState

Extended lattice that maps arguments and SSA values to escape information represented as EscapeInfo. Escape information imposed on SSA IR element x can be retrieved by estate[x].

source
Core.Compiler.EscapeAnalysis.EscapeInfoType
x::EscapeInfo

A lattice for escape information, which holds the following properties:

  • x.Analyzed::Bool: not formally part of the lattice, only indicates whether x has been analyzed
  • x.ReturnEscape::Bool: indicates x can escape to the caller via return
  • x.ThrownEscape::BitSet: records SSA statement numbers where x can be thrown as exception:
    • isempty(x.ThrownEscape): x will never be thrown in this call frame (the bottom)
    • pc ∈ x.ThrownEscape: x may be thrown at the SSA statement at pc
    • -1 ∈ x.ThrownEscape: x may be thrown at arbitrary points of this call frame (the top)
    This information will be used by escape_exception! to propagate potential escapes via exception.
  • x.AliasInfo::Union{Bool,IndexableFields,IndexableElements,Unindexable}: maintains all possible values that can be aliased to fields or array elements of x:
    • x.AliasInfo === false indicates the fields/elements of x aren't analyzed yet
    • x.AliasInfo === true indicates the fields/elements of x can't be analyzed, e.g. the type of x is not known or is not concrete and thus its fields/elements can't be known precisely
    • x.AliasInfo::IndexableFields records all the possible values that can be aliased to fields of object x with precise index information
    • x.AliasInfo::IndexableElements records all the possible values that can be aliased to elements of array x with precise index information
    • x.AliasInfo::Unindexable records all the possible values that can be aliased to fields/elements of x without precise index information
  • x.Liveness::BitSet: records SSA statement numbers where x should be live, e.g. to be used as a call argument, to be returned to a caller, or preserved for :foreigncall:
    • isempty(x.Liveness): x is never be used in this call frame (the bottom)
    • 0 ∈ x.Liveness also has the special meaning that it's a call argument of the currently analyzed call frame (and thus it's visible from the caller immediately).
    • pc ∈ x.Liveness: x may be used at the SSA statement at pc
    • -1 ∈ x.Liveness: x may be used at arbitrary points of this call frame (the top)

There are utility constructors to create common EscapeInfos, e.g.,

  • NoEscape(): the bottom(-like) element of this lattice, meaning it won't escape to anywhere
  • AllEscape(): the topmost element of this lattice, meaning it will escape to everywhere

analyze_escapes will transition these elements from the bottom to the top, in the same direction as Julia's native type inference routine. An abstract state will be initialized with the bottom(-like) elements:

  • the call arguments are initialized as ArgEscape(), whose Liveness property includes 0 to indicate that it is passed as a call argument and visible from a caller immediately
  • the other states are initialized as NotAnalyzed(), which is a special lattice element that is slightly lower than NoEscape, but at the same time doesn't represent any meaning other than it's not analyzed yet (thus it's not formally part of the lattice)
source

diff --git a/en/v1.12-dev/devdocs/aot/index.html b/en/v1.12-dev/devdocs/aot/index.html index dff4470fc8f1..eb205d69bca5 100644 --- a/en/v1.12-dev/devdocs/aot/index.html +++ b/en/v1.12-dev/devdocs/aot/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Ahead of Time Compilation

This document describes the design and structure of the ahead-of-time (AOT) compilation system in Julia. This system is used when generating system images and package images. Much of the implementation described here is located in aotcompile.cpp, staticdata.c, and processor.cpp

Introduction

Though Julia normally compiles code just-in-time (JIT), it is possible to compile code ahead of time and save the resulting code to a file. This can be useful for a number of reasons:

  1. To reduce the time it takes to start a Julia process.
  2. To reduce the time spent in the JIT compiler instead of executing code (time to first execution, TTFX).
  3. To reduce the amount of memory used by the JIT compiler.

High-Level Overview

The following descriptions are a snapshot of the current implementation details of the end-to-end pipeline that happens internally when the user compiles a new AOT module, such as occurs when they type using Foo. These details are likely to change over time as we implement better ways to handle them, so current implementations may not exactly match the dataflow and functions described below.

Compiling Code Images

Firstly, the methods that need to be compiled to native code must be identified. This can only be done by actually executing the code to be compiled, as the set of methods that need to be compiled depends on the types of the arguments passed to the methods, and method invocations with certain combinations of types may not be known until runtime. During this process, the exact methods that the compiler sees are tracked for later compilation, producing a compilation trace.

Note

Currently when compiling images, Julia runs the trace generation in a different process than the process performing the AOT compilation. This can have impacts when attempting to use a debugger during precompilation. The best way to debug precompilation with a debugger is to use the rr debugger, record the entire process tree, use rr ps to identify the relevant failing process, and then use rr replay -p PID to replay just the failing process.

Once the methods to be compiled have been identified, they are passed to the jl_create_system_image function. This function sets up a number of data structures that will be used when serializing native code to a file, and then calls jl_create_native with the array of methods. jl_create_native runs codegen on the methods produces one or more LLVM modules. jl_create_system_image then records some useful information about what codegen produced from the module(s).

The module(s) are then passed to jl_dump_native, along with the information recorded by jl_create_system_image. jl_dump_native contains the code necessary to serialize the module(s) to bitcode, object, or assembly files depending on the command-line options passed to Julia. The serialized code and information are then written to a file as an archive.

The final step is to run a system linker on the object files in the archive produced by jl_dump_native. Once this step is complete, a shared library containing the compiled code is produced.

Loading Code Images

When loading a code image, the shared library produced by the linker is loaded into memory. The system image data is then loaded from the shared library. This data contains information about the types, methods, and code instances that were compiled into the shared library. This data is used to restore the state of the runtime to what it was when the code image was compiled.

If the code image was compiled with multiversioning, the loader will pick the appropriate version of each function to use based on the CPU features available on the current machine.

For system images, since no other code has been loaded, the state of the runtime is now the same as it was when the code image was compiled. For package images, the environment may have changed compared to when the code was compiled, so each method must be checked against the global method table to determine if it is still valid code.

Compiling Methods

Tracing Compiled Methods

Julia has a command-line flag to record all of the methods that are compiled by the JIT compiler, --trace-compile=filename. When a function is compiled and this flag has a filename, Julia will print out a precompile statement to that file with the method and argument types it was called with. This therefore generates a precompile script that can be used later in the AOT compilation process. The PrecompileTools package has tooling that can make taking advantage of this functionality easier for package developers.

jl_create_system_image

jl_create_system_image saves all of the Julia-specific metadata necessary to later restore the state of the runtime. This includes data such as code instances, method instances, method tables, and type information. This function also sets up the data structures necessary to serialize the native code to a file. Finally, it calls jl_create_native to create one or more LLVM modules containing the native code for the methods passed to it. jl_create_native is responsible for running codegen on the methods passed to it.

jl_dump_native

jl_dump_native is responsible for serializing the LLVM module containing the native code to a file. In addition to the module, the system image data produced by jl_create_system_image is compiled as a global variable. The output of this method is bitcode, object, and/or assembly archives containing the code and system image data.

jl_dump_native is typically one of the larger time sinks when emitting native code, with much of the time spent in optimizing LLVM IR and emitting machine code. Therefore, this function is capable of multithreading the optimization and machine code emission steps. This multithreading is parameterized on the size of the module, but can be explicitly overridden by setting the JULIA_IMAGE_THREADS environment variable. The default maximum number of threads is half the number of available threads, but setting it to be lower can reduce peak memory usage during compilation.

jl_dump_native can also produce native code optimized for multiple architectures, when integrated with the Julia loader. This is triggered by setting the JULIA_CPU_TARGET environment variable and mediated by the multiversioning pass in the optimization pipeline. To make this work with multithreading, an annotation step is added before the module is split into submodules that are emitted on their own threads, and this annotation step uses information available throughout the entire module to decide what functions are cloned for different architectures. Once the annotation has happened, individual threads can emit code for different architectures in parallel, knowing that a different submodule is guaranteed to produce the necessary functions that will be called by a cloned function.

Some other metadata about how the module was serialized is also stored in the archive, such as the number of threads used to serialize the module and the number of functions that were compiled.

Static Linking

The final step in the AOT compilation process is to run a linker on the object files in the archive produced by jl_dump_native. This produces a shared library containing the compiled code. This shared library can then be loaded by Julia to restore the state of the runtime. When compiling a system image, the native linker used by a C compiler is used to produce the final shared library. For package images, the LLVM linker LLD is used to provide a more consistent linking interface.

Loading Code Images

Loading the Shared Library

The first step in loading a code image is to load the shared library produced by the linker. This is done by calling jl_dlopen on the path to the shared library. This function is responsible for loading the shared library and resolving all of the symbols in the library.

Loading Native Code

The loader first needs to identify whether the native code that was compiled is valid for the architecture that the loader is running on. This is necessary to avoid executing instructions that older CPUs do not recognize. This is done by checking the CPU features available on the current machine against the CPU features that the code was compiled for. When multiversioning is enabled, the loader will pick the appropriate version of each function to use based on the CPU features available on the current machine. If none of the feature sets that were multiversioned, the loader will throw an error.

Part of the multiversioning pass creates a number of global arrays of all of the functions in the module. When this process is multithreaded, an array of arrays is created, which the loader reorganizes into one large array with all of the functions that were compiled for this architecture. A similar process occurs for the global variables in the module.

Setting Up Julia State

The loader then uses the global variables and functions produced from loading native code to set up Julia runtime core data structures in the current process. This setup involves adding types and methods to the Julia runtime, and making the cached native code available for use by other Julia functions and the interpreter. For package images, each method must be validated, in that the global method table's state must match the state that the package image was compiled for. In particular, if a different set of methods exists at the load time compared to compile time of the package image, the method must be invalidated and recompiled on first use. This is necessary to ensure that execution semantics remain the same regardless of if a package was precompiled or if the code was directly executed. System images do not need to perform this validation, since the global method table is empty at load time. Thus, system images have faster load times than package images.

+

Ahead of Time Compilation

This document describes the design and structure of the ahead-of-time (AOT) compilation system in Julia. This system is used when generating system images and package images. Much of the implementation described here is located in aotcompile.cpp, staticdata.c, and processor.cpp

Introduction

Though Julia normally compiles code just-in-time (JIT), it is possible to compile code ahead of time and save the resulting code to a file. This can be useful for a number of reasons:

  1. To reduce the time it takes to start a Julia process.
  2. To reduce the time spent in the JIT compiler instead of executing code (time to first execution, TTFX).
  3. To reduce the amount of memory used by the JIT compiler.

High-Level Overview

The following descriptions are a snapshot of the current implementation details of the end-to-end pipeline that happens internally when the user compiles a new AOT module, such as occurs when they type using Foo. These details are likely to change over time as we implement better ways to handle them, so current implementations may not exactly match the dataflow and functions described below.

Compiling Code Images

Firstly, the methods that need to be compiled to native code must be identified. This can only be done by actually executing the code to be compiled, as the set of methods that need to be compiled depends on the types of the arguments passed to the methods, and method invocations with certain combinations of types may not be known until runtime. During this process, the exact methods that the compiler sees are tracked for later compilation, producing a compilation trace.

Note

Currently when compiling images, Julia runs the trace generation in a different process than the process performing the AOT compilation. This can have impacts when attempting to use a debugger during precompilation. The best way to debug precompilation with a debugger is to use the rr debugger, record the entire process tree, use rr ps to identify the relevant failing process, and then use rr replay -p PID to replay just the failing process.

Once the methods to be compiled have been identified, they are passed to the jl_create_system_image function. This function sets up a number of data structures that will be used when serializing native code to a file, and then calls jl_create_native with the array of methods. jl_create_native runs codegen on the methods produces one or more LLVM modules. jl_create_system_image then records some useful information about what codegen produced from the module(s).

The module(s) are then passed to jl_dump_native, along with the information recorded by jl_create_system_image. jl_dump_native contains the code necessary to serialize the module(s) to bitcode, object, or assembly files depending on the command-line options passed to Julia. The serialized code and information are then written to a file as an archive.

The final step is to run a system linker on the object files in the archive produced by jl_dump_native. Once this step is complete, a shared library containing the compiled code is produced.

Loading Code Images

When loading a code image, the shared library produced by the linker is loaded into memory. The system image data is then loaded from the shared library. This data contains information about the types, methods, and code instances that were compiled into the shared library. This data is used to restore the state of the runtime to what it was when the code image was compiled.

If the code image was compiled with multiversioning, the loader will pick the appropriate version of each function to use based on the CPU features available on the current machine.

For system images, since no other code has been loaded, the state of the runtime is now the same as it was when the code image was compiled. For package images, the environment may have changed compared to when the code was compiled, so each method must be checked against the global method table to determine if it is still valid code.

Compiling Methods

Tracing Compiled Methods

Julia has a command-line flag to record all of the methods that are compiled by the JIT compiler, --trace-compile=filename. When a function is compiled and this flag has a filename, Julia will print out a precompile statement to that file with the method and argument types it was called with. This therefore generates a precompile script that can be used later in the AOT compilation process. The PrecompileTools package has tooling that can make taking advantage of this functionality easier for package developers.

jl_create_system_image

jl_create_system_image saves all of the Julia-specific metadata necessary to later restore the state of the runtime. This includes data such as code instances, method instances, method tables, and type information. This function also sets up the data structures necessary to serialize the native code to a file. Finally, it calls jl_create_native to create one or more LLVM modules containing the native code for the methods passed to it. jl_create_native is responsible for running codegen on the methods passed to it.

jl_dump_native

jl_dump_native is responsible for serializing the LLVM module containing the native code to a file. In addition to the module, the system image data produced by jl_create_system_image is compiled as a global variable. The output of this method is bitcode, object, and/or assembly archives containing the code and system image data.

jl_dump_native is typically one of the larger time sinks when emitting native code, with much of the time spent in optimizing LLVM IR and emitting machine code. Therefore, this function is capable of multithreading the optimization and machine code emission steps. This multithreading is parameterized on the size of the module, but can be explicitly overridden by setting the JULIA_IMAGE_THREADS environment variable. The default maximum number of threads is half the number of available threads, but setting it to be lower can reduce peak memory usage during compilation.

jl_dump_native can also produce native code optimized for multiple architectures, when integrated with the Julia loader. This is triggered by setting the JULIA_CPU_TARGET environment variable and mediated by the multiversioning pass in the optimization pipeline. To make this work with multithreading, an annotation step is added before the module is split into submodules that are emitted on their own threads, and this annotation step uses information available throughout the entire module to decide what functions are cloned for different architectures. Once the annotation has happened, individual threads can emit code for different architectures in parallel, knowing that a different submodule is guaranteed to produce the necessary functions that will be called by a cloned function.

Some other metadata about how the module was serialized is also stored in the archive, such as the number of threads used to serialize the module and the number of functions that were compiled.

Static Linking

The final step in the AOT compilation process is to run a linker on the object files in the archive produced by jl_dump_native. This produces a shared library containing the compiled code. This shared library can then be loaded by Julia to restore the state of the runtime. When compiling a system image, the native linker used by a C compiler is used to produce the final shared library. For package images, the LLVM linker LLD is used to provide a more consistent linking interface.

Loading Code Images

Loading the Shared Library

The first step in loading a code image is to load the shared library produced by the linker. This is done by calling jl_dlopen on the path to the shared library. This function is responsible for loading the shared library and resolving all of the symbols in the library.

Loading Native Code

The loader first needs to identify whether the native code that was compiled is valid for the architecture that the loader is running on. This is necessary to avoid executing instructions that older CPUs do not recognize. This is done by checking the CPU features available on the current machine against the CPU features that the code was compiled for. When multiversioning is enabled, the loader will pick the appropriate version of each function to use based on the CPU features available on the current machine. If none of the feature sets that were multiversioned, the loader will throw an error.

Part of the multiversioning pass creates a number of global arrays of all of the functions in the module. When this process is multithreaded, an array of arrays is created, which the loader reorganizes into one large array with all of the functions that were compiled for this architecture. A similar process occurs for the global variables in the module.

Setting Up Julia State

The loader then uses the global variables and functions produced from loading native code to set up Julia runtime core data structures in the current process. This setup involves adding types and methods to the Julia runtime, and making the cached native code available for use by other Julia functions and the interpreter. For package images, each method must be validated, in that the global method table's state must match the state that the package image was compiled for. In particular, if a different set of methods exists at the load time compared to compile time of the package image, the method must be invalidated and recompiled on first use. This is necessary to ensure that execution semantics remain the same regardless of if a package was precompiled or if the code was directly executed. System images do not need to perform this validation, since the global method table is empty at load time. Thus, system images have faster load times than package images.

diff --git a/en/v1.12-dev/devdocs/ast/index.html b/en/v1.12-dev/devdocs/ast/index.html index 14fe1ebe9d84..bdd3c4a9ce6b 100644 --- a/en/v1.12-dev/devdocs/ast/index.html +++ b/en/v1.12-dev/devdocs/ast/index.html @@ -38,4 +38,4 @@ # index into linetable (if defined), else a line number (in the file represented by def) # then index into edges # then index into edges[linetable] -end

Special codes include: - (zero, zero, *) : no change to the line number or edges from the previous statement (you may choose to interpret this either syntactically or lexically). The inlining depth also might have changed, though most callers should ignore that. - (zero, non-zero, *) : no line number, just edges (usually because of macro-expansion into top-level code)

+end

Special codes include: - (zero, zero, *) : no change to the line number or edges from the previous statement (you may choose to interpret this either syntactically or lexically). The inlining depth also might have changed, though most callers should ignore that. - (zero, non-zero, *) : no line number, just edges (usually because of macro-expansion into top-level code)

diff --git a/en/v1.12-dev/devdocs/backtraces/index.html b/en/v1.12-dev/devdocs/backtraces/index.html index 1f1610205825..d9ebf7fef783 100644 --- a/en/v1.12-dev/devdocs/backtraces/index.html +++ b/en/v1.12-dev/devdocs/backtraces/index.html @@ -3,8 +3,8 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Reporting and analyzing crashes (segfaults)

So you managed to break Julia. Congratulations! Collected here are some general procedures you can undergo for common symptoms encountered when something goes awry. Including the information from these debugging steps can greatly help the maintainers when tracking down a segfault or trying to figure out why your script is running slower than expected.

If you've been directed to this page, find the symptom that best matches what you're experiencing and follow the instructions to generate the debugging information requested. Table of symptoms:

Version/Environment info

No matter the error, we will always need to know what version of Julia you are running. When Julia first starts up, a header is printed out with a version number and date. Please also include the output of versioninfo() (exported from the InteractiveUtils standard library) in any report you create:

julia> using InteractiveUtils
julia> versioninfo()Julia Version 1.12.0-DEV.246 -Commit 86a697c7fea (2024-03-26 09:20 UTC) +

Reporting and analyzing crashes (segfaults)

So you managed to break Julia. Congratulations! Collected here are some general procedures you can undergo for common symptoms encountered when something goes awry. Including the information from these debugging steps can greatly help the maintainers when tracking down a segfault or trying to figure out why your script is running slower than expected.

If you've been directed to this page, find the symptom that best matches what you're experiencing and follow the instructions to generate the debugging information requested. Table of symptoms:

Version/Environment info

No matter the error, we will always need to know what version of Julia you are running. When Julia first starts up, a header is printed out with a version number and date. Please also include the output of versioninfo() (exported from the InteractiveUtils standard library) in any report you create:

julia> using InteractiveUtils
julia> versioninfo()Julia Version 1.12.0-DEV.247 +Commit 64de065a183 (2024-03-26 12:56 UTC) Build Info: Official https://julialang.org/ release Platform Info: @@ -12,10 +12,10 @@ CPU: 128 × AMD EPYC 7502 32-Core Processor WORD_SIZE: 64 LLVM: libLLVM-16.0.6 (ORCJIT, znver2) -Threads: 1 default, 0 interactive, 1 GC (on 16 virtual cores) +Threads: 1 default, 0 interactive, 1 GC (on 128 virtual cores) Environment: JULIA_DEPOT_PATH = /cache/julia-buildkite-plugin/depots/53de1ea5-6dd3-4008-b976-161c9f34b0ad - JULIA_CPU_THREADS = 16 + JULIA_CPU_THREADS = 128 JULIA_NUM_THREADS = 1

Segfaults during bootstrap (sysimg.jl)

Segfaults toward the end of the make process of building Julia are a common symptom of something going wrong while Julia is preparsing the corpus of code in the base/ folder. Many factors can contribute toward this process dying unexpectedly, however it is as often as not due to an error in the C-code portion of Julia, and as such must typically be debugged with a debug build inside of gdb. Explicitly:

Create a debug build of Julia:

$ cd <julia_root>
 $ make debug

Note that this process will likely fail with the same error as a normal make incantation, however this will create a debug executable that will offer gdb the debugging symbols needed to get accurate backtraces. Next, manually run the bootstrap process inside of gdb:

$ cd base/
 $ gdb -x ../contrib/debug_bootstrap.gdb

This will start gdb, attempt to run the bootstrap process using the debug build of Julia, and print out a backtrace if (when) it segfaults. You may need to hit <enter> a few times to get the full backtrace. Create a gist with the backtrace, the version info, and any other pertinent information you can think of and open a new issue on Github with a link to the gist.

Segfaults when running a script

The procedure is very similar to Segfaults during bootstrap (sysimg.jl). Create a debug build of Julia, and run your script inside of a debugged Julia process:

$ cd <julia_root>
@@ -24,4 +24,4 @@
 Starting program: /home/sabae/src/julia/usr/bin/julia-debug ./test.jl
 ...
 (gdb) bt

Create a gist with the backtrace, the version info, and any other pertinent information you can think of and open a new issue on Github with a link to the gist.

Errors during Julia startup

Occasionally errors occur during Julia's startup process (especially when using binary distributions, as opposed to compiling from source) such as the following:

$ julia
-exec: error -5

These errors typically indicate something is not getting loaded properly very early on in the bootup phase, and our best bet in determining what's going wrong is to use external tools to audit the disk activity of the julia process:

  • On Linux, use strace:

    $ strace julia
  • On OSX, use dtruss:

    $ dtruss -f julia

Create a gist with the strace/ dtruss output, the version info, and any other pertinent information and open a new issue on Github with a link to the gist.

Other generic segfaults or unreachables reached

As mentioned elsewhere, julia has good integration with rr for generating traces; this includes, on Linux, the ability to automatically run julia under rr and share the trace after a crash. This can be immensely helpful when debugging such crashes and is strongly encouraged when reporting crash issues to the JuliaLang/julia repo. To run julia under rr automatically, do:

julia --bug-report=rr

To generate the rr trace locally, but not share, you can do:

julia --bug-report=rr-local

Note that this is only works on Linux. The blog post on Time Travelling Bug Reporting has many more details.

Glossary

A few terms have been used as shorthand in this guide:

  • <julia_root> refers to the root directory of the Julia source tree; e.g. it should contain folders such as base, deps, src, test, etc.....
+exec: error -5

These errors typically indicate something is not getting loaded properly very early on in the bootup phase, and our best bet in determining what's going wrong is to use external tools to audit the disk activity of the julia process:

  • On Linux, use strace:

    $ strace julia
  • On OSX, use dtruss:

    $ dtruss -f julia

Create a gist with the strace/ dtruss output, the version info, and any other pertinent information and open a new issue on Github with a link to the gist.

Other generic segfaults or unreachables reached

As mentioned elsewhere, julia has good integration with rr for generating traces; this includes, on Linux, the ability to automatically run julia under rr and share the trace after a crash. This can be immensely helpful when debugging such crashes and is strongly encouraged when reporting crash issues to the JuliaLang/julia repo. To run julia under rr automatically, do:

julia --bug-report=rr

To generate the rr trace locally, but not share, you can do:

julia --bug-report=rr-local

Note that this is only works on Linux. The blog post on Time Travelling Bug Reporting has many more details.

Glossary

A few terms have been used as shorthand in this guide:

  • <julia_root> refers to the root directory of the Julia source tree; e.g. it should contain folders such as base, deps, src, test, etc.....
diff --git a/en/v1.12-dev/devdocs/boundscheck/index.html b/en/v1.12-dev/devdocs/boundscheck/index.html index c0615fe599db..4fbdaa8d8a61 100644 --- a/en/v1.12-dev/devdocs/boundscheck/index.html +++ b/en/v1.12-dev/devdocs/boundscheck/index.html @@ -19,4 +19,4 @@ julia> sum(OffsetArray([1, 2, 3], -10)) 9164911648 # inconsistent results or segfault

While the original source of the error here is 1:length(A), the use of @inbounds increases the consequences from a bounds error to a less easily caught and debugged unsafe memory access. It is often difficult or impossible to prove that a method which uses @inbounds is safe, so one must weigh the benefits of performance improvements against the risk of segfaults and silent misbehavior, especially in public facing APIs.

Propagating inbounds

There may be certain scenarios where for code-organization reasons you want more than one layer between the @inbounds and @boundscheck declarations. For instance, the default getindex methods have the chain getindex(A::AbstractArray, i::Real) calls getindex(IndexStyle(A), A, i) calls _getindex(::IndexLinear, A, i).

To override the "one layer of inlining" rule, a function may be marked with Base.@propagate_inbounds to propagate an inbounds context (or out of bounds context) through one additional layer of inlining.

The bounds checking call hierarchy

The overall hierarchy is:

Here A is the array, and I contains the "requested" indices. axes(A) returns a tuple of "permitted" indices of A.

checkbounds(A, I...) throws an error if the indices are invalid, whereas checkbounds(Bool, A, I...) returns false in that circumstance. checkbounds_indices discards any information about the array other than its axes tuple, and performs a pure indices-vs-indices comparison: this allows relatively few compiled methods to serve a huge variety of array types. Indices are specified as tuples, and are usually compared in a 1-1 fashion with individual dimensions handled by calling another important function, checkindex: typically,

checkbounds_indices(Bool, (IA1, IA...), (I1, I...)) = checkindex(Bool, IA1, I1) &
-                                                      checkbounds_indices(Bool, IA, I)

so checkindex checks a single dimension. All of these functions, including the unexported checkbounds_indices have docstrings accessible with ? .

If you have to customize bounds checking for a specific array type, you should specialize checkbounds(Bool, A, I...). However, in most cases you should be able to rely on checkbounds_indices as long as you supply useful axes for your array type.

If you have novel index types, first consider specializing checkindex, which handles a single index for a particular dimension of an array. If you have a custom multidimensional index type (similar to CartesianIndex), then you may have to consider specializing checkbounds_indices.

Note this hierarchy has been designed to reduce the likelihood of method ambiguities. We try to make checkbounds the place to specialize on array type, and try to avoid specializations on index types; conversely, checkindex is intended to be specialized only on index type (especially, the last argument).

Emit bounds checks

Julia can be launched with --check-bounds={yes|no|auto} to emit bounds checks always, never, or respect @inbounds declarations.

+ checkbounds_indices(Bool, IA, I)

so checkindex checks a single dimension. All of these functions, including the unexported checkbounds_indices have docstrings accessible with ? .

If you have to customize bounds checking for a specific array type, you should specialize checkbounds(Bool, A, I...). However, in most cases you should be able to rely on checkbounds_indices as long as you supply useful axes for your array type.

If you have novel index types, first consider specializing checkindex, which handles a single index for a particular dimension of an array. If you have a custom multidimensional index type (similar to CartesianIndex), then you may have to consider specializing checkbounds_indices.

Note this hierarchy has been designed to reduce the likelihood of method ambiguities. We try to make checkbounds the place to specialize on array type, and try to avoid specializations on index types; conversely, checkindex is intended to be specialized only on index type (especially, the last argument).

Emit bounds checks

Julia can be launched with --check-bounds={yes|no|auto} to emit bounds checks always, never, or respect @inbounds declarations.

diff --git a/en/v1.12-dev/devdocs/build/arm/index.html b/en/v1.12-dev/devdocs/build/arm/index.html index 07b104d5ab86..5667ecbcc2ab 100644 --- a/en/v1.12-dev/devdocs/build/arm/index.html +++ b/en/v1.12-dev/devdocs/build/arm/index.html @@ -4,4 +4,4 @@ gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash});

ARM (Linux)

Julia fully supports ARMv8 (AArch64) processors, and supports ARMv7 and ARMv6 (AArch32) with some caveats. This file provides general guidelines for compilation, in addition to instructions for specific devices.

A list of known issues for ARM is available. If you encounter difficulties, please create an issue including the output from cat /proc/cpuinfo.

32-bit (ARMv6, ARMv7)

Julia has been successfully compiled on several variants of the following ARMv6 & ARMv7 devices:

  • ARMv7 / Cortex A15 Samsung Chromebooks running Ubuntu Linux under Crouton;
  • Raspberry Pi.
  • Odroid.

Julia requires at least the armv6 and vfpv2 instruction sets. It's recommended to use armv7-a. armv5 or soft float are not supported.

Raspberry Pi 1 / Raspberry Pi Zero

If the type of ARM CPU used in the Raspberry Pi is not detected by LLVM, then explicitly set the CPU target by adding the following to Make.user:

JULIA_CPU_TARGET=arm1176jzf-s

To complete the build, you may need to increase the swap file size. To do so, edit /etc/dphys-swapfile, changing the line:

CONF_SWAPSIZE=100

to:

CONF_SWAPSIZE=512

before restarting the swapfile service:

sudo /etc/init.d/dphys-swapfile stop
-sudo /etc/init.d/dphys-swapfile start

Raspberry Pi 2

The type of ARM CPU used in the Raspberry Pi 2 is not detected by LLVM. Explicitly set the CPU target by adding the following to Make.user:

JULIA_CPU_TARGET=cortex-a7

Depending on the exact compiler and distribution, there might be a build failure due to unsupported inline assembly. In that case, add MCPU=armv7-a to Make.user.

AArch64 (ARMv8)

Julia has been successfully built on the following ARMv8 devices:

Compilation on ARMv8-A requires that Make.user is configured as follows:

MCPU=armv8-a

Starting from Julia v1.10, JITLink is automatically enabled on this architecture for all operating systems when linking to LLVM 15 or later versions. Due to a bug in LLVM memory manager, non-trivial workloads may generate too many memory mappings that on Linux can exceed the limit of memory mappings (mmap) set in the file /proc/sys/vm/max_map_count, resulting in an error like

JIT session error: Cannot allocate memory

Should this happen, ask your system administrator to increase the limit of memory mappings for example with the command

sysctl -w vm.max_map_count=262144

nVidia Jetson TX2

Julia builds and runs on the nVidia Jetson TX2 platform with minimal configuration changes.

After configuring Make.user as per the AArch64 instructions in this document, follow the general build instructions. The majority of the build dependencies specified in the instructions are installed by the default configuration flashed by Jetpack 3.0. The remaining tools can be installed by issuing the following command:

sudo apt-get install gfortran wget cmake

A full parallel build, including LLVM, will complete in around two hours. All tests pass and CUDA functionality is available through, e.g., CUDAdrv.

+sudo /etc/init.d/dphys-swapfile start

Raspberry Pi 2

The type of ARM CPU used in the Raspberry Pi 2 is not detected by LLVM. Explicitly set the CPU target by adding the following to Make.user:

JULIA_CPU_TARGET=cortex-a7

Depending on the exact compiler and distribution, there might be a build failure due to unsupported inline assembly. In that case, add MCPU=armv7-a to Make.user.

AArch64 (ARMv8)

Julia has been successfully built on the following ARMv8 devices:

Compilation on ARMv8-A requires that Make.user is configured as follows:

MCPU=armv8-a

Starting from Julia v1.10, JITLink is automatically enabled on this architecture for all operating systems when linking to LLVM 15 or later versions. Due to a bug in LLVM memory manager, non-trivial workloads may generate too many memory mappings that on Linux can exceed the limit of memory mappings (mmap) set in the file /proc/sys/vm/max_map_count, resulting in an error like

JIT session error: Cannot allocate memory

Should this happen, ask your system administrator to increase the limit of memory mappings for example with the command

sysctl -w vm.max_map_count=262144

nVidia Jetson TX2

Julia builds and runs on the nVidia Jetson TX2 platform with minimal configuration changes.

After configuring Make.user as per the AArch64 instructions in this document, follow the general build instructions. The majority of the build dependencies specified in the instructions are installed by the default configuration flashed by Jetpack 3.0. The remaining tools can be installed by issuing the following command:

sudo apt-get install gfortran wget cmake

A full parallel build, including LLVM, will complete in around two hours. All tests pass and CUDA functionality is available through, e.g., CUDAdrv.

diff --git a/en/v1.12-dev/devdocs/build/build/index.html b/en/v1.12-dev/devdocs/build/build/index.html index 1739a40ad8b6..1dd10e0225d9 100644 --- a/en/v1.12-dev/devdocs/build/build/index.html +++ b/en/v1.12-dev/devdocs/build/build/index.html @@ -42,4 +42,4 @@ Patches: - [ ] `deps/$(libname).mk` -- [ ] `deps/patches/$(libname)-*.patch`

Note:

Example: OpenLibm

  1. Update Version numbers in deps/openlibm.version
  2. Update Version number in stdlib/OpenLibm_jll/Project.toml
  3. Update checksums in deps/checksums/openlibm
  4. Check if the patch files deps/patches/openlibm-*.patch exist
+- [ ] `deps/patches/$(libname)-*.patch`

Note:

Example: OpenLibm

  1. Update Version numbers in deps/openlibm.version
  2. Update Version number in stdlib/OpenLibm_jll/Project.toml
  3. Update checksums in deps/checksums/openlibm
  4. Check if the patch files deps/patches/openlibm-*.patch exist
diff --git a/en/v1.12-dev/devdocs/build/distributing/index.html b/en/v1.12-dev/devdocs/build/distributing/index.html index 844a56cdaa6a..f35db2c38842 100644 --- a/en/v1.12-dev/devdocs/build/distributing/index.html +++ b/en/v1.12-dev/devdocs/build/distributing/index.html @@ -47,4 +47,4 @@ signtool sign /f julia-windows-code-sign_2017.p12 /p "PASSWORD" ^ /t http://timestamp.verisign.com/scripts/timstamp.dll ^ /v julia-x.y.z-win32.exe

Note that ^ is a line continuation character in Windows CMD and PASSWORD is a placeholder for the password for this certificate. As usual, contact Elliot or Alex for passwords. If there are no errors, we're all good!

Uploading binaries

Now that everything is signed, we need to upload the binaries to AWS. You can use a program like Cyberduck or the aws command line utility. The binaries should go in the julialang2 bucket in the appropriate folders. For example, Linux x86-64 goes in julialang2/bin/linux/x.y. Be sure to delete the current julia-x.y-latest-linux-<arch>.tar.gz file and replace it with a duplicate of julia-x.y.z-linux-<arch>.tar.gz.

We also need to upload the checksums for everything we've built, including the source tarballs and all release binaries. This is simple:

shasum -a 256 julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.sha256
-md5sum julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.md5

Note that if you're running those commands on macOS, you'll get very slightly different output, which can be reformatted by looking at an existing file. Mac users will also need to use md5 -r instead of md5sum. Upload the .md5 and .sha256 files to julialang2/bin/checksums on AWS.

Ensure that the permissions on AWS for all uploaded files are set to "Everyone: READ."

For each file we've uploaded, we need to purge the Fastly cache so that the links on the website point to the updated files. As an example:

curl -X PURGE https://julialang-s3.julialang.org/bin/checksums/julia-x.y.z.sha256

Sometimes this isn't necessary but it's good to do anyway.

+md5sum julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.md5

Note that if you're running those commands on macOS, you'll get very slightly different output, which can be reformatted by looking at an existing file. Mac users will also need to use md5 -r instead of md5sum. Upload the .md5 and .sha256 files to julialang2/bin/checksums on AWS.

Ensure that the permissions on AWS for all uploaded files are set to "Everyone: READ."

For each file we've uploaded, we need to purge the Fastly cache so that the links on the website point to the updated files. As an example:

curl -X PURGE https://julialang-s3.julialang.org/bin/checksums/julia-x.y.z.sha256

Sometimes this isn't necessary but it's good to do anyway.

diff --git a/en/v1.12-dev/devdocs/build/freebsd/index.html b/en/v1.12-dev/devdocs/build/freebsd/index.html index e7080612a847..bcd305de9dd4 100644 --- a/en/v1.12-dev/devdocs/build/freebsd/index.html +++ b/en/v1.12-dev/devdocs/build/freebsd/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

FreeBSD

Clang is the default compiler on FreeBSD 11.0-RELEASE and above. The remaining build tools are available from the Ports Collection, and can be installed using pkg install git gcc gmake cmake pkgconf. To build Julia, simply run gmake. (Note that gmake must be used rather than make, since make on FreeBSD corresponds to the incompatible BSD Make rather than GNU Make.)

As mentioned above, it is important to note that the USE_SYSTEM_* flags should be used with caution on FreeBSD. This is because many system libraries, and even libraries from the Ports Collection, link to the system's libgcc_s.so.1, or to another library which links to the system libgcc_s. This library declares its GCC version to be 4.6, which is too old to build Julia, and conflicts with other libraries when linking. Thus it is highly recommended to simply allow Julia to build all of its dependencies. If you do choose to use the USE_SYSTEM_* flags, note that /usr/local is not on the compiler path by default, so you may need to add LDFLAGS=-L/usr/local/lib and CPPFLAGS=-I/usr/local/include to your Make.user, though doing so may interfere with other dependencies.

Note that the x86 architecture does not support threading due to lack of compiler runtime library support, so you may need to set JULIA_THREADS=0 in your Make.user if you're on a 32-bit system.

+

FreeBSD

Clang is the default compiler on FreeBSD 11.0-RELEASE and above. The remaining build tools are available from the Ports Collection, and can be installed using pkg install git gcc gmake cmake pkgconf. To build Julia, simply run gmake. (Note that gmake must be used rather than make, since make on FreeBSD corresponds to the incompatible BSD Make rather than GNU Make.)

As mentioned above, it is important to note that the USE_SYSTEM_* flags should be used with caution on FreeBSD. This is because many system libraries, and even libraries from the Ports Collection, link to the system's libgcc_s.so.1, or to another library which links to the system libgcc_s. This library declares its GCC version to be 4.6, which is too old to build Julia, and conflicts with other libraries when linking. Thus it is highly recommended to simply allow Julia to build all of its dependencies. If you do choose to use the USE_SYSTEM_* flags, note that /usr/local is not on the compiler path by default, so you may need to add LDFLAGS=-L/usr/local/lib and CPPFLAGS=-I/usr/local/include to your Make.user, though doing so may interfere with other dependencies.

Note that the x86 architecture does not support threading due to lack of compiler runtime library support, so you may need to set JULIA_THREADS=0 in your Make.user if you're on a 32-bit system.

diff --git a/en/v1.12-dev/devdocs/build/linux/index.html b/en/v1.12-dev/devdocs/build/linux/index.html index 0764ab9042d6..a8fd06421075 100644 --- a/en/v1.12-dev/devdocs/build/linux/index.html +++ b/en/v1.12-dev/devdocs/build/linux/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Linux

  • GCC version 4.7 or later is required to build Julia.
  • To use external shared libraries not in the system library search path, set USE_SYSTEM_XXX=1 and LDFLAGS=-Wl,-rpath,/path/to/dir/contains/libXXX.so in Make.user.
  • Instead of setting LDFLAGS, putting the library directory into the environment variable LD_LIBRARY_PATH (at both compile and run time) also works.
  • The USE_SYSTEM_* flags should be used with caution. These are meant only for troubleshooting, porting, and packaging, where package maintainers work closely with the Julia developers to make sure that Julia is built correctly. Production use cases should use the officially provided binaries. Issues arising from the use of these flags will generally not be accepted.
  • See also the external dependencies.

Architecture Customization

Julia can be built for a non-generic architecture by configuring the ARCH Makefile variable in a Make.user file. See the appropriate section of Make.inc for additional customization options, such as MARCH and JULIA_CPU_TARGET.

For example, to build for Pentium 4, set MARCH=pentium4 and install the necessary system libraries for linking. On Ubuntu, these may include lib32gfortran-6-dev, lib32gcc1, and lib32stdc++6, among others.

You can also set MARCH=native in Make.user for a maximum-performance build customized for the current machine CPU.

Linux Build Troubleshooting

ProblemPossible Solution
OpenBLAS build failureSet one of the following build options in Make.user and build again: <ul><li> OPENBLAS_TARGET_ARCH=BARCELONA (AMD CPUs) or OPENBLAS_TARGET_ARCH=NEHALEM (Intel CPUs)<ul>Set OPENBLAS_DYNAMIC_ARCH = 0 to disable compiling multiple architectures in a single binary.</ul></li><li> OPENBLAS_NO_AVX2 = 1 disables AVX2 instructions, allowing OpenBLAS to compile with OPENBLAS_DYNAMIC_ARCH = 1 using old versions of binutils </li><li> USE_SYSTEM_BLAS=1 uses the system provided libblas <ul><li>Set LIBBLAS=-lopenblas and LIBBLASNAME=libopenblas to force the use of the system provided OpenBLAS when multiple BLAS versions are installed. </li></ul></li></ul><p> If you get an error that looks like ../kernel/x86_64/dgemm_kernel_4x4_haswell.S:1709: Error: no such instruction: `vpermpd $ 0xb1,%ymm0,%ymm0', then you need to set OPENBLAS_DYNAMIC_ARCH = 0 or OPENBLAS_NO_AVX2 = 1, or you need a newer version of binutils (2.18 or newer). (Issue #7653)</p><p> If the linker cannot find gfortran and you get an error like julia /usr/bin/x86_64-linux-gnu-ld: cannot find -lgfortran, check the path with gfortran -print-file-name=libgfortran.so and use the output to export something similar to this: export LDFLAGS=-L/usr/lib/gcc/x86_64-linux-gnu/8/. See Issue #6150.</p>
Illegal Instruction errorCheck if your CPU supports AVX while your OS does not (e.g. through virtualization, as described in this issue).
+

Linux

  • GCC version 4.7 or later is required to build Julia.
  • To use external shared libraries not in the system library search path, set USE_SYSTEM_XXX=1 and LDFLAGS=-Wl,-rpath,/path/to/dir/contains/libXXX.so in Make.user.
  • Instead of setting LDFLAGS, putting the library directory into the environment variable LD_LIBRARY_PATH (at both compile and run time) also works.
  • The USE_SYSTEM_* flags should be used with caution. These are meant only for troubleshooting, porting, and packaging, where package maintainers work closely with the Julia developers to make sure that Julia is built correctly. Production use cases should use the officially provided binaries. Issues arising from the use of these flags will generally not be accepted.
  • See also the external dependencies.

Architecture Customization

Julia can be built for a non-generic architecture by configuring the ARCH Makefile variable in a Make.user file. See the appropriate section of Make.inc for additional customization options, such as MARCH and JULIA_CPU_TARGET.

For example, to build for Pentium 4, set MARCH=pentium4 and install the necessary system libraries for linking. On Ubuntu, these may include lib32gfortran-6-dev, lib32gcc1, and lib32stdc++6, among others.

You can also set MARCH=native in Make.user for a maximum-performance build customized for the current machine CPU.

Linux Build Troubleshooting

ProblemPossible Solution
OpenBLAS build failureSet one of the following build options in Make.user and build again: <ul><li> OPENBLAS_TARGET_ARCH=BARCELONA (AMD CPUs) or OPENBLAS_TARGET_ARCH=NEHALEM (Intel CPUs)<ul>Set OPENBLAS_DYNAMIC_ARCH = 0 to disable compiling multiple architectures in a single binary.</ul></li><li> OPENBLAS_NO_AVX2 = 1 disables AVX2 instructions, allowing OpenBLAS to compile with OPENBLAS_DYNAMIC_ARCH = 1 using old versions of binutils </li><li> USE_SYSTEM_BLAS=1 uses the system provided libblas <ul><li>Set LIBBLAS=-lopenblas and LIBBLASNAME=libopenblas to force the use of the system provided OpenBLAS when multiple BLAS versions are installed. </li></ul></li></ul><p> If you get an error that looks like ../kernel/x86_64/dgemm_kernel_4x4_haswell.S:1709: Error: no such instruction: `vpermpd $ 0xb1,%ymm0,%ymm0', then you need to set OPENBLAS_DYNAMIC_ARCH = 0 or OPENBLAS_NO_AVX2 = 1, or you need a newer version of binutils (2.18 or newer). (Issue #7653)</p><p> If the linker cannot find gfortran and you get an error like julia /usr/bin/x86_64-linux-gnu-ld: cannot find -lgfortran, check the path with gfortran -print-file-name=libgfortran.so and use the output to export something similar to this: export LDFLAGS=-L/usr/lib/gcc/x86_64-linux-gnu/8/. See Issue #6150.</p>
Illegal Instruction errorCheck if your CPU supports AVX while your OS does not (e.g. through virtualization, as described in this issue).
diff --git a/en/v1.12-dev/devdocs/build/macos/index.html b/en/v1.12-dev/devdocs/build/macos/index.html index 289be997af37..8dc7a3b4b1ab 100644 --- a/en/v1.12-dev/devdocs/build/macos/index.html +++ b/en/v1.12-dev/devdocs/build/macos/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

macOS

You need to have the current Xcode command line utilities installed: run xcode-select --install in the terminal. You will need to rerun this terminal command after each macOS update, otherwise you may run into errors involving missing libraries or headers.

The dependent libraries are now built with BinaryBuilder and will be automatically downloaded. This is the preferred way to build Julia source. In case you want to build them all on your own, you will need a 64-bit gfortran to compile Julia dependencies.

brew install gcc

If you have set LD_LIBRARY_PATH or DYLD_LIBRARY_PATH in your .bashrc or equivalent, Julia may be unable to find various libraries that come bundled with it. These environment variables need to be unset for Julia to work.

+

macOS

You need to have the current Xcode command line utilities installed: run xcode-select --install in the terminal. You will need to rerun this terminal command after each macOS update, otherwise you may run into errors involving missing libraries or headers.

The dependent libraries are now built with BinaryBuilder and will be automatically downloaded. This is the preferred way to build Julia source. In case you want to build them all on your own, you will need a 64-bit gfortran to compile Julia dependencies.

brew install gcc

If you have set LD_LIBRARY_PATH or DYLD_LIBRARY_PATH in your .bashrc or equivalent, Julia may be unable to find various libraries that come bundled with it. These environment variables need to be unset for Julia to work.

diff --git a/en/v1.12-dev/devdocs/build/windows/index.html b/en/v1.12-dev/devdocs/build/windows/index.html index 6f5d3a51df1d..085ace779dca 100644 --- a/en/v1.12-dev/devdocs/build/windows/index.html +++ b/en/v1.12-dev/devdocs/build/windows/index.html @@ -28,4 +28,4 @@ # switch all of the following to their "-posix" variants (interactively): for pkg in i686-w64-mingw32-g++ i686-w64-mingw32-gcc i686-w64-mingw32-gfortran x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gfortran; do sudo update-alternatives --config $pkg -done

On Mac: Install XCode, XCode command line tools, X11 (now XQuartz), and MacPorts or Homebrew. Then run port install wine wget mingw-w64, or brew install wine wget mingw-w64, as appropriate.

Then run the build:

  1. git clone https://github.com/JuliaLang/julia.git julia-win32
  2. cd julia-win32
  3. echo override XC_HOST = i686-w64-mingw32 >> Make.user
  4. make
  5. make win-extras (Necessary before running make binary-dist)
  6. make binary-dist then make exe to create the Windows installer.
  7. move the julia-*.exe installer to the target machine

If you are building for 64-bit Windows, the steps are essentially the same. Just replace i686 in XC_HOST with x86_64. (Note: on Mac, wine only runs in 32-bit mode).

Debugging a cross-compiled build under wine

The most effective way to debug a cross-compiled version of Julia on the cross-compilation host is to install a Windows version of GDB and run it under wine as usual. The pre-built packages available as part of the MSYS2 project are known to work. Apart from the GDB package you may also need the python and termcap packages. Finally, GDB's prompt may not work when launched from the command line. This can be worked around by prepending wineconsole to the regular GDB invocation.

After compiling

Compiling using one of the options above creates a basic Julia build, but not some extra components that are included if you run the full Julia binary installer. If you need these components, the easiest way to get them is to build the installer yourself using make win-extras followed by make binary-dist and make exe. Then run the resulting installer.

Windows Build Debugging

GDB hangs with Cygwin mintty

GDB not attaching to the right process

GDB not showing the right backtrace

Build process is slow/eats memory/hangs my computer

+done

On Mac: Install XCode, XCode command line tools, X11 (now XQuartz), and MacPorts or Homebrew. Then run port install wine wget mingw-w64, or brew install wine wget mingw-w64, as appropriate.

Then run the build:

  1. git clone https://github.com/JuliaLang/julia.git julia-win32
  2. cd julia-win32
  3. echo override XC_HOST = i686-w64-mingw32 >> Make.user
  4. make
  5. make win-extras (Necessary before running make binary-dist)
  6. make binary-dist then make exe to create the Windows installer.
  7. move the julia-*.exe installer to the target machine

If you are building for 64-bit Windows, the steps are essentially the same. Just replace i686 in XC_HOST with x86_64. (Note: on Mac, wine only runs in 32-bit mode).

Debugging a cross-compiled build under wine

The most effective way to debug a cross-compiled version of Julia on the cross-compilation host is to install a Windows version of GDB and run it under wine as usual. The pre-built packages available as part of the MSYS2 project are known to work. Apart from the GDB package you may also need the python and termcap packages. Finally, GDB's prompt may not work when launched from the command line. This can be worked around by prepending wineconsole to the regular GDB invocation.

After compiling

Compiling using one of the options above creates a basic Julia build, but not some extra components that are included if you run the full Julia binary installer. If you need these components, the easiest way to get them is to build the installer yourself using make win-extras followed by make binary-dist and make exe. Then run the resulting installer.

Windows Build Debugging

GDB hangs with Cygwin mintty

GDB not attaching to the right process

GDB not showing the right backtrace

Build process is slow/eats memory/hangs my computer

diff --git a/en/v1.12-dev/devdocs/builtins/index.html b/en/v1.12-dev/devdocs/builtins/index.html index 86bbe334ab2b..b41d4111413f 100644 --- a/en/v1.12-dev/devdocs/builtins/index.html +++ b/en/v1.12-dev/devdocs/builtins/index.html @@ -4,6 +4,6 @@ gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash});

Core.Builtins

Builtin Function APIs

The following Builtin function APIs are considered unstable, but provide the basic definitions for what defines the abilities and behaviors of a Julia program. They are typically accessed through a higher level generic API.

Core.memoryrefFunction
Core.memoryref(::GenericMemory)
-Core.memoryref(::GenericMemoryRef, index::Int, [boundscheck::Bool])

Return a GenericMemoryRef for a GenericMemory. See MemoryRef.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryrefoffsetFunction
Core..memoryrefoffset(::GenericMemoryRef)

Return the offset index that was used to construct the MemoryRef. See Core.memoryref.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryrefgetFunction
Core.memoryrefget(::GenericMemoryRef, ordering::Symbol, boundscheck::Bool)

Return the value stored at the MemoryRef, throwing a BoundsError if the Memory is empty. See ref[]. The memory ordering specified must be compatible with the isatomic parameter.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryrefset!Function
Core.memoryrefset!(::GenericMemoryRef, value, ordering::Symbol, boundscheck::Bool)

Store the value to the MemoryRef, throwing a BoundsError if the Memory is empty. See ref[] = value. The memory ordering specified must be compatible with the isatomic parameter.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryref_isassignedFunction
Core.memoryref_isassigned(::GenericMemoryRef, ordering::Symbol, boundscheck::Bool)

Return whether there is a value stored at the MemoryRef, returning false if the Memory is empty. See isassigned(::Base.RefValue), Core.memoryrefget. The memory ordering specified must be compatible with the isatomic parameter.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryrefswap!Function
Core.memoryrefswap!(::GenericMemoryRef, value, ordering::Symbol, boundscheck::Bool)

Atomically perform the operations to simultaneously get and set a MemoryRef value.

Julia 1.11

This function requires Julia 1.11 or later.

See also swapproperty! and Core.memoryrefset!.

source
Core.memoryrefmodify!Function
Core.memoryrefmodify!(::GenericMemoryRef, op, value, ordering::Symbol, boundscheck::Bool) -> Pair

Atomically perform the operations to get and set a MemoryRef value after applying the function op.

Julia 1.11

This function requires Julia 1.11 or later.

See also modifyproperty! and Core.memoryrefset!.

source
Core.memoryrefreplace!Function
Core.memoryrefreplace!(::GenericMemoryRef, expected, desired,
-                       success_order::Symbol, fail_order::Symbol=success_order, boundscheck::Bool) -> (; old, success::Bool)

Atomically perform the operations to get and conditionally set a MemoryRef value.

Julia 1.11

This function requires Julia 1.11 or later.

See also replaceproperty! and Core.memoryrefset!.

source
Core.memoryrefsetonce!Function
Core.memoryrefsetonce!(::GenericMemoryRef, value,
-                       success_order::Symbol, fail_order::Symbol=success_order, boundscheck::Bool) -> success::Bool

Atomically perform the operations to set a MemoryRef to a given value, only if it was previously not set.

Julia 1.11

This function requires Julia 1.11 or later.

See also setpropertyonce! and Core.memoryrefset!.

source
Core.get_binding_typeFunction
Core.get_binding_type(module::Module, name::Symbol)

Retrieve the declared type of the binding name from the module module.

Julia 1.9

This function requires Julia 1.9 or later.

source
Core.set_binding_type!Function
Core.set_binding_type!(module::Module, name::Symbol, [type::Type])

Set the declared type of the binding name in the module module to type. Error if the binding already has a type that is not equivalent to type. If the type argument is absent, set the binding type to Any if unset, but do not error.

Julia 1.9

This function requires Julia 1.9 or later.

source
Core.IntrinsicFunctionType
Core.IntrinsicFunction <: Core.Builtin <: Function

The Core.IntrinsicFunction function define some basic primitives for what defines the abilities and behaviors of a Julia program

source
Core.IntrinsicsModule
Core.Intrinsics

The Core.Intrinsics module holds the Core.IntrinsicFunction objects.

source
Core.IRModule
Core.IR

The Core.IR module exports the IR object model.

source
+Core.memoryref(::GenericMemoryRef, index::Int, [boundscheck::Bool])

Return a GenericMemoryRef for a GenericMemory. See MemoryRef.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryrefoffsetFunction
Core..memoryrefoffset(::GenericMemoryRef)

Return the offset index that was used to construct the MemoryRef. See Core.memoryref.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryrefgetFunction
Core.memoryrefget(::GenericMemoryRef, ordering::Symbol, boundscheck::Bool)

Return the value stored at the MemoryRef, throwing a BoundsError if the Memory is empty. See ref[]. The memory ordering specified must be compatible with the isatomic parameter.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryrefset!Function
Core.memoryrefset!(::GenericMemoryRef, value, ordering::Symbol, boundscheck::Bool)

Store the value to the MemoryRef, throwing a BoundsError if the Memory is empty. See ref[] = value. The memory ordering specified must be compatible with the isatomic parameter.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryref_isassignedFunction
Core.memoryref_isassigned(::GenericMemoryRef, ordering::Symbol, boundscheck::Bool)

Return whether there is a value stored at the MemoryRef, returning false if the Memory is empty. See isassigned(::Base.RefValue), Core.memoryrefget. The memory ordering specified must be compatible with the isatomic parameter.

Julia 1.11

This function requires Julia 1.11 or later.

source
Core.memoryrefswap!Function
Core.memoryrefswap!(::GenericMemoryRef, value, ordering::Symbol, boundscheck::Bool)

Atomically perform the operations to simultaneously get and set a MemoryRef value.

Julia 1.11

This function requires Julia 1.11 or later.

See also swapproperty! and Core.memoryrefset!.

source
Core.memoryrefmodify!Function
Core.memoryrefmodify!(::GenericMemoryRef, op, value, ordering::Symbol, boundscheck::Bool) -> Pair

Atomically perform the operations to get and set a MemoryRef value after applying the function op.

Julia 1.11

This function requires Julia 1.11 or later.

See also modifyproperty! and Core.memoryrefset!.

source
Core.memoryrefreplace!Function
Core.memoryrefreplace!(::GenericMemoryRef, expected, desired,
+                       success_order::Symbol, fail_order::Symbol=success_order, boundscheck::Bool) -> (; old, success::Bool)

Atomically perform the operations to get and conditionally set a MemoryRef value.

Julia 1.11

This function requires Julia 1.11 or later.

See also replaceproperty! and Core.memoryrefset!.

source
Core.memoryrefsetonce!Function
Core.memoryrefsetonce!(::GenericMemoryRef, value,
+                       success_order::Symbol, fail_order::Symbol=success_order, boundscheck::Bool) -> success::Bool

Atomically perform the operations to set a MemoryRef to a given value, only if it was previously not set.

Julia 1.11

This function requires Julia 1.11 or later.

See also setpropertyonce! and Core.memoryrefset!.

source
Core.Intrinsics.atomic_pointerrefFunction
Core.Intrinsics.atomic_pointerref(pointer::Ptr{T}, order::Symbol) --> T
Julia 1.7

This function requires Julia 1.7 or later.

See unsafe_load.

source
Core.Intrinsics.atomic_pointersetFunction
Core.Intrinsics.atomic_pointerset(pointer::Ptr{T}, new::T, order::Symbol) --> pointer
Julia 1.7

This function requires Julia 1.7 or later.

See unsafe_store!.

source
Core.Intrinsics.atomic_pointerswapFunction
Core.Intrinsics.atomic_pointerswap(pointer::Ptr{T}, new::T, order::Symbol) --> old
Julia 1.7

This function requires Julia 1.7 or later.

See unsafe_swap!.

source
Core.Intrinsics.atomic_pointermodifyFunction
Core.Intrinsics.atomic_pointermodify(pointer::Ptr{T}, function::(old::T,arg::S)->T, arg::S, order::Symbol) --> old
Julia 1.7

This function requires Julia 1.7 or later.

See unsafe_modify!.

source
Core.Intrinsics.atomic_pointerreplaceFunction
Core.Intrinsics.atomic_pointerreplace(pointer::Ptr{T}, expected::Any, new::T, success_order::Symbol, failure_order::Symbol) --> (old, cmp)
Julia 1.7

This function requires Julia 1.7 or later.

See unsafe_replace!.

source
Core.get_binding_typeFunction
Core.get_binding_type(module::Module, name::Symbol)

Retrieve the declared type of the binding name from the module module.

Julia 1.9

This function requires Julia 1.9 or later.

source
Core.set_binding_type!Function
Core.set_binding_type!(module::Module, name::Symbol, [type::Type])

Set the declared type of the binding name in the module module to type. Error if the binding already has a type that is not equivalent to type. If the type argument is absent, set the binding type to Any if unset, but do not error.

Julia 1.9

This function requires Julia 1.9 or later.

source
Core.IntrinsicFunctionType
Core.IntrinsicFunction <: Core.Builtin <: Function

The Core.IntrinsicFunction function define some basic primitives for what defines the abilities and behaviors of a Julia program

source
Core.IntrinsicsModule
Core.Intrinsics

The Core.Intrinsics module holds the Core.IntrinsicFunction objects.

source
Core.IRModule
Core.IR

The Core.IR module exports the IR object model.

source
diff --git a/en/v1.12-dev/devdocs/callconv/index.html b/en/v1.12-dev/devdocs/callconv/index.html index 3259ae15f5fa..e751abc0aa82 100644 --- a/en/v1.12-dev/devdocs/callconv/index.html +++ b/en/v1.12-dev/devdocs/callconv/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Calling Conventions

Julia uses three calling conventions for four distinct purposes:

NamePrefixPurpose
Nativejulia_Speed via specialized signatures
JL Calljlcall_Wrapper for generic calls
JL Calljl_Builtins
C ABIjlcapi_Wrapper callable from C

Julia Native Calling Convention

The native calling convention is designed for fast non-generic calls. It usually uses a specialized signature.

  • LLVM ghosts (zero-length types) are omitted.
  • LLVM scalars and vectors are passed by value.
  • LLVM aggregates (arrays and structs) are passed by reference.

A small return values is returned as LLVM return values. A large return values is returned via the "structure return" (sret) convention, where the caller provides a pointer to a return slot.

An argument or return values that is a homogeneous tuple is sometimes represented as an LLVM vector instead of an LLVM array.

JL Call Convention

The JL Call convention is for builtins and generic dispatch. Hand-written functions using this convention are declared via the macro JL_CALLABLE. The convention uses exactly 3 parameters:

  • F - Julia representation of function that is being applied
  • args - pointer to array of pointers to boxes
  • nargs - length of the array

The return value is a pointer to a box.

C ABI

C ABI wrappers enable calling Julia from C. The wrapper calls a function using the native calling convention.

Tuples are always represented as C arrays.

+

Calling Conventions

Julia uses three calling conventions for four distinct purposes:

NamePrefixPurpose
Nativejulia_Speed via specialized signatures
JL Calljlcall_Wrapper for generic calls
JL Calljl_Builtins
C ABIjlcapi_Wrapper callable from C

Julia Native Calling Convention

The native calling convention is designed for fast non-generic calls. It usually uses a specialized signature.

  • LLVM ghosts (zero-length types) are omitted.
  • LLVM scalars and vectors are passed by value.
  • LLVM aggregates (arrays and structs) are passed by reference.

A small return values is returned as LLVM return values. A large return values is returned via the "structure return" (sret) convention, where the caller provides a pointer to a return slot.

An argument or return values that is a homogeneous tuple is sometimes represented as an LLVM vector instead of an LLVM array.

JL Call Convention

The JL Call convention is for builtins and generic dispatch. Hand-written functions using this convention are declared via the macro JL_CALLABLE. The convention uses exactly 3 parameters:

  • F - Julia representation of function that is being applied
  • args - pointer to array of pointers to boxes
  • nargs - length of the array

The return value is a pointer to a box.

C ABI

C ABI wrappers enable calling Julia from C. The wrapper calls a function using the native calling convention.

Tuples are always represented as C arrays.

diff --git a/en/v1.12-dev/devdocs/cartesian/index.html b/en/v1.12-dev/devdocs/cartesian/index.html index c02ee5ee59f7..a92c9241591a 100644 --- a/en/v1.12-dev/devdocs/cartesian/index.html +++ b/en/v1.12-dev/devdocs/cartesian/index.html @@ -35,17 +35,17 @@ j_1 = min(i_1, 5) s += A[j_1, j_2] end -end

If you want just a post-expression, supply nothing for the pre-expression. Using parentheses and semicolons, you can supply multi-statement expressions.

source
Base.Cartesian.@nrefMacro
@nref N A indexexpr

Generate expressions like A[i_1, i_2, ...]. indexexpr can either be an iteration-symbol prefix, or an anonymous-function expression.

Examples

julia> @macroexpand Base.Cartesian.@nref 3 A i
-:(A[i_1, i_2, i_3])
source
Base.Cartesian.@nextractMacro
@nextract N esym isym

Generate N variables esym_1, esym_2, ..., esym_N to extract values from isym. isym can be either a Symbol or anonymous-function expression.

@nextract 2 x y would generate

x_1 = y[1]
+end

If you want just a post-expression, supply nothing for the pre-expression. Using parentheses and semicolons, you can supply multi-statement expressions.

source
Base.Cartesian.@nrefMacro
@nref N A indexexpr

Generate expressions like A[i_1, i_2, ...]. indexexpr can either be an iteration-symbol prefix, or an anonymous-function expression.

Examples

julia> @macroexpand Base.Cartesian.@nref 3 A i
+:(A[i_1, i_2, i_3])
source
Base.Cartesian.@nextractMacro
@nextract N esym isym

Generate N variables esym_1, esym_2, ..., esym_N to extract values from isym. isym can be either a Symbol or anonymous-function expression.

@nextract 2 x y would generate

x_1 = y[1]
 x_2 = y[2]

while @nextract 3 x d->y[2d-1] yields

x_1 = y[1]
 x_2 = y[3]
-x_3 = y[5]
source
Base.Cartesian.@nexprsMacro
@nexprs N expr

Generate N expressions. expr should be an anonymous-function expression.

Examples

julia> @macroexpand Base.Cartesian.@nexprs 4 i -> y[i] = A[i+j]
+x_3 = y[5]
source
Base.Cartesian.@nexprsMacro
@nexprs N expr

Generate N expressions. expr should be an anonymous-function expression.

Examples

julia> @macroexpand Base.Cartesian.@nexprs 4 i -> y[i] = A[i+j]
 quote
     y[1] = A[1 + j]
     y[2] = A[2 + j]
     y[3] = A[3 + j]
     y[4] = A[4 + j]
-end
source
Base.Cartesian.@ncallMacro
@ncall N f sym...

Generate a function call expression. sym represents any number of function arguments, the last of which may be an anonymous-function expression and is expanded into N arguments.

For example, @ncall 3 func a generates

func(a_1, a_2, a_3)

while @ncall 2 func a b i->c[i] yields

func(a, b, c[1], c[2])
source
Base.Cartesian.@ncallkwMacro
@ncallkw N f kw sym...

Generate a function call expression with keyword arguments kw.... As in the case of @ncall, sym represents any number of function arguments, the last of which may be an anonymous-function expression and is expanded into N arguments.

Examples

julia> using Base.Cartesian
+end
source
Base.Cartesian.@ncallMacro
@ncall N f sym...

Generate a function call expression. sym represents any number of function arguments, the last of which may be an anonymous-function expression and is expanded into N arguments.

For example, @ncall 3 func a generates

func(a_1, a_2, a_3)

while @ncall 2 func a b i->c[i] yields

func(a, b, c[1], c[2])
source
Base.Cartesian.@ncallkwMacro
@ncallkw N f kw sym...

Generate a function call expression with keyword arguments kw.... As in the case of @ncall, sym represents any number of function arguments, the last of which may be an anonymous-function expression and is expanded into N arguments.

Examples

julia> using Base.Cartesian
 
 julia> f(x...; a, b = 1, c = 2, d = 3) = +(x..., a, b, c, d);
 
@@ -53,11 +53,11 @@
 
 julia> @ncallkw 2 f (; a = 0, b, kw...) x
 -3
-
source
Base.Cartesian.@ntupleMacro
@ntuple N expr

Generates an N-tuple. @ntuple 2 i would generate (i_1, i_2), and @ntuple 2 k->k+1 would generate (2,3).

source
Base.Cartesian.@nallMacro
@nall N expr

Check whether all of the expressions generated by the anonymous-function expression expr evaluate to true.

@nall 3 d->(i_d > 1) would generate the expression (i_1 > 1 && i_2 > 1 && i_3 > 1). This can be convenient for bounds-checking.

source
Base.Cartesian.@nanyMacro
@nany N expr

Check whether any of the expressions generated by the anonymous-function expression expr evaluate to true.

@nany 3 d->(i_d > 1) would generate the expression (i_1 > 1 || i_2 > 1 || i_3 > 1).

source
Base.Cartesian.@nifMacro
@nif N conditionexpr expr
+
source
Base.Cartesian.@ntupleMacro
@ntuple N expr

Generates an N-tuple. @ntuple 2 i would generate (i_1, i_2), and @ntuple 2 k->k+1 would generate (2,3).

source
Base.Cartesian.@nallMacro
@nall N expr

Check whether all of the expressions generated by the anonymous-function expression expr evaluate to true.

@nall 3 d->(i_d > 1) would generate the expression (i_1 > 1 && i_2 > 1 && i_3 > 1). This can be convenient for bounds-checking.

source
Base.Cartesian.@nanyMacro
@nany N expr

Check whether any of the expressions generated by the anonymous-function expression expr evaluate to true.

@nany 3 d->(i_d > 1) would generate the expression (i_1 > 1 || i_2 > 1 || i_3 > 1).

source
Base.Cartesian.@nifMacro
@nif N conditionexpr expr
 @nif N conditionexpr expr elseexpr

Generates a sequence of if ... elseif ... else ... end statements. For example:

@nif 3 d->(i_d >= size(A,d)) d->(error("Dimension ", d, " too big")) d->println("All OK")

would generate:

if i_1 > size(A, 1)
     error("Dimension ", 1, " too big")
 elseif i_2 > size(A, 2)
     error("Dimension ", 2, " too big")
 else
     println("All OK")
-end
source
+endsource diff --git a/en/v1.12-dev/devdocs/compiler/index.html b/en/v1.12-dev/devdocs/compiler/index.html index b5458839fb65..d1113c023320 100644 --- a/en/v1.12-dev/devdocs/compiler/index.html +++ b/en/v1.12-dev/devdocs/compiler/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

High-level Overview of the Native-Code Generation Process

Representation of Pointers

When emitting code to an object file, pointers will be emitted as relocations. The deserialization code will ensure any object that pointed to one of these constants gets recreated and contains the right runtime pointer.

Otherwise, they will be emitted as literal constants.

To emit one of these objects, call literal_pointer_val. It'll handle tracking the Julia value and the LLVM global, ensuring they are valid both for the current runtime and after deserialization.

When emitted into the object file, these globals are stored as references in a large gvals table. This allows the deserializer to reference them by index, and implement a custom manual mechanism similar to a Global Offset Table (GOT) to restore them.

Function pointers are handled similarly. They are stored as values in a large fvals table. Like globals, this allows the deserializer to reference them by index.

Note that extern functions are handled separately, with names, via the usual symbol resolution mechanism in the linker.

Note too that ccall functions are also handled separately, via a manual GOT and Procedure Linkage Table (PLT).

Representation of Intermediate Values

Values are passed around in a jl_cgval_t struct. This represents an R-value, and includes enough information to determine how to assign or pass it somewhere.

They are created via one of the helper constructors, usually: mark_julia_type (for immediate values) and mark_julia_slot (for pointers to values).

The function convert_julia_type can transform between any two types. It returns an R-value with cgval.typ set to typ. It'll cast the object to the requested representation, making heap boxes, allocating stack copies, and computing tagged unions as needed to change the representation.

By contrast update_julia_type will change cgval.typ to typ, only if it can be done at zero-cost (i.e. without emitting any code).

Union representation

Inferred union types may be stack allocated via a tagged type representation.

The primitive routines that need to be able to handle tagged unions are:

  • mark-type
  • load-local
  • store-local
  • isa
  • is
  • emit_typeof
  • emit_sizeof
  • boxed
  • unbox
  • specialized cc-ret

Everything else should be possible to handle in inference by using these primitives to implement union-splitting.

The representation of the tagged-union is as a pair of < void* union, byte selector >. The selector is fixed-size as byte & 0x7f, and will union-tag the first 126 isbits. It records the one-based depth-first count into the type-union of the isbits objects inside. An index of zero indicates that the union* is actually a tagged heap-allocated jl_value_t*, and needs to be treated as normal for a boxed object rather than as a tagged union.

The high bit of the selector (byte & 0x80) can be tested to determine if the void* is actually a heap-allocated (jl_value_t*) box, thus avoiding the cost of re-allocating a box, while maintaining the ability to efficiently handle union-splitting based on the low bits.

It is guaranteed that byte & 0x7f is an exact test for the type, if the value can be represented by a tag – it will never be marked byte = 0x80. It is not necessary to also test the type-tag when testing isa.

The union* memory region may be allocated at any size. The only constraint is that it is big enough to contain the data currently specified by selector. It might not be big enough to contain the union of all types that could be stored there according to the associated Union type field. Use appropriate care when copying.

Specialized Calling Convention Signature Representation

A jl_returninfo_t object describes the calling convention details of any callable.

If any of the arguments or return type of a method can be represented unboxed, and the method is not varargs, it'll be given an optimized calling convention signature based on its specTypes and rettype fields.

The general principles are that:

  • Primitive types get passed in int/float registers.
  • Tuples of VecElement types get passed in vector registers.
  • Structs get passed on the stack.
  • Return values are handle similarly to arguments, with a size-cutoff at which they will instead be returned via a hidden sret argument.

The total logic for this is implemented by get_specsig_function and deserves_sret.

Additionally, if the return type is a union, it may be returned as a pair of values (a pointer and a tag). If the union values can be stack-allocated, then sufficient space to store them will also be passed as a hidden first argument. It is up to the callee whether the returned pointer will point to this space, a boxed object, or even other constant memory.

+

High-level Overview of the Native-Code Generation Process

Representation of Pointers

When emitting code to an object file, pointers will be emitted as relocations. The deserialization code will ensure any object that pointed to one of these constants gets recreated and contains the right runtime pointer.

Otherwise, they will be emitted as literal constants.

To emit one of these objects, call literal_pointer_val. It'll handle tracking the Julia value and the LLVM global, ensuring they are valid both for the current runtime and after deserialization.

When emitted into the object file, these globals are stored as references in a large gvals table. This allows the deserializer to reference them by index, and implement a custom manual mechanism similar to a Global Offset Table (GOT) to restore them.

Function pointers are handled similarly. They are stored as values in a large fvals table. Like globals, this allows the deserializer to reference them by index.

Note that extern functions are handled separately, with names, via the usual symbol resolution mechanism in the linker.

Note too that ccall functions are also handled separately, via a manual GOT and Procedure Linkage Table (PLT).

Representation of Intermediate Values

Values are passed around in a jl_cgval_t struct. This represents an R-value, and includes enough information to determine how to assign or pass it somewhere.

They are created via one of the helper constructors, usually: mark_julia_type (for immediate values) and mark_julia_slot (for pointers to values).

The function convert_julia_type can transform between any two types. It returns an R-value with cgval.typ set to typ. It'll cast the object to the requested representation, making heap boxes, allocating stack copies, and computing tagged unions as needed to change the representation.

By contrast update_julia_type will change cgval.typ to typ, only if it can be done at zero-cost (i.e. without emitting any code).

Union representation

Inferred union types may be stack allocated via a tagged type representation.

The primitive routines that need to be able to handle tagged unions are:

  • mark-type
  • load-local
  • store-local
  • isa
  • is
  • emit_typeof
  • emit_sizeof
  • boxed
  • unbox
  • specialized cc-ret

Everything else should be possible to handle in inference by using these primitives to implement union-splitting.

The representation of the tagged-union is as a pair of < void* union, byte selector >. The selector is fixed-size as byte & 0x7f, and will union-tag the first 126 isbits. It records the one-based depth-first count into the type-union of the isbits objects inside. An index of zero indicates that the union* is actually a tagged heap-allocated jl_value_t*, and needs to be treated as normal for a boxed object rather than as a tagged union.

The high bit of the selector (byte & 0x80) can be tested to determine if the void* is actually a heap-allocated (jl_value_t*) box, thus avoiding the cost of re-allocating a box, while maintaining the ability to efficiently handle union-splitting based on the low bits.

It is guaranteed that byte & 0x7f is an exact test for the type, if the value can be represented by a tag – it will never be marked byte = 0x80. It is not necessary to also test the type-tag when testing isa.

The union* memory region may be allocated at any size. The only constraint is that it is big enough to contain the data currently specified by selector. It might not be big enough to contain the union of all types that could be stored there according to the associated Union type field. Use appropriate care when copying.

Specialized Calling Convention Signature Representation

A jl_returninfo_t object describes the calling convention details of any callable.

If any of the arguments or return type of a method can be represented unboxed, and the method is not varargs, it'll be given an optimized calling convention signature based on its specTypes and rettype fields.

The general principles are that:

  • Primitive types get passed in int/float registers.
  • Tuples of VecElement types get passed in vector registers.
  • Structs get passed on the stack.
  • Return values are handle similarly to arguments, with a size-cutoff at which they will instead be returned via a hidden sret argument.

The total logic for this is implemented by get_specsig_function and deserves_sret.

Additionally, if the return type is a union, it may be returned as a pair of values (a pointer and a tag). If the union values can be stack-allocated, then sufficient space to store them will also be passed as a hidden first argument. It is up to the callee whether the returned pointer will point to this space, a boxed object, or even other constant memory.

diff --git a/en/v1.12-dev/devdocs/debuggingtips/index.html b/en/v1.12-dev/devdocs/debuggingtips/index.html index 1b1c8af859f1..76bb70bcac6a 100644 --- a/en/v1.12-dev/devdocs/debuggingtips/index.html +++ b/en/v1.12-dev/devdocs/debuggingtips/index.html @@ -29,4 +29,4 @@ Expr(:return, Expr(:call, :box, :Float32, Expr(:call, :fptrunc, :Float32, :x)::Any)::Any)::Any)::Any)::Any

Finally, and perhaps most usefully, we can force the function to be recompiled in order to step through the codegen process. To do this, clear the cached functionObject from the jl_lamdbda_info_t*:

(gdb) p f->linfo->functionObject
 $8 = (void *) 0x1289d070
 (gdb) set f->linfo->functionObject = NULL

Then, set a breakpoint somewhere useful (e.g. emit_function, emit_expr, emit_call, etc.), and run codegen:

(gdb) p jl_compile(f)
-... # your breakpoint here

Debugging precompilation errors

Module precompilation spawns a separate Julia process to precompile each module. Setting a breakpoint or catching failures in a precompile worker requires attaching a debugger to the worker. The easiest approach is to set the debugger watch for new process launches matching a given name. For example:

(gdb) attach -w -n julia-debug

or:

(lldb) process attach -w -n julia-debug

Then run a script/command to start precompilation. As described earlier, use conditional breakpoints in the parent process to catch specific file-loading events and narrow the debugging window. (some operating systems may require alternative approaches, such as following each fork from the parent process)

Mozilla's Record and Replay Framework (rr)

Julia now works out of the box with rr, the lightweight recording and deterministic debugging framework from Mozilla. This allows you to replay the trace of an execution deterministically. The replayed execution's address spaces, register contents, syscall data etc are exactly the same in every run.

A recent version of rr (3.1.0 or higher) is required.

Reproducing concurrency bugs with rr

rr simulates a single-threaded machine by default. In order to debug concurrent code you can use rr record --chaos which will cause rr to simulate between one to eight cores, chosen randomly. You might therefore want to set JULIA_NUM_THREADS=8 and rerun your code under rr until you have caught your bug.

+... # your breakpoint here

Debugging precompilation errors

Module precompilation spawns a separate Julia process to precompile each module. Setting a breakpoint or catching failures in a precompile worker requires attaching a debugger to the worker. The easiest approach is to set the debugger watch for new process launches matching a given name. For example:

(gdb) attach -w -n julia-debug

or:

(lldb) process attach -w -n julia-debug

Then run a script/command to start precompilation. As described earlier, use conditional breakpoints in the parent process to catch specific file-loading events and narrow the debugging window. (some operating systems may require alternative approaches, such as following each fork from the parent process)

Mozilla's Record and Replay Framework (rr)

Julia now works out of the box with rr, the lightweight recording and deterministic debugging framework from Mozilla. This allows you to replay the trace of an execution deterministically. The replayed execution's address spaces, register contents, syscall data etc are exactly the same in every run.

A recent version of rr (3.1.0 or higher) is required.

Reproducing concurrency bugs with rr

rr simulates a single-threaded machine by default. In order to debug concurrent code you can use rr record --chaos which will cause rr to simulate between one to eight cores, chosen randomly. You might therefore want to set JULIA_NUM_THREADS=8 and rerun your code under rr until you have caught your bug.

diff --git a/en/v1.12-dev/devdocs/eval/index.html b/en/v1.12-dev/devdocs/eval/index.html index 14005570afd9..0c83119a4ed2 100644 --- a/en/v1.12-dev/devdocs/eval/index.html +++ b/en/v1.12-dev/devdocs/eval/index.html @@ -6,4 +6,4 @@

Eval of Julia code

One of the hardest parts about learning how the Julia Language runs code is learning how all of the pieces work together to execute a block of code.

Each chunk of code typically makes a trip through many steps with potentially unfamiliar names, such as (in no particular order): flisp, AST, C++, LLVM, eval, typeinf, macroexpand, sysimg (or system image), bootstrapping, compile, parse, execute, JIT, interpret, box, unbox, intrinsic function, and primitive function, before turning into the desired result (hopefully).

Definitions
  • REPL

    REPL stands for Read-Eval-Print Loop. It's just what we call the command line environment for short.

  • AST

    Abstract Syntax Tree The AST is the digital representation of the code structure. In this form the code has been tokenized for meaning so that it is more suitable for manipulation and execution.

Diagram of the compiler flow

Julia Execution

The 10,000 foot view of the whole process is as follows:

  1. The user starts julia.
  2. The C function main() from cli/loader_exe.c gets called. This function processes the command line arguments, filling in the jl_options struct and setting the variable ARGS. It then initializes Julia (by calling julia_init in init.c, which may load a previously compiled sysimg). Finally, it passes off control to Julia by calling Base._start().
  3. When _start() takes over control, the subsequent sequence of commands depends on the command line arguments given. For example, if a filename was supplied, it will proceed to execute that file. Otherwise, it will start an interactive REPL.
  4. Skipping the details about how the REPL interacts with the user, let's just say the program ends up with a block of code that it wants to run.
  5. If the block of code to run is in a file, jl_load(char *filename) gets invoked to load the file and parse it. Each fragment of code is then passed to eval to execute.
  6. Each fragment of code (or AST), is handed off to eval() to turn into results.
  7. eval() takes each code fragment and tries to run it in jl_toplevel_eval_flex().
  8. jl_toplevel_eval_flex() decides whether the code is a "toplevel" action (such as using or module), which would be invalid inside a function. If so, it passes off the code to the toplevel interpreter.
  9. jl_toplevel_eval_flex() then expands the code to eliminate any macros and to "lower" the AST to make it simpler to execute.
  10. jl_toplevel_eval_flex() then uses some simple heuristics to decide whether to JIT compile the AST or to interpret it directly.
  11. The bulk of the work to interpret code is handled by eval in interpreter.c.
  12. If instead, the code is compiled, the bulk of the work is handled by codegen.cpp. Whenever a Julia function is called for the first time with a given set of argument types, type inference will be run on that function. This information is used by the codegen step to generate faster code.
  13. Eventually, the user quits the REPL, or the end of the program is reached, and the _start() method returns.
  14. Just before exiting, main() calls jl_atexit_hook(exit_code). This calls Base._atexit() (which calls any functions registered to atexit() inside Julia). Then it calls jl_gc_run_all_finalizers(). Finally, it gracefully cleans up all libuv handles and waits for them to flush and close.

Parsing

The Julia parser is a small lisp program written in femtolisp, the source-code for which is distributed inside Julia in src/flisp.

The interface functions for this are primarily defined in jlfrontend.scm. The code in ast.c handles this handoff on the Julia side.

The other relevant files at this stage are julia-parser.scm, which handles tokenizing Julia code and turning it into an AST, and julia-syntax.scm, which handles transforming complex AST representations into simpler, "lowered" AST representations which are more suitable for analysis and execution.

If you want to test the parser without re-building Julia in its entirety, you can run the frontend on its own as follows:

$ cd src
 $ flisp/flisp
 > (load "jlfrontend.scm")
-> (jl-parse-file "<filename>")

Macro Expansion

When eval() encounters a macro, it expands that AST node before attempting to evaluate the expression. Macro expansion involves a handoff from eval() (in Julia), to the parser function jl_macroexpand() (written in flisp) to the Julia macro itself (written in - what else - Julia) via fl_invoke_julia_macro(), and back.

Typically, macro expansion is invoked as a first step during a call to Meta.lower()/jl_expand(), although it can also be invoked directly by a call to macroexpand()/jl_macroexpand().

Type Inference

Type inference is implemented in Julia by typeinf() in compiler/typeinfer.jl. Type inference is the process of examining a Julia function and determining bounds for the types of each of its variables, as well as bounds on the type of the return value from the function. This enables many future optimizations, such as unboxing of known immutable values, and compile-time hoisting of various run-time operations such as computing field offsets and function pointers. Type inference may also include other steps such as constant propagation and inlining.

More Definitions
  • JIT

    Just-In-Time Compilation The process of generating native-machine code into memory right when it is needed.

  • LLVM

    Low-Level Virtual Machine (a compiler) The Julia JIT compiler is a program/library called libLLVM. Codegen in Julia refers both to the process of taking a Julia AST and turning it into LLVM instructions, and the process of LLVM optimizing that and turning it into native assembly instructions.

  • C++

    The programming language that LLVM is implemented in, which means that codegen is also implemented in this language. The rest of Julia's library is implemented in C, in part because its smaller feature set makes it more usable as a cross-language interface layer.

  • box

    This term is used to describe the process of taking a value and allocating a wrapper around the data that is tracked by the garbage collector (gc) and is tagged with the object's type.

  • unbox

    The reverse of boxing a value. This operation enables more efficient manipulation of data when the type of that data is fully known at compile-time (through type inference).

  • generic function

    A Julia function composed of multiple "methods" that are selected for dynamic dispatch based on the argument type-signature

  • anonymous function or "method"

    A Julia function without a name and without type-dispatch capabilities

  • primitive function

    A function implemented in C but exposed in Julia as a named function "method" (albeit without generic function dispatch capabilities, similar to a anonymous function)

  • intrinsic function

    A low-level operation exposed as a function in Julia. These pseudo-functions implement operations on raw bits such as add and sign extend that cannot be expressed directly in any other way. Since they operate on bits directly, they must be compiled into a function and surrounded by a call to Core.Intrinsics.box(T, ...) to reassign type information to the value.

JIT Code Generation

Codegen is the process of turning a Julia AST into native machine code.

The JIT environment is initialized by an early call to jl_init_codegen in codegen.cpp.

On demand, a Julia method is converted into a native function by the function emit_function(jl_method_instance_t*). (note, when using the MCJIT (in LLVM v3.4+), each function must be JIT into a new module.) This function recursively calls emit_expr() until the entire function has been emitted.

Much of the remaining bulk of this file is devoted to various manual optimizations of specific code patterns. For example, emit_known_call() knows how to inline many of the primitive functions (defined in builtins.c) for various combinations of argument types.

Other parts of codegen are handled by various helper files:

  • debuginfo.cpp

    Handles backtraces for JIT functions

  • ccall.cpp

    Handles the ccall and llvmcall FFI, along with various abi_*.cpp files

  • intrinsics.cpp

    Handles the emission of various low-level intrinsic functions

Bootstrapping

The process of creating a new system image is called "bootstrapping".

The etymology of this word comes from the phrase "pulling oneself up by the bootstraps", and refers to the idea of starting from a very limited set of available functions and definitions and ending with the creation of a full-featured environment.

System Image

The system image is a precompiled archive of a set of Julia files. The sys.ji file distributed with Julia is one such system image, generated by executing the file sysimg.jl, and serializing the resulting environment (including Types, Functions, Modules, and all other defined values) into a file. Therefore, it contains a frozen version of the Main, Core, and Base modules (and whatever else was in the environment at the end of bootstrapping). This serializer/deserializer is implemented by jl_save_system_image/jl_restore_system_image in staticdata.c.

If there is no sysimg file (jl_options.image_file == NULL), this also implies that --build was given on the command line, so the final result should be a new sysimg file. During Julia initialization, minimal Core and Main modules are created. Then a file named boot.jl is evaluated from the current directory. Julia then evaluates any file given as a command line argument until it reaches the end. Finally, it saves the resulting environment to a "sysimg" file for use as a starting point for a future Julia run.

+> (jl-parse-file "<filename>")

Macro Expansion

When eval() encounters a macro, it expands that AST node before attempting to evaluate the expression. Macro expansion involves a handoff from eval() (in Julia), to the parser function jl_macroexpand() (written in flisp) to the Julia macro itself (written in - what else - Julia) via fl_invoke_julia_macro(), and back.

Typically, macro expansion is invoked as a first step during a call to Meta.lower()/jl_expand(), although it can also be invoked directly by a call to macroexpand()/jl_macroexpand().

Type Inference

Type inference is implemented in Julia by typeinf() in compiler/typeinfer.jl. Type inference is the process of examining a Julia function and determining bounds for the types of each of its variables, as well as bounds on the type of the return value from the function. This enables many future optimizations, such as unboxing of known immutable values, and compile-time hoisting of various run-time operations such as computing field offsets and function pointers. Type inference may also include other steps such as constant propagation and inlining.

More Definitions

JIT Code Generation

Codegen is the process of turning a Julia AST into native machine code.

The JIT environment is initialized by an early call to jl_init_codegen in codegen.cpp.

On demand, a Julia method is converted into a native function by the function emit_function(jl_method_instance_t*). (note, when using the MCJIT (in LLVM v3.4+), each function must be JIT into a new module.) This function recursively calls emit_expr() until the entire function has been emitted.

Much of the remaining bulk of this file is devoted to various manual optimizations of specific code patterns. For example, emit_known_call() knows how to inline many of the primitive functions (defined in builtins.c) for various combinations of argument types.

Other parts of codegen are handled by various helper files:

Bootstrapping

The process of creating a new system image is called "bootstrapping".

The etymology of this word comes from the phrase "pulling oneself up by the bootstraps", and refers to the idea of starting from a very limited set of available functions and definitions and ending with the creation of a full-featured environment.

System Image

The system image is a precompiled archive of a set of Julia files. The sys.ji file distributed with Julia is one such system image, generated by executing the file sysimg.jl, and serializing the resulting environment (including Types, Functions, Modules, and all other defined values) into a file. Therefore, it contains a frozen version of the Main, Core, and Base modules (and whatever else was in the environment at the end of bootstrapping). This serializer/deserializer is implemented by jl_save_system_image/jl_restore_system_image in staticdata.c.

If there is no sysimg file (jl_options.image_file == NULL), this also implies that --build was given on the command line, so the final result should be a new sysimg file. During Julia initialization, minimal Core and Main modules are created. Then a file named boot.jl is evaluated from the current directory. Julia then evaluates any file given as a command line argument until it reaches the end. Finally, it saves the resulting environment to a "sysimg" file for use as a starting point for a future Julia run.

diff --git a/en/v1.12-dev/devdocs/external_profilers/index.html b/en/v1.12-dev/devdocs/external_profilers/index.html index b2363e70415c..34789a6c3273 100644 --- a/en/v1.12-dev/devdocs/external_profilers/index.html +++ b/en/v1.12-dev/devdocs/external_profilers/index.html @@ -8,4 +8,4 @@ Base.compilecache(pkg) end

Here, we use a custom port for tracy which makes it easier to find the correct client in the Tracy UI to connect to.

Adding metadata to zones

The various jl_timing_show_* and jl_timing_printf functions can be used to attach a string (or strings) to a zone. For example, the trace zone for inference shows the method instance that is being inferred.

The TracyCZoneColor function can be used to set the color of a certain zone. Search through the codebase to see how it is used.

Viewing Tracy files in your browser

Visit https://topolarity.github.io/trace-viewer/ for an (experimental) web viewer for Tracy traces.

You can open a local .tracy file or provide a URL from the web (e.g. a file in a Github repo). If you load a trace file from the web, you can also share the page URL directly with others, enabling them to view the same trace.

Enabling stack trace samples

To enable call stack sampling in Tracy, build Julia with these options in your Make.user file:

WITH_TRACY := 1
 WITH_TRACY_CALLSTACKS := 1
-USE_BINARYBUILDER_LIBTRACYCLIENT := 0

You may also need to run make -C deps clean-libtracyclient to force a re-build of Tracy.

This feature has a significant impact on trace size and profiling overhead, so it is recommended to leave call stack sampling off when possible, especially if you intend to share your trace files online.

Note that the Julia JIT runtime does not yet have integration for Tracy's symbolification, so Julia functions will typically be unknown in these stack traces.

Intel VTune (ITTAPI) Profiler

This section is yet to be written.

+USE_BINARYBUILDER_LIBTRACYCLIENT := 0

You may also need to run make -C deps clean-libtracyclient to force a re-build of Tracy.

This feature has a significant impact on trace size and profiling overhead, so it is recommended to leave call stack sampling off when possible, especially if you intend to share your trace files online.

Note that the Julia JIT runtime does not yet have integration for Tracy's symbolification, so Julia functions will typically be unknown in these stack traces.

Intel VTune (ITTAPI) Profiler

This section is yet to be written.

diff --git a/en/v1.12-dev/devdocs/functions/index.html b/en/v1.12-dev/devdocs/functions/index.html index 58ca632c4a59..e09fb15e5633 100644 --- a/en/v1.12-dev/devdocs/functions/index.html +++ b/en/v1.12-dev/devdocs/functions/index.html @@ -43,4 +43,4 @@ # unless `options` is empty #circle#1(color, fill, pairs(options), circle, center, radius) -end

The function Core.kwftype(t) creates the field t.name.mt.kwsorter (if it hasn't been created yet), and returns the type of that function.

This design has the feature that call sites that don't use keyword arguments require no special handling; everything works as if they were not part of the language at all. Call sites that do use keyword arguments are dispatched directly to the called function's kwsorter. For example the call:

circle((0, 0), 1.0, color = red; other...)

is lowered to:

kwcall(merge((color = red,), other), circle, (0, 0), 1.0)

kwcall (also inCore) denotes a kwcall signature and dispatch. The keyword splatting operation (written as other...) calls the named tuple merge function. This function further unpacks each element of other, expecting each one to contain two values (a symbol and a value). Naturally, a more efficient implementation is available if all splatted arguments are named tuples. Notice that the original circle function is passed through, to handle closures.

Compiler efficiency issues

Generating a new type for every function has potentially serious consequences for compiler resource use when combined with Julia's "specialize on all arguments by default" design. Indeed, the initial implementation of this design suffered from much longer build and test times, higher memory use, and a system image nearly 2x larger than the baseline. In a naive implementation, the problem is bad enough to make the system nearly unusable. Several significant optimizations were needed to make the design practical.

The first issue is excessive specialization of functions for different values of function-valued arguments. Many functions simply "pass through" an argument to somewhere else, e.g. to another function or to a storage location. Such functions do not need to be specialized for every closure that might be passed in. Fortunately this case is easy to distinguish by simply considering whether a function calls one of its arguments (i.e. the argument appears in "head position" somewhere). Performance-critical higher-order functions like map certainly call their argument function and so will still be specialized as expected. This optimization is implemented by recording which arguments are called during the analyze-variables pass in the front end. When cache_method sees an argument in the Function type hierarchy passed to a slot declared as Any or Function, it behaves as if the @nospecialize annotation were applied. This heuristic seems to be extremely effective in practice.

The next issue concerns the structure of method cache hash tables. Empirical studies show that the vast majority of dynamically-dispatched calls involve one or two arguments. In turn, many of these cases can be resolved by considering only the first argument. (Aside: proponents of single dispatch would not be surprised by this at all. However, this argument means "multiple dispatch is easy to optimize in practice", and that we should therefore use it, not "we should use single dispatch"!) So the method cache uses the type of the first argument as its primary key. Note, however, that this corresponds to the second element of the tuple type for a function call (the first element being the type of the function itself). Typically, type variation in head position is extremely low – indeed, the majority of functions belong to singleton types with no parameters. However, this is not the case for constructors, where a single method table holds constructors for every type. Therefore the Type method table is special-cased to use the first tuple type element instead of the second.

The front end generates type declarations for all closures. Initially, this was implemented by generating normal type declarations. However, this produced an extremely large number of constructors, all of which were trivial (simply passing all arguments through to new). Since methods are partially ordered, inserting all of these methods is O(n²), plus there are just too many of them to keep around. This was optimized by generating struct_type expressions directly (bypassing default constructor generation), and using new directly to create closure instances. Not the prettiest thing ever, but you do what you gotta do.

The next problem was the @test macro, which generated a 0-argument closure for each test case. This is not really necessary, since each test case is simply run once in place. Therefore, @test was modified to expand to a try-catch block that records the test result (true, false, or exception raised) and calls the test suite handler on it.

+end

The function Core.kwftype(t) creates the field t.name.mt.kwsorter (if it hasn't been created yet), and returns the type of that function.

This design has the feature that call sites that don't use keyword arguments require no special handling; everything works as if they were not part of the language at all. Call sites that do use keyword arguments are dispatched directly to the called function's kwsorter. For example the call:

circle((0, 0), 1.0, color = red; other...)

is lowered to:

kwcall(merge((color = red,), other), circle, (0, 0), 1.0)

kwcall (also inCore) denotes a kwcall signature and dispatch. The keyword splatting operation (written as other...) calls the named tuple merge function. This function further unpacks each element of other, expecting each one to contain two values (a symbol and a value). Naturally, a more efficient implementation is available if all splatted arguments are named tuples. Notice that the original circle function is passed through, to handle closures.

Compiler efficiency issues

Generating a new type for every function has potentially serious consequences for compiler resource use when combined with Julia's "specialize on all arguments by default" design. Indeed, the initial implementation of this design suffered from much longer build and test times, higher memory use, and a system image nearly 2x larger than the baseline. In a naive implementation, the problem is bad enough to make the system nearly unusable. Several significant optimizations were needed to make the design practical.

The first issue is excessive specialization of functions for different values of function-valued arguments. Many functions simply "pass through" an argument to somewhere else, e.g. to another function or to a storage location. Such functions do not need to be specialized for every closure that might be passed in. Fortunately this case is easy to distinguish by simply considering whether a function calls one of its arguments (i.e. the argument appears in "head position" somewhere). Performance-critical higher-order functions like map certainly call their argument function and so will still be specialized as expected. This optimization is implemented by recording which arguments are called during the analyze-variables pass in the front end. When cache_method sees an argument in the Function type hierarchy passed to a slot declared as Any or Function, it behaves as if the @nospecialize annotation were applied. This heuristic seems to be extremely effective in practice.

The next issue concerns the structure of method cache hash tables. Empirical studies show that the vast majority of dynamically-dispatched calls involve one or two arguments. In turn, many of these cases can be resolved by considering only the first argument. (Aside: proponents of single dispatch would not be surprised by this at all. However, this argument means "multiple dispatch is easy to optimize in practice", and that we should therefore use it, not "we should use single dispatch"!) So the method cache uses the type of the first argument as its primary key. Note, however, that this corresponds to the second element of the tuple type for a function call (the first element being the type of the function itself). Typically, type variation in head position is extremely low – indeed, the majority of functions belong to singleton types with no parameters. However, this is not the case for constructors, where a single method table holds constructors for every type. Therefore the Type method table is special-cased to use the first tuple type element instead of the second.

The front end generates type declarations for all closures. Initially, this was implemented by generating normal type declarations. However, this produced an extremely large number of constructors, all of which were trivial (simply passing all arguments through to new). Since methods are partially ordered, inserting all of these methods is O(n²), plus there are just too many of them to keep around. This was optimized by generating struct_type expressions directly (bypassing default constructor generation), and using new directly to create closure instances. Not the prettiest thing ever, but you do what you gotta do.

The next problem was the @test macro, which generated a 0-argument closure for each test case. This is not really necessary, since each test case is simply run once in place. Therefore, @test was modified to expand to a try-catch block that records the test result (true, false, or exception raised) and calls the test suite handler on it.

diff --git a/en/v1.12-dev/devdocs/gc-sa/index.html b/en/v1.12-dev/devdocs/gc-sa/index.html index 38ecdefcdc6c..860ce6bb5ac1 100644 --- a/en/v1.12-dev/devdocs/gc-sa/index.html +++ b/en/v1.12-dev/devdocs/gc-sa/index.html @@ -72,4 +72,4 @@ // that val is rooted under these conditions JL_GC_PROMISE_ROOTED(val); } -}

Completeness of analysis

The analyzer only looks at local information. In particular, e.g. in the PROPAGATES_ROOT case above, it assumes that such memory is only modified in ways it can see, not in any called functions (unless it happens to decide to consider them in its analysis) and not in any concurrently running threads. As such, it may miss a few problematic cases, though in practice such concurrent modification is fairly rare. Improving the analyzer to handle more such cases may be an interesting topic for future work.

+}

Completeness of analysis

The analyzer only looks at local information. In particular, e.g. in the PROPAGATES_ROOT case above, it assumes that such memory is only modified in ways it can see, not in any called functions (unless it happens to decide to consider them in its analysis) and not in any concurrently running threads. As such, it may miss a few problematic cases, though in practice such concurrent modification is fairly rare. Improving the analyzer to handle more such cases may be an interesting topic for future work.

diff --git a/en/v1.12-dev/devdocs/gc/index.html b/en/v1.12-dev/devdocs/gc/index.html index 9397919892b3..23574eaa532b 100644 --- a/en/v1.12-dev/devdocs/gc/index.html +++ b/en/v1.12-dev/devdocs/gc/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Garbage Collection in Julia

Introduction

Julia has a non-moving, partially concurrent, parallel, generational and mostly precise mark-sweep collector (an interface for conservative stack scanning is provided as an option for users who wish to call Julia from C).

Allocation

Julia uses two types of allocators, the size of the allocation request determining which one is used. Objects up to 2k bytes are allocated on a per-thread free-list pool allocator, while objects larger than 2k bytes are allocated through libc malloc.

Julia’s pool allocator partitions objects on different size classes, so that a memory page managed by the pool allocator (which spans 4 operating system pages on 64bit platforms) only contains objects of the same size class. Each memory page from the pool allocator is paired with some page metadata stored on per-thread lock-free lists. The page metadata contains information such as whether the page has live objects at all, number of free slots, and offsets to the first and last objects in the free-list contained in that page. These metadata are used to optimize the collection phase: a page which has no live objects at all may be returned to the operating system without any need of scanning it, for example.

While a page that has no objects may be returned to the operating system, its associated metadata is permanently allocated and may outlive the given page. As mentioned above, metadata for allocated pages are stored on per-thread lock-free lists. Metadata for free pages, however, may be stored into three separate lock-free lists depending on whether the page has been mapped but never accessed (page_pool_clean), or whether the page has been lazily sweeped and it's waiting to be madvised by a background GC thread (page_pool_lazily_freed), or whether the page has been madvised (page_pool_freed).

Julia's pool allocator follows a "tiered" allocation discipline. When requesting a memory page for the pool allocator, Julia will:

  • Try to claim a page from page_pool_lazily_freed, which contains pages which were empty on the last stop-the-world phase, but not yet madivsed by a concurrent sweeper GC thread.

  • If it failed claiming a page from page_pool_lazily_freed, it will try to claim a page from the page_pool_clean, which contains pages which were mmaped on a previous page allocation request but never accessed.

  • If it failed claiming a page from pool_page_clean and from page_pool_lazily_freed, it will try to claim a page from page_pool_freed, which contains pages which have already been madvised by a concurrent sweeper GC thread and whose underlying virtual address can be recycled.

  • If it failed in all of the attempts mentioned above, it will mmap a batch of pages, claim one page for itself, and insert the remaining pages into page_pool_clean.

Diagram of tiered pool allocation

Marking and Generational Collection

Julia’s mark phase is implemented through a parallel iterative depth-first-search over the object graph. Julia’s collector is non-moving, so object age information can’t be determined through the memory region in which the object resides alone, but has to be somehow encoded in the object header or on a side table. The lowest two bits of an object’s header are used to store, respectively, a mark bit that is set when an object is scanned during the mark phase and an age bit for the generational collection.

Generational collection is implemented through sticky bits: objects are only pushed to the mark-stack, and therefore traced, if their mark-bits are not set. When objects reach the oldest generation, their mark-bits are not reset during the so-called "quick-sweep", which leads to these objects not being traced in a subsequent mark phase. A "full-sweep", however, causes the mark-bits of all objects to be reset, leading to all objects being traced in a subsequent mark phase. Objects are promoted to the next generation during every sweep phase they survive. On the mutator side, field writes are intercepted through a write barrier that pushes an object’s address into a per-thread remembered set if the object is in the last generation, and if the object at the field being written is not. Objects in this remembered set are then traced during the mark phase.

Sweeping

Sweeping of object pools for Julia may fall into two categories: if a given page managed by the pool allocator contains at least one live object, then a free-list must be threaded through its dead objects; if a given page contains no live objects at all, then its underlying physical memory may be returned to the operating system through, for instance, the use of madvise system calls on Linux.

The first category of sweeping is parallelized through work-stealing. For the second category of sweeping, if concurrent page sweeping is enabled through the flag --gcthreads=X,1 we perform the madvise system calls in a background sweeper thread, concurrently with the mutator threads. During the stop-the-world phase of the collector, pool allocated pages which contain no live objects are initially pushed into the pool_page_lazily_freed. The background sweeping thread is then woken up and is responsible for removing pages from pool_page_lazily_freed, calling madvise on them, and inserting them into pool_page_freed. As described above, pool_page_lazily_freed is also shared with mutator threads. This implies that on allocation-heavy multithreaded workloads, mutator threads would often avoid a page fault on allocation (coming from accessing a fresh mmaped page or accessing a madvised page) by directly allocating from a page in pool_page_lazily_freed, while the background sweeper thread needs to madvise a reduce number of pages given some of them were already claimed by the mutators.

Heuristics

GC heuristics tune the GC by changing the size of the allocation interval between garbage collections.

The GC heuristics measure how big the heap size is after a collection and set the next collection according to the algorithm described by https://dl.acm.org/doi/10.1145/3563323, in summary, it argues that the heap target should have a square root relationship with the live heap, and that it should also be scaled by how fast the GC is freeing objects and how fast the mutators are allocating. The heuristics measure the heap size by counting the number of pages that are in use and the objects that use malloc. Previously we measured the heap size by counting the alive objects, but that doesn't take into account fragmentation which could lead to bad decisions, that also meant that we used thread local information (allocations) to make decisions about a process wide (when to GC), measuring pages means the decision is global.

The GC will do full collections when the heap size reaches 80% of the maximum allowed size.

+

Garbage Collection in Julia

Introduction

Julia has a non-moving, partially concurrent, parallel, generational and mostly precise mark-sweep collector (an interface for conservative stack scanning is provided as an option for users who wish to call Julia from C).

Allocation

Julia uses two types of allocators, the size of the allocation request determining which one is used. Objects up to 2k bytes are allocated on a per-thread free-list pool allocator, while objects larger than 2k bytes are allocated through libc malloc.

Julia’s pool allocator partitions objects on different size classes, so that a memory page managed by the pool allocator (which spans 4 operating system pages on 64bit platforms) only contains objects of the same size class. Each memory page from the pool allocator is paired with some page metadata stored on per-thread lock-free lists. The page metadata contains information such as whether the page has live objects at all, number of free slots, and offsets to the first and last objects in the free-list contained in that page. These metadata are used to optimize the collection phase: a page which has no live objects at all may be returned to the operating system without any need of scanning it, for example.

While a page that has no objects may be returned to the operating system, its associated metadata is permanently allocated and may outlive the given page. As mentioned above, metadata for allocated pages are stored on per-thread lock-free lists. Metadata for free pages, however, may be stored into three separate lock-free lists depending on whether the page has been mapped but never accessed (page_pool_clean), or whether the page has been lazily sweeped and it's waiting to be madvised by a background GC thread (page_pool_lazily_freed), or whether the page has been madvised (page_pool_freed).

Julia's pool allocator follows a "tiered" allocation discipline. When requesting a memory page for the pool allocator, Julia will:

  • Try to claim a page from page_pool_lazily_freed, which contains pages which were empty on the last stop-the-world phase, but not yet madivsed by a concurrent sweeper GC thread.

  • If it failed claiming a page from page_pool_lazily_freed, it will try to claim a page from the page_pool_clean, which contains pages which were mmaped on a previous page allocation request but never accessed.

  • If it failed claiming a page from pool_page_clean and from page_pool_lazily_freed, it will try to claim a page from page_pool_freed, which contains pages which have already been madvised by a concurrent sweeper GC thread and whose underlying virtual address can be recycled.

  • If it failed in all of the attempts mentioned above, it will mmap a batch of pages, claim one page for itself, and insert the remaining pages into page_pool_clean.

Diagram of tiered pool allocation

Marking and Generational Collection

Julia’s mark phase is implemented through a parallel iterative depth-first-search over the object graph. Julia’s collector is non-moving, so object age information can’t be determined through the memory region in which the object resides alone, but has to be somehow encoded in the object header or on a side table. The lowest two bits of an object’s header are used to store, respectively, a mark bit that is set when an object is scanned during the mark phase and an age bit for the generational collection.

Generational collection is implemented through sticky bits: objects are only pushed to the mark-stack, and therefore traced, if their mark-bits are not set. When objects reach the oldest generation, their mark-bits are not reset during the so-called "quick-sweep", which leads to these objects not being traced in a subsequent mark phase. A "full-sweep", however, causes the mark-bits of all objects to be reset, leading to all objects being traced in a subsequent mark phase. Objects are promoted to the next generation during every sweep phase they survive. On the mutator side, field writes are intercepted through a write barrier that pushes an object’s address into a per-thread remembered set if the object is in the last generation, and if the object at the field being written is not. Objects in this remembered set are then traced during the mark phase.

Sweeping

Sweeping of object pools for Julia may fall into two categories: if a given page managed by the pool allocator contains at least one live object, then a free-list must be threaded through its dead objects; if a given page contains no live objects at all, then its underlying physical memory may be returned to the operating system through, for instance, the use of madvise system calls on Linux.

The first category of sweeping is parallelized through work-stealing. For the second category of sweeping, if concurrent page sweeping is enabled through the flag --gcthreads=X,1 we perform the madvise system calls in a background sweeper thread, concurrently with the mutator threads. During the stop-the-world phase of the collector, pool allocated pages which contain no live objects are initially pushed into the pool_page_lazily_freed. The background sweeping thread is then woken up and is responsible for removing pages from pool_page_lazily_freed, calling madvise on them, and inserting them into pool_page_freed. As described above, pool_page_lazily_freed is also shared with mutator threads. This implies that on allocation-heavy multithreaded workloads, mutator threads would often avoid a page fault on allocation (coming from accessing a fresh mmaped page or accessing a madvised page) by directly allocating from a page in pool_page_lazily_freed, while the background sweeper thread needs to madvise a reduce number of pages given some of them were already claimed by the mutators.

Heuristics

GC heuristics tune the GC by changing the size of the allocation interval between garbage collections.

The GC heuristics measure how big the heap size is after a collection and set the next collection according to the algorithm described by https://dl.acm.org/doi/10.1145/3563323, in summary, it argues that the heap target should have a square root relationship with the live heap, and that it should also be scaled by how fast the GC is freeing objects and how fast the mutators are allocating. The heuristics measure the heap size by counting the number of pages that are in use and the objects that use malloc. Previously we measured the heap size by counting the alive objects, but that doesn't take into account fragmentation which could lead to bad decisions, that also meant that we used thread local information (allocations) to make decisions about a process wide (when to GC), measuring pages means the decision is global.

The GC will do full collections when the heap size reaches 80% of the maximum allowed size.

diff --git a/en/v1.12-dev/devdocs/inference/index.html b/en/v1.12-dev/devdocs/inference/index.html index 50a33ec2a94d..cf51acfa7728 100644 --- a/en/v1.12-dev/devdocs/inference/index.html +++ b/en/v1.12-dev/devdocs/inference/index.html @@ -28,4 +28,4 @@ 0 4 ─ goto #5 0 5 ─ %11 = Core.tuple(%8)::Tuple{Float64} 0 └── return %11 -

The line costs are in the left column. This includes the consequences of inlining and other forms of optimization.

+

The line costs are in the left column. This includes the consequences of inlining and other forms of optimization.

diff --git a/en/v1.12-dev/devdocs/init/index.html b/en/v1.12-dev/devdocs/init/index.html index 17f7835a6591..adb60c1d275f 100644 --- a/en/v1.12-dev/devdocs/init/index.html +++ b/en/v1.12-dev/devdocs/init/index.html @@ -12,4 +12,4 @@ jl_any_type, jl_emptysvec, 32);

jl_init_tasks() creates the jl_datatype_t* jl_task_type object; initializes the global jl_root_task struct; and sets jl_current_task to the root task.

jl_init_codegen() initializes the LLVM library.

jl_init_serializer() initializes 8-bit serialization tags for builtin jl_value_t values.

If there is no sysimg file (!jl_options.image_file) then the Core and Main modules are created and boot.jl is evaluated:

jl_core_module = jl_new_module(jl_symbol("Core")) creates the Julia Core module.

jl_init_intrinsic_functions() creates a new Julia module Intrinsics containing constant jl_intrinsic_type symbols. These define an integer code for each intrinsic function. emit_intrinsic() translates these symbols into LLVM instructions during code generation.

jl_init_primitives() hooks C functions up to Julia function symbols. e.g. the symbol Core.:(===)() is bound to C function pointer jl_f_is() by calling add_builtin_func("===", jl_f_is).

jl_new_main_module() creates the global "Main" module and sets jl_current_task->current_module = jl_main_module.

Note: _julia_init() then sets jl_root_task->current_module = jl_core_module. jl_root_task is an alias of jl_current_task at this point, so the current_module set by jl_new_main_module() above is overwritten.

jl_load("boot.jl", sizeof("boot.jl")) calls jl_parse_eval_all which repeatedly calls jl_toplevel_eval_flex() to execute boot.jl. <!– TODO – drill down into eval? –>

jl_get_builtin_hooks() initializes global C pointers to Julia globals defined in boot.jl.

jl_init_box_caches() pre-allocates global boxed integer value objects for values up to 1024. This speeds up allocation of boxed ints later on. e.g.:

jl_value_t *jl_box_uint8(uint32_t x)
 {
     return boxed_uint8_cache[(uint8_t)x];
-}

_julia_init() iterates over the jl_core_module->bindings.table looking for jl_datatype_t values and sets the type name's module prefix to jl_core_module.

jl_add_standard_imports(jl_main_module) does "using Base" in the "Main" module.

Note: _julia_init() now reverts to jl_root_task->current_module = jl_main_module as it was before being set to jl_core_module above.

Platform specific signal handlers are initialized for SIGSEGV (OSX, Linux), and SIGFPE (Windows).

Other signals (SIGINFO, SIGBUS, SIGILL, SIGTERM, SIGABRT, SIGQUIT, SIGSYS and SIGPIPE) are hooked up to sigdie_handler() which prints a backtrace.

jl_init_restored_module() calls jl_module_run_initializer() for each deserialized module to run the __init__() function.

Finally sigint_handler() is hooked up to SIGINT and calls jl_throw(jl_interrupt_exception).

_julia_init() then returns back to main() in cli/loader_exe.c and main() calls repl_entrypoint(argc, (char**)argv).

sysimg

If there is a sysimg file, it contains a pre-cooked image of the Core and Main modules (and whatever else is created by boot.jl). See Building the Julia system image.

jl_restore_system_image() deserializes the saved sysimg into the current Julia runtime environment and initialization continues after jl_init_box_caches() below...

Note: jl_restore_system_image() (and staticdata.c in general) uses the Legacy ios.c library.

repl_entrypoint()

repl_entrypoint() loads the contents of argv[] into Base.ARGS.

If a .jl "program" file was supplied on the command line, then exec_program() calls jl_load(program,len) which calls jl_parse_eval_all which repeatedly calls jl_toplevel_eval_flex() to execute the program.

However, in our example (julia -e 'println("Hello World!")'), jl_get_global(jl_base_module, jl_symbol("_start")) looks up Base._start and jl_apply() executes it.

Base._start

Base._start calls Base.exec_options which calls jl_parse_input_line("println("Hello World!")") to create an expression object and Core.eval(Main, ex) to execute the parsed expression ex in the module context of Main.

Core.eval

Core.eval(Main, ex) calls jl_toplevel_eval_in(m, ex), which calls jl_toplevel_eval_flex. jl_toplevel_eval_flex implements a simple heuristic to decide whether to compile a given code thunk or run it by interpreter. When given println("Hello World!"), it would usually decide to run the code by interpreter, in which case it calls jl_interpret_toplevel_thunk, which then calls eval_body.

The stack dump below shows how the interpreter works its way through various methods of Base.println() and Base.print() before arriving at write(s::IO, a::Array{T}) where T which does ccall(jl_uv_write()).

jl_uv_write() calls uv_write() to write "Hello World!" to JL_STDOUT. See Libuv wrappers for stdio.:

Hello World!
Stack frameSource codeNotes
jl_uv_write()jl_uv.ccalled though ccall
julia_write_282942stream.jlfunction write!(s::IO, a::Array{T}) where T
julia_print_284639ascii.jlprint(io::IO, s::String) = (write(io, s); nothing)
jlcall_print_284639
jl_apply()julia.h
jl_trampoline()builtins.c
jl_apply()julia.h
jl_apply_generic()gf.cBase.print(Base.TTY, String)
jl_apply()julia.h
jl_trampoline()builtins.c
jl_apply()julia.h
jl_apply_generic()gf.cBase.print(Base.TTY, String, Char, Char...)
jl_apply()julia.h
jl_f_apply()builtins.c
jl_apply()julia.h
jl_trampoline()builtins.c
jl_apply()julia.h
jl_apply_generic()gf.cBase.println(Base.TTY, String, String...)
jl_apply()julia.h
jl_trampoline()builtins.c
jl_apply()julia.h
jl_apply_generic()gf.cBase.println(String,)
jl_apply()julia.h
do_call()interpreter.c
eval_body()interpreter.c
jl_interpret_toplevel_thunkinterpreter.c
jl_toplevel_eval_flextoplevel.c
jl_toplevel_eval_intoplevel.c
Core.evalboot.jl

Since our example has just one function call, which has done its job of printing "Hello World!", the stack now rapidly unwinds back to main().

jl_atexit_hook()

main() calls jl_atexit_hook(). This calls Base._atexit, then calls jl_gc_run_all_finalizers() and cleans up libuv handles.

julia_save()

Finally, main() calls julia_save(), which if requested on the command line, saves the runtime state to a new system image. See jl_compile_all() and jl_save_system_image().

+}

_julia_init() iterates over the jl_core_module->bindings.table looking for jl_datatype_t values and sets the type name's module prefix to jl_core_module.

jl_add_standard_imports(jl_main_module) does "using Base" in the "Main" module.

Note: _julia_init() now reverts to jl_root_task->current_module = jl_main_module as it was before being set to jl_core_module above.

Platform specific signal handlers are initialized for SIGSEGV (OSX, Linux), and SIGFPE (Windows).

Other signals (SIGINFO, SIGBUS, SIGILL, SIGTERM, SIGABRT, SIGQUIT, SIGSYS and SIGPIPE) are hooked up to sigdie_handler() which prints a backtrace.

jl_init_restored_module() calls jl_module_run_initializer() for each deserialized module to run the __init__() function.

Finally sigint_handler() is hooked up to SIGINT and calls jl_throw(jl_interrupt_exception).

_julia_init() then returns back to main() in cli/loader_exe.c and main() calls repl_entrypoint(argc, (char**)argv).

sysimg

If there is a sysimg file, it contains a pre-cooked image of the Core and Main modules (and whatever else is created by boot.jl). See Building the Julia system image.

jl_restore_system_image() deserializes the saved sysimg into the current Julia runtime environment and initialization continues after jl_init_box_caches() below...

Note: jl_restore_system_image() (and staticdata.c in general) uses the Legacy ios.c library.

repl_entrypoint()

repl_entrypoint() loads the contents of argv[] into Base.ARGS.

If a .jl "program" file was supplied on the command line, then exec_program() calls jl_load(program,len) which calls jl_parse_eval_all which repeatedly calls jl_toplevel_eval_flex() to execute the program.

However, in our example (julia -e 'println("Hello World!")'), jl_get_global(jl_base_module, jl_symbol("_start")) looks up Base._start and jl_apply() executes it.

Base._start

Base._start calls Base.exec_options which calls jl_parse_input_line("println("Hello World!")") to create an expression object and Core.eval(Main, ex) to execute the parsed expression ex in the module context of Main.

Core.eval

Core.eval(Main, ex) calls jl_toplevel_eval_in(m, ex), which calls jl_toplevel_eval_flex. jl_toplevel_eval_flex implements a simple heuristic to decide whether to compile a given code thunk or run it by interpreter. When given println("Hello World!"), it would usually decide to run the code by interpreter, in which case it calls jl_interpret_toplevel_thunk, which then calls eval_body.

The stack dump below shows how the interpreter works its way through various methods of Base.println() and Base.print() before arriving at write(s::IO, a::Array{T}) where T which does ccall(jl_uv_write()).

jl_uv_write() calls uv_write() to write "Hello World!" to JL_STDOUT. See Libuv wrappers for stdio.:

Hello World!
Stack frameSource codeNotes
jl_uv_write()jl_uv.ccalled though ccall
julia_write_282942stream.jlfunction write!(s::IO, a::Array{T}) where T
julia_print_284639ascii.jlprint(io::IO, s::String) = (write(io, s); nothing)
jlcall_print_284639
jl_apply()julia.h
jl_trampoline()builtins.c
jl_apply()julia.h
jl_apply_generic()gf.cBase.print(Base.TTY, String)
jl_apply()julia.h
jl_trampoline()builtins.c
jl_apply()julia.h
jl_apply_generic()gf.cBase.print(Base.TTY, String, Char, Char...)
jl_apply()julia.h
jl_f_apply()builtins.c
jl_apply()julia.h
jl_trampoline()builtins.c
jl_apply()julia.h
jl_apply_generic()gf.cBase.println(Base.TTY, String, String...)
jl_apply()julia.h
jl_trampoline()builtins.c
jl_apply()julia.h
jl_apply_generic()gf.cBase.println(String,)
jl_apply()julia.h
do_call()interpreter.c
eval_body()interpreter.c
jl_interpret_toplevel_thunkinterpreter.c
jl_toplevel_eval_flextoplevel.c
jl_toplevel_eval_intoplevel.c
Core.evalboot.jl

Since our example has just one function call, which has done its job of printing "Hello World!", the stack now rapidly unwinds back to main().

jl_atexit_hook()

main() calls jl_atexit_hook(). This calls Base._atexit, then calls jl_gc_run_all_finalizers() and cleans up libuv handles.

julia_save()

Finally, main() calls julia_save(), which if requested on the command line, saves the runtime state to a new system image. See jl_compile_all() and jl_save_system_image().

diff --git a/en/v1.12-dev/devdocs/isbitsunionarrays/index.html b/en/v1.12-dev/devdocs/isbitsunionarrays/index.html index f6c862a01c09..216b0dd37740 100644 --- a/en/v1.12-dev/devdocs/isbitsunionarrays/index.html +++ b/en/v1.12-dev/devdocs/isbitsunionarrays/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

isbits Union Optimizations

In Julia, the Array type holds both "bits" values as well as heap-allocated "boxed" values. The distinction is whether the value itself is stored inline (in the direct allocated memory of the array), or if the memory of the array is simply a collection of pointers to objects allocated elsewhere. In terms of performance, accessing values inline is clearly an advantage over having to follow a pointer to the actual value. The definition of "isbits" generally means any Julia type with a fixed, determinate size, meaning no "pointer" fields, see ?isbitstype.

Julia also supports Union types, quite literally the union of a set of types. Custom Union type definitions can be extremely handy for applications wishing to "cut across" the nominal type system (i.e. explicit subtype relationships) and define methods or functionality on these, otherwise unrelated, set of types. A compiler challenge, however, is in determining how to treat these Union types. The naive approach (and indeed, what Julia itself did pre-0.7), is to simply make a "box" and then a pointer in the box to the actual value, similar to the previously mentioned "boxed" values. This is unfortunate, however, because of the number of small, primitive "bits" types (think UInt8, Int32, Float64, etc.) that would easily fit themselves inline in this "box" without needing any indirection for value access. There are two main ways Julia can take advantage of this optimization as of 0.7: isbits Union fields in types, and isbits Union Arrays.

isbits Union Structs

Julia now includes an optimization wherein "isbits Union" fields in types (mutable struct, struct, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. Union{UInt8, Int16} will have a size of two bytes, which represents the size needed of the largest Union type Int16), and in addition, allocating an extra "type tag byte" (UInt8), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of 0x02 for a field with type Union{Nothing, UInt8, Int16} would indicate that an Int16 value is stored in the 16 bits of the field in the structure's memory; a 0x01 value would indicate that a UInt8 value was stored in the first 8 bits of the 16 bits of the field's memory. Lastly, a value of 0x00 signals that the nothing value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory.

isbits Union Memory

Julia can now also store "isbits Union" values inline in a Memory, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra "type tag memory" of bytes, one byte per element, alongside the bytes of the actual data. This type tag memory serves the same function as the type field case: its value signals the type of the actual stored Union value. The "type tag memory" directly follows the regular data space. So the formula to access an isbits Union Array's type tag bytes is a->data + a->length * a->elsize.

+

isbits Union Optimizations

In Julia, the Array type holds both "bits" values as well as heap-allocated "boxed" values. The distinction is whether the value itself is stored inline (in the direct allocated memory of the array), or if the memory of the array is simply a collection of pointers to objects allocated elsewhere. In terms of performance, accessing values inline is clearly an advantage over having to follow a pointer to the actual value. The definition of "isbits" generally means any Julia type with a fixed, determinate size, meaning no "pointer" fields, see ?isbitstype.

Julia also supports Union types, quite literally the union of a set of types. Custom Union type definitions can be extremely handy for applications wishing to "cut across" the nominal type system (i.e. explicit subtype relationships) and define methods or functionality on these, otherwise unrelated, set of types. A compiler challenge, however, is in determining how to treat these Union types. The naive approach (and indeed, what Julia itself did pre-0.7), is to simply make a "box" and then a pointer in the box to the actual value, similar to the previously mentioned "boxed" values. This is unfortunate, however, because of the number of small, primitive "bits" types (think UInt8, Int32, Float64, etc.) that would easily fit themselves inline in this "box" without needing any indirection for value access. There are two main ways Julia can take advantage of this optimization as of 0.7: isbits Union fields in types, and isbits Union Arrays.

isbits Union Structs

Julia now includes an optimization wherein "isbits Union" fields in types (mutable struct, struct, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. Union{UInt8, Int16} will have a size of two bytes, which represents the size needed of the largest Union type Int16), and in addition, allocating an extra "type tag byte" (UInt8), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of 0x02 for a field with type Union{Nothing, UInt8, Int16} would indicate that an Int16 value is stored in the 16 bits of the field in the structure's memory; a 0x01 value would indicate that a UInt8 value was stored in the first 8 bits of the 16 bits of the field's memory. Lastly, a value of 0x00 signals that the nothing value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory.

isbits Union Memory

Julia can now also store "isbits Union" values inline in a Memory, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra "type tag memory" of bytes, one byte per element, alongside the bytes of the actual data. This type tag memory serves the same function as the type field case: its value signals the type of the actual stored Union value. The "type tag memory" directly follows the regular data space. So the formula to access an isbits Union Array's type tag bytes is a->data + a->length * a->elsize.

diff --git a/en/v1.12-dev/devdocs/jit/index.html b/en/v1.12-dev/devdocs/jit/index.html index b2f41e99ffe9..6bb3b14a5813 100644 --- a/en/v1.12-dev/devdocs/jit/index.html +++ b/en/v1.12-dev/devdocs/jit/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

JIT Design and Implementation

This document explains the design and implementation of Julia's JIT, after codegen has finished and unoptimized LLVM IR has been produced. The JIT is responsible for optimizing and compiling this IR to machine code, and for linking it into the current process and making the code available for execution.

Introduction

The JIT is responsible for managing compilation resources, looking up previously compiled code, and compiling new code. It is primarily built on LLVM's On-Request-Compilation (ORCv2) technology, which provides support for a number of useful features such as concurrent compilation, lazy compilation, and the ability to compile code in a separate process. Though LLVM provides a basic JIT compiler in the form of LLJIT, Julia uses many ORCv2 APIs directly to create its own custom JIT compiler.

Overview

Diagram of the compiler flow

Codegen produces an LLVM module containing IR for one or more Julia functions from the original Julia SSA IR produced by type inference (labeled as translate on the compiler diagram above). It also produces a mapping of code-instance to LLVM function name. However, though some optimizations have been applied by the Julia-based compiler on Julia IR, the LLVM IR produced by codegen still contains many opportunities for optimization. Thus, the first step the JIT takes is to run a target-independent optimization pipeline[tdp] on the LLVM module. Then, the JIT runs a target-dependent optimization pipeline, which includes target-specific optimizations and code generation, and outputs an object file. Finally, the JIT links the resulting object file into the current process and makes the code available for execution. All of this is controlled by code in src/jitlayers.cpp.

Currently, only one thread at a time is permitted to enter the optimize-compile-link pipeline at a time, due to restrictions imposed by one of our linkers (RuntimeDyld). However, the JIT is designed to support concurrent optimization and compilation, and the linker restriction is expected to be lifted in the future when RuntimeDyld has been fully superseded on all platforms.

Optimization Pipeline

The optimization pipeline is based off LLVM's new pass manager, but the pipeline is customized for Julia's needs. The pipeline is defined in src/pipeline.cpp, and broadly proceeds through a number of stages as detailed below.

  1. Early Simplification
    1. These passes are mainly used to simplify the IR and canonicalize patterns so that later passes can identify those patterns more easily. Additionally, various intrinsic calls such as branch prediction hints and annotations are lowered into other metadata or other IR features. SimplifyCFG (simplify control flow graph), DCE (dead code elimination), and SROA (scalar replacement of aggregates) are some of the key players here.
  2. Early Optimization
    1. These passes are typically cheap and are primarily focused around reducing the number of instructions in the IR and propagating knowledge to other instructions. For example, EarlyCSE is used to perform common subexpression elimination, and InstCombine and InstSimplify perform a number of small peephole optimizations to make operations less expensive.
  3. Loop Optimization
    1. These passes canonicalize and simplify loops. Loops are often hot code, which makes loop optimization extremely important for performance. Key players here include LoopRotate, LICM, and LoopFullUnroll. Some bounds check elimination also happens here, as a result of the IRCE pass which can prove certain bounds are never exceeded.
  4. Scalar Optimization
    1. The scalar optimization pipeline contains a number of more expensive, but more powerful passes such as GVN (global value numbering), SCCP (sparse conditional constant propagation), and another round of bounds check elimination. These passes are expensive, but they can often remove large amounts of code and make vectorization much more successful and effective. Several other simplification and optimization passes intersperse the more expensive ones to reduce the amount of work they have to do.
  5. Vectorization
    1. Automatic vectorization is an extremely powerful transformation for CPU-intensive code. Briefly, vectorization allows execution of a single instruction on multiple data (SIMD), e.g. performing 8 addition operations at the same time. However, proving code to be both capable of vectorization and profitable to vectorize is difficult, and this relies heavily on the prior optimization passes to massage the IR into a state where vectorization is worth it.
  6. Intrinsic Lowering
    1. Julia inserts a number of custom intrinsics, for reasons such as object allocation, garbage collection, and exception handling. These intrinsics were originally placed to make optimization opportunities more obvious, but they are now lowered into LLVM IR to enable the IR to be emitted as machine code.
  7. Cleanup
    1. These passes are last-chance optimizations, and perform small optimizations such as fused multiply-add propagation and division-remainder simplification. Additionally, targets that do not support half-precision floating point numbers will have their half-precision instructions lowered into single-precision instructions here, and passes are added to provide sanitizer support.

Target-Dependent Optimization and Code Generation

LLVM provides target-dependent optimization and machine code generation in the same pipeline, located in the TargetMachine for a given platform. These passes include instruction selection, instruction scheduling, register allocation, and machine code emission. The LLVM documentation provides a good overview of the process, and the LLVM source code is the best place to look for details on the pipeline and passes.

Linking

Currently, Julia is transitioning between two linkers: the older RuntimeDyld linker, and the newer JITLink linker. JITLink contains a number of features that RuntimeDyld does not have, such as concurrent and reentrant linking, but currently lacks good support for profiling integrations and does not yet support all of the platforms that RuntimeDyld supports. Over time, JITLink is expected to replace RuntimeDyld entirely. Further details on JITLink can be found in the LLVM documentation.

Execution

Once the code has been linked into the current process, it is available for execution. This fact is made known to the generating codeinst by updating the invoke, specsigflags, and specptr fields appropriately. Codeinsts support upgrading invoke, specsigflags, and specptr fields, so long as every combination of these fields that exists at any given point in time is valid to be called. This allows the JIT to update these fields without invalidating existing codeinsts, supporting a potential future concurrent JIT. Specifically, the following states may be valid:

  1. invoke is NULL, specsigflags is 0b00, specptr is NULL
    1. This is the initial state of a codeinst, and indicates that the codeinst has not yet been compiled.
  2. invoke is non-null, specsigflags is 0b00, specptr is NULL
    1. This indicates that the codeinst was not compiled with any specialization, and that the codeinst should be invoked directly. Note that in this instance, invoke does not read either the specsigflags or specptr fields, and therefore they may be modified without invalidating the invoke pointer.
  3. invoke is non-null, specsigflags is 0b10, specptr is non-null
    1. This indicates that the codeinst was compiled, but a specialized function signature was deemed unnecessary by codegen.
  4. invoke is non-null, specsigflags is 0b11, specptr is non-null
    1. This indicates that the codeinst was compiled, and a specialized function signature was deemed necessary by codegen. The specptr field contains a pointer to the specialized function signature. The invoke pointer is permitted to read both specsigflags and specptr fields.

In addition, there are a number of different transitional states that occur during the update process. To account for these potential situations, the following write and read patterns should be used when dealing with these codeinst fields.

  1. When writing invoke, specsigflags, and specptr:
    1. Perform an atomic compare-exchange operation of specptr assuming the old value was NULL. This compare-exchange operation should have at least acquire-release ordering, to provide ordering guarantees of the remaining memory operations in the write.
    2. If specptr was non-null, cease the write operation and wait for bit 0b10 of specsigflags to be written.
    3. Write the new low bit of specsigflags to its final value. This may be a relaxed write.
    4. Write the new invoke pointer to its final value. This must have at least a release memory ordering to synchronize with reads of invoke.
    5. Set the second bit of specsigflags to 1. This must be at least a release memory ordering to synchronize with reads of specsigflags. This step completes the write operation and announces to all other threads that all fields have been set.
  2. When reading all of invoke, specsigflags, and specptr:
    1. Read the invoke field with at least an acquire memory ordering. This load will be referred to as initial_invoke.
    2. If initial_invoke is NULL, the codeinst is not yet executable. invoke is NULL, specsigflags may be treated as 0b00, specptr may be treated as NULL.
    3. Read the specptr field with at least an acquire memory ordering.
    4. If specptr is NULL, then the initial_invoke pointer must not be relying on specptr to guarantee correct execution. Therefore, invoke is non-null, specsigflags may be treated as 0b00, specptr may be treated as NULL.
    5. If specptr is non-null, then initial_invoke might not be the final invoke field that uses specptr. This can occur if specptr has been written, but invoke has not yet been written. Therefore, spin on the second bit of specsigflags until it is set to 1 with at least acquire memory ordering.
    6. Re-read the invoke field with at least an acquire memory ordering. This load will be referred to as final_invoke.
    7. Read the specsigflags field with any memory ordering.
    8. invoke is final_invoke, specsigflags is the value read in step 7, specptr is the value read in step 3.
  3. When updating a specptr to a different but equivalent function pointer:
    1. Perform a release store of the new function pointer to specptr. Races here must be benign, as the old function pointer is required to still be valid, and any new ones are also required to be valid as well. Once a pointer has been written to specptr, it must always be callable whether or not it is later overwritten.

Although these write, read, and update steps are complicated, they ensure that the JIT can update codeinsts without invalidating existing codeinsts, and that the JIT can update codeinsts without invalidating existing invoke pointers. This allows the JIT to potentially reoptimize functions at higher optimization levels in the future, and also will allow the JIT to support concurrent compilation of functions in the future.

  • tdpThis is not a totally-target independent pipeline, as transformations such as vectorization rely upon target information such as vector register width and cost modeling. Additionally, codegen itself makes a few target-dependent assumptions, and the optimization pipeline will take advantage of that knowledge.
+

JIT Design and Implementation

This document explains the design and implementation of Julia's JIT, after codegen has finished and unoptimized LLVM IR has been produced. The JIT is responsible for optimizing and compiling this IR to machine code, and for linking it into the current process and making the code available for execution.

Introduction

The JIT is responsible for managing compilation resources, looking up previously compiled code, and compiling new code. It is primarily built on LLVM's On-Request-Compilation (ORCv2) technology, which provides support for a number of useful features such as concurrent compilation, lazy compilation, and the ability to compile code in a separate process. Though LLVM provides a basic JIT compiler in the form of LLJIT, Julia uses many ORCv2 APIs directly to create its own custom JIT compiler.

Overview

Diagram of the compiler flow

Codegen produces an LLVM module containing IR for one or more Julia functions from the original Julia SSA IR produced by type inference (labeled as translate on the compiler diagram above). It also produces a mapping of code-instance to LLVM function name. However, though some optimizations have been applied by the Julia-based compiler on Julia IR, the LLVM IR produced by codegen still contains many opportunities for optimization. Thus, the first step the JIT takes is to run a target-independent optimization pipeline[tdp] on the LLVM module. Then, the JIT runs a target-dependent optimization pipeline, which includes target-specific optimizations and code generation, and outputs an object file. Finally, the JIT links the resulting object file into the current process and makes the code available for execution. All of this is controlled by code in src/jitlayers.cpp.

Currently, only one thread at a time is permitted to enter the optimize-compile-link pipeline at a time, due to restrictions imposed by one of our linkers (RuntimeDyld). However, the JIT is designed to support concurrent optimization and compilation, and the linker restriction is expected to be lifted in the future when RuntimeDyld has been fully superseded on all platforms.

Optimization Pipeline

The optimization pipeline is based off LLVM's new pass manager, but the pipeline is customized for Julia's needs. The pipeline is defined in src/pipeline.cpp, and broadly proceeds through a number of stages as detailed below.

  1. Early Simplification
    1. These passes are mainly used to simplify the IR and canonicalize patterns so that later passes can identify those patterns more easily. Additionally, various intrinsic calls such as branch prediction hints and annotations are lowered into other metadata or other IR features. SimplifyCFG (simplify control flow graph), DCE (dead code elimination), and SROA (scalar replacement of aggregates) are some of the key players here.
  2. Early Optimization
    1. These passes are typically cheap and are primarily focused around reducing the number of instructions in the IR and propagating knowledge to other instructions. For example, EarlyCSE is used to perform common subexpression elimination, and InstCombine and InstSimplify perform a number of small peephole optimizations to make operations less expensive.
  3. Loop Optimization
    1. These passes canonicalize and simplify loops. Loops are often hot code, which makes loop optimization extremely important for performance. Key players here include LoopRotate, LICM, and LoopFullUnroll. Some bounds check elimination also happens here, as a result of the IRCE pass which can prove certain bounds are never exceeded.
  4. Scalar Optimization
    1. The scalar optimization pipeline contains a number of more expensive, but more powerful passes such as GVN (global value numbering), SCCP (sparse conditional constant propagation), and another round of bounds check elimination. These passes are expensive, but they can often remove large amounts of code and make vectorization much more successful and effective. Several other simplification and optimization passes intersperse the more expensive ones to reduce the amount of work they have to do.
  5. Vectorization
    1. Automatic vectorization is an extremely powerful transformation for CPU-intensive code. Briefly, vectorization allows execution of a single instruction on multiple data (SIMD), e.g. performing 8 addition operations at the same time. However, proving code to be both capable of vectorization and profitable to vectorize is difficult, and this relies heavily on the prior optimization passes to massage the IR into a state where vectorization is worth it.
  6. Intrinsic Lowering
    1. Julia inserts a number of custom intrinsics, for reasons such as object allocation, garbage collection, and exception handling. These intrinsics were originally placed to make optimization opportunities more obvious, but they are now lowered into LLVM IR to enable the IR to be emitted as machine code.
  7. Cleanup
    1. These passes are last-chance optimizations, and perform small optimizations such as fused multiply-add propagation and division-remainder simplification. Additionally, targets that do not support half-precision floating point numbers will have their half-precision instructions lowered into single-precision instructions here, and passes are added to provide sanitizer support.

Target-Dependent Optimization and Code Generation

LLVM provides target-dependent optimization and machine code generation in the same pipeline, located in the TargetMachine for a given platform. These passes include instruction selection, instruction scheduling, register allocation, and machine code emission. The LLVM documentation provides a good overview of the process, and the LLVM source code is the best place to look for details on the pipeline and passes.

Linking

Currently, Julia is transitioning between two linkers: the older RuntimeDyld linker, and the newer JITLink linker. JITLink contains a number of features that RuntimeDyld does not have, such as concurrent and reentrant linking, but currently lacks good support for profiling integrations and does not yet support all of the platforms that RuntimeDyld supports. Over time, JITLink is expected to replace RuntimeDyld entirely. Further details on JITLink can be found in the LLVM documentation.

Execution

Once the code has been linked into the current process, it is available for execution. This fact is made known to the generating codeinst by updating the invoke, specsigflags, and specptr fields appropriately. Codeinsts support upgrading invoke, specsigflags, and specptr fields, so long as every combination of these fields that exists at any given point in time is valid to be called. This allows the JIT to update these fields without invalidating existing codeinsts, supporting a potential future concurrent JIT. Specifically, the following states may be valid:

  1. invoke is NULL, specsigflags is 0b00, specptr is NULL
    1. This is the initial state of a codeinst, and indicates that the codeinst has not yet been compiled.
  2. invoke is non-null, specsigflags is 0b00, specptr is NULL
    1. This indicates that the codeinst was not compiled with any specialization, and that the codeinst should be invoked directly. Note that in this instance, invoke does not read either the specsigflags or specptr fields, and therefore they may be modified without invalidating the invoke pointer.
  3. invoke is non-null, specsigflags is 0b10, specptr is non-null
    1. This indicates that the codeinst was compiled, but a specialized function signature was deemed unnecessary by codegen.
  4. invoke is non-null, specsigflags is 0b11, specptr is non-null
    1. This indicates that the codeinst was compiled, and a specialized function signature was deemed necessary by codegen. The specptr field contains a pointer to the specialized function signature. The invoke pointer is permitted to read both specsigflags and specptr fields.

In addition, there are a number of different transitional states that occur during the update process. To account for these potential situations, the following write and read patterns should be used when dealing with these codeinst fields.

  1. When writing invoke, specsigflags, and specptr:
    1. Perform an atomic compare-exchange operation of specptr assuming the old value was NULL. This compare-exchange operation should have at least acquire-release ordering, to provide ordering guarantees of the remaining memory operations in the write.
    2. If specptr was non-null, cease the write operation and wait for bit 0b10 of specsigflags to be written.
    3. Write the new low bit of specsigflags to its final value. This may be a relaxed write.
    4. Write the new invoke pointer to its final value. This must have at least a release memory ordering to synchronize with reads of invoke.
    5. Set the second bit of specsigflags to 1. This must be at least a release memory ordering to synchronize with reads of specsigflags. This step completes the write operation and announces to all other threads that all fields have been set.
  2. When reading all of invoke, specsigflags, and specptr:
    1. Read the invoke field with at least an acquire memory ordering. This load will be referred to as initial_invoke.
    2. If initial_invoke is NULL, the codeinst is not yet executable. invoke is NULL, specsigflags may be treated as 0b00, specptr may be treated as NULL.
    3. Read the specptr field with at least an acquire memory ordering.
    4. If specptr is NULL, then the initial_invoke pointer must not be relying on specptr to guarantee correct execution. Therefore, invoke is non-null, specsigflags may be treated as 0b00, specptr may be treated as NULL.
    5. If specptr is non-null, then initial_invoke might not be the final invoke field that uses specptr. This can occur if specptr has been written, but invoke has not yet been written. Therefore, spin on the second bit of specsigflags until it is set to 1 with at least acquire memory ordering.
    6. Re-read the invoke field with at least an acquire memory ordering. This load will be referred to as final_invoke.
    7. Read the specsigflags field with any memory ordering.
    8. invoke is final_invoke, specsigflags is the value read in step 7, specptr is the value read in step 3.
  3. When updating a specptr to a different but equivalent function pointer:
    1. Perform a release store of the new function pointer to specptr. Races here must be benign, as the old function pointer is required to still be valid, and any new ones are also required to be valid as well. Once a pointer has been written to specptr, it must always be callable whether or not it is later overwritten.

Although these write, read, and update steps are complicated, they ensure that the JIT can update codeinsts without invalidating existing codeinsts, and that the JIT can update codeinsts without invalidating existing invoke pointers. This allows the JIT to potentially reoptimize functions at higher optimization levels in the future, and also will allow the JIT to support concurrent compilation of functions in the future.

  • tdpThis is not a totally-target independent pipeline, as transformations such as vectorization rely upon target information such as vector register width and cost modeling. Additionally, codegen itself makes a few target-dependent assumptions, and the optimization pipeline will take advantage of that knowledge.
diff --git a/en/v1.12-dev/devdocs/llvm-passes/index.html b/en/v1.12-dev/devdocs/llvm-passes/index.html index b16c1fd99840..a389ad6d4e64 100644 --- a/en/v1.12-dev/devdocs/llvm-passes/index.html +++ b/en/v1.12-dev/devdocs/llvm-passes/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Custom LLVM Passes

Julia has a number of custom LLVM passes. Broadly, they can be classified into passes that are required to be run to maintain Julia semantics, and passes that take advantage of Julia semantics to optimize LLVM IR.

Semantic Passes

These passes are used to transform LLVM IR into code that is legal to be run on a CPU. Their main purpose is to enable simpler IR to be emitted by codegen, which then enables other LLVM passes to optimize common patterns.

CPUFeatures

  • Filename: llvm-cpufeatures.cpp
  • Class Name: CPUFeaturesPass
  • Opt Name: module(CPUFeatures)

This pass lowers the julia.cpu.have_fma.(f32|f64) intrinsic to either true or false, depending on the target architecture and target features present on the function. This intrinsic is often used to determine if using algorithms dependent on fast fused multiply-add operations is better than using standard algorithms not dependent on such instructions.

DemoteFloat16

  • Filename: llvm-demote-float16.cpp
  • ClassName: DemoteFloat16Pass
  • Opt Name function(DemoteFloat16)

This pass replaces float16 operations with float32 operations on architectures that do not natively support float16 operations. This is done by inserting fpext and fptrunc instructions around any float16 operation. On architectures that do support native float16 operations, this pass is a no-op.

LateGCLowering

  • Filename: llvm-late-gc-lowering.cpp
  • Class Name: LateLowerGCPass
  • Opt Name: function(LateLowerGCFrame)

This pass performs most of the GC rooting work required to track pointers between GC safepoints. It also lowers several intrinsics to their corresponding instruction translation, and is permitted to violate the non-integral invariants previously established (pointer_from_objref is lowered to a ptrtoint instruction here). This pass typically occupies the most time out of all the custom Julia passes, due to its dataflow algorithm to minimize the number of objects live at any safepoint.

FinalGCLowering

  • Filename: llvm-final-gc-lowering.cpp
  • Class Name: FinalLowerGCPass
  • Opt Name: module(FinalLowerGC)

This pass lowers a few last intrinsics to their final form targeting functions in the libjulia library. Separating this from LateGCLowering enables other backends (GPU compilation) to supply their own custom lowerings for these intrinsics, enabling the Julia pipeline to be used on those backends as well.

LowerHandlers

  • Filename: llvm-lower-handlers.cpp
  • Class Name: LowerExcHandlersPass
  • Opt Name: function(LowerExcHandlers)

This pass lowers exception handling intrinsics into calls to runtime functions that are actually called when handling exceptions.

RemoveNI

  • Filename: llvm-remove-ni.cpp
  • Class Name: RemoveNIPass
  • Opt Name: module(RemoveNI)

This pass removes the non-integral address spaces from the module's datalayout string. This enables the backend to lower Julia's custom address spaces directly to machine code, without a costly rewrite of every pointer operation to address space 0.

SIMDLoop

  • Filename: llvm-simdloop.cpp
  • Class Name: LowerSIMDLoopPass
  • Opt Name: loop(LowerSIMDLoop)

This pass acts as the main driver of the @simd annotation. Codegen inserts a !llvm.loopid marker at the back branch of a loop, which this pass uses to identify loops that were originally marked with @simd. Then, this pass looks for a chain of floating point operations that form a reduce and adds the contract and reassoc fast math flags to allow reassociation (and thus vectorization). This pass does not preserve either loop information nor inference correctness, so it may violate Julia semantics in surprising ways. If the loop was annotated with ivdep as well, then the pass marks the loop as having no loop-carried dependencies (the resulting behavior is undefined if the user annotation was incorrect or gets applied to the wrong loop).

LowerPTLS

  • Filename: llvm-ptls.cpp
  • Class Name: LowerPTLSPass
  • Opt Name: module(LowerPTLSPass)

This pass lowers thread-local Julia intrinsics to assembly instructions. Julia relies on thread-local storage for garbage collection and multithreading task scheduling. When compiling code for system images and package images, this pass replaces calls to intrinsics with loads from global variables that are initialized at load time.

If codegen produces a function with a swiftself argument and calling convention, this pass assumes the swiftself argument is the pgcstack and will replace the intrinsics with that argument. Doing so provides speedups on architectures that have slow thread local storage accesses.

RemoveAddrspaces

  • Filename: llvm-remove-addrspaces.cpp
  • Class Name: RemoveAddrspacesPass
  • Opt Name: module(RemoveAddrspaces)

This pass renames pointers in one address space to another address space. This is used to remove Julia-specific address spaces from LLVM IR.

RemoveJuliaAddrspaces

  • Filename: llvm-remove-addrspaces.cpp
  • Class Name: RemoveJuliaAddrspacesPass
  • Opt Name: module(RemoveJuliaAddrspaces)

This pass removes Julia-specific address spaces from LLVM IR. It is mostly used for displaying LLVM IR in a less cluttered format. Internally, it is implemented off the RemoveAddrspaces pass.

Multiversioning

  • Filename: llvm-multiversioning.cpp
  • Class Name: MultiVersioningPass
  • Opt Name: module(JuliaMultiVersioning)

This pass performs modifications to a module to create functions that are optimized for running on different architectures (see sysimg.md and pkgimg.md for more details). Implementation-wise, it clones functions and applies different target-specific attributes to them to allow the optimizer to use advanced features such as vectorization and instruction scheduling for that platform. It also creates some infrastructure to enable the Julia image loader to select the appropriate version of the function to call based on the architecture the loader is running on. The target-specific attributes are controlled by the julia.mv.specs module flag, which during compilation is derived from the JULIA_CPU_TARGET environment variable. The pass must also be enabled by providing a julia.mv.enable module flag with a value of 1.

Warning

Use of llvmcall with multiversioning is dangerous. llvmcall enables access to features not typically exposed by the Julia APIs, and are therefore usually not available on all architectures. If multiversioning is enabled and code generation is requested for a target architecture that does not support the feature required by an llvmcall expression, LLVM will probably error out, likely with an abort and the message LLVM ERROR: Do not know how to split the result of this operator!.

GCInvariantVerifier

  • Filename: llvm-gc-invariant-verifier.cpp
  • Class Name: GCInvariantVerifierPass
  • Opt Name: module(GCInvariantVerifier)

This pass is used to verify Julia's invariants about LLVM IR. This includes things such as the nonexistence of ptrtoint in Julia's non-integral address spaces [nislides] and the existence of only blessed addrspacecast instructions (Tracked -> Derived, 0 -> Tracked, etc). It performs no transformations on IR.

Optimization Passes

These passes are used to perform transformations on LLVM IR that LLVM will not perform itself, e.g. fast math flag propagation, escape analysis, and optimizations on Julia-specific internal functions. They use knowledge about Julia's semantics to perform these optimizations.

CombineMulAdd

  • Filename: llvm-muladd.cpp
  • Class Name: CombineMulAddPass
  • Opt Name: function(CombineMulAdd)

This pass serves to optimize the particular combination of a regular fmul with a fast fadd into a contract fmul with a fast fadd. This is later optimized by the backend to a fused multiply-add instruction, which can provide significantly faster operations at the cost of more unpredictable semantics.

Note

This optimization only occurs when the fmul has a single use, which is the fast fadd.

AllocOpt

  • Filename: llvm-alloc-opt.cpp
  • Class Name: AllocOptPass
  • Opt Name: function(AllocOpt)

Julia does not have the concept of a program stack as a place to allocate mutable objects. However, allocating objects on the stack reduces GC pressure and is critical for GPU compilation. Thus, AllocOpt performs heap to stack conversion of objects that it can prove do not escape the current function. It also performs a number of other optimizations on allocations, such as removing allocations that are never used, optimizing typeof calls to freshly allocated objects, and removing stores to allocations that are immediately overwritten. The escape analysis implementation is located in llvm-alloc-helpers.cpp. Currently, this pass does not use information from EscapeAnalysis.jl, though that may change in the future.

PropagateJuliaAddrspaces

  • Filename: llvm-propagate-addrspaces.cpp
  • Class Name: PropagateJuliaAddrspacesPass
  • Opt Name: function(PropagateJuliaAddrspaces)

This pass is used to propagate Julia-specific address spaces through operations on pointers. LLVM is not allowed to introduce or remove addrspacecast instructions by optimizations, so this pass acts to eliminate redundant addrspace casts by replacing operations with their equivalent in a Julia address space. For more information on Julia's address spaces, see (TODO link to llvm.md).

JuliaLICM

  • Filename: llvm-julia-licm.cpp
  • Class Name: JuliaLICMPass
  • Opt Name: loop(JuliaLICM)

This pass is used to hoist Julia-specific intrinsics out of loops. Specifically, it performs the following transformations:

  1. Hoist gc_preserve_begin and sink gc_preserve_end out of loops when the preserved objects are loop-invariant.
    1. Since objects preserved within a loop are likely preserved for the duration of the loop, this transformation can reduce the number of gc_preserve_begin/gc_preserve_end pairs in the IR. This makes it easier for the LateLowerGCPass to identify where particular objects are preserved.
  2. Hoist write barriers with invariant objects
    1. Here we assume that there are only two generations that an object can be a part of. Given that, a write barrier needs to only execute once for any pair of the same object. Thus, we can hoist write barriers out of loops when the object being written to is loop-invariant.
  3. Hoist allocations out of loops when they do not escape the loop
    1. We use a very conservative definition of escape here, the same as the one used in AllocOptPass. This transformation can reduce the number of allocations in the IR, even when an allocation escapes the function altogether.

!!!note

This pass is required to preserve LLVM's [MemorySSA](https://llvm.org/docs/MemorySSA.html) ([Short Video](https://www.youtube.com/watch?v=bdxWmryoHak), [Longer Video](https://www.youtube.com/watch?v=1e5y6WDbXCQ)) and [ScalarEvolution](https://baziotis.cs.illinois.edu/compilers/introduction-to-scalar-evolution.html) ([Newer Slides](https://llvm.org/devmtg/2018-04/slides/Absar-ScalarEvolution.pdf) [Older Slides](https://llvm.org/devmtg/2009-10/ScalarEvolutionAndLoopOptimization.pdf)) analyses.
  • nislideshttps://llvm.org/devmtg/2015-02/slides/chisnall-pointers-not-int.pdf
+

Custom LLVM Passes

Julia has a number of custom LLVM passes. Broadly, they can be classified into passes that are required to be run to maintain Julia semantics, and passes that take advantage of Julia semantics to optimize LLVM IR.

Semantic Passes

These passes are used to transform LLVM IR into code that is legal to be run on a CPU. Their main purpose is to enable simpler IR to be emitted by codegen, which then enables other LLVM passes to optimize common patterns.

CPUFeatures

  • Filename: llvm-cpufeatures.cpp
  • Class Name: CPUFeaturesPass
  • Opt Name: module(CPUFeatures)

This pass lowers the julia.cpu.have_fma.(f32|f64) intrinsic to either true or false, depending on the target architecture and target features present on the function. This intrinsic is often used to determine if using algorithms dependent on fast fused multiply-add operations is better than using standard algorithms not dependent on such instructions.

DemoteFloat16

  • Filename: llvm-demote-float16.cpp
  • ClassName: DemoteFloat16Pass
  • Opt Name function(DemoteFloat16)

This pass replaces float16 operations with float32 operations on architectures that do not natively support float16 operations. This is done by inserting fpext and fptrunc instructions around any float16 operation. On architectures that do support native float16 operations, this pass is a no-op.

LateGCLowering

  • Filename: llvm-late-gc-lowering.cpp
  • Class Name: LateLowerGCPass
  • Opt Name: function(LateLowerGCFrame)

This pass performs most of the GC rooting work required to track pointers between GC safepoints. It also lowers several intrinsics to their corresponding instruction translation, and is permitted to violate the non-integral invariants previously established (pointer_from_objref is lowered to a ptrtoint instruction here). This pass typically occupies the most time out of all the custom Julia passes, due to its dataflow algorithm to minimize the number of objects live at any safepoint.

FinalGCLowering

  • Filename: llvm-final-gc-lowering.cpp
  • Class Name: FinalLowerGCPass
  • Opt Name: module(FinalLowerGC)

This pass lowers a few last intrinsics to their final form targeting functions in the libjulia library. Separating this from LateGCLowering enables other backends (GPU compilation) to supply their own custom lowerings for these intrinsics, enabling the Julia pipeline to be used on those backends as well.

LowerHandlers

  • Filename: llvm-lower-handlers.cpp
  • Class Name: LowerExcHandlersPass
  • Opt Name: function(LowerExcHandlers)

This pass lowers exception handling intrinsics into calls to runtime functions that are actually called when handling exceptions.

RemoveNI

  • Filename: llvm-remove-ni.cpp
  • Class Name: RemoveNIPass
  • Opt Name: module(RemoveNI)

This pass removes the non-integral address spaces from the module's datalayout string. This enables the backend to lower Julia's custom address spaces directly to machine code, without a costly rewrite of every pointer operation to address space 0.

SIMDLoop

  • Filename: llvm-simdloop.cpp
  • Class Name: LowerSIMDLoopPass
  • Opt Name: loop(LowerSIMDLoop)

This pass acts as the main driver of the @simd annotation. Codegen inserts a !llvm.loopid marker at the back branch of a loop, which this pass uses to identify loops that were originally marked with @simd. Then, this pass looks for a chain of floating point operations that form a reduce and adds the contract and reassoc fast math flags to allow reassociation (and thus vectorization). This pass does not preserve either loop information nor inference correctness, so it may violate Julia semantics in surprising ways. If the loop was annotated with ivdep as well, then the pass marks the loop as having no loop-carried dependencies (the resulting behavior is undefined if the user annotation was incorrect or gets applied to the wrong loop).

LowerPTLS

  • Filename: llvm-ptls.cpp
  • Class Name: LowerPTLSPass
  • Opt Name: module(LowerPTLSPass)

This pass lowers thread-local Julia intrinsics to assembly instructions. Julia relies on thread-local storage for garbage collection and multithreading task scheduling. When compiling code for system images and package images, this pass replaces calls to intrinsics with loads from global variables that are initialized at load time.

If codegen produces a function with a swiftself argument and calling convention, this pass assumes the swiftself argument is the pgcstack and will replace the intrinsics with that argument. Doing so provides speedups on architectures that have slow thread local storage accesses.

RemoveAddrspaces

  • Filename: llvm-remove-addrspaces.cpp
  • Class Name: RemoveAddrspacesPass
  • Opt Name: module(RemoveAddrspaces)

This pass renames pointers in one address space to another address space. This is used to remove Julia-specific address spaces from LLVM IR.

RemoveJuliaAddrspaces

  • Filename: llvm-remove-addrspaces.cpp
  • Class Name: RemoveJuliaAddrspacesPass
  • Opt Name: module(RemoveJuliaAddrspaces)

This pass removes Julia-specific address spaces from LLVM IR. It is mostly used for displaying LLVM IR in a less cluttered format. Internally, it is implemented off the RemoveAddrspaces pass.

Multiversioning

  • Filename: llvm-multiversioning.cpp
  • Class Name: MultiVersioningPass
  • Opt Name: module(JuliaMultiVersioning)

This pass performs modifications to a module to create functions that are optimized for running on different architectures (see sysimg.md and pkgimg.md for more details). Implementation-wise, it clones functions and applies different target-specific attributes to them to allow the optimizer to use advanced features such as vectorization and instruction scheduling for that platform. It also creates some infrastructure to enable the Julia image loader to select the appropriate version of the function to call based on the architecture the loader is running on. The target-specific attributes are controlled by the julia.mv.specs module flag, which during compilation is derived from the JULIA_CPU_TARGET environment variable. The pass must also be enabled by providing a julia.mv.enable module flag with a value of 1.

Warning

Use of llvmcall with multiversioning is dangerous. llvmcall enables access to features not typically exposed by the Julia APIs, and are therefore usually not available on all architectures. If multiversioning is enabled and code generation is requested for a target architecture that does not support the feature required by an llvmcall expression, LLVM will probably error out, likely with an abort and the message LLVM ERROR: Do not know how to split the result of this operator!.

GCInvariantVerifier

  • Filename: llvm-gc-invariant-verifier.cpp
  • Class Name: GCInvariantVerifierPass
  • Opt Name: module(GCInvariantVerifier)

This pass is used to verify Julia's invariants about LLVM IR. This includes things such as the nonexistence of ptrtoint in Julia's non-integral address spaces [nislides] and the existence of only blessed addrspacecast instructions (Tracked -> Derived, 0 -> Tracked, etc). It performs no transformations on IR.

Optimization Passes

These passes are used to perform transformations on LLVM IR that LLVM will not perform itself, e.g. fast math flag propagation, escape analysis, and optimizations on Julia-specific internal functions. They use knowledge about Julia's semantics to perform these optimizations.

CombineMulAdd

  • Filename: llvm-muladd.cpp
  • Class Name: CombineMulAddPass
  • Opt Name: function(CombineMulAdd)

This pass serves to optimize the particular combination of a regular fmul with a fast fadd into a contract fmul with a fast fadd. This is later optimized by the backend to a fused multiply-add instruction, which can provide significantly faster operations at the cost of more unpredictable semantics.

Note

This optimization only occurs when the fmul has a single use, which is the fast fadd.

AllocOpt

  • Filename: llvm-alloc-opt.cpp
  • Class Name: AllocOptPass
  • Opt Name: function(AllocOpt)

Julia does not have the concept of a program stack as a place to allocate mutable objects. However, allocating objects on the stack reduces GC pressure and is critical for GPU compilation. Thus, AllocOpt performs heap to stack conversion of objects that it can prove do not escape the current function. It also performs a number of other optimizations on allocations, such as removing allocations that are never used, optimizing typeof calls to freshly allocated objects, and removing stores to allocations that are immediately overwritten. The escape analysis implementation is located in llvm-alloc-helpers.cpp. Currently, this pass does not use information from EscapeAnalysis.jl, though that may change in the future.

PropagateJuliaAddrspaces

  • Filename: llvm-propagate-addrspaces.cpp
  • Class Name: PropagateJuliaAddrspacesPass
  • Opt Name: function(PropagateJuliaAddrspaces)

This pass is used to propagate Julia-specific address spaces through operations on pointers. LLVM is not allowed to introduce or remove addrspacecast instructions by optimizations, so this pass acts to eliminate redundant addrspace casts by replacing operations with their equivalent in a Julia address space. For more information on Julia's address spaces, see (TODO link to llvm.md).

JuliaLICM

  • Filename: llvm-julia-licm.cpp
  • Class Name: JuliaLICMPass
  • Opt Name: loop(JuliaLICM)

This pass is used to hoist Julia-specific intrinsics out of loops. Specifically, it performs the following transformations:

  1. Hoist gc_preserve_begin and sink gc_preserve_end out of loops when the preserved objects are loop-invariant.
    1. Since objects preserved within a loop are likely preserved for the duration of the loop, this transformation can reduce the number of gc_preserve_begin/gc_preserve_end pairs in the IR. This makes it easier for the LateLowerGCPass to identify where particular objects are preserved.
  2. Hoist write barriers with invariant objects
    1. Here we assume that there are only two generations that an object can be a part of. Given that, a write barrier needs to only execute once for any pair of the same object. Thus, we can hoist write barriers out of loops when the object being written to is loop-invariant.
  3. Hoist allocations out of loops when they do not escape the loop
    1. We use a very conservative definition of escape here, the same as the one used in AllocOptPass. This transformation can reduce the number of allocations in the IR, even when an allocation escapes the function altogether.

!!!note

This pass is required to preserve LLVM's [MemorySSA](https://llvm.org/docs/MemorySSA.html) ([Short Video](https://www.youtube.com/watch?v=bdxWmryoHak), [Longer Video](https://www.youtube.com/watch?v=1e5y6WDbXCQ)) and [ScalarEvolution](https://baziotis.cs.illinois.edu/compilers/introduction-to-scalar-evolution.html) ([Newer Slides](https://llvm.org/devmtg/2018-04/slides/Absar-ScalarEvolution.pdf) [Older Slides](https://llvm.org/devmtg/2009-10/ScalarEvolutionAndLoopOptimization.pdf)) analyses.
  • nislideshttps://llvm.org/devmtg/2015-02/slides/chisnall-pointers-not-int.pdf
diff --git a/en/v1.12-dev/devdocs/llvm/index.html b/en/v1.12-dev/devdocs/llvm/index.html index c6e1408e286b..0b249fc30c6e 100644 --- a/en/v1.12-dev/devdocs/llvm/index.html +++ b/en/v1.12-dev/devdocs/llvm/index.html @@ -18,4 +18,4 @@ error("An error occurred") end

During constant folding, LLVM may discover that the condition is always false, and can remove the basic block. However, if GC root lowering is done early, the GC root slots used in the deleted block, as well as any values kept alive in those slots only because they were used in the error path, would be kept alive by LLVM. By doing GC root lowering late, we give LLVM the license to do any of its usual optimizations (constant folding, dead code elimination, etc.), without having to worry (too much) about which values may or may not be GC tracked.

However, in order to be able to do late GC root placement, we need to be able to identify a) which pointers are GC tracked and b) all uses of such pointers. The goal of the GC placement pass is thus simple:

Minimize the number of needed GC roots/stores to them subject to the constraint that at every safepoint, any live GC-tracked pointer (i.e. for which there is a path after this point that contains a use of this pointer) is in some GC slot.

Representation

The primary difficulty is thus choosing an IR representation that allows us to identify GC-tracked pointers and their uses, even after the program has been run through the optimizer. Our design makes use of three LLVM features to achieve this:

Custom address spaces allow us to tag every point with an integer that needs to be preserved through optimizations. The compiler may not insert casts between address spaces that did not exist in the original program and it must never change the address space of a pointer on a load/store/etc operation. This allows us to annotate which pointers are GC-tracked in an optimizer-resistant way. Note that metadata would not be able to achieve the same purpose. Metadata is supposed to always be discardable without altering the semantics of the program. However, failing to identify a GC-tracked pointer alters the resulting program behavior dramatically - it'll probably crash or return wrong results. We currently use three different address spaces (their numbers are defined in src/codegen_shared.cpp):

Invariants

The GC root placement pass makes use of several invariants, which need to be observed by the frontend and are preserved by the optimizer.

First, only the following address space casts are allowed:

Now let us consider what constitutes a use:

We explicitly allow load/stores and simple calls in address spaces Tracked/Derived. Elements of jlcall argument arrays must always be in address space Tracked (it is required by the ABI that they are valid jl_value_t* pointers). The same is true for return instructions (though note that struct return arguments are allowed to have any of the address spaces). The only allowable use of an address space CalleeRooted pointer is to pass it to a call (which must have an appropriately typed operand).

Further, we disallow getelementptr in addrspace Tracked. This is because unless the operation is a noop, the resulting pointer will not be validly storable to a GC slot and may thus not be in this address space. If such a pointer is required, it should be decayed to addrspace Derived first.

Lastly, we disallow inttoptr/ptrtoint instructions in these address spaces. Having these instructions would mean that some i64 values are really GC tracked. This is problematic, because it breaks that stated requirement that we're able to identify GC-relevant pointers. This invariant is accomplished using the LLVM "non-integral pointers" feature, which is new in LLVM 5.0. It prohibits the optimizer from making optimizations that would introduce these operations. Note we can still insert static constants at JIT time by using inttoptr in address space 0 and then decaying to the appropriate address space afterwards.

Supporting ccall

One important aspect missing from the discussion so far is the handling of ccall. ccall has the peculiar feature that the location and scope of a use do not coincide. As an example consider:

A = randn(1024)
 ccall(:foo, Cvoid, (Ptr{Float64},), A)

In lowering, the compiler will insert a conversion from the array to the pointer which drops the reference to the array value. However, we of course need to make sure that the array does stay alive while we're doing the ccall. To understand how this is done, lets look at a hypothetical approximate possible lowering of the above code:

return $(Expr(:foreigncall, :(:foo), Cvoid, svec(Ptr{Float64}), 0, :(:ccall), Expr(:foreigncall, :(:jl_array_ptr), Ptr{Float64}, svec(Any), 0, :(:ccall), :(A)), :(A)))

The last :(A), is an extra argument list inserted during lowering that informs the code generator which Julia level values need to be kept alive for the duration of this ccall. We then take this information and represent it in an "operand bundle" at the IR level. An operand bundle is essentially a fake use that is attached to the call site. At the IR level, this looks like so:

call void inttoptr (i64 ... to void (double*)*)(double* %5) [ "jl_roots"(%jl_value_t addrspace(10)* %A) ]

The GC root placement pass will treat the jl_roots operand bundle as if it were a regular operand. However, as a final step, after the GC roots are inserted, it will drop the operand bundle to avoid confusing instruction selection.

Supporting pointer_from_objref

pointer_from_objref is special because it requires the user to take explicit control of GC rooting. By our above invariants, this function is illegal, because it performs an address space cast from 10 to 0. However, it can be useful, in certain situations, so we provide a special intrinsic:

declared %jl_value_t *julia.pointer_from_objref(%jl_value_t addrspace(10)*)

which is lowered to the corresponding address space cast after GC root lowering. Do note however that by using this intrinsic, the caller assumes all responsibility for making sure that the value in question is rooted. Further this intrinsic is not considered a use, so the GC root placement pass will not provide a GC root for the function. As a result, the external rooting must be arranged while the value is still tracked by the system. I.e. it is not valid to attempt to use the result of this operation to establish a global root - the optimizer may have already dropped the value.

Keeping values alive in the absence of uses

In certain cases it is necessary to keep an object alive, even though there is no compiler-visible use of said object. This may be case for low level code that operates on the memory-representation of an object directly or code that needs to interface with C code. In order to allow this, we provide the following intrinsics at the LLVM level:

token @llvm.julia.gc_preserve_begin(...)
-void @llvm.julia.gc_preserve_end(token)

(The llvm. in the name is required in order to be able to use the token type). The semantics of these intrinsics are as follows: At any safepoint that is dominated by a gc_preserve_begin call, but that is not not dominated by a corresponding gc_preserve_end call (i.e. a call whose argument is the token returned by a gc_preserve_begin call), the values passed as arguments to that gc_preserve_begin will be kept live. Note that the gc_preserve_begin still counts as a regular use of those values, so the standard lifetime semantics will ensure that the values will be kept alive before entering the preserve region.

+void @llvm.julia.gc_preserve_end(token)

(The llvm. in the name is required in order to be able to use the token type). The semantics of these intrinsics are as follows: At any safepoint that is dominated by a gc_preserve_begin call, but that is not not dominated by a corresponding gc_preserve_end call (i.e. a call whose argument is the token returned by a gc_preserve_begin call), the values passed as arguments to that gc_preserve_begin will be kept live. Note that the gc_preserve_begin still counts as a regular use of those values, so the standard lifetime semantics will ensure that the values will be kept alive before entering the preserve region.

diff --git a/en/v1.12-dev/devdocs/locks/index.html b/en/v1.12-dev/devdocs/locks/index.html index 9a2eb98981cf..4366f2ff0ccb 100644 --- a/en/v1.12-dev/devdocs/locks/index.html +++ b/en/v1.12-dev/devdocs/locks/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Proper maintenance and care of multi-threading locks

The following strategies are used to ensure that the code is dead-lock free (generally by addressing the 4th Coffman condition: circular wait).

  1. structure code such that only one lock will need to be acquired at a time
  2. always acquire shared locks in the same order, as given by the table below
  3. avoid constructs that expect to need unrestricted recursion

Locks

Below are all of the locks that exist in the system and the mechanisms for using them that avoid the potential for deadlocks (no Ostrich algorithm allowed here):

The following are definitely leaf locks (level 1), and must not try to acquire any other lock:

  • safepoint

    Note that this lock is acquired implicitly by JL_LOCK and JL_UNLOCK. use the _NOGC variants to avoid that for level 1 locks.

    While holding this lock, the code must not do any allocation or hit any safepoints. Note that there are safepoints when doing allocation, enabling / disabling GC, entering / restoring exception frames, and taking / releasing locks.

  • shared_map

  • finalizers

  • pagealloc

  • gcpermlock

  • flisp

  • jlinstackwalk (Win32)

  • ResourcePool<?>::mutex

  • RLST_mutex

  • llvmprintingmutex

  • jllockedstream::mutex

  • debuginfo_asyncsafe

  • inferencetimingmutex

  • ExecutionEngine::SessionLock

    flisp itself is already threadsafe, this lock only protects the jl_ast_context_list_t pool likewise, the ResourcePool<?>::mutexes just protect the associated resource pool

The following is a leaf lock (level 2), and only acquires level 1 locks (safepoint) internally:

  • globalrootslock
  • Module->lock
  • JLDebuginfoPlugin::PluginMutex
  • newlyinferredmutex

The following is a level 3 lock, which can only acquire level 1 or level 2 locks internally:

  • Method->writelock
  • typecache

The following is a level 4 lock, which can only recurse to acquire level 1, 2, or 3 locks:

  • MethodTable->writelock

No Julia code may be called while holding a lock above this point.

orc::ThreadSafeContext (TSCtx) locks occupy a special spot in the locking hierarchy. They are used to protect LLVM's global non-threadsafe state, but there may be an arbitrary number of them. By default, all of these locks may be treated as level 5 locks for the purposes of comparing with the rest of the hierarchy. Acquiring a TSCtx should only be done from the JIT's pool of TSCtx's, and all locks on that TSCtx should be released prior to returning it to the pool. If multiple TSCtx locks must be acquired at the same time (due to recursive compilation), then locks should be acquired in the order that the TSCtxs were borrowed from the pool.

The following is a level 5 lock

  • JuliaOJIT::EmissionMutex

The following are a level 6 lock, which can only recurse to acquire locks at lower levels:

  • codegen
  • jlmodulesmutex

The following is an almost root lock (level end-1), meaning only the root look may be held when trying to acquire it:

  • typeinf

    this one is perhaps one of the most tricky ones, since type-inference can be invoked from many points

    currently the lock is merged with the codegen lock, since they call each other recursively

The following lock synchronizes IO operation. Be aware that doing any I/O (for example, printing warning messages or debug information) while holding any other lock listed above may result in pernicious and hard-to-find deadlocks. BE VERY CAREFUL!

  • iolock

  • Individual ThreadSynchronizers locks

    this may continue to be held after releasing the iolock, or acquired without it, but be very careful to never attempt to acquire the iolock while holding it

  • Libdl.LazyLibrary lock

The following is the root lock, meaning no other lock shall be held when trying to acquire it:

  • toplevel

    this should be held while attempting a top-level action (such as making a new type or defining a new method): trying to obtain this lock inside a staged function will cause a deadlock condition!

    additionally, it's unclear if any code can safely run in parallel with an arbitrary toplevel expression, so it may require all threads to get to a safepoint first

Broken Locks

The following locks are broken:

  • toplevel

    doesn't exist right now

    fix: create it

  • Module->lock

    This is vulnerable to deadlocks since it can't be certain it is acquired in sequence. Some operations (such as import_module) are missing a lock.

    fix: replace with jl_modules_mutex?

  • loading.jl: require and register_root_module

    This file potentially has numerous problems.

    fix: needs locks

Shared Global Data Structures

These data structures each need locks due to being shared mutable global state. It is the inverse list for the above lock priority list. This list does not include level 1 leaf resources due to their simplicity.

MethodTable modifications (def, cache) : MethodTable->writelock

Type declarations : toplevel lock

Type application : typecache lock

Global variable tables : Module->lock

Module serializer : toplevel lock

JIT & type-inference : codegen lock

MethodInstance/CodeInstance updates : Method->writelock, codegen lock

  • These are set at construction and immutable:
    • specTypes
    • sparam_vals
    • def
    • owner
  • These are set by jl_type_infer (while holding codegen lock):
    • cache
    • rettype
    • inferred
    * valid ages
  • inInference flag:
    • optimization to quickly avoid recurring into jl_type_infer while it is already running
    • actual state (of setting inferred, then fptr) is protected by codegen lock
  • Function pointers:

    • these transition once, from NULL to a value, while the codegen lock is held
  • Code-generator cache (the contents of functionObjectsDecls):

    • these can transition multiple times, but only while the codegen lock is held
    • it is valid to use old version of this, or block for new versions of this, so races are benign, as long as the code is careful not to reference other data in the method instance (such as rettype) and assume it is coordinated, unless also holding the codegen lock

LLVMContext : codegen lock

Method : Method->writelock

  • roots array (serializer and codegen)
  • invoke / specializations / tfunc modifications
+

Proper maintenance and care of multi-threading locks

The following strategies are used to ensure that the code is dead-lock free (generally by addressing the 4th Coffman condition: circular wait).

  1. structure code such that only one lock will need to be acquired at a time
  2. always acquire shared locks in the same order, as given by the table below
  3. avoid constructs that expect to need unrestricted recursion

Locks

Below are all of the locks that exist in the system and the mechanisms for using them that avoid the potential for deadlocks (no Ostrich algorithm allowed here):

The following are definitely leaf locks (level 1), and must not try to acquire any other lock:

  • safepoint

    Note that this lock is acquired implicitly by JL_LOCK and JL_UNLOCK. use the _NOGC variants to avoid that for level 1 locks.

    While holding this lock, the code must not do any allocation or hit any safepoints. Note that there are safepoints when doing allocation, enabling / disabling GC, entering / restoring exception frames, and taking / releasing locks.

  • shared_map

  • finalizers

  • pagealloc

  • gcpermlock

  • flisp

  • jlinstackwalk (Win32)

  • ResourcePool<?>::mutex

  • RLST_mutex

  • llvmprintingmutex

  • jllockedstream::mutex

  • debuginfo_asyncsafe

  • inferencetimingmutex

  • ExecutionEngine::SessionLock

    flisp itself is already threadsafe, this lock only protects the jl_ast_context_list_t pool likewise, the ResourcePool<?>::mutexes just protect the associated resource pool

The following is a leaf lock (level 2), and only acquires level 1 locks (safepoint) internally:

  • globalrootslock
  • Module->lock
  • JLDebuginfoPlugin::PluginMutex
  • newlyinferredmutex

The following is a level 3 lock, which can only acquire level 1 or level 2 locks internally:

  • Method->writelock
  • typecache

The following is a level 4 lock, which can only recurse to acquire level 1, 2, or 3 locks:

  • MethodTable->writelock

No Julia code may be called while holding a lock above this point.

orc::ThreadSafeContext (TSCtx) locks occupy a special spot in the locking hierarchy. They are used to protect LLVM's global non-threadsafe state, but there may be an arbitrary number of them. By default, all of these locks may be treated as level 5 locks for the purposes of comparing with the rest of the hierarchy. Acquiring a TSCtx should only be done from the JIT's pool of TSCtx's, and all locks on that TSCtx should be released prior to returning it to the pool. If multiple TSCtx locks must be acquired at the same time (due to recursive compilation), then locks should be acquired in the order that the TSCtxs were borrowed from the pool.

The following is a level 5 lock

  • JuliaOJIT::EmissionMutex

The following are a level 6 lock, which can only recurse to acquire locks at lower levels:

  • codegen
  • jlmodulesmutex

The following is an almost root lock (level end-1), meaning only the root look may be held when trying to acquire it:

  • typeinf

    this one is perhaps one of the most tricky ones, since type-inference can be invoked from many points

    currently the lock is merged with the codegen lock, since they call each other recursively

The following lock synchronizes IO operation. Be aware that doing any I/O (for example, printing warning messages or debug information) while holding any other lock listed above may result in pernicious and hard-to-find deadlocks. BE VERY CAREFUL!

  • iolock

  • Individual ThreadSynchronizers locks

    this may continue to be held after releasing the iolock, or acquired without it, but be very careful to never attempt to acquire the iolock while holding it

  • Libdl.LazyLibrary lock

The following is the root lock, meaning no other lock shall be held when trying to acquire it:

  • toplevel

    this should be held while attempting a top-level action (such as making a new type or defining a new method): trying to obtain this lock inside a staged function will cause a deadlock condition!

    additionally, it's unclear if any code can safely run in parallel with an arbitrary toplevel expression, so it may require all threads to get to a safepoint first

Broken Locks

The following locks are broken:

  • toplevel

    doesn't exist right now

    fix: create it

  • Module->lock

    This is vulnerable to deadlocks since it can't be certain it is acquired in sequence. Some operations (such as import_module) are missing a lock.

    fix: replace with jl_modules_mutex?

  • loading.jl: require and register_root_module

    This file potentially has numerous problems.

    fix: needs locks

Shared Global Data Structures

These data structures each need locks due to being shared mutable global state. It is the inverse list for the above lock priority list. This list does not include level 1 leaf resources due to their simplicity.

MethodTable modifications (def, cache) : MethodTable->writelock

Type declarations : toplevel lock

Type application : typecache lock

Global variable tables : Module->lock

Module serializer : toplevel lock

JIT & type-inference : codegen lock

MethodInstance/CodeInstance updates : Method->writelock, codegen lock

  • These are set at construction and immutable:
    • specTypes
    • sparam_vals
    • def
    • owner
  • These are set by jl_type_infer (while holding codegen lock):
    • cache
    • rettype
    • inferred
    * valid ages
  • inInference flag:
    • optimization to quickly avoid recurring into jl_type_infer while it is already running
    • actual state (of setting inferred, then fptr) is protected by codegen lock
  • Function pointers:

    • these transition once, from NULL to a value, while the codegen lock is held
  • Code-generator cache (the contents of functionObjectsDecls):

    • these can transition multiple times, but only while the codegen lock is held
    • it is valid to use old version of this, or block for new versions of this, so races are benign, as long as the code is careful not to reference other data in the method instance (such as rettype) and assume it is coordinated, unless also holding the codegen lock

LLVMContext : codegen lock

Method : Method->writelock

  • roots array (serializer and codegen)
  • invoke / specializations / tfunc modifications
diff --git a/en/v1.12-dev/devdocs/meta/index.html b/en/v1.12-dev/devdocs/meta/index.html index a1185aff899f..b5751b715069 100644 --- a/en/v1.12-dev/devdocs/meta/index.html +++ b/en/v1.12-dev/devdocs/meta/index.html @@ -12,4 +12,4 @@ Expr(:meta, :inline) x*(x+3) end -end

Base.pushmeta!(ex, tag::Union{Symbol,Expr}) appends :tag to the end of the :meta expression, creating a new :meta expression if necessary.

To use the metadata, you have to parse these :meta expressions. If your implementation can be performed within Julia, Base.popmeta! is very handy: Base.popmeta!(body, :symbol) will scan a function body expression (one without the function signature) for the first :meta expression containing :symbol, extract any arguments, and return a tuple (found::Bool, args::Array{Any}). If the metadata did not have any arguments, or :symbol was not found, the args array will be empty.

Not yet provided is a convenient infrastructure for parsing :meta expressions from C++.

+end

Base.pushmeta!(ex, tag::Union{Symbol,Expr}) appends :tag to the end of the :meta expression, creating a new :meta expression if necessary.

To use the metadata, you have to parse these :meta expressions. If your implementation can be performed within Julia, Base.popmeta! is very handy: Base.popmeta!(body, :symbol) will scan a function body expression (one without the function signature) for the first :meta expression containing :symbol, extract any arguments, and return a tuple (found::Bool, args::Array{Any}). If the metadata did not have any arguments, or :symbol was not found, the args array will be empty.

Not yet provided is a convenient infrastructure for parsing :meta expressions from C++.

diff --git a/en/v1.12-dev/devdocs/object/index.html b/en/v1.12-dev/devdocs/object/index.html index 072407e8fa31..5850040441d3 100644 --- a/en/v1.12-dev/devdocs/object/index.html +++ b/en/v1.12-dev/devdocs/object/index.html @@ -24,4 +24,4 @@ jl_array_t *jl_alloc_array_1d(jl_value_t *atype, size_t nr); jl_array_t *jl_alloc_array_nd(jl_value_t *atype, size_t *dims, size_t ndims);

Note that many of these have alternative allocation functions for various special-purposes. The list here reflects the more common usages, but a more complete list can be found by reading the julia.h header file.

Internal to Julia, storage is typically allocated by newstruct() (or newobj() for the special types):

jl_value_t *newstruct(jl_value_t *type);
 jl_value_t *newobj(jl_value_t *type, size_t nfields);

And at the lowest level, memory is getting allocated by a call to the garbage collector (in gc.c), then tagged with its type:

jl_value_t *jl_gc_allocobj(size_t nbytes);
-void jl_set_typeof(jl_value_t *v, jl_datatype_t *type);
Out of date Warning

The documentation and usage for the function jl_gc_allocobj may be out of date

Note that all objects are allocated in multiples of 4 bytes and aligned to the platform pointer size. Memory is allocated from a pool for smaller objects, or directly with malloc() for large objects.

Singleton Types

Singleton types have only one instance and no data fields. Singleton instances have a size of 0 bytes, and consist only of their metadata. e.g. nothing::Nothing.

See Singleton Types and Nothingness and missing values

+void jl_set_typeof(jl_value_t *v, jl_datatype_t *type);
Out of date Warning

The documentation and usage for the function jl_gc_allocobj may be out of date

Note that all objects are allocated in multiples of 4 bytes and aligned to the platform pointer size. Memory is allocated from a pool for smaller objects, or directly with malloc() for large objects.

Singleton Types

Singleton types have only one instance and no data fields. Singleton instances have a size of 0 bytes, and consist only of their metadata. e.g. nothing::Nothing.

See Singleton Types and Nothingness and missing values

diff --git a/en/v1.12-dev/devdocs/offset-arrays/index.html b/en/v1.12-dev/devdocs/offset-arrays/index.html index 5d1562864b93..83adec04d67d 100644 --- a/en/v1.12-dev/devdocs/offset-arrays/index.html +++ b/en/v1.12-dev/devdocs/offset-arrays/index.html @@ -23,4 +23,4 @@ function Base.similar(f::Union{Function,DataType}, shape::Tuple{ZeroRange,Vararg{ZeroRange}}) # body -end

Both of these should allocate your custom array type.

Specializing reshape

Optionally, define a method

Base.reshape(A::AbstractArray, shape::Tuple{ZeroRange,Vararg{ZeroRange}}) = ...

and you can reshape an array so that the result has custom indices.

For objects that mimic AbstractArray but are not subtypes

has_offset_axes depends on having axes defined for the objects you call it on. If there is some reason you don't have an axes method defined for your object, consider defining a method

Base.has_offset_axes(obj::MyNon1IndexedArraylikeObject) = true

This will allow code that assumes 1-based indexing to detect a problem and throw a helpful error, rather than returning incorrect results or segfaulting julia.

Catching errors

If your new array type triggers errors in other code, one helpful debugging step can be to comment out @boundscheck in your getindex and setindex! implementation. This will ensure that every element access checks bounds. Or, restart julia with --check-bounds=yes.

In some cases it may also be helpful to temporarily disable size and length for your new array type, since code that makes incorrect assumptions frequently uses these functions.

+end

Both of these should allocate your custom array type.

Specializing reshape

Optionally, define a method

Base.reshape(A::AbstractArray, shape::Tuple{ZeroRange,Vararg{ZeroRange}}) = ...

and you can reshape an array so that the result has custom indices.

For objects that mimic AbstractArray but are not subtypes

has_offset_axes depends on having axes defined for the objects you call it on. If there is some reason you don't have an axes method defined for your object, consider defining a method

Base.has_offset_axes(obj::MyNon1IndexedArraylikeObject) = true

This will allow code that assumes 1-based indexing to detect a problem and throw a helpful error, rather than returning incorrect results or segfaulting julia.

Catching errors

If your new array type triggers errors in other code, one helpful debugging step can be to comment out @boundscheck in your getindex and setindex! implementation. This will ensure that every element access checks bounds. Or, restart julia with --check-bounds=yes.

In some cases it may also be helpful to temporarily disable size and length for your new array type, since code that makes incorrect assumptions frequently uses these functions.

diff --git a/en/v1.12-dev/devdocs/pkgimg/index.html b/en/v1.12-dev/devdocs/pkgimg/index.html index fc37ab57b0fb..e33fe586e19b 100644 --- a/en/v1.12-dev/devdocs/pkgimg/index.html +++ b/en/v1.12-dev/devdocs/pkgimg/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

Package Images

Julia package images provide object (native code) caches for Julia packages. They are similar to Julia's system image and support many of the same features. In fact the underlying serialization format is the same, and the system image is the base image that the package images are build against.

High-level overview

Package images are shared libraries that contain both code and data. Like .ji cache files, they are generated per package. The data section contains both global data (global variables in the package) as well as the necessary metadata about what methods and types are defined by the package. The code section contains native objects that cache the final output of Julia's LLVM-based compiler.

The command line option --pkgimages=no can be used to turn off object caching for this session. Note that this means that cache files have to likely be regenerated. See JULIA_MAX_NUM_PRECOMPILE_FILES for the upper limit of variants Julia caches per default.

Note

While the package images present themselves as native shared libraries, they are only an approximation thereof. You will not be able to link against them from a native program and they must be loaded from Julia.

Linking

Since the package images contain native code, we must run a linker over them before we can use them. You can set the environment variable JULIA_VERBOSE_LINKING to true to make the package image linking process verbose.

Furthermore, we cannot assume that the user has a working system linker installed. Therefore, Julia ships with LLD, the LLVM linker, to provide a working out of the box experience. In base/linking.jl, we implement a limited interface to be able to link package images on all supported platforms.

Quirks

Despite LLD being a multi-platform linker, it does not provide a consistent interface across platforms. Furthermore, it is meant to be used from clang or another compiler driver, we therefore reimplement some of the logic from llvm-project/clang/lib/Driver/ToolChains. Thankfully one can use lld -flavor to set lld to the right platform

Windows

To avoid having to deal with link.exe we use -flavor gnu, effectively turning lld into a cross-linker from a mingw32 environment. Windows DLLs are required to contain a _DllMainCRTStartup function and to minimize our dependence on mingw32 libraries, we inject a stub definition ourselves.

MacOS

Dynamic libraries on macOS need to link against -lSystem. On recent macOS versions, -lSystem is only available for linking when Xcode is available. To that effect we link with -undefined dynamic_lookup.

Package images optimized for multiple microarchitectures

Similar to multi-versioning for system images, package images support multi-versioning. If you are in a heterogeneous environment, with a unified cache, you can set the environment variable JULIA_CPU_TARGET=generic to multi-version the object caches.

Flags that impact package image creation and selection

These are the Julia command line flags that impact cache selection. Package images that were created with different flags will be rejected.

  • -g, --debug-info: Exact match required since it changes code generation.
  • --check-bounds: Exact match required since it changes code generation.
  • --inline: Exact match required since it changes code generation.
  • --pkgimages: To allow running without object caching enabled.
  • -O, --optimize: Reject package images generated for a lower optimization level, but allow for higher optimization levels to be loaded.
+

Package Images

Julia package images provide object (native code) caches for Julia packages. They are similar to Julia's system image and support many of the same features. In fact the underlying serialization format is the same, and the system image is the base image that the package images are build against.

High-level overview

Package images are shared libraries that contain both code and data. Like .ji cache files, they are generated per package. The data section contains both global data (global variables in the package) as well as the necessary metadata about what methods and types are defined by the package. The code section contains native objects that cache the final output of Julia's LLVM-based compiler.

The command line option --pkgimages=no can be used to turn off object caching for this session. Note that this means that cache files have to likely be regenerated. See JULIA_MAX_NUM_PRECOMPILE_FILES for the upper limit of variants Julia caches per default.

Note

While the package images present themselves as native shared libraries, they are only an approximation thereof. You will not be able to link against them from a native program and they must be loaded from Julia.

Linking

Since the package images contain native code, we must run a linker over them before we can use them. You can set the environment variable JULIA_VERBOSE_LINKING to true to make the package image linking process verbose.

Furthermore, we cannot assume that the user has a working system linker installed. Therefore, Julia ships with LLD, the LLVM linker, to provide a working out of the box experience. In base/linking.jl, we implement a limited interface to be able to link package images on all supported platforms.

Quirks

Despite LLD being a multi-platform linker, it does not provide a consistent interface across platforms. Furthermore, it is meant to be used from clang or another compiler driver, we therefore reimplement some of the logic from llvm-project/clang/lib/Driver/ToolChains. Thankfully one can use lld -flavor to set lld to the right platform

Windows

To avoid having to deal with link.exe we use -flavor gnu, effectively turning lld into a cross-linker from a mingw32 environment. Windows DLLs are required to contain a _DllMainCRTStartup function and to minimize our dependence on mingw32 libraries, we inject a stub definition ourselves.

MacOS

Dynamic libraries on macOS need to link against -lSystem. On recent macOS versions, -lSystem is only available for linking when Xcode is available. To that effect we link with -undefined dynamic_lookup.

Package images optimized for multiple microarchitectures

Similar to multi-versioning for system images, package images support multi-versioning. If you are in a heterogeneous environment, with a unified cache, you can set the environment variable JULIA_CPU_TARGET=generic to multi-version the object caches.

Flags that impact package image creation and selection

These are the Julia command line flags that impact cache selection. Package images that were created with different flags will be rejected.

  • -g, --debug-info: Exact match required since it changes code generation.
  • --check-bounds: Exact match required since it changes code generation.
  • --inline: Exact match required since it changes code generation.
  • --pkgimages: To allow running without object caching enabled.
  • -O, --optimize: Reject package images generated for a lower optimization level, but allow for higher optimization levels to be loaded.
diff --git a/en/v1.12-dev/devdocs/precompile_hang/index.html b/en/v1.12-dev/devdocs/precompile_hang/index.html index 0980477ea257..b54da58555c7 100644 --- a/en/v1.12-dev/devdocs/precompile_hang/index.html +++ b/en/v1.12-dev/devdocs/precompile_hang/index.html @@ -14,4 +14,4 @@ MWE\Project.toml MWE\src\MWE.jl

where the source code of MWE.jl is

module MWE
 using ThePackageYouThinkIsCausingTheProblem
-end

and you've added ThePackageYouThinkIsCausingTheProblem to MWE's dependencies.

If that MWE reproduces the hang, you've found your culprit: ThePackageYouThinkIsCausingTheProblem.__init__ must be creating the Timer object. If the timer object can be safely closed, that's a good option. Otherwise, the most common solution is to avoid creating the timer while any package is being precompiled: add

ccall(:jl_generating_output, Cint, ()) == 1 && return nothing

as the first line of ThePackageYouThinkIsCausingTheProblem.__init__, and it will avoid doing any initialization in any Julia process whose purpose is to precompile packages.

Fixing package code to avoid hangs

Search your package for suggestive words (here like "Timer") and see if you can identify where the problem is being created. Note that a method definition like

maketimer() = Timer(timer -> println("hi"), 0; interval=1)

is not problematic in and of itself: it can cause this problem only if maketimer gets called while the module is being defined. This might be happening from a top-level statement such as

const GLOBAL_TIMER = maketimer()

or it might conceivably occur in a precompile workload.

If you struggle to identify the causative lines, then consider doing a binary search: comment out sections of your package (or include lines to omit entire files) until you've reduced the problem in scope.

+end

and you've added ThePackageYouThinkIsCausingTheProblem to MWE's dependencies.

If that MWE reproduces the hang, you've found your culprit: ThePackageYouThinkIsCausingTheProblem.__init__ must be creating the Timer object. If the timer object can be safely closed, that's a good option. Otherwise, the most common solution is to avoid creating the timer while any package is being precompiled: add

ccall(:jl_generating_output, Cint, ()) == 1 && return nothing

as the first line of ThePackageYouThinkIsCausingTheProblem.__init__, and it will avoid doing any initialization in any Julia process whose purpose is to precompile packages.

Fixing package code to avoid hangs

Search your package for suggestive words (here like "Timer") and see if you can identify where the problem is being created. Note that a method definition like

maketimer() = Timer(timer -> println("hi"), 0; interval=1)

is not problematic in and of itself: it can cause this problem only if maketimer gets called while the module is being defined. This might be happening from a top-level statement such as

const GLOBAL_TIMER = maketimer()

or it might conceivably occur in a precompile workload.

If you struggle to identify the causative lines, then consider doing a binary search: comment out sections of your package (or include lines to omit entire files) until you've reduced the problem in scope.

diff --git a/en/v1.12-dev/devdocs/probes/index.html b/en/v1.12-dev/devdocs/probes/index.html index 7757e7ffedcd..e828b32f8c1b 100644 --- a/en/v1.12-dev/devdocs/probes/index.html +++ b/en/v1.12-dev/devdocs/probes/index.html @@ -108,4 +108,4 @@ Thread wake up! 3e312190

Even though we only spawned a single task (which only one thread could process at a time), we woke up all of our other threads! In the future, a smarter task runtime might only wake up a single thread (or none at all; the spawning thread could execute this task!), and we should see this behavior go away.

Task Monitor with BPFnative.jl

BPFnative.jl is able to attach to USDT probe points just like bpftrace. There is a demo available for monitoring the task runtime, GC, and thread sleep/wake transitions here.

Notes on using bpftrace

An example probe in the bpftrace format looks like:

usdt:usr/lib/libjulia-internal.so:julia:gc__begin
 {
   @start[pid] = nsecs;
-}

The probe declaration takes the kind usdt, then either the path to the library or the PID, the provider name julia and the probe name gc__begin. Note that I am using a relative path to the libjulia-internal.so, but this might need to be an absolute path on a production system.

Useful references:

+}

The probe declaration takes the kind usdt, then either the path to the library or the PID, the provider name julia and the probe name gc__begin. Note that I am using a relative path to the libjulia-internal.so, but this might need to be an absolute path on a production system.

Useful references:

diff --git a/en/v1.12-dev/devdocs/require/index.html b/en/v1.12-dev/devdocs/require/index.html index fd811ff5fb13..fbe729946478 100644 --- a/en/v1.12-dev/devdocs/require/index.html +++ b/en/v1.12-dev/devdocs/require/index.html @@ -9,4 +9,4 @@ julia> loaded_packages 1-element Vector{Base.PkgId}: - Example [7876af07-990d-54b4-ab0e-23690620f79a] + Example [7876af07-990d-54b4-ab0e-23690620f79a] diff --git a/en/v1.12-dev/devdocs/sanitizers/index.html b/en/v1.12-dev/devdocs/sanitizers/index.html index 7aa35dd79a34..23239d3af265 100644 --- a/en/v1.12-dev/devdocs/sanitizers/index.html +++ b/en/v1.12-dev/devdocs/sanitizers/index.html @@ -38,4 +38,4 @@ # tell libblastrampoline to not use RTLD_DEEPBIND export LBT_USE_RTLD_DEEPBIND=0

Run:

cd $BUILD_WORKTREE
-make debug

to build julia-debug with ASAN.

Memory Sanitizer (MSAN)

For detecting use of uninitialized memory, you can use Clang's memory sanitizer (MSAN) by compiling with SANITIZE_MEMORY=1.

Thread Sanitizer (TSAN)

For debugging data-races and other threading related issues you can use Clang's thread sanitizer (TSAN) by compiling with SANITIZE_THREAD=1.

+make debug

to build julia-debug with ASAN.

Memory Sanitizer (MSAN)

For detecting use of uninitialized memory, you can use Clang's memory sanitizer (MSAN) by compiling with SANITIZE_MEMORY=1.

Thread Sanitizer (TSAN)

For debugging data-races and other threading related issues you can use Clang's thread sanitizer (TSAN) by compiling with SANITIZE_THREAD=1.

diff --git a/en/v1.12-dev/devdocs/ssair/index.html b/en/v1.12-dev/devdocs/ssair/index.html index 745d4cbcb254..64b75d28a16a 100644 --- a/en/v1.12-dev/devdocs/ssair/index.html +++ b/en/v1.12-dev/devdocs/ssair/index.html @@ -74,4 +74,4 @@ 5 ─ $(Expr(:pop_exception, :(%2)))::Any │ $(Expr(:throw_undef_if_not, :y, :(%13)))::Any │ %19 = Core.tuple(%15, %14) -└── return %19

Note in particular that every value live into the critical region gets an upsilon node at the top of the critical region. This is because catch blocks are considered to have an invisible control flow edge from outside the function. As a result, no SSA value dominates the catch blocks, and all incoming values have to come through a φᶜ node.

Main SSA data structure

The main SSAIR data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. The core of the data structure is a flat vector of statements. Each statement is implicitly assigned an SSA value based on its position in the vector (i.e. the result of the statement at idx 1 can be accessed using SSAValue(1) etc). For each SSA value, we additionally maintain its type. Since, SSA values are definitionally assigned only once, this type is also the result type of the expression at the corresponding index. However, while this representation is rather efficient (since the assignments don't need to be explicitly encoded), it of course carries the drawback that order is semantically significant, so reorderings and insertions change statement numbers. Additionally, we do not keep use lists (i.e. it is impossible to walk from a def to all its uses without explicitly computing this map–def lists however are trivial since you can look up the corresponding statement from the index), so the LLVM-style RAUW (replace-all-uses-with) operation is unavailable.

Instead, we do the following:

There is a compact! function that compacts the above data structure by performing the insertion of nodes in the appropriate place, trivial copy propagation, and renaming of uses to any changed SSA values. However, the clever part of this scheme is that this compaction can be done lazily as part of the subsequent pass. Most optimization passes need to walk over the entire list of statements, performing analysis or modifications along the way. We provide an IncrementalCompact iterator that can be used to iterate over the statement list. It will perform any necessary compaction and return the new index of the node, as well as the node itself. It is legal at this point to walk def-use chains, as well as make any modifications or deletions to the IR (insertions are disallowed however).

The idea behind this arrangement is that, since the optimization passes need to touch the corresponding memory anyway and incur the corresponding memory access penalty, performing the extra housekeeping should have comparatively little overhead (and save the overhead of maintaining these data structures during IR modification).

+└── return %19

Note in particular that every value live into the critical region gets an upsilon node at the top of the critical region. This is because catch blocks are considered to have an invisible control flow edge from outside the function. As a result, no SSA value dominates the catch blocks, and all incoming values have to come through a φᶜ node.

Main SSA data structure

The main SSAIR data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. The core of the data structure is a flat vector of statements. Each statement is implicitly assigned an SSA value based on its position in the vector (i.e. the result of the statement at idx 1 can be accessed using SSAValue(1) etc). For each SSA value, we additionally maintain its type. Since, SSA values are definitionally assigned only once, this type is also the result type of the expression at the corresponding index. However, while this representation is rather efficient (since the assignments don't need to be explicitly encoded), it of course carries the drawback that order is semantically significant, so reorderings and insertions change statement numbers. Additionally, we do not keep use lists (i.e. it is impossible to walk from a def to all its uses without explicitly computing this map–def lists however are trivial since you can look up the corresponding statement from the index), so the LLVM-style RAUW (replace-all-uses-with) operation is unavailable.

Instead, we do the following:

There is a compact! function that compacts the above data structure by performing the insertion of nodes in the appropriate place, trivial copy propagation, and renaming of uses to any changed SSA values. However, the clever part of this scheme is that this compaction can be done lazily as part of the subsequent pass. Most optimization passes need to walk over the entire list of statements, performing analysis or modifications along the way. We provide an IncrementalCompact iterator that can be used to iterate over the statement list. It will perform any necessary compaction and return the new index of the node, as well as the node itself. It is legal at this point to walk def-use chains, as well as make any modifications or deletions to the IR (insertions are disallowed however).

The idea behind this arrangement is that, since the optimization passes need to touch the corresponding memory anyway and incur the corresponding memory access penalty, performing the extra housekeeping should have comparatively little overhead (and save the overhead of maintaining these data structures during IR modification).

diff --git a/en/v1.12-dev/devdocs/stdio/index.html b/en/v1.12-dev/devdocs/stdio/index.html index dd5b59848bc3..1af229bea152 100644 --- a/en/v1.12-dev/devdocs/stdio/index.html +++ b/en/v1.12-dev/devdocs/stdio/index.html @@ -18,4 +18,4 @@ jl_uv.c: -> int jl_uv_write(uv_stream_t *stream, ...) -> uv_write(uvw, stream, buf, ...)

printf() during initialization

The libuv streams relied upon by jl_printf() etc., are not available until midway through initialization of the runtime (see init.c, init_stdio()). Error messages or warnings that need to be printed before this are routed to the standard C library fwrite() function by the following mechanism:

In sys.c, the JL_STD* stream pointers are statically initialized to integer constants: STD*_FILENO (0, 1 and 2). In jl_uv.c the jl_uv_puts() function checks its uv_stream_t* stream argument and calls fwrite() if stream is set to STDOUT_FILENO or STDERR_FILENO.

This allows for uniform use of jl_printf() throughout the runtime regardless of whether or not any particular piece of code is reachable before initialization is complete.

Legacy ios.c library

The src/support/ios.c library is inherited from femtolisp. It provides cross-platform buffered file IO and in-memory temporary buffers.

ios.c is still used by:

Use of ios.c in these modules is mostly self-contained and separated from the libuv I/O system. However, there is one place where femtolisp calls through to jl_printf() with a legacy ios_t stream.

There is a hack in ios.h that makes the ios_t.bm field line up with the uv_stream_t.type and ensures that the values used for ios_t.bm to not overlap with valid UV_HANDLE_TYPE values. This allows uv_stream_t pointers to point to ios_t streams.

This is needed because jl_printf() caller jl_static_show() is passed an ios_t stream by femtolisp's fl_print() function. Julia's jl_uv_puts() function has special handling for this:

if (stream->type > UV_HANDLE_TYPE_MAX) {
     return ios_write((ios_t*)stream, str, n);
-}
+} diff --git a/en/v1.12-dev/devdocs/subarrays/index.html b/en/v1.12-dev/devdocs/subarrays/index.html index cd0f6ccf4f95..88537bb21b56 100644 --- a/en/v1.12-dev/devdocs/subarrays/index.html +++ b/en/v1.12-dev/devdocs/subarrays/index.html @@ -66,4 +66,4 @@ 3 2

then A[2:2:4,:] does not have uniform stride, so we cannot guarantee efficient linear indexing. Since we have to base this decision based purely on types encoded in the parameters of the SubArray, S = view(A, 2:2:4, :) cannot implement efficient linear indexing.

A few details

+S = view(A, :, :, 1:1) # Appending extra indices is supported

Naively, you'd think you could just set S.parent = A and S.indices = (:,:,1:1), but supporting this dramatically complicates the reindexing process, especially for views of views. Not only do you need to dispatch on the types of the stored indices, but you need to examine whether a given index is the final one and "merge" any remaining stored indices together. This is not an easy task, and even worse: it's slow since it implicitly depends upon linear indexing.

Fortunately, this is precisely the computation that ReshapedArray performs, and it does so linearly if possible. Consequently, view ensures that the parent array is the appropriate dimensionality for the given indices by reshaping it if needed. The inner SubArray constructor ensures that this invariant is satisfied.

  • CartesianIndex and arrays thereof throw a nasty wrench into the reindex scheme. Recall that reindex simply dispatches on the type of the stored indices in order to determine how many passed indices should be used and where they should go. But with CartesianIndex, there's no longer a one-to-one correspondence between the number of passed arguments and the number of dimensions that they index into. If we return to the above example of Base.reindex(S1, S1.indices, (i, j)), you can see that the expansion is incorrect for i, j = CartesianIndex(), CartesianIndex(2,1). It should skip the CartesianIndex() entirely and return:

    (CartesianIndex(2,1)[1], S1.indices[2], S1.indices[3][CartesianIndex(2,1)[2]])

    Instead, though, we get:

    (CartesianIndex(), S1.indices[2], S1.indices[3][CartesianIndex(2,1)])

    Doing this correctly would require combined dispatch on both the stored and passed indices across all combinations of dimensionalities in an intractable manner. As such, reindex must never be called with CartesianIndex indices. Fortunately, the scalar case is easily handled by first flattening the CartesianIndex arguments to plain integers. Arrays of CartesianIndex, however, cannot be split apart into orthogonal pieces so easily. Before attempting to use reindex, view must ensure that there are no arrays of CartesianIndex in the argument list. If there are, it can simply "punt" by avoiding the reindex calculation entirely, constructing a nested SubArray with two levels of indirection instead.

  • diff --git a/en/v1.12-dev/devdocs/sysimg/index.html b/en/v1.12-dev/devdocs/sysimg/index.html index e56a0f480b9b..8ba5c09a2d7d 100644 --- a/en/v1.12-dev/devdocs/sysimg/index.html +++ b/en/v1.12-dev/devdocs/sysimg/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    System Image Building

    Building the Julia system image

    Julia ships with a preparsed system image containing the contents of the Base module, named sys.ji. This file is also precompiled into a shared library called sys.{so,dll,dylib} on as many platforms as possible, so as to give vastly improved startup times. On systems that do not ship with a precompiled system image file, one can be generated from the source files shipped in Julia's DATAROOTDIR/julia/base folder.

    Julia will by default generate its system image on half of the available system threads. This may be controlled by the JULIA_IMAGE_THREADS environment variable.

    This operation is useful for multiple reasons. A user may:

    • Build a precompiled shared library system image on a platform that did not ship with one, thereby improving startup times.
    • Modify Base, rebuild the system image and use the new Base next time Julia is started.
    • Include a userimg.jl file that includes packages into the system image, thereby creating a system image that has packages embedded into the startup environment.

    The PackageCompiler.jl package contains convenient wrapper functions to automate this process.

    System image optimized for multiple microarchitectures

    The system image can be compiled simultaneously for multiple CPU microarchitectures under the same instruction set architecture (ISA). Multiple versions of the same function may be created with minimum dispatch point inserted into shared functions in order to take advantage of different ISA extensions or other microarchitecture features. The version that offers the best performance will be selected automatically at runtime based on available CPU features.

    Specifying multiple system image targets

    A multi-microarchitecture system image can be enabled by passing multiple targets during system image compilation. This can be done either with the JULIA_CPU_TARGET make option or with the -C command line option when running the compilation command manually. Multiple targets are separated by ; in the option string. The syntax for each target is a CPU name followed by multiple features separated by ,. All features supported by LLVM are supported and a feature can be disabled with a - prefix. (+ prefix is also allowed and ignored to be consistent with LLVM syntax). Additionally, a few special features are supported to control the function cloning behavior.

    Note

    It is good practice to specify either clone_all or base(<n>) for every target apart from the first one. This makes it explicit which targets have all functions cloned, and which targets are based on other targets. If this is not done, the default behavior is to not clone every function, and to use the first target's function definition as the fallback when not cloning a function.

    1. clone_all

      By default, only functions that are the most likely to benefit from the microarchitecture features will be cloned. When clone_all is specified for a target, however, all functions in the system image will be cloned for the target. The negative form -clone_all can be used to prevent the built-in heuristic from cloning all functions.

    2. base(<n>)

      Where <n> is a placeholder for a non-negative number (e.g. base(0), base(1)). By default, a partially cloned (i.e. not clone_all) target will use functions from the default target (first one specified) if a function is not cloned. This behavior can be changed by specifying a different base with the base(<n>) option. The nth target (0-based) will be used as the base target instead of the default (0th) one. The base target has to be either 0 or another clone_all target. Specifying a non-clone_all target as the base target will cause an error.

    3. opt_size

      This causes the function for the target to be optimized for size when there isn't a significant runtime performance impact. This corresponds to -Os GCC and Clang option.

    4. min_size

      This causes the function for the target to be optimized for size that might have a significant runtime performance impact. This corresponds to -Oz Clang option.

    As an example, at the time of this writing, the following string is used in the creation of the official x86_64 Julia binaries downloadable from julialang.org:

    generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)

    This creates a system image with three separate targets; one for a generic x86_64 processor, one with a sandybridge ISA (explicitly excluding xsaveopt) that explicitly clones all functions, and one targeting the haswell ISA, based off of the sandybridge sysimg version, and also excluding rdrnd. When a Julia implementation loads the generated sysimg, it will check the host processor for matching CPU capability flags, enabling the highest ISA level possible. Note that the base level (generic) requires the cx16 instruction, which is disabled in some virtualization software and must be enabled for the generic target to be loaded. Alternatively, a sysimg could be generated with the target generic,-cx16 for greater compatibility, however note that this may cause performance and stability problems in some code.

    Implementation overview

    This is a brief overview of different part involved in the implementation. See code comments for each components for more implementation details.

    1. System image compilation

      The parsing and cloning decision are done in src/processor*. We currently support cloning of function based on the present of loops, simd instructions, or other math operations (e.g. fastmath, fma, muladd). This information is passed on to src/llvm-multiversioning.cpp which does the actual cloning. In addition to doing the cloning and insert dispatch slots (see comments in MultiVersioning::runOnModule for how this is done), the pass also generates metadata so that the runtime can load and initialize the system image correctly. A detailed description of the metadata is available in src/processor.h.

    2. System image loading

      The loading and initialization of the system image is done in src/processor* by parsing the metadata saved during system image generation. Host feature detection and selection decision are done in src/processor_*.cpp depending on the ISA. The target selection will prefer exact CPU name match, larger vector register size, and larger number of features. An overview of this process is in src/processor.cpp.

    +

    System Image Building

    Building the Julia system image

    Julia ships with a preparsed system image containing the contents of the Base module, named sys.ji. This file is also precompiled into a shared library called sys.{so,dll,dylib} on as many platforms as possible, so as to give vastly improved startup times. On systems that do not ship with a precompiled system image file, one can be generated from the source files shipped in Julia's DATAROOTDIR/julia/base folder.

    Julia will by default generate its system image on half of the available system threads. This may be controlled by the JULIA_IMAGE_THREADS environment variable.

    This operation is useful for multiple reasons. A user may:

    • Build a precompiled shared library system image on a platform that did not ship with one, thereby improving startup times.
    • Modify Base, rebuild the system image and use the new Base next time Julia is started.
    • Include a userimg.jl file that includes packages into the system image, thereby creating a system image that has packages embedded into the startup environment.

    The PackageCompiler.jl package contains convenient wrapper functions to automate this process.

    System image optimized for multiple microarchitectures

    The system image can be compiled simultaneously for multiple CPU microarchitectures under the same instruction set architecture (ISA). Multiple versions of the same function may be created with minimum dispatch point inserted into shared functions in order to take advantage of different ISA extensions or other microarchitecture features. The version that offers the best performance will be selected automatically at runtime based on available CPU features.

    Specifying multiple system image targets

    A multi-microarchitecture system image can be enabled by passing multiple targets during system image compilation. This can be done either with the JULIA_CPU_TARGET make option or with the -C command line option when running the compilation command manually. Multiple targets are separated by ; in the option string. The syntax for each target is a CPU name followed by multiple features separated by ,. All features supported by LLVM are supported and a feature can be disabled with a - prefix. (+ prefix is also allowed and ignored to be consistent with LLVM syntax). Additionally, a few special features are supported to control the function cloning behavior.

    Note

    It is good practice to specify either clone_all or base(<n>) for every target apart from the first one. This makes it explicit which targets have all functions cloned, and which targets are based on other targets. If this is not done, the default behavior is to not clone every function, and to use the first target's function definition as the fallback when not cloning a function.

    1. clone_all

      By default, only functions that are the most likely to benefit from the microarchitecture features will be cloned. When clone_all is specified for a target, however, all functions in the system image will be cloned for the target. The negative form -clone_all can be used to prevent the built-in heuristic from cloning all functions.

    2. base(<n>)

      Where <n> is a placeholder for a non-negative number (e.g. base(0), base(1)). By default, a partially cloned (i.e. not clone_all) target will use functions from the default target (first one specified) if a function is not cloned. This behavior can be changed by specifying a different base with the base(<n>) option. The nth target (0-based) will be used as the base target instead of the default (0th) one. The base target has to be either 0 or another clone_all target. Specifying a non-clone_all target as the base target will cause an error.

    3. opt_size

      This causes the function for the target to be optimized for size when there isn't a significant runtime performance impact. This corresponds to -Os GCC and Clang option.

    4. min_size

      This causes the function for the target to be optimized for size that might have a significant runtime performance impact. This corresponds to -Oz Clang option.

    As an example, at the time of this writing, the following string is used in the creation of the official x86_64 Julia binaries downloadable from julialang.org:

    generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)

    This creates a system image with three separate targets; one for a generic x86_64 processor, one with a sandybridge ISA (explicitly excluding xsaveopt) that explicitly clones all functions, and one targeting the haswell ISA, based off of the sandybridge sysimg version, and also excluding rdrnd. When a Julia implementation loads the generated sysimg, it will check the host processor for matching CPU capability flags, enabling the highest ISA level possible. Note that the base level (generic) requires the cx16 instruction, which is disabled in some virtualization software and must be enabled for the generic target to be loaded. Alternatively, a sysimg could be generated with the target generic,-cx16 for greater compatibility, however note that this may cause performance and stability problems in some code.

    Implementation overview

    This is a brief overview of different part involved in the implementation. See code comments for each components for more implementation details.

    1. System image compilation

      The parsing and cloning decision are done in src/processor*. We currently support cloning of function based on the present of loops, simd instructions, or other math operations (e.g. fastmath, fma, muladd). This information is passed on to src/llvm-multiversioning.cpp which does the actual cloning. In addition to doing the cloning and insert dispatch slots (see comments in MultiVersioning::runOnModule for how this is done), the pass also generates metadata so that the runtime can load and initialize the system image correctly. A detailed description of the metadata is available in src/processor.h.

    2. System image loading

      The loading and initialization of the system image is done in src/processor* by parsing the metadata saved during system image generation. Host feature detection and selection decision are done in src/processor_*.cpp depending on the ISA. The target selection will prefer exact CPU name match, larger vector register size, and larger number of features. An overview of this process is in src/processor.cpp.

    diff --git a/en/v1.12-dev/devdocs/types/index.html b/en/v1.12-dev/devdocs/types/index.html index 3fbaa4fc9fc6..d7b4c4e7fa99 100644 --- a/en/v1.12-dev/devdocs/types/index.html +++ b/en/v1.12-dev/devdocs/types/index.html @@ -137,4 +137,4 @@ f(nothing, 2.0)

    These examples are telling us something: when x is nothing::Nothing, there are no extra constraints on y. It is as if the method signature had y::Any. Indeed, we have the following type equivalence:

    (Tuple{Union{Nothing,T},T} where T) == Union{Tuple{Nothing,Any}, Tuple{T,T} where T}

    The general rule is: a concrete variable in covariant position acts like it's not concrete if the subtyping algorithm only uses it once. When x has type Nothing, we don't need to use the T in Union{Nothing,T}; we only use it in the second slot. This arises naturally from the observation that in Tuple{T} where T restricting T to concrete types makes no difference; the type is equal to Tuple{Any} either way.

    However, appearing in invariant position disqualifies a variable from being concrete whether that appearance of the variable is used or not. Otherwise types can behave differently depending on which other types they are compared to, making subtyping not transitive. For example, consider

    Tuple{Int,Int8,Vector{Integer}} <: Tuple{T,T,Vector{Union{Integer,T}}} where T

    If the T inside the Union is ignored, then T is concrete and the answer is "false" since the first two types aren't the same. But consider instead

    Tuple{Int,Int8,Vector{Any}} <: Tuple{T,T,Vector{Union{Integer,T}}} where T

    Now we cannot ignore the T in the Union (we must have T == Any), so T is not concrete and the answer is "true". That would make the concreteness of T depend on the other type, which is not acceptable since a type must have a clear meaning on its own. Therefore the appearance of T inside Vector is considered in both cases.

    Subtyping diagonal variables

    The subtyping algorithm for diagonal variables has two components: (1) identifying variable occurrences, and (2) ensuring that diagonal variables range over concrete types only.

    The first task is accomplished by keeping counters occurs_inv and occurs_cov (in src/subtype.c) for each variable in the environment, tracking the number of invariant and covariant occurrences, respectively. A variable is diagonal when occurs_inv == 0 && occurs_cov > 1.

    The second task is accomplished by imposing a condition on a variable's lower bound. As the subtyping algorithm runs, it narrows the bounds of each variable (raising lower bounds and lowering upper bounds) to keep track of the range of variable values for which the subtype relation would hold. When we are done evaluating the body of a UnionAll type whose variable is diagonal, we look at the final values of the bounds. Since the variable must be concrete, a contradiction occurs if its lower bound could not be a subtype of a concrete type. For example, an abstract type like AbstractArray cannot be a subtype of a concrete type, but a concrete type like Int can be, and the empty type Bottom can be as well. If a lower bound fails this test the algorithm stops with the answer false.

    For example, in the problem Tuple{Int,String} <: Tuple{T,T} where T, we derive that this would be true if T were a supertype of Union{Int,String}. However, Union{Int,String} is an abstract type, so the relation does not hold.

    This concreteness test is done by the function is_leaf_bound. Note that this test is slightly different from jl_is_leaf_type, since it also returns true for Bottom. Currently this function is heuristic, and does not catch all possible concrete types. The difficulty is that whether a lower bound is concrete might depend on the values of other type variable bounds. For example, Vector{T} is equivalent to the concrete type Vector{Int} only if both the upper and lower bounds of T equal Int. We have not yet worked out a complete algorithm for this.

    Introduction to the internal machinery

    Most operations for dealing with types are found in the files jltypes.c and subtype.c. A good way to start is to watch subtyping in action. Build Julia with make debug and fire up Julia within a debugger. gdb debugging tips has some tips which may be useful.

    Because the subtyping code is used heavily in the REPL itself – and hence breakpoints in this code get triggered often – it will be easiest if you make the following definition:

    julia> function mysubtype(a,b)
                ccall(:jl_breakpoint, Cvoid, (Any,), nothing)
                a <: b
    -       end

    and then set a breakpoint in jl_breakpoint. Once this breakpoint gets triggered, you can set breakpoints in other functions.

    As a warm-up, try the following:

    mysubtype(Tuple{Int, Float64}, Tuple{Integer, Real})

    We can make it more interesting by trying a more complex case:

    mysubtype(Tuple{Array{Int,2}, Int8}, Tuple{Array{T}, T} where T)

    Subtyping and method sorting

    The type_morespecific functions are used for imposing a partial order on functions in method tables (from most-to-least specific). Specificity is strict; if a is more specific than b, then a does not equal b and b is not more specific than a.

    If a is a strict subtype of b, then it is automatically considered more specific. From there, type_morespecific employs some less formal rules. For example, subtype is sensitive to the number of arguments, but type_morespecific may not be. In particular, Tuple{Int,AbstractFloat} is more specific than Tuple{Integer}, even though it is not a subtype. (Of Tuple{Int,AbstractFloat} and Tuple{Integer,Float64}, neither is more specific than the other.) Likewise, Tuple{Int,Vararg{Int}} is not a subtype of Tuple{Integer}, but it is considered more specific. However, morespecific does get a bonus for length: in particular, Tuple{Int,Int} is more specific than Tuple{Int,Vararg{Int}}.

    Additionally, if 2 methods are defined with identical signatures, per type-equal, then they will instead by compared by order of addition, such that the later method is more specific than the earlier one.

    + end

    and then set a breakpoint in jl_breakpoint. Once this breakpoint gets triggered, you can set breakpoints in other functions.

    As a warm-up, try the following:

    mysubtype(Tuple{Int, Float64}, Tuple{Integer, Real})

    We can make it more interesting by trying a more complex case:

    mysubtype(Tuple{Array{Int,2}, Int8}, Tuple{Array{T}, T} where T)

    Subtyping and method sorting

    The type_morespecific functions are used for imposing a partial order on functions in method tables (from most-to-least specific). Specificity is strict; if a is more specific than b, then a does not equal b and b is not more specific than a.

    If a is a strict subtype of b, then it is automatically considered more specific. From there, type_morespecific employs some less formal rules. For example, subtype is sensitive to the number of arguments, but type_morespecific may not be. In particular, Tuple{Int,AbstractFloat} is more specific than Tuple{Integer}, even though it is not a subtype. (Of Tuple{Int,AbstractFloat} and Tuple{Integer,Float64}, neither is more specific than the other.) Likewise, Tuple{Int,Vararg{Int}} is not a subtype of Tuple{Integer}, but it is considered more specific. However, morespecific does get a bonus for length: in particular, Tuple{Int,Int} is more specific than Tuple{Int,Vararg{Int}}.

    Additionally, if 2 methods are defined with identical signatures, per type-equal, then they will instead by compared by order of addition, such that the later method is more specific than the earlier one.

    diff --git a/en/v1.12-dev/devdocs/valgrind/index.html b/en/v1.12-dev/devdocs/valgrind/index.html index 9b6f171bdac8..6ba7995adc60 100644 --- a/en/v1.12-dev/devdocs/valgrind/index.html +++ b/en/v1.12-dev/devdocs/valgrind/index.html @@ -7,4 +7,4 @@ --xxxxxx-- You may be able to write your own handler. --xxxxxx-- Read the file README_MISSING_SYSCALL_OR_IOCTL. --xxxxxx-- Nevertheless we consider this a bug. Please report ---xxxxxx-- it at http://valgrind.org/support/bug_reports.html.

    This issue has been reported to the Valgrind developers as they have requested.

    Caveats

    Valgrind currently does not support multiple rounding modes, so code that adjusts the rounding mode will behave differently when run under Valgrind.

    In general, if after setting --smc-check=all-non-file you find that your program behaves differently when run under Valgrind, it may help to pass --tool=none to valgrind as you investigate further. This will enable the minimal Valgrind machinery but will also run much faster than when the full memory checker is enabled.

    +--xxxxxx-- it at http://valgrind.org/support/bug_reports.html.

    This issue has been reported to the Valgrind developers as they have requested.

    Caveats

    Valgrind currently does not support multiple rounding modes, so code that adjusts the rounding mode will behave differently when run under Valgrind.

    In general, if after setting --smc-check=all-non-file you find that your program behaves differently when run under Valgrind, it may help to pass --tool=none to valgrind as you investigate further. This will enable the minimal Valgrind machinery but will also run much faster than when the full memory checker is enabled.

    diff --git a/en/v1.12-dev/index.html b/en/v1.12-dev/index.html index 4acac381e9e6..0ba67b57e6dc 100644 --- a/en/v1.12-dev/index.html +++ b/en/v1.12-dev/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Julia 1.12-DEV Documentation

    Welcome to the documentation for Julia 1.12-DEV.

    Work in progress!

    This documentation is for an unreleased, in-development, version of Julia.

    Please read the release notes to see what has changed since the last release.

    Note

    The documentation is also available in PDF format: julia-1.12.0-DEV.pdf.

    Below is a non-exhaustive list of links that will be useful as you learn and use the Julia programming language.

    Introduction

    Scientific computing has traditionally required the highest performance, yet domain experts have largely moved to slower dynamic languages for daily work. We believe there are many good reasons to prefer dynamic languages for these applications, and we do not expect their use to diminish. Fortunately, modern language design and compiler techniques make it possible to mostly eliminate the performance trade-off and provide a single environment productive enough for prototyping and efficient enough for deploying performance-intensive applications. The Julia programming language fills this role: it is a flexible dynamic language, appropriate for scientific and numerical computing, with performance comparable to traditional statically-typed languages.

    Because Julia's compiler is different from the interpreters used for languages like Python or R, you may find that Julia's performance is unintuitive at first. If you find that something is slow, we highly recommend reading through the Performance Tips section before trying anything else. Once you understand how Julia works, it is easy to write code that is nearly as fast as C.

    Julia Compared to Other Languages

    Julia features optional typing, multiple dispatch, and good performance, achieved using type inference and just-in-time (JIT) compilation (and optional ahead-of-time compilation), implemented using LLVM. It is multi-paradigm, combining features of imperative, functional, and object-oriented programming. Julia provides ease and expressiveness for high-level numerical computing, in the same way as languages such as R, MATLAB, and Python, but also supports general programming. To achieve this, Julia builds upon the lineage of mathematical programming languages, but also borrows much from popular dynamic languages, including Lisp, Perl, Python, Lua, and Ruby.

    The most significant departures of Julia from typical dynamic languages are:

    • The core language imposes very little; Julia Base and the standard library are written in Julia itself, including primitive operations like integer arithmetic
    • A rich language of types for constructing and describing objects, that can also optionally be used to make type declarations
    • The ability to define function behavior across many combinations of argument types via multiple dispatch
    • Automatic generation of efficient, specialized code for different argument types
    • Good performance, approaching that of statically-compiled languages like C

    Although one sometimes speaks of dynamic languages as being "typeless", they are definitely not. Every object, whether primitive or user-defined, has a type. The lack of type declarations in most dynamic languages, however, means that one cannot instruct the compiler about the types of values, and often cannot explicitly talk about types at all. In static languages, on the other hand, while one can – and usually must – annotate types for the compiler, types exist only at compile time and cannot be manipulated or expressed at run time. In Julia, types are themselves run-time objects, and can also be used to convey information to the compiler.

    What Makes Julia, Julia?

    While the casual programmer need not explicitly use types or multiple dispatch, they are the core unifying features of Julia: functions are defined on different combinations of argument types, and applied by dispatching to the most specific matching definition. This model is a good fit for mathematical programming, where it is unnatural for the first argument to "own" an operation as in traditional object-oriented dispatch. Operators are just functions with special notation – to extend addition to new user-defined data types, you define new methods for the + function. Existing code then seamlessly applies to the new data types.

    Partly because of run-time type inference (augmented by optional type annotations), and partly because of a strong focus on performance from the inception of the project, Julia's computational efficiency exceeds that of other dynamic languages, and even rivals that of statically-compiled languages. For large scale numerical problems, speed always has been, continues to be, and probably always will be crucial: the amount of data being processed has easily kept pace with Moore's Law over the past decades.

    Advantages of Julia

    Julia aims to create an unprecedented combination of ease-of-use, power, and efficiency in a single language. In addition to the above, some advantages of Julia over comparable systems include:

    • Free and open source (MIT licensed)
    • User-defined types are as fast and compact as built-ins
    • No need to vectorize code for performance; devectorized code is fast
    • Designed for parallelism and distributed computation
    • Lightweight "green" threading (coroutines)
    • Unobtrusive yet powerful type system
    • Elegant and extensible conversions and promotions for numeric and other types
    • Efficient support for Unicode, including but not limited to UTF-8
    • Call C functions directly (no wrappers or special APIs needed)
    • Powerful shell-like capabilities for managing other processes
    • Lisp-like macros and other metaprogramming facilities
    +

    Julia 1.12-DEV Documentation

    Welcome to the documentation for Julia 1.12-DEV.

    Work in progress!

    This documentation is for an unreleased, in-development, version of Julia.

    Please read the release notes to see what has changed since the last release.

    Note

    The documentation is also available in PDF format: julia-1.12.0-DEV.pdf.

    Below is a non-exhaustive list of links that will be useful as you learn and use the Julia programming language.

    Introduction

    Scientific computing has traditionally required the highest performance, yet domain experts have largely moved to slower dynamic languages for daily work. We believe there are many good reasons to prefer dynamic languages for these applications, and we do not expect their use to diminish. Fortunately, modern language design and compiler techniques make it possible to mostly eliminate the performance trade-off and provide a single environment productive enough for prototyping and efficient enough for deploying performance-intensive applications. The Julia programming language fills this role: it is a flexible dynamic language, appropriate for scientific and numerical computing, with performance comparable to traditional statically-typed languages.

    Because Julia's compiler is different from the interpreters used for languages like Python or R, you may find that Julia's performance is unintuitive at first. If you find that something is slow, we highly recommend reading through the Performance Tips section before trying anything else. Once you understand how Julia works, it is easy to write code that is nearly as fast as C.

    Julia Compared to Other Languages

    Julia features optional typing, multiple dispatch, and good performance, achieved using type inference and just-in-time (JIT) compilation (and optional ahead-of-time compilation), implemented using LLVM. It is multi-paradigm, combining features of imperative, functional, and object-oriented programming. Julia provides ease and expressiveness for high-level numerical computing, in the same way as languages such as R, MATLAB, and Python, but also supports general programming. To achieve this, Julia builds upon the lineage of mathematical programming languages, but also borrows much from popular dynamic languages, including Lisp, Perl, Python, Lua, and Ruby.

    The most significant departures of Julia from typical dynamic languages are:

    • The core language imposes very little; Julia Base and the standard library are written in Julia itself, including primitive operations like integer arithmetic
    • A rich language of types for constructing and describing objects, that can also optionally be used to make type declarations
    • The ability to define function behavior across many combinations of argument types via multiple dispatch
    • Automatic generation of efficient, specialized code for different argument types
    • Good performance, approaching that of statically-compiled languages like C

    Although one sometimes speaks of dynamic languages as being "typeless", they are definitely not. Every object, whether primitive or user-defined, has a type. The lack of type declarations in most dynamic languages, however, means that one cannot instruct the compiler about the types of values, and often cannot explicitly talk about types at all. In static languages, on the other hand, while one can – and usually must – annotate types for the compiler, types exist only at compile time and cannot be manipulated or expressed at run time. In Julia, types are themselves run-time objects, and can also be used to convey information to the compiler.

    What Makes Julia, Julia?

    While the casual programmer need not explicitly use types or multiple dispatch, they are the core unifying features of Julia: functions are defined on different combinations of argument types, and applied by dispatching to the most specific matching definition. This model is a good fit for mathematical programming, where it is unnatural for the first argument to "own" an operation as in traditional object-oriented dispatch. Operators are just functions with special notation – to extend addition to new user-defined data types, you define new methods for the + function. Existing code then seamlessly applies to the new data types.

    Partly because of run-time type inference (augmented by optional type annotations), and partly because of a strong focus on performance from the inception of the project, Julia's computational efficiency exceeds that of other dynamic languages, and even rivals that of statically-compiled languages. For large scale numerical problems, speed always has been, continues to be, and probably always will be crucial: the amount of data being processed has easily kept pace with Moore's Law over the past decades.

    Advantages of Julia

    Julia aims to create an unprecedented combination of ease-of-use, power, and efficiency in a single language. In addition to the above, some advantages of Julia over comparable systems include:

    • Free and open source (MIT licensed)
    • User-defined types are as fast and compact as built-ins
    • No need to vectorize code for performance; devectorized code is fast
    • Designed for parallelism and distributed computation
    • Lightweight "green" threading (coroutines)
    • Unobtrusive yet powerful type system
    • Elegant and extensible conversions and promotions for numeric and other types
    • Efficient support for Unicode, including but not limited to UTF-8
    • Call C functions directly (no wrappers or special APIs needed)
    • Powerful shell-like capabilities for managing other processes
    • Lisp-like macros and other metaprogramming facilities
    diff --git a/en/v1.12-dev/manual/arrays/index.html b/en/v1.12-dev/manual/arrays/index.html index 913d9dea5c76..6d4af11146de 100644 --- a/en/v1.12-dev/manual/arrays/index.html +++ b/en/v1.12-dev/manual/arrays/index.html @@ -490,4 +490,4 @@ julia> stride(V, 1) 3

    This view is similarly selecting every other column from our original A — and thus it needs to skip the equivalent of two five-element columns when moving between indices in the second dimension:

    julia> stride(V, 2)
     10

    The third dimension is interesting because its order is reversed! Thus to get from the first "page" to the second one it must go backwards in memory, and so its stride in this dimension is negative!

    julia> stride(V, 3)
    --35

    This means that the pointer for V is actually pointing into the middle of A's memory block, and it refers to elements both backwards and forwards in memory. See the interface guide for strided arrays for more details on defining your own strided arrays. StridedVector and StridedMatrix are convenient aliases for many of the builtin array types that are considered strided arrays, allowing them to dispatch to select specialized implementations that call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides.

    It is worth emphasizing that strides are about offsets in memory rather than indexing. If you are looking to convert between linear (single-index) indexing and cartesian (multi-index) indexing, see LinearIndices and CartesianIndices.

    +-35

    This means that the pointer for V is actually pointing into the middle of A's memory block, and it refers to elements both backwards and forwards in memory. See the interface guide for strided arrays for more details on defining your own strided arrays. StridedVector and StridedMatrix are convenient aliases for many of the builtin array types that are considered strided arrays, allowing them to dispatch to select specialized implementations that call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides.

    It is worth emphasizing that strides are about offsets in memory rather than indexing. If you are looking to convert between linear (single-index) indexing and cartesian (multi-index) indexing, see LinearIndices and CartesianIndices.

    diff --git a/en/v1.12-dev/manual/asynchronous-programming/index.html b/en/v1.12-dev/manual/asynchronous-programming/index.html index 4a46fb93884b..fc3358274e2d 100644 --- a/en/v1.12-dev/manual/asynchronous-programming/index.html +++ b/en/v1.12-dev/manual/asynchronous-programming/index.html @@ -127,4 +127,4 @@ 10 finished in 0.64 seconds 12 finished in 0.5 seconds 11 finished in 0.97 seconds -0.029772311

    Instead of errormonitor(t), a more robust solution may be to use bind(results, t), as that will not only log any unexpected failures, but also force the associated resources to close and propagate the exception everywhere.

    More task operations

    Task operations are built on a low-level primitive called yieldto. yieldto(task, value) suspends the current task, switches to the specified task, and causes that task's last yieldto call to return the specified value. Notice that yieldto is the only operation required to use task-style control flow; instead of calling and returning we are always just switching to a different task. This is why this feature is also called "symmetric coroutines"; each task is switched to and from using the same mechanism.

    yieldto is powerful, but most uses of tasks do not invoke it directly. Consider why this might be. If you switch away from the current task, you will probably want to switch back to it at some point, but knowing when to switch back, and knowing which task has the responsibility of switching back, can require considerable coordination. For example, put! and take! are blocking operations, which, when used in the context of channels maintain state to remember who the consumers are. Not needing to manually keep track of the consuming task is what makes put! easier to use than the low-level yieldto.

    In addition to yieldto, a few other basic functions are needed to use tasks effectively.

    Tasks and events

    Most task switches occur as a result of waiting for events such as I/O requests, and are performed by a scheduler included in Julia Base. The scheduler maintains a queue of runnable tasks, and executes an event loop that restarts tasks based on external events such as message arrival.

    The basic function for waiting for an event is wait. Several objects implement wait; for example, given a Process object, wait will wait for it to exit. wait is often implicit; for example, a wait can happen inside a call to read to wait for data to be available.

    In all of these cases, wait ultimately operates on a Condition object, which is in charge of queueing and restarting tasks. When a task calls wait on a Condition, the task is marked as non-runnable, added to the condition's queue, and switches to the scheduler. The scheduler will then pick another task to run, or block waiting for external events. If all goes well, eventually an event handler will call notify on the condition, which causes tasks waiting for that condition to become runnable again.

    A task created explicitly by calling Task is initially not known to the scheduler. This allows you to manage tasks manually using yieldto if you wish. However, when such a task waits for an event, it still gets restarted automatically when the event happens, as you would expect.

    +0.029772311

    Instead of errormonitor(t), a more robust solution may be to use bind(results, t), as that will not only log any unexpected failures, but also force the associated resources to close and propagate the exception everywhere.

    More task operations

    Task operations are built on a low-level primitive called yieldto. yieldto(task, value) suspends the current task, switches to the specified task, and causes that task's last yieldto call to return the specified value. Notice that yieldto is the only operation required to use task-style control flow; instead of calling and returning we are always just switching to a different task. This is why this feature is also called "symmetric coroutines"; each task is switched to and from using the same mechanism.

    yieldto is powerful, but most uses of tasks do not invoke it directly. Consider why this might be. If you switch away from the current task, you will probably want to switch back to it at some point, but knowing when to switch back, and knowing which task has the responsibility of switching back, can require considerable coordination. For example, put! and take! are blocking operations, which, when used in the context of channels maintain state to remember who the consumers are. Not needing to manually keep track of the consuming task is what makes put! easier to use than the low-level yieldto.

    In addition to yieldto, a few other basic functions are needed to use tasks effectively.

    Tasks and events

    Most task switches occur as a result of waiting for events such as I/O requests, and are performed by a scheduler included in Julia Base. The scheduler maintains a queue of runnable tasks, and executes an event loop that restarts tasks based on external events such as message arrival.

    The basic function for waiting for an event is wait. Several objects implement wait; for example, given a Process object, wait will wait for it to exit. wait is often implicit; for example, a wait can happen inside a call to read to wait for data to be available.

    In all of these cases, wait ultimately operates on a Condition object, which is in charge of queueing and restarting tasks. When a task calls wait on a Condition, the task is marked as non-runnable, added to the condition's queue, and switches to the scheduler. The scheduler will then pick another task to run, or block waiting for external events. If all goes well, eventually an event handler will call notify on the condition, which causes tasks waiting for that condition to become runnable again.

    A task created explicitly by calling Task is initially not known to the scheduler. This allows you to manage tasks manually using yieldto if you wish. However, when such a task waits for an event, it still gets restarted automatically when the event happens, as you would expect.

    diff --git a/en/v1.12-dev/manual/calling-c-and-fortran-code/index.html b/en/v1.12-dev/manual/calling-c-and-fortran-code/index.html index 48959b5ec9aa..f9e1fa9bb262 100644 --- a/en/v1.12-dev/manual/calling-c-and-fortran-code/index.html +++ b/en/v1.12-dev/manual/calling-c-and-fortran-code/index.html @@ -158,4 +158,4 @@ 8

    ccall interface

    There is another alternative interface to @ccall. This interface is slightly less convenient but it does allow one to specify a calling convention.

    The arguments to ccall are:

    1. A (:function, "library") pair (most common),

      OR

      a :function name symbol or "function" name string (for symbols in the current process or libc),

      OR

      a function pointer (for example, from dlsym).

    2. The function's return type

    3. A tuple of input types, corresponding to the function signature. One common mistake is forgetting that a 1-tuple of argument types must be written with a trailing comma.

    4. The actual argument values to be passed to the function, if any; each is a separate parameter.

    Note

    The (:function, "library") pair, return type, and input types must be literal constants (i.e., they can't be variables, but see Non-constant Function Specifications).

    The remaining parameters are evaluated at compile-time, when the containing method is defined.

    A table of translations between the macro and function interfaces is given below.

    @ccallccall
    @ccall clock()::Int32ccall(:clock, Int32, ())
    @ccall f(a::Cint)::Cintccall(:a, Cint, (Cint,), a)
    @ccall "mylib".f(a::Cint, b::Cdouble)::Cvoidccall((:f, "mylib"), Cvoid, (Cint, Cdouble), (a, b))
    @ccall $fptr.f()::Cvoidccall(fptr, f, Cvoid, ())
    @ccall printf("%s = %d\n"::Cstring ; "foo"::Cstring, foo::Cint)::Cint<unavailable>
    @ccall printf("%s = %s\n"::Cstring ; "2 + 2"::Cstring, "5"::Cstring)::Cintccall(:printf, Cint, (Cstring, Cstring...), "%s = %s\n", "2 + 2", "5")
    <unavailable>ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn))

    Calling Convention

    The second argument to ccall (immediately preceding return type) can optionally be a calling convention specifier (the @ccall macro currently does not support giving a calling convention). Without any specifier, the platform-default C calling convention is used. Other supported conventions are: stdcall, cdecl, fastcall, and thiscall (no-op on 64-bit Windows). For example (from base/libc.jl) we see the same gethostnameccall as above, but with the correct signature for Windows:

    hn = Vector{UInt8}(undef, 256)
     err = ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn))

    For more information, please see the LLVM Language Reference.

    There is one additional special calling convention llvmcall, which allows inserting calls to LLVM intrinsics directly. This can be especially useful when targeting unusual platforms such as GPGPUs. For example, for CUDA, we need to be able to read the thread index:

    ccall("llvm.nvvm.read.ptx.sreg.tid.x", llvmcall, Int32, ())

    As with any ccall, it is essential to get the argument signature exactly correct. Also, note that there is no compatibility layer that ensures the intrinsic makes sense and works on the current target, unlike the equivalent Julia functions exposed by Core.Intrinsics.

    Accessing Global Variables

    Global variables exported by native libraries can be accessed by name using the cglobal function. The arguments to cglobal are a symbol specification identical to that used by ccall, and a type describing the value stored in the variable:

    julia> cglobal((:errno, :libc), Int32)
     Ptr{Int32} @0x00007f418d0816b8

    The result is a pointer giving the address of the value. The value can be manipulated through this pointer using unsafe_load and unsafe_store!.

    Note

    This errno symbol may not be found in a library named "libc", as this is an implementation detail of your system compiler. Typically standard library symbols should be accessed just by name, allowing the compiler to fill in the correct one. Also, however, the errno symbol shown in this example is special in most compilers, and so the value seen here is probably not what you expect or want. Compiling the equivalent code in C on any multi-threaded-capable system would typically actually call a different function (via macro preprocessor overloading), and may give a different result than the legacy value printed here.

    Accessing Data through a Pointer

    The following methods are described as "unsafe" because a bad pointer or type declaration can cause Julia to terminate abruptly.

    Given a Ptr{T}, the contents of type T can generally be copied from the referenced memory into a Julia object using unsafe_load(ptr, [index]). The index argument is optional (default is 1), and follows the Julia-convention of 1-based indexing. This function is intentionally similar to the behavior of getindex and setindex! (e.g. [] access syntax).

    The return value will be a new object initialized to contain a copy of the contents of the referenced memory. The referenced memory can safely be freed or released.

    If T is Any, then the memory is assumed to contain a reference to a Julia object (a jl_value_t*), the result will be a reference to this object, and the object will not be copied. You must be careful in this case to ensure that the object was always visible to the garbage collector (pointers do not count, but the new reference does) to ensure the memory is not prematurely freed. Note that if the object was not originally allocated by Julia, the new object will never be finalized by Julia's garbage collector. If the Ptr itself is actually a jl_value_t*, it can be converted back to a Julia object reference by unsafe_pointer_to_objref(ptr). (Julia values v can be converted to jl_value_t* pointers, as Ptr{Cvoid}, by calling pointer_from_objref(v).)

    The reverse operation (writing data to a Ptr{T}), can be performed using unsafe_store!(ptr, value, [index]). Currently, this is only supported for primitive types or other pointer-free (isbits) immutable struct types.

    Any operation that throws an error is probably currently unimplemented and should be posted as a bug so that it can be resolved.

    If the pointer of interest is a plain-data array (primitive type or immutable struct), the function unsafe_wrap(Array, ptr,dims, own = false) may be more useful. The final parameter should be true if Julia should "take ownership" of the underlying buffer and call free(ptr) when the returned Array object is finalized. If the own parameter is omitted or false, the caller must ensure the buffer remains in existence until all access is complete.

    Arithmetic on the Ptr type in Julia (e.g. using +) does not behave the same as C's pointer arithmetic. Adding an integer to a Ptr in Julia always moves the pointer by some number of bytes, not elements. This way, the address values obtained from pointer arithmetic do not depend on the element types of pointers.

    Thread-safety

    Some C libraries execute their callbacks from a different thread, and since Julia isn't thread-safe you'll need to take some extra precautions. In particular, you'll need to set up a two-layered system: the C callback should only schedule (via Julia's event loop) the execution of your "real" callback. To do this, create an AsyncCondition object and wait on it:

    cond = Base.AsyncCondition()
    -wait(cond)

    The callback you pass to C should only execute a ccall to :uv_async_send, passing cond.handle as the argument, taking care to avoid any allocations or other interactions with the Julia runtime.

    Note that events may be coalesced, so multiple calls to uv_async_send may result in a single wakeup notification to the condition.

    More About Callbacks

    For more details on how to pass callbacks to C libraries, see this blog post.

    C++

    For tools to create C++ bindings, see the CxxWrap package.

    +wait(cond)

    The callback you pass to C should only execute a ccall to :uv_async_send, passing cond.handle as the argument, taking care to avoid any allocations or other interactions with the Julia runtime.

    Note that events may be coalesced, so multiple calls to uv_async_send may result in a single wakeup notification to the condition.

    More About Callbacks

    For more details on how to pass callbacks to C libraries, see this blog post.

    C++

    For tools to create C++ bindings, see the CxxWrap package.

    diff --git a/en/v1.12-dev/manual/code-loading/index.html b/en/v1.12-dev/manual/code-loading/index.html index a986c9f209eb..50d9cf760db7 100644 --- a/en/v1.12-dev/manual/code-loading/index.html +++ b/en/v1.12-dev/manual/code-loading/index.html @@ -150,4 +150,4 @@ MyPackage/ Project.toml # projects = ["test"] test/ - Project.toml

    Package/Environment Preferences

    Preferences are dictionaries of metadata that influence package behavior within an environment. The preferences system supports reading preferences at compile-time, which means that at code-loading time, we must ensure that the precompilation files selected by Julia were built with the same preferences as the current environment before loading them. The public API for modifying Preferences is contained within the Preferences.jl package. Preferences are stored as TOML dictionaries within a (Julia)LocalPreferences.toml file next to the currently-active project. If a preference is "exported", it is instead stored within the (Julia)Project.toml instead. The intention is to allow shared projects to contain shared preferences, while allowing for users themselves to override those preferences with their own settings in the LocalPreferences.toml file, which should be .gitignored as the name implies.

    Preferences that are accessed during compilation are automatically marked as compile-time preferences, and any change recorded to these preferences will cause the Julia compiler to recompile any cached precompilation file(s) (.ji and corresponding .so, .dll, or .dylib files) for that module. This is done by serializing the hash of all compile-time preferences during compilation, then checking that hash against the current environment when searching for the proper file(s) to load.

    Preferences can be set with depot-wide defaults; if package Foo is installed within your global environment and it has preferences set, these preferences will apply as long as your global environment is part of your LOAD_PATH. Preferences in environments higher up in the environment stack get overridden by the more proximal entries in the load path, ending with the currently active project. This allows depot-wide preference defaults to exist, with active projects able to merge or even completely overwrite these inherited preferences. See the docstring for Preferences.set_preferences!() for the full details of how to set preferences to allow or disallow merging.

    Conclusion

    Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Typically, Julia users should be able to use the built-in package manager to manage their projects without needing a precise understanding of these interactions. A call to Pkg.add("X") will add to the appropriate project and manifest files, selected via Pkg.activate("Y"), so that a future call to import X will load X without further thought.

    + Project.toml

    Package/Environment Preferences

    Preferences are dictionaries of metadata that influence package behavior within an environment. The preferences system supports reading preferences at compile-time, which means that at code-loading time, we must ensure that the precompilation files selected by Julia were built with the same preferences as the current environment before loading them. The public API for modifying Preferences is contained within the Preferences.jl package. Preferences are stored as TOML dictionaries within a (Julia)LocalPreferences.toml file next to the currently-active project. If a preference is "exported", it is instead stored within the (Julia)Project.toml instead. The intention is to allow shared projects to contain shared preferences, while allowing for users themselves to override those preferences with their own settings in the LocalPreferences.toml file, which should be .gitignored as the name implies.

    Preferences that are accessed during compilation are automatically marked as compile-time preferences, and any change recorded to these preferences will cause the Julia compiler to recompile any cached precompilation file(s) (.ji and corresponding .so, .dll, or .dylib files) for that module. This is done by serializing the hash of all compile-time preferences during compilation, then checking that hash against the current environment when searching for the proper file(s) to load.

    Preferences can be set with depot-wide defaults; if package Foo is installed within your global environment and it has preferences set, these preferences will apply as long as your global environment is part of your LOAD_PATH. Preferences in environments higher up in the environment stack get overridden by the more proximal entries in the load path, ending with the currently active project. This allows depot-wide preference defaults to exist, with active projects able to merge or even completely overwrite these inherited preferences. See the docstring for Preferences.set_preferences!() for the full details of how to set preferences to allow or disallow merging.

    Conclusion

    Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Typically, Julia users should be able to use the built-in package manager to manage their projects without needing a precise understanding of these interactions. A call to Pkg.add("X") will add to the appropriate project and manifest files, selected via Pkg.activate("Y"), so that a future call to import X will load X without further thought.

    diff --git a/en/v1.12-dev/manual/command-line-interface/index.html b/en/v1.12-dev/manual/command-line-interface/index.html index f9989b56dd0d..b2423690973a 100644 --- a/en/v1.12-dev/manual/command-line-interface/index.html +++ b/en/v1.12-dev/manual/command-line-interface/index.html @@ -30,4 +30,4 @@ ...

    Note that although you should have a ~/.julia directory once you've run Julia for the first time, you may need to create the ~/.julia/config folder and the ~/.julia/config/startup.jl file if you use it.

    To have startup code run only in The Julia REPL (and not when julia is e.g. run on a script), use atreplinit in startup.jl:

    atreplinit() do repl
         # ...
    -end

    Command-line switches for Julia

    There are various ways to run Julia code and provide options, similar to those available for the perl and ruby programs:

    julia [switches] -- [programfile] [args...]

    The following is a complete list of command-line switches available when launching julia (a '*' marks the default value, if applicable; settings marked '($)' may trigger package precompilation):

    SwitchDescription
    -v, --versionDisplay version information
    -h, --helpPrint command-line options (this message).
    --help-hiddenUncommon options not shown by -h
    --project[={<dir>|@.}]Set <dir> as the active project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.
    -J, --sysimage <file>Start up with the given system image file
    -H, --home <dir>Set location of julia executable
    --startup-file={yes*|no}Load JULIA_DEPOT_PATH/config/startup.jl; if JULIA_DEPOT_PATH environment variable is unset, load ~/.julia/config/startup.jl
    --handle-signals={yes*|no}Enable or disable Julia's default signal handlers
    --sysimage-native-code={yes*|no}Use native code from system image if available
    `–compiled-modules={yes*|no|existingstrict}`
    `–pkgimages={yes*|noexisting}`
    -e, --eval <expr>Evaluate <expr>
    -E, --print <expr>Evaluate <expr> and display the result
    -L, --load <file>Load <file> immediately on all processors
    -t, --threads {N|auto}Enable N threads; auto tries to infer a useful default number of threads to use but the exact behavior might change in the future. Currently, auto uses the number of CPUs assigned to this julia process based on the OS-specific affinity assignment interface, if supported (Linux and Windows). If this is not supported (macOS) or process affinity is not configured, it uses the number of CPU threads.
    --gcthreads=N[,M]Use N threads for the mark phase of GC and M (0 or 1) threads for the concurrent sweeping phase of GC. N is set to half of the number of compute threads and M is set to 0 if unspecified.
    -p, --procs {N|auto}Integer value N launches N additional local worker processes; auto launches as many workers as the number of local CPU threads (logical cores)
    --machine-file <file>Run processes on hosts listed in <file>
    -iInteractive mode; REPL runs and isinteractive() is true
    -q, --quietQuiet startup: no banner, suppress REPL warnings
    --banner={yes|no|auto*}Enable or disable startup banner
    --color={yes|no|auto*}Enable or disable color text
    --history-file={yes*|no}Load or save history
    --depwarn={yes|no*|error}Enable or disable syntax and method deprecation warnings (error turns warnings into errors)
    --warn-overwrite={yes|no*}Enable or disable method overwrite warnings
    --warn-scope={yes*|no}Enable or disable warning for ambiguous top-level scope
    -C, --cpu-target <target>Limit usage of CPU features up to <target>; set to help to see the available options
    -O, --optimize={0,1,2*,3}Set the optimization level (level is 3 if -O is used without a level) ($)
    --min-optlevel={0*,1,2,3}Set the lower bound on per-module optimization
    -g, --debug-info={0,1*,2}Set the level of debug info generation (level is 2 if -g is used without a level) ($)
    --inline={yes|no}Control whether inlining is permitted, including overriding @inline declarations
    --check-bounds={yes|no|auto*}Emit bounds checks always, never, or respect @inbounds declarations ($)
    --math-mode={ieee,fast}Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)
    --code-coverage[={none*|user|all}]Count executions of source lines (omitting setting is equivalent to user)
    --code-coverage=@<path>Count executions but only in files that fall under the given file path/directory. The @ prefix is required to select this option. A @ with no path will track the current directory.
    --code-coverage=tracefile.infoAppend coverage information to the LCOV tracefile (filename supports format tokens).
    --track-allocation[={none*|user|all}]Count bytes allocated by each source line (omitting setting is equivalent to "user")
    --track-allocation=@<path>Count bytes but only in files that fall under the given file path/directory. The @ prefix is required to select this option. A @ with no path will track the current directory.
    --bug-report=KINDLaunch a bug report session. It can be used to start a REPL, run a script, or evaluate expressions. It first tries to use BugReporting.jl installed in current environment and falls back to the latest compatible BugReporting.jl if not. For more information, see --bug-report=help.
    --compile={yes*|no|all|min}Enable or disable JIT compiler, or request exhaustive or minimal compilation
    --output-o <name>Generate an object file (including system image data)
    --output-ji <name>Generate a system image data file (.ji)
    --strip-metadataRemove docstrings and source location info from system image
    --strip-irRemove IR (intermediate representation) of compiled functions
    --output-unopt-bc <name>Generate unoptimized LLVM bitcode (.bc)
    --output-bc <name>Generate LLVM bitcode (.bc)
    --output-asm <name>Generate an assembly file (.s)
    --output-incremental={yes|no*}Generate an incremental output file (rather than complete)
    --trace-compile={stderr,name}Print precompile statements for methods compiled during execution or save to a path
    --image-codegenForce generate code in imaging mode
    --heap-size-hint=<size>Forces garbage collection if memory usage is higher than the given value. The value may be specified as a number of bytes, optionally in units of KB, MB, GB, or TB, or as a percentage of physical memory with %.
    Julia 1.1

    In Julia 1.0, the default --project=@. option did not search up from the root directory of a Git repository for the Project.toml file. From Julia 1.1 forward, it does.

    +end

    Command-line switches for Julia

    There are various ways to run Julia code and provide options, similar to those available for the perl and ruby programs:

    julia [switches] -- [programfile] [args...]

    The following is a complete list of command-line switches available when launching julia (a '*' marks the default value, if applicable; settings marked '($)' may trigger package precompilation):

    SwitchDescription
    -v, --versionDisplay version information
    -h, --helpPrint command-line options (this message).
    --help-hiddenUncommon options not shown by -h
    --project[={<dir>|@.}]Set <dir> as the active project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.
    -J, --sysimage <file>Start up with the given system image file
    -H, --home <dir>Set location of julia executable
    --startup-file={yes*|no}Load JULIA_DEPOT_PATH/config/startup.jl; if JULIA_DEPOT_PATH environment variable is unset, load ~/.julia/config/startup.jl
    --handle-signals={yes*|no}Enable or disable Julia's default signal handlers
    --sysimage-native-code={yes*|no}Use native code from system image if available
    `–compiled-modules={yes*|no|existingstrict}`
    `–pkgimages={yes*|noexisting}`
    -e, --eval <expr>Evaluate <expr>
    -E, --print <expr>Evaluate <expr> and display the result
    -L, --load <file>Load <file> immediately on all processors
    -t, --threads {N|auto}Enable N threads; auto tries to infer a useful default number of threads to use but the exact behavior might change in the future. Currently, auto uses the number of CPUs assigned to this julia process based on the OS-specific affinity assignment interface, if supported (Linux and Windows). If this is not supported (macOS) or process affinity is not configured, it uses the number of CPU threads.
    --gcthreads=N[,M]Use N threads for the mark phase of GC and M (0 or 1) threads for the concurrent sweeping phase of GC. N is set to half of the number of compute threads and M is set to 0 if unspecified.
    -p, --procs {N|auto}Integer value N launches N additional local worker processes; auto launches as many workers as the number of local CPU threads (logical cores)
    --machine-file <file>Run processes on hosts listed in <file>
    -iInteractive mode; REPL runs and isinteractive() is true
    -q, --quietQuiet startup: no banner, suppress REPL warnings
    --banner={yes|no|auto*}Enable or disable startup banner
    --color={yes|no|auto*}Enable or disable color text
    --history-file={yes*|no}Load or save history
    --depwarn={yes|no*|error}Enable or disable syntax and method deprecation warnings (error turns warnings into errors)
    --warn-overwrite={yes|no*}Enable or disable method overwrite warnings
    --warn-scope={yes*|no}Enable or disable warning for ambiguous top-level scope
    -C, --cpu-target <target>Limit usage of CPU features up to <target>; set to help to see the available options
    -O, --optimize={0,1,2*,3}Set the optimization level (level is 3 if -O is used without a level) ($)
    --min-optlevel={0*,1,2,3}Set the lower bound on per-module optimization
    -g, --debug-info={0,1*,2}Set the level of debug info generation (level is 2 if -g is used without a level) ($)
    --inline={yes|no}Control whether inlining is permitted, including overriding @inline declarations
    --check-bounds={yes|no|auto*}Emit bounds checks always, never, or respect @inbounds declarations ($)
    --math-mode={ieee,fast}Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)
    --code-coverage[={none*|user|all}]Count executions of source lines (omitting setting is equivalent to user)
    --code-coverage=@<path>Count executions but only in files that fall under the given file path/directory. The @ prefix is required to select this option. A @ with no path will track the current directory.
    --code-coverage=tracefile.infoAppend coverage information to the LCOV tracefile (filename supports format tokens).
    --track-allocation[={none*|user|all}]Count bytes allocated by each source line (omitting setting is equivalent to "user")
    --track-allocation=@<path>Count bytes but only in files that fall under the given file path/directory. The @ prefix is required to select this option. A @ with no path will track the current directory.
    --bug-report=KINDLaunch a bug report session. It can be used to start a REPL, run a script, or evaluate expressions. It first tries to use BugReporting.jl installed in current environment and falls back to the latest compatible BugReporting.jl if not. For more information, see --bug-report=help.
    --compile={yes*|no|all|min}Enable or disable JIT compiler, or request exhaustive or minimal compilation
    --output-o <name>Generate an object file (including system image data)
    --output-ji <name>Generate a system image data file (.ji)
    --strip-metadataRemove docstrings and source location info from system image
    --strip-irRemove IR (intermediate representation) of compiled functions
    --output-unopt-bc <name>Generate unoptimized LLVM bitcode (.bc)
    --output-bc <name>Generate LLVM bitcode (.bc)
    --output-asm <name>Generate an assembly file (.s)
    --output-incremental={yes|no*}Generate an incremental output file (rather than complete)
    --trace-compile={stderr,name}Print precompile statements for methods compiled during execution or save to a path
    --image-codegenForce generate code in imaging mode
    --heap-size-hint=<size>Forces garbage collection if memory usage is higher than the given value. The value may be specified as a number of bytes, optionally in units of KB, MB, GB, or TB, or as a percentage of physical memory with %.
    Julia 1.1

    In Julia 1.0, the default --project=@. option did not search up from the root directory of a Git repository for the Project.toml file. From Julia 1.1 forward, it does.

    diff --git a/en/v1.12-dev/manual/complex-and-rational-numbers/index.html b/en/v1.12-dev/manual/complex-and-rational-numbers/index.html index 445887ea663d..6e101bb76227 100644 --- a/en/v1.12-dev/manual/complex-and-rational-numbers/index.html +++ b/en/v1.12-dev/manual/complex-and-rational-numbers/index.html @@ -184,4 +184,4 @@ true julia> 1//3 - 0.33 -0.0033333333333332993 +0.0033333333333332993 diff --git a/en/v1.12-dev/manual/constructors/index.html b/en/v1.12-dev/manual/constructors/index.html index 0018d62a77e9..29a5071797b3 100644 --- a/en/v1.12-dev/manual/constructors/index.html +++ b/en/v1.12-dev/manual/constructors/index.html @@ -254,4 +254,4 @@ julia> (::Type{S})() = S(8) # overwrites the previous constructor method julia> S() -S(8)
    +S(8)
    diff --git a/en/v1.12-dev/manual/control-flow/index.html b/en/v1.12-dev/manual/control-flow/index.html index eee30a5e7676..1983e227c25a 100644 --- a/en/v1.12-dev/manual/control-flow/index.html +++ b/en/v1.12-dev/manual/control-flow/index.html @@ -375,4 +375,4 @@ # operate on file f finally close(f) -end

    When control leaves the try block (for example due to a return, or just finishing normally), close(f) will be executed. If the try block exits due to an exception, the exception will continue propagating. A catch block may be combined with try and finally as well. In this case the finally block will run after catch has handled the error.

    Tasks (aka Coroutines)

    Tasks are a control flow feature that allows computations to be suspended and resumed in a flexible manner. We mention them here only for completeness; for a full discussion see Asynchronous Programming.

    +end

    When control leaves the try block (for example due to a return, or just finishing normally), close(f) will be executed. If the try block exits due to an exception, the exception will continue propagating. A catch block may be combined with try and finally as well. In this case the finally block will run after catch has handled the error.

    Tasks (aka Coroutines)

    Tasks are a control flow feature that allows computations to be suspended and resumed in a flexible manner. We mention them here only for completeness; for a full discussion see Asynchronous Programming.

    diff --git a/en/v1.12-dev/manual/conversion-and-promotion/index.html b/en/v1.12-dev/manual/conversion-and-promotion/index.html index 45827831f709..7f38a891cc34 100644 --- a/en/v1.12-dev/manual/conversion-and-promotion/index.html +++ b/en/v1.12-dev/manual/conversion-and-promotion/index.html @@ -61,4 +61,4 @@ Int64

    Note that we do not overload promote_type directly: we overload promote_rule instead. promote_type uses promote_rule, and adds the symmetry. Overloading it directly can cause ambiguity errors. We overload promote_rule to define how things should be promoted, and we use promote_type to query that.

    Internally, promote_type is used inside of promote to determine what type argument values should be converted to for promotion. The curious reader can read the code in promotion.jl, which defines the complete promotion mechanism in about 35 lines.

    Case Study: Rational Promotions

    Finally, we finish off our ongoing case study of Julia's rational number type, which makes relatively sophisticated use of the promotion mechanism with the following promotion rules:

    import Base: promote_rule
     promote_rule(::Type{Rational{T}}, ::Type{S}) where {T<:Integer,S<:Integer} = Rational{promote_type(T,S)}
     promote_rule(::Type{Rational{T}}, ::Type{Rational{S}}) where {T<:Integer,S<:Integer} = Rational{promote_type(T,S)}
    -promote_rule(::Type{Rational{T}}, ::Type{S}) where {T<:Integer,S<:AbstractFloat} = promote_type(T,S)

    The first rule says that promoting a rational number with any other integer type promotes to a rational type whose numerator/denominator type is the result of promotion of its numerator/denominator type with the other integer type. The second rule applies the same logic to two different types of rational numbers, resulting in a rational of the promotion of their respective numerator/denominator types. The third and final rule dictates that promoting a rational with a float results in the same type as promoting the numerator/denominator type with the float.

    This small handful of promotion rules, together with the type's constructors and the default convert method for numbers, are sufficient to make rational numbers interoperate completely naturally with all of Julia's other numeric types – integers, floating-point numbers, and complex numbers. By providing appropriate conversion methods and promotion rules in the same manner, any user-defined numeric type can interoperate just as naturally with Julia's predefined numerics.

    +promote_rule(::Type{Rational{T}}, ::Type{S}) where {T<:Integer,S<:AbstractFloat} = promote_type(T,S)

    The first rule says that promoting a rational number with any other integer type promotes to a rational type whose numerator/denominator type is the result of promotion of its numerator/denominator type with the other integer type. The second rule applies the same logic to two different types of rational numbers, resulting in a rational of the promotion of their respective numerator/denominator types. The third and final rule dictates that promoting a rational with a float results in the same type as promoting the numerator/denominator type with the float.

    This small handful of promotion rules, together with the type's constructors and the default convert method for numbers, are sufficient to make rational numbers interoperate completely naturally with all of Julia's other numeric types – integers, floating-point numbers, and complex numbers. By providing appropriate conversion methods and promotion rules in the same manner, any user-defined numeric type can interoperate just as naturally with Julia's predefined numerics.

    diff --git a/en/v1.12-dev/manual/distributed-computing/index.html b/en/v1.12-dev/manual/distributed-computing/index.html index d3aa6d3894ac..2da128816221 100644 --- a/en/v1.12-dev/manual/distributed-computing/index.html +++ b/en/v1.12-dev/manual/distributed-computing/index.html @@ -495,4 +495,4 @@ @printf("sum of ranks: %s\n", sr) end -MPI.Finalize()
    mpirun -np 4 ./julia example.jl
    +MPI.Finalize()
    mpirun -np 4 ./julia example.jl
    diff --git a/en/v1.12-dev/manual/documentation/index.html b/en/v1.12-dev/manual/documentation/index.html index c36f72ee665e..b031e39dbcdf 100644 --- a/en/v1.12-dev/manual/documentation/index.html +++ b/en/v1.12-dev/manual/documentation/index.html @@ -220,4 +220,4 @@ 1 julia> "Docstring" @macroception -1source +1source diff --git a/en/v1.12-dev/manual/embedding/index.html b/en/v1.12-dev/manual/embedding/index.html index 7955c2904356..a4a9a57eb990 100644 --- a/en/v1.12-dev/manual/embedding/index.html +++ b/en/v1.12-dev/manual/embedding/index.html @@ -237,4 +237,4 @@ [J 2] i = 4 -> 2.0 [C 23938640] i = 5 [J 1] i = 3 -> 1.7320508075688772 -[J 2] i = 5 -> 2.23606797749979

    As can be seen, Julia thread 1 corresponds to pthread ID 3bfd9c00, and Julia thread 2 corresponds to ID 23938640, showing that indeed multiple threads are used at the C level, and that we can safely call Julia C API routines from those threads.

    +[J 2] i = 5 -> 2.23606797749979

    As can be seen, Julia thread 1 corresponds to pthread ID 3bfd9c00, and Julia thread 2 corresponds to ID 23938640, showing that indeed multiple threads are used at the C level, and that we can safely call Julia C API routines from those threads.

    diff --git a/en/v1.12-dev/manual/environment-variables/index.html b/en/v1.12-dev/manual/environment-variables/index.html index eaad2096ed64..fa3a80209df3 100644 --- a/en/v1.12-dev/manual/environment-variables/index.html +++ b/en/v1.12-dev/manual/environment-variables/index.html @@ -5,4 +5,4 @@ gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash});

    Environment Variables

    Julia can be configured with a number of environment variables, set either in the usual way for each operating system, or in a portable way from within Julia. Supposing that you want to set the environment variable JULIA_EDITOR to vim, you can type ENV["JULIA_EDITOR"] = "vim" (for instance, in the REPL) to make this change on a case by case basis, or add the same to the user configuration file ~/.julia/config/startup.jl in the user's home directory to have a permanent effect. The current value of the same environment variable can be determined by evaluating ENV["JULIA_EDITOR"].

    The environment variables that Julia uses generally start with JULIA. If InteractiveUtils.versioninfo is called with the keyword verbose=true, then the output will list any defined environment variables relevant for Julia, including those which include JULIA in their names.

    Note

    It is recommended to avoid changing environment variables during runtime, such as within a ~/.julia/config/startup.jl.

    One reason is that some julia language variables, such as JULIA_NUM_THREADS and JULIA_PROJECT, need to be set before Julia starts.

    Similarly, __init__() functions of user modules in the sysimage (via PackageCompiler) are run before startup.jl, so setting environment variables in a startup.jl may be too late for user code.

    Further, changing environment variables during runtime can introduce data races into otherwise benign code.

    In Bash, environment variables can either be set manually by running, e.g., export JULIA_NUM_THREADS=4 before starting Julia, or by adding the same command to ~/.bashrc or ~/.bash_profile to set the variable each time Bash is started.

    File locations

    JULIA_BINDIR

    The absolute path of the directory containing the Julia executable, which sets the global variable Sys.BINDIR. If $JULIA_BINDIR is not set, then Julia determines the value Sys.BINDIR at run-time.

    The executable itself is one of

    $JULIA_BINDIR/julia
     $JULIA_BINDIR/julia-debug

    by default.

    The global variable Base.DATAROOTDIR determines a relative path from Sys.BINDIR to the data directory associated with Julia. Then the path

    $JULIA_BINDIR/$DATAROOTDIR/julia/base

    determines the directory in which Julia initially searches for source files (via Base.find_source_file()).

    Likewise, the global variable Base.SYSCONFDIR determines a relative path to the configuration file directory. Then Julia searches for a startup.jl file at

    $JULIA_BINDIR/$SYSCONFDIR/julia/startup.jl
    -$JULIA_BINDIR/../etc/julia/startup.jl

    by default (via Base.load_julia_startup()).

    For example, a Linux installation with a Julia executable located at /bin/julia, a DATAROOTDIR of ../share, and a SYSCONFDIR of ../etc will have JULIA_BINDIR set to /bin, a source-file search path of

    /share/julia/base

    and a global configuration search path of

    /etc/julia/startup.jl

    JULIA_PROJECT

    A directory path that indicates which project should be the initial active project. Setting this environment variable has the same effect as specifying the --project start-up option, but --project has higher precedence. If the variable is set to @. (note the trailing dot) then Julia tries to find a project directory that contains Project.toml or JuliaProject.toml file from the current directory and its parents. See also the chapter on Code Loading.

    Note

    JULIA_PROJECT must be defined before starting julia; defining it in startup.jl is too late in the startup process.

    JULIA_LOAD_PATH

    The JULIA_LOAD_PATH environment variable is used to populate the global Julia LOAD_PATH variable, which determines which packages can be loaded via import and using (see Code Loading).

    Unlike the shell PATH variable, empty entries in JULIA_LOAD_PATH are expanded to the default value of LOAD_PATH, ["@", "@v#.#", "@stdlib"] when populating LOAD_PATH. This allows easy appending, prepending, etc. of the load path value in shell scripts regardless of whether JULIA_LOAD_PATH is already set or not. For example, to prepend the directory /foo/bar to LOAD_PATH just do

    export JULIA_LOAD_PATH="/foo/bar:$JULIA_LOAD_PATH"

    If the JULIA_LOAD_PATH environment variable is already set, its old value will be prepended with /foo/bar. On the other hand, if JULIA_LOAD_PATH is not set, then it will be set to /foo/bar: which will expand to a LOAD_PATH value of ["/foo/bar", "@", "@v#.#", "@stdlib"]. If JULIA_LOAD_PATH is set to the empty string, it expands to an empty LOAD_PATH array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty load path via the environment variable. If you want the default load path, either unset the environment variable or if it must have a value, set it to the string :.

    Note

    On Windows, path elements are separated by the ; character, as is the case with most path lists on Windows. Replace : with ; in the above paragraph.

    JULIA_DEPOT_PATH

    The JULIA_DEPOT_PATH environment variable is used to populate the global Julia DEPOT_PATH variable, which controls where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, configuration files, and the default location of the REPL's history file.

    Unlike the shell PATH variable but similar to JULIA_LOAD_PATH, empty entries in JULIA_DEPOT_PATH are expanded to the default value of DEPOT_PATH, excluding the user depot. This allows easy overriding of the user depot, while still retaining access to resources that are bundled with Julia, like cache files, artifacts, etc. For example, to switch the user depot to /foo/bar just do

    export JULIA_DEPOT_PATH="/foo/bar:"

    All package operations, like cloning registrise or installing packages, will now write to /foo/bar, but since the empty entry is expanded to the default system depot, any bundled resources will still be available. If you really only want to use the depot at /foo/bar, and not load any bundled resources, simply set the environment variable to /foo/bar without the trailing colon.

    There are two exceptions to the above rule. First, if JULIA_DEPOT_PATH is set to the empty string, it expands to an empty DEPOT_PATH array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty depot path via the environment variable.

    Second, if no user depot is specified in JULIA_DEPOT_PATH, then the empty entry is expanded to the default depot including the user depot. This makes it possible to use the default depot, as if the environment variable was unset, by setting it to the string :.

    Note

    On Windows, path elements are separated by the ; character, as is the case with most path lists on Windows. Replace : with ; in the above paragraph.

    Note

    JULIA_DEPOT_PATH must be defined before starting julia; defining it in startup.jl is too late in the startup process; at that point you can instead directly modify the DEPOT_PATH array, which is populated from the environment variable.

    JULIA_HISTORY

    The absolute path REPL.find_hist_file() of the REPL's history file. If $JULIA_HISTORY is not set, then REPL.find_hist_file() defaults to

    $(DEPOT_PATH[1])/logs/repl_history.jl

    JULIA_MAX_NUM_PRECOMPILE_FILES

    Sets the maximum number of different instances of a single package that are to be stored in the precompile cache (default = 10).

    JULIA_VERBOSE_LINKING

    If set to true, linker commands will be displayed during precompilation.

    Pkg.jl

    JULIA_CI

    If set to true, this indicates to the package server that any package operations are part of a continuous integration (CI) system for the purposes of gathering package usage statistics.

    JULIA_NUM_PRECOMPILE_TASKS

    The number of parallel tasks to use when precompiling packages. See Pkg.precompile.

    JULIA_PKG_DEVDIR

    The default directory used by Pkg.develop for downloading packages.

    JULIA_PKG_IGNORE_HASHES

    If set to 1, this will ignore incorrect hashes in artifacts. This should be used carefully, as it disables verification of downloads, but can resolve issues when moving files across different types of file systems. See Pkg.jl issue #2317 for more details.

    Julia 1.6

    This is only supported in Julia 1.6 and above.

    JULIA_PKG_OFFLINE

    If set to true, this will enable offline mode: see Pkg.offline.

    Julia 1.5

    Pkg's offline mode requires Julia 1.5 or later.

    JULIA_PKG_PRECOMPILE_AUTO

    If set to 0, this will disable automatic precompilation by package actions which change the manifest. See Pkg.precompile.

    JULIA_PKG_SERVER

    Specifies the URL of the package registry to use. By default, Pkg uses https://pkg.julialang.org to fetch Julia packages. In addition, you can disable the use of the PkgServer protocol, and instead access the packages directly from their hosts (GitHub, GitLab, etc.) by setting: export JULIA_PKG_SERVER=""

    JULIA_PKG_SERVER_REGISTRY_PREFERENCE

    Specifies the preferred registry flavor. Currently supported values are conservative (the default), which will only publish resources that have been processed by the storage server (and thereby have a higher probability of being available from the PkgServers), whereas eager will publish registries whose resources have not necessarily been processed by the storage servers. Users behind restrictive firewalls that do not allow downloading from arbitrary servers should not use the eager flavor.

    Julia 1.7

    This only affects Julia 1.7 and above.

    JULIA_PKG_UNPACK_REGISTRY

    If set to true, this will unpack the registry instead of storing it as a compressed tarball.

    Julia 1.7

    This only affects Julia 1.7 and above. Earlier versions will always unpack the registry.

    JULIA_PKG_USE_CLI_GIT

    If set to true, Pkg operations which use the git protocol will use an external git executable instead of the default libgit2 library.

    Julia 1.7

    Use of the git executable is only supported on Julia 1.7 and above.

    JULIA_PKGRESOLVE_ACCURACY

    The accuracy of the package resolver. This should be a positive integer, the default is 1.

    JULIA_PKG_PRESERVE_TIERED_INSTALLED

    Change the default package installation strategy to Pkg.PRESERVE_TIERED_INSTALLED to let the package manager try to install versions of packages while keeping as many versions of packages already installed as possible.

    Julia 1.9

    This only affects Julia 1.9 and above.

    Network transport

    JULIA_NO_VERIFY_HOSTS

    JULIA_SSL_NO_VERIFY_HOSTS

    JULIA_SSH_NO_VERIFY_HOSTS

    JULIA_ALWAYS_VERIFY_HOSTS

    Specify hosts whose identity should or should not be verified for specific transport layers. See NetworkOptions.verify_host

    JULIA_SSL_CA_ROOTS_PATH

    Specify the file or directory containing the certificate authority roots. See NetworkOptions.ca_roots

    External applications

    JULIA_SHELL

    The absolute path of the shell with which Julia should execute external commands (via Base.repl_cmd()). Defaults to the environment variable $SHELL, and falls back to /bin/sh if $SHELL is unset.

    Note

    On Windows, this environment variable is ignored, and external commands are executed directly.

    JULIA_EDITOR

    The editor returned by InteractiveUtils.editor() and used in, e.g., InteractiveUtils.edit, referring to the command of the preferred editor, for instance vim.

    $JULIA_EDITOR takes precedence over $VISUAL, which in turn takes precedence over $EDITOR. If none of these environment variables is set, then the editor is taken to be open on Windows and OS X, or /etc/alternatives/editor if it exists, or emacs otherwise.

    To use Visual Studio Code on Windows, set $JULIA_EDITOR to code.cmd.

    Parallelization

    JULIA_CPU_THREADS

    Overrides the global variable Base.Sys.CPU_THREADS, the number of logical CPU cores available.

    JULIA_WORKER_TIMEOUT

    A Float64 that sets the value of Distributed.worker_timeout() (default: 60.0). This function gives the number of seconds a worker process will wait for a master process to establish a connection before dying.

    JULIA_NUM_THREADS

    An unsigned 64-bit integer (uint64_t) that sets the maximum number of threads available to Julia. If $JULIA_NUM_THREADS is not positive or is not set, or if the number of CPU threads cannot be determined through system calls, then the number of threads is set to 1.

    If $JULIA_NUM_THREADS is set to auto, then the number of threads will be set to the number of CPU threads.

    Note

    JULIA_NUM_THREADS must be defined before starting julia; defining it in startup.jl is too late in the startup process.

    Julia 1.5

    In Julia 1.5 and above the number of threads can also be specified on startup using the -t/--threads command line argument.

    Julia 1.7

    The auto value for $JULIA_NUM_THREADS requires Julia 1.7 or above.

    JULIA_THREAD_SLEEP_THRESHOLD

    If set to a string that starts with the case-insensitive substring "infinite", then spinning threads never sleep. Otherwise, $JULIA_THREAD_SLEEP_THRESHOLD is interpreted as an unsigned 64-bit integer (uint64_t) and gives, in nanoseconds, the amount of time after which spinning threads should sleep.

    JULIA_NUM_GC_THREADS

    Sets the number of threads used by Garbage Collection. If unspecified is set to half of the number of worker threads.

    Julia 1.10

    The environment variable was added in 1.10

    JULIA_IMAGE_THREADS

    An unsigned 32-bit integer that sets the number of threads used by image compilation in this Julia process. The value of this variable may be ignored if the module is a small module. If left unspecified, the smaller of the value of JULIA_CPU_THREADS or half the number of logical CPU cores is used in its place.

    JULIA_IMAGE_TIMINGS

    A boolean value that determines if detailed timing information is printed during during image compilation. Defaults to 0.

    JULIA_EXCLUSIVE

    If set to anything besides 0, then Julia's thread policy is consistent with running on a dedicated machine: the master thread is on proc 0, and threads are affinitized. Otherwise, Julia lets the operating system handle thread policy.

    REPL formatting

    Environment variables that determine how REPL output should be formatted at the terminal. Generally, these variables should be set to ANSI terminal escape sequences. Julia provides a high-level interface with much of the same functionality; see the section on The Julia REPL.

    JULIA_ERROR_COLOR

    The formatting Base.error_color() (default: light red, "\033[91m") that errors should have at the terminal.

    JULIA_WARN_COLOR

    The formatting Base.warn_color() (default: yellow, "\033[93m") that warnings should have at the terminal.

    JULIA_INFO_COLOR

    The formatting Base.info_color() (default: cyan, "\033[36m") that info should have at the terminal.

    JULIA_INPUT_COLOR

    The formatting Base.input_color() (default: normal, "\033[0m") that input should have at the terminal.

    JULIA_ANSWER_COLOR

    The formatting Base.answer_color() (default: normal, "\033[0m") that output should have at the terminal.

    System and Package Image Building

    JULIA_CPU_TARGET

    Modify the target machine architecture for (pre)compiling system and package images. JULIA_CPU_TARGET only affects machine code image generation being output to a disk cache. Unlike the --cpu-target, or -C, command line option, it does not influence just-in-time (JIT) code generation within a Julia session where machine code is only stored in memory.

    Valid values for JULIA_CPU_TARGET can be obtained by executing julia -C help.

    Setting JULIA_CPU_TARGET is important for heterogeneous compute systems where processors of distinct types or features may be present. This is commonly encountered in high performance computing (HPC) clusters since the component nodes may be using distinct processors.

    The CPU target string is a list of strings separated by ; each string starts with a CPU or architecture name and followed by an optional list of features separated by ,. A generic or empty CPU name means the basic required feature set of the target ISA which is at least the architecture the C/C++ runtime is compiled with. Each string is interpreted by LLVM.

    A few special features are supported:

    1. clone_all

      This forces the target to have all functions in sysimg cloned. When used in negative form (i.e. -clone_all), this disables full clone that's enabled by default for certain targets.

    2. base([0-9]*)

      This specifies the (0-based) base target index. The base target is the target that the current target is based on, i.e. the functions that are not being cloned will use the version in the base target. This option causes the base target to be fully cloned (as if clone_all is specified for it) if it is not the default target (0). The index can only be smaller than the current index.

    3. opt_size

      Optimize for size with minimum performance impact. Clang/GCC's -Os.

    4. min_size

      Optimize only for size. Clang's -Oz.

    Debugging and profiling

    JULIA_DEBUG

    Enable debug logging for a file or module, see Logging for more information.

    JULIA_PROFILE_PEEK_HEAP_SNAPSHOT

    Enable collecting of a heap snapshot during execution via the profiling peek mechanism. See Triggered During Execution.

    JULIA_TIMING_SUBSYSTEMS

    Allows you to enable or disable zones for a specific Julia run. For instance, setting the variable to +GC,-INFERENCE will enable the GC zones and disable the INFERENCE zones. See Dynamically Enabling and Disabling Zones.

    JULIA_GC_ALLOC_POOL

    JULIA_GC_ALLOC_OTHER

    JULIA_GC_ALLOC_PRINT

    If set, these environment variables take strings that optionally start with the character 'r', followed by a string interpolation of a colon-separated list of three signed 64-bit integers (int64_t). This triple of integers a:b:c represents the arithmetic sequence a, a + b, a + 2*b, ... c.

    • If it's the nth time that jl_gc_pool_alloc() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_POOL, then garbage collection is forced.
    • If it's the nth time that maybe_collect() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_OTHER, then garbage collection is forced.
    • If it's the nth time that jl_gc_collect() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_PRINT, then counts for the number of calls to jl_gc_pool_alloc() and maybe_collect() are printed.

    If the value of the environment variable begins with the character 'r', then the interval between garbage collection events is randomized.

    Note

    These environment variables only have an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).

    JULIA_GC_NO_GENERATIONAL

    If set to anything besides 0, then the Julia garbage collector never performs "quick sweeps" of memory.

    Note

    This environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).

    JULIA_GC_WAIT_FOR_DEBUGGER

    If set to anything besides 0, then the Julia garbage collector will wait for a debugger to attach instead of aborting whenever there's a critical error.

    Note

    This environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).

    ENABLE_JITPROFILING

    If set to anything besides 0, then the compiler will create and register an event listener for just-in-time (JIT) profiling.

    Note

    This environment variable only has an effect if Julia was compiled with JIT profiling support, using either

    • Intel's VTune™ Amplifier (USE_INTEL_JITEVENTS set to 1 in the build configuration), or
    • OProfile (USE_OPROFILE_JITEVENTS set to 1 in the build configuration).
    • Perf (USE_PERF_JITEVENTS set to 1 in the build configuration). This integration is enabled by default.

    ENABLE_GDBLISTENER

    If set to anything besides 0 enables GDB registration of Julia code on release builds. On debug builds of Julia this is always enabled. Recommended to use with -g 2.

    JULIA_LLVM_ARGS

    Arguments to be passed to the LLVM backend.

    JULIA_FALLBACK_REPL

    Forces the fallback repl instead of REPL.jl.

    +$JULIA_BINDIR/../etc/julia/startup.jl

    by default (via Base.load_julia_startup()).

    For example, a Linux installation with a Julia executable located at /bin/julia, a DATAROOTDIR of ../share, and a SYSCONFDIR of ../etc will have JULIA_BINDIR set to /bin, a source-file search path of

    /share/julia/base

    and a global configuration search path of

    /etc/julia/startup.jl

    JULIA_PROJECT

    A directory path that indicates which project should be the initial active project. Setting this environment variable has the same effect as specifying the --project start-up option, but --project has higher precedence. If the variable is set to @. (note the trailing dot) then Julia tries to find a project directory that contains Project.toml or JuliaProject.toml file from the current directory and its parents. See also the chapter on Code Loading.

    Note

    JULIA_PROJECT must be defined before starting julia; defining it in startup.jl is too late in the startup process.

    JULIA_LOAD_PATH

    The JULIA_LOAD_PATH environment variable is used to populate the global Julia LOAD_PATH variable, which determines which packages can be loaded via import and using (see Code Loading).

    Unlike the shell PATH variable, empty entries in JULIA_LOAD_PATH are expanded to the default value of LOAD_PATH, ["@", "@v#.#", "@stdlib"] when populating LOAD_PATH. This allows easy appending, prepending, etc. of the load path value in shell scripts regardless of whether JULIA_LOAD_PATH is already set or not. For example, to prepend the directory /foo/bar to LOAD_PATH just do

    export JULIA_LOAD_PATH="/foo/bar:$JULIA_LOAD_PATH"

    If the JULIA_LOAD_PATH environment variable is already set, its old value will be prepended with /foo/bar. On the other hand, if JULIA_LOAD_PATH is not set, then it will be set to /foo/bar: which will expand to a LOAD_PATH value of ["/foo/bar", "@", "@v#.#", "@stdlib"]. If JULIA_LOAD_PATH is set to the empty string, it expands to an empty LOAD_PATH array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty load path via the environment variable. If you want the default load path, either unset the environment variable or if it must have a value, set it to the string :.

    Note

    On Windows, path elements are separated by the ; character, as is the case with most path lists on Windows. Replace : with ; in the above paragraph.

    JULIA_DEPOT_PATH

    The JULIA_DEPOT_PATH environment variable is used to populate the global Julia DEPOT_PATH variable, which controls where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, configuration files, and the default location of the REPL's history file.

    Unlike the shell PATH variable but similar to JULIA_LOAD_PATH, empty entries in JULIA_DEPOT_PATH are expanded to the default value of DEPOT_PATH, excluding the user depot. This allows easy overriding of the user depot, while still retaining access to resources that are bundled with Julia, like cache files, artifacts, etc. For example, to switch the user depot to /foo/bar just do

    export JULIA_DEPOT_PATH="/foo/bar:"

    All package operations, like cloning registrise or installing packages, will now write to /foo/bar, but since the empty entry is expanded to the default system depot, any bundled resources will still be available. If you really only want to use the depot at /foo/bar, and not load any bundled resources, simply set the environment variable to /foo/bar without the trailing colon.

    There are two exceptions to the above rule. First, if JULIA_DEPOT_PATH is set to the empty string, it expands to an empty DEPOT_PATH array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty depot path via the environment variable.

    Second, if no user depot is specified in JULIA_DEPOT_PATH, then the empty entry is expanded to the default depot including the user depot. This makes it possible to use the default depot, as if the environment variable was unset, by setting it to the string :.

    Note

    On Windows, path elements are separated by the ; character, as is the case with most path lists on Windows. Replace : with ; in the above paragraph.

    Note

    JULIA_DEPOT_PATH must be defined before starting julia; defining it in startup.jl is too late in the startup process; at that point you can instead directly modify the DEPOT_PATH array, which is populated from the environment variable.

    JULIA_HISTORY

    The absolute path REPL.find_hist_file() of the REPL's history file. If $JULIA_HISTORY is not set, then REPL.find_hist_file() defaults to

    $(DEPOT_PATH[1])/logs/repl_history.jl

    JULIA_MAX_NUM_PRECOMPILE_FILES

    Sets the maximum number of different instances of a single package that are to be stored in the precompile cache (default = 10).

    JULIA_VERBOSE_LINKING

    If set to true, linker commands will be displayed during precompilation.

    Pkg.jl

    JULIA_CI

    If set to true, this indicates to the package server that any package operations are part of a continuous integration (CI) system for the purposes of gathering package usage statistics.

    JULIA_NUM_PRECOMPILE_TASKS

    The number of parallel tasks to use when precompiling packages. See Pkg.precompile.

    JULIA_PKG_DEVDIR

    The default directory used by Pkg.develop for downloading packages.

    JULIA_PKG_IGNORE_HASHES

    If set to 1, this will ignore incorrect hashes in artifacts. This should be used carefully, as it disables verification of downloads, but can resolve issues when moving files across different types of file systems. See Pkg.jl issue #2317 for more details.

    Julia 1.6

    This is only supported in Julia 1.6 and above.

    JULIA_PKG_OFFLINE

    If set to true, this will enable offline mode: see Pkg.offline.

    Julia 1.5

    Pkg's offline mode requires Julia 1.5 or later.

    JULIA_PKG_PRECOMPILE_AUTO

    If set to 0, this will disable automatic precompilation by package actions which change the manifest. See Pkg.precompile.

    JULIA_PKG_SERVER

    Specifies the URL of the package registry to use. By default, Pkg uses https://pkg.julialang.org to fetch Julia packages. In addition, you can disable the use of the PkgServer protocol, and instead access the packages directly from their hosts (GitHub, GitLab, etc.) by setting: export JULIA_PKG_SERVER=""

    JULIA_PKG_SERVER_REGISTRY_PREFERENCE

    Specifies the preferred registry flavor. Currently supported values are conservative (the default), which will only publish resources that have been processed by the storage server (and thereby have a higher probability of being available from the PkgServers), whereas eager will publish registries whose resources have not necessarily been processed by the storage servers. Users behind restrictive firewalls that do not allow downloading from arbitrary servers should not use the eager flavor.

    Julia 1.7

    This only affects Julia 1.7 and above.

    JULIA_PKG_UNPACK_REGISTRY

    If set to true, this will unpack the registry instead of storing it as a compressed tarball.

    Julia 1.7

    This only affects Julia 1.7 and above. Earlier versions will always unpack the registry.

    JULIA_PKG_USE_CLI_GIT

    If set to true, Pkg operations which use the git protocol will use an external git executable instead of the default libgit2 library.

    Julia 1.7

    Use of the git executable is only supported on Julia 1.7 and above.

    JULIA_PKGRESOLVE_ACCURACY

    The accuracy of the package resolver. This should be a positive integer, the default is 1.

    JULIA_PKG_PRESERVE_TIERED_INSTALLED

    Change the default package installation strategy to Pkg.PRESERVE_TIERED_INSTALLED to let the package manager try to install versions of packages while keeping as many versions of packages already installed as possible.

    Julia 1.9

    This only affects Julia 1.9 and above.

    Network transport

    JULIA_NO_VERIFY_HOSTS

    JULIA_SSL_NO_VERIFY_HOSTS

    JULIA_SSH_NO_VERIFY_HOSTS

    JULIA_ALWAYS_VERIFY_HOSTS

    Specify hosts whose identity should or should not be verified for specific transport layers. See NetworkOptions.verify_host

    JULIA_SSL_CA_ROOTS_PATH

    Specify the file or directory containing the certificate authority roots. See NetworkOptions.ca_roots

    External applications

    JULIA_SHELL

    The absolute path of the shell with which Julia should execute external commands (via Base.repl_cmd()). Defaults to the environment variable $SHELL, and falls back to /bin/sh if $SHELL is unset.

    Note

    On Windows, this environment variable is ignored, and external commands are executed directly.

    JULIA_EDITOR

    The editor returned by InteractiveUtils.editor() and used in, e.g., InteractiveUtils.edit, referring to the command of the preferred editor, for instance vim.

    $JULIA_EDITOR takes precedence over $VISUAL, which in turn takes precedence over $EDITOR. If none of these environment variables is set, then the editor is taken to be open on Windows and OS X, or /etc/alternatives/editor if it exists, or emacs otherwise.

    To use Visual Studio Code on Windows, set $JULIA_EDITOR to code.cmd.

    Parallelization

    JULIA_CPU_THREADS

    Overrides the global variable Base.Sys.CPU_THREADS, the number of logical CPU cores available.

    JULIA_WORKER_TIMEOUT

    A Float64 that sets the value of Distributed.worker_timeout() (default: 60.0). This function gives the number of seconds a worker process will wait for a master process to establish a connection before dying.

    JULIA_NUM_THREADS

    An unsigned 64-bit integer (uint64_t) that sets the maximum number of threads available to Julia. If $JULIA_NUM_THREADS is not positive or is not set, or if the number of CPU threads cannot be determined through system calls, then the number of threads is set to 1.

    If $JULIA_NUM_THREADS is set to auto, then the number of threads will be set to the number of CPU threads.

    Note

    JULIA_NUM_THREADS must be defined before starting julia; defining it in startup.jl is too late in the startup process.

    Julia 1.5

    In Julia 1.5 and above the number of threads can also be specified on startup using the -t/--threads command line argument.

    Julia 1.7

    The auto value for $JULIA_NUM_THREADS requires Julia 1.7 or above.

    JULIA_THREAD_SLEEP_THRESHOLD

    If set to a string that starts with the case-insensitive substring "infinite", then spinning threads never sleep. Otherwise, $JULIA_THREAD_SLEEP_THRESHOLD is interpreted as an unsigned 64-bit integer (uint64_t) and gives, in nanoseconds, the amount of time after which spinning threads should sleep.

    JULIA_NUM_GC_THREADS

    Sets the number of threads used by Garbage Collection. If unspecified is set to half of the number of worker threads.

    Julia 1.10

    The environment variable was added in 1.10

    JULIA_IMAGE_THREADS

    An unsigned 32-bit integer that sets the number of threads used by image compilation in this Julia process. The value of this variable may be ignored if the module is a small module. If left unspecified, the smaller of the value of JULIA_CPU_THREADS or half the number of logical CPU cores is used in its place.

    JULIA_IMAGE_TIMINGS

    A boolean value that determines if detailed timing information is printed during during image compilation. Defaults to 0.

    JULIA_EXCLUSIVE

    If set to anything besides 0, then Julia's thread policy is consistent with running on a dedicated machine: the master thread is on proc 0, and threads are affinitized. Otherwise, Julia lets the operating system handle thread policy.

    REPL formatting

    Environment variables that determine how REPL output should be formatted at the terminal. Generally, these variables should be set to ANSI terminal escape sequences. Julia provides a high-level interface with much of the same functionality; see the section on The Julia REPL.

    JULIA_ERROR_COLOR

    The formatting Base.error_color() (default: light red, "\033[91m") that errors should have at the terminal.

    JULIA_WARN_COLOR

    The formatting Base.warn_color() (default: yellow, "\033[93m") that warnings should have at the terminal.

    JULIA_INFO_COLOR

    The formatting Base.info_color() (default: cyan, "\033[36m") that info should have at the terminal.

    JULIA_INPUT_COLOR

    The formatting Base.input_color() (default: normal, "\033[0m") that input should have at the terminal.

    JULIA_ANSWER_COLOR

    The formatting Base.answer_color() (default: normal, "\033[0m") that output should have at the terminal.

    System and Package Image Building

    JULIA_CPU_TARGET

    Modify the target machine architecture for (pre)compiling system and package images. JULIA_CPU_TARGET only affects machine code image generation being output to a disk cache. Unlike the --cpu-target, or -C, command line option, it does not influence just-in-time (JIT) code generation within a Julia session where machine code is only stored in memory.

    Valid values for JULIA_CPU_TARGET can be obtained by executing julia -C help.

    Setting JULIA_CPU_TARGET is important for heterogeneous compute systems where processors of distinct types or features may be present. This is commonly encountered in high performance computing (HPC) clusters since the component nodes may be using distinct processors.

    The CPU target string is a list of strings separated by ; each string starts with a CPU or architecture name and followed by an optional list of features separated by ,. A generic or empty CPU name means the basic required feature set of the target ISA which is at least the architecture the C/C++ runtime is compiled with. Each string is interpreted by LLVM.

    A few special features are supported:

    1. clone_all

      This forces the target to have all functions in sysimg cloned. When used in negative form (i.e. -clone_all), this disables full clone that's enabled by default for certain targets.

    2. base([0-9]*)

      This specifies the (0-based) base target index. The base target is the target that the current target is based on, i.e. the functions that are not being cloned will use the version in the base target. This option causes the base target to be fully cloned (as if clone_all is specified for it) if it is not the default target (0). The index can only be smaller than the current index.

    3. opt_size

      Optimize for size with minimum performance impact. Clang/GCC's -Os.

    4. min_size

      Optimize only for size. Clang's -Oz.

    Debugging and profiling

    JULIA_DEBUG

    Enable debug logging for a file or module, see Logging for more information.

    JULIA_PROFILE_PEEK_HEAP_SNAPSHOT

    Enable collecting of a heap snapshot during execution via the profiling peek mechanism. See Triggered During Execution.

    JULIA_TIMING_SUBSYSTEMS

    Allows you to enable or disable zones for a specific Julia run. For instance, setting the variable to +GC,-INFERENCE will enable the GC zones and disable the INFERENCE zones. See Dynamically Enabling and Disabling Zones.

    JULIA_GC_ALLOC_POOL

    JULIA_GC_ALLOC_OTHER

    JULIA_GC_ALLOC_PRINT

    If set, these environment variables take strings that optionally start with the character 'r', followed by a string interpolation of a colon-separated list of three signed 64-bit integers (int64_t). This triple of integers a:b:c represents the arithmetic sequence a, a + b, a + 2*b, ... c.

    If the value of the environment variable begins with the character 'r', then the interval between garbage collection events is randomized.

    Note

    These environment variables only have an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).

    JULIA_GC_NO_GENERATIONAL

    If set to anything besides 0, then the Julia garbage collector never performs "quick sweeps" of memory.

    Note

    This environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).

    JULIA_GC_WAIT_FOR_DEBUGGER

    If set to anything besides 0, then the Julia garbage collector will wait for a debugger to attach instead of aborting whenever there's a critical error.

    Note

    This environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).

    ENABLE_JITPROFILING

    If set to anything besides 0, then the compiler will create and register an event listener for just-in-time (JIT) profiling.

    Note

    This environment variable only has an effect if Julia was compiled with JIT profiling support, using either

    ENABLE_GDBLISTENER

    If set to anything besides 0 enables GDB registration of Julia code on release builds. On debug builds of Julia this is always enabled. Recommended to use with -g 2.

    JULIA_LLVM_ARGS

    Arguments to be passed to the LLVM backend.

    JULIA_FALLBACK_REPL

    Forces the fallback repl instead of REPL.jl.

    diff --git a/en/v1.12-dev/manual/faq/index.html b/en/v1.12-dev/manual/faq/index.html index 09222da331d0..20fbd3b49952 100644 --- a/en/v1.12-dev/manual/faq/index.html +++ b/en/v1.12-dev/manual/faq/index.html @@ -328,4 +328,4 @@ A = randn(1000, 1000) B = randn(1000, 1000) @btime $A \ $B -@btime $A * $B

    can be different when compared to other languages like Matlab or R.

    Since operations like this are very thin wrappers over the relevant BLAS functions, the reason for the discrepancy is very likely to be

    1. the BLAS library each language is using,

    2. the number of concurrent threads.

    Julia compiles and uses its own copy of OpenBLAS, with threads currently capped at 8 (or the number of your cores).

    Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg Intel MKL, may provide performance improvements. You can use MKL.jl, a package that makes Julia's linear algebra use Intel MKL BLAS and LAPACK instead of OpenBLAS, or search the discussion forum for suggestions on how to set this up manually. Note that Intel MKL cannot be bundled with Julia, as it is not open source.

    Computing cluster

    How do I manage precompilation caches in distributed file systems?

    When using Julia in high-performance computing (HPC) facilities with shared filesystems, it is recommended to use a shared depot (via the JULIA_DEPOT_PATH environment variable). Since Julia v1.10, multiple Julia processes on functionally similar workers and using the same depot will coordinate via pidfile locks to only spend effort precompiling on one process while the others wait. The precompilation process will indicate when the process is precompiling or waiting for another that is precompiling. If non-interactive the messages are via @debug.

    However, due to caching of binary code, the cache rejection since v1.9 is more strict and users may need to set the JULIA_CPU_TARGET environment variable appropriately to get a single cache that is usable throughout the HPC environment.

    Julia Releases

    Do I want to use the Stable, LTS, or nightly version of Julia?

    The Stable version of Julia is the latest released version of Julia, this is the version most people will want to run. It has the latest features, including improved performance. The Stable version of Julia is versioned according to SemVer as v1.x.y. A new minor release of Julia corresponding to a new Stable version is made approximately every 4-5 months after a few weeks of testing as a release candidate. Unlike the LTS version the Stable version will not normally receive bugfixes after another Stable version of Julia has been released. However, upgrading to the next Stable release will always be possible as each release of Julia v1.x will continue to run code written for earlier versions.

    You may prefer the LTS (Long Term Support) version of Julia if you are looking for a very stable code base. The current LTS version of Julia is versioned according to SemVer as v1.6.x; this branch will continue to receive bugfixes until a new LTS branch is chosen, at which point the v1.6.x series will no longer received regular bug fixes and all but the most conservative users will be advised to upgrade to the new LTS version series. As a package developer, you may prefer to develop for the LTS version, to maximize the number of users who can use your package. As per SemVer, code written for v1.0 will continue to work for all future LTS and Stable versions. In general, even if targeting the LTS, one can develop and run code in the latest Stable version, to take advantage of the improved performance; so long as one avoids using new features (such as added library functions or new methods).

    You may prefer the nightly version of Julia if you want to take advantage of the latest updates to the language, and don't mind if the version available today occasionally doesn't actually work. As the name implies, releases to the nightly version are made roughly every night (depending on build infrastructure stability). In general nightly released are fairly safe to use—your code will not catch on fire. However, they may be occasional regressions and or issues that will not be found until more thorough pre-release testing. You may wish to test against the nightly version to ensure that such regressions that affect your use case are caught before a release is made.

    Finally, you may also consider building Julia from source for yourself. This option is mainly for those individuals who are comfortable at the command line, or interested in learning. If this describes you, you may also be interested in reading our guidelines for contributing.

    Links to each of these download types can be found on the download page at https://julialang.org/downloads/. Note that not all versions of Julia are available for all platforms.

    How can I transfer the list of installed packages after updating my version of Julia?

    Each minor version of julia has its own default environment. As a result, upon installing a new minor version of Julia, the packages you added using the previous minor version will not be available by default. The environment for a given julia version is defined by the files Project.toml and Manifest.toml in a folder matching the version number in .julia/environments/, for instance, .julia/environments/v1.3.

    If you install a new minor version of Julia, say 1.4, and want to use in its default environment the same packages as in a previous version (e.g. 1.3), you can copy the contents of the file Project.toml from the 1.3 folder to 1.4. Then, in a session of the new Julia version, enter the "package management mode" by typing the key ], and run the command instantiate.

    This operation will resolve a set of feasible packages from the copied file that are compatible with the target Julia version, and will install or update them if suitable. If you want to reproduce not only the set of packages, but also the versions you were using in the previous Julia version, you should also copy the Manifest.toml file before running the Pkg command instantiate. However, note that packages may define compatibility constraints that may be affected by changing the version of Julia, so the exact set of versions you had in 1.3 may not work for 1.4.

    +@btime $A * $B

    can be different when compared to other languages like Matlab or R.

    Since operations like this are very thin wrappers over the relevant BLAS functions, the reason for the discrepancy is very likely to be

    1. the BLAS library each language is using,

    2. the number of concurrent threads.

    Julia compiles and uses its own copy of OpenBLAS, with threads currently capped at 8 (or the number of your cores).

    Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg Intel MKL, may provide performance improvements. You can use MKL.jl, a package that makes Julia's linear algebra use Intel MKL BLAS and LAPACK instead of OpenBLAS, or search the discussion forum for suggestions on how to set this up manually. Note that Intel MKL cannot be bundled with Julia, as it is not open source.

    Computing cluster

    How do I manage precompilation caches in distributed file systems?

    When using Julia in high-performance computing (HPC) facilities with shared filesystems, it is recommended to use a shared depot (via the JULIA_DEPOT_PATH environment variable). Since Julia v1.10, multiple Julia processes on functionally similar workers and using the same depot will coordinate via pidfile locks to only spend effort precompiling on one process while the others wait. The precompilation process will indicate when the process is precompiling or waiting for another that is precompiling. If non-interactive the messages are via @debug.

    However, due to caching of binary code, the cache rejection since v1.9 is more strict and users may need to set the JULIA_CPU_TARGET environment variable appropriately to get a single cache that is usable throughout the HPC environment.

    Julia Releases

    Do I want to use the Stable, LTS, or nightly version of Julia?

    The Stable version of Julia is the latest released version of Julia, this is the version most people will want to run. It has the latest features, including improved performance. The Stable version of Julia is versioned according to SemVer as v1.x.y. A new minor release of Julia corresponding to a new Stable version is made approximately every 4-5 months after a few weeks of testing as a release candidate. Unlike the LTS version the Stable version will not normally receive bugfixes after another Stable version of Julia has been released. However, upgrading to the next Stable release will always be possible as each release of Julia v1.x will continue to run code written for earlier versions.

    You may prefer the LTS (Long Term Support) version of Julia if you are looking for a very stable code base. The current LTS version of Julia is versioned according to SemVer as v1.6.x; this branch will continue to receive bugfixes until a new LTS branch is chosen, at which point the v1.6.x series will no longer received regular bug fixes and all but the most conservative users will be advised to upgrade to the new LTS version series. As a package developer, you may prefer to develop for the LTS version, to maximize the number of users who can use your package. As per SemVer, code written for v1.0 will continue to work for all future LTS and Stable versions. In general, even if targeting the LTS, one can develop and run code in the latest Stable version, to take advantage of the improved performance; so long as one avoids using new features (such as added library functions or new methods).

    You may prefer the nightly version of Julia if you want to take advantage of the latest updates to the language, and don't mind if the version available today occasionally doesn't actually work. As the name implies, releases to the nightly version are made roughly every night (depending on build infrastructure stability). In general nightly released are fairly safe to use—your code will not catch on fire. However, they may be occasional regressions and or issues that will not be found until more thorough pre-release testing. You may wish to test against the nightly version to ensure that such regressions that affect your use case are caught before a release is made.

    Finally, you may also consider building Julia from source for yourself. This option is mainly for those individuals who are comfortable at the command line, or interested in learning. If this describes you, you may also be interested in reading our guidelines for contributing.

    Links to each of these download types can be found on the download page at https://julialang.org/downloads/. Note that not all versions of Julia are available for all platforms.

    How can I transfer the list of installed packages after updating my version of Julia?

    Each minor version of julia has its own default environment. As a result, upon installing a new minor version of Julia, the packages you added using the previous minor version will not be available by default. The environment for a given julia version is defined by the files Project.toml and Manifest.toml in a folder matching the version number in .julia/environments/, for instance, .julia/environments/v1.3.

    If you install a new minor version of Julia, say 1.4, and want to use in its default environment the same packages as in a previous version (e.g. 1.3), you can copy the contents of the file Project.toml from the 1.3 folder to 1.4. Then, in a session of the new Julia version, enter the "package management mode" by typing the key ], and run the command instantiate.

    This operation will resolve a set of feasible packages from the copied file that are compatible with the target Julia version, and will install or update them if suitable. If you want to reproduce not only the set of packages, but also the versions you were using in the previous Julia version, you should also copy the Manifest.toml file before running the Pkg command instantiate. However, note that packages may define compatibility constraints that may be affected by changing the version of Julia, so the exact set of versions you had in 1.3 may not work for 1.4.

    diff --git a/en/v1.12-dev/manual/functions/index.html b/en/v1.12-dev/manual/functions/index.html index 9b8ed0805301..89dab7a280ba 100644 --- a/en/v1.12-dev/manual/functions/index.html +++ b/en/v1.12-dev/manual/functions/index.html @@ -418,4 +418,4 @@ 0.5 6 -4 - true

    All functions in the fused broadcast are always called for every element of the result. Thus X .+ σ .* randn.() will add a mask of independent and identically sampled random values to each element of the array X, but X .+ σ .* randn() will add the same random sample to each element. In cases where the fused computation is constant along one or more axes of the broadcast iteration, it may be possible to leverage a space-time tradeoff and allocate intermediate values to reduce the number of computations. See more at performance tips.

    Further Reading

    We should mention here that this is far from a complete picture of defining functions. Julia has a sophisticated type system and allows multiple dispatch on argument types. None of the examples given here provide any type annotations on their arguments, meaning that they are applicable to all types of arguments. The type system is described in Types and defining a function in terms of methods chosen by multiple dispatch on run-time argument types is described in Methods.

    + true

    All functions in the fused broadcast are always called for every element of the result. Thus X .+ σ .* randn.() will add a mask of independent and identically sampled random values to each element of the array X, but X .+ σ .* randn() will add the same random sample to each element. In cases where the fused computation is constant along one or more axes of the broadcast iteration, it may be possible to leverage a space-time tradeoff and allocate intermediate values to reduce the number of computations. See more at performance tips.

    Further Reading

    We should mention here that this is far from a complete picture of defining functions. Julia has a sophisticated type system and allows multiple dispatch on argument types. None of the examples given here provide any type annotations on their arguments, meaning that they are applicable to all types of arguments. The type system is described in Types and defining a function in terms of methods chosen by multiple dispatch on run-time argument types is described in Methods.

    diff --git a/en/v1.12-dev/manual/getting-started/index.html b/en/v1.12-dev/manual/getting-started/index.html index 957042b21216..4659fb11b5f1 100644 --- a/en/v1.12-dev/manual/getting-started/index.html +++ b/en/v1.12-dev/manual/getting-started/index.html @@ -10,8 +10,8 @@ (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | - | | |_| | | | (_| | | Version 1.12.0-DEV.246 (2024-03-26) - _/ |\__'_|_|_|\__'_| | Commit 86a697c7fea (0 days old master) + | | |_| | | | (_| | | Version 1.12.0-DEV.247 (2024-03-26) + _/ |\__'_|_|_|\__'_| | Commit 64de065a183 (0 days old master) |__/ | @@ -24,4 +24,4 @@ begin - begin...end denotes a block of code.

    If you already know Julia a bit, you might want to peek ahead at Performance Tips and Workflow Tips.

    + begin...end denotes a block of code.

    If you already know Julia a bit, you might want to peek ahead at Performance Tips and Workflow Tips.

    diff --git a/en/v1.12-dev/manual/handling-operating-system-variation/index.html b/en/v1.12-dev/manual/handling-operating-system-variation/index.html index c96018719f1c..05f3a28f1b1d 100644 --- a/en/v1.12-dev/manual/handling-operating-system-variation/index.html +++ b/en/v1.12-dev/manual/handling-operating-system-variation/index.html @@ -11,4 +11,4 @@ apple_specific_thing(a) else generic_thing(a) -end

    When nesting conditionals, the @static must be repeated for each level (parentheses optional, but recommended for readability):

    @static Sys.iswindows() ? :a : (@static Sys.isapple() ? :b : :c)
    +end

    When nesting conditionals, the @static must be repeated for each level (parentheses optional, but recommended for readability):

    @static Sys.iswindows() ? :a : (@static Sys.isapple() ? :b : :c)
    diff --git a/en/v1.12-dev/manual/installation/index.html b/en/v1.12-dev/manual/installation/index.html index dd868b961dfe..6f5013dec5fd 100644 --- a/en/v1.12-dev/manual/installation/index.html +++ b/en/v1.12-dev/manual/installation/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Installation

    There are many ways to install Julia. The following sections highlight the recommended method for each of the main supported platforms, and then present alternative ways that might be useful in specialized situations.

    The current installation recommendation is a solution based on Juliaup. If you installed Julia previously with a method that is not based on Juliaup and want to switch your system to an installation that is based on Juliaup, we recommend that you uninstall all previous Julia versions, ensure that you remove anything Julia related from your PATH variable and then install Julia with one of the methods described below.

    Windows

    On Windows Julia can be installed directly from the Windows store here. One can also install exactly the same version by executing

    winget install julia -s msstore

    in any shell.

    Mac and Linux

    Julia can be installed on Linux or Mac by executing

    curl -fsSL https://install.julialang.org | sh

    in a shell.

    Command line arguments

    One can pass various command line arguments to the Julia installer. The syntax for installer arguments is

    curl -fsSL https://install.julialang.org | sh -s -- <ARGS>

    Here <ARGS> should be replaced with one or more of the following arguments:

    • --yes (or -y): Run the installer in a non-interactive mode. All

    configuration values use their default or a value supplied as a command line argument.

    • --default-channel=<NAME>: Configure the default Juliaup channel. For

    example --default-channel lts would install the lts channel and configure it as the default.

    • --add-to-path=<yes|no>: Configure whether Julia should be added to the PATH

    environment variable. Valid values are yes (default) and no.

    • --background-selfupdate=<SECONDS>: Configure an optional CRON job that

    auto-updates Juliaup if <SECONDS> has a value larger than 0. The actual value controls how often the CRON job will run to check for a new Juliaup version in seconds. The default value is 0, i.e. no CRON job will be created.

    • --startup-selfupdate=<MINUTES>: Configure how often Julia will check for new

    versions of Juliaup when Julia is started. The default is every 1440 minutes.

    • -p=<PATH> (or --path): Configure where the Julia and Juliaup binaries are

    installed. The default is ~/.juliaup.

    Alternative installation methods

    Note that we recommend the following methods only if none of the installation methods described above work for your system.

    Some of the installation methods described below recommend installing a package called juliaup. Note that this nevertheless installs a fully functional Julia system, not just Juliaup.

    App Installer (Windows)

    If the Windows Store is blocked on a system, we have an alternative MSIX App Installer based setup. To use the App Installer version, download this file and open it by double clicking on it.

    MSI Installer (Windows)

    If neither the Windows Store nor the App Installer version work on your Windows system, you can also use a MSI based installer. Note that this installation methods comes with serious limitations and is generally not recommended unless no other method works. For example, there is no automatic update mechanism for Juliaup with this installation method. The 64 bit version of the MSI installer can be downloaded from here and the 32 bit version from here.

    By default the install will be a per-user install that does not require elevation. You can also do a system install by running the following command from a shell:

    msiexec /i <PATH_TO_JULIA_MSI> ALLUSERS=1

    Homebrew (Mac and Linux)

    On systems with brew, you can install Julia by running

    brew install juliaup

    in a shell. Note that you will have to update Juliaup with standard brew commands.

    Arch Linux - AUR (Linux)

    On Arch Linux, Juliaup is available in the Arch User Repository (AUR).

    openSUSE Tumbleweed (Linux)

    On openSUSE Tumbleweed, you can install Julia by running

    zypper install juliaup

    in a shell with root privileges.

    cargo (Windows, Mac and Linux)

    To install Julia via Rust's cargo, run:

    cargo install juliaup
    +

    Installation

    There are many ways to install Julia. The following sections highlight the recommended method for each of the main supported platforms, and then present alternative ways that might be useful in specialized situations.

    The current installation recommendation is a solution based on Juliaup. If you installed Julia previously with a method that is not based on Juliaup and want to switch your system to an installation that is based on Juliaup, we recommend that you uninstall all previous Julia versions, ensure that you remove anything Julia related from your PATH variable and then install Julia with one of the methods described below.

    Windows

    On Windows Julia can be installed directly from the Windows store here. One can also install exactly the same version by executing

    winget install julia -s msstore

    in any shell.

    Mac and Linux

    Julia can be installed on Linux or Mac by executing

    curl -fsSL https://install.julialang.org | sh

    in a shell.

    Command line arguments

    One can pass various command line arguments to the Julia installer. The syntax for installer arguments is

    curl -fsSL https://install.julialang.org | sh -s -- <ARGS>

    Here <ARGS> should be replaced with one or more of the following arguments:

    • --yes (or -y): Run the installer in a non-interactive mode. All

    configuration values use their default or a value supplied as a command line argument.

    • --default-channel=<NAME>: Configure the default Juliaup channel. For

    example --default-channel lts would install the lts channel and configure it as the default.

    • --add-to-path=<yes|no>: Configure whether Julia should be added to the PATH

    environment variable. Valid values are yes (default) and no.

    • --background-selfupdate=<SECONDS>: Configure an optional CRON job that

    auto-updates Juliaup if <SECONDS> has a value larger than 0. The actual value controls how often the CRON job will run to check for a new Juliaup version in seconds. The default value is 0, i.e. no CRON job will be created.

    • --startup-selfupdate=<MINUTES>: Configure how often Julia will check for new

    versions of Juliaup when Julia is started. The default is every 1440 minutes.

    • -p=<PATH> (or --path): Configure where the Julia and Juliaup binaries are

    installed. The default is ~/.juliaup.

    Alternative installation methods

    Note that we recommend the following methods only if none of the installation methods described above work for your system.

    Some of the installation methods described below recommend installing a package called juliaup. Note that this nevertheless installs a fully functional Julia system, not just Juliaup.

    App Installer (Windows)

    If the Windows Store is blocked on a system, we have an alternative MSIX App Installer based setup. To use the App Installer version, download this file and open it by double clicking on it.

    MSI Installer (Windows)

    If neither the Windows Store nor the App Installer version work on your Windows system, you can also use a MSI based installer. Note that this installation methods comes with serious limitations and is generally not recommended unless no other method works. For example, there is no automatic update mechanism for Juliaup with this installation method. The 64 bit version of the MSI installer can be downloaded from here and the 32 bit version from here.

    By default the install will be a per-user install that does not require elevation. You can also do a system install by running the following command from a shell:

    msiexec /i <PATH_TO_JULIA_MSI> ALLUSERS=1

    Homebrew (Mac and Linux)

    On systems with brew, you can install Julia by running

    brew install juliaup

    in a shell. Note that you will have to update Juliaup with standard brew commands.

    Arch Linux - AUR (Linux)

    On Arch Linux, Juliaup is available in the Arch User Repository (AUR).

    openSUSE Tumbleweed (Linux)

    On openSUSE Tumbleweed, you can install Julia by running

    zypper install juliaup

    in a shell with root privileges.

    cargo (Windows, Mac and Linux)

    To install Julia via Rust's cargo, run:

    cargo install juliaup
    diff --git a/en/v1.12-dev/manual/integers-and-floating-point-numbers/index.html b/en/v1.12-dev/manual/integers-and-floating-point-numbers/index.html index f957a95ea406..2789f522897d 100644 --- a/en/v1.12-dev/manual/integers-and-floating-point-numbers/index.html +++ b/en/v1.12-dev/manual/integers-and-floating-point-numbers/index.html @@ -327,4 +327,4 @@ 1 julia> one(BigFloat) -1.0 +1.0 diff --git a/en/v1.12-dev/manual/interfaces/index.html b/en/v1.12-dev/manual/interfaces/index.html index e2598aafb941..37eda24d1b19 100644 --- a/en/v1.12-dev/manual/interfaces/index.html +++ b/en/v1.12-dev/manual/interfaces/index.html @@ -263,4 +263,4 @@ Interval{Float64}(2.0, 3.0) julia> trunc(x) -Interval{Float64}(1.0, 2.0) +Interval{Float64}(1.0, 2.0) diff --git a/en/v1.12-dev/manual/mathematical-operations/index.html b/en/v1.12-dev/manual/mathematical-operations/index.html index 5ea61c9e694b..ca403baac1da 100644 --- a/en/v1.12-dev/manual/mathematical-operations/index.html +++ b/en/v1.12-dev/manual/mathematical-operations/index.html @@ -179,4 +179,4 @@ asin acos atan acot asec acsc asinh acosh atanh acoth asech acsch sinc cosc

    These are all single-argument functions, with atan also accepting two arguments corresponding to a traditional atan2 function.

    Additionally, sinpi(x) and cospi(x) are provided for more accurate computations of sin(pi * x) and cos(pi * x) respectively.

    In order to compute trigonometric functions with degrees instead of radians, suffix the function with d. For example, sind(x) computes the sine of x where x is specified in degrees. The complete list of trigonometric functions with degree variants is:

    sind   cosd   tand   cotd   secd   cscd
    -asind  acosd  atand  acotd  asecd  acscd

    Special functions

    Many other special mathematical functions are provided by the package SpecialFunctions.jl.

    +asind acosd atand acotd asecd acscd

    Special functions

    Many other special mathematical functions are provided by the package SpecialFunctions.jl.

    diff --git a/en/v1.12-dev/manual/metaprogramming/index.html b/en/v1.12-dev/manual/metaprogramming/index.html index c76239c75768..c3a7248ac83c 100644 --- a/en/v1.12-dev/manual/metaprogramming/index.html +++ b/en/v1.12-dev/manual/metaprogramming/index.html @@ -502,4 +502,4 @@ end; julia> sub2ind_gen((3, 5), 1, 2) -4

    Internally, this code creates two implementations of the function: a generated one where the first block in if @generated is used, and a normal one where the else block is used. Inside the then part of the if @generated block, code has the same semantics as other generated functions: argument names refer to types, and the code should return an expression. Multiple if @generated blocks may occur, in which case the generated implementation uses all of the then blocks and the alternate implementation uses all of the else blocks.

    Notice that we added an error check to the top of the function. This code will be common to both versions, and is run-time code in both versions (it will be quoted and returned as an expression from the generated version). That means that the values and types of local variables are not available at code generation time –- the code-generation code can only see the types of arguments.

    In this style of definition, the code generation feature is essentially an optional optimization. The compiler will use it if convenient, but otherwise may choose to use the normal implementation instead. This style is preferred, since it allows the compiler to make more decisions and compile programs in more ways, and since normal code is more readable than code-generating code. However, which implementation is used depends on compiler implementation details, so it is essential for the two implementations to behave identically.

    +4

    Internally, this code creates two implementations of the function: a generated one where the first block in if @generated is used, and a normal one where the else block is used. Inside the then part of the if @generated block, code has the same semantics as other generated functions: argument names refer to types, and the code should return an expression. Multiple if @generated blocks may occur, in which case the generated implementation uses all of the then blocks and the alternate implementation uses all of the else blocks.

    Notice that we added an error check to the top of the function. This code will be common to both versions, and is run-time code in both versions (it will be quoted and returned as an expression from the generated version). That means that the values and types of local variables are not available at code generation time –- the code-generation code can only see the types of arguments.

    In this style of definition, the code generation feature is essentially an optional optimization. The compiler will use it if convenient, but otherwise may choose to use the normal implementation instead. This style is preferred, since it allows the compiler to make more decisions and compile programs in more ways, and since normal code is more readable than code-generating code. However, which implementation is used depends on compiler implementation details, so it is essential for the two implementations to behave identically.

    diff --git a/en/v1.12-dev/manual/methods/index.html b/en/v1.12-dev/manual/methods/index.html index c93039eb6fb7..dbbf5728a648 100644 --- a/en/v1.12-dev/manual/methods/index.html +++ b/en/v1.12-dev/manual/methods/index.html @@ -463,4 +463,4 @@ else x -> x - 1 end -end
    +end
    diff --git a/en/v1.12-dev/manual/missing/index.html b/en/v1.12-dev/manual/missing/index.html index fbdbad7ae1a3..5d450afd372c 100644 --- a/en/v1.12-dev/manual/missing/index.html +++ b/en/v1.12-dev/manual/missing/index.html @@ -161,4 +161,4 @@ true julia> any([false, missing]) -missing +missing diff --git a/en/v1.12-dev/manual/modules/index.html b/en/v1.12-dev/manual/modules/index.html index 92ff3df5a882..fe7230bbc257 100644 --- a/en/v1.12-dev/manual/modules/index.html +++ b/en/v1.12-dev/manual/modules/index.html @@ -132,4 +132,4 @@ # instead use accessor functions: getstdout() = Base.stdout #= best option =# # or move the assignment into the runtime: -__init__() = global mystdout = Base.stdout #= also works =#

    Several additional restrictions are placed on the operations that can be done while precompiling code to help the user avoid other wrong-behavior situations:

    1. Calling eval to cause a side-effect in another module. This will also cause a warning to be emitted when the incremental precompile flag is set.
    2. global const statements from local scope after __init__() has been started (see issue #12010 for plans to add an error for this)
    3. Replacing a module is a runtime error while doing an incremental precompile.

    A few other points to be aware of:

    1. No code reload / cache invalidation is performed after changes are made to the source files themselves, (including by Pkg.update), and no cleanup is done after Pkg.rm
    2. The memory sharing behavior of a reshaped array is disregarded by precompilation (each view gets its own copy)
    3. Expecting the filesystem to be unchanged between compile-time and runtime e.g. @__FILE__/source_path() to find resources at runtime, or the BinDeps @checked_lib macro. Sometimes this is unavoidable. However, when possible, it can be good practice to copy resources into the module at compile-time so they won't need to be found at runtime.
    4. WeakRef objects and finalizers are not currently handled properly by the serializer (this will be fixed in an upcoming release).
    5. It is usually best to avoid capturing references to instances of internal metadata objects such as Method, MethodInstance, MethodTable, TypeMapLevel, TypeMapEntry and fields of those objects, as this can confuse the serializer and may not lead to the outcome you desire. It is not necessarily an error to do this, but you simply need to be prepared that the system will try to copy some of these and to create a single unique instance of others.

    It is sometimes helpful during module development to turn off incremental precompilation. The command line flag --compiled-modules={yes|no|existing} enables you to toggle module precompilation on and off. When Julia is started with --compiled-modules=no the serialized modules in the compile cache are ignored when loading modules and module dependencies. In some cases, you may want to load existing precompiled modules, but not create new ones. This can be done by starting Julia with --compiled-modules=existing. More fine-grained control is available with --pkgimages={yes|no|existing}, which only affects native-code storage during precompilation. Base.compilecache can still be called manually. The state of this command line flag is passed to Pkg.build to disable automatic precompilation triggering when installing, updating, and explicitly building packages.

    You can also debug some precompilation failures with environment variables. Setting JULIA_VERBOSE_LINKING=true may help resolve failures in linking shared libraries of compiled native code. See the Developer Documentation part of the Julia manual, where you will find further details in the section documenting Julia's internals under "Package Images".

    +__init__() = global mystdout = Base.stdout #= also works =#

    Several additional restrictions are placed on the operations that can be done while precompiling code to help the user avoid other wrong-behavior situations:

    1. Calling eval to cause a side-effect in another module. This will also cause a warning to be emitted when the incremental precompile flag is set.
    2. global const statements from local scope after __init__() has been started (see issue #12010 for plans to add an error for this)
    3. Replacing a module is a runtime error while doing an incremental precompile.

    A few other points to be aware of:

    1. No code reload / cache invalidation is performed after changes are made to the source files themselves, (including by Pkg.update), and no cleanup is done after Pkg.rm
    2. The memory sharing behavior of a reshaped array is disregarded by precompilation (each view gets its own copy)
    3. Expecting the filesystem to be unchanged between compile-time and runtime e.g. @__FILE__/source_path() to find resources at runtime, or the BinDeps @checked_lib macro. Sometimes this is unavoidable. However, when possible, it can be good practice to copy resources into the module at compile-time so they won't need to be found at runtime.
    4. WeakRef objects and finalizers are not currently handled properly by the serializer (this will be fixed in an upcoming release).
    5. It is usually best to avoid capturing references to instances of internal metadata objects such as Method, MethodInstance, MethodTable, TypeMapLevel, TypeMapEntry and fields of those objects, as this can confuse the serializer and may not lead to the outcome you desire. It is not necessarily an error to do this, but you simply need to be prepared that the system will try to copy some of these and to create a single unique instance of others.

    It is sometimes helpful during module development to turn off incremental precompilation. The command line flag --compiled-modules={yes|no|existing} enables you to toggle module precompilation on and off. When Julia is started with --compiled-modules=no the serialized modules in the compile cache are ignored when loading modules and module dependencies. In some cases, you may want to load existing precompiled modules, but not create new ones. This can be done by starting Julia with --compiled-modules=existing. More fine-grained control is available with --pkgimages={yes|no|existing}, which only affects native-code storage during precompilation. Base.compilecache can still be called manually. The state of this command line flag is passed to Pkg.build to disable automatic precompilation triggering when installing, updating, and explicitly building packages.

    You can also debug some precompilation failures with environment variables. Setting JULIA_VERBOSE_LINKING=true may help resolve failures in linking shared libraries of compiled native code. See the Developer Documentation part of the Julia manual, where you will find further details in the section documenting Julia's internals under "Package Images".

    diff --git a/en/v1.12-dev/manual/multi-threading/index.html b/en/v1.12-dev/manual/multi-threading/index.html index cf8a36761cca..5d5b5d80824b 100644 --- a/en/v1.12-dev/manual/multi-threading/index.html +++ b/en/v1.12-dev/manual/multi-threading/index.html @@ -172,4 +172,4 @@ end end nothing -end
  • A related third strategy is to use a yield-free queue. We don't currently have a lock-free queue implemented in Base, but Base.IntrusiveLinkedListSynchronized{T} is suitable. This can frequently be a good strategy to use for code with event loops. For example, this strategy is employed by Gtk.jl to manage lifetime ref-counting. In this approach, we don't do any explicit work inside the finalizer, and instead add it to a queue to run at a safer time. In fact, Julia's task scheduler already uses this, so defining the finalizer as x -> @spawn do_cleanup(x) is one example of this approach. Note however that this doesn't control which thread do_cleanup runs on, so do_cleanup would still need to acquire a lock. That doesn't need to be true if you implement your own queue, as you can explicitly only drain that queue from your thread.

  • +end
  • A related third strategy is to use a yield-free queue. We don't currently have a lock-free queue implemented in Base, but Base.IntrusiveLinkedListSynchronized{T} is suitable. This can frequently be a good strategy to use for code with event loops. For example, this strategy is employed by Gtk.jl to manage lifetime ref-counting. In this approach, we don't do any explicit work inside the finalizer, and instead add it to a queue to run at a safer time. In fact, Julia's task scheduler already uses this, so defining the finalizer as x -> @spawn do_cleanup(x) is one example of this approach. Note however that this doesn't control which thread do_cleanup runs on, so do_cleanup would still need to acquire a lock. That doesn't need to be true if you implement your own queue, as you can explicitly only drain that queue from your thread.

  • diff --git a/en/v1.12-dev/manual/networking-and-streams/index.html b/en/v1.12-dev/manual/networking-and-streams/index.html index 5bafb9cd209f..40ee22b8cfa6 100644 --- a/en/v1.12-dev/manual/networking-and-streams/index.html +++ b/en/v1.12-dev/manual/networking-and-streams/index.html @@ -157,4 +157,4 @@ group = Sockets.IPv6("ff05::5:6:7") socket = Sockets.UDPSocket() send(socket, group, 6789, "Hello over IPv6") -close(socket) +close(socket) diff --git a/en/v1.12-dev/manual/noteworthy-differences/index.html b/en/v1.12-dev/manual/noteworthy-differences/index.html index 30e715b739b2..85347acd2a8a 100644 --- a/en/v1.12-dev/manual/noteworthy-differences/index.html +++ b/en/v1.12-dev/manual/noteworthy-differences/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Noteworthy Differences from other Languages

    Noteworthy differences from MATLAB

    Although MATLAB users may find Julia's syntax familiar, Julia is not a MATLAB clone. There are major syntactic and functional differences. The following are some noteworthy differences that may trip up Julia users accustomed to MATLAB:

    • Julia arrays are indexed with square brackets, A[i,j].
    • Julia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well. To avoid this, use A = copy(B).
    • Julia values are not copied when passed to a function. If a function modifies an array, the changes will be visible in the caller.
    • Julia does not automatically grow arrays in an assignment statement. Whereas in MATLAB a(4) = 3.2 can create the array a = [0 0 0 3.2] and a(5) = 7 can grow it into a = [0 0 0 3.2 7], the corresponding Julia statement a[5] = 7 throws an error if the length of a is less than 5 or if this statement is the first use of the identifier a. Julia has push! and append!, which grow Vectors much more efficiently than MATLAB's a(end+1) = val.
    • The imaginary unit sqrt(-1) is represented in Julia as im, not i or j as in MATLAB.
    • In Julia, literal numbers without a decimal point (such as 42) create integers instead of floating point numbers. As a result, some operations can throw a domain error if they expect a float; for example, julia> a = -1; 2^a throws a domain error, as the result is not an integer (see the FAQ entry on domain errors for details).
    • In Julia, multiple values are returned and assigned as tuples, e.g. (a, b) = (1, 2) or a, b = 1, 2. MATLAB's nargout, which is often used in MATLAB to do optional work based on the number of returned values, does not exist in Julia. Instead, users can use optional and keyword arguments to achieve similar capabilities.
    • Julia has true one-dimensional arrays. Column vectors are of size N, not Nx1. For example, rand(N) makes a 1-dimensional array.
    • In Julia, [x,y,z] will always construct a 3-element array containing x, y and z.
      • To concatenate in the first ("vertical") dimension use either vcat(x,y,z) or separate with semicolons ([x; y; z]).
      • To concatenate in the second ("horizontal") dimension use either hcat(x,y,z) or separate with spaces ([x y z]).
      • To construct block matrices (concatenating in the first two dimensions), use either hvcat or combine spaces and semicolons ([a b; c d]).
    • In Julia, a:b and a:b:c construct AbstractRange objects. To construct a full vector like in MATLAB, use collect(a:b). Generally, there is no need to call collect though. An AbstractRange object will act like a normal array in most cases but is more efficient because it lazily computes its values. This pattern of creating specialized objects instead of full arrays is used frequently, and is also seen in functions such as range, or with iterators such as enumerate, and zip. The special objects can mostly be used as if they were normal arrays.
    • Functions in Julia return values from their last expression or the return keyword instead of listing the names of variables to return in the function definition (see The return Keyword for details).
    • A Julia script may contain any number of functions, and all definitions will be externally visible when the file is loaded. Function definitions can be loaded from files outside the current working directory.
    • In Julia, reductions such as sum, prod, and maximum are performed over every element of an array when called with a single argument, as in sum(A), even if A has more than one dimension.
    • In Julia, parentheses must be used to call a function with zero arguments, like in rand().
    • Julia discourages the use of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end with semicolons. println or @printf can be used to print specific output.
    • In Julia, if A and B are arrays, logical comparison operations like A == B do not return an array of booleans. Instead, use A .== B, and similarly for the other boolean operators like <, >.
    • In Julia, when you want to apply a scalar-valued function elementwise to an array, use broadcasting syntax: f.(A) instead of f(A). In some cases, both operations are defined but mean different things: in MATLAB exp(A) applies elementwise and expm(A) is the matrix exponential, but in Julia exp.(A) applies elementwise and exp(A) is the matrix exponential.
    • In Julia, the operators &, |, and (xor) perform the bitwise operations equivalent to and, or, and xor respectively in MATLAB, and have precedence similar to Python's bitwise operators (unlike C). They can operate on scalars or element-wise across arrays and can be used to combine logical arrays, but note the difference in order of operations: parentheses may be required (e.g., to select elements of A equal to 1 or 2 use (A .== 1) .| (A .== 2)).
    • In Julia, the elements of a collection can be passed as arguments to a function using the splat operator ..., as in xs=[1,2]; f(xs...).
    • Julia's svd returns singular values as a vector instead of as a dense diagonal matrix.
    • In Julia, ... is not used to continue lines of code. Instead, incomplete expressions automatically continue onto the next line.
    • In both Julia and MATLAB, the variable ans is set to the value of the last expression issued in an interactive session. In Julia, unlike MATLAB, ans is not set when Julia code is run in non-interactive mode.
    • Julia's structs do not support dynamically adding fields at runtime, unlike MATLAB's classes. Instead, use a Dict. Dict in Julia isn't ordered.
    • In Julia each module has its own global scope/namespace, whereas in MATLAB there is just one global scope.
    • In MATLAB, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression x(x>3) or in the statement x(x>3) = [] to modify x in-place. In contrast, Julia provides the higher order functions filter and filter!, allowing users to write filter(z->z>3, x) and filter!(z->z>3, x) as alternatives to the corresponding transliterations x[x.>3] and x = x[x.>3]. Using filter! reduces the use of temporary arrays.
    • The analogue of extracting (or "dereferencing") all elements of a cell array, e.g. in vertcat(A{:}) in MATLAB, is written using the splat operator in Julia, e.g. as vcat(A...).
    • In Julia, the adjoint function performs conjugate transposition; in MATLAB, adjoint provides the "adjugate" or classical adjoint, which is the transpose of the matrix of cofactors.
    • In Julia, a^b^c is evaluated a^(b^c) while in MATLAB it's (a^b)^c.

    Noteworthy differences from R

    One of Julia's goals is to provide an effective language for data analysis and statistical programming. For users coming to Julia from R, these are some noteworthy differences:

    • Julia's single quotes enclose characters, not strings.

    • Julia can create substrings by indexing into strings. In R, strings must be converted into character vectors before creating substrings.

    • In Julia, like Python but unlike R, strings can be created with triple quotes """ ... """. This syntax is convenient for constructing strings that contain line breaks.

    • In Julia, varargs are specified using the splat operator ..., which always follows the name of a specific variable, unlike R, for which ... can occur in isolation.

    • In Julia, modulus is mod(a, b), not a %% b. % in Julia is the remainder operator.

    • Julia constructs vectors using brackets. Julia's [1, 2, 3] is the equivalent of R's c(1, 2, 3).

    • In Julia, not all data structures support logical indexing. Furthermore, logical indexing in Julia is supported only with vectors of length equal to the object being indexed. For example:

      • In R, c(1, 2, 3, 4)[c(TRUE, FALSE)] is equivalent to c(1, 3).
      • In R, c(1, 2, 3, 4)[c(TRUE, FALSE, TRUE, FALSE)] is equivalent to c(1, 3).
      • In Julia, [1, 2, 3, 4][[true, false]] throws a BoundsError.
      • In Julia, [1, 2, 3, 4][[true, false, true, false]] produces [1, 3].
    • Like many languages, Julia does not always allow operations on vectors of different lengths, unlike R where the vectors only need to share a common index range. For example, c(1, 2, 3, 4) + c(1, 2) is valid R but the equivalent [1, 2, 3, 4] + [1, 2] will throw an error in Julia.

    • Julia allows an optional trailing comma when that comma does not change the meaning of code. This can cause confusion among R users when indexing into arrays. For example, x[1,] in R would return the first row of a matrix; in Julia, however, the comma is ignored, so x[1,] == x[1], and will return the first element. To extract a row, be sure to use :, as in x[1,:].

    • Julia's map takes the function first, then its arguments, unlike lapply(<structure>, function, ...) in R. Similarly Julia's equivalent of apply(X, MARGIN, FUN, ...) in R is mapslices where the function is the first argument.

    • Multivariate apply in R, e.g. mapply(choose, 11:13, 1:3), can be written as broadcast(binomial, 11:13, 1:3) in Julia. Equivalently Julia offers a shorter dot syntax for vectorizing functions binomial.(11:13, 1:3).

    • Julia uses end to denote the end of conditional blocks, like if, loop blocks, like while/ for, and functions. In lieu of the one-line if ( cond ) statement, Julia allows statements of the form if cond; statement; end, cond && statement and !cond || statement. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g. cond && (x = value).

    • In Julia, <-, <<- and -> are not assignment operators.

    • Julia's -> creates an anonymous function.

    • Julia's * operator can perform matrix multiplication, unlike in R. If A and B are matrices, then A * B denotes a matrix multiplication in Julia, equivalent to R's A %*% B. In R, this same notation would perform an element-wise (Hadamard) product. To get the element-wise multiplication operation, you need to write A .* B in Julia.

    • Julia performs matrix transposition using the transpose function and conjugated transposition using the ' operator or the adjoint function. Julia's transpose(A) is therefore equivalent to R's t(A). Additionally a non-recursive transpose in Julia is provided by the permutedims function.

    • Julia does not require parentheses when writing if statements or for/while loops: use for i in [1, 2, 3] instead of for (i in c(1, 2, 3)) and if i == 1 instead of if (i == 1).

    • Julia does not treat the numbers 0 and 1 as Booleans. You cannot write if (1) in Julia, because if statements accept only booleans. Instead, you can write if true, if Bool(1), or if 1==1.

    • Julia does not provide nrow and ncol. Instead, use size(M, 1) for nrow(M) and size(M, 2) for ncol(M).

    • Julia is careful to distinguish scalars, vectors and matrices. In R, 1 and c(1) are the same. In Julia, they cannot be used interchangeably.

    • Julia's diag and diagm are not like R's.

    • Julia cannot assign to the results of function calls on the left hand side of an assignment operation: you cannot write diag(M) = fill(1, n).

    • Julia discourages populating the main namespace with functions. Most statistical functionality for Julia is found in packages under the JuliaStats organization. For example:

    • Julia provides tuples and real hash tables, but not R-style lists. When returning multiple items, you should typically use a tuple or a named tuple: instead of list(a = 1, b = 2), use (1, 2) or (a=1, b=2).

    • Julia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that table(x::TypeA) and table(x::TypeB) act like R's table.TypeA(x) and table.TypeB(x).

    • In Julia, values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. This is very different from R and allows new functions to operate on large data structures much more efficiently.

    • In Julia, vectors and matrices are concatenated using hcat, vcat and hvcat, not c, rbind and cbind like in R.

    • In Julia, a range like a:b is not shorthand for a vector like in R, but is a specialized AbstractRange object that is used for iteration. To convert a range into a vector, use collect(a:b).

    • The : operator has a different precedence in R and Julia. In particular, in Julia arithmetic operators have higher precedence than the : operator, whereas the reverse is true in R. For example, 1:n-1 in Julia is equivalent to 1:(n-1) in R.

    • Julia's max and min are the equivalent of pmax and pmin respectively in R, but both arguments need to have the same dimensions. While maximum and minimum replace max and min in R, there are important differences.

    • Julia's sum, prod, maximum, and minimum are different from their counterparts in R. They all accept an optional keyword argument dims, which indicates the dimensions, over which the operation is carried out. For instance, let A = [1 2; 3 4] in Julia and B <- rbind(c(1,2),c(3,4)) be the same matrix in R. Then sum(A) gives the same result as sum(B), but sum(A, dims=1) is a row vector containing the sum over each column and sum(A, dims=2) is a column vector containing the sum over each row. This contrasts to the behavior of R, where separate colSums(B) and rowSums(B) functions provide these functionalities. If the dims keyword argument is a vector, then it specifies all the dimensions over which the sum is performed, while retaining the dimensions of the summed array, e.g. sum(A, dims=(1,2)) == hcat(10). It should be noted that there is no error checking regarding the second argument.

    • Julia has several functions that can mutate their arguments. For example, it has both sort and sort!.

    • In R, performance requires vectorization. In Julia, almost the opposite is true: the best performing code is often achieved by using devectorized loops.

    • Julia is eagerly evaluated and does not support R-style lazy evaluation. For most users, this means that there are very few unquoted expressions or column names.

    • Julia does not support the NULL type. The closest equivalent is nothing, but it behaves like a scalar value rather than like a list. Use x === nothing instead of is.null(x).

    • In Julia, missing values are represented by the missing object rather than by NA. Use ismissing(x) (or ismissing.(x) for element-wise operation on vectors) instead of is.na(x). The skipmissing function is generally used instead of na.rm=TRUE (though in some particular cases functions take a skipmissing argument).

    • Julia lacks the equivalent of R's assign or get.

    • In Julia, return does not require parentheses.

    • In R, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression x[x>3] or in the statement x = x[x>3] to modify x in-place. In contrast, Julia provides the higher order functions filter and filter!, allowing users to write filter(z->z>3, x) and filter!(z->z>3, x) as alternatives to the corresponding transliterations x[x.>3] and x = x[x.>3]. Using filter! reduces the use of temporary arrays.

    Noteworthy differences from Python

    • Julia's for, if, while, etc. blocks are terminated by the end keyword. Indentation level is not significant as it is in Python. Unlike Python, Julia has no pass keyword.
    • Strings are denoted by double quotation marks ("text") in Julia (with three double quotation marks for multi-line strings), whereas in Python they can be denoted either by single ('text') or double quotation marks ("text"). Single quotation marks are used for characters in Julia ('c').
    • String concatenation is done with * in Julia, not + like in Python. Analogously, string repetition is done with ^, not *. Implicit string concatenation of string literals like in Python (e.g. 'ab' 'cd' == 'abcd') is not done in Julia.
    • Python Lists—flexible but slow—correspond to the Julia Vector{Any} type or more generally Vector{T} where T is some non-concrete element type. "Fast" arrays like NumPy arrays that store elements in-place (i.e., dtype is np.float64, [('f1', np.uint64), ('f2', np.int32)], etc.) can be represented by Array{T} where T is a concrete, immutable element type. This includes built-in types like Float64, Int32, Int64 but also more complex types like Tuple{UInt64,Float64} and many user-defined types as well.
    • In Julia, indexing of arrays, strings, etc. is 1-based not 0-based.
    • Julia's slice indexing includes the last element, unlike in Python. a[2:3] in Julia is a[1:3] in Python.
    • Unlike Python, Julia allows AbstractArrays with arbitrary indexes. Python's special interpretation of negative indexing, a[-1] and a[-2], should be written a[end] and a[end-1] in Julia.
    • Julia requires end for indexing until the last element. x[1:] in Python is equivalent to x[2:end] in Julia.
    • In Julia, : before any object creates a Symbol or quotes an expression; so, x[:5] is same as x[5]. If you want to get the first n elements of an array, then use range indexing.
    • Julia's range indexing has the format of x[start:step:stop], whereas Python's format is x[start:(stop+1):step]. Hence, x[0:10:2] in Python is equivalent to x[1:2:10] in Julia. Similarly, x[::-1] in Python, which refers to the reversed array, is equivalent to x[end:-1:1] in Julia.
    • In Julia, ranges can be constructed independently as start:step:stop, the same syntax it uses in array-indexing. The range function is also supported.
    • In Julia, indexing a matrix with arrays like X[[1,2], [1,3]] refers to a sub-matrix that contains the intersections of the first and second rows with the first and third columns. In Python, X[[1,2], [1,3]] refers to a vector that contains the values of cell [1,1] and [2,3] in the matrix. X[[1,2], [1,3]] in Julia is equivalent with X[np.ix_([0,1],[0,2])] in Python. X[[0,1], [0,2]] in Python is equivalent with X[[CartesianIndex(1,1), CartesianIndex(2,3)]] in Julia.
    • Julia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.
    • Julia arrays are column-major (Fortran-ordered) whereas NumPy arrays are row-major (C-ordered) by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to NumPy (see relevant section of Performance Tips).
    • Julia's updating operators (e.g. +=, -=, ...) are not in-place whereas NumPy's are. This means A = [1, 1]; B = A; B += [3, 3] doesn't change values in A, it rather rebinds the name B to the result of the right-hand side B = B + 3, which is a new array. For in-place operation, use B .+= 3 (see also dot operators), explicit loops, or InplaceOps.jl.
    • Julia evaluates default values of function arguments every time the method is invoked, unlike in Python where the default values are evaluated only once when the function is defined. For example, the function f(x=rand()) = x returns a new random number every time it is invoked without argument. On the other hand, the function g(x=[1,2]) = push!(x,3) returns [1,2,3] every time it is called as g().
    • In Julia, keyword arguments must be passed using keywords, unlike Python in which it is usually possible to pass them positionally. Attempting to pass a keyword argument positionally alters the method signature leading to a MethodError or calling of the wrong method.
    • In Julia % is the remainder operator, whereas in Python it is the modulus.
    • In Julia, the commonly used Int type corresponds to the machine integer type (Int32 or Int64), unlike in Python, where int is an arbitrary length integer. This means in Julia the Int type will overflow, such that 2^64 == 0. If you need larger values use another appropriate type, such as Int128, BigInt or a floating point type like Float64.
    • The imaginary unit sqrt(-1) is represented in Julia as im, not j as in Python.
    • In Julia, the exponentiation operator is ^, not ** as in Python.
    • Julia uses nothing of type Nothing to represent a null value, whereas Python uses None of type NoneType.
    • In Julia, the standard operators over a matrix type are matrix operations, whereas, in Python, the standard operators are element-wise operations. When both A and B are matrices, A * B in Julia performs matrix multiplication, not element-wise multiplication as in Python. A * B in Julia is equivalent with A @ B in Python, whereas A * B in Python is equivalent with A .* B in Julia.
    • In Julia, when you want to apply a scalar-valued function elementwise to an array, use broadcasting syntax: f.(A) instead of f(A). In some cases, both operations are defined but mean different things: numpy.exp(A) applies elementwise and scipy.linalg.expm(A) is the matrix exponential, but in Julia exp.(A) applies elementwise and exp(A) is the matrix exponential.
    • The adjoint operator ' in Julia returns an adjoint of a vector (a lazy representation of row vector), whereas the transpose operator .T over a vector in Python returns the original vector (non-op).
    • In Julia, a function may contain multiple concrete implementations (called methods), which are selected via multiple dispatch based on the types of all arguments to the call, as compared to functions in Python, which have a single implementation and no polymorphism (as opposed to Python method calls which use a different syntax and allows dispatch on the receiver of the method).
    • There are no classes in Julia. Instead there are structures (mutable or immutable), containing data but no methods.
    • Calling a method of a class instance in Python (x = MyClass(*args); x.f(y)) corresponds to a function call in Julia, e.g. x = MyType(args...); f(x, y). In general, multiple dispatch is more flexible and powerful than the Python class system.
    • Julia structures may have exactly one abstract supertype, whereas Python classes can inherit from one or more (abstract or concrete) superclasses.
    • The logical Julia program structure (Packages and Modules) is independent of the file structure, whereas the Python code structure is defined by directories (Packages) and files (Modules).
    • In Julia, it is idiomatic to split the text of large modules into multiple files, without introducing a new module per file. The code is reassembled inside a single module in a main file via include. While the Python equivalent (exec) is not typical for this use (it will silently clobber prior definitions), Julia programs are defined as a unit at the module level with using or import, which will only get executed once when first needed–like include in Python. Within those modules, the individual files that make up that module are loaded with include by listing them once in the intended order.
    • The ternary operator x > 0 ? 1 : -1 in Julia corresponds to a conditional expression in Python 1 if x > 0 else -1.
    • In Julia the @ symbol refers to a macro, whereas in Python it refers to a decorator.
    • Exception handling in Julia is done using trycatchfinally, instead of tryexceptfinally. In contrast to Python, it is not recommended to use exception handling as part of the normal workflow in Julia (compared with Python, Julia is faster at ordinary control flow but slower at exception-catching).
    • In Julia loops are fast, there is no need to write "vectorized" code for performance reasons.
    • Be careful with non-constant global variables in Julia, especially in tight loops. Since you can write close-to-metal code in Julia (unlike Python), the effect of globals can be drastic (see Performance Tips).
    • In Julia, rounding and truncation are explicit. Python's int(3.7) should be floor(Int, 3.7) or Int(floor(3.7)) and is distinguished from round(Int, 3.7). floor(x) and round(x) on their own return an integer value of the same type as x rather than always returning Int.
    • In Julia, parsing is explicit. Python's float("3.7") would be parse(Float64, "3.7") in Julia.
    • In Python, the majority of values can be used in logical contexts (e.g. if "a": means the following block is executed, and if "": means it is not). In Julia, you need explicit conversion to Bool (e.g. if "a" throws an exception). If you want to test for a non-empty string in Julia, you would explicitly write if !isempty(""). Perhaps surprisingly, in Python if "False" and bool("False") both evaluate to True (because "False" is a non-empty string); in Julia, parse(Bool, "false") returns false.
    • In Julia, a new local scope is introduced by most code blocks, including loops and trycatchfinally. Note that comprehensions (list, generator, etc.) introduce a new local scope both in Python and Julia, whereas if blocks do not introduce a new local scope in both languages.

    Noteworthy differences from C/C++

    • Julia arrays are indexed with square brackets, and can have more than one dimension A[i,j]. This syntax is not just syntactic sugar for a reference to a pointer or address as in C/C++. See the manual entry about array construction.
    • In Julia, indexing of arrays, strings, etc. is 1-based not 0-based.
    • Julia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well. Updating operators like += do not operate in-place, they are equivalent to A = A + B which rebinds the left-hand side to the result of the right-hand side expression.
    • Julia arrays are column major (Fortran ordered) whereas C/C++ arrays are row major ordered by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to C/C++ (see relevant section of Performance Tips).
    • Julia values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller.
    • In Julia, whitespace is significant, unlike C/C++, so care must be taken when adding/removing whitespace from a Julia program.
    • In Julia, literal numbers without a decimal point (such as 42) create signed integers, of type Int, but literals too large to fit in the machine word size will automatically be promoted to a larger size type, such as Int64 (if Int is Int32), Int128, or the arbitrarily large BigInt type. There are no numeric literal suffixes, such as L, LL, U, UL, ULL to indicate unsigned and/or signed vs. unsigned. Decimal literals are always signed, and hexadecimal literals (which start with 0x like C/C++), are unsigned, unless when they encode more than 128 bits, in which case they are of type BigInt. Hexadecimal literals also, unlike C/C++/Java and unlike decimal literals in Julia, have a type based on the length of the literal, including leading 0s. For example, 0x0 and 0x00 have type UInt8, 0x000 and 0x0000 have type UInt16, then literals with 5 to 8 hex digits have type UInt32, 9 to 16 hex digits type UInt64, 17 to 32 hex digits type UInt128, and more that 32 hex digits type BigInt. This needs to be taken into account when defining hexadecimal masks, for example ~0xf == 0xf0 is very different from ~0x000f == 0xfff0. 64 bit Float64 and 32 bit Float32 bit literals are expressed as 1.0 and 1.0f0 respectively. Floating point literals are rounded (and not promoted to the BigFloat type) if they can not be exactly represented. Floating point literals are closer in behavior to C/C++. Octal (prefixed with 0o) and binary (prefixed with 0b) literals are also treated as unsigned (or BigInt for more than 128 bits).
    • In Julia, the division operator / returns a floating point number when both operands are of integer type. To perform integer division, use div or ÷.
    • Indexing an Array with floating point types is generally an error in Julia. The Julia equivalent of the C expression a[i / 2] is a[i ÷ 2 + 1], where i is of integer type.
    • String literals can be delimited with either " or """, """ delimited literals can contain " characters without quoting it like "\"". String literals can have values of other variables or expressions interpolated into them, indicated by $variablename or $(expression), which evaluates the variable name or the expression in the context of the function.
    • // indicates a Rational number, and not a single-line comment (which is # in Julia)
    • #= indicates the start of a multiline comment, and =# ends it.
    • Functions in Julia return values from their last expression(s) or the return keyword. Multiple values can be returned from functions and assigned as tuples, e.g. (a, b) = myfunction() or a, b = myfunction(), instead of having to pass pointers to values as one would have to do in C/C++ (i.e. a = myfunction(&b).
    • Julia does not require the use of semicolons to end statements. The results of expressions are not automatically printed (except at the interactive prompt, i.e. the REPL), and lines of code do not need to end with semicolons. println or @printf can be used to print specific output. In the REPL, ; can be used to suppress output. ; also has a different meaning within [ ], something to watch out for. ; can be used to separate expressions on a single line, but are not strictly necessary in many cases, and are more an aid to readability.
    • In Julia, the operator (xor) performs the bitwise XOR operation, i.e. ^ in C/C++. Also, the bitwise operators do not have the same precedence as C/C++, so parenthesis may be required.
    • Julia's ^ is exponentiation (pow), not bitwise XOR as in C/C++ (use , or xor, in Julia)
    • Julia has two right-shift operators, >> and >>>. >> performs an arithmetic shift, >>> always performs a logical shift, unlike C/C++, where the meaning of >> depends on the type of the value being shifted.
    • Julia's -> creates an anonymous function, it does not access a member via a pointer.
    • Julia does not require parentheses when writing if statements or for/while loops: use for i in [1, 2, 3] instead of for (int i=1; i <= 3; i++) and if i == 1 instead of if (i == 1).
    • Julia does not treat the numbers 0 and 1 as Booleans. You cannot write if (1) in Julia, because if statements accept only booleans. Instead, you can write if true, if Bool(1), or if 1==1.
    • Julia uses end to denote the end of conditional blocks, like if, loop blocks, like while/ for, and functions. In lieu of the one-line if ( cond ) statement, Julia allows statements of the form if cond; statement; end, cond && statement and !cond || statement. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g. cond && (x = value), because of the operator precedence.
    • Julia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.
    • Julia macros operate on parsed expressions, rather than the text of the program, which allows them to perform sophisticated transformations of Julia code. Macro names start with the @ character, and have both a function-like syntax, @mymacro(arg1, arg2, arg3), and a statement-like syntax, @mymacro arg1 arg2 arg3. The forms are interchangeable; the function-like form is particularly useful if the macro appears within another expression, and is often clearest. The statement-like form is often used to annotate blocks, as in the distributed for construct: @distributed for i in 1:n; #= body =#; end. Where the end of the macro construct may be unclear, use the function-like form.
    • Julia has an enumeration type, expressed using the macro @enum(name, value1, value2, ...) For example: @enum(Fruit, banana=1, apple, pear)
    • By convention, functions that modify their arguments have a ! at the end of the name, for example push!.
    • In C++, by default, you have static dispatch, i.e. you need to annotate a function as virtual, in order to have dynamic dispatch. On the other hand, in Julia every method is "virtual" (although it's more general than that since methods are dispatched on every argument type, not only this, using the most-specific-declaration rule).

    Julia ⇔ C/C++: Namespaces

    • C/C++ namespaces correspond roughly to Julia modules.
    • There are no private globals or fields in Julia. Everything is publicly accessible through fully qualified paths (or relative paths, if desired).
    • using MyNamespace::myfun (C++) corresponds roughly to import MyModule: myfun (Julia).
    • using namespace MyNamespace (C++) corresponds roughly to using MyModule (Julia)
      • In Julia, only exported symbols are made available to the calling module.
      • In C++, only elements found in the included (public) header files are made available.
    • Caveat: import/using keywords (Julia) also load modules (see below).
    • Caveat: import/using (Julia) works only at the global scope level (modules)
      • In C++, using namespace X works within arbitrary scopes (ex: function scope).

    Julia ⇔ C/C++: Module loading

    • When you think of a C/C++ "library", you are likely looking for a Julia "package".
      • Caveat: C/C++ libraries often house multiple "software modules" whereas Julia "packages" typically house one.
      • Reminder: Julia modules are global scopes (not necessarily "software modules").
    • Instead of build/make scripts, Julia uses "Project Environments" (sometimes called either "Project" or "Environment").
      • Build scripts are only needed for more complex applications (like those needing to compile or download C/C++ executables).
      • To develop application or project in Julia, you can initialize its root directory as a "Project Environment", and house application-specific code/packages there. This provides good control over project dependencies, and future reproducibility.
      • Available packages are added to a "Project Environment" with the Pkg.add() function or Pkg REPL mode. (This does not load said package, however).
      • The list of available packages (direct dependencies) for a "Project Environment" are saved in its Project.toml file.
      • The full dependency information for a "Project Environment" is auto-generated & saved in its Manifest.toml file by Pkg.resolve().
    • Packages ("software modules") available to the "Project Environment" are loaded with import or using.
      • In C/C++, you #include <moduleheader> to get object/function declarations, and link in libraries when you build the executable.
      • In Julia, calling using/import again just brings the existing module into scope, but does not load it again (similar to adding the non-standard #pragma once to C/C++).
    • Directory-based package repositories (Julia) can be made available by adding repository paths to the Base.LOAD_PATH array.
      • Packages from directory-based repositories do not require the Pkg.add() tool prior to being loaded with import or using. They are simply available to the project.
      • Directory-based package repositories are the quickest solution to developing local libraries of "software modules".

    Julia ⇔ C/C++: Assembling modules

    • In C/C++, .c/.cpp files are compiled & added to a library with build/make scripts.
      • In Julia, import [PkgName]/using [PkgName] statements load [PkgName].jl located in a package's [PkgName]/src/ subdirectory.
      • In turn, [PkgName].jl typically loads associated source files with calls to include "[someotherfile].jl".
    • include "./path/to/somefile.jl" (Julia) is very similar to #include "./path/to/somefile.jl" (C/C++).
      • However include "..." (Julia) is not used to include header files (not required).
      • Do not use include "..." (Julia) to load code from other "software modules" (use import/using instead).
      • include "path/to/some/module.jl" (Julia) would instantiate multiple versions of the same code in different modules (creating distinct types (etc.) with the same names).
      • include "somefile.jl" is typically used to assemble multiple files within the same Julia package ("software module"). It is therefore relatively straightforward to ensure file are included only once (No #ifdef confusion).

    Julia ⇔ C/C++: Module interface

    • C++ exposes interfaces using "public" .h/.hpp files whereas Julia modules mark specific symbols that are intended for their users as publicor exported.
      • Often, Julia modules simply add functionality by generating new "methods" to existing functions (ex: Base.push!).
      • Developers of Julia packages therefore cannot rely on header files for interface documentation.
      • Interfaces for Julia packages are typically described using docstrings, README.md, static web pages, ...
    • Some developers choose not to export all symbols required to use their package/module, but should still mark unexported user facing symbols as public.
      • Users might be expected to access these components by qualifying functions/structs/... with the package/module name (ex: MyModule.run_this_task(...)).

    Julia ⇔ C/C++: Quick reference

    Software ConceptJuliaC/C++
    unnamed scopebegin ... end{ ... }
    function scopefunction x() ... endint x() { ... }
    global scopemodule MyMod ... endnamespace MyNS { ... }
    software moduleA Julia "package".h/.hpp files<br>+compiled somelib.a
    assembling<br>software modulesSomePkg.jl: ...<br>import("subfile1.jl")<br>import("subfile2.jl")<br>...$(AR) *.o &rArr; somelib.a
    import<br>software moduleimport SomePkg#include <somelib><br>+link in somelib.a
    module libraryLOAD_PATH[], *Git repository,<br>**custom package registrymore .h/.hpp files<br>+bigger compiled somebiglib.a

    * The Julia package manager supports registering multiple packages from a single Git repository.<br> * This allows users to house a library of related packages in a single repository.<br> ** Julia registries are primarily designed to provide versioning \& distribution of packages.<br> ** Custom package registries can be used to create a type of module library.

    Noteworthy differences from Common Lisp

    • Julia uses 1-based indexing for arrays by default, and it can also handle arbitrary index offsets.

    • Functions and variables share the same namespace (“Lisp-1”).

    • There is a Pair type, but it is not meant to be used as a COMMON-LISP:CONS. Various iterable collections can be used interchangeably in most parts of the language (eg splatting, tuples, etc). Tuples are the closest to Common Lisp lists for short collections of heterogeneous elements. Use NamedTuples in place of alists. For larger collections of homogeneous types, Arrays and Dicts should be used.

    • The typical Julia workflow for prototyping also uses continuous manipulation of the image, implemented with the Revise.jl package.

    • For performance, Julia prefers that operations have type stability. Where Common Lisp abstracts away from the underlying machine operations, Julia cleaves closer to them. For example:

      • Integer division using / always returns a floating-point result, even if the computation is exact.
        • // always returns a rational result
        • ÷ always returns a (truncated) integer result
      • Bignums are supported, but conversion is not automatic; ordinary integers overflow.
      • Complex numbers are supported, but to get complex results, you need complex inputs.
      • There are multiple Complex and Rational types, with different component types.
    • Modules (namespaces) can be hierarchical. import and using have a dual role: they load the code and make it available in the namespace. import for only the module name is possible (roughly equivalent to ASDF:LOAD-OP). Slot names don't need to be exported separately. Global variables can't be assigned to from outside the module (except with eval(mod, :(var = val)) as an escape hatch).

    • Macros start with @, and are not as seamlessly integrated into the language as Common Lisp; consequently, macro usage is not as widespread as in the latter. A form of hygiene for macros is supported by the language. Because of the different surface syntax, there is no equivalent to COMMON-LISP:&BODY.

    • All functions are generic and use multiple dispatch. Argument lists don't have to follow the same template, which leads to a powerful idiom (see do). Optional and keyword arguments are handled differently. Method ambiguities are not resolved like in the Common Lisp Object System, necessitating the definition of a more specific method for the intersection.

    • Symbols do not belong to any package, and do not contain any values per se. M.var evaluates the symbol var in the module M.

    • A functional programming style is fully supported by the language, including closures, but isn't always the idiomatic solution for Julia. Some workarounds may be necessary for performance when modifying captured variables.

    +

    Noteworthy Differences from other Languages

    Noteworthy differences from MATLAB

    Although MATLAB users may find Julia's syntax familiar, Julia is not a MATLAB clone. There are major syntactic and functional differences. The following are some noteworthy differences that may trip up Julia users accustomed to MATLAB:

    • Julia arrays are indexed with square brackets, A[i,j].
    • Julia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well. To avoid this, use A = copy(B).
    • Julia values are not copied when passed to a function. If a function modifies an array, the changes will be visible in the caller.
    • Julia does not automatically grow arrays in an assignment statement. Whereas in MATLAB a(4) = 3.2 can create the array a = [0 0 0 3.2] and a(5) = 7 can grow it into a = [0 0 0 3.2 7], the corresponding Julia statement a[5] = 7 throws an error if the length of a is less than 5 or if this statement is the first use of the identifier a. Julia has push! and append!, which grow Vectors much more efficiently than MATLAB's a(end+1) = val.
    • The imaginary unit sqrt(-1) is represented in Julia as im, not i or j as in MATLAB.
    • In Julia, literal numbers without a decimal point (such as 42) create integers instead of floating point numbers. As a result, some operations can throw a domain error if they expect a float; for example, julia> a = -1; 2^a throws a domain error, as the result is not an integer (see the FAQ entry on domain errors for details).
    • In Julia, multiple values are returned and assigned as tuples, e.g. (a, b) = (1, 2) or a, b = 1, 2. MATLAB's nargout, which is often used in MATLAB to do optional work based on the number of returned values, does not exist in Julia. Instead, users can use optional and keyword arguments to achieve similar capabilities.
    • Julia has true one-dimensional arrays. Column vectors are of size N, not Nx1. For example, rand(N) makes a 1-dimensional array.
    • In Julia, [x,y,z] will always construct a 3-element array containing x, y and z.
      • To concatenate in the first ("vertical") dimension use either vcat(x,y,z) or separate with semicolons ([x; y; z]).
      • To concatenate in the second ("horizontal") dimension use either hcat(x,y,z) or separate with spaces ([x y z]).
      • To construct block matrices (concatenating in the first two dimensions), use either hvcat or combine spaces and semicolons ([a b; c d]).
    • In Julia, a:b and a:b:c construct AbstractRange objects. To construct a full vector like in MATLAB, use collect(a:b). Generally, there is no need to call collect though. An AbstractRange object will act like a normal array in most cases but is more efficient because it lazily computes its values. This pattern of creating specialized objects instead of full arrays is used frequently, and is also seen in functions such as range, or with iterators such as enumerate, and zip. The special objects can mostly be used as if they were normal arrays.
    • Functions in Julia return values from their last expression or the return keyword instead of listing the names of variables to return in the function definition (see The return Keyword for details).
    • A Julia script may contain any number of functions, and all definitions will be externally visible when the file is loaded. Function definitions can be loaded from files outside the current working directory.
    • In Julia, reductions such as sum, prod, and maximum are performed over every element of an array when called with a single argument, as in sum(A), even if A has more than one dimension.
    • In Julia, parentheses must be used to call a function with zero arguments, like in rand().
    • Julia discourages the use of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end with semicolons. println or @printf can be used to print specific output.
    • In Julia, if A and B are arrays, logical comparison operations like A == B do not return an array of booleans. Instead, use A .== B, and similarly for the other boolean operators like <, >.
    • In Julia, when you want to apply a scalar-valued function elementwise to an array, use broadcasting syntax: f.(A) instead of f(A). In some cases, both operations are defined but mean different things: in MATLAB exp(A) applies elementwise and expm(A) is the matrix exponential, but in Julia exp.(A) applies elementwise and exp(A) is the matrix exponential.
    • In Julia, the operators &, |, and (xor) perform the bitwise operations equivalent to and, or, and xor respectively in MATLAB, and have precedence similar to Python's bitwise operators (unlike C). They can operate on scalars or element-wise across arrays and can be used to combine logical arrays, but note the difference in order of operations: parentheses may be required (e.g., to select elements of A equal to 1 or 2 use (A .== 1) .| (A .== 2)).
    • In Julia, the elements of a collection can be passed as arguments to a function using the splat operator ..., as in xs=[1,2]; f(xs...).
    • Julia's svd returns singular values as a vector instead of as a dense diagonal matrix.
    • In Julia, ... is not used to continue lines of code. Instead, incomplete expressions automatically continue onto the next line.
    • In both Julia and MATLAB, the variable ans is set to the value of the last expression issued in an interactive session. In Julia, unlike MATLAB, ans is not set when Julia code is run in non-interactive mode.
    • Julia's structs do not support dynamically adding fields at runtime, unlike MATLAB's classes. Instead, use a Dict. Dict in Julia isn't ordered.
    • In Julia each module has its own global scope/namespace, whereas in MATLAB there is just one global scope.
    • In MATLAB, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression x(x>3) or in the statement x(x>3) = [] to modify x in-place. In contrast, Julia provides the higher order functions filter and filter!, allowing users to write filter(z->z>3, x) and filter!(z->z>3, x) as alternatives to the corresponding transliterations x[x.>3] and x = x[x.>3]. Using filter! reduces the use of temporary arrays.
    • The analogue of extracting (or "dereferencing") all elements of a cell array, e.g. in vertcat(A{:}) in MATLAB, is written using the splat operator in Julia, e.g. as vcat(A...).
    • In Julia, the adjoint function performs conjugate transposition; in MATLAB, adjoint provides the "adjugate" or classical adjoint, which is the transpose of the matrix of cofactors.
    • In Julia, a^b^c is evaluated a^(b^c) while in MATLAB it's (a^b)^c.

    Noteworthy differences from R

    One of Julia's goals is to provide an effective language for data analysis and statistical programming. For users coming to Julia from R, these are some noteworthy differences:

    • Julia's single quotes enclose characters, not strings.

    • Julia can create substrings by indexing into strings. In R, strings must be converted into character vectors before creating substrings.

    • In Julia, like Python but unlike R, strings can be created with triple quotes """ ... """. This syntax is convenient for constructing strings that contain line breaks.

    • In Julia, varargs are specified using the splat operator ..., which always follows the name of a specific variable, unlike R, for which ... can occur in isolation.

    • In Julia, modulus is mod(a, b), not a %% b. % in Julia is the remainder operator.

    • Julia constructs vectors using brackets. Julia's [1, 2, 3] is the equivalent of R's c(1, 2, 3).

    • In Julia, not all data structures support logical indexing. Furthermore, logical indexing in Julia is supported only with vectors of length equal to the object being indexed. For example:

      • In R, c(1, 2, 3, 4)[c(TRUE, FALSE)] is equivalent to c(1, 3).
      • In R, c(1, 2, 3, 4)[c(TRUE, FALSE, TRUE, FALSE)] is equivalent to c(1, 3).
      • In Julia, [1, 2, 3, 4][[true, false]] throws a BoundsError.
      • In Julia, [1, 2, 3, 4][[true, false, true, false]] produces [1, 3].
    • Like many languages, Julia does not always allow operations on vectors of different lengths, unlike R where the vectors only need to share a common index range. For example, c(1, 2, 3, 4) + c(1, 2) is valid R but the equivalent [1, 2, 3, 4] + [1, 2] will throw an error in Julia.

    • Julia allows an optional trailing comma when that comma does not change the meaning of code. This can cause confusion among R users when indexing into arrays. For example, x[1,] in R would return the first row of a matrix; in Julia, however, the comma is ignored, so x[1,] == x[1], and will return the first element. To extract a row, be sure to use :, as in x[1,:].

    • Julia's map takes the function first, then its arguments, unlike lapply(<structure>, function, ...) in R. Similarly Julia's equivalent of apply(X, MARGIN, FUN, ...) in R is mapslices where the function is the first argument.

    • Multivariate apply in R, e.g. mapply(choose, 11:13, 1:3), can be written as broadcast(binomial, 11:13, 1:3) in Julia. Equivalently Julia offers a shorter dot syntax for vectorizing functions binomial.(11:13, 1:3).

    • Julia uses end to denote the end of conditional blocks, like if, loop blocks, like while/ for, and functions. In lieu of the one-line if ( cond ) statement, Julia allows statements of the form if cond; statement; end, cond && statement and !cond || statement. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g. cond && (x = value).

    • In Julia, <-, <<- and -> are not assignment operators.

    • Julia's -> creates an anonymous function.

    • Julia's * operator can perform matrix multiplication, unlike in R. If A and B are matrices, then A * B denotes a matrix multiplication in Julia, equivalent to R's A %*% B. In R, this same notation would perform an element-wise (Hadamard) product. To get the element-wise multiplication operation, you need to write A .* B in Julia.

    • Julia performs matrix transposition using the transpose function and conjugated transposition using the ' operator or the adjoint function. Julia's transpose(A) is therefore equivalent to R's t(A). Additionally a non-recursive transpose in Julia is provided by the permutedims function.

    • Julia does not require parentheses when writing if statements or for/while loops: use for i in [1, 2, 3] instead of for (i in c(1, 2, 3)) and if i == 1 instead of if (i == 1).

    • Julia does not treat the numbers 0 and 1 as Booleans. You cannot write if (1) in Julia, because if statements accept only booleans. Instead, you can write if true, if Bool(1), or if 1==1.

    • Julia does not provide nrow and ncol. Instead, use size(M, 1) for nrow(M) and size(M, 2) for ncol(M).

    • Julia is careful to distinguish scalars, vectors and matrices. In R, 1 and c(1) are the same. In Julia, they cannot be used interchangeably.

    • Julia's diag and diagm are not like R's.

    • Julia cannot assign to the results of function calls on the left hand side of an assignment operation: you cannot write diag(M) = fill(1, n).

    • Julia discourages populating the main namespace with functions. Most statistical functionality for Julia is found in packages under the JuliaStats organization. For example:

    • Julia provides tuples and real hash tables, but not R-style lists. When returning multiple items, you should typically use a tuple or a named tuple: instead of list(a = 1, b = 2), use (1, 2) or (a=1, b=2).

    • Julia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that table(x::TypeA) and table(x::TypeB) act like R's table.TypeA(x) and table.TypeB(x).

    • In Julia, values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. This is very different from R and allows new functions to operate on large data structures much more efficiently.

    • In Julia, vectors and matrices are concatenated using hcat, vcat and hvcat, not c, rbind and cbind like in R.

    • In Julia, a range like a:b is not shorthand for a vector like in R, but is a specialized AbstractRange object that is used for iteration. To convert a range into a vector, use collect(a:b).

    • The : operator has a different precedence in R and Julia. In particular, in Julia arithmetic operators have higher precedence than the : operator, whereas the reverse is true in R. For example, 1:n-1 in Julia is equivalent to 1:(n-1) in R.

    • Julia's max and min are the equivalent of pmax and pmin respectively in R, but both arguments need to have the same dimensions. While maximum and minimum replace max and min in R, there are important differences.

    • Julia's sum, prod, maximum, and minimum are different from their counterparts in R. They all accept an optional keyword argument dims, which indicates the dimensions, over which the operation is carried out. For instance, let A = [1 2; 3 4] in Julia and B <- rbind(c(1,2),c(3,4)) be the same matrix in R. Then sum(A) gives the same result as sum(B), but sum(A, dims=1) is a row vector containing the sum over each column and sum(A, dims=2) is a column vector containing the sum over each row. This contrasts to the behavior of R, where separate colSums(B) and rowSums(B) functions provide these functionalities. If the dims keyword argument is a vector, then it specifies all the dimensions over which the sum is performed, while retaining the dimensions of the summed array, e.g. sum(A, dims=(1,2)) == hcat(10). It should be noted that there is no error checking regarding the second argument.

    • Julia has several functions that can mutate their arguments. For example, it has both sort and sort!.

    • In R, performance requires vectorization. In Julia, almost the opposite is true: the best performing code is often achieved by using devectorized loops.

    • Julia is eagerly evaluated and does not support R-style lazy evaluation. For most users, this means that there are very few unquoted expressions or column names.

    • Julia does not support the NULL type. The closest equivalent is nothing, but it behaves like a scalar value rather than like a list. Use x === nothing instead of is.null(x).

    • In Julia, missing values are represented by the missing object rather than by NA. Use ismissing(x) (or ismissing.(x) for element-wise operation on vectors) instead of is.na(x). The skipmissing function is generally used instead of na.rm=TRUE (though in some particular cases functions take a skipmissing argument).

    • Julia lacks the equivalent of R's assign or get.

    • In Julia, return does not require parentheses.

    • In R, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression x[x>3] or in the statement x = x[x>3] to modify x in-place. In contrast, Julia provides the higher order functions filter and filter!, allowing users to write filter(z->z>3, x) and filter!(z->z>3, x) as alternatives to the corresponding transliterations x[x.>3] and x = x[x.>3]. Using filter! reduces the use of temporary arrays.

    Noteworthy differences from Python

    • Julia's for, if, while, etc. blocks are terminated by the end keyword. Indentation level is not significant as it is in Python. Unlike Python, Julia has no pass keyword.
    • Strings are denoted by double quotation marks ("text") in Julia (with three double quotation marks for multi-line strings), whereas in Python they can be denoted either by single ('text') or double quotation marks ("text"). Single quotation marks are used for characters in Julia ('c').
    • String concatenation is done with * in Julia, not + like in Python. Analogously, string repetition is done with ^, not *. Implicit string concatenation of string literals like in Python (e.g. 'ab' 'cd' == 'abcd') is not done in Julia.
    • Python Lists—flexible but slow—correspond to the Julia Vector{Any} type or more generally Vector{T} where T is some non-concrete element type. "Fast" arrays like NumPy arrays that store elements in-place (i.e., dtype is np.float64, [('f1', np.uint64), ('f2', np.int32)], etc.) can be represented by Array{T} where T is a concrete, immutable element type. This includes built-in types like Float64, Int32, Int64 but also more complex types like Tuple{UInt64,Float64} and many user-defined types as well.
    • In Julia, indexing of arrays, strings, etc. is 1-based not 0-based.
    • Julia's slice indexing includes the last element, unlike in Python. a[2:3] in Julia is a[1:3] in Python.
    • Unlike Python, Julia allows AbstractArrays with arbitrary indexes. Python's special interpretation of negative indexing, a[-1] and a[-2], should be written a[end] and a[end-1] in Julia.
    • Julia requires end for indexing until the last element. x[1:] in Python is equivalent to x[2:end] in Julia.
    • In Julia, : before any object creates a Symbol or quotes an expression; so, x[:5] is same as x[5]. If you want to get the first n elements of an array, then use range indexing.
    • Julia's range indexing has the format of x[start:step:stop], whereas Python's format is x[start:(stop+1):step]. Hence, x[0:10:2] in Python is equivalent to x[1:2:10] in Julia. Similarly, x[::-1] in Python, which refers to the reversed array, is equivalent to x[end:-1:1] in Julia.
    • In Julia, ranges can be constructed independently as start:step:stop, the same syntax it uses in array-indexing. The range function is also supported.
    • In Julia, indexing a matrix with arrays like X[[1,2], [1,3]] refers to a sub-matrix that contains the intersections of the first and second rows with the first and third columns. In Python, X[[1,2], [1,3]] refers to a vector that contains the values of cell [1,1] and [2,3] in the matrix. X[[1,2], [1,3]] in Julia is equivalent with X[np.ix_([0,1],[0,2])] in Python. X[[0,1], [0,2]] in Python is equivalent with X[[CartesianIndex(1,1), CartesianIndex(2,3)]] in Julia.
    • Julia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.
    • Julia arrays are column-major (Fortran-ordered) whereas NumPy arrays are row-major (C-ordered) by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to NumPy (see relevant section of Performance Tips).
    • Julia's updating operators (e.g. +=, -=, ...) are not in-place whereas NumPy's are. This means A = [1, 1]; B = A; B += [3, 3] doesn't change values in A, it rather rebinds the name B to the result of the right-hand side B = B + 3, which is a new array. For in-place operation, use B .+= 3 (see also dot operators), explicit loops, or InplaceOps.jl.
    • Julia evaluates default values of function arguments every time the method is invoked, unlike in Python where the default values are evaluated only once when the function is defined. For example, the function f(x=rand()) = x returns a new random number every time it is invoked without argument. On the other hand, the function g(x=[1,2]) = push!(x,3) returns [1,2,3] every time it is called as g().
    • In Julia, keyword arguments must be passed using keywords, unlike Python in which it is usually possible to pass them positionally. Attempting to pass a keyword argument positionally alters the method signature leading to a MethodError or calling of the wrong method.
    • In Julia % is the remainder operator, whereas in Python it is the modulus.
    • In Julia, the commonly used Int type corresponds to the machine integer type (Int32 or Int64), unlike in Python, where int is an arbitrary length integer. This means in Julia the Int type will overflow, such that 2^64 == 0. If you need larger values use another appropriate type, such as Int128, BigInt or a floating point type like Float64.
    • The imaginary unit sqrt(-1) is represented in Julia as im, not j as in Python.
    • In Julia, the exponentiation operator is ^, not ** as in Python.
    • Julia uses nothing of type Nothing to represent a null value, whereas Python uses None of type NoneType.
    • In Julia, the standard operators over a matrix type are matrix operations, whereas, in Python, the standard operators are element-wise operations. When both A and B are matrices, A * B in Julia performs matrix multiplication, not element-wise multiplication as in Python. A * B in Julia is equivalent with A @ B in Python, whereas A * B in Python is equivalent with A .* B in Julia.
    • In Julia, when you want to apply a scalar-valued function elementwise to an array, use broadcasting syntax: f.(A) instead of f(A). In some cases, both operations are defined but mean different things: numpy.exp(A) applies elementwise and scipy.linalg.expm(A) is the matrix exponential, but in Julia exp.(A) applies elementwise and exp(A) is the matrix exponential.
    • The adjoint operator ' in Julia returns an adjoint of a vector (a lazy representation of row vector), whereas the transpose operator .T over a vector in Python returns the original vector (non-op).
    • In Julia, a function may contain multiple concrete implementations (called methods), which are selected via multiple dispatch based on the types of all arguments to the call, as compared to functions in Python, which have a single implementation and no polymorphism (as opposed to Python method calls which use a different syntax and allows dispatch on the receiver of the method).
    • There are no classes in Julia. Instead there are structures (mutable or immutable), containing data but no methods.
    • Calling a method of a class instance in Python (x = MyClass(*args); x.f(y)) corresponds to a function call in Julia, e.g. x = MyType(args...); f(x, y). In general, multiple dispatch is more flexible and powerful than the Python class system.
    • Julia structures may have exactly one abstract supertype, whereas Python classes can inherit from one or more (abstract or concrete) superclasses.
    • The logical Julia program structure (Packages and Modules) is independent of the file structure, whereas the Python code structure is defined by directories (Packages) and files (Modules).
    • In Julia, it is idiomatic to split the text of large modules into multiple files, without introducing a new module per file. The code is reassembled inside a single module in a main file via include. While the Python equivalent (exec) is not typical for this use (it will silently clobber prior definitions), Julia programs are defined as a unit at the module level with using or import, which will only get executed once when first needed–like include in Python. Within those modules, the individual files that make up that module are loaded with include by listing them once in the intended order.
    • The ternary operator x > 0 ? 1 : -1 in Julia corresponds to a conditional expression in Python 1 if x > 0 else -1.
    • In Julia the @ symbol refers to a macro, whereas in Python it refers to a decorator.
    • Exception handling in Julia is done using trycatchfinally, instead of tryexceptfinally. In contrast to Python, it is not recommended to use exception handling as part of the normal workflow in Julia (compared with Python, Julia is faster at ordinary control flow but slower at exception-catching).
    • In Julia loops are fast, there is no need to write "vectorized" code for performance reasons.
    • Be careful with non-constant global variables in Julia, especially in tight loops. Since you can write close-to-metal code in Julia (unlike Python), the effect of globals can be drastic (see Performance Tips).
    • In Julia, rounding and truncation are explicit. Python's int(3.7) should be floor(Int, 3.7) or Int(floor(3.7)) and is distinguished from round(Int, 3.7). floor(x) and round(x) on their own return an integer value of the same type as x rather than always returning Int.
    • In Julia, parsing is explicit. Python's float("3.7") would be parse(Float64, "3.7") in Julia.
    • In Python, the majority of values can be used in logical contexts (e.g. if "a": means the following block is executed, and if "": means it is not). In Julia, you need explicit conversion to Bool (e.g. if "a" throws an exception). If you want to test for a non-empty string in Julia, you would explicitly write if !isempty(""). Perhaps surprisingly, in Python if "False" and bool("False") both evaluate to True (because "False" is a non-empty string); in Julia, parse(Bool, "false") returns false.
    • In Julia, a new local scope is introduced by most code blocks, including loops and trycatchfinally. Note that comprehensions (list, generator, etc.) introduce a new local scope both in Python and Julia, whereas if blocks do not introduce a new local scope in both languages.

    Noteworthy differences from C/C++

    • Julia arrays are indexed with square brackets, and can have more than one dimension A[i,j]. This syntax is not just syntactic sugar for a reference to a pointer or address as in C/C++. See the manual entry about array construction.
    • In Julia, indexing of arrays, strings, etc. is 1-based not 0-based.
    • Julia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well. Updating operators like += do not operate in-place, they are equivalent to A = A + B which rebinds the left-hand side to the result of the right-hand side expression.
    • Julia arrays are column major (Fortran ordered) whereas C/C++ arrays are row major ordered by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to C/C++ (see relevant section of Performance Tips).
    • Julia values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller.
    • In Julia, whitespace is significant, unlike C/C++, so care must be taken when adding/removing whitespace from a Julia program.
    • In Julia, literal numbers without a decimal point (such as 42) create signed integers, of type Int, but literals too large to fit in the machine word size will automatically be promoted to a larger size type, such as Int64 (if Int is Int32), Int128, or the arbitrarily large BigInt type. There are no numeric literal suffixes, such as L, LL, U, UL, ULL to indicate unsigned and/or signed vs. unsigned. Decimal literals are always signed, and hexadecimal literals (which start with 0x like C/C++), are unsigned, unless when they encode more than 128 bits, in which case they are of type BigInt. Hexadecimal literals also, unlike C/C++/Java and unlike decimal literals in Julia, have a type based on the length of the literal, including leading 0s. For example, 0x0 and 0x00 have type UInt8, 0x000 and 0x0000 have type UInt16, then literals with 5 to 8 hex digits have type UInt32, 9 to 16 hex digits type UInt64, 17 to 32 hex digits type UInt128, and more that 32 hex digits type BigInt. This needs to be taken into account when defining hexadecimal masks, for example ~0xf == 0xf0 is very different from ~0x000f == 0xfff0. 64 bit Float64 and 32 bit Float32 bit literals are expressed as 1.0 and 1.0f0 respectively. Floating point literals are rounded (and not promoted to the BigFloat type) if they can not be exactly represented. Floating point literals are closer in behavior to C/C++. Octal (prefixed with 0o) and binary (prefixed with 0b) literals are also treated as unsigned (or BigInt for more than 128 bits).
    • In Julia, the division operator / returns a floating point number when both operands are of integer type. To perform integer division, use div or ÷.
    • Indexing an Array with floating point types is generally an error in Julia. The Julia equivalent of the C expression a[i / 2] is a[i ÷ 2 + 1], where i is of integer type.
    • String literals can be delimited with either " or """, """ delimited literals can contain " characters without quoting it like "\"". String literals can have values of other variables or expressions interpolated into them, indicated by $variablename or $(expression), which evaluates the variable name or the expression in the context of the function.
    • // indicates a Rational number, and not a single-line comment (which is # in Julia)
    • #= indicates the start of a multiline comment, and =# ends it.
    • Functions in Julia return values from their last expression(s) or the return keyword. Multiple values can be returned from functions and assigned as tuples, e.g. (a, b) = myfunction() or a, b = myfunction(), instead of having to pass pointers to values as one would have to do in C/C++ (i.e. a = myfunction(&b).
    • Julia does not require the use of semicolons to end statements. The results of expressions are not automatically printed (except at the interactive prompt, i.e. the REPL), and lines of code do not need to end with semicolons. println or @printf can be used to print specific output. In the REPL, ; can be used to suppress output. ; also has a different meaning within [ ], something to watch out for. ; can be used to separate expressions on a single line, but are not strictly necessary in many cases, and are more an aid to readability.
    • In Julia, the operator (xor) performs the bitwise XOR operation, i.e. ^ in C/C++. Also, the bitwise operators do not have the same precedence as C/C++, so parenthesis may be required.
    • Julia's ^ is exponentiation (pow), not bitwise XOR as in C/C++ (use , or xor, in Julia)
    • Julia has two right-shift operators, >> and >>>. >> performs an arithmetic shift, >>> always performs a logical shift, unlike C/C++, where the meaning of >> depends on the type of the value being shifted.
    • Julia's -> creates an anonymous function, it does not access a member via a pointer.
    • Julia does not require parentheses when writing if statements or for/while loops: use for i in [1, 2, 3] instead of for (int i=1; i <= 3; i++) and if i == 1 instead of if (i == 1).
    • Julia does not treat the numbers 0 and 1 as Booleans. You cannot write if (1) in Julia, because if statements accept only booleans. Instead, you can write if true, if Bool(1), or if 1==1.
    • Julia uses end to denote the end of conditional blocks, like if, loop blocks, like while/ for, and functions. In lieu of the one-line if ( cond ) statement, Julia allows statements of the form if cond; statement; end, cond && statement and !cond || statement. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g. cond && (x = value), because of the operator precedence.
    • Julia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.
    • Julia macros operate on parsed expressions, rather than the text of the program, which allows them to perform sophisticated transformations of Julia code. Macro names start with the @ character, and have both a function-like syntax, @mymacro(arg1, arg2, arg3), and a statement-like syntax, @mymacro arg1 arg2 arg3. The forms are interchangeable; the function-like form is particularly useful if the macro appears within another expression, and is often clearest. The statement-like form is often used to annotate blocks, as in the distributed for construct: @distributed for i in 1:n; #= body =#; end. Where the end of the macro construct may be unclear, use the function-like form.
    • Julia has an enumeration type, expressed using the macro @enum(name, value1, value2, ...) For example: @enum(Fruit, banana=1, apple, pear)
    • By convention, functions that modify their arguments have a ! at the end of the name, for example push!.
    • In C++, by default, you have static dispatch, i.e. you need to annotate a function as virtual, in order to have dynamic dispatch. On the other hand, in Julia every method is "virtual" (although it's more general than that since methods are dispatched on every argument type, not only this, using the most-specific-declaration rule).

    Julia ⇔ C/C++: Namespaces

    • C/C++ namespaces correspond roughly to Julia modules.
    • There are no private globals or fields in Julia. Everything is publicly accessible through fully qualified paths (or relative paths, if desired).
    • using MyNamespace::myfun (C++) corresponds roughly to import MyModule: myfun (Julia).
    • using namespace MyNamespace (C++) corresponds roughly to using MyModule (Julia)
      • In Julia, only exported symbols are made available to the calling module.
      • In C++, only elements found in the included (public) header files are made available.
    • Caveat: import/using keywords (Julia) also load modules (see below).
    • Caveat: import/using (Julia) works only at the global scope level (modules)
      • In C++, using namespace X works within arbitrary scopes (ex: function scope).

    Julia ⇔ C/C++: Module loading

    • When you think of a C/C++ "library", you are likely looking for a Julia "package".
      • Caveat: C/C++ libraries often house multiple "software modules" whereas Julia "packages" typically house one.
      • Reminder: Julia modules are global scopes (not necessarily "software modules").
    • Instead of build/make scripts, Julia uses "Project Environments" (sometimes called either "Project" or "Environment").
      • Build scripts are only needed for more complex applications (like those needing to compile or download C/C++ executables).
      • To develop application or project in Julia, you can initialize its root directory as a "Project Environment", and house application-specific code/packages there. This provides good control over project dependencies, and future reproducibility.
      • Available packages are added to a "Project Environment" with the Pkg.add() function or Pkg REPL mode. (This does not load said package, however).
      • The list of available packages (direct dependencies) for a "Project Environment" are saved in its Project.toml file.
      • The full dependency information for a "Project Environment" is auto-generated & saved in its Manifest.toml file by Pkg.resolve().
    • Packages ("software modules") available to the "Project Environment" are loaded with import or using.
      • In C/C++, you #include <moduleheader> to get object/function declarations, and link in libraries when you build the executable.
      • In Julia, calling using/import again just brings the existing module into scope, but does not load it again (similar to adding the non-standard #pragma once to C/C++).
    • Directory-based package repositories (Julia) can be made available by adding repository paths to the Base.LOAD_PATH array.
      • Packages from directory-based repositories do not require the Pkg.add() tool prior to being loaded with import or using. They are simply available to the project.
      • Directory-based package repositories are the quickest solution to developing local libraries of "software modules".

    Julia ⇔ C/C++: Assembling modules

    • In C/C++, .c/.cpp files are compiled & added to a library with build/make scripts.
      • In Julia, import [PkgName]/using [PkgName] statements load [PkgName].jl located in a package's [PkgName]/src/ subdirectory.
      • In turn, [PkgName].jl typically loads associated source files with calls to include "[someotherfile].jl".
    • include "./path/to/somefile.jl" (Julia) is very similar to #include "./path/to/somefile.jl" (C/C++).
      • However include "..." (Julia) is not used to include header files (not required).
      • Do not use include "..." (Julia) to load code from other "software modules" (use import/using instead).
      • include "path/to/some/module.jl" (Julia) would instantiate multiple versions of the same code in different modules (creating distinct types (etc.) with the same names).
      • include "somefile.jl" is typically used to assemble multiple files within the same Julia package ("software module"). It is therefore relatively straightforward to ensure file are included only once (No #ifdef confusion).

    Julia ⇔ C/C++: Module interface

    • C++ exposes interfaces using "public" .h/.hpp files whereas Julia modules mark specific symbols that are intended for their users as publicor exported.
      • Often, Julia modules simply add functionality by generating new "methods" to existing functions (ex: Base.push!).
      • Developers of Julia packages therefore cannot rely on header files for interface documentation.
      • Interfaces for Julia packages are typically described using docstrings, README.md, static web pages, ...
    • Some developers choose not to export all symbols required to use their package/module, but should still mark unexported user facing symbols as public.
      • Users might be expected to access these components by qualifying functions/structs/... with the package/module name (ex: MyModule.run_this_task(...)).

    Julia ⇔ C/C++: Quick reference

    Software ConceptJuliaC/C++
    unnamed scopebegin ... end{ ... }
    function scopefunction x() ... endint x() { ... }
    global scopemodule MyMod ... endnamespace MyNS { ... }
    software moduleA Julia "package".h/.hpp files<br>+compiled somelib.a
    assembling<br>software modulesSomePkg.jl: ...<br>import("subfile1.jl")<br>import("subfile2.jl")<br>...$(AR) *.o &rArr; somelib.a
    import<br>software moduleimport SomePkg#include <somelib><br>+link in somelib.a
    module libraryLOAD_PATH[], *Git repository,<br>**custom package registrymore .h/.hpp files<br>+bigger compiled somebiglib.a

    * The Julia package manager supports registering multiple packages from a single Git repository.<br> * This allows users to house a library of related packages in a single repository.<br> ** Julia registries are primarily designed to provide versioning \& distribution of packages.<br> ** Custom package registries can be used to create a type of module library.

    Noteworthy differences from Common Lisp

    • Julia uses 1-based indexing for arrays by default, and it can also handle arbitrary index offsets.

    • Functions and variables share the same namespace (“Lisp-1”).

    • There is a Pair type, but it is not meant to be used as a COMMON-LISP:CONS. Various iterable collections can be used interchangeably in most parts of the language (eg splatting, tuples, etc). Tuples are the closest to Common Lisp lists for short collections of heterogeneous elements. Use NamedTuples in place of alists. For larger collections of homogeneous types, Arrays and Dicts should be used.

    • The typical Julia workflow for prototyping also uses continuous manipulation of the image, implemented with the Revise.jl package.

    • For performance, Julia prefers that operations have type stability. Where Common Lisp abstracts away from the underlying machine operations, Julia cleaves closer to them. For example:

      • Integer division using / always returns a floating-point result, even if the computation is exact.
        • // always returns a rational result
        • ÷ always returns a (truncated) integer result
      • Bignums are supported, but conversion is not automatic; ordinary integers overflow.
      • Complex numbers are supported, but to get complex results, you need complex inputs.
      • There are multiple Complex and Rational types, with different component types.
    • Modules (namespaces) can be hierarchical. import and using have a dual role: they load the code and make it available in the namespace. import for only the module name is possible (roughly equivalent to ASDF:LOAD-OP). Slot names don't need to be exported separately. Global variables can't be assigned to from outside the module (except with eval(mod, :(var = val)) as an escape hatch).

    • Macros start with @, and are not as seamlessly integrated into the language as Common Lisp; consequently, macro usage is not as widespread as in the latter. A form of hygiene for macros is supported by the language. Because of the different surface syntax, there is no equivalent to COMMON-LISP:&BODY.

    • All functions are generic and use multiple dispatch. Argument lists don't have to follow the same template, which leads to a powerful idiom (see do). Optional and keyword arguments are handled differently. Method ambiguities are not resolved like in the Common Lisp Object System, necessitating the definition of a more specific method for the intersection.

    • Symbols do not belong to any package, and do not contain any values per se. M.var evaluates the symbol var in the module M.

    • A functional programming style is fully supported by the language, including closures, but isn't always the idiomatic solution for Julia. Some workarounds may be necessary for performance when modifying captured variables.

    diff --git a/en/v1.12-dev/manual/parallel-computing/index.html b/en/v1.12-dev/manual/parallel-computing/index.html index e4de3b04f9dd..567561e0ea5e 100644 --- a/en/v1.12-dev/manual/parallel-computing/index.html +++ b/en/v1.12-dev/manual/parallel-computing/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Parallel Computing

    Julia supports these four categories of concurrent and parallel programming:

    1. Asynchronous "tasks", or coroutines:

      Julia Tasks allow suspending and resuming computations for I/O, event handling, producer-consumer processes, and similar patterns. Tasks can synchronize through operations like wait and fetch, and communicate via Channels. While strictly not parallel computing by themselves, Julia lets you schedule Tasks on several threads.

    2. Multi-threading:

      Julia's multi-threading provides the ability to schedule Tasks simultaneously on more than one thread or CPU core, sharing memory. This is usually the easiest way to get parallelism on one's PC or on a single large multi-core server. Julia's multi-threading is composable. When one multi-threaded function calls another multi-threaded function, Julia will schedule all the threads globally on available resources, without oversubscribing.

    3. Distributed computing:

      Distributed computing runs multiple Julia processes with separate memory spaces. These can be on the same computer or multiple computers. The Distributed standard library provides the capability for remote execution of a Julia function. With this basic building block, it is possible to build many different kinds of distributed computing abstractions. Packages like DistributedArrays.jl are an example of such an abstraction. On the other hand, packages like MPI.jl and Elemental.jl provide access to the existing MPI ecosystem of libraries.

    4. GPU computing:

      The Julia GPU compiler provides the ability to run Julia code natively on GPUs. There is a rich ecosystem of Julia packages that target GPUs. The JuliaGPU.org website provides a list of capabilities, supported GPUs, related packages and documentation.

    +

    Parallel Computing

    Julia supports these four categories of concurrent and parallel programming:

    1. Asynchronous "tasks", or coroutines:

      Julia Tasks allow suspending and resuming computations for I/O, event handling, producer-consumer processes, and similar patterns. Tasks can synchronize through operations like wait and fetch, and communicate via Channels. While strictly not parallel computing by themselves, Julia lets you schedule Tasks on several threads.

    2. Multi-threading:

      Julia's multi-threading provides the ability to schedule Tasks simultaneously on more than one thread or CPU core, sharing memory. This is usually the easiest way to get parallelism on one's PC or on a single large multi-core server. Julia's multi-threading is composable. When one multi-threaded function calls another multi-threaded function, Julia will schedule all the threads globally on available resources, without oversubscribing.

    3. Distributed computing:

      Distributed computing runs multiple Julia processes with separate memory spaces. These can be on the same computer or multiple computers. The Distributed standard library provides the capability for remote execution of a Julia function. With this basic building block, it is possible to build many different kinds of distributed computing abstractions. Packages like DistributedArrays.jl are an example of such an abstraction. On the other hand, packages like MPI.jl and Elemental.jl provide access to the existing MPI ecosystem of libraries.

    4. GPU computing:

      The Julia GPU compiler provides the ability to run Julia code natively on GPUs. There is a rich ecosystem of Julia packages that target GPUs. The JuliaGPU.org website provides a list of capabilities, supported GPUs, related packages and documentation.

    diff --git a/en/v1.12-dev/manual/performance-tips/index.html b/en/v1.12-dev/manual/performance-tips/index.html index f54612e6f90a..ec9f41c4ab18 100644 --- a/en/v1.12-dev/manual/performance-tips/index.html +++ b/en/v1.12-dev/manual/performance-tips/index.html @@ -593,4 +593,4 @@ x -> x * r end return f -end

    The let block creates a new variable r whose scope is only the inner function. The second technique recovers full language performance in the presence of captured variables. Note that this is a rapidly evolving aspect of the compiler, and it is likely that future releases will not require this degree of programmer annotation to attain performance. In the mean time, some user-contributed packages like FastClosures automate the insertion of let statements as in abmult3.

    Multithreading and linear algebra

    This section applies to multithreaded Julia code which, in each thread, performs linear algebra operations. Indeed, these linear algebra operations involve BLAS / LAPACK calls, which are themselves multithreaded. In this case, one must ensure that cores aren't oversubscribed due to the two different types of multithreading.

    Julia compiles and uses its own copy of OpenBLAS for linear algebra, whose number of threads is controlled by the environment variable OPENBLAS_NUM_THREADS. It can either be set as a command line option when launching Julia, or modified during the Julia session with BLAS.set_num_threads(N) (the submodule BLAS is exported by using LinearAlgebra). Its current value can be accessed with BLAS.get_num_threads().

    When the user does not specify anything, Julia tries to choose a reasonable value for the number of OpenBLAS threads (e.g. based on the platform, the Julia version, etc.). However, it is generally recommended to check and set the value manually. The OpenBLAS behavior is as follows:

    When you start Julia in multithreaded mode with JULIA_NUM_THREADS=X, it is generally recommended to set OPENBLAS_NUM_THREADS=1. Given the behavior described above, increasing the number of BLAS threads to N>1 can very easily lead to worse performance, in particular when N<<X. However this is just a rule of thumb, and the best way to set each number of threads is to experiment on your specific application.

    Alternative linear algebra backends

    As an alternative to OpenBLAS, there exist several other backends that can help with linear algebra performance. Prominent examples include MKL.jl and AppleAccelerate.jl.

    These are external packages, so we will not discuss them in detail here. Please refer to their respective documentations (especially because they have different behaviors than OpenBLAS with respect to multithreading).

    +end

    The let block creates a new variable r whose scope is only the inner function. The second technique recovers full language performance in the presence of captured variables. Note that this is a rapidly evolving aspect of the compiler, and it is likely that future releases will not require this degree of programmer annotation to attain performance. In the mean time, some user-contributed packages like FastClosures automate the insertion of let statements as in abmult3.

    Multithreading and linear algebra

    This section applies to multithreaded Julia code which, in each thread, performs linear algebra operations. Indeed, these linear algebra operations involve BLAS / LAPACK calls, which are themselves multithreaded. In this case, one must ensure that cores aren't oversubscribed due to the two different types of multithreading.

    Julia compiles and uses its own copy of OpenBLAS for linear algebra, whose number of threads is controlled by the environment variable OPENBLAS_NUM_THREADS. It can either be set as a command line option when launching Julia, or modified during the Julia session with BLAS.set_num_threads(N) (the submodule BLAS is exported by using LinearAlgebra). Its current value can be accessed with BLAS.get_num_threads().

    When the user does not specify anything, Julia tries to choose a reasonable value for the number of OpenBLAS threads (e.g. based on the platform, the Julia version, etc.). However, it is generally recommended to check and set the value manually. The OpenBLAS behavior is as follows:

    When you start Julia in multithreaded mode with JULIA_NUM_THREADS=X, it is generally recommended to set OPENBLAS_NUM_THREADS=1. Given the behavior described above, increasing the number of BLAS threads to N>1 can very easily lead to worse performance, in particular when N<<X. However this is just a rule of thumb, and the best way to set each number of threads is to experiment on your specific application.

    Alternative linear algebra backends

    As an alternative to OpenBLAS, there exist several other backends that can help with linear algebra performance. Prominent examples include MKL.jl and AppleAccelerate.jl.

    These are external packages, so we will not discuss them in detail here. Please refer to their respective documentations (especially because they have different behaviors than OpenBLAS with respect to multithreading).

    diff --git a/en/v1.12-dev/manual/running-external-programs/index.html b/en/v1.12-dev/manual/running-external-programs/index.html index 1a5c568737c7..fe931a66d2c1 100644 --- a/en/v1.12-dev/manual/running-external-programs/index.html +++ b/en/v1.12-dev/manual/running-external-programs/index.html @@ -136,4 +136,4 @@ foo ever! julia> run(addenv(`sh -c "echo foo \$HOWLONG"`, "HOWLONG" => "ever!")); -foo ever! +foo ever! diff --git a/en/v1.12-dev/manual/stacktraces/index.html b/en/v1.12-dev/manual/stacktraces/index.html index b090735b38de..d29ed4e92db5 100644 --- a/en/v1.12-dev/manual/stacktraces/index.html +++ b/en/v1.12-dev/manual/stacktraces/index.html @@ -196,4 +196,4 @@ jl_apply_generic at gf.c:2167 julia> println("The top frame is from $(frame[1].func)!") -The top frame is from jl_apply_generic! +The top frame is from jl_apply_generic! diff --git a/en/v1.12-dev/manual/strings/index.html b/en/v1.12-dev/manual/strings/index.html index fa4818ded025..119ba98265cf 100644 --- a/en/v1.12-dev/manual/strings/index.html +++ b/en/v1.12-dev/manual/strings/index.html @@ -469,4 +469,4 @@ "hello there julia" julia> str * str2 == Base.annotatedstring(str, str2) # *-concatenation still works -true

    The annotations of a AnnotatedString can be accessed and modified via the annotations and annotate! functions.

    +true

    The annotations of a AnnotatedString can be accessed and modified via the annotations and annotate! functions.

    diff --git a/en/v1.12-dev/manual/style-guide/index.html b/en/v1.12-dev/manual/style-guide/index.html index 222082e6cfb0..2eb4ede9af17 100644 --- a/en/v1.12-dev/manual/style-guide/index.html +++ b/en/v1.12-dev/manual/style-guide/index.html @@ -72,4 +72,4 @@ 1.0 julia> h(1) -2//1

    Thus, use Int literals when possible, with Rational{Int} for literal non-integer numbers, in order to make it easier to use your code.

    +2//1

    Thus, use Int literals when possible, with Rational{Int} for literal non-integer numbers, in order to make it easier to use your code.

    diff --git a/en/v1.12-dev/manual/types/index.html b/en/v1.12-dev/manual/types/index.html index a7725ed05d3b..49ca12d1f543 100644 --- a/en/v1.12-dev/manual/types/index.html +++ b/en/v1.12-dev/manual/types/index.html @@ -463,4 +463,4 @@ "First" julia> firstlast(Val(false)) -"Last"

    For consistency across Julia, the call site should always pass a Val instance rather than using a type, i.e., use foo(Val(:bar)) rather than foo(Val{:bar}).

    It's worth noting that it's extremely easy to mis-use parametric "value" types, including Val; in unfavorable cases, you can easily end up making the performance of your code much worse. In particular, you would never want to write actual code as illustrated above. For more information about the proper (and improper) uses of Val, please read the more extensive discussion in the performance tips.

    +"Last"

    For consistency across Julia, the call site should always pass a Val instance rather than using a type, i.e., use foo(Val(:bar)) rather than foo(Val{:bar}).

    It's worth noting that it's extremely easy to mis-use parametric "value" types, including Val; in unfavorable cases, you can easily end up making the performance of your code much worse. In particular, you would never want to write actual code as illustrated above. For more information about the proper (and improper) uses of Val, please read the more extensive discussion in the performance tips.

    diff --git a/en/v1.12-dev/manual/unicode-input/index.html b/en/v1.12-dev/manual/unicode-input/index.html index 084a35acbda5..e1fea6a55846 100644 --- a/en/v1.12-dev/manual/unicode-input/index.html +++ b/en/v1.12-dev/manual/unicode-input/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Unicode Input

    The following table lists Unicode characters that can be entered via tab completion of LaTeX-like abbreviations in the Julia REPL (and in various other editing environments). You can also get information on how to type a symbol by entering it in the REPL help, i.e. by typing ? and then entering the symbol in the REPL (e.g., by copy-paste from somewhere you saw the symbol).

    Warning

    This table may appear to contain missing characters in the second column, or even show characters that are inconsistent with the characters as they are rendered in the Julia REPL. In these cases, users are strongly advised to check their choice of fonts in their browser and REPL environment, as there are known issues with glyphs in many fonts.

    Code point(s)Character(s)Tab completion sequence(s)Unicode name(s)
    U+000A1¡\exclamdownInverted Exclamation Mark
    U+000A3£\sterlingPound Sign
    U+000A5¥\yenYen Sign
    U+000A6¦\brokenbarBroken Bar / Broken Vertical Bar
    U+000A7§\SSection Sign
    U+000A9©\copyright, \:copyright:Copyright Sign
    U+000AAª\ordfeminineFeminine Ordinal Indicator
    U+000AB«\guillemotleftLeft-Pointing Double Angle Quotation Mark / Left Pointing Guillemet
    U+000AC¬\negNot Sign
    U+000AE®\circledR, \:registered:Registered Sign / Registered Trade Mark Sign
    U+000AF¯\highminusMacron / Spacing Macron
    U+000B0°\degreeDegree Sign
    U+000B1±\pmPlus-Minus Sign / Plus-Or-Minus Sign
    U+000B2²\^2Superscript Two / Superscript Digit Two
    U+000B3³\^3Superscript Three / Superscript Digit Three
    U+000B6\PPilcrow Sign / Paragraph Sign
    U+000B7·\cdotpMiddle Dot
    U+000B9¹\^1Superscript One / Superscript Digit One
    U+000BAº\ordmasculineMasculine Ordinal Indicator
    U+000BB»\guillemotrightRight-Pointing Double Angle Quotation Mark / Right Pointing Guillemet
    U+000BC¼\1/4Vulgar Fraction One Quarter / Fraction One Quarter
    U+000BD½\1/2Vulgar Fraction One Half / Fraction One Half
    U+000BE¾\3/4Vulgar Fraction Three Quarters / Fraction Three Quarters
    U+000BF¿\questiondownInverted Question Mark
    U+000C5Å\AALatin Capital Letter A With Ring Above / Latin Capital Letter A Ring
    U+000C6Æ\AELatin Capital Letter Ae / Latin Capital Letter A E
    U+000D0Ð\DHLatin Capital Letter Eth
    U+000D7×\timesMultiplication Sign
    U+000D8Ø\OLatin Capital Letter O With Stroke / Latin Capital Letter O Slash
    U+000DEÞ\THLatin Capital Letter Thorn
    U+000DFß\ssLatin Small Letter Sharp S
    U+000E5å\aaLatin Small Letter A With Ring Above / Latin Small Letter A Ring
    U+000E6æ\aeLatin Small Letter Ae / Latin Small Letter A E
    U+000F0ð\eth, \dhLatin Small Letter Eth
    U+000F7÷\divDivision Sign
    U+000F8ø\oLatin Small Letter O With Stroke / Latin Small Letter O Slash
    U+000FEþ\thLatin Small Letter Thorn
    U+00110Đ\DJLatin Capital Letter D With Stroke / Latin Capital Letter D Bar
    U+00111đ\djLatin Small Letter D With Stroke / Latin Small Letter D Bar
    U+00127ħ\hbarLatin Small Letter H With Stroke / Latin Small Letter H Bar
    U+00131ı\imathLatin Small Letter Dotless I
    U+00141Ł\LLatin Capital Letter L With Stroke / Latin Capital Letter L Slash
    U+00142ł\lLatin Small Letter L With Stroke / Latin Small Letter L Slash
    U+0014AŊ\NGLatin Capital Letter Eng
    U+0014Bŋ\ngLatin Small Letter Eng
    U+00152Œ\OELatin Capital Ligature Oe / Latin Capital Letter O E
    U+00153œ\oeLatin Small Ligature Oe / Latin Small Letter O E
    U+00195ƕ\hvligLatin Small Letter Hv / Latin Small Letter H V
    U+0019Eƞ\nrlegLatin Small Letter N With Long Right Leg
    U+001B5Ƶ\ZbarLatin Capital Letter Z With Stroke / Latin Capital Letter Z Bar
    U+001C2ǂ\doublepipeLatin Letter Alveolar Click / Latin Letter Pipe Double Bar
    U+00237ȷ\jmathLatin Small Letter Dotless J
    U+00250ɐ\trnaLatin Small Letter Turned A
    U+00252ɒ\trnsaLatin Small Letter Turned Alpha / Latin Small Letter Turned Script A
    U+00254ɔ\openoLatin Small Letter Open O
    U+00256ɖ\rtldLatin Small Letter D With Tail / Latin Small Letter D Retroflex Hook
    U+00259ə\schwaLatin Small Letter Schwa
    U+00263ɣ\pgammaLatin Small Letter Gamma
    U+00264ɤ\pbgamLatin Small Letter Rams Horn / Latin Small Letter Baby Gamma
    U+00265ɥ\trnhLatin Small Letter Turned H
    U+0026Cɬ\btdlLatin Small Letter L With Belt / Latin Small Letter L Belt
    U+0026Dɭ\rtllLatin Small Letter L With Retroflex Hook / Latin Small Letter L Retroflex Hook
    U+0026Fɯ\trnmLatin Small Letter Turned M
    U+00270ɰ\trnmlrLatin Small Letter Turned M With Long Leg
    U+00271ɱ\ltlmrLatin Small Letter M With Hook / Latin Small Letter M Hook
    U+00272ɲ\ltlnLatin Small Letter N With Left Hook / Latin Small Letter N Hook
    U+00273ɳ\rtlnLatin Small Letter N With Retroflex Hook / Latin Small Letter N Retroflex Hook
    U+00277ɷ\clomegLatin Small Letter Closed Omega
    U+00278ɸ\ltphiLatin Small Letter Phi
    U+00279ɹ\trnrLatin Small Letter Turned R
    U+0027Aɺ\trnrlLatin Small Letter Turned R With Long Leg
    U+0027Bɻ\rttrnrLatin Small Letter Turned R With Hook / Latin Small Letter Turned R Hook
    U+0027Cɼ\rlLatin Small Letter R With Long Leg
    U+0027Dɽ\rtlrLatin Small Letter R With Tail / Latin Small Letter R Hook
    U+0027Eɾ\fhrLatin Small Letter R With Fishhook / Latin Small Letter Fishhook R
    U+00282ʂ\rtlsLatin Small Letter S With Hook / Latin Small Letter S Hook
    U+00283ʃ\eshLatin Small Letter Esh
    U+00287ʇ\trntLatin Small Letter Turned T
    U+00288ʈ\rtltLatin Small Letter T With Retroflex Hook / Latin Small Letter T Retroflex Hook
    U+0028Aʊ\pupsilLatin Small Letter Upsilon
    U+0028Bʋ\pscrvLatin Small Letter V With Hook / Latin Small Letter Script V
    U+0028Cʌ\invvLatin Small Letter Turned V
    U+0028Dʍ\invwLatin Small Letter Turned W
    U+0028Eʎ\trnyLatin Small Letter Turned Y
    U+00290ʐ\rtlzLatin Small Letter Z With Retroflex Hook / Latin Small Letter Z Retroflex Hook
    U+00292ʒ\yoghLatin Small Letter Ezh / Latin Small Letter Yogh
    U+00294ʔ\glstLatin Letter Glottal Stop
    U+00295ʕ\reglstLatin Letter Pharyngeal Voiced Fricative / Latin Letter Reversed Glottal Stop
    U+00296ʖ\inglstLatin Letter Inverted Glottal Stop
    U+0029Eʞ\turnkLatin Small Letter Turned K
    U+002A4ʤ\dyoghLatin Small Letter Dezh Digraph / Latin Small Letter D Yogh
    U+002A7ʧ\teshLatin Small Letter Tesh Digraph / Latin Small Letter T Esh
    U+002B0ʰ\^hModifier Letter Small H
    U+002B2ʲ\^jModifier Letter Small J
    U+002B3ʳ\^rModifier Letter Small R
    U+002B7ʷ\^wModifier Letter Small W
    U+002B8ʸ\^yModifier Letter Small Y
    U+002BCʼ\raspModifier Letter Apostrophe
    U+002C8ˈ\vertsModifier Letter Vertical Line
    U+002CCˌ\vertiModifier Letter Low Vertical Line
    U+002D0ː\lmrkModifier Letter Triangular Colon
    U+002D1ˑ\hlmrkModifier Letter Half Triangular Colon
    U+002D2˒\sbrhrModifier Letter Centred Right Half Ring / Modifier Letter Centered Right Half Ring
    U+002D3˓\sblhrModifier Letter Centred Left Half Ring / Modifier Letter Centered Left Half Ring
    U+002D4˔\raisModifier Letter Up Tack
    U+002D5˕\lowModifier Letter Down Tack
    U+002D8˘\uBreve / Spacing Breve
    U+002DC˜\tildelowSmall Tilde / Spacing Tilde
    U+002E1ˡ\^lModifier Letter Small L
    U+002E2ˢ\^sModifier Letter Small S
    U+002E3ˣ\^xModifier Letter Small X
    U+00300 ̀ \graveCombining Grave Accent / Non-Spacing Grave
    U+00301 ́ \acuteCombining Acute Accent / Non-Spacing Acute
    U+00302 ̂ \hatCombining Circumflex Accent / Non-Spacing Circumflex
    U+00303 ̃ \tildeCombining Tilde / Non-Spacing Tilde
    U+00304 ̄ \barCombining Macron / Non-Spacing Macron
    U+00305 ̅ \overbarCombining Overline / Non-Spacing Overscore
    U+00306 ̆ \breveCombining Breve / Non-Spacing Breve
    U+00307 ̇ \dotCombining Dot Above / Non-Spacing Dot Above
    U+00308 ̈ \ddotCombining Diaeresis / Non-Spacing Diaeresis
    U+00309 ̉ \ovhookCombining Hook Above / Non-Spacing Hook Above
    U+0030A ̊ \ocircCombining Ring Above / Non-Spacing Ring Above
    U+0030B ̋ \HCombining Double Acute Accent / Non-Spacing Double Acute
    U+0030C ̌ \checkCombining Caron / Non-Spacing Hacek
    U+00310 ̐ \candraCombining Candrabindu / Non-Spacing Candrabindu
    U+00312 ̒ \oturnedcommaCombining Turned Comma Above / Non-Spacing Turned Comma Above
    U+00315 ̕ \ocommatoprightCombining Comma Above Right / Non-Spacing Comma Above Right
    U+0031A ̚ \droangCombining Left Angle Above / Non-Spacing Left Angle Above
    U+00321 ̡ \palhCombining Palatalized Hook Below / Non-Spacing Palatalized Hook Below
    U+00322 ̢ \rhCombining Retroflex Hook Below / Non-Spacing Retroflex Hook Below
    U+00327 ̧ \cCombining Cedilla / Non-Spacing Cedilla
    U+00328 ̨ \kCombining Ogonek / Non-Spacing Ogonek
    U+0032A ̪ \sbbrgCombining Bridge Below / Non-Spacing Bridge Below
    U+00330 ̰ \wideutildeCombining Tilde Below / Non-Spacing Tilde Below
    U+00332 ̲ \underbarCombining Low Line / Non-Spacing Underscore
    U+00336 ̶ \strike, \soutCombining Long Stroke Overlay / Non-Spacing Long Bar Overlay
    U+00338 ̸ \notCombining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0034D ͍ \underleftrightarrowCombining Left Right Arrow Below
    U+00391Α\AlphaGreek Capital Letter Alpha
    U+00392Β\BetaGreek Capital Letter Beta
    U+00393Γ\GammaGreek Capital Letter Gamma
    U+00394Δ\DeltaGreek Capital Letter Delta
    U+00395Ε\EpsilonGreek Capital Letter Epsilon
    U+00396Ζ\ZetaGreek Capital Letter Zeta
    U+00397Η\EtaGreek Capital Letter Eta
    U+00398Θ\ThetaGreek Capital Letter Theta
    U+00399Ι\IotaGreek Capital Letter Iota
    U+0039AΚ\KappaGreek Capital Letter Kappa
    U+0039BΛ\LambdaGreek Capital Letter Lamda / Greek Capital Letter Lambda
    U+0039CΜ\MuGreek Capital Letter Mu
    U+0039DΝ\NuGreek Capital Letter Nu
    U+0039EΞ\XiGreek Capital Letter Xi
    U+0039FΟ\OmicronGreek Capital Letter Omicron
    U+003A0Π\PiGreek Capital Letter Pi
    U+003A1Ρ\RhoGreek Capital Letter Rho
    U+003A3Σ\SigmaGreek Capital Letter Sigma
    U+003A4Τ\TauGreek Capital Letter Tau
    U+003A5Υ\UpsilonGreek Capital Letter Upsilon
    U+003A6Φ\PhiGreek Capital Letter Phi
    U+003A7Χ\ChiGreek Capital Letter Chi
    U+003A8Ψ\PsiGreek Capital Letter Psi
    U+003A9Ω\OmegaGreek Capital Letter Omega
    U+003B1α\alphaGreek Small Letter Alpha
    U+003B2β\betaGreek Small Letter Beta
    U+003B3γ\gammaGreek Small Letter Gamma
    U+003B4δ\deltaGreek Small Letter Delta
    U+003B5ε\varepsilonGreek Small Letter Epsilon
    U+003B6ζ\zetaGreek Small Letter Zeta
    U+003B7η\etaGreek Small Letter Eta
    U+003B8θ\thetaGreek Small Letter Theta
    U+003B9ι\iotaGreek Small Letter Iota
    U+003BAκ\kappaGreek Small Letter Kappa
    U+003BBλ\lambdaGreek Small Letter Lamda / Greek Small Letter Lambda
    U+003BCμ\muGreek Small Letter Mu
    U+003BDν\nuGreek Small Letter Nu
    U+003BEξ\xiGreek Small Letter Xi
    U+003BFο\omicronGreek Small Letter Omicron
    U+003C0π\piGreek Small Letter Pi
    U+003C1ρ\rhoGreek Small Letter Rho
    U+003C2ς\varsigmaGreek Small Letter Final Sigma
    U+003C3σ\sigmaGreek Small Letter Sigma
    U+003C4τ\tauGreek Small Letter Tau
    U+003C5υ\upsilonGreek Small Letter Upsilon
    U+003C6φ\varphiGreek Small Letter Phi
    U+003C7χ\chiGreek Small Letter Chi
    U+003C8ψ\psiGreek Small Letter Psi
    U+003C9ω\omegaGreek Small Letter Omega
    U+003D0ϐ\varbetaGreek Beta Symbol / Greek Small Letter Curled Beta
    U+003D1ϑ\varthetaGreek Theta Symbol / Greek Small Letter Script Theta
    U+003D5ϕ\phiGreek Phi Symbol / Greek Small Letter Script Phi
    U+003D6ϖ\varpiGreek Pi Symbol / Greek Small Letter Omega Pi
    U+003D8Ϙ\oldKoppaGreek Letter Archaic Koppa
    U+003D9ϙ\oldkoppaGreek Small Letter Archaic Koppa
    U+003DAϚ\StigmaGreek Letter Stigma / Greek Capital Letter Stigma
    U+003DBϛ\stigmaGreek Small Letter Stigma
    U+003DCϜ\DigammaGreek Letter Digamma / Greek Capital Letter Digamma
    U+003DDϝ\digammaGreek Small Letter Digamma
    U+003DEϞ\KoppaGreek Letter Koppa / Greek Capital Letter Koppa
    U+003DFϟ\koppaGreek Small Letter Koppa
    U+003E0Ϡ\SampiGreek Letter Sampi / Greek Capital Letter Sampi
    U+003E1ϡ\sampiGreek Small Letter Sampi
    U+003F0ϰ\varkappaGreek Kappa Symbol / Greek Small Letter Script Kappa
    U+003F1ϱ\varrhoGreek Rho Symbol / Greek Small Letter Tailed Rho
    U+003F4ϴ\varThetaGreek Capital Theta Symbol
    U+003F5ϵ\epsilonGreek Lunate Epsilon Symbol
    U+003F6϶\backepsilonGreek Reversed Lunate Epsilon Symbol
    U+01D2C\^AModifier Letter Capital A
    U+01D2E\^BModifier Letter Capital B
    U+01D30\^DModifier Letter Capital D
    U+01D31\^EModifier Letter Capital E
    U+01D33\^GModifier Letter Capital G
    U+01D34\^HModifier Letter Capital H
    U+01D35\^IModifier Letter Capital I
    U+01D36\^JModifier Letter Capital J
    U+01D37\^KModifier Letter Capital K
    U+01D38\^LModifier Letter Capital L
    U+01D39\^MModifier Letter Capital M
    U+01D3A\^NModifier Letter Capital N
    U+01D3C\^OModifier Letter Capital O
    U+01D3E\^PModifier Letter Capital P
    U+01D3Fᴿ\^RModifier Letter Capital R
    U+01D40\^TModifier Letter Capital T
    U+01D41\^UModifier Letter Capital U
    U+01D42\^WModifier Letter Capital W
    U+01D43\^aModifier Letter Small A
    U+01D45\^alphaModifier Letter Small Alpha
    U+01D47\^bModifier Letter Small B
    U+01D48\^dModifier Letter Small D
    U+01D49\^eModifier Letter Small E
    U+01D4B\^epsilonModifier Letter Small Open E
    U+01D4D\^gModifier Letter Small G
    U+01D4F\^kModifier Letter Small K
    U+01D50\^mModifier Letter Small M
    U+01D52\^oModifier Letter Small O
    U+01D56\^pModifier Letter Small P
    U+01D57\^tModifier Letter Small T
    U+01D58\^uModifier Letter Small U
    U+01D5B\^vModifier Letter Small V
    U+01D5D\^betaModifier Letter Small Beta
    U+01D5E\^gammaModifier Letter Small Greek Gamma
    U+01D5F\^deltaModifier Letter Small Delta
    U+01D60\^phiModifier Letter Small Greek Phi
    U+01D61\^chiModifier Letter Small Chi
    U+01D62\_iLatin Subscript Small Letter I
    U+01D63\_rLatin Subscript Small Letter R
    U+01D64\_uLatin Subscript Small Letter U
    U+01D65\_vLatin Subscript Small Letter V
    U+01D66\_betaGreek Subscript Small Letter Beta
    U+01D67\_gammaGreek Subscript Small Letter Gamma
    U+01D68\_rhoGreek Subscript Small Letter Rho
    U+01D69\_phiGreek Subscript Small Letter Phi
    U+01D6A\_chiGreek Subscript Small Letter Chi
    U+01D9C\^cModifier Letter Small C
    U+01DA0\^fModifier Letter Small F
    U+01DA5\^iotaModifier Letter Small Iota
    U+01DB2\^ltphiModifier Letter Small Phi
    U+01DBB\^zModifier Letter Small Z
    U+01DBFᶿ\^thetaModifier Letter Small Theta
    U+02002\enspaceEn Space
    U+02003\quadEm Space
    U+02005\thickspaceFour-Per-Em Space
    U+02009\thinspaceThin Space
    U+0200A\hspaceHair Space
    U+02013\endashEn Dash
    U+02014\emdashEm Dash
    U+02016\VertDouble Vertical Line / Double Vertical Bar
    U+02018\lqLeft Single Quotation Mark / Single Turned Comma Quotation Mark
    U+02019\rqRight Single Quotation Mark / Single Comma Quotation Mark
    U+0201B\reaposSingle High-Reversed-9 Quotation Mark / Single Reversed Comma Quotation Mark
    U+0201C\ldqLeft Double Quotation Mark / Double Turned Comma Quotation Mark
    U+0201D\rdqRight Double Quotation Mark / Double Comma Quotation Mark
    U+02020\daggerDagger
    U+02021\ddaggerDouble Dagger
    U+02022\bulletBullet
    U+02026\dots, \ldotsHorizontal Ellipsis
    U+02030\perthousandPer Mille Sign
    U+02031\pertenthousandPer Ten Thousand Sign
    U+02032\primePrime
    U+02033\pprimeDouble Prime
    U+02034\ppprimeTriple Prime
    U+02035\backprimeReversed Prime
    U+02036\backpprimeReversed Double Prime
    U+02037\backppprimeReversed Triple Prime
    U+02039\guilsinglleftSingle Left-Pointing Angle Quotation Mark / Left Pointing Single Guillemet
    U+0203A\guilsinglrightSingle Right-Pointing Angle Quotation Mark / Right Pointing Single Guillemet
    U+0203C\:bangbang:Double Exclamation Mark
    U+02040\tieconcatCharacter Tie
    U+02049\:interrobang:Exclamation Question Mark
    U+02057\pppprimeQuadruple Prime
    U+0205D\tricolonTricolon
    U+02060\nolinebreakWord Joiner
    U+02070\^0Superscript Zero / Superscript Digit Zero
    U+02071\^iSuperscript Latin Small Letter I
    U+02074\^4Superscript Four / Superscript Digit Four
    U+02075\^5Superscript Five / Superscript Digit Five
    U+02076\^6Superscript Six / Superscript Digit Six
    U+02077\^7Superscript Seven / Superscript Digit Seven
    U+02078\^8Superscript Eight / Superscript Digit Eight
    U+02079\^9Superscript Nine / Superscript Digit Nine
    U+0207A\^+Superscript Plus Sign
    U+0207B\^-Superscript Minus / Superscript Hyphen-Minus
    U+0207C\^=Superscript Equals Sign
    U+0207D\^(Superscript Left Parenthesis / Superscript Opening Parenthesis
    U+0207E\^)Superscript Right Parenthesis / Superscript Closing Parenthesis
    U+0207F\^nSuperscript Latin Small Letter N
    U+02080\_0Subscript Zero / Subscript Digit Zero
    U+02081\_1Subscript One / Subscript Digit One
    U+02082\_2Subscript Two / Subscript Digit Two
    U+02083\_3Subscript Three / Subscript Digit Three
    U+02084\_4Subscript Four / Subscript Digit Four
    U+02085\_5Subscript Five / Subscript Digit Five
    U+02086\_6Subscript Six / Subscript Digit Six
    U+02087\_7Subscript Seven / Subscript Digit Seven
    U+02088\_8Subscript Eight / Subscript Digit Eight
    U+02089\_9Subscript Nine / Subscript Digit Nine
    U+0208A\_+Subscript Plus Sign
    U+0208B\_-Subscript Minus / Subscript Hyphen-Minus
    U+0208C\_=Subscript Equals Sign
    U+0208D\_(Subscript Left Parenthesis / Subscript Opening Parenthesis
    U+0208E\_)Subscript Right Parenthesis / Subscript Closing Parenthesis
    U+02090\_aLatin Subscript Small Letter A
    U+02091\_eLatin Subscript Small Letter E
    U+02092\_oLatin Subscript Small Letter O
    U+02093\_xLatin Subscript Small Letter X
    U+02094\_schwaLatin Subscript Small Letter Schwa
    U+02095\_hLatin Subscript Small Letter H
    U+02096\_kLatin Subscript Small Letter K
    U+02097\_lLatin Subscript Small Letter L
    U+02098\_mLatin Subscript Small Letter M
    U+02099\_nLatin Subscript Small Letter N
    U+0209A\_pLatin Subscript Small Letter P
    U+0209B\_sLatin Subscript Small Letter S
    U+0209C\_tLatin Subscript Small Letter T
    U+020A7\pesPeseta Sign
    U+020AC\euroEuro Sign
    U+020D0 ⃐ \leftharpoonaccentCombining Left Harpoon Above / Non-Spacing Left Harpoon Above
    U+020D1 ⃑ \rightharpoonaccentCombining Right Harpoon Above / Non-Spacing Right Harpoon Above
    U+020D2 ⃒ \vertoverlayCombining Long Vertical Line Overlay / Non-Spacing Long Vertical Bar Overlay
    U+020D6 ⃖ \overleftarrowCombining Left Arrow Above / Non-Spacing Left Arrow Above
    U+020D7 ⃗ \vecCombining Right Arrow Above / Non-Spacing Right Arrow Above
    U+020DB ⃛ \dddotCombining Three Dots Above / Non-Spacing Three Dots Above
    U+020DC ⃜ \ddddotCombining Four Dots Above / Non-Spacing Four Dots Above
    U+020DD ⃝ \enclosecircleCombining Enclosing Circle / Enclosing Circle
    U+020DE ⃞ \enclosesquareCombining Enclosing Square / Enclosing Square
    U+020DF ⃟ \enclosediamondCombining Enclosing Diamond / Enclosing Diamond
    U+020E1 ⃡ \overleftrightarrowCombining Left Right Arrow Above / Non-Spacing Left Right Arrow Above
    U+020E4 ⃤ \enclosetriangleCombining Enclosing Upward Pointing Triangle
    U+020E7 ⃧ \annuityCombining Annuity Symbol
    U+020E8 ⃨ \threeunderdotCombining Triple Underdot
    U+020E9 ⃩ \widebridgeaboveCombining Wide Bridge Above
    U+020EC ⃬ \underrightharpoondownCombining Rightwards Harpoon With Barb Downwards
    U+020ED ⃭ \underleftharpoondownCombining Leftwards Harpoon With Barb Downwards
    U+020EE ⃮ \underleftarrowCombining Left Arrow Below
    U+020EF ⃯ \underrightarrowCombining Right Arrow Below
    U+020F0 ⃰ \asteraccentCombining Asterisk Above
    U+02102\bbCDouble-Struck Capital C / Double-Struck C
    U+02107\eulermascheroniEuler Constant / Eulers
    U+0210A\scrgScript Small G
    U+0210B\scrHScript Capital H / Script H
    U+0210C\frakHBlack-Letter Capital H / Black-Letter H
    U+0210D\bbHDouble-Struck Capital H / Double-Struck H
    U+0210E\ith, \planckPlanck Constant
    U+0210F\hslashPlanck Constant Over Two Pi / Planck Constant Over 2 Pi
    U+02110\scrIScript Capital I / Script I
    U+02111\Im, \frakIBlack-Letter Capital I / Black-Letter I
    U+02112\scrLScript Capital L / Script L
    U+02113\ellScript Small L
    U+02115\bbNDouble-Struck Capital N / Double-Struck N
    U+02116\numeroNumero Sign / Numero
    U+02118\wpScript Capital P / Script P
    U+02119\bbPDouble-Struck Capital P / Double-Struck P
    U+0211A\bbQDouble-Struck Capital Q / Double-Struck Q
    U+0211B\scrRScript Capital R / Script R
    U+0211C\Re, \frakRBlack-Letter Capital R / Black-Letter R
    U+0211D\bbRDouble-Struck Capital R / Double-Struck R
    U+0211E\xratPrescription Take
    U+02122\trademark, \:tm:Trade Mark Sign / Trademark
    U+02124\bbZDouble-Struck Capital Z / Double-Struck Z
    U+02126\ohmOhm Sign / Ohm
    U+02127\mhoInverted Ohm Sign / Mho
    U+02128\frakZBlack-Letter Capital Z / Black-Letter Z
    U+02129\turnediotaTurned Greek Small Letter Iota
    U+0212B\AngstromAngstrom Sign / Angstrom Unit
    U+0212C\scrBScript Capital B / Script B
    U+0212D\frakCBlack-Letter Capital C / Black-Letter C
    U+0212F\scre, \eulerScript Small E
    U+02130\scrEScript Capital E / Script E
    U+02131\scrFScript Capital F / Script F
    U+02132\FinvTurned Capital F / Turned F
    U+02133\scrMScript Capital M / Script M
    U+02134\scroScript Small O
    U+02135\alephAlef Symbol / First Transfinite Cardinal
    U+02136\bethBet Symbol / Second Transfinite Cardinal
    U+02137\gimelGimel Symbol / Third Transfinite Cardinal
    U+02138\dalethDalet Symbol / Fourth Transfinite Cardinal
    U+02139\:information_source:Information Source
    U+0213C\bbpiDouble-Struck Small Pi
    U+0213D\bbgammaDouble-Struck Small Gamma
    U+0213E\bbGammaDouble-Struck Capital Gamma
    U+0213F\bbPiDouble-Struck Capital Pi
    U+02140\bbsumDouble-Struck N-Ary Summation
    U+02141\GameTurned Sans-Serif Capital G
    U+02142\sansLturnedTurned Sans-Serif Capital L
    U+02143\sansLmirroredReversed Sans-Serif Capital L
    U+02144\YupTurned Sans-Serif Capital Y
    U+02145\bbiDDouble-Struck Italic Capital D
    U+02146\bbidDouble-Struck Italic Small D
    U+02147\bbieDouble-Struck Italic Small E
    U+02148\bbiiDouble-Struck Italic Small I
    U+02149\bbijDouble-Struck Italic Small J
    U+0214A\PropertyLineProperty Line
    U+0214B\upandTurned Ampersand
    U+02150\1/7Vulgar Fraction One Seventh
    U+02151\1/9Vulgar Fraction One Ninth
    U+02152\1/10Vulgar Fraction One Tenth
    U+02153\1/3Vulgar Fraction One Third / Fraction One Third
    U+02154\2/3Vulgar Fraction Two Thirds / Fraction Two Thirds
    U+02155\1/5Vulgar Fraction One Fifth / Fraction One Fifth
    U+02156\2/5Vulgar Fraction Two Fifths / Fraction Two Fifths
    U+02157\3/5Vulgar Fraction Three Fifths / Fraction Three Fifths
    U+02158\4/5Vulgar Fraction Four Fifths / Fraction Four Fifths
    U+02159\1/6Vulgar Fraction One Sixth / Fraction One Sixth
    U+0215A\5/6Vulgar Fraction Five Sixths / Fraction Five Sixths
    U+0215B\1/8Vulgar Fraction One Eighth / Fraction One Eighth
    U+0215C\3/8Vulgar Fraction Three Eighths / Fraction Three Eighths
    U+0215D\5/8Vulgar Fraction Five Eighths / Fraction Five Eighths
    U+0215E\7/8Vulgar Fraction Seven Eighths / Fraction Seven Eighths
    U+0215F\1/Fraction Numerator One
    U+02189\0/3Vulgar Fraction Zero Thirds
    U+02190\leftarrowLeftwards Arrow / Left Arrow
    U+02191\uparrowUpwards Arrow / Up Arrow
    U+02192\to, \rightarrowRightwards Arrow / Right Arrow
    U+02193\downarrowDownwards Arrow / Down Arrow
    U+02194\leftrightarrow, \:left_right_arrow:Left Right Arrow
    U+02195\updownarrow, \:arrow_up_down:Up Down Arrow
    U+02196\nwarrow, \:arrow_upper_left:North West Arrow / Upper Left Arrow
    U+02197\nearrow, \:arrow_upper_right:North East Arrow / Upper Right Arrow
    U+02198\searrow, \:arrow_lower_right:South East Arrow / Lower Right Arrow
    U+02199\swarrow, \:arrow_lower_left:South West Arrow / Lower Left Arrow
    U+0219A\nleftarrowLeftwards Arrow With Stroke / Left Arrow With Stroke
    U+0219B\nrightarrowRightwards Arrow With Stroke / Right Arrow With Stroke
    U+0219C\leftwavearrowLeftwards Wave Arrow / Left Wave Arrow
    U+0219D\rightwavearrowRightwards Wave Arrow / Right Wave Arrow
    U+0219E\twoheadleftarrowLeftwards Two Headed Arrow / Left Two Headed Arrow
    U+0219F\twoheaduparrowUpwards Two Headed Arrow / Up Two Headed Arrow
    U+021A0\twoheadrightarrowRightwards Two Headed Arrow / Right Two Headed Arrow
    U+021A1\twoheaddownarrowDownwards Two Headed Arrow / Down Two Headed Arrow
    U+021A2\leftarrowtailLeftwards Arrow With Tail / Left Arrow With Tail
    U+021A3\rightarrowtailRightwards Arrow With Tail / Right Arrow With Tail
    U+021A4\mapsfromLeftwards Arrow From Bar / Left Arrow From Bar
    U+021A5\mapsupUpwards Arrow From Bar / Up Arrow From Bar
    U+021A6\mapstoRightwards Arrow From Bar / Right Arrow From Bar
    U+021A7\mapsdownDownwards Arrow From Bar / Down Arrow From Bar
    U+021A8\updownarrowbarUp Down Arrow With Base
    U+021A9\hookleftarrow, \:leftwards_arrow_with_hook:Leftwards Arrow With Hook / Left Arrow With Hook
    U+021AA\hookrightarrow, \:arrow_right_hook:Rightwards Arrow With Hook / Right Arrow With Hook
    U+021AB\looparrowleftLeftwards Arrow With Loop / Left Arrow With Loop
    U+021AC\looparrowrightRightwards Arrow With Loop / Right Arrow With Loop
    U+021AD\leftrightsquigarrowLeft Right Wave Arrow
    U+021AE\nleftrightarrowLeft Right Arrow With Stroke
    U+021AF\downzigzagarrowDownwards Zigzag Arrow / Down Zigzag Arrow
    U+021B0\LshUpwards Arrow With Tip Leftwards / Up Arrow With Tip Left
    U+021B1\RshUpwards Arrow With Tip Rightwards / Up Arrow With Tip Right
    U+021B2\LdshDownwards Arrow With Tip Leftwards / Down Arrow With Tip Left
    U+021B3\RdshDownwards Arrow With Tip Rightwards / Down Arrow With Tip Right
    U+021B4\linefeedRightwards Arrow With Corner Downwards / Right Arrow With Corner Down
    U+021B5\carriagereturnDownwards Arrow With Corner Leftwards / Down Arrow With Corner Left
    U+021B6\curvearrowleftAnticlockwise Top Semicircle Arrow
    U+021B7\curvearrowrightClockwise Top Semicircle Arrow
    U+021B8\barovernorthwestarrowNorth West Arrow To Long Bar / Upper Left Arrow To Long Bar
    U+021B9\barleftarrowrightarrowbarLeftwards Arrow To Bar Over Rightwards Arrow To Bar / Left Arrow To Bar Over Right Arrow To Bar
    U+021BA\circlearrowleftAnticlockwise Open Circle Arrow
    U+021BB\circlearrowrightClockwise Open Circle Arrow
    U+021BC\leftharpoonupLeftwards Harpoon With Barb Upwards / Left Harpoon With Barb Up
    U+021BD\leftharpoondownLeftwards Harpoon With Barb Downwards / Left Harpoon With Barb Down
    U+021BE\upharpoonrightUpwards Harpoon With Barb Rightwards / Up Harpoon With Barb Right
    U+021BF\upharpoonleftUpwards Harpoon With Barb Leftwards / Up Harpoon With Barb Left
    U+021C0\rightharpoonupRightwards Harpoon With Barb Upwards / Right Harpoon With Barb Up
    U+021C1\rightharpoondownRightwards Harpoon With Barb Downwards / Right Harpoon With Barb Down
    U+021C2\downharpoonrightDownwards Harpoon With Barb Rightwards / Down Harpoon With Barb Right
    U+021C3\downharpoonleftDownwards Harpoon With Barb Leftwards / Down Harpoon With Barb Left
    U+021C4\rightleftarrowsRightwards Arrow Over Leftwards Arrow / Right Arrow Over Left Arrow
    U+021C5\dblarrowupdownUpwards Arrow Leftwards Of Downwards Arrow / Up Arrow Left Of Down Arrow
    U+021C6\leftrightarrowsLeftwards Arrow Over Rightwards Arrow / Left Arrow Over Right Arrow
    U+021C7\leftleftarrowsLeftwards Paired Arrows / Left Paired Arrows
    U+021C8\upuparrowsUpwards Paired Arrows / Up Paired Arrows
    U+021C9\rightrightarrowsRightwards Paired Arrows / Right Paired Arrows
    U+021CA\downdownarrowsDownwards Paired Arrows / Down Paired Arrows
    U+021CB\leftrightharpoonsLeftwards Harpoon Over Rightwards Harpoon / Left Harpoon Over Right Harpoon
    U+021CC\rightleftharpoonsRightwards Harpoon Over Leftwards Harpoon / Right Harpoon Over Left Harpoon
    U+021CD\nLeftarrowLeftwards Double Arrow With Stroke / Left Double Arrow With Stroke
    U+021CE\nLeftrightarrowLeft Right Double Arrow With Stroke
    U+021CF\nRightarrowRightwards Double Arrow With Stroke / Right Double Arrow With Stroke
    U+021D0\LeftarrowLeftwards Double Arrow / Left Double Arrow
    U+021D1\UparrowUpwards Double Arrow / Up Double Arrow
    U+021D2\RightarrowRightwards Double Arrow / Right Double Arrow
    U+021D3\DownarrowDownwards Double Arrow / Down Double Arrow
    U+021D4\LeftrightarrowLeft Right Double Arrow
    U+021D5\UpdownarrowUp Down Double Arrow
    U+021D6\NwarrowNorth West Double Arrow / Upper Left Double Arrow
    U+021D7\NearrowNorth East Double Arrow / Upper Right Double Arrow
    U+021D8\SearrowSouth East Double Arrow / Lower Right Double Arrow
    U+021D9\SwarrowSouth West Double Arrow / Lower Left Double Arrow
    U+021DA\LleftarrowLeftwards Triple Arrow / Left Triple Arrow
    U+021DB\RrightarrowRightwards Triple Arrow / Right Triple Arrow
    U+021DC\leftsquigarrowLeftwards Squiggle Arrow / Left Squiggle Arrow
    U+021DD\rightsquigarrowRightwards Squiggle Arrow / Right Squiggle Arrow
    U+021DE\nHuparrowUpwards Arrow With Double Stroke / Up Arrow With Double Stroke
    U+021DF\nHdownarrowDownwards Arrow With Double Stroke / Down Arrow With Double Stroke
    U+021E0\leftdasharrowLeftwards Dashed Arrow / Left Dashed Arrow
    U+021E1\updasharrowUpwards Dashed Arrow / Up Dashed Arrow
    U+021E2\rightdasharrowRightwards Dashed Arrow / Right Dashed Arrow
    U+021E3\downdasharrowDownwards Dashed Arrow / Down Dashed Arrow
    U+021E4\barleftarrowLeftwards Arrow To Bar / Left Arrow To Bar
    U+021E5\rightarrowbarRightwards Arrow To Bar / Right Arrow To Bar
    U+021E6\leftwhitearrowLeftwards White Arrow / White Left Arrow
    U+021E7\upwhitearrowUpwards White Arrow / White Up Arrow
    U+021E8\rightwhitearrowRightwards White Arrow / White Right Arrow
    U+021E9\downwhitearrowDownwards White Arrow / White Down Arrow
    U+021EA\whitearrowupfrombarUpwards White Arrow From Bar / White Up Arrow From Bar
    U+021F4\circleonrightarrowRight Arrow With Small Circle
    U+021F5\DownArrowUpArrowDownwards Arrow Leftwards Of Upwards Arrow
    U+021F6\rightthreearrowsThree Rightwards Arrows
    U+021F7\nvleftarrowLeftwards Arrow With Vertical Stroke
    U+021F8\nvrightarrowRightwards Arrow With Vertical Stroke
    U+021F9\nvleftrightarrowLeft Right Arrow With Vertical Stroke
    U+021FA\nVleftarrowLeftwards Arrow With Double Vertical Stroke
    U+021FB\nVrightarrowRightwards Arrow With Double Vertical Stroke
    U+021FC\nVleftrightarrowLeft Right Arrow With Double Vertical Stroke
    U+021FD\leftarrowtriangleLeftwards Open-Headed Arrow
    U+021FE\rightarrowtriangleRightwards Open-Headed Arrow
    U+021FF\leftrightarrowtriangleLeft Right Open-Headed Arrow
    U+02200\forallFor All
    U+02201\complementComplement
    U+02202\partialPartial Differential
    U+02203\existsThere Exists
    U+02204\nexistsThere Does Not Exist
    U+02205\varnothing, \emptysetEmpty Set
    U+02206\incrementIncrement
    U+02207\del, \nablaNabla
    U+02208\inElement Of
    U+02209\notinNot An Element Of
    U+0220A\smallinSmall Element Of
    U+0220B\niContains As Member
    U+0220C\nniDoes Not Contain As Member
    U+0220D\smallniSmall Contains As Member
    U+0220E\QEDEnd Of Proof
    U+0220F\prodN-Ary Product
    U+02210\coprodN-Ary Coproduct
    U+02211\sumN-Ary Summation
    U+02212\minusMinus Sign
    U+02213\mpMinus-Or-Plus Sign
    U+02214\dotplusDot Plus
    U+02216\setminusSet Minus
    U+02217\astAsterisk Operator
    U+02218\circRing Operator
    U+02219\vysmblkcircleBullet Operator
    U+0221A\surd, \sqrtSquare Root
    U+0221B\cbrtCube Root
    U+0221C\fourthrootFourth Root
    U+0221D\proptoProportional To
    U+0221E\inftyInfinity
    U+0221F\rightangleRight Angle
    U+02220\angleAngle
    U+02221\measuredangleMeasured Angle
    U+02222\sphericalangleSpherical Angle
    U+02223\midDivides
    U+02224\nmidDoes Not Divide
    U+02225\parallelParallel To
    U+02226\nparallelNot Parallel To
    U+02227\wedgeLogical And
    U+02228\veeLogical Or
    U+02229\capIntersection
    U+0222A\cupUnion
    U+0222B\intIntegral
    U+0222C\iintDouble Integral
    U+0222D\iiintTriple Integral
    U+0222E\ointContour Integral
    U+0222F\oiintSurface Integral
    U+02230\oiiintVolume Integral
    U+02231\clwintegralClockwise Integral
    U+02232\varointclockwiseClockwise Contour Integral
    U+02233\ointctrclockwiseAnticlockwise Contour Integral
    U+02234\thereforeTherefore
    U+02235\becauseBecause
    U+02237\ColonProportion
    U+02238\dotminusDot Minus
    U+0223A\dotsminusdotsGeometric Proportion
    U+0223B\kernelcontractionHomothetic
    U+0223C\simTilde Operator
    U+0223D\backsimReversed Tilde
    U+0223E\lazysinvInverted Lazy S
    U+0223F\sinewaveSine Wave
    U+02240\wrWreath Product
    U+02241\nsimNot Tilde
    U+02242\eqsimMinus Tilde
    U+02242 + U+00338≂̸\neqsimMinus Tilde + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02243\simeqAsymptotically Equal To
    U+02244\nsimeNot Asymptotically Equal To
    U+02245\congApproximately Equal To
    U+02246\approxnotequalApproximately But Not Actually Equal To
    U+02247\ncongNeither Approximately Nor Actually Equal To
    U+02248\approxAlmost Equal To
    U+02249\napproxNot Almost Equal To
    U+0224A\approxeqAlmost Equal Or Equal To
    U+0224B\tildetrplTriple Tilde
    U+0224C\allequalAll Equal To
    U+0224D\asympEquivalent To
    U+0224E\BumpeqGeometrically Equivalent To
    U+0224E + U+00338≎̸\nBumpeqGeometrically Equivalent To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0224F\bumpeqDifference Between
    U+0224F + U+00338≏̸\nbumpeqDifference Between + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02250\doteqApproaches The Limit
    U+02251\DoteqGeometrically Equal To
    U+02252\fallingdotseqApproximately Equal To Or The Image Of
    U+02253\risingdotseqImage Of Or Approximately Equal To
    U+02254\coloneqColon Equals / Colon Equal
    U+02255\eqcolonEquals Colon / Equal Colon
    U+02256\eqcircRing In Equal To
    U+02257\circeqRing Equal To
    U+02258\arceqCorresponds To
    U+02259\wedgeqEstimates
    U+0225A\veeeqEquiangular To
    U+0225B\starequalStar Equals
    U+0225C\triangleqDelta Equal To
    U+0225D\eqdefEqual To By Definition
    U+0225E\measeqMeasured By
    U+0225F\questeqQuestioned Equal To
    U+02260\ne, \neqNot Equal To
    U+02261\equivIdentical To
    U+02262\nequivNot Identical To
    U+02263\EquivStrictly Equivalent To
    U+02264\le, \leqLess-Than Or Equal To / Less Than Or Equal To
    U+02265\ge, \geqGreater-Than Or Equal To / Greater Than Or Equal To
    U+02266\leqqLess-Than Over Equal To / Less Than Over Equal To
    U+02267\geqqGreater-Than Over Equal To / Greater Than Over Equal To
    U+02268\lneqqLess-Than But Not Equal To / Less Than But Not Equal To
    U+02268 + U+0FE00≨︀\lvertneqqLess-Than But Not Equal To / Less Than But Not Equal To + Variation Selector-1
    U+02269\gneqqGreater-Than But Not Equal To / Greater Than But Not Equal To
    U+02269 + U+0FE00≩︀\gvertneqqGreater-Than But Not Equal To / Greater Than But Not Equal To + Variation Selector-1
    U+0226A\llMuch Less-Than / Much Less Than
    U+0226A + U+00338≪̸\NotLessLessMuch Less-Than / Much Less Than + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0226B\ggMuch Greater-Than / Much Greater Than
    U+0226B + U+00338≫̸\NotGreaterGreaterMuch Greater-Than / Much Greater Than + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0226C\betweenBetween
    U+0226D\nasympNot Equivalent To
    U+0226E\nlessNot Less-Than / Not Less Than
    U+0226F\ngtrNot Greater-Than / Not Greater Than
    U+02270\nleqNeither Less-Than Nor Equal To / Neither Less Than Nor Equal To
    U+02271\ngeqNeither Greater-Than Nor Equal To / Neither Greater Than Nor Equal To
    U+02272\lesssimLess-Than Or Equivalent To / Less Than Or Equivalent To
    U+02273\gtrsimGreater-Than Or Equivalent To / Greater Than Or Equivalent To
    U+02274\nlesssimNeither Less-Than Nor Equivalent To / Neither Less Than Nor Equivalent To
    U+02275\ngtrsimNeither Greater-Than Nor Equivalent To / Neither Greater Than Nor Equivalent To
    U+02276\lessgtrLess-Than Or Greater-Than / Less Than Or Greater Than
    U+02277\gtrlessGreater-Than Or Less-Than / Greater Than Or Less Than
    U+02278\notlessgreaterNeither Less-Than Nor Greater-Than / Neither Less Than Nor Greater Than
    U+02279\notgreaterlessNeither Greater-Than Nor Less-Than / Neither Greater Than Nor Less Than
    U+0227A\precPrecedes
    U+0227B\succSucceeds
    U+0227C\preccurlyeqPrecedes Or Equal To
    U+0227D\succcurlyeqSucceeds Or Equal To
    U+0227E\precsimPrecedes Or Equivalent To
    U+0227E + U+00338≾̸\nprecsimPrecedes Or Equivalent To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0227F\succsimSucceeds Or Equivalent To
    U+0227F + U+00338≿̸\nsuccsimSucceeds Or Equivalent To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02280\nprecDoes Not Precede
    U+02281\nsuccDoes Not Succeed
    U+02282\subsetSubset Of
    U+02283\supsetSuperset Of
    U+02284\nsubsetNot A Subset Of
    U+02285\nsupsetNot A Superset Of
    U+02286\subseteqSubset Of Or Equal To
    U+02287\supseteqSuperset Of Or Equal To
    U+02288\nsubseteqNeither A Subset Of Nor Equal To
    U+02289\nsupseteqNeither A Superset Of Nor Equal To
    U+0228A\subsetneqSubset Of With Not Equal To / Subset Of Or Not Equal To
    U+0228A + U+0FE00⊊︀\varsubsetneqqSubset Of With Not Equal To / Subset Of Or Not Equal To + Variation Selector-1
    U+0228B\supsetneqSuperset Of With Not Equal To / Superset Of Or Not Equal To
    U+0228B + U+0FE00⊋︀\varsupsetneqSuperset Of With Not Equal To / Superset Of Or Not Equal To + Variation Selector-1
    U+0228D\cupdotMultiset Multiplication
    U+0228E\uplusMultiset Union
    U+0228F\sqsubsetSquare Image Of
    U+0228F + U+00338⊏̸\NotSquareSubsetSquare Image Of + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02290\sqsupsetSquare Original Of
    U+02290 + U+00338⊐̸\NotSquareSupersetSquare Original Of + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02291\sqsubseteqSquare Image Of Or Equal To
    U+02292\sqsupseteqSquare Original Of Or Equal To
    U+02293\sqcapSquare Cap
    U+02294\sqcupSquare Cup
    U+02295\oplusCircled Plus
    U+02296\ominusCircled Minus
    U+02297\otimesCircled Times
    U+02298\oslashCircled Division Slash
    U+02299\odotCircled Dot Operator
    U+0229A\circledcircCircled Ring Operator
    U+0229B\circledastCircled Asterisk Operator
    U+0229C\circledequalCircled Equals
    U+0229D\circleddashCircled Dash
    U+0229E\boxplusSquared Plus
    U+0229F\boxminusSquared Minus
    U+022A0\boxtimesSquared Times
    U+022A1\boxdotSquared Dot Operator
    U+022A2\vdashRight Tack
    U+022A3\dashvLeft Tack
    U+022A4\topDown Tack
    U+022A5\botUp Tack
    U+022A7\modelsModels
    U+022A8\vDashTrue
    U+022A9\VdashForces
    U+022AA\VvdashTriple Vertical Bar Right Turnstile
    U+022AB\VDashDouble Vertical Bar Double Right Turnstile
    U+022AC\nvdashDoes Not Prove
    U+022AD\nvDashNot True
    U+022AE\nVdashDoes Not Force
    U+022AF\nVDashNegated Double Vertical Bar Double Right Turnstile
    U+022B0\prurelPrecedes Under Relation
    U+022B1\scurelSucceeds Under Relation
    U+022B2\vartriangleleftNormal Subgroup Of
    U+022B3\vartrianglerightContains As Normal Subgroup
    U+022B4\trianglelefteqNormal Subgroup Of Or Equal To
    U+022B5\trianglerighteqContains As Normal Subgroup Or Equal To
    U+022B6\originalOriginal Of
    U+022B7\imageImage Of
    U+022B8\multimapMultimap
    U+022B9\hermitconjmatrixHermitian Conjugate Matrix
    U+022BA\intercalIntercalate
    U+022BB\veebar, \xorXor
    U+022BC\barwedge, \nandNand
    U+022BD\barvee, \norNor
    U+022BE\rightanglearcRight Angle With Arc
    U+022BF\varlrtriangleRight Triangle
    U+022C0\bigwedgeN-Ary Logical And
    U+022C1\bigveeN-Ary Logical Or
    U+022C2\bigcapN-Ary Intersection
    U+022C3\bigcupN-Ary Union
    U+022C4\diamondDiamond Operator
    U+022C5\cdotDot Operator
    U+022C6\starStar Operator
    U+022C7\divideontimesDivision Times
    U+022C8\bowtieBowtie
    U+022C9\ltimesLeft Normal Factor Semidirect Product
    U+022CA\rtimesRight Normal Factor Semidirect Product
    U+022CB\leftthreetimesLeft Semidirect Product
    U+022CC\rightthreetimesRight Semidirect Product
    U+022CD\backsimeqReversed Tilde Equals
    U+022CE\curlyveeCurly Logical Or
    U+022CF\curlywedgeCurly Logical And
    U+022D0\SubsetDouble Subset
    U+022D1\SupsetDouble Superset
    U+022D2\CapDouble Intersection
    U+022D3\CupDouble Union
    U+022D4\pitchforkPitchfork
    U+022D5\equalparallelEqual And Parallel To
    U+022D6\lessdotLess-Than With Dot / Less Than With Dot
    U+022D7\gtrdotGreater-Than With Dot / Greater Than With Dot
    U+022D8\verymuchlessVery Much Less-Than / Very Much Less Than
    U+022D9\gggVery Much Greater-Than / Very Much Greater Than
    U+022DA\lesseqgtrLess-Than Equal To Or Greater-Than / Less Than Equal To Or Greater Than
    U+022DB\gtreqlessGreater-Than Equal To Or Less-Than / Greater Than Equal To Or Less Than
    U+022DC\eqlessEqual To Or Less-Than / Equal To Or Less Than
    U+022DD\eqgtrEqual To Or Greater-Than / Equal To Or Greater Than
    U+022DE\curlyeqprecEqual To Or Precedes
    U+022DF\curlyeqsuccEqual To Or Succeeds
    U+022E0\npreccurlyeqDoes Not Precede Or Equal
    U+022E1\nsucccurlyeqDoes Not Succeed Or Equal
    U+022E2\nsqsubseteqNot Square Image Of Or Equal To
    U+022E3\nsqsupseteqNot Square Original Of Or Equal To
    U+022E4\sqsubsetneqSquare Image Of Or Not Equal To
    U+022E5\sqsupsetneqSquare Original Of Or Not Equal To
    U+022E6\lnsimLess-Than But Not Equivalent To / Less Than But Not Equivalent To
    U+022E7\gnsimGreater-Than But Not Equivalent To / Greater Than But Not Equivalent To
    U+022E8\precnsimPrecedes But Not Equivalent To
    U+022E9\succnsimSucceeds But Not Equivalent To
    U+022EA\ntriangleleftNot Normal Subgroup Of
    U+022EB\ntrianglerightDoes Not Contain As Normal Subgroup
    U+022EC\ntrianglelefteqNot Normal Subgroup Of Or Equal To
    U+022ED\ntrianglerighteqDoes Not Contain As Normal Subgroup Or Equal
    U+022EE\vdotsVertical Ellipsis
    U+022EF\cdotsMidline Horizontal Ellipsis
    U+022F0\adotsUp Right Diagonal Ellipsis
    U+022F1\ddotsDown Right Diagonal Ellipsis
    U+022F2\disinElement Of With Long Horizontal Stroke
    U+022F3\varisinsElement Of With Vertical Bar At End Of Horizontal Stroke
    U+022F4\isinsSmall Element Of With Vertical Bar At End Of Horizontal Stroke
    U+022F5\isindotElement Of With Dot Above
    U+022F6\varisinobarElement Of With Overbar
    U+022F7\isinobarSmall Element Of With Overbar
    U+022F8\isinvbElement Of With Underbar
    U+022F9\isinEElement Of With Two Horizontal Strokes
    U+022FA\nisdContains With Long Horizontal Stroke
    U+022FB\varnisContains With Vertical Bar At End Of Horizontal Stroke
    U+022FC\nisSmall Contains With Vertical Bar At End Of Horizontal Stroke
    U+022FD\varniobarContains With Overbar
    U+022FE\niobarSmall Contains With Overbar
    U+022FF\bagmemberZ Notation Bag Membership
    U+02300\diameterDiameter Sign
    U+02302\houseHouse
    U+02305\varbarwedgeProjective
    U+02306\vardoublebarwedgePerspective
    U+02308\lceilLeft Ceiling
    U+02309\rceilRight Ceiling
    U+0230A\lfloorLeft Floor
    U+0230B\rfloorRight Floor
    U+02310\invnotReversed Not Sign
    U+02311\sqlozengeSquare Lozenge
    U+02312\proflineArc
    U+02313\profsurfSegment
    U+02315\recorderTelephone Recorder
    U+02317\viewdataViewdata Square
    U+02319\turnednotTurned Not Sign
    U+0231A\:watch:Watch
    U+0231B\:hourglass:Hourglass
    U+0231C\ulcornerTop Left Corner
    U+0231D\urcornerTop Right Corner
    U+0231E\llcornerBottom Left Corner
    U+0231F\lrcornerBottom Right Corner
    U+02322\frownFrown
    U+02323\smileSmile
    U+0232C\varhexagonlrbondsBenzene Ring
    U+02332\conictaperConical Taper
    U+02336\topbotApl Functional Symbol I-Beam
    U+0233D\obarApl Functional Symbol Circle Stile
    U+0233F\notslashApl Functional Symbol Slash Bar
    U+02340\notbackslashApl Functional Symbol Backslash Bar
    U+02353\boxupcaretApl Functional Symbol Quad Up Caret
    U+02370\boxquestionApl Functional Symbol Quad Question
    U+02394\hexagonSoftware-Function Symbol
    U+023A3\dlcornLeft Square Bracket Lower Corner
    U+023B0\lmoustacheUpper Left Or Lower Right Curly Bracket Section
    U+023B1\rmoustacheUpper Right Or Lower Left Curly Bracket Section
    U+023B4\overbracketTop Square Bracket
    U+023B5\underbracketBottom Square Bracket
    U+023B6\bbrktbrkBottom Square Bracket Over Top Square Bracket
    U+023B7\sqrtbottomRadical Symbol Bottom
    U+023B8\lvboxlineLeft Vertical Box Line
    U+023B9\rvboxlineRight Vertical Box Line
    U+023CE\varcarriagereturnReturn Symbol
    U+023DE\overbraceTop Curly Bracket
    U+023DF\underbraceBottom Curly Bracket
    U+023E2\trapeziumWhite Trapezium
    U+023E3\benzenrBenzene Ring With Circle
    U+023E4\strnsStraightness
    U+023E5\fltnsFlatness
    U+023E6\accurrentAc Current
    U+023E7\elintersElectrical Intersection
    U+023E9\:fast_forward:Black Right-Pointing Double Triangle
    U+023EA\:rewind:Black Left-Pointing Double Triangle
    U+023EB\:arrow_double_up:Black Up-Pointing Double Triangle
    U+023EC\:arrow_double_down:Black Down-Pointing Double Triangle
    U+023F0\:alarm_clock:Alarm Clock
    U+023F3\:hourglass_flowing_sand:Hourglass With Flowing Sand
    U+02422\blanksymbolBlank Symbol / Blank
    U+02423\visiblespaceOpen Box
    U+024C2\:m:Circled Latin Capital Letter M
    U+024C8\circledSCircled Latin Capital Letter S
    U+02506\dshfncBox Drawings Light Triple Dash Vertical / Forms Light Triple Dash Vertical
    U+02519\sqfnwBox Drawings Up Light And Left Heavy / Forms Up Light And Left Heavy
    U+02571\diagupBox Drawings Light Diagonal Upper Right To Lower Left / Forms Light Diagonal Upper Right To Lower Left
    U+02572\diagdownBox Drawings Light Diagonal Upper Left To Lower Right / Forms Light Diagonal Upper Left To Lower Right
    U+02580\blockuphalfUpper Half Block
    U+02584\blocklowhalfLower Half Block
    U+02588\blockfullFull Block
    U+0258C\blocklefthalfLeft Half Block
    U+02590\blockrighthalfRight Half Block
    U+02591\blockqtrshadedLight Shade
    U+02592\blockhalfshadedMedium Shade
    U+02593\blockthreeqtrshadedDark Shade
    U+025A0\blacksquareBlack Square
    U+025A1\squareWhite Square
    U+025A2\squovalWhite Square With Rounded Corners
    U+025A3\blackinwhitesquareWhite Square Containing Black Small Square
    U+025A4\squarehfillSquare With Horizontal Fill
    U+025A5\squarevfillSquare With Vertical Fill
    U+025A6\squarehvfillSquare With Orthogonal Crosshatch Fill
    U+025A7\squarenwsefillSquare With Upper Left To Lower Right Fill
    U+025A8\squareneswfillSquare With Upper Right To Lower Left Fill
    U+025A9\squarecrossfillSquare With Diagonal Crosshatch Fill
    U+025AA\smblksquare, \:black_small_square:Black Small Square
    U+025AB\smwhtsquare, \:white_small_square:White Small Square
    U+025AC\hrectangleblackBlack Rectangle
    U+025AD\hrectangleWhite Rectangle
    U+025AE\vrectangleblackBlack Vertical Rectangle
    U+025AF\vrectoWhite Vertical Rectangle
    U+025B0\parallelogramblackBlack Parallelogram
    U+025B1\parallelogramWhite Parallelogram
    U+025B2\bigblacktriangleupBlack Up-Pointing Triangle / Black Up Pointing Triangle
    U+025B3\bigtriangleupWhite Up-Pointing Triangle / White Up Pointing Triangle
    U+025B4\blacktriangleBlack Up-Pointing Small Triangle / Black Up Pointing Small Triangle
    U+025B5\vartriangleWhite Up-Pointing Small Triangle / White Up Pointing Small Triangle
    U+025B6\blacktriangleright, \:arrow_forward:Black Right-Pointing Triangle / Black Right Pointing Triangle
    U+025B7\trianglerightWhite Right-Pointing Triangle / White Right Pointing Triangle
    U+025B8\smallblacktrianglerightBlack Right-Pointing Small Triangle / Black Right Pointing Small Triangle
    U+025B9\smalltrianglerightWhite Right-Pointing Small Triangle / White Right Pointing Small Triangle
    U+025BA\blackpointerrightBlack Right-Pointing Pointer / Black Right Pointing Pointer
    U+025BB\whitepointerrightWhite Right-Pointing Pointer / White Right Pointing Pointer
    U+025BC\bigblacktriangledownBlack Down-Pointing Triangle / Black Down Pointing Triangle
    U+025BD\bigtriangledownWhite Down-Pointing Triangle / White Down Pointing Triangle
    U+025BE\blacktriangledownBlack Down-Pointing Small Triangle / Black Down Pointing Small Triangle
    U+025BF\triangledownWhite Down-Pointing Small Triangle / White Down Pointing Small Triangle
    U+025C0\blacktriangleleft, \:arrow_backward:Black Left-Pointing Triangle / Black Left Pointing Triangle
    U+025C1\triangleleftWhite Left-Pointing Triangle / White Left Pointing Triangle
    U+025C2\smallblacktriangleleftBlack Left-Pointing Small Triangle / Black Left Pointing Small Triangle
    U+025C3\smalltriangleleftWhite Left-Pointing Small Triangle / White Left Pointing Small Triangle
    U+025C4\blackpointerleftBlack Left-Pointing Pointer / Black Left Pointing Pointer
    U+025C5\whitepointerleftWhite Left-Pointing Pointer / White Left Pointing Pointer
    U+025C6\mdlgblkdiamondBlack Diamond
    U+025C7\mdlgwhtdiamondWhite Diamond
    U+025C8\blackinwhitediamondWhite Diamond Containing Black Small Diamond
    U+025C9\fisheyeFisheye
    U+025CA\lozengeLozenge
    U+025CB\bigcircWhite Circle
    U+025CC\dottedcircleDotted Circle
    U+025CD\circlevertfillCircle With Vertical Fill
    U+025CE\bullseyeBullseye
    U+025CF\mdlgblkcircleBlack Circle
    U+025D0\cirflCircle With Left Half Black
    U+025D1\cirfrCircle With Right Half Black
    U+025D2\cirfbCircle With Lower Half Black
    U+025D3\circletophalfblackCircle With Upper Half Black
    U+025D4\circleurquadblackCircle With Upper Right Quadrant Black
    U+025D5\blackcircleulquadwhiteCircle With All But Upper Left Quadrant Black
    U+025D6\blacklefthalfcircleLeft Half Black Circle
    U+025D7\blackrighthalfcircleRight Half Black Circle
    U+025D8\rvbullInverse Bullet
    U+025D9\inversewhitecircleInverse White Circle
    U+025DA\invwhiteupperhalfcircleUpper Half Inverse White Circle
    U+025DB\invwhitelowerhalfcircleLower Half Inverse White Circle
    U+025DC\ularcUpper Left Quadrant Circular Arc
    U+025DD\urarcUpper Right Quadrant Circular Arc
    U+025DE\lrarcLower Right Quadrant Circular Arc
    U+025DF\llarcLower Left Quadrant Circular Arc
    U+025E0\topsemicircleUpper Half Circle
    U+025E1\botsemicircleLower Half Circle
    U+025E2\lrblacktriangleBlack Lower Right Triangle
    U+025E3\llblacktriangleBlack Lower Left Triangle
    U+025E4\ulblacktriangleBlack Upper Left Triangle
    U+025E5\urblacktriangleBlack Upper Right Triangle
    U+025E6\smwhtcircleWhite Bullet
    U+025E7\sqflSquare With Left Half Black
    U+025E8\sqfrSquare With Right Half Black
    U+025E9\squareulblackSquare With Upper Left Diagonal Half Black
    U+025EA\sqfseSquare With Lower Right Diagonal Half Black
    U+025EB\boxbarWhite Square With Vertical Bisecting Line
    U+025EC\trianglecdotWhite Up-Pointing Triangle With Dot / White Up Pointing Triangle With Dot
    U+025ED\triangleleftblackUp-Pointing Triangle With Left Half Black / Up Pointing Triangle With Left Half Black
    U+025EE\trianglerightblackUp-Pointing Triangle With Right Half Black / Up Pointing Triangle With Right Half Black
    U+025EF\lgwhtcircleLarge Circle
    U+025F0\squareulquadWhite Square With Upper Left Quadrant
    U+025F1\squarellquadWhite Square With Lower Left Quadrant
    U+025F2\squarelrquadWhite Square With Lower Right Quadrant
    U+025F3\squareurquadWhite Square With Upper Right Quadrant
    U+025F4\circleulquadWhite Circle With Upper Left Quadrant
    U+025F5\circlellquadWhite Circle With Lower Left Quadrant
    U+025F6\circlelrquadWhite Circle With Lower Right Quadrant
    U+025F7\circleurquadWhite Circle With Upper Right Quadrant
    U+025F8\ultriangleUpper Left Triangle
    U+025F9\urtriangleUpper Right Triangle
    U+025FA\lltriangleLower Left Triangle
    U+025FB\mdwhtsquare, \:white_medium_square:White Medium Square
    U+025FC\mdblksquare, \:black_medium_square:Black Medium Square
    U+025FD\mdsmwhtsquare, \:white_medium_small_square:White Medium Small Square
    U+025FE\mdsmblksquare, \:black_medium_small_square:Black Medium Small Square
    U+025FF\lrtriangleLower Right Triangle
    U+02600\:sunny:Black Sun With Rays
    U+02601\:cloud:Cloud
    U+02605\bigstarBlack Star
    U+02606\bigwhitestarWhite Star
    U+02609\astrosunSun
    U+0260E\:phone:Black Telephone
    U+02611\:ballot_box_with_check:Ballot Box With Check
    U+02614\:umbrella_with_rain_drops:, \:umbrella:Umbrella With Rain Drops
    U+02615\:coffee:Hot Beverage
    U+0261D\:point_up:White Up Pointing Index
    U+02621\dangerCaution Sign
    U+0263A\:relaxed:White Smiling Face
    U+0263B\blacksmileyBlack Smiling Face
    U+0263C\sunWhite Sun With Rays
    U+0263D\rightmoonFirst Quarter Moon
    U+0263E\leftmoonLast Quarter Moon
    U+0263F\mercuryMercury
    U+02640\venus, \femaleFemale Sign
    U+02642\male, \marsMale Sign
    U+02643\jupiterJupiter
    U+02644\saturnSaturn
    U+02645\uranusUranus
    U+02646\neptuneNeptune
    U+02647\plutoPluto
    U+02648\aries, \:aries:Aries
    U+02649\taurus, \:taurus:Taurus
    U+0264A\gemini, \:gemini:Gemini
    U+0264B\cancer, \:cancer:Cancer
    U+0264C\leo, \:leo:Leo
    U+0264D\virgo, \:virgo:Virgo
    U+0264E\libra, \:libra:Libra
    U+0264F\scorpio, \:scorpius:Scorpius
    U+02650\sagittarius, \:sagittarius:Sagittarius
    U+02651\capricornus, \:capricorn:Capricorn
    U+02652\aquarius, \:aquarius:Aquarius
    U+02653\pisces, \:pisces:Pisces
    U+02660\spadesuit, \:spades:Black Spade Suit
    U+02661\heartsuitWhite Heart Suit
    U+02662\diamondsuitWhite Diamond Suit
    U+02663\clubsuit, \:clubs:Black Club Suit
    U+02664\varspadesuitWhite Spade Suit
    U+02665\varheartsuit, \:hearts:Black Heart Suit
    U+02666\vardiamondsuit, \:diamonds:Black Diamond Suit
    U+02667\varclubsuitWhite Club Suit
    U+02668\:hotsprings:Hot Springs
    U+02669\quarternoteQuarter Note
    U+0266A\eighthnoteEighth Note
    U+0266B\twonotesBeamed Eighth Notes / Barred Eighth Notes
    U+0266D\flatMusic Flat Sign / Flat
    U+0266E\naturalMusic Natural Sign / Natural
    U+0266F\sharpMusic Sharp Sign / Sharp
    U+0267B\:recycle:Black Universal Recycling Symbol
    U+0267E\acidfreePermanent Paper Sign
    U+0267F\:wheelchair:Wheelchair Symbol
    U+02680\diceiDie Face-1
    U+02681\diceiiDie Face-2
    U+02682\diceiiiDie Face-3
    U+02683\diceivDie Face-4
    U+02684\dicevDie Face-5
    U+02685\diceviDie Face-6
    U+02686\circledrightdotWhite Circle With Dot Right
    U+02687\circledtwodotsWhite Circle With Two Dots
    U+02688\blackcircledrightdotBlack Circle With White Dot Right
    U+02689\blackcircledtwodotsBlack Circle With Two White Dots
    U+02693\:anchor:Anchor
    U+026A0\:warning:Warning Sign
    U+026A1\:zap:High Voltage Sign
    U+026A5\hermaphroditeMale And Female Sign
    U+026AA\mdwhtcircle, \:white_circle:Medium White Circle
    U+026AB\mdblkcircle, \:black_circle:Medium Black Circle
    U+026AC\mdsmwhtcircleMedium Small White Circle
    U+026B2\neuterNeuter
    U+026BD\:soccer:Soccer Ball
    U+026BE\:baseball:Baseball
    U+026C4\:snowman:, \:snowman_without_snow:Snowman Without Snow
    U+026C5\:partly_sunny:Sun Behind Cloud
    U+026CE\:ophiuchus:Ophiuchus
    U+026D4\:no_entry:No Entry
    U+026EA\:church:Church
    U+026F2\:fountain:Fountain
    U+026F3\:golf:Flag In Hole
    U+026F5\:boat:Sailboat
    U+026FA\:tent:Tent
    U+026FD\:fuelpump:Fuel Pump
    U+02702\:scissors:Black Scissors
    U+02705\:white_check_mark:White Heavy Check Mark
    U+02708\:airplane:Airplane
    U+02709\:email:Envelope
    U+0270A\:fist:Raised Fist
    U+0270B\:hand:Raised Hand
    U+0270C\:v:Victory Hand
    U+0270F\:pencil2:Pencil
    U+02712\:black_nib:Black Nib
    U+02713\checkmarkCheck Mark
    U+02714\:heavy_check_mark:Heavy Check Mark
    U+02716\:heavy_multiplication_x:Heavy Multiplication X
    U+02720\malteseMaltese Cross
    U+02728\:sparkles:Sparkles
    U+0272A\circledstarCircled White Star
    U+02733\:eight_spoked_asterisk:Eight Spoked Asterisk
    U+02734\:eight_pointed_black_star:Eight Pointed Black Star
    U+02736\varstarSix Pointed Black Star
    U+0273D\dingasteriskHeavy Teardrop-Spoked Asterisk
    U+02744\:snowflake:Snowflake
    U+02747\:sparkle:Sparkle
    U+0274C\:x:Cross Mark
    U+0274E\:negative_squared_cross_mark:Negative Squared Cross Mark
    U+02753\:question:Black Question Mark Ornament
    U+02754\:grey_question:White Question Mark Ornament
    U+02755\:grey_exclamation:White Exclamation Mark Ornament
    U+02757\:exclamation:Heavy Exclamation Mark Symbol
    U+02764\:heart:Heavy Black Heart
    U+02795\:heavy_plus_sign:Heavy Plus Sign
    U+02796\:heavy_minus_sign:Heavy Minus Sign
    U+02797\:heavy_division_sign:Heavy Division Sign
    U+0279B\draftingarrowDrafting Point Rightwards Arrow / Drafting Point Right Arrow
    U+027A1\:arrow_right:Black Rightwards Arrow / Black Right Arrow
    U+027B0\:curly_loop:Curly Loop
    U+027BF\:loop:Double Curly Loop
    U+027C0\threedangleThree Dimensional Angle
    U+027C1\whiteinwhitetriangleWhite Triangle Containing Small White Triangle
    U+027C2\perpPerpendicular
    U+027C7\veedotOr With Dot Inside
    U+027C8\bsolhsubReverse Solidus Preceding Subset
    U+027C9\suphsolSuperset Preceding Solidus
    U+027D1\wedgedotAnd With Dot
    U+027D2\upinElement Of Opening Upwards
    U+027D5\leftouterjoinLeft Outer Join
    U+027D6\rightouterjoinRight Outer Join
    U+027D7\fullouterjoinFull Outer Join
    U+027D8\bigbotLarge Up Tack
    U+027D9\bigtopLarge Down Tack
    U+027E6\llbracket, \openbracketleftMathematical Left White Square Bracket
    U+027E7\openbracketright, \rrbracketMathematical Right White Square Bracket
    U+027E8\langleMathematical Left Angle Bracket
    U+027E9\rangleMathematical Right Angle Bracket
    U+027F0\UUparrowUpwards Quadruple Arrow
    U+027F1\DDownarrowDownwards Quadruple Arrow
    U+027F5\longleftarrowLong Leftwards Arrow
    U+027F6\longrightarrowLong Rightwards Arrow
    U+027F7\longleftrightarrowLong Left Right Arrow
    U+027F8\impliedby, \LongleftarrowLong Leftwards Double Arrow
    U+027F9\implies, \LongrightarrowLong Rightwards Double Arrow
    U+027FA\Longleftrightarrow, \iffLong Left Right Double Arrow
    U+027FB\longmapsfromLong Leftwards Arrow From Bar
    U+027FC\longmapstoLong Rightwards Arrow From Bar
    U+027FD\LongmapsfromLong Leftwards Double Arrow From Bar
    U+027FE\LongmapstoLong Rightwards Double Arrow From Bar
    U+027FF\longrightsquigarrowLong Rightwards Squiggle Arrow
    U+02900\nvtwoheadrightarrowRightwards Two-Headed Arrow With Vertical Stroke
    U+02901\nVtwoheadrightarrowRightwards Two-Headed Arrow With Double Vertical Stroke
    U+02902\nvLeftarrowLeftwards Double Arrow With Vertical Stroke
    U+02903\nvRightarrowRightwards Double Arrow With Vertical Stroke
    U+02904\nvLeftrightarrowLeft Right Double Arrow With Vertical Stroke
    U+02905\twoheadmapstoRightwards Two-Headed Arrow From Bar
    U+02906\MapsfromLeftwards Double Arrow From Bar
    U+02907\MapstoRightwards Double Arrow From Bar
    U+02908\downarrowbarredDownwards Arrow With Horizontal Stroke
    U+02909\uparrowbarredUpwards Arrow With Horizontal Stroke
    U+0290A\UuparrowUpwards Triple Arrow
    U+0290B\DdownarrowDownwards Triple Arrow
    U+0290C\leftbkarrowLeftwards Double Dash Arrow
    U+0290D\bkarowRightwards Double Dash Arrow
    U+0290E\leftdbkarrowLeftwards Triple Dash Arrow
    U+0290F\dbkarowRightwards Triple Dash Arrow
    U+02910\drbkarrowRightwards Two-Headed Triple Dash Arrow
    U+02911\rightdotarrowRightwards Arrow With Dotted Stem
    U+02912\UpArrowBarUpwards Arrow To Bar
    U+02913\DownArrowBarDownwards Arrow To Bar
    U+02914\nvrightarrowtailRightwards Arrow With Tail With Vertical Stroke
    U+02915\nVrightarrowtailRightwards Arrow With Tail With Double Vertical Stroke
    U+02916\twoheadrightarrowtailRightwards Two-Headed Arrow With Tail
    U+02917\nvtwoheadrightarrowtailRightwards Two-Headed Arrow With Tail With Vertical Stroke
    U+02918\nVtwoheadrightarrowtailRightwards Two-Headed Arrow With Tail With Double Vertical Stroke
    U+0291D\diamondleftarrowLeftwards Arrow To Black Diamond
    U+0291E\rightarrowdiamondRightwards Arrow To Black Diamond
    U+0291F\diamondleftarrowbarLeftwards Arrow From Bar To Black Diamond
    U+02920\barrightarrowdiamondRightwards Arrow From Bar To Black Diamond
    U+02925\hksearowSouth East Arrow With Hook
    U+02926\hkswarowSouth West Arrow With Hook
    U+02927\tonaNorth West Arrow And North East Arrow
    U+02928\toeaNorth East Arrow And South East Arrow
    U+02929\tosaSouth East Arrow And South West Arrow
    U+0292A\towaSouth West Arrow And North West Arrow
    U+0292B\rdiagovfdiagRising Diagonal Crossing Falling Diagonal
    U+0292C\fdiagovrdiagFalling Diagonal Crossing Rising Diagonal
    U+0292D\seovnearrowSouth East Arrow Crossing North East Arrow
    U+0292E\neovsearrowNorth East Arrow Crossing South East Arrow
    U+0292F\fdiagovnearrowFalling Diagonal Crossing North East Arrow
    U+02930\rdiagovsearrowRising Diagonal Crossing South East Arrow
    U+02931\neovnwarrowNorth East Arrow Crossing North West Arrow
    U+02932\nwovnearrowNorth West Arrow Crossing North East Arrow
    U+02934\:arrow_heading_up:Arrow Pointing Rightwards Then Curving Upwards
    U+02935\:arrow_heading_down:Arrow Pointing Rightwards Then Curving Downwards
    U+02942\RlarrRightwards Arrow Above Short Leftwards Arrow
    U+02944\rLarrShort Rightwards Arrow Above Leftwards Arrow
    U+02945\rightarrowplusRightwards Arrow With Plus Below
    U+02946\leftarrowplusLeftwards Arrow With Plus Below
    U+02947\rarrxRightwards Arrow Through X
    U+02948\leftrightarrowcircleLeft Right Arrow Through Small Circle
    U+02949\twoheaduparrowcircleUpwards Two-Headed Arrow From Small Circle
    U+0294A\leftrightharpoonupdownLeft Barb Up Right Barb Down Harpoon
    U+0294B\leftrightharpoondownupLeft Barb Down Right Barb Up Harpoon
    U+0294C\updownharpoonrightleftUp Barb Right Down Barb Left Harpoon
    U+0294D\updownharpoonleftrightUp Barb Left Down Barb Right Harpoon
    U+0294E\LeftRightVectorLeft Barb Up Right Barb Up Harpoon
    U+0294F\RightUpDownVectorUp Barb Right Down Barb Right Harpoon
    U+02950\DownLeftRightVectorLeft Barb Down Right Barb Down Harpoon
    U+02951\LeftUpDownVectorUp Barb Left Down Barb Left Harpoon
    U+02952\LeftVectorBarLeftwards Harpoon With Barb Up To Bar
    U+02953\RightVectorBarRightwards Harpoon With Barb Up To Bar
    U+02954\RightUpVectorBarUpwards Harpoon With Barb Right To Bar
    U+02955\RightDownVectorBarDownwards Harpoon With Barb Right To Bar
    U+02956\DownLeftVectorBarLeftwards Harpoon With Barb Down To Bar
    U+02957\DownRightVectorBarRightwards Harpoon With Barb Down To Bar
    U+02958\LeftUpVectorBarUpwards Harpoon With Barb Left To Bar
    U+02959\LeftDownVectorBarDownwards Harpoon With Barb Left To Bar
    U+0295A\LeftTeeVectorLeftwards Harpoon With Barb Up From Bar
    U+0295B\RightTeeVectorRightwards Harpoon With Barb Up From Bar
    U+0295C\RightUpTeeVectorUpwards Harpoon With Barb Right From Bar
    U+0295D\RightDownTeeVectorDownwards Harpoon With Barb Right From Bar
    U+0295E\DownLeftTeeVectorLeftwards Harpoon With Barb Down From Bar
    U+0295F\DownRightTeeVectorRightwards Harpoon With Barb Down From Bar
    U+02960\LeftUpTeeVectorUpwards Harpoon With Barb Left From Bar
    U+02961\LeftDownTeeVectorDownwards Harpoon With Barb Left From Bar
    U+02962\leftharpoonsupdownLeftwards Harpoon With Barb Up Above Leftwards Harpoon With Barb Down
    U+02963\upharpoonsleftrightUpwards Harpoon With Barb Left Beside Upwards Harpoon With Barb Right
    U+02964\rightharpoonsupdownRightwards Harpoon With Barb Up Above Rightwards Harpoon With Barb Down
    U+02965\downharpoonsleftrightDownwards Harpoon With Barb Left Beside Downwards Harpoon With Barb Right
    U+02966\leftrightharpoonsupLeftwards Harpoon With Barb Up Above Rightwards Harpoon With Barb Up
    U+02967\leftrightharpoonsdownLeftwards Harpoon With Barb Down Above Rightwards Harpoon With Barb Down
    U+02968\rightleftharpoonsupRightwards Harpoon With Barb Up Above Leftwards Harpoon With Barb Up
    U+02969\rightleftharpoonsdownRightwards Harpoon With Barb Down Above Leftwards Harpoon With Barb Down
    U+0296A\leftharpoonupdashLeftwards Harpoon With Barb Up Above Long Dash
    U+0296B\dashleftharpoondownLeftwards Harpoon With Barb Down Below Long Dash
    U+0296C\rightharpoonupdashRightwards Harpoon With Barb Up Above Long Dash
    U+0296D\dashrightharpoondownRightwards Harpoon With Barb Down Below Long Dash
    U+0296E\UpEquilibriumUpwards Harpoon With Barb Left Beside Downwards Harpoon With Barb Right
    U+0296F\ReverseUpEquilibriumDownwards Harpoon With Barb Left Beside Upwards Harpoon With Barb Right
    U+02970\RoundImpliesRight Double Arrow With Rounded Head
    U+02977\leftarrowlessLeftwards Arrow Through Less-Than
    U+0297A\leftarrowsubsetLeftwards Arrow Through Subset
    U+02980\VvertTriple Vertical Bar Delimiter
    U+02986\ElroangRight White Parenthesis
    U+02999\ddfncDotted Fence
    U+0299B\measuredangleleftMeasured Angle Opening Left
    U+0299C\AngleRight Angle Variant With Square
    U+0299D\rightanglemdotMeasured Right Angle With Dot
    U+0299E\anglesAngle With S Inside
    U+0299F\angdnrAcute Angle
    U+029A0\lpargtSpherical Angle Opening Left
    U+029A1\sphericalangleupSpherical Angle Opening Up
    U+029A2\turnangleTurned Angle
    U+029A3\revangleReversed Angle
    U+029A4\angleubarAngle With Underbar
    U+029A5\revangleubarReversed Angle With Underbar
    U+029A6\wideangledownOblique Angle Opening Up
    U+029A7\wideangleupOblique Angle Opening Down
    U+029A8\measanglerutoneMeasured Angle With Open Arm Ending In Arrow Pointing Up And Right
    U+029A9\measanglelutonwMeasured Angle With Open Arm Ending In Arrow Pointing Up And Left
    U+029AA\measanglerdtoseMeasured Angle With Open Arm Ending In Arrow Pointing Down And Right
    U+029AB\measangleldtoswMeasured Angle With Open Arm Ending In Arrow Pointing Down And Left
    U+029AC\measangleurtoneMeasured Angle With Open Arm Ending In Arrow Pointing Right And Up
    U+029AD\measangleultonwMeasured Angle With Open Arm Ending In Arrow Pointing Left And Up
    U+029AE\measangledrtoseMeasured Angle With Open Arm Ending In Arrow Pointing Right And Down
    U+029AF\measangledltoswMeasured Angle With Open Arm Ending In Arrow Pointing Left And Down
    U+029B0\revemptysetReversed Empty Set
    U+029B1\emptysetobarEmpty Set With Overbar
    U+029B2\emptysetocircEmpty Set With Small Circle Above
    U+029B3\emptysetoarrEmpty Set With Right Arrow Above
    U+029B4\emptysetoarrlEmpty Set With Left Arrow Above
    U+029B7\circledparallelCircled Parallel
    U+029B8\obslashCircled Reverse Solidus
    U+029BC\odotslashdotCircled Anticlockwise-Rotated Division Sign
    U+029BE\circledwhitebulletCircled White Bullet
    U+029BF⦿\circledbulletCircled Bullet
    U+029C0\olessthanCircled Less-Than
    U+029C1\ogreaterthanCircled Greater-Than
    U+029C4\boxdiagSquared Rising Diagonal Slash
    U+029C5\boxbslashSquared Falling Diagonal Slash
    U+029C6\boxastSquared Asterisk
    U+029C7\boxcircleSquared Small Circle
    U+029CA\LapTriangle With Dot Above
    U+029CB\defasTriangle With Underbar
    U+029CF\LeftTriangleBarLeft Triangle Beside Vertical Bar
    U+029CF + U+00338⧏̸\NotLeftTriangleBarLeft Triangle Beside Vertical Bar + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+029D0\RightTriangleBarVertical Bar Beside Right Triangle
    U+029D0 + U+00338⧐̸\NotRightTriangleBarVertical Bar Beside Right Triangle + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+029DF\dualmapDouble-Ended Multimap
    U+029E1\lrtriangleeqIncreases As
    U+029E2\shuffleShuffle Product
    U+029E3\eparslEquals Sign And Slanted Parallel
    U+029E4\smeparslEquals Sign And Slanted Parallel With Tilde Above
    U+029E5\eqvparslIdentical To And Slanted Parallel
    U+029EB\blacklozengeBlack Lozenge
    U+029F4\RuleDelayedRule-Delayed
    U+029F6\dsolSolidus With Overbar
    U+029F7\rsolbarReverse Solidus With Horizontal Stroke
    U+029FA\doubleplusDouble Plus
    U+029FB\tripleplusTriple Plus
    U+02A00\bigodotN-Ary Circled Dot Operator
    U+02A01\bigoplusN-Ary Circled Plus Operator
    U+02A02\bigotimesN-Ary Circled Times Operator
    U+02A03\bigcupdotN-Ary Union Operator With Dot
    U+02A04\biguplusN-Ary Union Operator With Plus
    U+02A05\bigsqcapN-Ary Square Intersection Operator
    U+02A06\bigsqcupN-Ary Square Union Operator
    U+02A07\conjquantTwo Logical And Operator
    U+02A08\disjquantTwo Logical Or Operator
    U+02A09\bigtimesN-Ary Times Operator
    U+02A0A\modtwosumModulo Two Sum
    U+02A0B\sumintSummation With Integral
    U+02A0C\iiiintQuadruple Integral Operator
    U+02A0D\intbarFinite Part Integral
    U+02A0E\intBarIntegral With Double Stroke
    U+02A0F\clockointIntegral Average With Slash
    U+02A10\cirfnintCirculation Function
    U+02A11\awintAnticlockwise Integration
    U+02A12\rppolintLine Integration With Rectangular Path Around Pole
    U+02A13\scpolintLine Integration With Semicircular Path Around Pole
    U+02A14\npolintLine Integration Not Including The Pole
    U+02A15\pointintIntegral Around A Point Operator
    U+02A16\sqrintQuaternion Integral Operator
    U+02A18\intxIntegral With Times Sign
    U+02A19\intcapIntegral With Intersection
    U+02A1A\intcupIntegral With Union
    U+02A1B\upintIntegral With Overbar
    U+02A1C\lowintIntegral With Underbar
    U+02A1D\joinJoin
    U+02A1F\bbsemiZ Notation Schema Composition
    U+02A22\ringplusPlus Sign With Small Circle Above
    U+02A23\plushatPlus Sign With Circumflex Accent Above
    U+02A24\simplusPlus Sign With Tilde Above
    U+02A25\plusdotPlus Sign With Dot Below
    U+02A26\plussimPlus Sign With Tilde Below
    U+02A27\plussubtwoPlus Sign With Subscript Two
    U+02A28\plustrifPlus Sign With Black Triangle
    U+02A29\commaminusMinus Sign With Comma Above
    U+02A2A\minusdotMinus Sign With Dot Below
    U+02A2B\minusfdotsMinus Sign With Falling Dots
    U+02A2C\minusrdotsMinus Sign With Rising Dots
    U+02A2D\opluslhrimPlus Sign In Left Half Circle
    U+02A2E\oplusrhrimPlus Sign In Right Half Circle
    U+02A2F\TimesVector Or Cross Product
    U+02A30\dottimesMultiplication Sign With Dot Above
    U+02A31\timesbarMultiplication Sign With Underbar
    U+02A32\btimesSemidirect Product With Bottom Closed
    U+02A33\smashtimesSmash Product
    U+02A34\otimeslhrimMultiplication Sign In Left Half Circle
    U+02A35\otimesrhrimMultiplication Sign In Right Half Circle
    U+02A36\otimeshatCircled Multiplication Sign With Circumflex Accent
    U+02A37\OtimesMultiplication Sign In Double Circle
    U+02A38\odivCircled Division Sign
    U+02A39\triangleplusPlus Sign In Triangle
    U+02A3A\triangleminusMinus Sign In Triangle
    U+02A3B\triangletimesMultiplication Sign In Triangle
    U+02A3C\intprodInterior Product
    U+02A3D\intprodrRighthand Interior Product
    U+02A3F⨿\amalgAmalgamation Or Coproduct
    U+02A40\capdotIntersection With Dot
    U+02A41\uminusUnion With Minus Sign
    U+02A42\barcupUnion With Overbar
    U+02A43\barcapIntersection With Overbar
    U+02A44\capwedgeIntersection With Logical And
    U+02A45\cupveeUnion With Logical Or
    U+02A4A\twocupsUnion Beside And Joined With Union
    U+02A4B\twocapsIntersection Beside And Joined With Intersection
    U+02A4C\closedvarcupClosed Union With Serifs
    U+02A4D\closedvarcapClosed Intersection With Serifs
    U+02A4E\SqcapDouble Square Intersection
    U+02A4F\SqcupDouble Square Union
    U+02A50\closedvarcupsmashprodClosed Union With Serifs And Smash Product
    U+02A51\wedgeodotLogical And With Dot Above
    U+02A52\veeodotLogical Or With Dot Above
    U+02A53\AndDouble Logical And
    U+02A54\OrDouble Logical Or
    U+02A55\wedgeonwedgeTwo Intersecting Logical And
    U+02A56\ElOrTwo Intersecting Logical Or
    U+02A57\bigslopedveeSloping Large Or
    U+02A58\bigslopedwedgeSloping Large And
    U+02A5A\wedgemidvertLogical And With Middle Stem
    U+02A5B\veemidvertLogical Or With Middle Stem
    U+02A5C\midbarwedgeLogical And With Horizontal Dash
    U+02A5D\midbarveeLogical Or With Horizontal Dash
    U+02A5E\perspcorrespondLogical And With Double Overbar
    U+02A5F\minhatLogical And With Underbar
    U+02A60\wedgedoublebarLogical And With Double Underbar
    U+02A61\varveebarSmall Vee With Underbar
    U+02A62\doublebarveeLogical Or With Double Overbar
    U+02A63\veedoublebarLogical Or With Double Underbar
    U+02A66\eqdotEquals Sign With Dot Below
    U+02A67\dotequivIdentical With Dot Above
    U+02A6A\dotsimTilde Operator With Dot Above
    U+02A6B\simrdotsTilde Operator With Rising Dots
    U+02A6C\simminussimSimilar Minus Similar
    U+02A6D\congdotCongruent With Dot Above
    U+02A6E\asteqEquals With Asterisk
    U+02A6F\hatapproxAlmost Equal To With Circumflex Accent
    U+02A70\approxeqqApproximately Equal Or Equal To
    U+02A71\eqqplusEquals Sign Above Plus Sign
    U+02A72\pluseqqPlus Sign Above Equals Sign
    U+02A73\eqqsimEquals Sign Above Tilde Operator
    U+02A74\ColoneqDouble Colon Equal
    U+02A75\EqualTwo Consecutive Equals Signs
    U+02A76\eqeqeqThree Consecutive Equals Signs
    U+02A77\ddotseqEquals Sign With Two Dots Above And Two Dots Below
    U+02A78\equivDDEquivalent With Four Dots Above
    U+02A79\ltcirLess-Than With Circle Inside
    U+02A7A\gtcirGreater-Than With Circle Inside
    U+02A7B\ltquestLess-Than With Question Mark Above
    U+02A7C\gtquestGreater-Than With Question Mark Above
    U+02A7D\leqslantLess-Than Or Slanted Equal To
    U+02A7D + U+00338⩽̸\nleqslantLess-Than Or Slanted Equal To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02A7E\geqslantGreater-Than Or Slanted Equal To
    U+02A7E + U+00338⩾̸\ngeqslantGreater-Than Or Slanted Equal To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02A7F⩿\lesdotLess-Than Or Slanted Equal To With Dot Inside
    U+02A80\gesdotGreater-Than Or Slanted Equal To With Dot Inside
    U+02A81\lesdotoLess-Than Or Slanted Equal To With Dot Above
    U+02A82\gesdotoGreater-Than Or Slanted Equal To With Dot Above
    U+02A83\lesdotorLess-Than Or Slanted Equal To With Dot Above Right
    U+02A84\gesdotolGreater-Than Or Slanted Equal To With Dot Above Left
    U+02A85\lessapproxLess-Than Or Approximate
    U+02A86\gtrapproxGreater-Than Or Approximate
    U+02A87\lneqLess-Than And Single-Line Not Equal To
    U+02A88\gneqGreater-Than And Single-Line Not Equal To
    U+02A89\lnapproxLess-Than And Not Approximate
    U+02A8A\gnapproxGreater-Than And Not Approximate
    U+02A8B\lesseqqgtrLess-Than Above Double-Line Equal Above Greater-Than
    U+02A8C\gtreqqlessGreater-Than Above Double-Line Equal Above Less-Than
    U+02A8D\lsimeLess-Than Above Similar Or Equal
    U+02A8E\gsimeGreater-Than Above Similar Or Equal
    U+02A8F\lsimgLess-Than Above Similar Above Greater-Than
    U+02A90\gsimlGreater-Than Above Similar Above Less-Than
    U+02A91\lgELess-Than Above Greater-Than Above Double-Line Equal
    U+02A92\glEGreater-Than Above Less-Than Above Double-Line Equal
    U+02A93\lesgesLess-Than Above Slanted Equal Above Greater-Than Above Slanted Equal
    U+02A94\geslesGreater-Than Above Slanted Equal Above Less-Than Above Slanted Equal
    U+02A95\eqslantlessSlanted Equal To Or Less-Than
    U+02A96\eqslantgtrSlanted Equal To Or Greater-Than
    U+02A97\elsdotSlanted Equal To Or Less-Than With Dot Inside
    U+02A98\egsdotSlanted Equal To Or Greater-Than With Dot Inside
    U+02A99\eqqlessDouble-Line Equal To Or Less-Than
    U+02A9A\eqqgtrDouble-Line Equal To Or Greater-Than
    U+02A9B\eqqslantlessDouble-Line Slanted Equal To Or Less-Than
    U+02A9C\eqqslantgtrDouble-Line Slanted Equal To Or Greater-Than
    U+02A9D\simlessSimilar Or Less-Than
    U+02A9E\simgtrSimilar Or Greater-Than
    U+02A9F\simlESimilar Above Less-Than Above Equals Sign
    U+02AA0\simgESimilar Above Greater-Than Above Equals Sign
    U+02AA1\NestedLessLessDouble Nested Less-Than
    U+02AA1 + U+00338⪡̸\NotNestedLessLessDouble Nested Less-Than + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AA2\NestedGreaterGreaterDouble Nested Greater-Than
    U+02AA2 + U+00338⪢̸\NotNestedGreaterGreaterDouble Nested Greater-Than + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AA3\partialmeetcontractionDouble Nested Less-Than With Underbar
    U+02AA4\gljGreater-Than Overlapping Less-Than
    U+02AA5\glaGreater-Than Beside Less-Than
    U+02AA6\ltccLess-Than Closed By Curve
    U+02AA7\gtccGreater-Than Closed By Curve
    U+02AA8\lesccLess-Than Closed By Curve Above Slanted Equal
    U+02AA9\gesccGreater-Than Closed By Curve Above Slanted Equal
    U+02AAA\smtSmaller Than
    U+02AAB\latLarger Than
    U+02AAC\smteSmaller Than Or Equal To
    U+02AAD\lateLarger Than Or Equal To
    U+02AAE\bumpeqqEquals Sign With Bumpy Above
    U+02AAF\preceqPrecedes Above Single-Line Equals Sign
    U+02AAF + U+00338⪯̸\npreceqPrecedes Above Single-Line Equals Sign + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AB0\succeqSucceeds Above Single-Line Equals Sign
    U+02AB0 + U+00338⪰̸\nsucceqSucceeds Above Single-Line Equals Sign + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AB1\precneqPrecedes Above Single-Line Not Equal To
    U+02AB2\succneqSucceeds Above Single-Line Not Equal To
    U+02AB3\preceqqPrecedes Above Equals Sign
    U+02AB4\succeqqSucceeds Above Equals Sign
    U+02AB5\precneqqPrecedes Above Not Equal To
    U+02AB6\succneqqSucceeds Above Not Equal To
    U+02AB7\precapproxPrecedes Above Almost Equal To
    U+02AB8\succapproxSucceeds Above Almost Equal To
    U+02AB9\precnapproxPrecedes Above Not Almost Equal To
    U+02ABA\succnapproxSucceeds Above Not Almost Equal To
    U+02ABB\PrecDouble Precedes
    U+02ABC\SuccDouble Succeeds
    U+02ABD\subsetdotSubset With Dot
    U+02ABE\supsetdotSuperset With Dot
    U+02ABF⪿\subsetplusSubset With Plus Sign Below
    U+02AC0\supsetplusSuperset With Plus Sign Below
    U+02AC1\submultSubset With Multiplication Sign Below
    U+02AC2\supmultSuperset With Multiplication Sign Below
    U+02AC3\subedotSubset Of Or Equal To With Dot Above
    U+02AC4\supedotSuperset Of Or Equal To With Dot Above
    U+02AC5\subseteqqSubset Of Above Equals Sign
    U+02AC5 + U+00338⫅̸\nsubseteqqSubset Of Above Equals Sign + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AC6\supseteqqSuperset Of Above Equals Sign
    U+02AC6 + U+00338⫆̸\nsupseteqqSuperset Of Above Equals Sign + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AC7\subsimSubset Of Above Tilde Operator
    U+02AC8\supsimSuperset Of Above Tilde Operator
    U+02AC9\subsetapproxSubset Of Above Almost Equal To
    U+02ACA\supsetapproxSuperset Of Above Almost Equal To
    U+02ACB\subsetneqqSubset Of Above Not Equal To
    U+02ACC\supsetneqqSuperset Of Above Not Equal To
    U+02ACD\lsqhookSquare Left Open Box Operator
    U+02ACE\rsqhookSquare Right Open Box Operator
    U+02ACF\csubClosed Subset
    U+02AD0\csupClosed Superset
    U+02AD1\csubeClosed Subset Or Equal To
    U+02AD2\csupeClosed Superset Or Equal To
    U+02AD3\subsupSubset Above Superset
    U+02AD4\supsubSuperset Above Subset
    U+02AD5\subsubSubset Above Subset
    U+02AD6\supsupSuperset Above Superset
    U+02AD7\suphsubSuperset Beside Subset
    U+02AD8\supdsubSuperset Beside And Joined By Dash With Subset
    U+02AD9\forkvElement Of Opening Downwards
    U+02ADB\mlcpTransversal Intersection
    U+02ADC\forksForking
    U+02ADD\forksnotNonforking
    U+02AE3\dashVDouble Vertical Bar Left Turnstile
    U+02AE4\DashvVertical Bar Double Left Turnstile
    U+02AEA\Top, \downvDashDouble Down Tack
    U+02AEB\upvDash, \Bot, \indepDouble Up Tack
    U+02AF4\interleaveTriple Vertical Bar Binary Relation
    U+02AF6\tdcolTriple Colon Operator
    U+02AF7\lllnestTriple Nested Less-Than
    U+02AF8\gggnestTriple Nested Greater-Than
    U+02AF9\leqqslantDouble-Line Slanted Less-Than Or Equal To
    U+02AFA\geqqslantDouble-Line Slanted Greater-Than Or Equal To
    U+02B05\:arrow_left:Leftwards Black Arrow
    U+02B06\:arrow_up:Upwards Black Arrow
    U+02B07\:arrow_down:Downwards Black Arrow
    U+02B12\squaretopblackSquare With Top Half Black
    U+02B13\squarebotblackSquare With Bottom Half Black
    U+02B14\squareurblackSquare With Upper Right Diagonal Half Black
    U+02B15\squarellblackSquare With Lower Left Diagonal Half Black
    U+02B16\diamondleftblackDiamond With Left Half Black
    U+02B17\diamondrightblackDiamond With Right Half Black
    U+02B18\diamondtopblackDiamond With Top Half Black
    U+02B19\diamondbotblackDiamond With Bottom Half Black
    U+02B1A\dottedsquareDotted Square
    U+02B1B\lgblksquare, \:black_large_square:Black Large Square
    U+02B1C\lgwhtsquare, \:white_large_square:White Large Square
    U+02B1D\vysmblksquareBlack Very Small Square
    U+02B1E\vysmwhtsquareWhite Very Small Square
    U+02B1F\pentagonblackBlack Pentagon
    U+02B20\pentagonWhite Pentagon
    U+02B21\varhexagonWhite Hexagon
    U+02B22\varhexagonblackBlack Hexagon
    U+02B23\hexagonblackHorizontal Black Hexagon
    U+02B24\lgblkcircleBlack Large Circle
    U+02B25\mdblkdiamondBlack Medium Diamond
    U+02B26\mdwhtdiamondWhite Medium Diamond
    U+02B27\mdblklozengeBlack Medium Lozenge
    U+02B28\mdwhtlozengeWhite Medium Lozenge
    U+02B29\smblkdiamondBlack Small Diamond
    U+02B2A\smblklozengeBlack Small Lozenge
    U+02B2B\smwhtlozengeWhite Small Lozenge
    U+02B2C\blkhorzovalBlack Horizontal Ellipse
    U+02B2D\whthorzovalWhite Horizontal Ellipse
    U+02B2E\blkvertovalBlack Vertical Ellipse
    U+02B2F\whtvertovalWhite Vertical Ellipse
    U+02B30\circleonleftarrowLeft Arrow With Small Circle
    U+02B31\leftthreearrowsThree Leftwards Arrows
    U+02B32\leftarrowonoplusLeft Arrow With Circled Plus
    U+02B33\longleftsquigarrowLong Leftwards Squiggle Arrow
    U+02B34\nvtwoheadleftarrowLeftwards Two-Headed Arrow With Vertical Stroke
    U+02B35\nVtwoheadleftarrowLeftwards Two-Headed Arrow With Double Vertical Stroke
    U+02B36\twoheadmapsfromLeftwards Two-Headed Arrow From Bar
    U+02B37\twoheadleftdbkarrowLeftwards Two-Headed Triple Dash Arrow
    U+02B38\leftdotarrowLeftwards Arrow With Dotted Stem
    U+02B39\nvleftarrowtailLeftwards Arrow With Tail With Vertical Stroke
    U+02B3A\nVleftarrowtailLeftwards Arrow With Tail With Double Vertical Stroke
    U+02B3B\twoheadleftarrowtailLeftwards Two-Headed Arrow With Tail
    U+02B3C\nvtwoheadleftarrowtailLeftwards Two-Headed Arrow With Tail With Vertical Stroke
    U+02B3D\nVtwoheadleftarrowtailLeftwards Two-Headed Arrow With Tail With Double Vertical Stroke
    U+02B3E\leftarrowxLeftwards Arrow Through X
    U+02B3F⬿\leftcurvedarrowWave Arrow Pointing Directly Left
    U+02B40\equalleftarrowEquals Sign Above Leftwards Arrow
    U+02B41\bsimilarleftarrowReverse Tilde Operator Above Leftwards Arrow
    U+02B42\leftarrowbackapproxLeftwards Arrow Above Reverse Almost Equal To
    U+02B43\rightarrowgtrRightwards Arrow Through Greater-Than
    U+02B44\rightarrowsupsetRightwards Arrow Through Superset
    U+02B45\LLeftarrowLeftwards Quadruple Arrow
    U+02B46\RRightarrowRightwards Quadruple Arrow
    U+02B47\bsimilarrightarrowReverse Tilde Operator Above Rightwards Arrow
    U+02B48\rightarrowbackapproxRightwards Arrow Above Reverse Almost Equal To
    U+02B49\similarleftarrowTilde Operator Above Leftwards Arrow
    U+02B4A\leftarrowapproxLeftwards Arrow Above Almost Equal To
    U+02B4B\leftarrowbsimilarLeftwards Arrow Above Reverse Tilde Operator
    U+02B4C\rightarrowbsimilarRightwards Arrow Above Reverse Tilde Operator
    U+02B50\medwhitestar, \:star:White Medium Star
    U+02B51\medblackstarBlack Small Star
    U+02B52\smwhitestarWhite Small Star
    U+02B53\rightpentagonblackBlack Right-Pointing Pentagon
    U+02B54\rightpentagonWhite Right-Pointing Pentagon
    U+02B55\:o:Heavy Large Circle
    U+02C7C\_jLatin Subscript Small Letter J
    U+02C7D\^VModifier Letter Capital V
    U+03012\postalmarkPostal Mark
    U+03030\:wavy_dash:Wavy Dash
    U+0303D\:part_alternation_mark:Part Alternation Mark
    U+03297\:congratulations:Circled Ideograph Congratulation
    U+03299\:secret:Circled Ideograph Secret
    U+0A71B\^uparrowModifier Letter Raised Up Arrow
    U+0A71C\^downarrowModifier Letter Raised Down Arrow
    U+0A71D\^!Modifier Letter Raised Exclamation Mark
    U+1D400𝐀\bfAMathematical Bold Capital A
    U+1D401𝐁\bfBMathematical Bold Capital B
    U+1D402𝐂\bfCMathematical Bold Capital C
    U+1D403𝐃\bfDMathematical Bold Capital D
    U+1D404𝐄\bfEMathematical Bold Capital E
    U+1D405𝐅\bfFMathematical Bold Capital F
    U+1D406𝐆\bfGMathematical Bold Capital G
    U+1D407𝐇\bfHMathematical Bold Capital H
    U+1D408𝐈\bfIMathematical Bold Capital I
    U+1D409𝐉\bfJMathematical Bold Capital J
    U+1D40A𝐊\bfKMathematical Bold Capital K
    U+1D40B𝐋\bfLMathematical Bold Capital L
    U+1D40C𝐌\bfMMathematical Bold Capital M
    U+1D40D𝐍\bfNMathematical Bold Capital N
    U+1D40E𝐎\bfOMathematical Bold Capital O
    U+1D40F𝐏\bfPMathematical Bold Capital P
    U+1D410𝐐\bfQMathematical Bold Capital Q
    U+1D411𝐑\bfRMathematical Bold Capital R
    U+1D412𝐒\bfSMathematical Bold Capital S
    U+1D413𝐓\bfTMathematical Bold Capital T
    U+1D414𝐔\bfUMathematical Bold Capital U
    U+1D415𝐕\bfVMathematical Bold Capital V
    U+1D416𝐖\bfWMathematical Bold Capital W
    U+1D417𝐗\bfXMathematical Bold Capital X
    U+1D418𝐘\bfYMathematical Bold Capital Y
    U+1D419𝐙\bfZMathematical Bold Capital Z
    U+1D41A𝐚\bfaMathematical Bold Small A
    U+1D41B𝐛\bfbMathematical Bold Small B
    U+1D41C𝐜\bfcMathematical Bold Small C
    U+1D41D𝐝\bfdMathematical Bold Small D
    U+1D41E𝐞\bfeMathematical Bold Small E
    U+1D41F𝐟\bffMathematical Bold Small F
    U+1D420𝐠\bfgMathematical Bold Small G
    U+1D421𝐡\bfhMathematical Bold Small H
    U+1D422𝐢\bfiMathematical Bold Small I
    U+1D423𝐣\bfjMathematical Bold Small J
    U+1D424𝐤\bfkMathematical Bold Small K
    U+1D425𝐥\bflMathematical Bold Small L
    U+1D426𝐦\bfmMathematical Bold Small M
    U+1D427𝐧\bfnMathematical Bold Small N
    U+1D428𝐨\bfoMathematical Bold Small O
    U+1D429𝐩\bfpMathematical Bold Small P
    U+1D42A𝐪\bfqMathematical Bold Small Q
    U+1D42B𝐫\bfrMathematical Bold Small R
    U+1D42C𝐬\bfsMathematical Bold Small S
    U+1D42D𝐭\bftMathematical Bold Small T
    U+1D42E𝐮\bfuMathematical Bold Small U
    U+1D42F𝐯\bfvMathematical Bold Small V
    U+1D430𝐰\bfwMathematical Bold Small W
    U+1D431𝐱\bfxMathematical Bold Small X
    U+1D432𝐲\bfyMathematical Bold Small Y
    U+1D433𝐳\bfzMathematical Bold Small Z
    U+1D434𝐴\itAMathematical Italic Capital A
    U+1D435𝐵\itBMathematical Italic Capital B
    U+1D436𝐶\itCMathematical Italic Capital C
    U+1D437𝐷\itDMathematical Italic Capital D
    U+1D438𝐸\itEMathematical Italic Capital E
    U+1D439𝐹\itFMathematical Italic Capital F
    U+1D43A𝐺\itGMathematical Italic Capital G
    U+1D43B𝐻\itHMathematical Italic Capital H
    U+1D43C𝐼\itIMathematical Italic Capital I
    U+1D43D𝐽\itJMathematical Italic Capital J
    U+1D43E𝐾\itKMathematical Italic Capital K
    U+1D43F𝐿\itLMathematical Italic Capital L
    U+1D440𝑀\itMMathematical Italic Capital M
    U+1D441𝑁\itNMathematical Italic Capital N
    U+1D442𝑂\itOMathematical Italic Capital O
    U+1D443𝑃\itPMathematical Italic Capital P
    U+1D444𝑄\itQMathematical Italic Capital Q
    U+1D445𝑅\itRMathematical Italic Capital R
    U+1D446𝑆\itSMathematical Italic Capital S
    U+1D447𝑇\itTMathematical Italic Capital T
    U+1D448𝑈\itUMathematical Italic Capital U
    U+1D449𝑉\itVMathematical Italic Capital V
    U+1D44A𝑊\itWMathematical Italic Capital W
    U+1D44B𝑋\itXMathematical Italic Capital X
    U+1D44C𝑌\itYMathematical Italic Capital Y
    U+1D44D𝑍\itZMathematical Italic Capital Z
    U+1D44E𝑎\itaMathematical Italic Small A
    U+1D44F𝑏\itbMathematical Italic Small B
    U+1D450𝑐\itcMathematical Italic Small C
    U+1D451𝑑\itdMathematical Italic Small D
    U+1D452𝑒\iteMathematical Italic Small E
    U+1D453𝑓\itfMathematical Italic Small F
    U+1D454𝑔\itgMathematical Italic Small G
    U+1D456𝑖\itiMathematical Italic Small I
    U+1D457𝑗\itjMathematical Italic Small J
    U+1D458𝑘\itkMathematical Italic Small K
    U+1D459𝑙\itlMathematical Italic Small L
    U+1D45A𝑚\itmMathematical Italic Small M
    U+1D45B𝑛\itnMathematical Italic Small N
    U+1D45C𝑜\itoMathematical Italic Small O
    U+1D45D𝑝\itpMathematical Italic Small P
    U+1D45E𝑞\itqMathematical Italic Small Q
    U+1D45F𝑟\itrMathematical Italic Small R
    U+1D460𝑠\itsMathematical Italic Small S
    U+1D461𝑡\ittMathematical Italic Small T
    U+1D462𝑢\ituMathematical Italic Small U
    U+1D463𝑣\itvMathematical Italic Small V
    U+1D464𝑤\itwMathematical Italic Small W
    U+1D465𝑥\itxMathematical Italic Small X
    U+1D466𝑦\ityMathematical Italic Small Y
    U+1D467𝑧\itzMathematical Italic Small Z
    U+1D468𝑨\biAMathematical Bold Italic Capital A
    U+1D469𝑩\biBMathematical Bold Italic Capital B
    U+1D46A𝑪\biCMathematical Bold Italic Capital C
    U+1D46B𝑫\biDMathematical Bold Italic Capital D
    U+1D46C𝑬\biEMathematical Bold Italic Capital E
    U+1D46D𝑭\biFMathematical Bold Italic Capital F
    U+1D46E𝑮\biGMathematical Bold Italic Capital G
    U+1D46F𝑯\biHMathematical Bold Italic Capital H
    U+1D470𝑰\biIMathematical Bold Italic Capital I
    U+1D471𝑱\biJMathematical Bold Italic Capital J
    U+1D472𝑲\biKMathematical Bold Italic Capital K
    U+1D473𝑳\biLMathematical Bold Italic Capital L
    U+1D474𝑴\biMMathematical Bold Italic Capital M
    U+1D475𝑵\biNMathematical Bold Italic Capital N
    U+1D476𝑶\biOMathematical Bold Italic Capital O
    U+1D477𝑷\biPMathematical Bold Italic Capital P
    U+1D478𝑸\biQMathematical Bold Italic Capital Q
    U+1D479𝑹\biRMathematical Bold Italic Capital R
    U+1D47A𝑺\biSMathematical Bold Italic Capital S
    U+1D47B𝑻\biTMathematical Bold Italic Capital T
    U+1D47C𝑼\biUMathematical Bold Italic Capital U
    U+1D47D𝑽\biVMathematical Bold Italic Capital V
    U+1D47E𝑾\biWMathematical Bold Italic Capital W
    U+1D47F𝑿\biXMathematical Bold Italic Capital X
    U+1D480𝒀\biYMathematical Bold Italic Capital Y
    U+1D481𝒁\biZMathematical Bold Italic Capital Z
    U+1D482𝒂\biaMathematical Bold Italic Small A
    U+1D483𝒃\bibMathematical Bold Italic Small B
    U+1D484𝒄\bicMathematical Bold Italic Small C
    U+1D485𝒅\bidMathematical Bold Italic Small D
    U+1D486𝒆\bieMathematical Bold Italic Small E
    U+1D487𝒇\bifMathematical Bold Italic Small F
    U+1D488𝒈\bigMathematical Bold Italic Small G
    U+1D489𝒉\bihMathematical Bold Italic Small H
    U+1D48A𝒊\biiMathematical Bold Italic Small I
    U+1D48B𝒋\bijMathematical Bold Italic Small J
    U+1D48C𝒌\bikMathematical Bold Italic Small K
    U+1D48D𝒍\bilMathematical Bold Italic Small L
    U+1D48E𝒎\bimMathematical Bold Italic Small M
    U+1D48F𝒏\binMathematical Bold Italic Small N
    U+1D490𝒐\bioMathematical Bold Italic Small O
    U+1D491𝒑\bipMathematical Bold Italic Small P
    U+1D492𝒒\biqMathematical Bold Italic Small Q
    U+1D493𝒓\birMathematical Bold Italic Small R
    U+1D494𝒔\bisMathematical Bold Italic Small S
    U+1D495𝒕\bitMathematical Bold Italic Small T
    U+1D496𝒖\biuMathematical Bold Italic Small U
    U+1D497𝒗\bivMathematical Bold Italic Small V
    U+1D498𝒘\biwMathematical Bold Italic Small W
    U+1D499𝒙\bixMathematical Bold Italic Small X
    U+1D49A𝒚\biyMathematical Bold Italic Small Y
    U+1D49B𝒛\bizMathematical Bold Italic Small Z
    U+1D49C𝒜\scrAMathematical Script Capital A
    U+1D49E𝒞\scrCMathematical Script Capital C
    U+1D49F𝒟\scrDMathematical Script Capital D
    U+1D4A2𝒢\scrGMathematical Script Capital G
    U+1D4A5𝒥\scrJMathematical Script Capital J
    U+1D4A6𝒦\scrKMathematical Script Capital K
    U+1D4A9𝒩\scrNMathematical Script Capital N
    U+1D4AA𝒪\scrOMathematical Script Capital O
    U+1D4AB𝒫\scrPMathematical Script Capital P
    U+1D4AC𝒬\scrQMathematical Script Capital Q
    U+1D4AE𝒮\scrSMathematical Script Capital S
    U+1D4AF𝒯\scrTMathematical Script Capital T
    U+1D4B0𝒰\scrUMathematical Script Capital U
    U+1D4B1𝒱\scrVMathematical Script Capital V
    U+1D4B2𝒲\scrWMathematical Script Capital W
    U+1D4B3𝒳\scrXMathematical Script Capital X
    U+1D4B4𝒴\scrYMathematical Script Capital Y
    U+1D4B5𝒵\scrZMathematical Script Capital Z
    U+1D4B6𝒶\scraMathematical Script Small A
    U+1D4B7𝒷\scrbMathematical Script Small B
    U+1D4B8𝒸\scrcMathematical Script Small C
    U+1D4B9𝒹\scrdMathematical Script Small D
    U+1D4BB𝒻\scrfMathematical Script Small F
    U+1D4BD𝒽\scrhMathematical Script Small H
    U+1D4BE𝒾\scriMathematical Script Small I
    U+1D4BF𝒿\scrjMathematical Script Small J
    U+1D4C0𝓀\scrkMathematical Script Small K
    U+1D4C1𝓁\scrlMathematical Script Small L
    U+1D4C2𝓂\scrmMathematical Script Small M
    U+1D4C3𝓃\scrnMathematical Script Small N
    U+1D4C5𝓅\scrpMathematical Script Small P
    U+1D4C6𝓆\scrqMathematical Script Small Q
    U+1D4C7𝓇\scrrMathematical Script Small R
    U+1D4C8𝓈\scrsMathematical Script Small S
    U+1D4C9𝓉\scrtMathematical Script Small T
    U+1D4CA𝓊\scruMathematical Script Small U
    U+1D4CB𝓋\scrvMathematical Script Small V
    U+1D4CC𝓌\scrwMathematical Script Small W
    U+1D4CD𝓍\scrxMathematical Script Small X
    U+1D4CE𝓎\scryMathematical Script Small Y
    U+1D4CF𝓏\scrzMathematical Script Small Z
    U+1D4D0𝓐\bscrAMathematical Bold Script Capital A
    U+1D4D1𝓑\bscrBMathematical Bold Script Capital B
    U+1D4D2𝓒\bscrCMathematical Bold Script Capital C
    U+1D4D3𝓓\bscrDMathematical Bold Script Capital D
    U+1D4D4𝓔\bscrEMathematical Bold Script Capital E
    U+1D4D5𝓕\bscrFMathematical Bold Script Capital F
    U+1D4D6𝓖\bscrGMathematical Bold Script Capital G
    U+1D4D7𝓗\bscrHMathematical Bold Script Capital H
    U+1D4D8𝓘\bscrIMathematical Bold Script Capital I
    U+1D4D9𝓙\bscrJMathematical Bold Script Capital J
    U+1D4DA𝓚\bscrKMathematical Bold Script Capital K
    U+1D4DB𝓛\bscrLMathematical Bold Script Capital L
    U+1D4DC𝓜\bscrMMathematical Bold Script Capital M
    U+1D4DD𝓝\bscrNMathematical Bold Script Capital N
    U+1D4DE𝓞\bscrOMathematical Bold Script Capital O
    U+1D4DF𝓟\bscrPMathematical Bold Script Capital P
    U+1D4E0𝓠\bscrQMathematical Bold Script Capital Q
    U+1D4E1𝓡\bscrRMathematical Bold Script Capital R
    U+1D4E2𝓢\bscrSMathematical Bold Script Capital S
    U+1D4E3𝓣\bscrTMathematical Bold Script Capital T
    U+1D4E4𝓤\bscrUMathematical Bold Script Capital U
    U+1D4E5𝓥\bscrVMathematical Bold Script Capital V
    U+1D4E6𝓦\bscrWMathematical Bold Script Capital W
    U+1D4E7𝓧\bscrXMathematical Bold Script Capital X
    U+1D4E8𝓨\bscrYMathematical Bold Script Capital Y
    U+1D4E9𝓩\bscrZMathematical Bold Script Capital Z
    U+1D4EA𝓪\bscraMathematical Bold Script Small A
    U+1D4EB𝓫\bscrbMathematical Bold Script Small B
    U+1D4EC𝓬\bscrcMathematical Bold Script Small C
    U+1D4ED𝓭\bscrdMathematical Bold Script Small D
    U+1D4EE𝓮\bscreMathematical Bold Script Small E
    U+1D4EF𝓯\bscrfMathematical Bold Script Small F
    U+1D4F0𝓰\bscrgMathematical Bold Script Small G
    U+1D4F1𝓱\bscrhMathematical Bold Script Small H
    U+1D4F2𝓲\bscriMathematical Bold Script Small I
    U+1D4F3𝓳\bscrjMathematical Bold Script Small J
    U+1D4F4𝓴\bscrkMathematical Bold Script Small K
    U+1D4F5𝓵\bscrlMathematical Bold Script Small L
    U+1D4F6𝓶\bscrmMathematical Bold Script Small M
    U+1D4F7𝓷\bscrnMathematical Bold Script Small N
    U+1D4F8𝓸\bscroMathematical Bold Script Small O
    U+1D4F9𝓹\bscrpMathematical Bold Script Small P
    U+1D4FA𝓺\bscrqMathematical Bold Script Small Q
    U+1D4FB𝓻\bscrrMathematical Bold Script Small R
    U+1D4FC𝓼\bscrsMathematical Bold Script Small S
    U+1D4FD𝓽\bscrtMathematical Bold Script Small T
    U+1D4FE𝓾\bscruMathematical Bold Script Small U
    U+1D4FF𝓿\bscrvMathematical Bold Script Small V
    U+1D500𝔀\bscrwMathematical Bold Script Small W
    U+1D501𝔁\bscrxMathematical Bold Script Small X
    U+1D502𝔂\bscryMathematical Bold Script Small Y
    U+1D503𝔃\bscrzMathematical Bold Script Small Z
    U+1D504𝔄\frakAMathematical Fraktur Capital A
    U+1D505𝔅\frakBMathematical Fraktur Capital B
    U+1D507𝔇\frakDMathematical Fraktur Capital D
    U+1D508𝔈\frakEMathematical Fraktur Capital E
    U+1D509𝔉\frakFMathematical Fraktur Capital F
    U+1D50A𝔊\frakGMathematical Fraktur Capital G
    U+1D50D𝔍\frakJMathematical Fraktur Capital J
    U+1D50E𝔎\frakKMathematical Fraktur Capital K
    U+1D50F𝔏\frakLMathematical Fraktur Capital L
    U+1D510𝔐\frakMMathematical Fraktur Capital M
    U+1D511𝔑\frakNMathematical Fraktur Capital N
    U+1D512𝔒\frakOMathematical Fraktur Capital O
    U+1D513𝔓\frakPMathematical Fraktur Capital P
    U+1D514𝔔\frakQMathematical Fraktur Capital Q
    U+1D516𝔖\frakSMathematical Fraktur Capital S
    U+1D517𝔗\frakTMathematical Fraktur Capital T
    U+1D518𝔘\frakUMathematical Fraktur Capital U
    U+1D519𝔙\frakVMathematical Fraktur Capital V
    U+1D51A𝔚\frakWMathematical Fraktur Capital W
    U+1D51B𝔛\frakXMathematical Fraktur Capital X
    U+1D51C𝔜\frakYMathematical Fraktur Capital Y
    U+1D51E𝔞\frakaMathematical Fraktur Small A
    U+1D51F𝔟\frakbMathematical Fraktur Small B
    U+1D520𝔠\frakcMathematical Fraktur Small C
    U+1D521𝔡\frakdMathematical Fraktur Small D
    U+1D522𝔢\frakeMathematical Fraktur Small E
    U+1D523𝔣\frakfMathematical Fraktur Small F
    U+1D524𝔤\frakgMathematical Fraktur Small G
    U+1D525𝔥\frakhMathematical Fraktur Small H
    U+1D526𝔦\frakiMathematical Fraktur Small I
    U+1D527𝔧\frakjMathematical Fraktur Small J
    U+1D528𝔨\frakkMathematical Fraktur Small K
    U+1D529𝔩\fraklMathematical Fraktur Small L
    U+1D52A𝔪\frakmMathematical Fraktur Small M
    U+1D52B𝔫\fraknMathematical Fraktur Small N
    U+1D52C𝔬\frakoMathematical Fraktur Small O
    U+1D52D𝔭\frakpMathematical Fraktur Small P
    U+1D52E𝔮\frakqMathematical Fraktur Small Q
    U+1D52F𝔯\frakrMathematical Fraktur Small R
    U+1D530𝔰\fraksMathematical Fraktur Small S
    U+1D531𝔱\fraktMathematical Fraktur Small T
    U+1D532𝔲\frakuMathematical Fraktur Small U
    U+1D533𝔳\frakvMathematical Fraktur Small V
    U+1D534𝔴\frakwMathematical Fraktur Small W
    U+1D535𝔵\frakxMathematical Fraktur Small X
    U+1D536𝔶\frakyMathematical Fraktur Small Y
    U+1D537𝔷\frakzMathematical Fraktur Small Z
    U+1D538𝔸\bbAMathematical Double-Struck Capital A
    U+1D539𝔹\bbBMathematical Double-Struck Capital B
    U+1D53B𝔻\bbDMathematical Double-Struck Capital D
    U+1D53C𝔼\bbEMathematical Double-Struck Capital E
    U+1D53D𝔽\bbFMathematical Double-Struck Capital F
    U+1D53E𝔾\bbGMathematical Double-Struck Capital G
    U+1D540𝕀\bbIMathematical Double-Struck Capital I
    U+1D541𝕁\bbJMathematical Double-Struck Capital J
    U+1D542𝕂\bbKMathematical Double-Struck Capital K
    U+1D543𝕃\bbLMathematical Double-Struck Capital L
    U+1D544𝕄\bbMMathematical Double-Struck Capital M
    U+1D546𝕆\bbOMathematical Double-Struck Capital O
    U+1D54A𝕊\bbSMathematical Double-Struck Capital S
    U+1D54B𝕋\bbTMathematical Double-Struck Capital T
    U+1D54C𝕌\bbUMathematical Double-Struck Capital U
    U+1D54D𝕍\bbVMathematical Double-Struck Capital V
    U+1D54E𝕎\bbWMathematical Double-Struck Capital W
    U+1D54F𝕏\bbXMathematical Double-Struck Capital X
    U+1D550𝕐\bbYMathematical Double-Struck Capital Y
    U+1D552𝕒\bbaMathematical Double-Struck Small A
    U+1D553𝕓\bbbMathematical Double-Struck Small B
    U+1D554𝕔\bbcMathematical Double-Struck Small C
    U+1D555𝕕\bbdMathematical Double-Struck Small D
    U+1D556𝕖\bbeMathematical Double-Struck Small E
    U+1D557𝕗\bbfMathematical Double-Struck Small F
    U+1D558𝕘\bbgMathematical Double-Struck Small G
    U+1D559𝕙\bbhMathematical Double-Struck Small H
    U+1D55A𝕚\bbiMathematical Double-Struck Small I
    U+1D55B𝕛\bbjMathematical Double-Struck Small J
    U+1D55C𝕜\bbkMathematical Double-Struck Small K
    U+1D55D𝕝\bblMathematical Double-Struck Small L
    U+1D55E𝕞\bbmMathematical Double-Struck Small M
    U+1D55F𝕟\bbnMathematical Double-Struck Small N
    U+1D560𝕠\bboMathematical Double-Struck Small O
    U+1D561𝕡\bbpMathematical Double-Struck Small P
    U+1D562𝕢\bbqMathematical Double-Struck Small Q
    U+1D563𝕣\bbrMathematical Double-Struck Small R
    U+1D564𝕤\bbsMathematical Double-Struck Small S
    U+1D565𝕥\bbtMathematical Double-Struck Small T
    U+1D566𝕦\bbuMathematical Double-Struck Small U
    U+1D567𝕧\bbvMathematical Double-Struck Small V
    U+1D568𝕨\bbwMathematical Double-Struck Small W
    U+1D569𝕩\bbxMathematical Double-Struck Small X
    U+1D56A𝕪\bbyMathematical Double-Struck Small Y
    U+1D56B𝕫\bbzMathematical Double-Struck Small Z
    U+1D56C𝕬\bfrakAMathematical Bold Fraktur Capital A
    U+1D56D𝕭\bfrakBMathematical Bold Fraktur Capital B
    U+1D56E𝕮\bfrakCMathematical Bold Fraktur Capital C
    U+1D56F𝕯\bfrakDMathematical Bold Fraktur Capital D
    U+1D570𝕰\bfrakEMathematical Bold Fraktur Capital E
    U+1D571𝕱\bfrakFMathematical Bold Fraktur Capital F
    U+1D572𝕲\bfrakGMathematical Bold Fraktur Capital G
    U+1D573𝕳\bfrakHMathematical Bold Fraktur Capital H
    U+1D574𝕴\bfrakIMathematical Bold Fraktur Capital I
    U+1D575𝕵\bfrakJMathematical Bold Fraktur Capital J
    U+1D576𝕶\bfrakKMathematical Bold Fraktur Capital K
    U+1D577𝕷\bfrakLMathematical Bold Fraktur Capital L
    U+1D578𝕸\bfrakMMathematical Bold Fraktur Capital M
    U+1D579𝕹\bfrakNMathematical Bold Fraktur Capital N
    U+1D57A𝕺\bfrakOMathematical Bold Fraktur Capital O
    U+1D57B𝕻\bfrakPMathematical Bold Fraktur Capital P
    U+1D57C𝕼\bfrakQMathematical Bold Fraktur Capital Q
    U+1D57D𝕽\bfrakRMathematical Bold Fraktur Capital R
    U+1D57E𝕾\bfrakSMathematical Bold Fraktur Capital S
    U+1D57F𝕿\bfrakTMathematical Bold Fraktur Capital T
    U+1D580𝖀\bfrakUMathematical Bold Fraktur Capital U
    U+1D581𝖁\bfrakVMathematical Bold Fraktur Capital V
    U+1D582𝖂\bfrakWMathematical Bold Fraktur Capital W
    U+1D583𝖃\bfrakXMathematical Bold Fraktur Capital X
    U+1D584𝖄\bfrakYMathematical Bold Fraktur Capital Y
    U+1D585𝖅\bfrakZMathematical Bold Fraktur Capital Z
    U+1D586𝖆\bfrakaMathematical Bold Fraktur Small A
    U+1D587𝖇\bfrakbMathematical Bold Fraktur Small B
    U+1D588𝖈\bfrakcMathematical Bold Fraktur Small C
    U+1D589𝖉\bfrakdMathematical Bold Fraktur Small D
    U+1D58A𝖊\bfrakeMathematical Bold Fraktur Small E
    U+1D58B𝖋\bfrakfMathematical Bold Fraktur Small F
    U+1D58C𝖌\bfrakgMathematical Bold Fraktur Small G
    U+1D58D𝖍\bfrakhMathematical Bold Fraktur Small H
    U+1D58E𝖎\bfrakiMathematical Bold Fraktur Small I
    U+1D58F𝖏\bfrakjMathematical Bold Fraktur Small J
    U+1D590𝖐\bfrakkMathematical Bold Fraktur Small K
    U+1D591𝖑\bfraklMathematical Bold Fraktur Small L
    U+1D592𝖒\bfrakmMathematical Bold Fraktur Small M
    U+1D593𝖓\bfraknMathematical Bold Fraktur Small N
    U+1D594𝖔\bfrakoMathematical Bold Fraktur Small O
    U+1D595𝖕\bfrakpMathematical Bold Fraktur Small P
    U+1D596𝖖\bfrakqMathematical Bold Fraktur Small Q
    U+1D597𝖗\bfrakrMathematical Bold Fraktur Small R
    U+1D598𝖘\bfraksMathematical Bold Fraktur Small S
    U+1D599𝖙\bfraktMathematical Bold Fraktur Small T
    U+1D59A𝖚\bfrakuMathematical Bold Fraktur Small U
    U+1D59B𝖛\bfrakvMathematical Bold Fraktur Small V
    U+1D59C𝖜\bfrakwMathematical Bold Fraktur Small W
    U+1D59D𝖝\bfrakxMathematical Bold Fraktur Small X
    U+1D59E𝖞\bfrakyMathematical Bold Fraktur Small Y
    U+1D59F𝖟\bfrakzMathematical Bold Fraktur Small Z
    U+1D5A0𝖠\sansAMathematical Sans-Serif Capital A
    U+1D5A1𝖡\sansBMathematical Sans-Serif Capital B
    U+1D5A2𝖢\sansCMathematical Sans-Serif Capital C
    U+1D5A3𝖣\sansDMathematical Sans-Serif Capital D
    U+1D5A4𝖤\sansEMathematical Sans-Serif Capital E
    U+1D5A5𝖥\sansFMathematical Sans-Serif Capital F
    U+1D5A6𝖦\sansGMathematical Sans-Serif Capital G
    U+1D5A7𝖧\sansHMathematical Sans-Serif Capital H
    U+1D5A8𝖨\sansIMathematical Sans-Serif Capital I
    U+1D5A9𝖩\sansJMathematical Sans-Serif Capital J
    U+1D5AA𝖪\sansKMathematical Sans-Serif Capital K
    U+1D5AB𝖫\sansLMathematical Sans-Serif Capital L
    U+1D5AC𝖬\sansMMathematical Sans-Serif Capital M
    U+1D5AD𝖭\sansNMathematical Sans-Serif Capital N
    U+1D5AE𝖮\sansOMathematical Sans-Serif Capital O
    U+1D5AF𝖯\sansPMathematical Sans-Serif Capital P
    U+1D5B0𝖰\sansQMathematical Sans-Serif Capital Q
    U+1D5B1𝖱\sansRMathematical Sans-Serif Capital R
    U+1D5B2𝖲\sansSMathematical Sans-Serif Capital S
    U+1D5B3𝖳\sansTMathematical Sans-Serif Capital T
    U+1D5B4𝖴\sansUMathematical Sans-Serif Capital U
    U+1D5B5𝖵\sansVMathematical Sans-Serif Capital V
    U+1D5B6𝖶\sansWMathematical Sans-Serif Capital W
    U+1D5B7𝖷\sansXMathematical Sans-Serif Capital X
    U+1D5B8𝖸\sansYMathematical Sans-Serif Capital Y
    U+1D5B9𝖹\sansZMathematical Sans-Serif Capital Z
    U+1D5BA𝖺\sansaMathematical Sans-Serif Small A
    U+1D5BB𝖻\sansbMathematical Sans-Serif Small B
    U+1D5BC𝖼\sanscMathematical Sans-Serif Small C
    U+1D5BD𝖽\sansdMathematical Sans-Serif Small D
    U+1D5BE𝖾\sanseMathematical Sans-Serif Small E
    U+1D5BF𝖿\sansfMathematical Sans-Serif Small F
    U+1D5C0𝗀\sansgMathematical Sans-Serif Small G
    U+1D5C1𝗁\sanshMathematical Sans-Serif Small H
    U+1D5C2𝗂\sansiMathematical Sans-Serif Small I
    U+1D5C3𝗃\sansjMathematical Sans-Serif Small J
    U+1D5C4𝗄\sanskMathematical Sans-Serif Small K
    U+1D5C5𝗅\sanslMathematical Sans-Serif Small L
    U+1D5C6𝗆\sansmMathematical Sans-Serif Small M
    U+1D5C7𝗇\sansnMathematical Sans-Serif Small N
    U+1D5C8𝗈\sansoMathematical Sans-Serif Small O
    U+1D5C9𝗉\sanspMathematical Sans-Serif Small P
    U+1D5CA𝗊\sansqMathematical Sans-Serif Small Q
    U+1D5CB𝗋\sansrMathematical Sans-Serif Small R
    U+1D5CC𝗌\sanssMathematical Sans-Serif Small S
    U+1D5CD𝗍\sanstMathematical Sans-Serif Small T
    U+1D5CE𝗎\sansuMathematical Sans-Serif Small U
    U+1D5CF𝗏\sansvMathematical Sans-Serif Small V
    U+1D5D0𝗐\sanswMathematical Sans-Serif Small W
    U+1D5D1𝗑\sansxMathematical Sans-Serif Small X
    U+1D5D2𝗒\sansyMathematical Sans-Serif Small Y
    U+1D5D3𝗓\sanszMathematical Sans-Serif Small Z
    U+1D5D4𝗔\bsansAMathematical Sans-Serif Bold Capital A
    U+1D5D5𝗕\bsansBMathematical Sans-Serif Bold Capital B
    U+1D5D6𝗖\bsansCMathematical Sans-Serif Bold Capital C
    U+1D5D7𝗗\bsansDMathematical Sans-Serif Bold Capital D
    U+1D5D8𝗘\bsansEMathematical Sans-Serif Bold Capital E
    U+1D5D9𝗙\bsansFMathematical Sans-Serif Bold Capital F
    U+1D5DA𝗚\bsansGMathematical Sans-Serif Bold Capital G
    U+1D5DB𝗛\bsansHMathematical Sans-Serif Bold Capital H
    U+1D5DC𝗜\bsansIMathematical Sans-Serif Bold Capital I
    U+1D5DD𝗝\bsansJMathematical Sans-Serif Bold Capital J
    U+1D5DE𝗞\bsansKMathematical Sans-Serif Bold Capital K
    U+1D5DF𝗟\bsansLMathematical Sans-Serif Bold Capital L
    U+1D5E0𝗠\bsansMMathematical Sans-Serif Bold Capital M
    U+1D5E1𝗡\bsansNMathematical Sans-Serif Bold Capital N
    U+1D5E2𝗢\bsansOMathematical Sans-Serif Bold Capital O
    U+1D5E3𝗣\bsansPMathematical Sans-Serif Bold Capital P
    U+1D5E4𝗤\bsansQMathematical Sans-Serif Bold Capital Q
    U+1D5E5𝗥\bsansRMathematical Sans-Serif Bold Capital R
    U+1D5E6𝗦\bsansSMathematical Sans-Serif Bold Capital S
    U+1D5E7𝗧\bsansTMathematical Sans-Serif Bold Capital T
    U+1D5E8𝗨\bsansUMathematical Sans-Serif Bold Capital U
    U+1D5E9𝗩\bsansVMathematical Sans-Serif Bold Capital V
    U+1D5EA𝗪\bsansWMathematical Sans-Serif Bold Capital W
    U+1D5EB𝗫\bsansXMathematical Sans-Serif Bold Capital X
    U+1D5EC𝗬\bsansYMathematical Sans-Serif Bold Capital Y
    U+1D5ED𝗭\bsansZMathematical Sans-Serif Bold Capital Z
    U+1D5EE𝗮\bsansaMathematical Sans-Serif Bold Small A
    U+1D5EF𝗯\bsansbMathematical Sans-Serif Bold Small B
    U+1D5F0𝗰\bsanscMathematical Sans-Serif Bold Small C
    U+1D5F1𝗱\bsansdMathematical Sans-Serif Bold Small D
    U+1D5F2𝗲\bsanseMathematical Sans-Serif Bold Small E
    U+1D5F3𝗳\bsansfMathematical Sans-Serif Bold Small F
    U+1D5F4𝗴\bsansgMathematical Sans-Serif Bold Small G
    U+1D5F5𝗵\bsanshMathematical Sans-Serif Bold Small H
    U+1D5F6𝗶\bsansiMathematical Sans-Serif Bold Small I
    U+1D5F7𝗷\bsansjMathematical Sans-Serif Bold Small J
    U+1D5F8𝗸\bsanskMathematical Sans-Serif Bold Small K
    U+1D5F9𝗹\bsanslMathematical Sans-Serif Bold Small L
    U+1D5FA𝗺\bsansmMathematical Sans-Serif Bold Small M
    U+1D5FB𝗻\bsansnMathematical Sans-Serif Bold Small N
    U+1D5FC𝗼\bsansoMathematical Sans-Serif Bold Small O
    U+1D5FD𝗽\bsanspMathematical Sans-Serif Bold Small P
    U+1D5FE𝗾\bsansqMathematical Sans-Serif Bold Small Q
    U+1D5FF𝗿\bsansrMathematical Sans-Serif Bold Small R
    U+1D600𝘀\bsanssMathematical Sans-Serif Bold Small S
    U+1D601𝘁\bsanstMathematical Sans-Serif Bold Small T
    U+1D602𝘂\bsansuMathematical Sans-Serif Bold Small U
    U+1D603𝘃\bsansvMathematical Sans-Serif Bold Small V
    U+1D604𝘄\bsanswMathematical Sans-Serif Bold Small W
    U+1D605𝘅\bsansxMathematical Sans-Serif Bold Small X
    U+1D606𝘆\bsansyMathematical Sans-Serif Bold Small Y
    U+1D607𝘇\bsanszMathematical Sans-Serif Bold Small Z
    U+1D608𝘈\isansAMathematical Sans-Serif Italic Capital A
    U+1D609𝘉\isansBMathematical Sans-Serif Italic Capital B
    U+1D60A𝘊\isansCMathematical Sans-Serif Italic Capital C
    U+1D60B𝘋\isansDMathematical Sans-Serif Italic Capital D
    U+1D60C𝘌\isansEMathematical Sans-Serif Italic Capital E
    U+1D60D𝘍\isansFMathematical Sans-Serif Italic Capital F
    U+1D60E𝘎\isansGMathematical Sans-Serif Italic Capital G
    U+1D60F𝘏\isansHMathematical Sans-Serif Italic Capital H
    U+1D610𝘐\isansIMathematical Sans-Serif Italic Capital I
    U+1D611𝘑\isansJMathematical Sans-Serif Italic Capital J
    U+1D612𝘒\isansKMathematical Sans-Serif Italic Capital K
    U+1D613𝘓\isansLMathematical Sans-Serif Italic Capital L
    U+1D614𝘔\isansMMathematical Sans-Serif Italic Capital M
    U+1D615𝘕\isansNMathematical Sans-Serif Italic Capital N
    U+1D616𝘖\isansOMathematical Sans-Serif Italic Capital O
    U+1D617𝘗\isansPMathematical Sans-Serif Italic Capital P
    U+1D618𝘘\isansQMathematical Sans-Serif Italic Capital Q
    U+1D619𝘙\isansRMathematical Sans-Serif Italic Capital R
    U+1D61A𝘚\isansSMathematical Sans-Serif Italic Capital S
    U+1D61B𝘛\isansTMathematical Sans-Serif Italic Capital T
    U+1D61C𝘜\isansUMathematical Sans-Serif Italic Capital U
    U+1D61D𝘝\isansVMathematical Sans-Serif Italic Capital V
    U+1D61E𝘞\isansWMathematical Sans-Serif Italic Capital W
    U+1D61F𝘟\isansXMathematical Sans-Serif Italic Capital X
    U+1D620𝘠\isansYMathematical Sans-Serif Italic Capital Y
    U+1D621𝘡\isansZMathematical Sans-Serif Italic Capital Z
    U+1D622𝘢\isansaMathematical Sans-Serif Italic Small A
    U+1D623𝘣\isansbMathematical Sans-Serif Italic Small B
    U+1D624𝘤\isanscMathematical Sans-Serif Italic Small C
    U+1D625𝘥\isansdMathematical Sans-Serif Italic Small D
    U+1D626𝘦\isanseMathematical Sans-Serif Italic Small E
    U+1D627𝘧\isansfMathematical Sans-Serif Italic Small F
    U+1D628𝘨\isansgMathematical Sans-Serif Italic Small G
    U+1D629𝘩\isanshMathematical Sans-Serif Italic Small H
    U+1D62A𝘪\isansiMathematical Sans-Serif Italic Small I
    U+1D62B𝘫\isansjMathematical Sans-Serif Italic Small J
    U+1D62C𝘬\isanskMathematical Sans-Serif Italic Small K
    U+1D62D𝘭\isanslMathematical Sans-Serif Italic Small L
    U+1D62E𝘮\isansmMathematical Sans-Serif Italic Small M
    U+1D62F𝘯\isansnMathematical Sans-Serif Italic Small N
    U+1D630𝘰\isansoMathematical Sans-Serif Italic Small O
    U+1D631𝘱\isanspMathematical Sans-Serif Italic Small P
    U+1D632𝘲\isansqMathematical Sans-Serif Italic Small Q
    U+1D633𝘳\isansrMathematical Sans-Serif Italic Small R
    U+1D634𝘴\isanssMathematical Sans-Serif Italic Small S
    U+1D635𝘵\isanstMathematical Sans-Serif Italic Small T
    U+1D636𝘶\isansuMathematical Sans-Serif Italic Small U
    U+1D637𝘷\isansvMathematical Sans-Serif Italic Small V
    U+1D638𝘸\isanswMathematical Sans-Serif Italic Small W
    U+1D639𝘹\isansxMathematical Sans-Serif Italic Small X
    U+1D63A𝘺\isansyMathematical Sans-Serif Italic Small Y
    U+1D63B𝘻\isanszMathematical Sans-Serif Italic Small Z
    U+1D63C𝘼\bisansAMathematical Sans-Serif Bold Italic Capital A
    U+1D63D𝘽\bisansBMathematical Sans-Serif Bold Italic Capital B
    U+1D63E𝘾\bisansCMathematical Sans-Serif Bold Italic Capital C
    U+1D63F𝘿\bisansDMathematical Sans-Serif Bold Italic Capital D
    U+1D640𝙀\bisansEMathematical Sans-Serif Bold Italic Capital E
    U+1D641𝙁\bisansFMathematical Sans-Serif Bold Italic Capital F
    U+1D642𝙂\bisansGMathematical Sans-Serif Bold Italic Capital G
    U+1D643𝙃\bisansHMathematical Sans-Serif Bold Italic Capital H
    U+1D644𝙄\bisansIMathematical Sans-Serif Bold Italic Capital I
    U+1D645𝙅\bisansJMathematical Sans-Serif Bold Italic Capital J
    U+1D646𝙆\bisansKMathematical Sans-Serif Bold Italic Capital K
    U+1D647𝙇\bisansLMathematical Sans-Serif Bold Italic Capital L
    U+1D648𝙈\bisansMMathematical Sans-Serif Bold Italic Capital M
    U+1D649𝙉\bisansNMathematical Sans-Serif Bold Italic Capital N
    U+1D64A𝙊\bisansOMathematical Sans-Serif Bold Italic Capital O
    U+1D64B𝙋\bisansPMathematical Sans-Serif Bold Italic Capital P
    U+1D64C𝙌\bisansQMathematical Sans-Serif Bold Italic Capital Q
    U+1D64D𝙍\bisansRMathematical Sans-Serif Bold Italic Capital R
    U+1D64E𝙎\bisansSMathematical Sans-Serif Bold Italic Capital S
    U+1D64F𝙏\bisansTMathematical Sans-Serif Bold Italic Capital T
    U+1D650𝙐\bisansUMathematical Sans-Serif Bold Italic Capital U
    U+1D651𝙑\bisansVMathematical Sans-Serif Bold Italic Capital V
    U+1D652𝙒\bisansWMathematical Sans-Serif Bold Italic Capital W
    U+1D653𝙓\bisansXMathematical Sans-Serif Bold Italic Capital X
    U+1D654𝙔\bisansYMathematical Sans-Serif Bold Italic Capital Y
    U+1D655𝙕\bisansZMathematical Sans-Serif Bold Italic Capital Z
    U+1D656𝙖\bisansaMathematical Sans-Serif Bold Italic Small A
    U+1D657𝙗\bisansbMathematical Sans-Serif Bold Italic Small B
    U+1D658𝙘\bisanscMathematical Sans-Serif Bold Italic Small C
    U+1D659𝙙\bisansdMathematical Sans-Serif Bold Italic Small D
    U+1D65A𝙚\bisanseMathematical Sans-Serif Bold Italic Small E
    U+1D65B𝙛\bisansfMathematical Sans-Serif Bold Italic Small F
    U+1D65C𝙜\bisansgMathematical Sans-Serif Bold Italic Small G
    U+1D65D𝙝\bisanshMathematical Sans-Serif Bold Italic Small H
    U+1D65E𝙞\bisansiMathematical Sans-Serif Bold Italic Small I
    U+1D65F𝙟\bisansjMathematical Sans-Serif Bold Italic Small J
    U+1D660𝙠\bisanskMathematical Sans-Serif Bold Italic Small K
    U+1D661𝙡\bisanslMathematical Sans-Serif Bold Italic Small L
    U+1D662𝙢\bisansmMathematical Sans-Serif Bold Italic Small M
    U+1D663𝙣\bisansnMathematical Sans-Serif Bold Italic Small N
    U+1D664𝙤\bisansoMathematical Sans-Serif Bold Italic Small O
    U+1D665𝙥\bisanspMathematical Sans-Serif Bold Italic Small P
    U+1D666𝙦\bisansqMathematical Sans-Serif Bold Italic Small Q
    U+1D667𝙧\bisansrMathematical Sans-Serif Bold Italic Small R
    U+1D668𝙨\bisanssMathematical Sans-Serif Bold Italic Small S
    U+1D669𝙩\bisanstMathematical Sans-Serif Bold Italic Small T
    U+1D66A𝙪\bisansuMathematical Sans-Serif Bold Italic Small U
    U+1D66B𝙫\bisansvMathematical Sans-Serif Bold Italic Small V
    U+1D66C𝙬\bisanswMathematical Sans-Serif Bold Italic Small W
    U+1D66D𝙭\bisansxMathematical Sans-Serif Bold Italic Small X
    U+1D66E𝙮\bisansyMathematical Sans-Serif Bold Italic Small Y
    U+1D66F𝙯\bisanszMathematical Sans-Serif Bold Italic Small Z
    U+1D670𝙰\ttAMathematical Monospace Capital A
    U+1D671𝙱\ttBMathematical Monospace Capital B
    U+1D672𝙲\ttCMathematical Monospace Capital C
    U+1D673𝙳\ttDMathematical Monospace Capital D
    U+1D674𝙴\ttEMathematical Monospace Capital E
    U+1D675𝙵\ttFMathematical Monospace Capital F
    U+1D676𝙶\ttGMathematical Monospace Capital G
    U+1D677𝙷\ttHMathematical Monospace Capital H
    U+1D678𝙸\ttIMathematical Monospace Capital I
    U+1D679𝙹\ttJMathematical Monospace Capital J
    U+1D67A𝙺\ttKMathematical Monospace Capital K
    U+1D67B𝙻\ttLMathematical Monospace Capital L
    U+1D67C𝙼\ttMMathematical Monospace Capital M
    U+1D67D𝙽\ttNMathematical Monospace Capital N
    U+1D67E𝙾\ttOMathematical Monospace Capital O
    U+1D67F𝙿\ttPMathematical Monospace Capital P
    U+1D680𝚀\ttQMathematical Monospace Capital Q
    U+1D681𝚁\ttRMathematical Monospace Capital R
    U+1D682𝚂\ttSMathematical Monospace Capital S
    U+1D683𝚃\ttTMathematical Monospace Capital T
    U+1D684𝚄\ttUMathematical Monospace Capital U
    U+1D685𝚅\ttVMathematical Monospace Capital V
    U+1D686𝚆\ttWMathematical Monospace Capital W
    U+1D687𝚇\ttXMathematical Monospace Capital X
    U+1D688𝚈\ttYMathematical Monospace Capital Y
    U+1D689𝚉\ttZMathematical Monospace Capital Z
    U+1D68A𝚊\ttaMathematical Monospace Small A
    U+1D68B𝚋\ttbMathematical Monospace Small B
    U+1D68C𝚌\ttcMathematical Monospace Small C
    U+1D68D𝚍\ttdMathematical Monospace Small D
    U+1D68E𝚎\tteMathematical Monospace Small E
    U+1D68F𝚏\ttfMathematical Monospace Small F
    U+1D690𝚐\ttgMathematical Monospace Small G
    U+1D691𝚑\tthMathematical Monospace Small H
    U+1D692𝚒\ttiMathematical Monospace Small I
    U+1D693𝚓\ttjMathematical Monospace Small J
    U+1D694𝚔\ttkMathematical Monospace Small K
    U+1D695𝚕\ttlMathematical Monospace Small L
    U+1D696𝚖\ttmMathematical Monospace Small M
    U+1D697𝚗\ttnMathematical Monospace Small N
    U+1D698𝚘\ttoMathematical Monospace Small O
    U+1D699𝚙\ttpMathematical Monospace Small P
    U+1D69A𝚚\ttqMathematical Monospace Small Q
    U+1D69B𝚛\ttrMathematical Monospace Small R
    U+1D69C𝚜\ttsMathematical Monospace Small S
    U+1D69D𝚝\tttMathematical Monospace Small T
    U+1D69E𝚞\ttuMathematical Monospace Small U
    U+1D69F𝚟\ttvMathematical Monospace Small V
    U+1D6A0𝚠\ttwMathematical Monospace Small W
    U+1D6A1𝚡\ttxMathematical Monospace Small X
    U+1D6A2𝚢\ttyMathematical Monospace Small Y
    U+1D6A3𝚣\ttzMathematical Monospace Small Z
    U+1D6A4𝚤\itimathMathematical Italic Small Dotless I
    U+1D6A5𝚥\itjmathMathematical Italic Small Dotless J
    U+1D6A8𝚨\bfAlphaMathematical Bold Capital Alpha
    U+1D6A9𝚩\bfBetaMathematical Bold Capital Beta
    U+1D6AA𝚪\bfGammaMathematical Bold Capital Gamma
    U+1D6AB𝚫\bfDeltaMathematical Bold Capital Delta
    U+1D6AC𝚬\bfEpsilonMathematical Bold Capital Epsilon
    U+1D6AD𝚭\bfZetaMathematical Bold Capital Zeta
    U+1D6AE𝚮\bfEtaMathematical Bold Capital Eta
    U+1D6AF𝚯\bfThetaMathematical Bold Capital Theta
    U+1D6B0𝚰\bfIotaMathematical Bold Capital Iota
    U+1D6B1𝚱\bfKappaMathematical Bold Capital Kappa
    U+1D6B2𝚲\bfLambdaMathematical Bold Capital Lamda
    U+1D6B3𝚳\bfMuMathematical Bold Capital Mu
    U+1D6B4𝚴\bfNuMathematical Bold Capital Nu
    U+1D6B5𝚵\bfXiMathematical Bold Capital Xi
    U+1D6B6𝚶\bfOmicronMathematical Bold Capital Omicron
    U+1D6B7𝚷\bfPiMathematical Bold Capital Pi
    U+1D6B8𝚸\bfRhoMathematical Bold Capital Rho
    U+1D6B9𝚹\bfvarThetaMathematical Bold Capital Theta Symbol
    U+1D6BA𝚺\bfSigmaMathematical Bold Capital Sigma
    U+1D6BB𝚻\bfTauMathematical Bold Capital Tau
    U+1D6BC𝚼\bfUpsilonMathematical Bold Capital Upsilon
    U+1D6BD𝚽\bfPhiMathematical Bold Capital Phi
    U+1D6BE𝚾\bfChiMathematical Bold Capital Chi
    U+1D6BF𝚿\bfPsiMathematical Bold Capital Psi
    U+1D6C0𝛀\bfOmegaMathematical Bold Capital Omega
    U+1D6C1𝛁\bfnablaMathematical Bold Nabla
    U+1D6C2𝛂\bfalphaMathematical Bold Small Alpha
    U+1D6C3𝛃\bfbetaMathematical Bold Small Beta
    U+1D6C4𝛄\bfgammaMathematical Bold Small Gamma
    U+1D6C5𝛅\bfdeltaMathematical Bold Small Delta
    U+1D6C6𝛆\bfvarepsilonMathematical Bold Small Epsilon
    U+1D6C7𝛇\bfzetaMathematical Bold Small Zeta
    U+1D6C8𝛈\bfetaMathematical Bold Small Eta
    U+1D6C9𝛉\bfthetaMathematical Bold Small Theta
    U+1D6CA𝛊\bfiotaMathematical Bold Small Iota
    U+1D6CB𝛋\bfkappaMathematical Bold Small Kappa
    U+1D6CC𝛌\bflambdaMathematical Bold Small Lamda
    U+1D6CD𝛍\bfmuMathematical Bold Small Mu
    U+1D6CE𝛎\bfnuMathematical Bold Small Nu
    U+1D6CF𝛏\bfxiMathematical Bold Small Xi
    U+1D6D0𝛐\bfomicronMathematical Bold Small Omicron
    U+1D6D1𝛑\bfpiMathematical Bold Small Pi
    U+1D6D2𝛒\bfrhoMathematical Bold Small Rho
    U+1D6D3𝛓\bfvarsigmaMathematical Bold Small Final Sigma
    U+1D6D4𝛔\bfsigmaMathematical Bold Small Sigma
    U+1D6D5𝛕\bftauMathematical Bold Small Tau
    U+1D6D6𝛖\bfupsilonMathematical Bold Small Upsilon
    U+1D6D7𝛗\bfvarphiMathematical Bold Small Phi
    U+1D6D8𝛘\bfchiMathematical Bold Small Chi
    U+1D6D9𝛙\bfpsiMathematical Bold Small Psi
    U+1D6DA𝛚\bfomegaMathematical Bold Small Omega
    U+1D6DB𝛛\bfpartialMathematical Bold Partial Differential
    U+1D6DC𝛜\bfepsilonMathematical Bold Epsilon Symbol
    U+1D6DD𝛝\bfvarthetaMathematical Bold Theta Symbol
    U+1D6DE𝛞\bfvarkappaMathematical Bold Kappa Symbol
    U+1D6DF𝛟\bfphiMathematical Bold Phi Symbol
    U+1D6E0𝛠\bfvarrhoMathematical Bold Rho Symbol
    U+1D6E1𝛡\bfvarpiMathematical Bold Pi Symbol
    U+1D6E2𝛢\itAlphaMathematical Italic Capital Alpha
    U+1D6E3𝛣\itBetaMathematical Italic Capital Beta
    U+1D6E4𝛤\itGammaMathematical Italic Capital Gamma
    U+1D6E5𝛥\itDeltaMathematical Italic Capital Delta
    U+1D6E6𝛦\itEpsilonMathematical Italic Capital Epsilon
    U+1D6E7𝛧\itZetaMathematical Italic Capital Zeta
    U+1D6E8𝛨\itEtaMathematical Italic Capital Eta
    U+1D6E9𝛩\itThetaMathematical Italic Capital Theta
    U+1D6EA𝛪\itIotaMathematical Italic Capital Iota
    U+1D6EB𝛫\itKappaMathematical Italic Capital Kappa
    U+1D6EC𝛬\itLambdaMathematical Italic Capital Lamda
    U+1D6ED𝛭\itMuMathematical Italic Capital Mu
    U+1D6EE𝛮\itNuMathematical Italic Capital Nu
    U+1D6EF𝛯\itXiMathematical Italic Capital Xi
    U+1D6F0𝛰\itOmicronMathematical Italic Capital Omicron
    U+1D6F1𝛱\itPiMathematical Italic Capital Pi
    U+1D6F2𝛲\itRhoMathematical Italic Capital Rho
    U+1D6F3𝛳\itvarThetaMathematical Italic Capital Theta Symbol
    U+1D6F4𝛴\itSigmaMathematical Italic Capital Sigma
    U+1D6F5𝛵\itTauMathematical Italic Capital Tau
    U+1D6F6𝛶\itUpsilonMathematical Italic Capital Upsilon
    U+1D6F7𝛷\itPhiMathematical Italic Capital Phi
    U+1D6F8𝛸\itChiMathematical Italic Capital Chi
    U+1D6F9𝛹\itPsiMathematical Italic Capital Psi
    U+1D6FA𝛺\itOmegaMathematical Italic Capital Omega
    U+1D6FB𝛻\itnablaMathematical Italic Nabla
    U+1D6FC𝛼\italphaMathematical Italic Small Alpha
    U+1D6FD𝛽\itbetaMathematical Italic Small Beta
    U+1D6FE𝛾\itgammaMathematical Italic Small Gamma
    U+1D6FF𝛿\itdeltaMathematical Italic Small Delta
    U+1D700𝜀\itvarepsilonMathematical Italic Small Epsilon
    U+1D701𝜁\itzetaMathematical Italic Small Zeta
    U+1D702𝜂\itetaMathematical Italic Small Eta
    U+1D703𝜃\itthetaMathematical Italic Small Theta
    U+1D704𝜄\itiotaMathematical Italic Small Iota
    U+1D705𝜅\itkappaMathematical Italic Small Kappa
    U+1D706𝜆\itlambdaMathematical Italic Small Lamda
    U+1D707𝜇\itmuMathematical Italic Small Mu
    U+1D708𝜈\itnuMathematical Italic Small Nu
    U+1D709𝜉\itxiMathematical Italic Small Xi
    U+1D70A𝜊\itomicronMathematical Italic Small Omicron
    U+1D70B𝜋\itpiMathematical Italic Small Pi
    U+1D70C𝜌\itrhoMathematical Italic Small Rho
    U+1D70D𝜍\itvarsigmaMathematical Italic Small Final Sigma
    U+1D70E𝜎\itsigmaMathematical Italic Small Sigma
    U+1D70F𝜏\ittauMathematical Italic Small Tau
    U+1D710𝜐\itupsilonMathematical Italic Small Upsilon
    U+1D711𝜑\itvarphiMathematical Italic Small Phi
    U+1D712𝜒\itchiMathematical Italic Small Chi
    U+1D713𝜓\itpsiMathematical Italic Small Psi
    U+1D714𝜔\itomegaMathematical Italic Small Omega
    U+1D715𝜕\itpartialMathematical Italic Partial Differential
    U+1D716𝜖\itepsilonMathematical Italic Epsilon Symbol
    U+1D717𝜗\itvarthetaMathematical Italic Theta Symbol
    U+1D718𝜘\itvarkappaMathematical Italic Kappa Symbol
    U+1D719𝜙\itphiMathematical Italic Phi Symbol
    U+1D71A𝜚\itvarrhoMathematical Italic Rho Symbol
    U+1D71B𝜛\itvarpiMathematical Italic Pi Symbol
    U+1D71C𝜜\biAlphaMathematical Bold Italic Capital Alpha
    U+1D71D𝜝\biBetaMathematical Bold Italic Capital Beta
    U+1D71E𝜞\biGammaMathematical Bold Italic Capital Gamma
    U+1D71F𝜟\biDeltaMathematical Bold Italic Capital Delta
    U+1D720𝜠\biEpsilonMathematical Bold Italic Capital Epsilon
    U+1D721𝜡\biZetaMathematical Bold Italic Capital Zeta
    U+1D722𝜢\biEtaMathematical Bold Italic Capital Eta
    U+1D723𝜣\biThetaMathematical Bold Italic Capital Theta
    U+1D724𝜤\biIotaMathematical Bold Italic Capital Iota
    U+1D725𝜥\biKappaMathematical Bold Italic Capital Kappa
    U+1D726𝜦\biLambdaMathematical Bold Italic Capital Lamda
    U+1D727𝜧\biMuMathematical Bold Italic Capital Mu
    U+1D728𝜨\biNuMathematical Bold Italic Capital Nu
    U+1D729𝜩\biXiMathematical Bold Italic Capital Xi
    U+1D72A𝜪\biOmicronMathematical Bold Italic Capital Omicron
    U+1D72B𝜫\biPiMathematical Bold Italic Capital Pi
    U+1D72C𝜬\biRhoMathematical Bold Italic Capital Rho
    U+1D72D𝜭\bivarThetaMathematical Bold Italic Capital Theta Symbol
    U+1D72E𝜮\biSigmaMathematical Bold Italic Capital Sigma
    U+1D72F𝜯\biTauMathematical Bold Italic Capital Tau
    U+1D730𝜰\biUpsilonMathematical Bold Italic Capital Upsilon
    U+1D731𝜱\biPhiMathematical Bold Italic Capital Phi
    U+1D732𝜲\biChiMathematical Bold Italic Capital Chi
    U+1D733𝜳\biPsiMathematical Bold Italic Capital Psi
    U+1D734𝜴\biOmegaMathematical Bold Italic Capital Omega
    U+1D735𝜵\binablaMathematical Bold Italic Nabla
    U+1D736𝜶\bialphaMathematical Bold Italic Small Alpha
    U+1D737𝜷\bibetaMathematical Bold Italic Small Beta
    U+1D738𝜸\bigammaMathematical Bold Italic Small Gamma
    U+1D739𝜹\bideltaMathematical Bold Italic Small Delta
    U+1D73A𝜺\bivarepsilonMathematical Bold Italic Small Epsilon
    U+1D73B𝜻\bizetaMathematical Bold Italic Small Zeta
    U+1D73C𝜼\bietaMathematical Bold Italic Small Eta
    U+1D73D𝜽\bithetaMathematical Bold Italic Small Theta
    U+1D73E𝜾\biiotaMathematical Bold Italic Small Iota
    U+1D73F𝜿\bikappaMathematical Bold Italic Small Kappa
    U+1D740𝝀\bilambdaMathematical Bold Italic Small Lamda
    U+1D741𝝁\bimuMathematical Bold Italic Small Mu
    U+1D742𝝂\binuMathematical Bold Italic Small Nu
    U+1D743𝝃\bixiMathematical Bold Italic Small Xi
    U+1D744𝝄\biomicronMathematical Bold Italic Small Omicron
    U+1D745𝝅\bipiMathematical Bold Italic Small Pi
    U+1D746𝝆\birhoMathematical Bold Italic Small Rho
    U+1D747𝝇\bivarsigmaMathematical Bold Italic Small Final Sigma
    U+1D748𝝈\bisigmaMathematical Bold Italic Small Sigma
    U+1D749𝝉\bitauMathematical Bold Italic Small Tau
    U+1D74A𝝊\biupsilonMathematical Bold Italic Small Upsilon
    U+1D74B𝝋\bivarphiMathematical Bold Italic Small Phi
    U+1D74C𝝌\bichiMathematical Bold Italic Small Chi
    U+1D74D𝝍\bipsiMathematical Bold Italic Small Psi
    U+1D74E𝝎\biomegaMathematical Bold Italic Small Omega
    U+1D74F𝝏\bipartialMathematical Bold Italic Partial Differential
    U+1D750𝝐\biepsilonMathematical Bold Italic Epsilon Symbol
    U+1D751𝝑\bivarthetaMathematical Bold Italic Theta Symbol
    U+1D752𝝒\bivarkappaMathematical Bold Italic Kappa Symbol
    U+1D753𝝓\biphiMathematical Bold Italic Phi Symbol
    U+1D754𝝔\bivarrhoMathematical Bold Italic Rho Symbol
    U+1D755𝝕\bivarpiMathematical Bold Italic Pi Symbol
    U+1D756𝝖\bsansAlphaMathematical Sans-Serif Bold Capital Alpha
    U+1D757𝝗\bsansBetaMathematical Sans-Serif Bold Capital Beta
    U+1D758𝝘\bsansGammaMathematical Sans-Serif Bold Capital Gamma
    U+1D759𝝙\bsansDeltaMathematical Sans-Serif Bold Capital Delta
    U+1D75A𝝚\bsansEpsilonMathematical Sans-Serif Bold Capital Epsilon
    U+1D75B𝝛\bsansZetaMathematical Sans-Serif Bold Capital Zeta
    U+1D75C𝝜\bsansEtaMathematical Sans-Serif Bold Capital Eta
    U+1D75D𝝝\bsansThetaMathematical Sans-Serif Bold Capital Theta
    U+1D75E𝝞\bsansIotaMathematical Sans-Serif Bold Capital Iota
    U+1D75F𝝟\bsansKappaMathematical Sans-Serif Bold Capital Kappa
    U+1D760𝝠\bsansLambdaMathematical Sans-Serif Bold Capital Lamda
    U+1D761𝝡\bsansMuMathematical Sans-Serif Bold Capital Mu
    U+1D762𝝢\bsansNuMathematical Sans-Serif Bold Capital Nu
    U+1D763𝝣\bsansXiMathematical Sans-Serif Bold Capital Xi
    U+1D764𝝤\bsansOmicronMathematical Sans-Serif Bold Capital Omicron
    U+1D765𝝥\bsansPiMathematical Sans-Serif Bold Capital Pi
    U+1D766𝝦\bsansRhoMathematical Sans-Serif Bold Capital Rho
    U+1D767𝝧\bsansvarThetaMathematical Sans-Serif Bold Capital Theta Symbol
    U+1D768𝝨\bsansSigmaMathematical Sans-Serif Bold Capital Sigma
    U+1D769𝝩\bsansTauMathematical Sans-Serif Bold Capital Tau
    U+1D76A𝝪\bsansUpsilonMathematical Sans-Serif Bold Capital Upsilon
    U+1D76B𝝫\bsansPhiMathematical Sans-Serif Bold Capital Phi
    U+1D76C𝝬\bsansChiMathematical Sans-Serif Bold Capital Chi
    U+1D76D𝝭\bsansPsiMathematical Sans-Serif Bold Capital Psi
    U+1D76E𝝮\bsansOmegaMathematical Sans-Serif Bold Capital Omega
    U+1D76F𝝯\bsansnablaMathematical Sans-Serif Bold Nabla
    U+1D770𝝰\bsansalphaMathematical Sans-Serif Bold Small Alpha
    U+1D771𝝱\bsansbetaMathematical Sans-Serif Bold Small Beta
    U+1D772𝝲\bsansgammaMathematical Sans-Serif Bold Small Gamma
    U+1D773𝝳\bsansdeltaMathematical Sans-Serif Bold Small Delta
    U+1D774𝝴\bsansvarepsilonMathematical Sans-Serif Bold Small Epsilon
    U+1D775𝝵\bsanszetaMathematical Sans-Serif Bold Small Zeta
    U+1D776𝝶\bsansetaMathematical Sans-Serif Bold Small Eta
    U+1D777𝝷\bsansthetaMathematical Sans-Serif Bold Small Theta
    U+1D778𝝸\bsansiotaMathematical Sans-Serif Bold Small Iota
    U+1D779𝝹\bsanskappaMathematical Sans-Serif Bold Small Kappa
    U+1D77A𝝺\bsanslambdaMathematical Sans-Serif Bold Small Lamda
    U+1D77B𝝻\bsansmuMathematical Sans-Serif Bold Small Mu
    U+1D77C𝝼\bsansnuMathematical Sans-Serif Bold Small Nu
    U+1D77D𝝽\bsansxiMathematical Sans-Serif Bold Small Xi
    U+1D77E𝝾\bsansomicronMathematical Sans-Serif Bold Small Omicron
    U+1D77F𝝿\bsanspiMathematical Sans-Serif Bold Small Pi
    U+1D780𝞀\bsansrhoMathematical Sans-Serif Bold Small Rho
    U+1D781𝞁\bsansvarsigmaMathematical Sans-Serif Bold Small Final Sigma
    U+1D782𝞂\bsanssigmaMathematical Sans-Serif Bold Small Sigma
    U+1D783𝞃\bsanstauMathematical Sans-Serif Bold Small Tau
    U+1D784𝞄\bsansupsilonMathematical Sans-Serif Bold Small Upsilon
    U+1D785𝞅\bsansvarphiMathematical Sans-Serif Bold Small Phi
    U+1D786𝞆\bsanschiMathematical Sans-Serif Bold Small Chi
    U+1D787𝞇\bsanspsiMathematical Sans-Serif Bold Small Psi
    U+1D788𝞈\bsansomegaMathematical Sans-Serif Bold Small Omega
    U+1D789𝞉\bsanspartialMathematical Sans-Serif Bold Partial Differential
    U+1D78A𝞊\bsansepsilonMathematical Sans-Serif Bold Epsilon Symbol
    U+1D78B𝞋\bsansvarthetaMathematical Sans-Serif Bold Theta Symbol
    U+1D78C𝞌\bsansvarkappaMathematical Sans-Serif Bold Kappa Symbol
    U+1D78D𝞍\bsansphiMathematical Sans-Serif Bold Phi Symbol
    U+1D78E𝞎\bsansvarrhoMathematical Sans-Serif Bold Rho Symbol
    U+1D78F𝞏\bsansvarpiMathematical Sans-Serif Bold Pi Symbol
    U+1D790𝞐\bisansAlphaMathematical Sans-Serif Bold Italic Capital Alpha
    U+1D791𝞑\bisansBetaMathematical Sans-Serif Bold Italic Capital Beta
    U+1D792𝞒\bisansGammaMathematical Sans-Serif Bold Italic Capital Gamma
    U+1D793𝞓\bisansDeltaMathematical Sans-Serif Bold Italic Capital Delta
    U+1D794𝞔\bisansEpsilonMathematical Sans-Serif Bold Italic Capital Epsilon
    U+1D795𝞕\bisansZetaMathematical Sans-Serif Bold Italic Capital Zeta
    U+1D796𝞖\bisansEtaMathematical Sans-Serif Bold Italic Capital Eta
    U+1D797𝞗\bisansThetaMathematical Sans-Serif Bold Italic Capital Theta
    U+1D798𝞘\bisansIotaMathematical Sans-Serif Bold Italic Capital Iota
    U+1D799𝞙\bisansKappaMathematical Sans-Serif Bold Italic Capital Kappa
    U+1D79A𝞚\bisansLambdaMathematical Sans-Serif Bold Italic Capital Lamda
    U+1D79B𝞛\bisansMuMathematical Sans-Serif Bold Italic Capital Mu
    U+1D79C𝞜\bisansNuMathematical Sans-Serif Bold Italic Capital Nu
    U+1D79D𝞝\bisansXiMathematical Sans-Serif Bold Italic Capital Xi
    U+1D79E𝞞\bisansOmicronMathematical Sans-Serif Bold Italic Capital Omicron
    U+1D79F𝞟\bisansPiMathematical Sans-Serif Bold Italic Capital Pi
    U+1D7A0𝞠\bisansRhoMathematical Sans-Serif Bold Italic Capital Rho
    U+1D7A1𝞡\bisansvarThetaMathematical Sans-Serif Bold Italic Capital Theta Symbol
    U+1D7A2𝞢\bisansSigmaMathematical Sans-Serif Bold Italic Capital Sigma
    U+1D7A3𝞣\bisansTauMathematical Sans-Serif Bold Italic Capital Tau
    U+1D7A4𝞤\bisansUpsilonMathematical Sans-Serif Bold Italic Capital Upsilon
    U+1D7A5𝞥\bisansPhiMathematical Sans-Serif Bold Italic Capital Phi
    U+1D7A6𝞦\bisansChiMathematical Sans-Serif Bold Italic Capital Chi
    U+1D7A7𝞧\bisansPsiMathematical Sans-Serif Bold Italic Capital Psi
    U+1D7A8𝞨\bisansOmegaMathematical Sans-Serif Bold Italic Capital Omega
    U+1D7A9𝞩\bisansnablaMathematical Sans-Serif Bold Italic Nabla
    U+1D7AA𝞪\bisansalphaMathematical Sans-Serif Bold Italic Small Alpha
    U+1D7AB𝞫\bisansbetaMathematical Sans-Serif Bold Italic Small Beta
    U+1D7AC𝞬\bisansgammaMathematical Sans-Serif Bold Italic Small Gamma
    U+1D7AD𝞭\bisansdeltaMathematical Sans-Serif Bold Italic Small Delta
    U+1D7AE𝞮\bisansvarepsilonMathematical Sans-Serif Bold Italic Small Epsilon
    U+1D7AF𝞯\bisanszetaMathematical Sans-Serif Bold Italic Small Zeta
    U+1D7B0𝞰\bisansetaMathematical Sans-Serif Bold Italic Small Eta
    U+1D7B1𝞱\bisansthetaMathematical Sans-Serif Bold Italic Small Theta
    U+1D7B2𝞲\bisansiotaMathematical Sans-Serif Bold Italic Small Iota
    U+1D7B3𝞳\bisanskappaMathematical Sans-Serif Bold Italic Small Kappa
    U+1D7B4𝞴\bisanslambdaMathematical Sans-Serif Bold Italic Small Lamda
    U+1D7B5𝞵\bisansmuMathematical Sans-Serif Bold Italic Small Mu
    U+1D7B6𝞶\bisansnuMathematical Sans-Serif Bold Italic Small Nu
    U+1D7B7𝞷\bisansxiMathematical Sans-Serif Bold Italic Small Xi
    U+1D7B8𝞸\bisansomicronMathematical Sans-Serif Bold Italic Small Omicron
    U+1D7B9𝞹\bisanspiMathematical Sans-Serif Bold Italic Small Pi
    U+1D7BA𝞺\bisansrhoMathematical Sans-Serif Bold Italic Small Rho
    U+1D7BB𝞻\bisansvarsigmaMathematical Sans-Serif Bold Italic Small Final Sigma
    U+1D7BC𝞼\bisanssigmaMathematical Sans-Serif Bold Italic Small Sigma
    U+1D7BD𝞽\bisanstauMathematical Sans-Serif Bold Italic Small Tau
    U+1D7BE𝞾\bisansupsilonMathematical Sans-Serif Bold Italic Small Upsilon
    U+1D7BF𝞿\bisansvarphiMathematical Sans-Serif Bold Italic Small Phi
    U+1D7C0𝟀\bisanschiMathematical Sans-Serif Bold Italic Small Chi
    U+1D7C1𝟁\bisanspsiMathematical Sans-Serif Bold Italic Small Psi
    U+1D7C2𝟂\bisansomegaMathematical Sans-Serif Bold Italic Small Omega
    U+1D7C3𝟃\bisanspartialMathematical Sans-Serif Bold Italic Partial Differential
    U+1D7C4𝟄\bisansepsilonMathematical Sans-Serif Bold Italic Epsilon Symbol
    U+1D7C5𝟅\bisansvarthetaMathematical Sans-Serif Bold Italic Theta Symbol
    U+1D7C6𝟆\bisansvarkappaMathematical Sans-Serif Bold Italic Kappa Symbol
    U+1D7C7𝟇\bisansphiMathematical Sans-Serif Bold Italic Phi Symbol
    U+1D7C8𝟈\bisansvarrhoMathematical Sans-Serif Bold Italic Rho Symbol
    U+1D7C9𝟉\bisansvarpiMathematical Sans-Serif Bold Italic Pi Symbol
    U+1D7CA𝟊\bfDigammaMathematical Bold Capital Digamma
    U+1D7CB𝟋\bfdigammaMathematical Bold Small Digamma
    U+1D7CE𝟎\bfzeroMathematical Bold Digit Zero
    U+1D7CF𝟏\bfoneMathematical Bold Digit One
    U+1D7D0𝟐\bftwoMathematical Bold Digit Two
    U+1D7D1𝟑\bfthreeMathematical Bold Digit Three
    U+1D7D2𝟒\bffourMathematical Bold Digit Four
    U+1D7D3𝟓\bffiveMathematical Bold Digit Five
    U+1D7D4𝟔\bfsixMathematical Bold Digit Six
    U+1D7D5𝟕\bfsevenMathematical Bold Digit Seven
    U+1D7D6𝟖\bfeightMathematical Bold Digit Eight
    U+1D7D7𝟗\bfnineMathematical Bold Digit Nine
    U+1D7D8𝟘\bbzeroMathematical Double-Struck Digit Zero
    U+1D7D9𝟙\bboneMathematical Double-Struck Digit One
    U+1D7DA𝟚\bbtwoMathematical Double-Struck Digit Two
    U+1D7DB𝟛\bbthreeMathematical Double-Struck Digit Three
    U+1D7DC𝟜\bbfourMathematical Double-Struck Digit Four
    U+1D7DD𝟝\bbfiveMathematical Double-Struck Digit Five
    U+1D7DE𝟞\bbsixMathematical Double-Struck Digit Six
    U+1D7DF𝟟\bbsevenMathematical Double-Struck Digit Seven
    U+1D7E0𝟠\bbeightMathematical Double-Struck Digit Eight
    U+1D7E1𝟡\bbnineMathematical Double-Struck Digit Nine
    U+1D7E2𝟢\sanszeroMathematical Sans-Serif Digit Zero
    U+1D7E3𝟣\sansoneMathematical Sans-Serif Digit One
    U+1D7E4𝟤\sanstwoMathematical Sans-Serif Digit Two
    U+1D7E5𝟥\sansthreeMathematical Sans-Serif Digit Three
    U+1D7E6𝟦\sansfourMathematical Sans-Serif Digit Four
    U+1D7E7𝟧\sansfiveMathematical Sans-Serif Digit Five
    U+1D7E8𝟨\sanssixMathematical Sans-Serif Digit Six
    U+1D7E9𝟩\sanssevenMathematical Sans-Serif Digit Seven
    U+1D7EA𝟪\sanseightMathematical Sans-Serif Digit Eight
    U+1D7EB𝟫\sansnineMathematical Sans-Serif Digit Nine
    U+1D7EC𝟬\bsanszeroMathematical Sans-Serif Bold Digit Zero
    U+1D7ED𝟭\bsansoneMathematical Sans-Serif Bold Digit One
    U+1D7EE𝟮\bsanstwoMathematical Sans-Serif Bold Digit Two
    U+1D7EF𝟯\bsansthreeMathematical Sans-Serif Bold Digit Three
    U+1D7F0𝟰\bsansfourMathematical Sans-Serif Bold Digit Four
    U+1D7F1𝟱\bsansfiveMathematical Sans-Serif Bold Digit Five
    U+1D7F2𝟲\bsanssixMathematical Sans-Serif Bold Digit Six
    U+1D7F3𝟳\bsanssevenMathematical Sans-Serif Bold Digit Seven
    U+1D7F4𝟴\bsanseightMathematical Sans-Serif Bold Digit Eight
    U+1D7F5𝟵\bsansnineMathematical Sans-Serif Bold Digit Nine
    U+1D7F6𝟶\ttzeroMathematical Monospace Digit Zero
    U+1D7F7𝟷\ttoneMathematical Monospace Digit One
    U+1D7F8𝟸\tttwoMathematical Monospace Digit Two
    U+1D7F9𝟹\ttthreeMathematical Monospace Digit Three
    U+1D7FA𝟺\ttfourMathematical Monospace Digit Four
    U+1D7FB𝟻\ttfiveMathematical Monospace Digit Five
    U+1D7FC𝟼\ttsixMathematical Monospace Digit Six
    U+1D7FD𝟽\ttsevenMathematical Monospace Digit Seven
    U+1D7FE𝟾\tteightMathematical Monospace Digit Eight
    U+1D7FF𝟿\ttnineMathematical Monospace Digit Nine
    U+1F004🀄\:mahjong:Mahjong Tile Red Dragon
    U+1F0CF🃏\:black_joker:Playing Card Black Joker
    U+1F170🅰\:a:Negative Squared Latin Capital Letter A
    U+1F171🅱\:b:Negative Squared Latin Capital Letter B
    U+1F17E🅾\:o2:Negative Squared Latin Capital Letter O
    U+1F17F🅿\:parking:Negative Squared Latin Capital Letter P
    U+1F18E🆎\:ab:Negative Squared Ab
    U+1F191🆑\:cl:Squared Cl
    U+1F192🆒\:cool:Squared Cool
    U+1F193🆓\:free:Squared Free
    U+1F194🆔\:id:Squared Id
    U+1F195🆕\:new:Squared New
    U+1F196🆖\:ng:Squared Ng
    U+1F197🆗\:ok:Squared Ok
    U+1F198🆘\:sos:Squared Sos
    U+1F199🆙\:up:Squared Up With Exclamation Mark
    U+1F19A🆚\:vs:Squared Vs
    U+1F201🈁\:koko:Squared Katakana Koko
    U+1F202🈂\:sa:Squared Katakana Sa
    U+1F21A🈚\:u7121:Squared Cjk Unified Ideograph-7121
    U+1F22F🈯\:u6307:Squared Cjk Unified Ideograph-6307
    U+1F232🈲\:u7981:Squared Cjk Unified Ideograph-7981
    U+1F233🈳\:u7a7a:Squared Cjk Unified Ideograph-7A7A
    U+1F234🈴\:u5408:Squared Cjk Unified Ideograph-5408
    U+1F235🈵\:u6e80:Squared Cjk Unified Ideograph-6E80
    U+1F236🈶\:u6709:Squared Cjk Unified Ideograph-6709
    U+1F237🈷\:u6708:Squared Cjk Unified Ideograph-6708
    U+1F238🈸\:u7533:Squared Cjk Unified Ideograph-7533
    U+1F239🈹\:u5272:Squared Cjk Unified Ideograph-5272
    U+1F23A🈺\:u55b6:Squared Cjk Unified Ideograph-55B6
    U+1F250🉐\:ideograph_advantage:Circled Ideograph Advantage
    U+1F251🉑\:accept:Circled Ideograph Accept
    U+1F300🌀\:cyclone:Cyclone
    U+1F301🌁\:foggy:Foggy
    U+1F302🌂\:closed_umbrella:Closed Umbrella
    U+1F303🌃\:night_with_stars:Night With Stars
    U+1F304🌄\:sunrise_over_mountains:Sunrise Over Mountains
    U+1F305🌅\:sunrise:Sunrise
    U+1F306🌆\:city_sunset:Cityscape At Dusk
    U+1F307🌇\:city_sunrise:Sunset Over Buildings
    U+1F308🌈\:rainbow:Rainbow
    U+1F309🌉\:bridge_at_night:Bridge At Night
    U+1F30A🌊\:ocean:Water Wave
    U+1F30B🌋\:volcano:Volcano
    U+1F30C🌌\:milky_way:Milky Way
    U+1F30D🌍\:earth_africa:Earth Globe Europe-Africa
    U+1F30E🌎\:earth_americas:Earth Globe Americas
    U+1F30F🌏\:earth_asia:Earth Globe Asia-Australia
    U+1F310🌐\:globe_with_meridians:Globe With Meridians
    U+1F311🌑\:new_moon:New Moon Symbol
    U+1F312🌒\:waxing_crescent_moon:Waxing Crescent Moon Symbol
    U+1F313🌓\:first_quarter_moon:First Quarter Moon Symbol
    U+1F314🌔\:moon:Waxing Gibbous Moon Symbol
    U+1F315🌕\:full_moon:Full Moon Symbol
    U+1F316🌖\:waning_gibbous_moon:Waning Gibbous Moon Symbol
    U+1F317🌗\:last_quarter_moon:Last Quarter Moon Symbol
    U+1F318🌘\:waning_crescent_moon:Waning Crescent Moon Symbol
    U+1F319🌙\:crescent_moon:Crescent Moon
    U+1F31A🌚\:new_moon_with_face:New Moon With Face
    U+1F31B🌛\:first_quarter_moon_with_face:First Quarter Moon With Face
    U+1F31C🌜\:last_quarter_moon_with_face:Last Quarter Moon With Face
    U+1F31D🌝\:full_moon_with_face:Full Moon With Face
    U+1F31E🌞\:sun_with_face:Sun With Face
    U+1F31F🌟\:star2:Glowing Star
    U+1F320🌠\:stars:Shooting Star
    U+1F32D🌭\:hotdog:Hot Dog
    U+1F32E🌮\:taco:Taco
    U+1F32F🌯\:burrito:Burrito
    U+1F330🌰\:chestnut:Chestnut
    U+1F331🌱\:seedling:Seedling
    U+1F332🌲\:evergreen_tree:Evergreen Tree
    U+1F333🌳\:deciduous_tree:Deciduous Tree
    U+1F334🌴\:palm_tree:Palm Tree
    U+1F335🌵\:cactus:Cactus
    U+1F337🌷\:tulip:Tulip
    U+1F338🌸\:cherry_blossom:Cherry Blossom
    U+1F339🌹\:rose:Rose
    U+1F33A🌺\:hibiscus:Hibiscus
    U+1F33B🌻\:sunflower:Sunflower
    U+1F33C🌼\:blossom:Blossom
    U+1F33D🌽\:corn:Ear Of Maize
    U+1F33E🌾\:ear_of_rice:Ear Of Rice
    U+1F33F🌿\:herb:Herb
    U+1F340🍀\:four_leaf_clover:Four Leaf Clover
    U+1F341🍁\:maple_leaf:Maple Leaf
    U+1F342🍂\:fallen_leaf:Fallen Leaf
    U+1F343🍃\:leaves:Leaf Fluttering In Wind
    U+1F344🍄\:mushroom:Mushroom
    U+1F345🍅\:tomato:Tomato
    U+1F346🍆\:eggplant:Aubergine
    U+1F347🍇\:grapes:Grapes
    U+1F348🍈\:melon:Melon
    U+1F349🍉\:watermelon:Watermelon
    U+1F34A🍊\:tangerine:Tangerine
    U+1F34B🍋\:lemon:Lemon
    U+1F34C🍌\:banana:Banana
    U+1F34D🍍\:pineapple:Pineapple
    U+1F34E🍎\:apple:Red Apple
    U+1F34F🍏\:green_apple:Green Apple
    U+1F350🍐\:pear:Pear
    U+1F351🍑\:peach:Peach
    U+1F352🍒\:cherries:Cherries
    U+1F353🍓\:strawberry:Strawberry
    U+1F354🍔\:hamburger:Hamburger
    U+1F355🍕\:pizza:Slice Of Pizza
    U+1F356🍖\:meat_on_bone:Meat On Bone
    U+1F357🍗\:poultry_leg:Poultry Leg
    U+1F358🍘\:rice_cracker:Rice Cracker
    U+1F359🍙\:rice_ball:Rice Ball
    U+1F35A🍚\:rice:Cooked Rice
    U+1F35B🍛\:curry:Curry And Rice
    U+1F35C🍜\:ramen:Steaming Bowl
    U+1F35D🍝\:spaghetti:Spaghetti
    U+1F35E🍞\:bread:Bread
    U+1F35F🍟\:fries:French Fries
    U+1F360🍠\:sweet_potato:Roasted Sweet Potato
    U+1F361🍡\:dango:Dango
    U+1F362🍢\:oden:Oden
    U+1F363🍣\:sushi:Sushi
    U+1F364🍤\:fried_shrimp:Fried Shrimp
    U+1F365🍥\:fish_cake:Fish Cake With Swirl Design
    U+1F366🍦\:icecream:Soft Ice Cream
    U+1F367🍧\:shaved_ice:Shaved Ice
    U+1F368🍨\:ice_cream:Ice Cream
    U+1F369🍩\:doughnut:Doughnut
    U+1F36A🍪\:cookie:Cookie
    U+1F36B🍫\:chocolate_bar:Chocolate Bar
    U+1F36C🍬\:candy:Candy
    U+1F36D🍭\:lollipop:Lollipop
    U+1F36E🍮\:custard:Custard
    U+1F36F🍯\:honey_pot:Honey Pot
    U+1F370🍰\:cake:Shortcake
    U+1F371🍱\:bento:Bento Box
    U+1F372🍲\:stew:Pot Of Food
    U+1F373🍳\:fried_egg:Cooking
    U+1F374🍴\:fork_and_knife:Fork And Knife
    U+1F375🍵\:tea:Teacup Without Handle
    U+1F376🍶\:sake:Sake Bottle And Cup
    U+1F377🍷\:wine_glass:Wine Glass
    U+1F378🍸\:cocktail:Cocktail Glass
    U+1F379🍹\:tropical_drink:Tropical Drink
    U+1F37A🍺\:beer:Beer Mug
    U+1F37B🍻\:beers:Clinking Beer Mugs
    U+1F37C🍼\:baby_bottle:Baby Bottle
    U+1F37E🍾\:champagne:Bottle With Popping Cork
    U+1F37F🍿\:popcorn:Popcorn
    U+1F380🎀\:ribbon:Ribbon
    U+1F381🎁\:gift:Wrapped Present
    U+1F382🎂\:birthday:Birthday Cake
    U+1F383🎃\:jack_o_lantern:Jack-O-Lantern
    U+1F384🎄\:christmas_tree:Christmas Tree
    U+1F385🎅\:santa:Father Christmas
    U+1F386🎆\:fireworks:Fireworks
    U+1F387🎇\:sparkler:Firework Sparkler
    U+1F388🎈\:balloon:Balloon
    U+1F389🎉\:tada:Party Popper
    U+1F38A🎊\:confetti_ball:Confetti Ball
    U+1F38B🎋\:tanabata_tree:Tanabata Tree
    U+1F38C🎌\:crossed_flags:Crossed Flags
    U+1F38D🎍\:bamboo:Pine Decoration
    U+1F38E🎎\:dolls:Japanese Dolls
    U+1F38F🎏\:flags:Carp Streamer
    U+1F390🎐\:wind_chime:Wind Chime
    U+1F391🎑\:rice_scene:Moon Viewing Ceremony
    U+1F392🎒\:school_satchel:School Satchel
    U+1F393🎓\:mortar_board:Graduation Cap
    U+1F3A0🎠\:carousel_horse:Carousel Horse
    U+1F3A1🎡\:ferris_wheel:Ferris Wheel
    U+1F3A2🎢\:roller_coaster:Roller Coaster
    U+1F3A3🎣\:fishing_pole_and_fish:Fishing Pole And Fish
    U+1F3A4🎤\:microphone:Microphone
    U+1F3A5🎥\:movie_camera:Movie Camera
    U+1F3A6🎦\:cinema:Cinema
    U+1F3A7🎧\:headphones:Headphone
    U+1F3A8🎨\:art:Artist Palette
    U+1F3A9🎩\:tophat:Top Hat
    U+1F3AA🎪\:circus_tent:Circus Tent
    U+1F3AB🎫\:ticket:Ticket
    U+1F3AC🎬\:clapper:Clapper Board
    U+1F3AD🎭\:performing_arts:Performing Arts
    U+1F3AE🎮\:video_game:Video Game
    U+1F3AF🎯\:dart:Direct Hit
    U+1F3B0🎰\:slot_machine:Slot Machine
    U+1F3B1🎱\:8ball:Billiards
    U+1F3B2🎲\:game_die:Game Die
    U+1F3B3🎳\:bowling:Bowling
    U+1F3B4🎴\:flower_playing_cards:Flower Playing Cards
    U+1F3B5🎵\:musical_note:Musical Note
    U+1F3B6🎶\:notes:Multiple Musical Notes
    U+1F3B7🎷\:saxophone:Saxophone
    U+1F3B8🎸\:guitar:Guitar
    U+1F3B9🎹\:musical_keyboard:Musical Keyboard
    U+1F3BA🎺\:trumpet:Trumpet
    U+1F3BB🎻\:violin:Violin
    U+1F3BC🎼\:musical_score:Musical Score
    U+1F3BD🎽\:running_shirt_with_sash:Running Shirt With Sash
    U+1F3BE🎾\:tennis:Tennis Racquet And Ball
    U+1F3BF🎿\:ski:Ski And Ski Boot
    U+1F3C0🏀\:basketball:Basketball And Hoop
    U+1F3C1🏁\:checkered_flag:Chequered Flag
    U+1F3C2🏂\:snowboarder:Snowboarder
    U+1F3C3🏃\:runner:Runner
    U+1F3C4🏄\:surfer:Surfer
    U+1F3C5🏅\:sports_medal:Sports Medal
    U+1F3C6🏆\:trophy:Trophy
    U+1F3C7🏇\:horse_racing:Horse Racing
    U+1F3C8🏈\:football:American Football
    U+1F3C9🏉\:rugby_football:Rugby Football
    U+1F3CA🏊\:swimmer:Swimmer
    U+1F3CF🏏\:cricket_bat_and_ball:Cricket Bat And Ball
    U+1F3D0🏐\:volleyball:Volleyball
    U+1F3D1🏑\:field_hockey_stick_and_ball:Field Hockey Stick And Ball
    U+1F3D2🏒\:ice_hockey_stick_and_puck:Ice Hockey Stick And Puck
    U+1F3D3🏓\:table_tennis_paddle_and_ball:Table Tennis Paddle And Ball
    U+1F3E0🏠\:house:House Building
    U+1F3E1🏡\:house_with_garden:House With Garden
    U+1F3E2🏢\:office:Office Building
    U+1F3E3🏣\:post_office:Japanese Post Office
    U+1F3E4🏤\:european_post_office:European Post Office
    U+1F3E5🏥\:hospital:Hospital
    U+1F3E6🏦\:bank:Bank
    U+1F3E7🏧\:atm:Automated Teller Machine
    U+1F3E8🏨\:hotel:Hotel
    U+1F3E9🏩\:love_hotel:Love Hotel
    U+1F3EA🏪\:convenience_store:Convenience Store
    U+1F3EB🏫\:school:School
    U+1F3EC🏬\:department_store:Department Store
    U+1F3ED🏭\:factory:Factory
    U+1F3EE🏮\:izakaya_lantern:Izakaya Lantern
    U+1F3EF🏯\:japanese_castle:Japanese Castle
    U+1F3F0🏰\:european_castle:European Castle
    U+1F3F4🏴\:waving_black_flag:Waving Black Flag
    U+1F3F8🏸\:badminton_racquet_and_shuttlecock:Badminton Racquet And Shuttlecock
    U+1F3F9🏹\:bow_and_arrow:Bow And Arrow
    U+1F3FA🏺\:amphora:Amphora
    U+1F3FB🏻\:skin-tone-2:Emoji Modifier Fitzpatrick Type-1-2
    U+1F3FC🏼\:skin-tone-3:Emoji Modifier Fitzpatrick Type-3
    U+1F3FD🏽\:skin-tone-4:Emoji Modifier Fitzpatrick Type-4
    U+1F3FE🏾\:skin-tone-5:Emoji Modifier Fitzpatrick Type-5
    U+1F3FF🏿\:skin-tone-6:Emoji Modifier Fitzpatrick Type-6
    U+1F400🐀\:rat:Rat
    U+1F401🐁\:mouse2:Mouse
    U+1F402🐂\:ox:Ox
    U+1F403🐃\:water_buffalo:Water Buffalo
    U+1F404🐄\:cow2:Cow
    U+1F405🐅\:tiger2:Tiger
    U+1F406🐆\:leopard:Leopard
    U+1F407🐇\:rabbit2:Rabbit
    U+1F408🐈\:cat2:Cat
    U+1F409🐉\:dragon:Dragon
    U+1F40A🐊\:crocodile:Crocodile
    U+1F40B🐋\:whale2:Whale
    U+1F40C🐌\:snail:Snail
    U+1F40D🐍\:snake:Snake
    U+1F40E🐎\:racehorse:Horse
    U+1F40F🐏\:ram:Ram
    U+1F410🐐\:goat:Goat
    U+1F411🐑\:sheep:Sheep
    U+1F412🐒\:monkey:Monkey
    U+1F413🐓\:rooster:Rooster
    U+1F414🐔\:chicken:Chicken
    U+1F415🐕\:dog2:Dog
    U+1F416🐖\:pig2:Pig
    U+1F417🐗\:boar:Boar
    U+1F418🐘\:elephant:Elephant
    U+1F419🐙\:octopus:Octopus
    U+1F41A🐚\:shell:Spiral Shell
    U+1F41B🐛\:bug:Bug
    U+1F41C🐜\:ant:Ant
    U+1F41D🐝\:bee:Honeybee
    U+1F41E🐞\:ladybug:Lady Beetle
    U+1F41F🐟\:fish:Fish
    U+1F420🐠\:tropical_fish:Tropical Fish
    U+1F421🐡\:blowfish:Blowfish
    U+1F422🐢\:turtle:Turtle
    U+1F423🐣\:hatching_chick:Hatching Chick
    U+1F424🐤\:baby_chick:Baby Chick
    U+1F425🐥\:hatched_chick:Front-Facing Baby Chick
    U+1F426🐦\:bird:Bird
    U+1F427🐧\:penguin:Penguin
    U+1F428🐨\:koala:Koala
    U+1F429🐩\:poodle:Poodle
    U+1F42A🐪\:dromedary_camel:Dromedary Camel
    U+1F42B🐫\:camel:Bactrian Camel
    U+1F42C🐬\:dolphin:Dolphin
    U+1F42D🐭\:mouse:Mouse Face
    U+1F42E🐮\:cow:Cow Face
    U+1F42F🐯\:tiger:Tiger Face
    U+1F430🐰\:rabbit:Rabbit Face
    U+1F431🐱\:cat:Cat Face
    U+1F432🐲\:dragon_face:Dragon Face
    U+1F433🐳\:whale:Spouting Whale
    U+1F434🐴\:horse:Horse Face
    U+1F435🐵\:monkey_face:Monkey Face
    U+1F436🐶\:dog:Dog Face
    U+1F437🐷\:pig:Pig Face
    U+1F438🐸\:frog:Frog Face
    U+1F439🐹\:hamster:Hamster Face
    U+1F43A🐺\:wolf:Wolf Face
    U+1F43B🐻\:bear:Bear Face
    U+1F43C🐼\:panda_face:Panda Face
    U+1F43D🐽\:pig_nose:Pig Nose
    U+1F43E🐾\:feet:Paw Prints
    U+1F440👀\:eyes:Eyes
    U+1F442👂\:ear:Ear
    U+1F443👃\:nose:Nose
    U+1F444👄\:lips:Mouth
    U+1F445👅\:tongue:Tongue
    U+1F446👆\:point_up_2:White Up Pointing Backhand Index
    U+1F447👇\:point_down:White Down Pointing Backhand Index
    U+1F448👈\:point_left:White Left Pointing Backhand Index
    U+1F449👉\:point_right:White Right Pointing Backhand Index
    U+1F44A👊\:facepunch:Fisted Hand Sign
    U+1F44B👋\:wave:Waving Hand Sign
    U+1F44C👌\:ok_hand:Ok Hand Sign
    U+1F44D👍\:+1:Thumbs Up Sign
    U+1F44E👎\:-1:Thumbs Down Sign
    U+1F44F👏\:clap:Clapping Hands Sign
    U+1F450👐\:open_hands:Open Hands Sign
    U+1F451👑\:crown:Crown
    U+1F452👒\:womans_hat:Womans Hat
    U+1F453👓\:eyeglasses:Eyeglasses
    U+1F454👔\:necktie:Necktie
    U+1F455👕\:shirt:T-Shirt
    U+1F456👖\:jeans:Jeans
    U+1F457👗\:dress:Dress
    U+1F458👘\:kimono:Kimono
    U+1F459👙\:bikini:Bikini
    U+1F45A👚\:womans_clothes:Womans Clothes
    U+1F45B👛\:purse:Purse
    U+1F45C👜\:handbag:Handbag
    U+1F45D👝\:pouch:Pouch
    U+1F45E👞\:mans_shoe:Mans Shoe
    U+1F45F👟\:athletic_shoe:Athletic Shoe
    U+1F460👠\:high_heel:High-Heeled Shoe
    U+1F461👡\:sandal:Womans Sandal
    U+1F462👢\:boot:Womans Boots
    U+1F463👣\:footprints:Footprints
    U+1F464👤\:bust_in_silhouette:Bust In Silhouette
    U+1F465👥\:busts_in_silhouette:Busts In Silhouette
    U+1F466👦\:boy:Boy
    U+1F467👧\:girl:Girl
    U+1F468👨\:man:Man
    U+1F469👩\:woman:Woman
    U+1F46A👪\:family:Family
    U+1F46B👫\:couple:, \:man_and_woman_holding_hands:Man And Woman Holding Hands
    U+1F46C👬\:two_men_holding_hands:Two Men Holding Hands
    U+1F46D👭\:two_women_holding_hands:Two Women Holding Hands
    U+1F46E👮\:cop:Police Officer
    U+1F46F👯\:dancers:Woman With Bunny Ears
    U+1F470👰\:bride_with_veil:Bride With Veil
    U+1F471👱\:person_with_blond_hair:Person With Blond Hair
    U+1F472👲\:man_with_gua_pi_mao:Man With Gua Pi Mao
    U+1F473👳\:man_with_turban:Man With Turban
    U+1F474👴\:older_man:Older Man
    U+1F475👵\:older_woman:Older Woman
    U+1F476👶\:baby:Baby
    U+1F477👷\:construction_worker:Construction Worker
    U+1F478👸\:princess:Princess
    U+1F479👹\:japanese_ogre:Japanese Ogre
    U+1F47A👺\:japanese_goblin:Japanese Goblin
    U+1F47B👻\:ghost:Ghost
    U+1F47C👼\:angel:Baby Angel
    U+1F47D👽\:alien:Extraterrestrial Alien
    U+1F47E👾\:space_invader:Alien Monster
    U+1F47F👿\:imp:Imp
    U+1F480💀\:skull:Skull
    U+1F481💁\:information_desk_person:Information Desk Person
    U+1F482💂\:guardsman:Guardsman
    U+1F483💃\:dancer:Dancer
    U+1F484💄\:lipstick:Lipstick
    U+1F485💅\:nail_care:Nail Polish
    U+1F486💆\:massage:Face Massage
    U+1F487💇\:haircut:Haircut
    U+1F488💈\:barber:Barber Pole
    U+1F489💉\:syringe:Syringe
    U+1F48A💊\:pill:Pill
    U+1F48B💋\:kiss:Kiss Mark
    U+1F48C💌\:love_letter:Love Letter
    U+1F48D💍\:ring:Ring
    U+1F48E💎\:gem:Gem Stone
    U+1F48F💏\:couplekiss:Kiss
    U+1F490💐\:bouquet:Bouquet
    U+1F491💑\:couple_with_heart:Couple With Heart
    U+1F492💒\:wedding:Wedding
    U+1F493💓\:heartbeat:Beating Heart
    U+1F494💔\:broken_heart:Broken Heart
    U+1F495💕\:two_hearts:Two Hearts
    U+1F496💖\:sparkling_heart:Sparkling Heart
    U+1F497💗\:heartpulse:Growing Heart
    U+1F498💘\:cupid:Heart With Arrow
    U+1F499💙\:blue_heart:Blue Heart
    U+1F49A💚\:green_heart:Green Heart
    U+1F49B💛\:yellow_heart:Yellow Heart
    U+1F49C💜\:purple_heart:Purple Heart
    U+1F49D💝\:gift_heart:Heart With Ribbon
    U+1F49E💞\:revolving_hearts:Revolving Hearts
    U+1F49F💟\:heart_decoration:Heart Decoration
    U+1F4A0💠\:diamond_shape_with_a_dot_inside:Diamond Shape With A Dot Inside
    U+1F4A1💡\:bulb:Electric Light Bulb
    U+1F4A2💢\:anger:Anger Symbol
    U+1F4A3💣\:bomb:Bomb
    U+1F4A4💤\:zzz:Sleeping Symbol
    U+1F4A5💥\:boom:Collision Symbol
    U+1F4A6💦\:sweat_drops:Splashing Sweat Symbol
    U+1F4A7💧\:droplet:Droplet
    U+1F4A8💨\:dash:Dash Symbol
    U+1F4A9💩\:hankey:Pile Of Poo
    U+1F4AA💪\:muscle:Flexed Biceps
    U+1F4AB💫\:dizzy:Dizzy Symbol
    U+1F4AC💬\:speech_balloon:Speech Balloon
    U+1F4AD💭\:thought_balloon:Thought Balloon
    U+1F4AE💮\:white_flower:White Flower
    U+1F4AF💯\:100:Hundred Points Symbol
    U+1F4B0💰\:moneybag:Money Bag
    U+1F4B1💱\:currency_exchange:Currency Exchange
    U+1F4B2💲\:heavy_dollar_sign:Heavy Dollar Sign
    U+1F4B3💳\:credit_card:Credit Card
    U+1F4B4💴\:yen:Banknote With Yen Sign
    U+1F4B5💵\:dollar:Banknote With Dollar Sign
    U+1F4B6💶\:euro:Banknote With Euro Sign
    U+1F4B7💷\:pound:Banknote With Pound Sign
    U+1F4B8💸\:money_with_wings:Money With Wings
    U+1F4B9💹\:chart:Chart With Upwards Trend And Yen Sign
    U+1F4BA💺\:seat:Seat
    U+1F4BB💻\:computer:Personal Computer
    U+1F4BC💼\:briefcase:Briefcase
    U+1F4BD💽\:minidisc:Minidisc
    U+1F4BE💾\:floppy_disk:Floppy Disk
    U+1F4BF💿\:cd:Optical Disc
    U+1F4C0📀\:dvd:Dvd
    U+1F4C1📁\:file_folder:File Folder
    U+1F4C2📂\:open_file_folder:Open File Folder
    U+1F4C3📃\:page_with_curl:Page With Curl
    U+1F4C4📄\:page_facing_up:Page Facing Up
    U+1F4C5📅\:date:Calendar
    U+1F4C6📆\:calendar:Tear-Off Calendar
    U+1F4C7📇\:card_index:Card Index
    U+1F4C8📈\:chart_with_upwards_trend:Chart With Upwards Trend
    U+1F4C9📉\:chart_with_downwards_trend:Chart With Downwards Trend
    U+1F4CA📊\:bar_chart:Bar Chart
    U+1F4CB📋\:clipboard:Clipboard
    U+1F4CC📌\:pushpin:Pushpin
    U+1F4CD📍\:round_pushpin:Round Pushpin
    U+1F4CE📎\:paperclip:Paperclip
    U+1F4CF📏\:straight_ruler:Straight Ruler
    U+1F4D0📐\:triangular_ruler:Triangular Ruler
    U+1F4D1📑\:bookmark_tabs:Bookmark Tabs
    U+1F4D2📒\:ledger:Ledger
    U+1F4D3📓\:notebook:Notebook
    U+1F4D4📔\:notebook_with_decorative_cover:Notebook With Decorative Cover
    U+1F4D5📕\:closed_book:Closed Book
    U+1F4D6📖\:book:Open Book
    U+1F4D7📗\:green_book:Green Book
    U+1F4D8📘\:blue_book:Blue Book
    U+1F4D9📙\:orange_book:Orange Book
    U+1F4DA📚\:books:Books
    U+1F4DB📛\:name_badge:Name Badge
    U+1F4DC📜\:scroll:Scroll
    U+1F4DD📝\:memo:Memo
    U+1F4DE📞\:telephone_receiver:Telephone Receiver
    U+1F4DF📟\:pager:Pager
    U+1F4E0📠\:fax:Fax Machine
    U+1F4E1📡\:satellite:, \:satellite_antenna:Satellite Antenna
    U+1F4E2📢\:loudspeaker:Public Address Loudspeaker
    U+1F4E3📣\:mega:Cheering Megaphone
    U+1F4E4📤\:outbox_tray:Outbox Tray
    U+1F4E5📥\:inbox_tray:Inbox Tray
    U+1F4E6📦\:package:Package
    U+1F4E7📧\:e-mail:E-Mail Symbol
    U+1F4E8📨\:incoming_envelope:Incoming Envelope
    U+1F4E9📩\:envelope_with_arrow:Envelope With Downwards Arrow Above
    U+1F4EA📪\:mailbox_closed:Closed Mailbox With Lowered Flag
    U+1F4EB📫\:mailbox:Closed Mailbox With Raised Flag
    U+1F4EC📬\:mailbox_with_mail:Open Mailbox With Raised Flag
    U+1F4ED📭\:mailbox_with_no_mail:Open Mailbox With Lowered Flag
    U+1F4EE📮\:postbox:Postbox
    U+1F4EF📯\:postal_horn:Postal Horn
    U+1F4F0📰\:newspaper:Newspaper
    U+1F4F1📱\:iphone:Mobile Phone
    U+1F4F2📲\:calling:Mobile Phone With Rightwards Arrow At Left
    U+1F4F3📳\:vibration_mode:Vibration Mode
    U+1F4F4📴\:mobile_phone_off:Mobile Phone Off
    U+1F4F5📵\:no_mobile_phones:No Mobile Phones
    U+1F4F6📶\:signal_strength:Antenna With Bars
    U+1F4F7📷\:camera:Camera
    U+1F4F8📸\:camera_with_flash:Camera With Flash
    U+1F4F9📹\:video_camera:Video Camera
    U+1F4FA📺\:tv:Television
    U+1F4FB📻\:radio:Radio
    U+1F4FC📼\:vhs:Videocassette
    U+1F4FF📿\:prayer_beads:Prayer Beads
    U+1F500🔀\:twisted_rightwards_arrows:Twisted Rightwards Arrows
    U+1F501🔁\:repeat:Clockwise Rightwards And Leftwards Open Circle Arrows
    U+1F502🔂\:repeat_one:Clockwise Rightwards And Leftwards Open Circle Arrows With Circled One Overlay
    U+1F503🔃\:arrows_clockwise:Clockwise Downwards And Upwards Open Circle Arrows
    U+1F504🔄\:arrows_counterclockwise:Anticlockwise Downwards And Upwards Open Circle Arrows
    U+1F505🔅\:low_brightness:Low Brightness Symbol
    U+1F506🔆\:high_brightness:High Brightness Symbol
    U+1F507🔇\:mute:Speaker With Cancellation Stroke
    U+1F508🔈\:speaker:Speaker
    U+1F509🔉\:sound:Speaker With One Sound Wave
    U+1F50A🔊\:loud_sound:Speaker With Three Sound Waves
    U+1F50B🔋\:battery:Battery
    U+1F50C🔌\:electric_plug:Electric Plug
    U+1F50D🔍\:mag:Left-Pointing Magnifying Glass
    U+1F50E🔎\:mag_right:Right-Pointing Magnifying Glass
    U+1F50F🔏\:lock_with_ink_pen:Lock With Ink Pen
    U+1F510🔐\:closed_lock_with_key:Closed Lock With Key
    U+1F511🔑\:key:Key
    U+1F512🔒\:lock:Lock
    U+1F513🔓\:unlock:Open Lock
    U+1F514🔔\:bell:Bell
    U+1F515🔕\:no_bell:Bell With Cancellation Stroke
    U+1F516🔖\:bookmark:Bookmark
    U+1F517🔗\:link:Link Symbol
    U+1F518🔘\:radio_button:Radio Button
    U+1F519🔙\:back:Back With Leftwards Arrow Above
    U+1F51A🔚\:end:End With Leftwards Arrow Above
    U+1F51B🔛\:on:On With Exclamation Mark With Left Right Arrow Above
    U+1F51C🔜\:soon:Soon With Rightwards Arrow Above
    U+1F51D🔝\:top:Top With Upwards Arrow Above
    U+1F51E🔞\:underage:No One Under Eighteen Symbol
    U+1F51F🔟\:keycap_ten:Keycap Ten
    U+1F520🔠\:capital_abcd:Input Symbol For Latin Capital Letters
    U+1F521🔡\:abcd:Input Symbol For Latin Small Letters
    U+1F522🔢\:1234:Input Symbol For Numbers
    U+1F523🔣\:symbols:Input Symbol For Symbols
    U+1F524🔤\:abc:Input Symbol For Latin Letters
    U+1F525🔥\:fire:Fire
    U+1F526🔦\:flashlight:Electric Torch
    U+1F527🔧\:wrench:Wrench
    U+1F528🔨\:hammer:Hammer
    U+1F529🔩\:nut_and_bolt:Nut And Bolt
    U+1F52A🔪\:hocho:Hocho
    U+1F52B🔫\:gun:Pistol
    U+1F52C🔬\:microscope:Microscope
    U+1F52D🔭\:telescope:Telescope
    U+1F52E🔮\:crystal_ball:Crystal Ball
    U+1F52F🔯\:six_pointed_star:Six Pointed Star With Middle Dot
    U+1F530🔰\:beginner:Japanese Symbol For Beginner
    U+1F531🔱\:trident:Trident Emblem
    U+1F532🔲\:black_square_button:Black Square Button
    U+1F533🔳\:white_square_button:White Square Button
    U+1F534🔴\:red_circle:Large Red Circle
    U+1F535🔵\:large_blue_circle:Large Blue Circle
    U+1F536🔶\:large_orange_diamond:Large Orange Diamond
    U+1F537🔷\:large_blue_diamond:Large Blue Diamond
    U+1F538🔸\:small_orange_diamond:Small Orange Diamond
    U+1F539🔹\:small_blue_diamond:Small Blue Diamond
    U+1F53A🔺\:small_red_triangle:Up-Pointing Red Triangle
    U+1F53B🔻\:small_red_triangle_down:Down-Pointing Red Triangle
    U+1F53C🔼\:arrow_up_small:Up-Pointing Small Red Triangle
    U+1F53D🔽\:arrow_down_small:Down-Pointing Small Red Triangle
    U+1F54B🕋\:kaaba:Kaaba
    U+1F54C🕌\:mosque:Mosque
    U+1F54D🕍\:synagogue:Synagogue
    U+1F54E🕎\:menorah_with_nine_branches:Menorah With Nine Branches
    U+1F550🕐\:clock1:Clock Face One Oclock
    U+1F551🕑\:clock2:Clock Face Two Oclock
    U+1F552🕒\:clock3:Clock Face Three Oclock
    U+1F553🕓\:clock4:Clock Face Four Oclock
    U+1F554🕔\:clock5:Clock Face Five Oclock
    U+1F555🕕\:clock6:Clock Face Six Oclock
    U+1F556🕖\:clock7:Clock Face Seven Oclock
    U+1F557🕗\:clock8:Clock Face Eight Oclock
    U+1F558🕘\:clock9:Clock Face Nine Oclock
    U+1F559🕙\:clock10:Clock Face Ten Oclock
    U+1F55A🕚\:clock11:Clock Face Eleven Oclock
    U+1F55B🕛\:clock12:Clock Face Twelve Oclock
    U+1F55C🕜\:clock130:Clock Face One-Thirty
    U+1F55D🕝\:clock230:Clock Face Two-Thirty
    U+1F55E🕞\:clock330:Clock Face Three-Thirty
    U+1F55F🕟\:clock430:Clock Face Four-Thirty
    U+1F560🕠\:clock530:Clock Face Five-Thirty
    U+1F561🕡\:clock630:Clock Face Six-Thirty
    U+1F562🕢\:clock730:Clock Face Seven-Thirty
    U+1F563🕣\:clock830:Clock Face Eight-Thirty
    U+1F564🕤\:clock930:Clock Face Nine-Thirty
    U+1F565🕥\:clock1030:Clock Face Ten-Thirty
    U+1F566🕦\:clock1130:Clock Face Eleven-Thirty
    U+1F567🕧\:clock1230:Clock Face Twelve-Thirty
    U+1F57A🕺\:man_dancing:Man Dancing
    U+1F595🖕\:middle_finger:Reversed Hand With Middle Finger Extended
    U+1F596🖖\:spock-hand:Raised Hand With Part Between Middle And Ring Fingers
    U+1F5A4🖤\:black_heart:Black Heart
    U+1F5FB🗻\:mount_fuji:Mount Fuji
    U+1F5FC🗼\:tokyo_tower:Tokyo Tower
    U+1F5FD🗽\:statue_of_liberty:Statue Of Liberty
    U+1F5FE🗾\:japan:Silhouette Of Japan
    U+1F5FF🗿\:moyai:Moyai
    U+1F600😀\:grinning:Grinning Face
    U+1F601😁\:grin:Grinning Face With Smiling Eyes
    U+1F602😂\:joy:Face With Tears Of Joy
    U+1F603😃\:smiley:Smiling Face With Open Mouth
    U+1F604😄\:smile:Smiling Face With Open Mouth And Smiling Eyes
    U+1F605😅\:sweat_smile:Smiling Face With Open Mouth And Cold Sweat
    U+1F606😆\:laughing:Smiling Face With Open Mouth And Tightly-Closed Eyes
    U+1F607😇\:innocent:Smiling Face With Halo
    U+1F608😈\:smiling_imp:Smiling Face With Horns
    U+1F609😉\:wink:Winking Face
    U+1F60A😊\:blush:Smiling Face With Smiling Eyes
    U+1F60B😋\:yum:Face Savouring Delicious Food
    U+1F60C😌\:relieved:Relieved Face
    U+1F60D😍\:heart_eyes:Smiling Face With Heart-Shaped Eyes
    U+1F60E😎\:sunglasses:Smiling Face With Sunglasses
    U+1F60F😏\:smirk:Smirking Face
    U+1F610😐\:neutral_face:Neutral Face
    U+1F611😑\:expressionless:Expressionless Face
    U+1F612😒\:unamused:Unamused Face
    U+1F613😓\:sweat:Face With Cold Sweat
    U+1F614😔\:pensive:Pensive Face
    U+1F615😕\:confused:Confused Face
    U+1F616😖\:confounded:Confounded Face
    U+1F617😗\:kissing:Kissing Face
    U+1F618😘\:kissing_heart:Face Throwing A Kiss
    U+1F619😙\:kissing_smiling_eyes:Kissing Face With Smiling Eyes
    U+1F61A😚\:kissing_closed_eyes:Kissing Face With Closed Eyes
    U+1F61B😛\:stuck_out_tongue:Face With Stuck-Out Tongue
    U+1F61C😜\:stuck_out_tongue_winking_eye:Face With Stuck-Out Tongue And Winking Eye
    U+1F61D😝\:stuck_out_tongue_closed_eyes:Face With Stuck-Out Tongue And Tightly-Closed Eyes
    U+1F61E😞\:disappointed:Disappointed Face
    U+1F61F😟\:worried:Worried Face
    U+1F620😠\:angry:Angry Face
    U+1F621😡\:rage:Pouting Face
    U+1F622😢\:cry:Crying Face
    U+1F623😣\:persevere:Persevering Face
    U+1F624😤\:triumph:Face With Look Of Triumph
    U+1F625😥\:disappointed_relieved:Disappointed But Relieved Face
    U+1F626😦\:frowning:Frowning Face With Open Mouth
    U+1F627😧\:anguished:Anguished Face
    U+1F628😨\:fearful:Fearful Face
    U+1F629😩\:weary:Weary Face
    U+1F62A😪\:sleepy:Sleepy Face
    U+1F62B😫\:tired_face:Tired Face
    U+1F62C😬\:grimacing:Grimacing Face
    U+1F62D😭\:sob:Loudly Crying Face
    U+1F62E😮\:open_mouth:Face With Open Mouth
    U+1F62F😯\:hushed:Hushed Face
    U+1F630😰\:cold_sweat:Face With Open Mouth And Cold Sweat
    U+1F631😱\:scream:Face Screaming In Fear
    U+1F632😲\:astonished:Astonished Face
    U+1F633😳\:flushed:Flushed Face
    U+1F634😴\:sleeping:Sleeping Face
    U+1F635😵\:dizzy_face:Dizzy Face
    U+1F636😶\:no_mouth:Face Without Mouth
    U+1F637😷\:mask:Face With Medical Mask
    U+1F638😸\:smile_cat:Grinning Cat Face With Smiling Eyes
    U+1F639😹\:joy_cat:Cat Face With Tears Of Joy
    U+1F63A😺\:smiley_cat:Smiling Cat Face With Open Mouth
    U+1F63B😻\:heart_eyes_cat:Smiling Cat Face With Heart-Shaped Eyes
    U+1F63C😼\:smirk_cat:Cat Face With Wry Smile
    U+1F63D😽\:kissing_cat:Kissing Cat Face With Closed Eyes
    U+1F63E😾\:pouting_cat:Pouting Cat Face
    U+1F63F😿\:crying_cat_face:Crying Cat Face
    U+1F640🙀\:scream_cat:Weary Cat Face
    U+1F641🙁\:slightly_frowning_face:Slightly Frowning Face
    U+1F642🙂\:slightly_smiling_face:Slightly Smiling Face
    U+1F643🙃\:upside_down_face:Upside-Down Face
    U+1F644🙄\:face_with_rolling_eyes:Face With Rolling Eyes
    U+1F645🙅\:no_good:Face With No Good Gesture
    U+1F646🙆\:ok_woman:Face With Ok Gesture
    U+1F647🙇\:bow:Person Bowing Deeply
    U+1F648🙈\:see_no_evil:See-No-Evil Monkey
    U+1F649🙉\:hear_no_evil:Hear-No-Evil Monkey
    U+1F64A🙊\:speak_no_evil:Speak-No-Evil Monkey
    U+1F64B🙋\:raising_hand:Happy Person Raising One Hand
    U+1F64C🙌\:raised_hands:Person Raising Both Hands In Celebration
    U+1F64D🙍\:person_frowning:Person Frowning
    U+1F64E🙎\:person_with_pouting_face:Person With Pouting Face
    U+1F64F🙏\:pray:Person With Folded Hands
    U+1F680🚀\:rocket:Rocket
    U+1F681🚁\:helicopter:Helicopter
    U+1F682🚂\:steam_locomotive:Steam Locomotive
    U+1F683🚃\:railway_car:Railway Car
    U+1F684🚄\:bullettrain_side:High-Speed Train
    U+1F685🚅\:bullettrain_front:High-Speed Train With Bullet Nose
    U+1F686🚆\:train2:Train
    U+1F687🚇\:metro:Metro
    U+1F688🚈\:light_rail:Light Rail
    U+1F689🚉\:station:Station
    U+1F68A🚊\:tram:Tram
    U+1F68B🚋\:train:Tram Car
    U+1F68C🚌\:bus:Bus
    U+1F68D🚍\:oncoming_bus:Oncoming Bus
    U+1F68E🚎\:trolleybus:Trolleybus
    U+1F68F🚏\:busstop:Bus Stop
    U+1F690🚐\:minibus:Minibus
    U+1F691🚑\:ambulance:Ambulance
    U+1F692🚒\:fire_engine:Fire Engine
    U+1F693🚓\:police_car:Police Car
    U+1F694🚔\:oncoming_police_car:Oncoming Police Car
    U+1F695🚕\:taxi:Taxi
    U+1F696🚖\:oncoming_taxi:Oncoming Taxi
    U+1F697🚗\:car:Automobile
    U+1F698🚘\:oncoming_automobile:Oncoming Automobile
    U+1F699🚙\:blue_car:Recreational Vehicle
    U+1F69A🚚\:truck:Delivery Truck
    U+1F69B🚛\:articulated_lorry:Articulated Lorry
    U+1F69C🚜\:tractor:Tractor
    U+1F69D🚝\:monorail:Monorail
    U+1F69E🚞\:mountain_railway:Mountain Railway
    U+1F69F🚟\:suspension_railway:Suspension Railway
    U+1F6A0🚠\:mountain_cableway:Mountain Cableway
    U+1F6A1🚡\:aerial_tramway:Aerial Tramway
    U+1F6A2🚢\:ship:Ship
    U+1F6A3🚣\:rowboat:Rowboat
    U+1F6A4🚤\:speedboat:Speedboat
    U+1F6A5🚥\:traffic_light:Horizontal Traffic Light
    U+1F6A6🚦\:vertical_traffic_light:Vertical Traffic Light
    U+1F6A7🚧\:construction:Construction Sign
    U+1F6A8🚨\:rotating_light:Police Cars Revolving Light
    U+1F6A9🚩\:triangular_flag_on_post:Triangular Flag On Post
    U+1F6AA🚪\:door:Door
    U+1F6AB🚫\:no_entry_sign:No Entry Sign
    U+1F6AC🚬\:smoking:Smoking Symbol
    U+1F6AD🚭\:no_smoking:No Smoking Symbol
    U+1F6AE🚮\:put_litter_in_its_place:Put Litter In Its Place Symbol
    U+1F6AF🚯\:do_not_litter:Do Not Litter Symbol
    U+1F6B0🚰\:potable_water:Potable Water Symbol
    U+1F6B1🚱\:non-potable_water:Non-Potable Water Symbol
    U+1F6B2🚲\:bike:Bicycle
    U+1F6B3🚳\:no_bicycles:No Bicycles
    U+1F6B4🚴\:bicyclist:Bicyclist
    U+1F6B5🚵\:mountain_bicyclist:Mountain Bicyclist
    U+1F6B6🚶\:walking:Pedestrian
    U+1F6B7🚷\:no_pedestrians:No Pedestrians
    U+1F6B8🚸\:children_crossing:Children Crossing
    U+1F6B9🚹\:mens:Mens Symbol
    U+1F6BA🚺\:womens:Womens Symbol
    U+1F6BB🚻\:restroom:Restroom
    U+1F6BC🚼\:baby_symbol:Baby Symbol
    U+1F6BD🚽\:toilet:Toilet
    U+1F6BE🚾\:wc:Water Closet
    U+1F6BF🚿\:shower:Shower
    U+1F6C0🛀\:bath:Bath
    U+1F6C1🛁\:bathtub:Bathtub
    U+1F6C2🛂\:passport_control:Passport Control
    U+1F6C3🛃\:customs:Customs
    U+1F6C4🛄\:baggage_claim:Baggage Claim
    U+1F6C5🛅\:left_luggage:Left Luggage
    U+1F6CC🛌\:sleeping_accommodation:Sleeping Accommodation
    U+1F6D0🛐\:place_of_worship:Place Of Worship
    U+1F6D1🛑\:octagonal_sign:Octagonal Sign
    U+1F6D2🛒\:shopping_trolley:Shopping Trolley
    U+1F6D5🛕\:hindu_temple:Hindu Temple
    U+1F6D6🛖\:hut:Hut
    U+1F6D7🛗\:elevator:Elevator
    U+1F6EB🛫\:airplane_departure:Airplane Departure
    U+1F6EC🛬\:airplane_arriving:Airplane Arriving
    U+1F6F4🛴\:scooter:Scooter
    U+1F6F5🛵\:motor_scooter:Motor Scooter
    U+1F6F6🛶\:canoe:Canoe
    U+1F6F7🛷\:sled:Sled
    U+1F6F8🛸\:flying_saucer:Flying Saucer
    U+1F6F9🛹\:skateboard:Skateboard
    U+1F6FA🛺\:auto_rickshaw:Auto Rickshaw
    U+1F6FB🛻\:pickup_truck:Pickup Truck
    U+1F6FC🛼\:roller_skate:Roller Skate
    U+1F7E0🟠\:large_orange_circle:Large Orange Circle
    U+1F7E1🟡\:large_yellow_circle:Large Yellow Circle
    U+1F7E2🟢\:large_green_circle:Large Green Circle
    U+1F7E3🟣\:large_purple_circle:Large Purple Circle
    U+1F7E4🟤\:large_brown_circle:Large Brown Circle
    U+1F7E5🟥\:large_red_square:Large Red Square
    U+1F7E6🟦\:large_blue_square:Large Blue Square
    U+1F7E7🟧\:large_orange_square:Large Orange Square
    U+1F7E8🟨\:large_yellow_square:Large Yellow Square
    U+1F7E9🟩\:large_green_square:Large Green Square
    U+1F7EA🟪\:large_purple_square:Large Purple Square
    U+1F7EB🟫\:large_brown_square:Large Brown Square
    U+1F90C🤌\:pinched_fingers:Pinched Fingers
    U+1F90D🤍\:white_heart:White Heart
    U+1F90E🤎\:brown_heart:Brown Heart
    U+1F90F🤏\:pinching_hand:Pinching Hand
    U+1F910🤐\:zipper_mouth_face:Zipper-Mouth Face
    U+1F911🤑\:money_mouth_face:Money-Mouth Face
    U+1F912🤒\:face_with_thermometer:Face With Thermometer
    U+1F913🤓\:nerd_face:Nerd Face
    U+1F914🤔\:thinking_face:Thinking Face
    U+1F915🤕\:face_with_head_bandage:Face With Head-Bandage
    U+1F916🤖\:robot_face:Robot Face
    U+1F917🤗\:hugging_face:Hugging Face
    U+1F918🤘\:the_horns:Sign Of The Horns
    U+1F919🤙\:call_me_hand:Call Me Hand
    U+1F91A🤚\:raised_back_of_hand:Raised Back Of Hand
    U+1F91B🤛\:left-facing_fist:Left-Facing Fist
    U+1F91C🤜\:right-facing_fist:Right-Facing Fist
    U+1F91D🤝\:handshake:Handshake
    U+1F91E🤞\:crossed_fingers:Hand With Index And Middle Fingers Crossed
    U+1F91F🤟\:i_love_you_hand_sign:I Love You Hand Sign
    U+1F920🤠\:face_with_cowboy_hat:Face With Cowboy Hat
    U+1F921🤡\:clown_face:Clown Face
    U+1F922🤢\:nauseated_face:Nauseated Face
    U+1F923🤣\:rolling_on_the_floor_laughing:Rolling On The Floor Laughing
    U+1F924🤤\:drooling_face:Drooling Face
    U+1F925🤥\:lying_face:Lying Face
    U+1F926🤦\:face_palm:Face Palm
    U+1F927🤧\:sneezing_face:Sneezing Face
    U+1F928🤨\:face_with_raised_eyebrow:Face With One Eyebrow Raised
    U+1F929🤩\:star-struck:Grinning Face With Star Eyes
    U+1F92A🤪\:zany_face:Grinning Face With One Large And One Small Eye
    U+1F92B🤫\:shushing_face:Face With Finger Covering Closed Lips
    U+1F92C🤬\:face_with_symbols_on_mouth:Serious Face With Symbols Covering Mouth
    U+1F92D🤭\:face_with_hand_over_mouth:Smiling Face With Smiling Eyes And Hand Covering Mouth
    U+1F92E🤮\:face_vomiting:Face With Open Mouth Vomiting
    U+1F92F🤯\:exploding_head:Shocked Face With Exploding Head
    U+1F930🤰\:pregnant_woman:Pregnant Woman
    U+1F931🤱\:breast-feeding:Breast-Feeding
    U+1F932🤲\:palms_up_together:Palms Up Together
    U+1F933🤳\:selfie:Selfie
    U+1F934🤴\:prince:Prince
    U+1F935🤵\:person_in_tuxedo:Man In Tuxedo
    U+1F936🤶\:mrs_claus:Mother Christmas
    U+1F937🤷\:shrug:Shrug
    U+1F938🤸\:person_doing_cartwheel:Person Doing Cartwheel
    U+1F939🤹\:juggling:Juggling
    U+1F93A🤺\:fencer:Fencer
    U+1F93C🤼\:wrestlers:Wrestlers
    U+1F93D🤽\:water_polo:Water Polo
    U+1F93E🤾\:handball:Handball
    U+1F93F🤿\:diving_mask:Diving Mask
    U+1F940🥀\:wilted_flower:Wilted Flower
    U+1F941🥁\:drum_with_drumsticks:Drum With Drumsticks
    U+1F942🥂\:clinking_glasses:Clinking Glasses
    U+1F943🥃\:tumbler_glass:Tumbler Glass
    U+1F944🥄\:spoon:Spoon
    U+1F945🥅\:goal_net:Goal Net
    U+1F947🥇\:first_place_medal:First Place Medal
    U+1F948🥈\:second_place_medal:Second Place Medal
    U+1F949🥉\:third_place_medal:Third Place Medal
    U+1F94A🥊\:boxing_glove:Boxing Glove
    U+1F94B🥋\:martial_arts_uniform:Martial Arts Uniform
    U+1F94C🥌\:curling_stone:Curling Stone
    U+1F94D🥍\:lacrosse:Lacrosse Stick And Ball
    U+1F94E🥎\:softball:Softball
    U+1F94F🥏\:flying_disc:Flying Disc
    U+1F950🥐\:croissant:Croissant
    U+1F951🥑\:avocado:Avocado
    U+1F952🥒\:cucumber:Cucumber
    U+1F953🥓\:bacon:Bacon
    U+1F954🥔\:potato:Potato
    U+1F955🥕\:carrot:Carrot
    U+1F956🥖\:baguette_bread:Baguette Bread
    U+1F957🥗\:green_salad:Green Salad
    U+1F958🥘\:shallow_pan_of_food:Shallow Pan Of Food
    U+1F959🥙\:stuffed_flatbread:Stuffed Flatbread
    U+1F95A🥚\:egg:Egg
    U+1F95B🥛\:glass_of_milk:Glass Of Milk
    U+1F95C🥜\:peanuts:Peanuts
    U+1F95D🥝\:kiwifruit:Kiwifruit
    U+1F95E🥞\:pancakes:Pancakes
    U+1F95F🥟\:dumpling:Dumpling
    U+1F960🥠\:fortune_cookie:Fortune Cookie
    U+1F961🥡\:takeout_box:Takeout Box
    U+1F962🥢\:chopsticks:Chopsticks
    U+1F963🥣\:bowl_with_spoon:Bowl With Spoon
    U+1F964🥤\:cup_with_straw:Cup With Straw
    U+1F965🥥\:coconut:Coconut
    U+1F966🥦\:broccoli:Broccoli
    U+1F967🥧\:pie:Pie
    U+1F968🥨\:pretzel:Pretzel
    U+1F969🥩\:cut_of_meat:Cut Of Meat
    U+1F96A🥪\:sandwich:Sandwich
    U+1F96B🥫\:canned_food:Canned Food
    U+1F96C🥬\:leafy_green:Leafy Green
    U+1F96D🥭\:mango:Mango
    U+1F96E🥮\:moon_cake:Moon Cake
    U+1F96F🥯\:bagel:Bagel
    U+1F970🥰\:smiling_face_with_3_hearts:Smiling Face With Smiling Eyes And Three Hearts
    U+1F971🥱\:yawning_face:Yawning Face
    U+1F972🥲\:smiling_face_with_tear:Smiling Face With Tear
    U+1F973🥳\:partying_face:Face With Party Horn And Party Hat
    U+1F974🥴\:woozy_face:Face With Uneven Eyes And Wavy Mouth
    U+1F975🥵\:hot_face:Overheated Face
    U+1F976🥶\:cold_face:Freezing Face
    U+1F977🥷\:ninja:Ninja
    U+1F978🥸\:disguised_face:Disguised Face
    U+1F97A🥺\:pleading_face:Face With Pleading Eyes
    U+1F97B🥻\:sari:Sari
    U+1F97C🥼\:lab_coat:Lab Coat
    U+1F97D🥽\:goggles:Goggles
    U+1F97E🥾\:hiking_boot:Hiking Boot
    U+1F97F🥿\:womans_flat_shoe:Flat Shoe
    U+1F980🦀\:crab:Crab
    U+1F981🦁\:lion_face:Lion Face
    U+1F982🦂\:scorpion:Scorpion
    U+1F983🦃\:turkey:Turkey
    U+1F984🦄\:unicorn_face:Unicorn Face
    U+1F985🦅\:eagle:Eagle
    U+1F986🦆\:duck:Duck
    U+1F987🦇\:bat:Bat
    U+1F988🦈\:shark:Shark
    U+1F989🦉\:owl:Owl
    U+1F98A🦊\:fox_face:Fox Face
    U+1F98B🦋\:butterfly:Butterfly
    U+1F98C🦌\:deer:Deer
    U+1F98D🦍\:gorilla:Gorilla
    U+1F98E🦎\:lizard:Lizard
    U+1F98F🦏\:rhinoceros:Rhinoceros
    U+1F990🦐\:shrimp:Shrimp
    U+1F991🦑\:squid:Squid
    U+1F992🦒\:giraffe_face:Giraffe Face
    U+1F993🦓\:zebra_face:Zebra Face
    U+1F994🦔\:hedgehog:Hedgehog
    U+1F995🦕\:sauropod:Sauropod
    U+1F996🦖\:t-rex:T-Rex
    U+1F997🦗\:cricket:Cricket
    U+1F998🦘\:kangaroo:Kangaroo
    U+1F999🦙\:llama:Llama
    U+1F99A🦚\:peacock:Peacock
    U+1F99B🦛\:hippopotamus:Hippopotamus
    U+1F99C🦜\:parrot:Parrot
    U+1F99D🦝\:raccoon:Raccoon
    U+1F99E🦞\:lobster:Lobster
    U+1F99F🦟\:mosquito:Mosquito
    U+1F9A0🦠\:microbe:Microbe
    U+1F9A1🦡\:badger:Badger
    U+1F9A2🦢\:swan:Swan
    U+1F9A3🦣\:mammoth:Mammoth
    U+1F9A4🦤\:dodo:Dodo
    U+1F9A5🦥\:sloth:Sloth
    U+1F9A6🦦\:otter:Otter
    U+1F9A7🦧\:orangutan:Orangutan
    U+1F9A8🦨\:skunk:Skunk
    U+1F9A9🦩\:flamingo:Flamingo
    U+1F9AA🦪\:oyster:Oyster
    U+1F9AB🦫\:beaver:Beaver
    U+1F9AC🦬\:bison:Bison
    U+1F9AD🦭\:seal:Seal
    U+1F9AE🦮\:guide_dog:Guide Dog
    U+1F9AF🦯\:probing_cane:Probing Cane
    U+1F9B4🦴\:bone:Bone
    U+1F9B5🦵\:leg:Leg
    U+1F9B6🦶\:foot:Foot
    U+1F9B7🦷\:tooth:Tooth
    U+1F9B8🦸\:superhero:Superhero
    U+1F9B9🦹\:supervillain:Supervillain
    U+1F9BA🦺\:safety_vest:Safety Vest
    U+1F9BB🦻\:ear_with_hearing_aid:Ear With Hearing Aid
    U+1F9BC🦼\:motorized_wheelchair:Motorized Wheelchair
    U+1F9BD🦽\:manual_wheelchair:Manual Wheelchair
    U+1F9BE🦾\:mechanical_arm:Mechanical Arm
    U+1F9BF🦿\:mechanical_leg:Mechanical Leg
    U+1F9C0🧀\:cheese_wedge:Cheese Wedge
    U+1F9C1🧁\:cupcake:Cupcake
    U+1F9C2🧂\:salt:Salt Shaker
    U+1F9C3🧃\:beverage_box:Beverage Box
    U+1F9C4🧄\:garlic:Garlic
    U+1F9C5🧅\:onion:Onion
    U+1F9C6🧆\:falafel:Falafel
    U+1F9C7🧇\:waffle:Waffle
    U+1F9C8🧈\:butter:Butter
    U+1F9C9🧉\:mate_drink:Mate Drink
    U+1F9CA🧊\:ice_cube:Ice Cube
    U+1F9CB🧋\:bubble_tea:Bubble Tea
    U+1F9CD🧍\:standing_person:Standing Person
    U+1F9CE🧎\:kneeling_person:Kneeling Person
    U+1F9CF🧏\:deaf_person:Deaf Person
    U+1F9D0🧐\:face_with_monocle:Face With Monocle
    U+1F9D1🧑\:adult:Adult
    U+1F9D2🧒\:child:Child
    U+1F9D3🧓\:older_adult:Older Adult
    U+1F9D4🧔\:bearded_person:Bearded Person
    U+1F9D5🧕\:person_with_headscarf:Person With Headscarf
    U+1F9D6🧖\:person_in_steamy_room:Person In Steamy Room
    U+1F9D7🧗\:person_climbing:Person Climbing
    U+1F9D8🧘\:person_in_lotus_position:Person In Lotus Position
    U+1F9D9🧙\:mage:Mage
    U+1F9DA🧚\:fairy:Fairy
    U+1F9DB🧛\:vampire:Vampire
    U+1F9DC🧜\:merperson:Merperson
    U+1F9DD🧝\:elf:Elf
    U+1F9DE🧞\:genie:Genie
    U+1F9DF🧟\:zombie:Zombie
    U+1F9E0🧠\:brain:Brain
    U+1F9E1🧡\:orange_heart:Orange Heart
    U+1F9E2🧢\:billed_cap:Billed Cap
    U+1F9E3🧣\:scarf:Scarf
    U+1F9E4🧤\:gloves:Gloves
    U+1F9E5🧥\:coat:Coat
    U+1F9E6🧦\:socks:Socks
    U+1F9E7🧧\:red_envelope:Red Gift Envelope
    U+1F9E8🧨\:firecracker:Firecracker
    U+1F9E9🧩\:jigsaw:Jigsaw Puzzle Piece
    U+1F9EA🧪\:test_tube:Test Tube
    U+1F9EB🧫\:petri_dish:Petri Dish
    U+1F9EC🧬\:dna:Dna Double Helix
    U+1F9ED🧭\:compass:Compass
    U+1F9EE🧮\:abacus:Abacus
    U+1F9EF🧯\:fire_extinguisher:Fire Extinguisher
    U+1F9F0🧰\:toolbox:Toolbox
    U+1F9F1🧱\:bricks:Brick
    U+1F9F2🧲\:magnet:Magnet
    U+1F9F3🧳\:luggage:Luggage
    U+1F9F4🧴\:lotion_bottle:Lotion Bottle
    U+1F9F5🧵\:thread:Spool Of Thread
    U+1F9F6🧶\:yarn:Ball Of Yarn
    U+1F9F7🧷\:safety_pin:Safety Pin
    U+1F9F8🧸\:teddy_bear:Teddy Bear
    U+1F9F9🧹\:broom:Broom
    U+1F9FA🧺\:basket:Basket
    U+1F9FB🧻\:roll_of_paper:Roll Of Paper
    U+1F9FC🧼\:soap:Bar Of Soap
    U+1F9FD🧽\:sponge:Sponge
    U+1F9FE🧾\:receipt:Receipt
    U+1F9FF🧿\:nazar_amulet:Nazar Amulet
    U+1FA70🩰\:ballet_shoes:Ballet Shoes
    U+1FA71🩱\:one-piece_swimsuit:One-Piece Swimsuit
    U+1FA72🩲\:briefs:Briefs
    U+1FA73🩳\:shorts:Shorts
    U+1FA74🩴\:thong_sandal:Thong Sandal
    U+1FA78🩸\:drop_of_blood:Drop Of Blood
    U+1FA79🩹\:adhesive_bandage:Adhesive Bandage
    U+1FA7A🩺\:stethoscope:Stethoscope
    U+1FA80🪀\:yo-yo:Yo-Yo
    U+1FA81🪁\:kite:Kite
    U+1FA82🪂\:parachute:Parachute
    U+1FA83🪃\:boomerang:Boomerang
    U+1FA84🪄\:magic_wand:Magic Wand
    U+1FA85🪅\:pinata:Pinata
    U+1FA86🪆\:nesting_dolls:Nesting Dolls
    U+1FA90🪐\:ringed_planet:Ringed Planet
    U+1FA91🪑\:chair:Chair
    U+1FA92🪒\:razor:Razor
    U+1FA93🪓\:axe:Axe
    U+1FA94🪔\:diya_lamp:Diya Lamp
    U+1FA95🪕\:banjo:Banjo
    U+1FA96🪖\:military_helmet:Military Helmet
    U+1FA97🪗\:accordion:Accordion
    U+1FA98🪘\:long_drum:Long Drum
    U+1FA99🪙\:coin:Coin
    U+1FA9A🪚\:carpentry_saw:Carpentry Saw
    U+1FA9B🪛\:screwdriver:Screwdriver
    U+1FA9C🪜\:ladder:Ladder
    U+1FA9D🪝\:hook:Hook
    U+1FA9E🪞\:mirror:Mirror
    U+1FA9F🪟\:window:Window
    U+1FAA0🪠\:plunger:Plunger
    U+1FAA1🪡\:sewing_needle:Sewing Needle
    U+1FAA2🪢\:knot:Knot
    U+1FAA3🪣\:bucket:Bucket
    U+1FAA4🪤\:mouse_trap:Mouse Trap
    U+1FAA5🪥\:toothbrush:Toothbrush
    U+1FAA6🪦\:headstone:Headstone
    U+1FAA7🪧\:placard:Placard
    U+1FAA8🪨\:rock:Rock
    U+1FAB0🪰\:fly:Fly
    U+1FAB1🪱\:worm:Worm
    U+1FAB2🪲\:beetle:Beetle
    U+1FAB3🪳\:cockroach:Cockroach
    U+1FAB4🪴\:potted_plant:Potted Plant
    U+1FAB5🪵\:wood:Wood
    U+1FAB6🪶\:feather:Feather
    U+1FAC0🫀\:anatomical_heart:Anatomical Heart
    U+1FAC1🫁\:lungs:Lungs
    U+1FAC2🫂\:people_hugging:People Hugging
    U+1FAD0🫐\:blueberries:Blueberries
    U+1FAD1🫑\:bell_pepper:Bell Pepper
    U+1FAD2🫒\:olive:Olive
    U+1FAD3🫓\:flatbread:Flatbread
    U+1FAD4🫔\:tamale:Tamale
    U+1FAD5🫕\:fondue:Fondue
    U+1FAD6🫖\:teapot:Teapot
    +

    Unicode Input

    The following table lists Unicode characters that can be entered via tab completion of LaTeX-like abbreviations in the Julia REPL (and in various other editing environments). You can also get information on how to type a symbol by entering it in the REPL help, i.e. by typing ? and then entering the symbol in the REPL (e.g., by copy-paste from somewhere you saw the symbol).

    Warning

    This table may appear to contain missing characters in the second column, or even show characters that are inconsistent with the characters as they are rendered in the Julia REPL. In these cases, users are strongly advised to check their choice of fonts in their browser and REPL environment, as there are known issues with glyphs in many fonts.

    Code point(s)Character(s)Tab completion sequence(s)Unicode name(s)
    U+000A1¡\exclamdownInverted Exclamation Mark
    U+000A3£\sterlingPound Sign
    U+000A5¥\yenYen Sign
    U+000A6¦\brokenbarBroken Bar / Broken Vertical Bar
    U+000A7§\SSection Sign
    U+000A9©\copyright, \:copyright:Copyright Sign
    U+000AAª\ordfeminineFeminine Ordinal Indicator
    U+000AB«\guillemotleftLeft-Pointing Double Angle Quotation Mark / Left Pointing Guillemet
    U+000AC¬\negNot Sign
    U+000AE®\circledR, \:registered:Registered Sign / Registered Trade Mark Sign
    U+000AF¯\highminusMacron / Spacing Macron
    U+000B0°\degreeDegree Sign
    U+000B1±\pmPlus-Minus Sign / Plus-Or-Minus Sign
    U+000B2²\^2Superscript Two / Superscript Digit Two
    U+000B3³\^3Superscript Three / Superscript Digit Three
    U+000B6\PPilcrow Sign / Paragraph Sign
    U+000B7·\cdotpMiddle Dot
    U+000B9¹\^1Superscript One / Superscript Digit One
    U+000BAº\ordmasculineMasculine Ordinal Indicator
    U+000BB»\guillemotrightRight-Pointing Double Angle Quotation Mark / Right Pointing Guillemet
    U+000BC¼\1/4Vulgar Fraction One Quarter / Fraction One Quarter
    U+000BD½\1/2Vulgar Fraction One Half / Fraction One Half
    U+000BE¾\3/4Vulgar Fraction Three Quarters / Fraction Three Quarters
    U+000BF¿\questiondownInverted Question Mark
    U+000C5Å\AALatin Capital Letter A With Ring Above / Latin Capital Letter A Ring
    U+000C6Æ\AELatin Capital Letter Ae / Latin Capital Letter A E
    U+000D0Ð\DHLatin Capital Letter Eth
    U+000D7×\timesMultiplication Sign
    U+000D8Ø\OLatin Capital Letter O With Stroke / Latin Capital Letter O Slash
    U+000DEÞ\THLatin Capital Letter Thorn
    U+000DFß\ssLatin Small Letter Sharp S
    U+000E5å\aaLatin Small Letter A With Ring Above / Latin Small Letter A Ring
    U+000E6æ\aeLatin Small Letter Ae / Latin Small Letter A E
    U+000F0ð\eth, \dhLatin Small Letter Eth
    U+000F7÷\divDivision Sign
    U+000F8ø\oLatin Small Letter O With Stroke / Latin Small Letter O Slash
    U+000FEþ\thLatin Small Letter Thorn
    U+00110Đ\DJLatin Capital Letter D With Stroke / Latin Capital Letter D Bar
    U+00111đ\djLatin Small Letter D With Stroke / Latin Small Letter D Bar
    U+00127ħ\hbarLatin Small Letter H With Stroke / Latin Small Letter H Bar
    U+00131ı\imathLatin Small Letter Dotless I
    U+00141Ł\LLatin Capital Letter L With Stroke / Latin Capital Letter L Slash
    U+00142ł\lLatin Small Letter L With Stroke / Latin Small Letter L Slash
    U+0014AŊ\NGLatin Capital Letter Eng
    U+0014Bŋ\ngLatin Small Letter Eng
    U+00152Œ\OELatin Capital Ligature Oe / Latin Capital Letter O E
    U+00153œ\oeLatin Small Ligature Oe / Latin Small Letter O E
    U+00195ƕ\hvligLatin Small Letter Hv / Latin Small Letter H V
    U+0019Eƞ\nrlegLatin Small Letter N With Long Right Leg
    U+001B5Ƶ\ZbarLatin Capital Letter Z With Stroke / Latin Capital Letter Z Bar
    U+001C2ǂ\doublepipeLatin Letter Alveolar Click / Latin Letter Pipe Double Bar
    U+00237ȷ\jmathLatin Small Letter Dotless J
    U+00250ɐ\trnaLatin Small Letter Turned A
    U+00252ɒ\trnsaLatin Small Letter Turned Alpha / Latin Small Letter Turned Script A
    U+00254ɔ\openoLatin Small Letter Open O
    U+00256ɖ\rtldLatin Small Letter D With Tail / Latin Small Letter D Retroflex Hook
    U+00259ə\schwaLatin Small Letter Schwa
    U+00263ɣ\pgammaLatin Small Letter Gamma
    U+00264ɤ\pbgamLatin Small Letter Rams Horn / Latin Small Letter Baby Gamma
    U+00265ɥ\trnhLatin Small Letter Turned H
    U+0026Cɬ\btdlLatin Small Letter L With Belt / Latin Small Letter L Belt
    U+0026Dɭ\rtllLatin Small Letter L With Retroflex Hook / Latin Small Letter L Retroflex Hook
    U+0026Fɯ\trnmLatin Small Letter Turned M
    U+00270ɰ\trnmlrLatin Small Letter Turned M With Long Leg
    U+00271ɱ\ltlmrLatin Small Letter M With Hook / Latin Small Letter M Hook
    U+00272ɲ\ltlnLatin Small Letter N With Left Hook / Latin Small Letter N Hook
    U+00273ɳ\rtlnLatin Small Letter N With Retroflex Hook / Latin Small Letter N Retroflex Hook
    U+00277ɷ\clomegLatin Small Letter Closed Omega
    U+00278ɸ\ltphiLatin Small Letter Phi
    U+00279ɹ\trnrLatin Small Letter Turned R
    U+0027Aɺ\trnrlLatin Small Letter Turned R With Long Leg
    U+0027Bɻ\rttrnrLatin Small Letter Turned R With Hook / Latin Small Letter Turned R Hook
    U+0027Cɼ\rlLatin Small Letter R With Long Leg
    U+0027Dɽ\rtlrLatin Small Letter R With Tail / Latin Small Letter R Hook
    U+0027Eɾ\fhrLatin Small Letter R With Fishhook / Latin Small Letter Fishhook R
    U+00282ʂ\rtlsLatin Small Letter S With Hook / Latin Small Letter S Hook
    U+00283ʃ\eshLatin Small Letter Esh
    U+00287ʇ\trntLatin Small Letter Turned T
    U+00288ʈ\rtltLatin Small Letter T With Retroflex Hook / Latin Small Letter T Retroflex Hook
    U+0028Aʊ\pupsilLatin Small Letter Upsilon
    U+0028Bʋ\pscrvLatin Small Letter V With Hook / Latin Small Letter Script V
    U+0028Cʌ\invvLatin Small Letter Turned V
    U+0028Dʍ\invwLatin Small Letter Turned W
    U+0028Eʎ\trnyLatin Small Letter Turned Y
    U+00290ʐ\rtlzLatin Small Letter Z With Retroflex Hook / Latin Small Letter Z Retroflex Hook
    U+00292ʒ\yoghLatin Small Letter Ezh / Latin Small Letter Yogh
    U+00294ʔ\glstLatin Letter Glottal Stop
    U+00295ʕ\reglstLatin Letter Pharyngeal Voiced Fricative / Latin Letter Reversed Glottal Stop
    U+00296ʖ\inglstLatin Letter Inverted Glottal Stop
    U+0029Eʞ\turnkLatin Small Letter Turned K
    U+002A4ʤ\dyoghLatin Small Letter Dezh Digraph / Latin Small Letter D Yogh
    U+002A7ʧ\teshLatin Small Letter Tesh Digraph / Latin Small Letter T Esh
    U+002B0ʰ\^hModifier Letter Small H
    U+002B2ʲ\^jModifier Letter Small J
    U+002B3ʳ\^rModifier Letter Small R
    U+002B7ʷ\^wModifier Letter Small W
    U+002B8ʸ\^yModifier Letter Small Y
    U+002BCʼ\raspModifier Letter Apostrophe
    U+002C8ˈ\vertsModifier Letter Vertical Line
    U+002CCˌ\vertiModifier Letter Low Vertical Line
    U+002D0ː\lmrkModifier Letter Triangular Colon
    U+002D1ˑ\hlmrkModifier Letter Half Triangular Colon
    U+002D2˒\sbrhrModifier Letter Centred Right Half Ring / Modifier Letter Centered Right Half Ring
    U+002D3˓\sblhrModifier Letter Centred Left Half Ring / Modifier Letter Centered Left Half Ring
    U+002D4˔\raisModifier Letter Up Tack
    U+002D5˕\lowModifier Letter Down Tack
    U+002D8˘\uBreve / Spacing Breve
    U+002DC˜\tildelowSmall Tilde / Spacing Tilde
    U+002E1ˡ\^lModifier Letter Small L
    U+002E2ˢ\^sModifier Letter Small S
    U+002E3ˣ\^xModifier Letter Small X
    U+00300 ̀ \graveCombining Grave Accent / Non-Spacing Grave
    U+00301 ́ \acuteCombining Acute Accent / Non-Spacing Acute
    U+00302 ̂ \hatCombining Circumflex Accent / Non-Spacing Circumflex
    U+00303 ̃ \tildeCombining Tilde / Non-Spacing Tilde
    U+00304 ̄ \barCombining Macron / Non-Spacing Macron
    U+00305 ̅ \overbarCombining Overline / Non-Spacing Overscore
    U+00306 ̆ \breveCombining Breve / Non-Spacing Breve
    U+00307 ̇ \dotCombining Dot Above / Non-Spacing Dot Above
    U+00308 ̈ \ddotCombining Diaeresis / Non-Spacing Diaeresis
    U+00309 ̉ \ovhookCombining Hook Above / Non-Spacing Hook Above
    U+0030A ̊ \ocircCombining Ring Above / Non-Spacing Ring Above
    U+0030B ̋ \HCombining Double Acute Accent / Non-Spacing Double Acute
    U+0030C ̌ \checkCombining Caron / Non-Spacing Hacek
    U+00310 ̐ \candraCombining Candrabindu / Non-Spacing Candrabindu
    U+00312 ̒ \oturnedcommaCombining Turned Comma Above / Non-Spacing Turned Comma Above
    U+00315 ̕ \ocommatoprightCombining Comma Above Right / Non-Spacing Comma Above Right
    U+0031A ̚ \droangCombining Left Angle Above / Non-Spacing Left Angle Above
    U+00321 ̡ \palhCombining Palatalized Hook Below / Non-Spacing Palatalized Hook Below
    U+00322 ̢ \rhCombining Retroflex Hook Below / Non-Spacing Retroflex Hook Below
    U+00327 ̧ \cCombining Cedilla / Non-Spacing Cedilla
    U+00328 ̨ \kCombining Ogonek / Non-Spacing Ogonek
    U+0032A ̪ \sbbrgCombining Bridge Below / Non-Spacing Bridge Below
    U+00330 ̰ \wideutildeCombining Tilde Below / Non-Spacing Tilde Below
    U+00332 ̲ \underbarCombining Low Line / Non-Spacing Underscore
    U+00336 ̶ \strike, \soutCombining Long Stroke Overlay / Non-Spacing Long Bar Overlay
    U+00338 ̸ \notCombining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0034D ͍ \underleftrightarrowCombining Left Right Arrow Below
    U+00391Α\AlphaGreek Capital Letter Alpha
    U+00392Β\BetaGreek Capital Letter Beta
    U+00393Γ\GammaGreek Capital Letter Gamma
    U+00394Δ\DeltaGreek Capital Letter Delta
    U+00395Ε\EpsilonGreek Capital Letter Epsilon
    U+00396Ζ\ZetaGreek Capital Letter Zeta
    U+00397Η\EtaGreek Capital Letter Eta
    U+00398Θ\ThetaGreek Capital Letter Theta
    U+00399Ι\IotaGreek Capital Letter Iota
    U+0039AΚ\KappaGreek Capital Letter Kappa
    U+0039BΛ\LambdaGreek Capital Letter Lamda / Greek Capital Letter Lambda
    U+0039CΜ\MuGreek Capital Letter Mu
    U+0039DΝ\NuGreek Capital Letter Nu
    U+0039EΞ\XiGreek Capital Letter Xi
    U+0039FΟ\OmicronGreek Capital Letter Omicron
    U+003A0Π\PiGreek Capital Letter Pi
    U+003A1Ρ\RhoGreek Capital Letter Rho
    U+003A3Σ\SigmaGreek Capital Letter Sigma
    U+003A4Τ\TauGreek Capital Letter Tau
    U+003A5Υ\UpsilonGreek Capital Letter Upsilon
    U+003A6Φ\PhiGreek Capital Letter Phi
    U+003A7Χ\ChiGreek Capital Letter Chi
    U+003A8Ψ\PsiGreek Capital Letter Psi
    U+003A9Ω\OmegaGreek Capital Letter Omega
    U+003B1α\alphaGreek Small Letter Alpha
    U+003B2β\betaGreek Small Letter Beta
    U+003B3γ\gammaGreek Small Letter Gamma
    U+003B4δ\deltaGreek Small Letter Delta
    U+003B5ε\varepsilonGreek Small Letter Epsilon
    U+003B6ζ\zetaGreek Small Letter Zeta
    U+003B7η\etaGreek Small Letter Eta
    U+003B8θ\thetaGreek Small Letter Theta
    U+003B9ι\iotaGreek Small Letter Iota
    U+003BAκ\kappaGreek Small Letter Kappa
    U+003BBλ\lambdaGreek Small Letter Lamda / Greek Small Letter Lambda
    U+003BCμ\muGreek Small Letter Mu
    U+003BDν\nuGreek Small Letter Nu
    U+003BEξ\xiGreek Small Letter Xi
    U+003BFο\omicronGreek Small Letter Omicron
    U+003C0π\piGreek Small Letter Pi
    U+003C1ρ\rhoGreek Small Letter Rho
    U+003C2ς\varsigmaGreek Small Letter Final Sigma
    U+003C3σ\sigmaGreek Small Letter Sigma
    U+003C4τ\tauGreek Small Letter Tau
    U+003C5υ\upsilonGreek Small Letter Upsilon
    U+003C6φ\varphiGreek Small Letter Phi
    U+003C7χ\chiGreek Small Letter Chi
    U+003C8ψ\psiGreek Small Letter Psi
    U+003C9ω\omegaGreek Small Letter Omega
    U+003D0ϐ\varbetaGreek Beta Symbol / Greek Small Letter Curled Beta
    U+003D1ϑ\varthetaGreek Theta Symbol / Greek Small Letter Script Theta
    U+003D5ϕ\phiGreek Phi Symbol / Greek Small Letter Script Phi
    U+003D6ϖ\varpiGreek Pi Symbol / Greek Small Letter Omega Pi
    U+003D8Ϙ\oldKoppaGreek Letter Archaic Koppa
    U+003D9ϙ\oldkoppaGreek Small Letter Archaic Koppa
    U+003DAϚ\StigmaGreek Letter Stigma / Greek Capital Letter Stigma
    U+003DBϛ\stigmaGreek Small Letter Stigma
    U+003DCϜ\DigammaGreek Letter Digamma / Greek Capital Letter Digamma
    U+003DDϝ\digammaGreek Small Letter Digamma
    U+003DEϞ\KoppaGreek Letter Koppa / Greek Capital Letter Koppa
    U+003DFϟ\koppaGreek Small Letter Koppa
    U+003E0Ϡ\SampiGreek Letter Sampi / Greek Capital Letter Sampi
    U+003E1ϡ\sampiGreek Small Letter Sampi
    U+003F0ϰ\varkappaGreek Kappa Symbol / Greek Small Letter Script Kappa
    U+003F1ϱ\varrhoGreek Rho Symbol / Greek Small Letter Tailed Rho
    U+003F4ϴ\varThetaGreek Capital Theta Symbol
    U+003F5ϵ\epsilonGreek Lunate Epsilon Symbol
    U+003F6϶\backepsilonGreek Reversed Lunate Epsilon Symbol
    U+01D2C\^AModifier Letter Capital A
    U+01D2E\^BModifier Letter Capital B
    U+01D30\^DModifier Letter Capital D
    U+01D31\^EModifier Letter Capital E
    U+01D33\^GModifier Letter Capital G
    U+01D34\^HModifier Letter Capital H
    U+01D35\^IModifier Letter Capital I
    U+01D36\^JModifier Letter Capital J
    U+01D37\^KModifier Letter Capital K
    U+01D38\^LModifier Letter Capital L
    U+01D39\^MModifier Letter Capital M
    U+01D3A\^NModifier Letter Capital N
    U+01D3C\^OModifier Letter Capital O
    U+01D3E\^PModifier Letter Capital P
    U+01D3Fᴿ\^RModifier Letter Capital R
    U+01D40\^TModifier Letter Capital T
    U+01D41\^UModifier Letter Capital U
    U+01D42\^WModifier Letter Capital W
    U+01D43\^aModifier Letter Small A
    U+01D45\^alphaModifier Letter Small Alpha
    U+01D47\^bModifier Letter Small B
    U+01D48\^dModifier Letter Small D
    U+01D49\^eModifier Letter Small E
    U+01D4B\^epsilonModifier Letter Small Open E
    U+01D4D\^gModifier Letter Small G
    U+01D4F\^kModifier Letter Small K
    U+01D50\^mModifier Letter Small M
    U+01D52\^oModifier Letter Small O
    U+01D56\^pModifier Letter Small P
    U+01D57\^tModifier Letter Small T
    U+01D58\^uModifier Letter Small U
    U+01D5B\^vModifier Letter Small V
    U+01D5D\^betaModifier Letter Small Beta
    U+01D5E\^gammaModifier Letter Small Greek Gamma
    U+01D5F\^deltaModifier Letter Small Delta
    U+01D60\^phiModifier Letter Small Greek Phi
    U+01D61\^chiModifier Letter Small Chi
    U+01D62\_iLatin Subscript Small Letter I
    U+01D63\_rLatin Subscript Small Letter R
    U+01D64\_uLatin Subscript Small Letter U
    U+01D65\_vLatin Subscript Small Letter V
    U+01D66\_betaGreek Subscript Small Letter Beta
    U+01D67\_gammaGreek Subscript Small Letter Gamma
    U+01D68\_rhoGreek Subscript Small Letter Rho
    U+01D69\_phiGreek Subscript Small Letter Phi
    U+01D6A\_chiGreek Subscript Small Letter Chi
    U+01D9C\^cModifier Letter Small C
    U+01DA0\^fModifier Letter Small F
    U+01DA5\^iotaModifier Letter Small Iota
    U+01DB2\^ltphiModifier Letter Small Phi
    U+01DBB\^zModifier Letter Small Z
    U+01DBFᶿ\^thetaModifier Letter Small Theta
    U+02002\enspaceEn Space
    U+02003\quadEm Space
    U+02005\thickspaceFour-Per-Em Space
    U+02009\thinspaceThin Space
    U+0200A\hspaceHair Space
    U+02013\endashEn Dash
    U+02014\emdashEm Dash
    U+02016\VertDouble Vertical Line / Double Vertical Bar
    U+02018\lqLeft Single Quotation Mark / Single Turned Comma Quotation Mark
    U+02019\rqRight Single Quotation Mark / Single Comma Quotation Mark
    U+0201B\reaposSingle High-Reversed-9 Quotation Mark / Single Reversed Comma Quotation Mark
    U+0201C\ldqLeft Double Quotation Mark / Double Turned Comma Quotation Mark
    U+0201D\rdqRight Double Quotation Mark / Double Comma Quotation Mark
    U+02020\daggerDagger
    U+02021\ddaggerDouble Dagger
    U+02022\bulletBullet
    U+02026\dots, \ldotsHorizontal Ellipsis
    U+02030\perthousandPer Mille Sign
    U+02031\pertenthousandPer Ten Thousand Sign
    U+02032\primePrime
    U+02033\pprimeDouble Prime
    U+02034\ppprimeTriple Prime
    U+02035\backprimeReversed Prime
    U+02036\backpprimeReversed Double Prime
    U+02037\backppprimeReversed Triple Prime
    U+02039\guilsinglleftSingle Left-Pointing Angle Quotation Mark / Left Pointing Single Guillemet
    U+0203A\guilsinglrightSingle Right-Pointing Angle Quotation Mark / Right Pointing Single Guillemet
    U+0203C\:bangbang:Double Exclamation Mark
    U+02040\tieconcatCharacter Tie
    U+02049\:interrobang:Exclamation Question Mark
    U+02057\pppprimeQuadruple Prime
    U+0205D\tricolonTricolon
    U+02060\nolinebreakWord Joiner
    U+02070\^0Superscript Zero / Superscript Digit Zero
    U+02071\^iSuperscript Latin Small Letter I
    U+02074\^4Superscript Four / Superscript Digit Four
    U+02075\^5Superscript Five / Superscript Digit Five
    U+02076\^6Superscript Six / Superscript Digit Six
    U+02077\^7Superscript Seven / Superscript Digit Seven
    U+02078\^8Superscript Eight / Superscript Digit Eight
    U+02079\^9Superscript Nine / Superscript Digit Nine
    U+0207A\^+Superscript Plus Sign
    U+0207B\^-Superscript Minus / Superscript Hyphen-Minus
    U+0207C\^=Superscript Equals Sign
    U+0207D\^(Superscript Left Parenthesis / Superscript Opening Parenthesis
    U+0207E\^)Superscript Right Parenthesis / Superscript Closing Parenthesis
    U+0207F\^nSuperscript Latin Small Letter N
    U+02080\_0Subscript Zero / Subscript Digit Zero
    U+02081\_1Subscript One / Subscript Digit One
    U+02082\_2Subscript Two / Subscript Digit Two
    U+02083\_3Subscript Three / Subscript Digit Three
    U+02084\_4Subscript Four / Subscript Digit Four
    U+02085\_5Subscript Five / Subscript Digit Five
    U+02086\_6Subscript Six / Subscript Digit Six
    U+02087\_7Subscript Seven / Subscript Digit Seven
    U+02088\_8Subscript Eight / Subscript Digit Eight
    U+02089\_9Subscript Nine / Subscript Digit Nine
    U+0208A\_+Subscript Plus Sign
    U+0208B\_-Subscript Minus / Subscript Hyphen-Minus
    U+0208C\_=Subscript Equals Sign
    U+0208D\_(Subscript Left Parenthesis / Subscript Opening Parenthesis
    U+0208E\_)Subscript Right Parenthesis / Subscript Closing Parenthesis
    U+02090\_aLatin Subscript Small Letter A
    U+02091\_eLatin Subscript Small Letter E
    U+02092\_oLatin Subscript Small Letter O
    U+02093\_xLatin Subscript Small Letter X
    U+02094\_schwaLatin Subscript Small Letter Schwa
    U+02095\_hLatin Subscript Small Letter H
    U+02096\_kLatin Subscript Small Letter K
    U+02097\_lLatin Subscript Small Letter L
    U+02098\_mLatin Subscript Small Letter M
    U+02099\_nLatin Subscript Small Letter N
    U+0209A\_pLatin Subscript Small Letter P
    U+0209B\_sLatin Subscript Small Letter S
    U+0209C\_tLatin Subscript Small Letter T
    U+020A7\pesPeseta Sign
    U+020AC\euroEuro Sign
    U+020D0 ⃐ \leftharpoonaccentCombining Left Harpoon Above / Non-Spacing Left Harpoon Above
    U+020D1 ⃑ \rightharpoonaccentCombining Right Harpoon Above / Non-Spacing Right Harpoon Above
    U+020D2 ⃒ \vertoverlayCombining Long Vertical Line Overlay / Non-Spacing Long Vertical Bar Overlay
    U+020D6 ⃖ \overleftarrowCombining Left Arrow Above / Non-Spacing Left Arrow Above
    U+020D7 ⃗ \vecCombining Right Arrow Above / Non-Spacing Right Arrow Above
    U+020DB ⃛ \dddotCombining Three Dots Above / Non-Spacing Three Dots Above
    U+020DC ⃜ \ddddotCombining Four Dots Above / Non-Spacing Four Dots Above
    U+020DD ⃝ \enclosecircleCombining Enclosing Circle / Enclosing Circle
    U+020DE ⃞ \enclosesquareCombining Enclosing Square / Enclosing Square
    U+020DF ⃟ \enclosediamondCombining Enclosing Diamond / Enclosing Diamond
    U+020E1 ⃡ \overleftrightarrowCombining Left Right Arrow Above / Non-Spacing Left Right Arrow Above
    U+020E4 ⃤ \enclosetriangleCombining Enclosing Upward Pointing Triangle
    U+020E7 ⃧ \annuityCombining Annuity Symbol
    U+020E8 ⃨ \threeunderdotCombining Triple Underdot
    U+020E9 ⃩ \widebridgeaboveCombining Wide Bridge Above
    U+020EC ⃬ \underrightharpoondownCombining Rightwards Harpoon With Barb Downwards
    U+020ED ⃭ \underleftharpoondownCombining Leftwards Harpoon With Barb Downwards
    U+020EE ⃮ \underleftarrowCombining Left Arrow Below
    U+020EF ⃯ \underrightarrowCombining Right Arrow Below
    U+020F0 ⃰ \asteraccentCombining Asterisk Above
    U+02102\bbCDouble-Struck Capital C / Double-Struck C
    U+02107\eulermascheroniEuler Constant / Eulers
    U+0210A\scrgScript Small G
    U+0210B\scrHScript Capital H / Script H
    U+0210C\frakHBlack-Letter Capital H / Black-Letter H
    U+0210D\bbHDouble-Struck Capital H / Double-Struck H
    U+0210E\ith, \planckPlanck Constant
    U+0210F\hslashPlanck Constant Over Two Pi / Planck Constant Over 2 Pi
    U+02110\scrIScript Capital I / Script I
    U+02111\Im, \frakIBlack-Letter Capital I / Black-Letter I
    U+02112\scrLScript Capital L / Script L
    U+02113\ellScript Small L
    U+02115\bbNDouble-Struck Capital N / Double-Struck N
    U+02116\numeroNumero Sign / Numero
    U+02118\wpScript Capital P / Script P
    U+02119\bbPDouble-Struck Capital P / Double-Struck P
    U+0211A\bbQDouble-Struck Capital Q / Double-Struck Q
    U+0211B\scrRScript Capital R / Script R
    U+0211C\Re, \frakRBlack-Letter Capital R / Black-Letter R
    U+0211D\bbRDouble-Struck Capital R / Double-Struck R
    U+0211E\xratPrescription Take
    U+02122\trademark, \:tm:Trade Mark Sign / Trademark
    U+02124\bbZDouble-Struck Capital Z / Double-Struck Z
    U+02126\ohmOhm Sign / Ohm
    U+02127\mhoInverted Ohm Sign / Mho
    U+02128\frakZBlack-Letter Capital Z / Black-Letter Z
    U+02129\turnediotaTurned Greek Small Letter Iota
    U+0212B\AngstromAngstrom Sign / Angstrom Unit
    U+0212C\scrBScript Capital B / Script B
    U+0212D\frakCBlack-Letter Capital C / Black-Letter C
    U+0212F\scre, \eulerScript Small E
    U+02130\scrEScript Capital E / Script E
    U+02131\scrFScript Capital F / Script F
    U+02132\FinvTurned Capital F / Turned F
    U+02133\scrMScript Capital M / Script M
    U+02134\scroScript Small O
    U+02135\alephAlef Symbol / First Transfinite Cardinal
    U+02136\bethBet Symbol / Second Transfinite Cardinal
    U+02137\gimelGimel Symbol / Third Transfinite Cardinal
    U+02138\dalethDalet Symbol / Fourth Transfinite Cardinal
    U+02139\:information_source:Information Source
    U+0213C\bbpiDouble-Struck Small Pi
    U+0213D\bbgammaDouble-Struck Small Gamma
    U+0213E\bbGammaDouble-Struck Capital Gamma
    U+0213F\bbPiDouble-Struck Capital Pi
    U+02140\bbsumDouble-Struck N-Ary Summation
    U+02141\GameTurned Sans-Serif Capital G
    U+02142\sansLturnedTurned Sans-Serif Capital L
    U+02143\sansLmirroredReversed Sans-Serif Capital L
    U+02144\YupTurned Sans-Serif Capital Y
    U+02145\bbiDDouble-Struck Italic Capital D
    U+02146\bbidDouble-Struck Italic Small D
    U+02147\bbieDouble-Struck Italic Small E
    U+02148\bbiiDouble-Struck Italic Small I
    U+02149\bbijDouble-Struck Italic Small J
    U+0214A\PropertyLineProperty Line
    U+0214B\upandTurned Ampersand
    U+02150\1/7Vulgar Fraction One Seventh
    U+02151\1/9Vulgar Fraction One Ninth
    U+02152\1/10Vulgar Fraction One Tenth
    U+02153\1/3Vulgar Fraction One Third / Fraction One Third
    U+02154\2/3Vulgar Fraction Two Thirds / Fraction Two Thirds
    U+02155\1/5Vulgar Fraction One Fifth / Fraction One Fifth
    U+02156\2/5Vulgar Fraction Two Fifths / Fraction Two Fifths
    U+02157\3/5Vulgar Fraction Three Fifths / Fraction Three Fifths
    U+02158\4/5Vulgar Fraction Four Fifths / Fraction Four Fifths
    U+02159\1/6Vulgar Fraction One Sixth / Fraction One Sixth
    U+0215A\5/6Vulgar Fraction Five Sixths / Fraction Five Sixths
    U+0215B\1/8Vulgar Fraction One Eighth / Fraction One Eighth
    U+0215C\3/8Vulgar Fraction Three Eighths / Fraction Three Eighths
    U+0215D\5/8Vulgar Fraction Five Eighths / Fraction Five Eighths
    U+0215E\7/8Vulgar Fraction Seven Eighths / Fraction Seven Eighths
    U+0215F\1/Fraction Numerator One
    U+02189\0/3Vulgar Fraction Zero Thirds
    U+02190\leftarrowLeftwards Arrow / Left Arrow
    U+02191\uparrowUpwards Arrow / Up Arrow
    U+02192\to, \rightarrowRightwards Arrow / Right Arrow
    U+02193\downarrowDownwards Arrow / Down Arrow
    U+02194\leftrightarrow, \:left_right_arrow:Left Right Arrow
    U+02195\updownarrow, \:arrow_up_down:Up Down Arrow
    U+02196\nwarrow, \:arrow_upper_left:North West Arrow / Upper Left Arrow
    U+02197\nearrow, \:arrow_upper_right:North East Arrow / Upper Right Arrow
    U+02198\searrow, \:arrow_lower_right:South East Arrow / Lower Right Arrow
    U+02199\swarrow, \:arrow_lower_left:South West Arrow / Lower Left Arrow
    U+0219A\nleftarrowLeftwards Arrow With Stroke / Left Arrow With Stroke
    U+0219B\nrightarrowRightwards Arrow With Stroke / Right Arrow With Stroke
    U+0219C\leftwavearrowLeftwards Wave Arrow / Left Wave Arrow
    U+0219D\rightwavearrowRightwards Wave Arrow / Right Wave Arrow
    U+0219E\twoheadleftarrowLeftwards Two Headed Arrow / Left Two Headed Arrow
    U+0219F\twoheaduparrowUpwards Two Headed Arrow / Up Two Headed Arrow
    U+021A0\twoheadrightarrowRightwards Two Headed Arrow / Right Two Headed Arrow
    U+021A1\twoheaddownarrowDownwards Two Headed Arrow / Down Two Headed Arrow
    U+021A2\leftarrowtailLeftwards Arrow With Tail / Left Arrow With Tail
    U+021A3\rightarrowtailRightwards Arrow With Tail / Right Arrow With Tail
    U+021A4\mapsfromLeftwards Arrow From Bar / Left Arrow From Bar
    U+021A5\mapsupUpwards Arrow From Bar / Up Arrow From Bar
    U+021A6\mapstoRightwards Arrow From Bar / Right Arrow From Bar
    U+021A7\mapsdownDownwards Arrow From Bar / Down Arrow From Bar
    U+021A8\updownarrowbarUp Down Arrow With Base
    U+021A9\hookleftarrow, \:leftwards_arrow_with_hook:Leftwards Arrow With Hook / Left Arrow With Hook
    U+021AA\hookrightarrow, \:arrow_right_hook:Rightwards Arrow With Hook / Right Arrow With Hook
    U+021AB\looparrowleftLeftwards Arrow With Loop / Left Arrow With Loop
    U+021AC\looparrowrightRightwards Arrow With Loop / Right Arrow With Loop
    U+021AD\leftrightsquigarrowLeft Right Wave Arrow
    U+021AE\nleftrightarrowLeft Right Arrow With Stroke
    U+021AF\downzigzagarrowDownwards Zigzag Arrow / Down Zigzag Arrow
    U+021B0\LshUpwards Arrow With Tip Leftwards / Up Arrow With Tip Left
    U+021B1\RshUpwards Arrow With Tip Rightwards / Up Arrow With Tip Right
    U+021B2\LdshDownwards Arrow With Tip Leftwards / Down Arrow With Tip Left
    U+021B3\RdshDownwards Arrow With Tip Rightwards / Down Arrow With Tip Right
    U+021B4\linefeedRightwards Arrow With Corner Downwards / Right Arrow With Corner Down
    U+021B5\carriagereturnDownwards Arrow With Corner Leftwards / Down Arrow With Corner Left
    U+021B6\curvearrowleftAnticlockwise Top Semicircle Arrow
    U+021B7\curvearrowrightClockwise Top Semicircle Arrow
    U+021B8\barovernorthwestarrowNorth West Arrow To Long Bar / Upper Left Arrow To Long Bar
    U+021B9\barleftarrowrightarrowbarLeftwards Arrow To Bar Over Rightwards Arrow To Bar / Left Arrow To Bar Over Right Arrow To Bar
    U+021BA\circlearrowleftAnticlockwise Open Circle Arrow
    U+021BB\circlearrowrightClockwise Open Circle Arrow
    U+021BC\leftharpoonupLeftwards Harpoon With Barb Upwards / Left Harpoon With Barb Up
    U+021BD\leftharpoondownLeftwards Harpoon With Barb Downwards / Left Harpoon With Barb Down
    U+021BE\upharpoonrightUpwards Harpoon With Barb Rightwards / Up Harpoon With Barb Right
    U+021BF\upharpoonleftUpwards Harpoon With Barb Leftwards / Up Harpoon With Barb Left
    U+021C0\rightharpoonupRightwards Harpoon With Barb Upwards / Right Harpoon With Barb Up
    U+021C1\rightharpoondownRightwards Harpoon With Barb Downwards / Right Harpoon With Barb Down
    U+021C2\downharpoonrightDownwards Harpoon With Barb Rightwards / Down Harpoon With Barb Right
    U+021C3\downharpoonleftDownwards Harpoon With Barb Leftwards / Down Harpoon With Barb Left
    U+021C4\rightleftarrowsRightwards Arrow Over Leftwards Arrow / Right Arrow Over Left Arrow
    U+021C5\dblarrowupdownUpwards Arrow Leftwards Of Downwards Arrow / Up Arrow Left Of Down Arrow
    U+021C6\leftrightarrowsLeftwards Arrow Over Rightwards Arrow / Left Arrow Over Right Arrow
    U+021C7\leftleftarrowsLeftwards Paired Arrows / Left Paired Arrows
    U+021C8\upuparrowsUpwards Paired Arrows / Up Paired Arrows
    U+021C9\rightrightarrowsRightwards Paired Arrows / Right Paired Arrows
    U+021CA\downdownarrowsDownwards Paired Arrows / Down Paired Arrows
    U+021CB\leftrightharpoonsLeftwards Harpoon Over Rightwards Harpoon / Left Harpoon Over Right Harpoon
    U+021CC\rightleftharpoonsRightwards Harpoon Over Leftwards Harpoon / Right Harpoon Over Left Harpoon
    U+021CD\nLeftarrowLeftwards Double Arrow With Stroke / Left Double Arrow With Stroke
    U+021CE\nLeftrightarrowLeft Right Double Arrow With Stroke
    U+021CF\nRightarrowRightwards Double Arrow With Stroke / Right Double Arrow With Stroke
    U+021D0\LeftarrowLeftwards Double Arrow / Left Double Arrow
    U+021D1\UparrowUpwards Double Arrow / Up Double Arrow
    U+021D2\RightarrowRightwards Double Arrow / Right Double Arrow
    U+021D3\DownarrowDownwards Double Arrow / Down Double Arrow
    U+021D4\LeftrightarrowLeft Right Double Arrow
    U+021D5\UpdownarrowUp Down Double Arrow
    U+021D6\NwarrowNorth West Double Arrow / Upper Left Double Arrow
    U+021D7\NearrowNorth East Double Arrow / Upper Right Double Arrow
    U+021D8\SearrowSouth East Double Arrow / Lower Right Double Arrow
    U+021D9\SwarrowSouth West Double Arrow / Lower Left Double Arrow
    U+021DA\LleftarrowLeftwards Triple Arrow / Left Triple Arrow
    U+021DB\RrightarrowRightwards Triple Arrow / Right Triple Arrow
    U+021DC\leftsquigarrowLeftwards Squiggle Arrow / Left Squiggle Arrow
    U+021DD\rightsquigarrowRightwards Squiggle Arrow / Right Squiggle Arrow
    U+021DE\nHuparrowUpwards Arrow With Double Stroke / Up Arrow With Double Stroke
    U+021DF\nHdownarrowDownwards Arrow With Double Stroke / Down Arrow With Double Stroke
    U+021E0\leftdasharrowLeftwards Dashed Arrow / Left Dashed Arrow
    U+021E1\updasharrowUpwards Dashed Arrow / Up Dashed Arrow
    U+021E2\rightdasharrowRightwards Dashed Arrow / Right Dashed Arrow
    U+021E3\downdasharrowDownwards Dashed Arrow / Down Dashed Arrow
    U+021E4\barleftarrowLeftwards Arrow To Bar / Left Arrow To Bar
    U+021E5\rightarrowbarRightwards Arrow To Bar / Right Arrow To Bar
    U+021E6\leftwhitearrowLeftwards White Arrow / White Left Arrow
    U+021E7\upwhitearrowUpwards White Arrow / White Up Arrow
    U+021E8\rightwhitearrowRightwards White Arrow / White Right Arrow
    U+021E9\downwhitearrowDownwards White Arrow / White Down Arrow
    U+021EA\whitearrowupfrombarUpwards White Arrow From Bar / White Up Arrow From Bar
    U+021F4\circleonrightarrowRight Arrow With Small Circle
    U+021F5\DownArrowUpArrowDownwards Arrow Leftwards Of Upwards Arrow
    U+021F6\rightthreearrowsThree Rightwards Arrows
    U+021F7\nvleftarrowLeftwards Arrow With Vertical Stroke
    U+021F8\nvrightarrowRightwards Arrow With Vertical Stroke
    U+021F9\nvleftrightarrowLeft Right Arrow With Vertical Stroke
    U+021FA\nVleftarrowLeftwards Arrow With Double Vertical Stroke
    U+021FB\nVrightarrowRightwards Arrow With Double Vertical Stroke
    U+021FC\nVleftrightarrowLeft Right Arrow With Double Vertical Stroke
    U+021FD\leftarrowtriangleLeftwards Open-Headed Arrow
    U+021FE\rightarrowtriangleRightwards Open-Headed Arrow
    U+021FF\leftrightarrowtriangleLeft Right Open-Headed Arrow
    U+02200\forallFor All
    U+02201\complementComplement
    U+02202\partialPartial Differential
    U+02203\existsThere Exists
    U+02204\nexistsThere Does Not Exist
    U+02205\varnothing, \emptysetEmpty Set
    U+02206\incrementIncrement
    U+02207\del, \nablaNabla
    U+02208\inElement Of
    U+02209\notinNot An Element Of
    U+0220A\smallinSmall Element Of
    U+0220B\niContains As Member
    U+0220C\nniDoes Not Contain As Member
    U+0220D\smallniSmall Contains As Member
    U+0220E\QEDEnd Of Proof
    U+0220F\prodN-Ary Product
    U+02210\coprodN-Ary Coproduct
    U+02211\sumN-Ary Summation
    U+02212\minusMinus Sign
    U+02213\mpMinus-Or-Plus Sign
    U+02214\dotplusDot Plus
    U+02216\setminusSet Minus
    U+02217\astAsterisk Operator
    U+02218\circRing Operator
    U+02219\vysmblkcircleBullet Operator
    U+0221A\surd, \sqrtSquare Root
    U+0221B\cbrtCube Root
    U+0221C\fourthrootFourth Root
    U+0221D\proptoProportional To
    U+0221E\inftyInfinity
    U+0221F\rightangleRight Angle
    U+02220\angleAngle
    U+02221\measuredangleMeasured Angle
    U+02222\sphericalangleSpherical Angle
    U+02223\midDivides
    U+02224\nmidDoes Not Divide
    U+02225\parallelParallel To
    U+02226\nparallelNot Parallel To
    U+02227\wedgeLogical And
    U+02228\veeLogical Or
    U+02229\capIntersection
    U+0222A\cupUnion
    U+0222B\intIntegral
    U+0222C\iintDouble Integral
    U+0222D\iiintTriple Integral
    U+0222E\ointContour Integral
    U+0222F\oiintSurface Integral
    U+02230\oiiintVolume Integral
    U+02231\clwintegralClockwise Integral
    U+02232\varointclockwiseClockwise Contour Integral
    U+02233\ointctrclockwiseAnticlockwise Contour Integral
    U+02234\thereforeTherefore
    U+02235\becauseBecause
    U+02237\ColonProportion
    U+02238\dotminusDot Minus
    U+0223A\dotsminusdotsGeometric Proportion
    U+0223B\kernelcontractionHomothetic
    U+0223C\simTilde Operator
    U+0223D\backsimReversed Tilde
    U+0223E\lazysinvInverted Lazy S
    U+0223F\sinewaveSine Wave
    U+02240\wrWreath Product
    U+02241\nsimNot Tilde
    U+02242\eqsimMinus Tilde
    U+02242 + U+00338≂̸\neqsimMinus Tilde + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02243\simeqAsymptotically Equal To
    U+02244\nsimeNot Asymptotically Equal To
    U+02245\congApproximately Equal To
    U+02246\approxnotequalApproximately But Not Actually Equal To
    U+02247\ncongNeither Approximately Nor Actually Equal To
    U+02248\approxAlmost Equal To
    U+02249\napproxNot Almost Equal To
    U+0224A\approxeqAlmost Equal Or Equal To
    U+0224B\tildetrplTriple Tilde
    U+0224C\allequalAll Equal To
    U+0224D\asympEquivalent To
    U+0224E\BumpeqGeometrically Equivalent To
    U+0224E + U+00338≎̸\nBumpeqGeometrically Equivalent To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0224F\bumpeqDifference Between
    U+0224F + U+00338≏̸\nbumpeqDifference Between + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02250\doteqApproaches The Limit
    U+02251\DoteqGeometrically Equal To
    U+02252\fallingdotseqApproximately Equal To Or The Image Of
    U+02253\risingdotseqImage Of Or Approximately Equal To
    U+02254\coloneqColon Equals / Colon Equal
    U+02255\eqcolonEquals Colon / Equal Colon
    U+02256\eqcircRing In Equal To
    U+02257\circeqRing Equal To
    U+02258\arceqCorresponds To
    U+02259\wedgeqEstimates
    U+0225A\veeeqEquiangular To
    U+0225B\starequalStar Equals
    U+0225C\triangleqDelta Equal To
    U+0225D\eqdefEqual To By Definition
    U+0225E\measeqMeasured By
    U+0225F\questeqQuestioned Equal To
    U+02260\ne, \neqNot Equal To
    U+02261\equivIdentical To
    U+02262\nequivNot Identical To
    U+02263\EquivStrictly Equivalent To
    U+02264\le, \leqLess-Than Or Equal To / Less Than Or Equal To
    U+02265\ge, \geqGreater-Than Or Equal To / Greater Than Or Equal To
    U+02266\leqqLess-Than Over Equal To / Less Than Over Equal To
    U+02267\geqqGreater-Than Over Equal To / Greater Than Over Equal To
    U+02268\lneqqLess-Than But Not Equal To / Less Than But Not Equal To
    U+02268 + U+0FE00≨︀\lvertneqqLess-Than But Not Equal To / Less Than But Not Equal To + Variation Selector-1
    U+02269\gneqqGreater-Than But Not Equal To / Greater Than But Not Equal To
    U+02269 + U+0FE00≩︀\gvertneqqGreater-Than But Not Equal To / Greater Than But Not Equal To + Variation Selector-1
    U+0226A\llMuch Less-Than / Much Less Than
    U+0226A + U+00338≪̸\NotLessLessMuch Less-Than / Much Less Than + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0226B\ggMuch Greater-Than / Much Greater Than
    U+0226B + U+00338≫̸\NotGreaterGreaterMuch Greater-Than / Much Greater Than + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0226C\betweenBetween
    U+0226D\nasympNot Equivalent To
    U+0226E\nlessNot Less-Than / Not Less Than
    U+0226F\ngtrNot Greater-Than / Not Greater Than
    U+02270\nleqNeither Less-Than Nor Equal To / Neither Less Than Nor Equal To
    U+02271\ngeqNeither Greater-Than Nor Equal To / Neither Greater Than Nor Equal To
    U+02272\lesssimLess-Than Or Equivalent To / Less Than Or Equivalent To
    U+02273\gtrsimGreater-Than Or Equivalent To / Greater Than Or Equivalent To
    U+02274\nlesssimNeither Less-Than Nor Equivalent To / Neither Less Than Nor Equivalent To
    U+02275\ngtrsimNeither Greater-Than Nor Equivalent To / Neither Greater Than Nor Equivalent To
    U+02276\lessgtrLess-Than Or Greater-Than / Less Than Or Greater Than
    U+02277\gtrlessGreater-Than Or Less-Than / Greater Than Or Less Than
    U+02278\notlessgreaterNeither Less-Than Nor Greater-Than / Neither Less Than Nor Greater Than
    U+02279\notgreaterlessNeither Greater-Than Nor Less-Than / Neither Greater Than Nor Less Than
    U+0227A\precPrecedes
    U+0227B\succSucceeds
    U+0227C\preccurlyeqPrecedes Or Equal To
    U+0227D\succcurlyeqSucceeds Or Equal To
    U+0227E\precsimPrecedes Or Equivalent To
    U+0227E + U+00338≾̸\nprecsimPrecedes Or Equivalent To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+0227F\succsimSucceeds Or Equivalent To
    U+0227F + U+00338≿̸\nsuccsimSucceeds Or Equivalent To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02280\nprecDoes Not Precede
    U+02281\nsuccDoes Not Succeed
    U+02282\subsetSubset Of
    U+02283\supsetSuperset Of
    U+02284\nsubsetNot A Subset Of
    U+02285\nsupsetNot A Superset Of
    U+02286\subseteqSubset Of Or Equal To
    U+02287\supseteqSuperset Of Or Equal To
    U+02288\nsubseteqNeither A Subset Of Nor Equal To
    U+02289\nsupseteqNeither A Superset Of Nor Equal To
    U+0228A\subsetneqSubset Of With Not Equal To / Subset Of Or Not Equal To
    U+0228A + U+0FE00⊊︀\varsubsetneqqSubset Of With Not Equal To / Subset Of Or Not Equal To + Variation Selector-1
    U+0228B\supsetneqSuperset Of With Not Equal To / Superset Of Or Not Equal To
    U+0228B + U+0FE00⊋︀\varsupsetneqSuperset Of With Not Equal To / Superset Of Or Not Equal To + Variation Selector-1
    U+0228D\cupdotMultiset Multiplication
    U+0228E\uplusMultiset Union
    U+0228F\sqsubsetSquare Image Of
    U+0228F + U+00338⊏̸\NotSquareSubsetSquare Image Of + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02290\sqsupsetSquare Original Of
    U+02290 + U+00338⊐̸\NotSquareSupersetSquare Original Of + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02291\sqsubseteqSquare Image Of Or Equal To
    U+02292\sqsupseteqSquare Original Of Or Equal To
    U+02293\sqcapSquare Cap
    U+02294\sqcupSquare Cup
    U+02295\oplusCircled Plus
    U+02296\ominusCircled Minus
    U+02297\otimesCircled Times
    U+02298\oslashCircled Division Slash
    U+02299\odotCircled Dot Operator
    U+0229A\circledcircCircled Ring Operator
    U+0229B\circledastCircled Asterisk Operator
    U+0229C\circledequalCircled Equals
    U+0229D\circleddashCircled Dash
    U+0229E\boxplusSquared Plus
    U+0229F\boxminusSquared Minus
    U+022A0\boxtimesSquared Times
    U+022A1\boxdotSquared Dot Operator
    U+022A2\vdashRight Tack
    U+022A3\dashvLeft Tack
    U+022A4\topDown Tack
    U+022A5\botUp Tack
    U+022A7\modelsModels
    U+022A8\vDashTrue
    U+022A9\VdashForces
    U+022AA\VvdashTriple Vertical Bar Right Turnstile
    U+022AB\VDashDouble Vertical Bar Double Right Turnstile
    U+022AC\nvdashDoes Not Prove
    U+022AD\nvDashNot True
    U+022AE\nVdashDoes Not Force
    U+022AF\nVDashNegated Double Vertical Bar Double Right Turnstile
    U+022B0\prurelPrecedes Under Relation
    U+022B1\scurelSucceeds Under Relation
    U+022B2\vartriangleleftNormal Subgroup Of
    U+022B3\vartrianglerightContains As Normal Subgroup
    U+022B4\trianglelefteqNormal Subgroup Of Or Equal To
    U+022B5\trianglerighteqContains As Normal Subgroup Or Equal To
    U+022B6\originalOriginal Of
    U+022B7\imageImage Of
    U+022B8\multimapMultimap
    U+022B9\hermitconjmatrixHermitian Conjugate Matrix
    U+022BA\intercalIntercalate
    U+022BB\veebar, \xorXor
    U+022BC\barwedge, \nandNand
    U+022BD\barvee, \norNor
    U+022BE\rightanglearcRight Angle With Arc
    U+022BF\varlrtriangleRight Triangle
    U+022C0\bigwedgeN-Ary Logical And
    U+022C1\bigveeN-Ary Logical Or
    U+022C2\bigcapN-Ary Intersection
    U+022C3\bigcupN-Ary Union
    U+022C4\diamondDiamond Operator
    U+022C5\cdotDot Operator
    U+022C6\starStar Operator
    U+022C7\divideontimesDivision Times
    U+022C8\bowtieBowtie
    U+022C9\ltimesLeft Normal Factor Semidirect Product
    U+022CA\rtimesRight Normal Factor Semidirect Product
    U+022CB\leftthreetimesLeft Semidirect Product
    U+022CC\rightthreetimesRight Semidirect Product
    U+022CD\backsimeqReversed Tilde Equals
    U+022CE\curlyveeCurly Logical Or
    U+022CF\curlywedgeCurly Logical And
    U+022D0\SubsetDouble Subset
    U+022D1\SupsetDouble Superset
    U+022D2\CapDouble Intersection
    U+022D3\CupDouble Union
    U+022D4\pitchforkPitchfork
    U+022D5\equalparallelEqual And Parallel To
    U+022D6\lessdotLess-Than With Dot / Less Than With Dot
    U+022D7\gtrdotGreater-Than With Dot / Greater Than With Dot
    U+022D8\verymuchlessVery Much Less-Than / Very Much Less Than
    U+022D9\gggVery Much Greater-Than / Very Much Greater Than
    U+022DA\lesseqgtrLess-Than Equal To Or Greater-Than / Less Than Equal To Or Greater Than
    U+022DB\gtreqlessGreater-Than Equal To Or Less-Than / Greater Than Equal To Or Less Than
    U+022DC\eqlessEqual To Or Less-Than / Equal To Or Less Than
    U+022DD\eqgtrEqual To Or Greater-Than / Equal To Or Greater Than
    U+022DE\curlyeqprecEqual To Or Precedes
    U+022DF\curlyeqsuccEqual To Or Succeeds
    U+022E0\npreccurlyeqDoes Not Precede Or Equal
    U+022E1\nsucccurlyeqDoes Not Succeed Or Equal
    U+022E2\nsqsubseteqNot Square Image Of Or Equal To
    U+022E3\nsqsupseteqNot Square Original Of Or Equal To
    U+022E4\sqsubsetneqSquare Image Of Or Not Equal To
    U+022E5\sqsupsetneqSquare Original Of Or Not Equal To
    U+022E6\lnsimLess-Than But Not Equivalent To / Less Than But Not Equivalent To
    U+022E7\gnsimGreater-Than But Not Equivalent To / Greater Than But Not Equivalent To
    U+022E8\precnsimPrecedes But Not Equivalent To
    U+022E9\succnsimSucceeds But Not Equivalent To
    U+022EA\ntriangleleftNot Normal Subgroup Of
    U+022EB\ntrianglerightDoes Not Contain As Normal Subgroup
    U+022EC\ntrianglelefteqNot Normal Subgroup Of Or Equal To
    U+022ED\ntrianglerighteqDoes Not Contain As Normal Subgroup Or Equal
    U+022EE\vdotsVertical Ellipsis
    U+022EF\cdotsMidline Horizontal Ellipsis
    U+022F0\adotsUp Right Diagonal Ellipsis
    U+022F1\ddotsDown Right Diagonal Ellipsis
    U+022F2\disinElement Of With Long Horizontal Stroke
    U+022F3\varisinsElement Of With Vertical Bar At End Of Horizontal Stroke
    U+022F4\isinsSmall Element Of With Vertical Bar At End Of Horizontal Stroke
    U+022F5\isindotElement Of With Dot Above
    U+022F6\varisinobarElement Of With Overbar
    U+022F7\isinobarSmall Element Of With Overbar
    U+022F8\isinvbElement Of With Underbar
    U+022F9\isinEElement Of With Two Horizontal Strokes
    U+022FA\nisdContains With Long Horizontal Stroke
    U+022FB\varnisContains With Vertical Bar At End Of Horizontal Stroke
    U+022FC\nisSmall Contains With Vertical Bar At End Of Horizontal Stroke
    U+022FD\varniobarContains With Overbar
    U+022FE\niobarSmall Contains With Overbar
    U+022FF\bagmemberZ Notation Bag Membership
    U+02300\diameterDiameter Sign
    U+02302\houseHouse
    U+02305\varbarwedgeProjective
    U+02306\vardoublebarwedgePerspective
    U+02308\lceilLeft Ceiling
    U+02309\rceilRight Ceiling
    U+0230A\lfloorLeft Floor
    U+0230B\rfloorRight Floor
    U+02310\invnotReversed Not Sign
    U+02311\sqlozengeSquare Lozenge
    U+02312\proflineArc
    U+02313\profsurfSegment
    U+02315\recorderTelephone Recorder
    U+02317\viewdataViewdata Square
    U+02319\turnednotTurned Not Sign
    U+0231A\:watch:Watch
    U+0231B\:hourglass:Hourglass
    U+0231C\ulcornerTop Left Corner
    U+0231D\urcornerTop Right Corner
    U+0231E\llcornerBottom Left Corner
    U+0231F\lrcornerBottom Right Corner
    U+02322\frownFrown
    U+02323\smileSmile
    U+0232C\varhexagonlrbondsBenzene Ring
    U+02332\conictaperConical Taper
    U+02336\topbotApl Functional Symbol I-Beam
    U+0233D\obarApl Functional Symbol Circle Stile
    U+0233F\notslashApl Functional Symbol Slash Bar
    U+02340\notbackslashApl Functional Symbol Backslash Bar
    U+02353\boxupcaretApl Functional Symbol Quad Up Caret
    U+02370\boxquestionApl Functional Symbol Quad Question
    U+02394\hexagonSoftware-Function Symbol
    U+023A3\dlcornLeft Square Bracket Lower Corner
    U+023B0\lmoustacheUpper Left Or Lower Right Curly Bracket Section
    U+023B1\rmoustacheUpper Right Or Lower Left Curly Bracket Section
    U+023B4\overbracketTop Square Bracket
    U+023B5\underbracketBottom Square Bracket
    U+023B6\bbrktbrkBottom Square Bracket Over Top Square Bracket
    U+023B7\sqrtbottomRadical Symbol Bottom
    U+023B8\lvboxlineLeft Vertical Box Line
    U+023B9\rvboxlineRight Vertical Box Line
    U+023CE\varcarriagereturnReturn Symbol
    U+023DE\overbraceTop Curly Bracket
    U+023DF\underbraceBottom Curly Bracket
    U+023E2\trapeziumWhite Trapezium
    U+023E3\benzenrBenzene Ring With Circle
    U+023E4\strnsStraightness
    U+023E5\fltnsFlatness
    U+023E6\accurrentAc Current
    U+023E7\elintersElectrical Intersection
    U+023E9\:fast_forward:Black Right-Pointing Double Triangle
    U+023EA\:rewind:Black Left-Pointing Double Triangle
    U+023EB\:arrow_double_up:Black Up-Pointing Double Triangle
    U+023EC\:arrow_double_down:Black Down-Pointing Double Triangle
    U+023F0\:alarm_clock:Alarm Clock
    U+023F3\:hourglass_flowing_sand:Hourglass With Flowing Sand
    U+02422\blanksymbolBlank Symbol / Blank
    U+02423\visiblespaceOpen Box
    U+024C2\:m:Circled Latin Capital Letter M
    U+024C8\circledSCircled Latin Capital Letter S
    U+02506\dshfncBox Drawings Light Triple Dash Vertical / Forms Light Triple Dash Vertical
    U+02519\sqfnwBox Drawings Up Light And Left Heavy / Forms Up Light And Left Heavy
    U+02571\diagupBox Drawings Light Diagonal Upper Right To Lower Left / Forms Light Diagonal Upper Right To Lower Left
    U+02572\diagdownBox Drawings Light Diagonal Upper Left To Lower Right / Forms Light Diagonal Upper Left To Lower Right
    U+02580\blockuphalfUpper Half Block
    U+02584\blocklowhalfLower Half Block
    U+02588\blockfullFull Block
    U+0258C\blocklefthalfLeft Half Block
    U+02590\blockrighthalfRight Half Block
    U+02591\blockqtrshadedLight Shade
    U+02592\blockhalfshadedMedium Shade
    U+02593\blockthreeqtrshadedDark Shade
    U+025A0\blacksquareBlack Square
    U+025A1\squareWhite Square
    U+025A2\squovalWhite Square With Rounded Corners
    U+025A3\blackinwhitesquareWhite Square Containing Black Small Square
    U+025A4\squarehfillSquare With Horizontal Fill
    U+025A5\squarevfillSquare With Vertical Fill
    U+025A6\squarehvfillSquare With Orthogonal Crosshatch Fill
    U+025A7\squarenwsefillSquare With Upper Left To Lower Right Fill
    U+025A8\squareneswfillSquare With Upper Right To Lower Left Fill
    U+025A9\squarecrossfillSquare With Diagonal Crosshatch Fill
    U+025AA\smblksquare, \:black_small_square:Black Small Square
    U+025AB\smwhtsquare, \:white_small_square:White Small Square
    U+025AC\hrectangleblackBlack Rectangle
    U+025AD\hrectangleWhite Rectangle
    U+025AE\vrectangleblackBlack Vertical Rectangle
    U+025AF\vrectoWhite Vertical Rectangle
    U+025B0\parallelogramblackBlack Parallelogram
    U+025B1\parallelogramWhite Parallelogram
    U+025B2\bigblacktriangleupBlack Up-Pointing Triangle / Black Up Pointing Triangle
    U+025B3\bigtriangleupWhite Up-Pointing Triangle / White Up Pointing Triangle
    U+025B4\blacktriangleBlack Up-Pointing Small Triangle / Black Up Pointing Small Triangle
    U+025B5\vartriangleWhite Up-Pointing Small Triangle / White Up Pointing Small Triangle
    U+025B6\blacktriangleright, \:arrow_forward:Black Right-Pointing Triangle / Black Right Pointing Triangle
    U+025B7\trianglerightWhite Right-Pointing Triangle / White Right Pointing Triangle
    U+025B8\smallblacktrianglerightBlack Right-Pointing Small Triangle / Black Right Pointing Small Triangle
    U+025B9\smalltrianglerightWhite Right-Pointing Small Triangle / White Right Pointing Small Triangle
    U+025BA\blackpointerrightBlack Right-Pointing Pointer / Black Right Pointing Pointer
    U+025BB\whitepointerrightWhite Right-Pointing Pointer / White Right Pointing Pointer
    U+025BC\bigblacktriangledownBlack Down-Pointing Triangle / Black Down Pointing Triangle
    U+025BD\bigtriangledownWhite Down-Pointing Triangle / White Down Pointing Triangle
    U+025BE\blacktriangledownBlack Down-Pointing Small Triangle / Black Down Pointing Small Triangle
    U+025BF\triangledownWhite Down-Pointing Small Triangle / White Down Pointing Small Triangle
    U+025C0\blacktriangleleft, \:arrow_backward:Black Left-Pointing Triangle / Black Left Pointing Triangle
    U+025C1\triangleleftWhite Left-Pointing Triangle / White Left Pointing Triangle
    U+025C2\smallblacktriangleleftBlack Left-Pointing Small Triangle / Black Left Pointing Small Triangle
    U+025C3\smalltriangleleftWhite Left-Pointing Small Triangle / White Left Pointing Small Triangle
    U+025C4\blackpointerleftBlack Left-Pointing Pointer / Black Left Pointing Pointer
    U+025C5\whitepointerleftWhite Left-Pointing Pointer / White Left Pointing Pointer
    U+025C6\mdlgblkdiamondBlack Diamond
    U+025C7\mdlgwhtdiamondWhite Diamond
    U+025C8\blackinwhitediamondWhite Diamond Containing Black Small Diamond
    U+025C9\fisheyeFisheye
    U+025CA\lozengeLozenge
    U+025CB\bigcircWhite Circle
    U+025CC\dottedcircleDotted Circle
    U+025CD\circlevertfillCircle With Vertical Fill
    U+025CE\bullseyeBullseye
    U+025CF\mdlgblkcircleBlack Circle
    U+025D0\cirflCircle With Left Half Black
    U+025D1\cirfrCircle With Right Half Black
    U+025D2\cirfbCircle With Lower Half Black
    U+025D3\circletophalfblackCircle With Upper Half Black
    U+025D4\circleurquadblackCircle With Upper Right Quadrant Black
    U+025D5\blackcircleulquadwhiteCircle With All But Upper Left Quadrant Black
    U+025D6\blacklefthalfcircleLeft Half Black Circle
    U+025D7\blackrighthalfcircleRight Half Black Circle
    U+025D8\rvbullInverse Bullet
    U+025D9\inversewhitecircleInverse White Circle
    U+025DA\invwhiteupperhalfcircleUpper Half Inverse White Circle
    U+025DB\invwhitelowerhalfcircleLower Half Inverse White Circle
    U+025DC\ularcUpper Left Quadrant Circular Arc
    U+025DD\urarcUpper Right Quadrant Circular Arc
    U+025DE\lrarcLower Right Quadrant Circular Arc
    U+025DF\llarcLower Left Quadrant Circular Arc
    U+025E0\topsemicircleUpper Half Circle
    U+025E1\botsemicircleLower Half Circle
    U+025E2\lrblacktriangleBlack Lower Right Triangle
    U+025E3\llblacktriangleBlack Lower Left Triangle
    U+025E4\ulblacktriangleBlack Upper Left Triangle
    U+025E5\urblacktriangleBlack Upper Right Triangle
    U+025E6\smwhtcircleWhite Bullet
    U+025E7\sqflSquare With Left Half Black
    U+025E8\sqfrSquare With Right Half Black
    U+025E9\squareulblackSquare With Upper Left Diagonal Half Black
    U+025EA\sqfseSquare With Lower Right Diagonal Half Black
    U+025EB\boxbarWhite Square With Vertical Bisecting Line
    U+025EC\trianglecdotWhite Up-Pointing Triangle With Dot / White Up Pointing Triangle With Dot
    U+025ED\triangleleftblackUp-Pointing Triangle With Left Half Black / Up Pointing Triangle With Left Half Black
    U+025EE\trianglerightblackUp-Pointing Triangle With Right Half Black / Up Pointing Triangle With Right Half Black
    U+025EF\lgwhtcircleLarge Circle
    U+025F0\squareulquadWhite Square With Upper Left Quadrant
    U+025F1\squarellquadWhite Square With Lower Left Quadrant
    U+025F2\squarelrquadWhite Square With Lower Right Quadrant
    U+025F3\squareurquadWhite Square With Upper Right Quadrant
    U+025F4\circleulquadWhite Circle With Upper Left Quadrant
    U+025F5\circlellquadWhite Circle With Lower Left Quadrant
    U+025F6\circlelrquadWhite Circle With Lower Right Quadrant
    U+025F7\circleurquadWhite Circle With Upper Right Quadrant
    U+025F8\ultriangleUpper Left Triangle
    U+025F9\urtriangleUpper Right Triangle
    U+025FA\lltriangleLower Left Triangle
    U+025FB\mdwhtsquare, \:white_medium_square:White Medium Square
    U+025FC\mdblksquare, \:black_medium_square:Black Medium Square
    U+025FD\mdsmwhtsquare, \:white_medium_small_square:White Medium Small Square
    U+025FE\mdsmblksquare, \:black_medium_small_square:Black Medium Small Square
    U+025FF\lrtriangleLower Right Triangle
    U+02600\:sunny:Black Sun With Rays
    U+02601\:cloud:Cloud
    U+02605\bigstarBlack Star
    U+02606\bigwhitestarWhite Star
    U+02609\astrosunSun
    U+0260E\:phone:Black Telephone
    U+02611\:ballot_box_with_check:Ballot Box With Check
    U+02614\:umbrella_with_rain_drops:, \:umbrella:Umbrella With Rain Drops
    U+02615\:coffee:Hot Beverage
    U+0261D\:point_up:White Up Pointing Index
    U+02621\dangerCaution Sign
    U+0263A\:relaxed:White Smiling Face
    U+0263B\blacksmileyBlack Smiling Face
    U+0263C\sunWhite Sun With Rays
    U+0263D\rightmoonFirst Quarter Moon
    U+0263E\leftmoonLast Quarter Moon
    U+0263F\mercuryMercury
    U+02640\venus, \femaleFemale Sign
    U+02642\male, \marsMale Sign
    U+02643\jupiterJupiter
    U+02644\saturnSaturn
    U+02645\uranusUranus
    U+02646\neptuneNeptune
    U+02647\plutoPluto
    U+02648\aries, \:aries:Aries
    U+02649\taurus, \:taurus:Taurus
    U+0264A\gemini, \:gemini:Gemini
    U+0264B\cancer, \:cancer:Cancer
    U+0264C\leo, \:leo:Leo
    U+0264D\virgo, \:virgo:Virgo
    U+0264E\libra, \:libra:Libra
    U+0264F\scorpio, \:scorpius:Scorpius
    U+02650\sagittarius, \:sagittarius:Sagittarius
    U+02651\capricornus, \:capricorn:Capricorn
    U+02652\aquarius, \:aquarius:Aquarius
    U+02653\pisces, \:pisces:Pisces
    U+02660\spadesuit, \:spades:Black Spade Suit
    U+02661\heartsuitWhite Heart Suit
    U+02662\diamondsuitWhite Diamond Suit
    U+02663\clubsuit, \:clubs:Black Club Suit
    U+02664\varspadesuitWhite Spade Suit
    U+02665\varheartsuit, \:hearts:Black Heart Suit
    U+02666\vardiamondsuit, \:diamonds:Black Diamond Suit
    U+02667\varclubsuitWhite Club Suit
    U+02668\:hotsprings:Hot Springs
    U+02669\quarternoteQuarter Note
    U+0266A\eighthnoteEighth Note
    U+0266B\twonotesBeamed Eighth Notes / Barred Eighth Notes
    U+0266D\flatMusic Flat Sign / Flat
    U+0266E\naturalMusic Natural Sign / Natural
    U+0266F\sharpMusic Sharp Sign / Sharp
    U+0267B\:recycle:Black Universal Recycling Symbol
    U+0267E\acidfreePermanent Paper Sign
    U+0267F\:wheelchair:Wheelchair Symbol
    U+02680\diceiDie Face-1
    U+02681\diceiiDie Face-2
    U+02682\diceiiiDie Face-3
    U+02683\diceivDie Face-4
    U+02684\dicevDie Face-5
    U+02685\diceviDie Face-6
    U+02686\circledrightdotWhite Circle With Dot Right
    U+02687\circledtwodotsWhite Circle With Two Dots
    U+02688\blackcircledrightdotBlack Circle With White Dot Right
    U+02689\blackcircledtwodotsBlack Circle With Two White Dots
    U+02693\:anchor:Anchor
    U+026A0\:warning:Warning Sign
    U+026A1\:zap:High Voltage Sign
    U+026A5\hermaphroditeMale And Female Sign
    U+026AA\mdwhtcircle, \:white_circle:Medium White Circle
    U+026AB\mdblkcircle, \:black_circle:Medium Black Circle
    U+026AC\mdsmwhtcircleMedium Small White Circle
    U+026B2\neuterNeuter
    U+026BD\:soccer:Soccer Ball
    U+026BE\:baseball:Baseball
    U+026C4\:snowman:, \:snowman_without_snow:Snowman Without Snow
    U+026C5\:partly_sunny:Sun Behind Cloud
    U+026CE\:ophiuchus:Ophiuchus
    U+026D4\:no_entry:No Entry
    U+026EA\:church:Church
    U+026F2\:fountain:Fountain
    U+026F3\:golf:Flag In Hole
    U+026F5\:boat:Sailboat
    U+026FA\:tent:Tent
    U+026FD\:fuelpump:Fuel Pump
    U+02702\:scissors:Black Scissors
    U+02705\:white_check_mark:White Heavy Check Mark
    U+02708\:airplane:Airplane
    U+02709\:email:Envelope
    U+0270A\:fist:Raised Fist
    U+0270B\:hand:Raised Hand
    U+0270C\:v:Victory Hand
    U+0270F\:pencil2:Pencil
    U+02712\:black_nib:Black Nib
    U+02713\checkmarkCheck Mark
    U+02714\:heavy_check_mark:Heavy Check Mark
    U+02716\:heavy_multiplication_x:Heavy Multiplication X
    U+02720\malteseMaltese Cross
    U+02728\:sparkles:Sparkles
    U+0272A\circledstarCircled White Star
    U+02733\:eight_spoked_asterisk:Eight Spoked Asterisk
    U+02734\:eight_pointed_black_star:Eight Pointed Black Star
    U+02736\varstarSix Pointed Black Star
    U+0273D\dingasteriskHeavy Teardrop-Spoked Asterisk
    U+02744\:snowflake:Snowflake
    U+02747\:sparkle:Sparkle
    U+0274C\:x:Cross Mark
    U+0274E\:negative_squared_cross_mark:Negative Squared Cross Mark
    U+02753\:question:Black Question Mark Ornament
    U+02754\:grey_question:White Question Mark Ornament
    U+02755\:grey_exclamation:White Exclamation Mark Ornament
    U+02757\:exclamation:Heavy Exclamation Mark Symbol
    U+02764\:heart:Heavy Black Heart
    U+02795\:heavy_plus_sign:Heavy Plus Sign
    U+02796\:heavy_minus_sign:Heavy Minus Sign
    U+02797\:heavy_division_sign:Heavy Division Sign
    U+0279B\draftingarrowDrafting Point Rightwards Arrow / Drafting Point Right Arrow
    U+027A1\:arrow_right:Black Rightwards Arrow / Black Right Arrow
    U+027B0\:curly_loop:Curly Loop
    U+027BF\:loop:Double Curly Loop
    U+027C0\threedangleThree Dimensional Angle
    U+027C1\whiteinwhitetriangleWhite Triangle Containing Small White Triangle
    U+027C2\perpPerpendicular
    U+027C7\veedotOr With Dot Inside
    U+027C8\bsolhsubReverse Solidus Preceding Subset
    U+027C9\suphsolSuperset Preceding Solidus
    U+027D1\wedgedotAnd With Dot
    U+027D2\upinElement Of Opening Upwards
    U+027D5\leftouterjoinLeft Outer Join
    U+027D6\rightouterjoinRight Outer Join
    U+027D7\fullouterjoinFull Outer Join
    U+027D8\bigbotLarge Up Tack
    U+027D9\bigtopLarge Down Tack
    U+027E6\llbracket, \openbracketleftMathematical Left White Square Bracket
    U+027E7\openbracketright, \rrbracketMathematical Right White Square Bracket
    U+027E8\langleMathematical Left Angle Bracket
    U+027E9\rangleMathematical Right Angle Bracket
    U+027F0\UUparrowUpwards Quadruple Arrow
    U+027F1\DDownarrowDownwards Quadruple Arrow
    U+027F5\longleftarrowLong Leftwards Arrow
    U+027F6\longrightarrowLong Rightwards Arrow
    U+027F7\longleftrightarrowLong Left Right Arrow
    U+027F8\impliedby, \LongleftarrowLong Leftwards Double Arrow
    U+027F9\implies, \LongrightarrowLong Rightwards Double Arrow
    U+027FA\Longleftrightarrow, \iffLong Left Right Double Arrow
    U+027FB\longmapsfromLong Leftwards Arrow From Bar
    U+027FC\longmapstoLong Rightwards Arrow From Bar
    U+027FD\LongmapsfromLong Leftwards Double Arrow From Bar
    U+027FE\LongmapstoLong Rightwards Double Arrow From Bar
    U+027FF\longrightsquigarrowLong Rightwards Squiggle Arrow
    U+02900\nvtwoheadrightarrowRightwards Two-Headed Arrow With Vertical Stroke
    U+02901\nVtwoheadrightarrowRightwards Two-Headed Arrow With Double Vertical Stroke
    U+02902\nvLeftarrowLeftwards Double Arrow With Vertical Stroke
    U+02903\nvRightarrowRightwards Double Arrow With Vertical Stroke
    U+02904\nvLeftrightarrowLeft Right Double Arrow With Vertical Stroke
    U+02905\twoheadmapstoRightwards Two-Headed Arrow From Bar
    U+02906\MapsfromLeftwards Double Arrow From Bar
    U+02907\MapstoRightwards Double Arrow From Bar
    U+02908\downarrowbarredDownwards Arrow With Horizontal Stroke
    U+02909\uparrowbarredUpwards Arrow With Horizontal Stroke
    U+0290A\UuparrowUpwards Triple Arrow
    U+0290B\DdownarrowDownwards Triple Arrow
    U+0290C\leftbkarrowLeftwards Double Dash Arrow
    U+0290D\bkarowRightwards Double Dash Arrow
    U+0290E\leftdbkarrowLeftwards Triple Dash Arrow
    U+0290F\dbkarowRightwards Triple Dash Arrow
    U+02910\drbkarrowRightwards Two-Headed Triple Dash Arrow
    U+02911\rightdotarrowRightwards Arrow With Dotted Stem
    U+02912\UpArrowBarUpwards Arrow To Bar
    U+02913\DownArrowBarDownwards Arrow To Bar
    U+02914\nvrightarrowtailRightwards Arrow With Tail With Vertical Stroke
    U+02915\nVrightarrowtailRightwards Arrow With Tail With Double Vertical Stroke
    U+02916\twoheadrightarrowtailRightwards Two-Headed Arrow With Tail
    U+02917\nvtwoheadrightarrowtailRightwards Two-Headed Arrow With Tail With Vertical Stroke
    U+02918\nVtwoheadrightarrowtailRightwards Two-Headed Arrow With Tail With Double Vertical Stroke
    U+0291D\diamondleftarrowLeftwards Arrow To Black Diamond
    U+0291E\rightarrowdiamondRightwards Arrow To Black Diamond
    U+0291F\diamondleftarrowbarLeftwards Arrow From Bar To Black Diamond
    U+02920\barrightarrowdiamondRightwards Arrow From Bar To Black Diamond
    U+02925\hksearowSouth East Arrow With Hook
    U+02926\hkswarowSouth West Arrow With Hook
    U+02927\tonaNorth West Arrow And North East Arrow
    U+02928\toeaNorth East Arrow And South East Arrow
    U+02929\tosaSouth East Arrow And South West Arrow
    U+0292A\towaSouth West Arrow And North West Arrow
    U+0292B\rdiagovfdiagRising Diagonal Crossing Falling Diagonal
    U+0292C\fdiagovrdiagFalling Diagonal Crossing Rising Diagonal
    U+0292D\seovnearrowSouth East Arrow Crossing North East Arrow
    U+0292E\neovsearrowNorth East Arrow Crossing South East Arrow
    U+0292F\fdiagovnearrowFalling Diagonal Crossing North East Arrow
    U+02930\rdiagovsearrowRising Diagonal Crossing South East Arrow
    U+02931\neovnwarrowNorth East Arrow Crossing North West Arrow
    U+02932\nwovnearrowNorth West Arrow Crossing North East Arrow
    U+02934\:arrow_heading_up:Arrow Pointing Rightwards Then Curving Upwards
    U+02935\:arrow_heading_down:Arrow Pointing Rightwards Then Curving Downwards
    U+02942\RlarrRightwards Arrow Above Short Leftwards Arrow
    U+02944\rLarrShort Rightwards Arrow Above Leftwards Arrow
    U+02945\rightarrowplusRightwards Arrow With Plus Below
    U+02946\leftarrowplusLeftwards Arrow With Plus Below
    U+02947\rarrxRightwards Arrow Through X
    U+02948\leftrightarrowcircleLeft Right Arrow Through Small Circle
    U+02949\twoheaduparrowcircleUpwards Two-Headed Arrow From Small Circle
    U+0294A\leftrightharpoonupdownLeft Barb Up Right Barb Down Harpoon
    U+0294B\leftrightharpoondownupLeft Barb Down Right Barb Up Harpoon
    U+0294C\updownharpoonrightleftUp Barb Right Down Barb Left Harpoon
    U+0294D\updownharpoonleftrightUp Barb Left Down Barb Right Harpoon
    U+0294E\LeftRightVectorLeft Barb Up Right Barb Up Harpoon
    U+0294F\RightUpDownVectorUp Barb Right Down Barb Right Harpoon
    U+02950\DownLeftRightVectorLeft Barb Down Right Barb Down Harpoon
    U+02951\LeftUpDownVectorUp Barb Left Down Barb Left Harpoon
    U+02952\LeftVectorBarLeftwards Harpoon With Barb Up To Bar
    U+02953\RightVectorBarRightwards Harpoon With Barb Up To Bar
    U+02954\RightUpVectorBarUpwards Harpoon With Barb Right To Bar
    U+02955\RightDownVectorBarDownwards Harpoon With Barb Right To Bar
    U+02956\DownLeftVectorBarLeftwards Harpoon With Barb Down To Bar
    U+02957\DownRightVectorBarRightwards Harpoon With Barb Down To Bar
    U+02958\LeftUpVectorBarUpwards Harpoon With Barb Left To Bar
    U+02959\LeftDownVectorBarDownwards Harpoon With Barb Left To Bar
    U+0295A\LeftTeeVectorLeftwards Harpoon With Barb Up From Bar
    U+0295B\RightTeeVectorRightwards Harpoon With Barb Up From Bar
    U+0295C\RightUpTeeVectorUpwards Harpoon With Barb Right From Bar
    U+0295D\RightDownTeeVectorDownwards Harpoon With Barb Right From Bar
    U+0295E\DownLeftTeeVectorLeftwards Harpoon With Barb Down From Bar
    U+0295F\DownRightTeeVectorRightwards Harpoon With Barb Down From Bar
    U+02960\LeftUpTeeVectorUpwards Harpoon With Barb Left From Bar
    U+02961\LeftDownTeeVectorDownwards Harpoon With Barb Left From Bar
    U+02962\leftharpoonsupdownLeftwards Harpoon With Barb Up Above Leftwards Harpoon With Barb Down
    U+02963\upharpoonsleftrightUpwards Harpoon With Barb Left Beside Upwards Harpoon With Barb Right
    U+02964\rightharpoonsupdownRightwards Harpoon With Barb Up Above Rightwards Harpoon With Barb Down
    U+02965\downharpoonsleftrightDownwards Harpoon With Barb Left Beside Downwards Harpoon With Barb Right
    U+02966\leftrightharpoonsupLeftwards Harpoon With Barb Up Above Rightwards Harpoon With Barb Up
    U+02967\leftrightharpoonsdownLeftwards Harpoon With Barb Down Above Rightwards Harpoon With Barb Down
    U+02968\rightleftharpoonsupRightwards Harpoon With Barb Up Above Leftwards Harpoon With Barb Up
    U+02969\rightleftharpoonsdownRightwards Harpoon With Barb Down Above Leftwards Harpoon With Barb Down
    U+0296A\leftharpoonupdashLeftwards Harpoon With Barb Up Above Long Dash
    U+0296B\dashleftharpoondownLeftwards Harpoon With Barb Down Below Long Dash
    U+0296C\rightharpoonupdashRightwards Harpoon With Barb Up Above Long Dash
    U+0296D\dashrightharpoondownRightwards Harpoon With Barb Down Below Long Dash
    U+0296E\UpEquilibriumUpwards Harpoon With Barb Left Beside Downwards Harpoon With Barb Right
    U+0296F\ReverseUpEquilibriumDownwards Harpoon With Barb Left Beside Upwards Harpoon With Barb Right
    U+02970\RoundImpliesRight Double Arrow With Rounded Head
    U+02977\leftarrowlessLeftwards Arrow Through Less-Than
    U+0297A\leftarrowsubsetLeftwards Arrow Through Subset
    U+02980\VvertTriple Vertical Bar Delimiter
    U+02986\ElroangRight White Parenthesis
    U+02999\ddfncDotted Fence
    U+0299B\measuredangleleftMeasured Angle Opening Left
    U+0299C\AngleRight Angle Variant With Square
    U+0299D\rightanglemdotMeasured Right Angle With Dot
    U+0299E\anglesAngle With S Inside
    U+0299F\angdnrAcute Angle
    U+029A0\lpargtSpherical Angle Opening Left
    U+029A1\sphericalangleupSpherical Angle Opening Up
    U+029A2\turnangleTurned Angle
    U+029A3\revangleReversed Angle
    U+029A4\angleubarAngle With Underbar
    U+029A5\revangleubarReversed Angle With Underbar
    U+029A6\wideangledownOblique Angle Opening Up
    U+029A7\wideangleupOblique Angle Opening Down
    U+029A8\measanglerutoneMeasured Angle With Open Arm Ending In Arrow Pointing Up And Right
    U+029A9\measanglelutonwMeasured Angle With Open Arm Ending In Arrow Pointing Up And Left
    U+029AA\measanglerdtoseMeasured Angle With Open Arm Ending In Arrow Pointing Down And Right
    U+029AB\measangleldtoswMeasured Angle With Open Arm Ending In Arrow Pointing Down And Left
    U+029AC\measangleurtoneMeasured Angle With Open Arm Ending In Arrow Pointing Right And Up
    U+029AD\measangleultonwMeasured Angle With Open Arm Ending In Arrow Pointing Left And Up
    U+029AE\measangledrtoseMeasured Angle With Open Arm Ending In Arrow Pointing Right And Down
    U+029AF\measangledltoswMeasured Angle With Open Arm Ending In Arrow Pointing Left And Down
    U+029B0\revemptysetReversed Empty Set
    U+029B1\emptysetobarEmpty Set With Overbar
    U+029B2\emptysetocircEmpty Set With Small Circle Above
    U+029B3\emptysetoarrEmpty Set With Right Arrow Above
    U+029B4\emptysetoarrlEmpty Set With Left Arrow Above
    U+029B7\circledparallelCircled Parallel
    U+029B8\obslashCircled Reverse Solidus
    U+029BC\odotslashdotCircled Anticlockwise-Rotated Division Sign
    U+029BE\circledwhitebulletCircled White Bullet
    U+029BF⦿\circledbulletCircled Bullet
    U+029C0\olessthanCircled Less-Than
    U+029C1\ogreaterthanCircled Greater-Than
    U+029C4\boxdiagSquared Rising Diagonal Slash
    U+029C5\boxbslashSquared Falling Diagonal Slash
    U+029C6\boxastSquared Asterisk
    U+029C7\boxcircleSquared Small Circle
    U+029CA\LapTriangle With Dot Above
    U+029CB\defasTriangle With Underbar
    U+029CF\LeftTriangleBarLeft Triangle Beside Vertical Bar
    U+029CF + U+00338⧏̸\NotLeftTriangleBarLeft Triangle Beside Vertical Bar + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+029D0\RightTriangleBarVertical Bar Beside Right Triangle
    U+029D0 + U+00338⧐̸\NotRightTriangleBarVertical Bar Beside Right Triangle + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+029DF\dualmapDouble-Ended Multimap
    U+029E1\lrtriangleeqIncreases As
    U+029E2\shuffleShuffle Product
    U+029E3\eparslEquals Sign And Slanted Parallel
    U+029E4\smeparslEquals Sign And Slanted Parallel With Tilde Above
    U+029E5\eqvparslIdentical To And Slanted Parallel
    U+029EB\blacklozengeBlack Lozenge
    U+029F4\RuleDelayedRule-Delayed
    U+029F6\dsolSolidus With Overbar
    U+029F7\rsolbarReverse Solidus With Horizontal Stroke
    U+029FA\doubleplusDouble Plus
    U+029FB\tripleplusTriple Plus
    U+02A00\bigodotN-Ary Circled Dot Operator
    U+02A01\bigoplusN-Ary Circled Plus Operator
    U+02A02\bigotimesN-Ary Circled Times Operator
    U+02A03\bigcupdotN-Ary Union Operator With Dot
    U+02A04\biguplusN-Ary Union Operator With Plus
    U+02A05\bigsqcapN-Ary Square Intersection Operator
    U+02A06\bigsqcupN-Ary Square Union Operator
    U+02A07\conjquantTwo Logical And Operator
    U+02A08\disjquantTwo Logical Or Operator
    U+02A09\bigtimesN-Ary Times Operator
    U+02A0A\modtwosumModulo Two Sum
    U+02A0B\sumintSummation With Integral
    U+02A0C\iiiintQuadruple Integral Operator
    U+02A0D\intbarFinite Part Integral
    U+02A0E\intBarIntegral With Double Stroke
    U+02A0F\clockointIntegral Average With Slash
    U+02A10\cirfnintCirculation Function
    U+02A11\awintAnticlockwise Integration
    U+02A12\rppolintLine Integration With Rectangular Path Around Pole
    U+02A13\scpolintLine Integration With Semicircular Path Around Pole
    U+02A14\npolintLine Integration Not Including The Pole
    U+02A15\pointintIntegral Around A Point Operator
    U+02A16\sqrintQuaternion Integral Operator
    U+02A18\intxIntegral With Times Sign
    U+02A19\intcapIntegral With Intersection
    U+02A1A\intcupIntegral With Union
    U+02A1B\upintIntegral With Overbar
    U+02A1C\lowintIntegral With Underbar
    U+02A1D\joinJoin
    U+02A1F\bbsemiZ Notation Schema Composition
    U+02A22\ringplusPlus Sign With Small Circle Above
    U+02A23\plushatPlus Sign With Circumflex Accent Above
    U+02A24\simplusPlus Sign With Tilde Above
    U+02A25\plusdotPlus Sign With Dot Below
    U+02A26\plussimPlus Sign With Tilde Below
    U+02A27\plussubtwoPlus Sign With Subscript Two
    U+02A28\plustrifPlus Sign With Black Triangle
    U+02A29\commaminusMinus Sign With Comma Above
    U+02A2A\minusdotMinus Sign With Dot Below
    U+02A2B\minusfdotsMinus Sign With Falling Dots
    U+02A2C\minusrdotsMinus Sign With Rising Dots
    U+02A2D\opluslhrimPlus Sign In Left Half Circle
    U+02A2E\oplusrhrimPlus Sign In Right Half Circle
    U+02A2F\TimesVector Or Cross Product
    U+02A30\dottimesMultiplication Sign With Dot Above
    U+02A31\timesbarMultiplication Sign With Underbar
    U+02A32\btimesSemidirect Product With Bottom Closed
    U+02A33\smashtimesSmash Product
    U+02A34\otimeslhrimMultiplication Sign In Left Half Circle
    U+02A35\otimesrhrimMultiplication Sign In Right Half Circle
    U+02A36\otimeshatCircled Multiplication Sign With Circumflex Accent
    U+02A37\OtimesMultiplication Sign In Double Circle
    U+02A38\odivCircled Division Sign
    U+02A39\triangleplusPlus Sign In Triangle
    U+02A3A\triangleminusMinus Sign In Triangle
    U+02A3B\triangletimesMultiplication Sign In Triangle
    U+02A3C\intprodInterior Product
    U+02A3D\intprodrRighthand Interior Product
    U+02A3F⨿\amalgAmalgamation Or Coproduct
    U+02A40\capdotIntersection With Dot
    U+02A41\uminusUnion With Minus Sign
    U+02A42\barcupUnion With Overbar
    U+02A43\barcapIntersection With Overbar
    U+02A44\capwedgeIntersection With Logical And
    U+02A45\cupveeUnion With Logical Or
    U+02A4A\twocupsUnion Beside And Joined With Union
    U+02A4B\twocapsIntersection Beside And Joined With Intersection
    U+02A4C\closedvarcupClosed Union With Serifs
    U+02A4D\closedvarcapClosed Intersection With Serifs
    U+02A4E\SqcapDouble Square Intersection
    U+02A4F\SqcupDouble Square Union
    U+02A50\closedvarcupsmashprodClosed Union With Serifs And Smash Product
    U+02A51\wedgeodotLogical And With Dot Above
    U+02A52\veeodotLogical Or With Dot Above
    U+02A53\AndDouble Logical And
    U+02A54\OrDouble Logical Or
    U+02A55\wedgeonwedgeTwo Intersecting Logical And
    U+02A56\ElOrTwo Intersecting Logical Or
    U+02A57\bigslopedveeSloping Large Or
    U+02A58\bigslopedwedgeSloping Large And
    U+02A5A\wedgemidvertLogical And With Middle Stem
    U+02A5B\veemidvertLogical Or With Middle Stem
    U+02A5C\midbarwedgeLogical And With Horizontal Dash
    U+02A5D\midbarveeLogical Or With Horizontal Dash
    U+02A5E\perspcorrespondLogical And With Double Overbar
    U+02A5F\minhatLogical And With Underbar
    U+02A60\wedgedoublebarLogical And With Double Underbar
    U+02A61\varveebarSmall Vee With Underbar
    U+02A62\doublebarveeLogical Or With Double Overbar
    U+02A63\veedoublebarLogical Or With Double Underbar
    U+02A66\eqdotEquals Sign With Dot Below
    U+02A67\dotequivIdentical With Dot Above
    U+02A6A\dotsimTilde Operator With Dot Above
    U+02A6B\simrdotsTilde Operator With Rising Dots
    U+02A6C\simminussimSimilar Minus Similar
    U+02A6D\congdotCongruent With Dot Above
    U+02A6E\asteqEquals With Asterisk
    U+02A6F\hatapproxAlmost Equal To With Circumflex Accent
    U+02A70\approxeqqApproximately Equal Or Equal To
    U+02A71\eqqplusEquals Sign Above Plus Sign
    U+02A72\pluseqqPlus Sign Above Equals Sign
    U+02A73\eqqsimEquals Sign Above Tilde Operator
    U+02A74\ColoneqDouble Colon Equal
    U+02A75\EqualTwo Consecutive Equals Signs
    U+02A76\eqeqeqThree Consecutive Equals Signs
    U+02A77\ddotseqEquals Sign With Two Dots Above And Two Dots Below
    U+02A78\equivDDEquivalent With Four Dots Above
    U+02A79\ltcirLess-Than With Circle Inside
    U+02A7A\gtcirGreater-Than With Circle Inside
    U+02A7B\ltquestLess-Than With Question Mark Above
    U+02A7C\gtquestGreater-Than With Question Mark Above
    U+02A7D\leqslantLess-Than Or Slanted Equal To
    U+02A7D + U+00338⩽̸\nleqslantLess-Than Or Slanted Equal To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02A7E\geqslantGreater-Than Or Slanted Equal To
    U+02A7E + U+00338⩾̸\ngeqslantGreater-Than Or Slanted Equal To + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02A7F⩿\lesdotLess-Than Or Slanted Equal To With Dot Inside
    U+02A80\gesdotGreater-Than Or Slanted Equal To With Dot Inside
    U+02A81\lesdotoLess-Than Or Slanted Equal To With Dot Above
    U+02A82\gesdotoGreater-Than Or Slanted Equal To With Dot Above
    U+02A83\lesdotorLess-Than Or Slanted Equal To With Dot Above Right
    U+02A84\gesdotolGreater-Than Or Slanted Equal To With Dot Above Left
    U+02A85\lessapproxLess-Than Or Approximate
    U+02A86\gtrapproxGreater-Than Or Approximate
    U+02A87\lneqLess-Than And Single-Line Not Equal To
    U+02A88\gneqGreater-Than And Single-Line Not Equal To
    U+02A89\lnapproxLess-Than And Not Approximate
    U+02A8A\gnapproxGreater-Than And Not Approximate
    U+02A8B\lesseqqgtrLess-Than Above Double-Line Equal Above Greater-Than
    U+02A8C\gtreqqlessGreater-Than Above Double-Line Equal Above Less-Than
    U+02A8D\lsimeLess-Than Above Similar Or Equal
    U+02A8E\gsimeGreater-Than Above Similar Or Equal
    U+02A8F\lsimgLess-Than Above Similar Above Greater-Than
    U+02A90\gsimlGreater-Than Above Similar Above Less-Than
    U+02A91\lgELess-Than Above Greater-Than Above Double-Line Equal
    U+02A92\glEGreater-Than Above Less-Than Above Double-Line Equal
    U+02A93\lesgesLess-Than Above Slanted Equal Above Greater-Than Above Slanted Equal
    U+02A94\geslesGreater-Than Above Slanted Equal Above Less-Than Above Slanted Equal
    U+02A95\eqslantlessSlanted Equal To Or Less-Than
    U+02A96\eqslantgtrSlanted Equal To Or Greater-Than
    U+02A97\elsdotSlanted Equal To Or Less-Than With Dot Inside
    U+02A98\egsdotSlanted Equal To Or Greater-Than With Dot Inside
    U+02A99\eqqlessDouble-Line Equal To Or Less-Than
    U+02A9A\eqqgtrDouble-Line Equal To Or Greater-Than
    U+02A9B\eqqslantlessDouble-Line Slanted Equal To Or Less-Than
    U+02A9C\eqqslantgtrDouble-Line Slanted Equal To Or Greater-Than
    U+02A9D\simlessSimilar Or Less-Than
    U+02A9E\simgtrSimilar Or Greater-Than
    U+02A9F\simlESimilar Above Less-Than Above Equals Sign
    U+02AA0\simgESimilar Above Greater-Than Above Equals Sign
    U+02AA1\NestedLessLessDouble Nested Less-Than
    U+02AA1 + U+00338⪡̸\NotNestedLessLessDouble Nested Less-Than + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AA2\NestedGreaterGreaterDouble Nested Greater-Than
    U+02AA2 + U+00338⪢̸\NotNestedGreaterGreaterDouble Nested Greater-Than + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AA3\partialmeetcontractionDouble Nested Less-Than With Underbar
    U+02AA4\gljGreater-Than Overlapping Less-Than
    U+02AA5\glaGreater-Than Beside Less-Than
    U+02AA6\ltccLess-Than Closed By Curve
    U+02AA7\gtccGreater-Than Closed By Curve
    U+02AA8\lesccLess-Than Closed By Curve Above Slanted Equal
    U+02AA9\gesccGreater-Than Closed By Curve Above Slanted Equal
    U+02AAA\smtSmaller Than
    U+02AAB\latLarger Than
    U+02AAC\smteSmaller Than Or Equal To
    U+02AAD\lateLarger Than Or Equal To
    U+02AAE\bumpeqqEquals Sign With Bumpy Above
    U+02AAF\preceqPrecedes Above Single-Line Equals Sign
    U+02AAF + U+00338⪯̸\npreceqPrecedes Above Single-Line Equals Sign + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AB0\succeqSucceeds Above Single-Line Equals Sign
    U+02AB0 + U+00338⪰̸\nsucceqSucceeds Above Single-Line Equals Sign + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AB1\precneqPrecedes Above Single-Line Not Equal To
    U+02AB2\succneqSucceeds Above Single-Line Not Equal To
    U+02AB3\preceqqPrecedes Above Equals Sign
    U+02AB4\succeqqSucceeds Above Equals Sign
    U+02AB5\precneqqPrecedes Above Not Equal To
    U+02AB6\succneqqSucceeds Above Not Equal To
    U+02AB7\precapproxPrecedes Above Almost Equal To
    U+02AB8\succapproxSucceeds Above Almost Equal To
    U+02AB9\precnapproxPrecedes Above Not Almost Equal To
    U+02ABA\succnapproxSucceeds Above Not Almost Equal To
    U+02ABB\PrecDouble Precedes
    U+02ABC\SuccDouble Succeeds
    U+02ABD\subsetdotSubset With Dot
    U+02ABE\supsetdotSuperset With Dot
    U+02ABF⪿\subsetplusSubset With Plus Sign Below
    U+02AC0\supsetplusSuperset With Plus Sign Below
    U+02AC1\submultSubset With Multiplication Sign Below
    U+02AC2\supmultSuperset With Multiplication Sign Below
    U+02AC3\subedotSubset Of Or Equal To With Dot Above
    U+02AC4\supedotSuperset Of Or Equal To With Dot Above
    U+02AC5\subseteqqSubset Of Above Equals Sign
    U+02AC5 + U+00338⫅̸\nsubseteqqSubset Of Above Equals Sign + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AC6\supseteqqSuperset Of Above Equals Sign
    U+02AC6 + U+00338⫆̸\nsupseteqqSuperset Of Above Equals Sign + Combining Long Solidus Overlay / Non-Spacing Long Slash Overlay
    U+02AC7\subsimSubset Of Above Tilde Operator
    U+02AC8\supsimSuperset Of Above Tilde Operator
    U+02AC9\subsetapproxSubset Of Above Almost Equal To
    U+02ACA\supsetapproxSuperset Of Above Almost Equal To
    U+02ACB\subsetneqqSubset Of Above Not Equal To
    U+02ACC\supsetneqqSuperset Of Above Not Equal To
    U+02ACD\lsqhookSquare Left Open Box Operator
    U+02ACE\rsqhookSquare Right Open Box Operator
    U+02ACF\csubClosed Subset
    U+02AD0\csupClosed Superset
    U+02AD1\csubeClosed Subset Or Equal To
    U+02AD2\csupeClosed Superset Or Equal To
    U+02AD3\subsupSubset Above Superset
    U+02AD4\supsubSuperset Above Subset
    U+02AD5\subsubSubset Above Subset
    U+02AD6\supsupSuperset Above Superset
    U+02AD7\suphsubSuperset Beside Subset
    U+02AD8\supdsubSuperset Beside And Joined By Dash With Subset
    U+02AD9\forkvElement Of Opening Downwards
    U+02ADB\mlcpTransversal Intersection
    U+02ADC\forksForking
    U+02ADD\forksnotNonforking
    U+02AE3\dashVDouble Vertical Bar Left Turnstile
    U+02AE4\DashvVertical Bar Double Left Turnstile
    U+02AEA\Top, \downvDashDouble Down Tack
    U+02AEB\upvDash, \Bot, \indepDouble Up Tack
    U+02AF4\interleaveTriple Vertical Bar Binary Relation
    U+02AF6\tdcolTriple Colon Operator
    U+02AF7\lllnestTriple Nested Less-Than
    U+02AF8\gggnestTriple Nested Greater-Than
    U+02AF9\leqqslantDouble-Line Slanted Less-Than Or Equal To
    U+02AFA\geqqslantDouble-Line Slanted Greater-Than Or Equal To
    U+02B05\:arrow_left:Leftwards Black Arrow
    U+02B06\:arrow_up:Upwards Black Arrow
    U+02B07\:arrow_down:Downwards Black Arrow
    U+02B12\squaretopblackSquare With Top Half Black
    U+02B13\squarebotblackSquare With Bottom Half Black
    U+02B14\squareurblackSquare With Upper Right Diagonal Half Black
    U+02B15\squarellblackSquare With Lower Left Diagonal Half Black
    U+02B16\diamondleftblackDiamond With Left Half Black
    U+02B17\diamondrightblackDiamond With Right Half Black
    U+02B18\diamondtopblackDiamond With Top Half Black
    U+02B19\diamondbotblackDiamond With Bottom Half Black
    U+02B1A\dottedsquareDotted Square
    U+02B1B\lgblksquare, \:black_large_square:Black Large Square
    U+02B1C\lgwhtsquare, \:white_large_square:White Large Square
    U+02B1D\vysmblksquareBlack Very Small Square
    U+02B1E\vysmwhtsquareWhite Very Small Square
    U+02B1F\pentagonblackBlack Pentagon
    U+02B20\pentagonWhite Pentagon
    U+02B21\varhexagonWhite Hexagon
    U+02B22\varhexagonblackBlack Hexagon
    U+02B23\hexagonblackHorizontal Black Hexagon
    U+02B24\lgblkcircleBlack Large Circle
    U+02B25\mdblkdiamondBlack Medium Diamond
    U+02B26\mdwhtdiamondWhite Medium Diamond
    U+02B27\mdblklozengeBlack Medium Lozenge
    U+02B28\mdwhtlozengeWhite Medium Lozenge
    U+02B29\smblkdiamondBlack Small Diamond
    U+02B2A\smblklozengeBlack Small Lozenge
    U+02B2B\smwhtlozengeWhite Small Lozenge
    U+02B2C\blkhorzovalBlack Horizontal Ellipse
    U+02B2D\whthorzovalWhite Horizontal Ellipse
    U+02B2E\blkvertovalBlack Vertical Ellipse
    U+02B2F\whtvertovalWhite Vertical Ellipse
    U+02B30\circleonleftarrowLeft Arrow With Small Circle
    U+02B31\leftthreearrowsThree Leftwards Arrows
    U+02B32\leftarrowonoplusLeft Arrow With Circled Plus
    U+02B33\longleftsquigarrowLong Leftwards Squiggle Arrow
    U+02B34\nvtwoheadleftarrowLeftwards Two-Headed Arrow With Vertical Stroke
    U+02B35\nVtwoheadleftarrowLeftwards Two-Headed Arrow With Double Vertical Stroke
    U+02B36\twoheadmapsfromLeftwards Two-Headed Arrow From Bar
    U+02B37\twoheadleftdbkarrowLeftwards Two-Headed Triple Dash Arrow
    U+02B38\leftdotarrowLeftwards Arrow With Dotted Stem
    U+02B39\nvleftarrowtailLeftwards Arrow With Tail With Vertical Stroke
    U+02B3A\nVleftarrowtailLeftwards Arrow With Tail With Double Vertical Stroke
    U+02B3B\twoheadleftarrowtailLeftwards Two-Headed Arrow With Tail
    U+02B3C\nvtwoheadleftarrowtailLeftwards Two-Headed Arrow With Tail With Vertical Stroke
    U+02B3D\nVtwoheadleftarrowtailLeftwards Two-Headed Arrow With Tail With Double Vertical Stroke
    U+02B3E\leftarrowxLeftwards Arrow Through X
    U+02B3F⬿\leftcurvedarrowWave Arrow Pointing Directly Left
    U+02B40\equalleftarrowEquals Sign Above Leftwards Arrow
    U+02B41\bsimilarleftarrowReverse Tilde Operator Above Leftwards Arrow
    U+02B42\leftarrowbackapproxLeftwards Arrow Above Reverse Almost Equal To
    U+02B43\rightarrowgtrRightwards Arrow Through Greater-Than
    U+02B44\rightarrowsupsetRightwards Arrow Through Superset
    U+02B45\LLeftarrowLeftwards Quadruple Arrow
    U+02B46\RRightarrowRightwards Quadruple Arrow
    U+02B47\bsimilarrightarrowReverse Tilde Operator Above Rightwards Arrow
    U+02B48\rightarrowbackapproxRightwards Arrow Above Reverse Almost Equal To
    U+02B49\similarleftarrowTilde Operator Above Leftwards Arrow
    U+02B4A\leftarrowapproxLeftwards Arrow Above Almost Equal To
    U+02B4B\leftarrowbsimilarLeftwards Arrow Above Reverse Tilde Operator
    U+02B4C\rightarrowbsimilarRightwards Arrow Above Reverse Tilde Operator
    U+02B50\medwhitestar, \:star:White Medium Star
    U+02B51\medblackstarBlack Small Star
    U+02B52\smwhitestarWhite Small Star
    U+02B53\rightpentagonblackBlack Right-Pointing Pentagon
    U+02B54\rightpentagonWhite Right-Pointing Pentagon
    U+02B55\:o:Heavy Large Circle
    U+02C7C\_jLatin Subscript Small Letter J
    U+02C7D\^VModifier Letter Capital V
    U+03012\postalmarkPostal Mark
    U+03030\:wavy_dash:Wavy Dash
    U+0303D\:part_alternation_mark:Part Alternation Mark
    U+03297\:congratulations:Circled Ideograph Congratulation
    U+03299\:secret:Circled Ideograph Secret
    U+0A71B\^uparrowModifier Letter Raised Up Arrow
    U+0A71C\^downarrowModifier Letter Raised Down Arrow
    U+0A71D\^!Modifier Letter Raised Exclamation Mark
    U+1D400𝐀\bfAMathematical Bold Capital A
    U+1D401𝐁\bfBMathematical Bold Capital B
    U+1D402𝐂\bfCMathematical Bold Capital C
    U+1D403𝐃\bfDMathematical Bold Capital D
    U+1D404𝐄\bfEMathematical Bold Capital E
    U+1D405𝐅\bfFMathematical Bold Capital F
    U+1D406𝐆\bfGMathematical Bold Capital G
    U+1D407𝐇\bfHMathematical Bold Capital H
    U+1D408𝐈\bfIMathematical Bold Capital I
    U+1D409𝐉\bfJMathematical Bold Capital J
    U+1D40A𝐊\bfKMathematical Bold Capital K
    U+1D40B𝐋\bfLMathematical Bold Capital L
    U+1D40C𝐌\bfMMathematical Bold Capital M
    U+1D40D𝐍\bfNMathematical Bold Capital N
    U+1D40E𝐎\bfOMathematical Bold Capital O
    U+1D40F𝐏\bfPMathematical Bold Capital P
    U+1D410𝐐\bfQMathematical Bold Capital Q
    U+1D411𝐑\bfRMathematical Bold Capital R
    U+1D412𝐒\bfSMathematical Bold Capital S
    U+1D413𝐓\bfTMathematical Bold Capital T
    U+1D414𝐔\bfUMathematical Bold Capital U
    U+1D415𝐕\bfVMathematical Bold Capital V
    U+1D416𝐖\bfWMathematical Bold Capital W
    U+1D417𝐗\bfXMathematical Bold Capital X
    U+1D418𝐘\bfYMathematical Bold Capital Y
    U+1D419𝐙\bfZMathematical Bold Capital Z
    U+1D41A𝐚\bfaMathematical Bold Small A
    U+1D41B𝐛\bfbMathematical Bold Small B
    U+1D41C𝐜\bfcMathematical Bold Small C
    U+1D41D𝐝\bfdMathematical Bold Small D
    U+1D41E𝐞\bfeMathematical Bold Small E
    U+1D41F𝐟\bffMathematical Bold Small F
    U+1D420𝐠\bfgMathematical Bold Small G
    U+1D421𝐡\bfhMathematical Bold Small H
    U+1D422𝐢\bfiMathematical Bold Small I
    U+1D423𝐣\bfjMathematical Bold Small J
    U+1D424𝐤\bfkMathematical Bold Small K
    U+1D425𝐥\bflMathematical Bold Small L
    U+1D426𝐦\bfmMathematical Bold Small M
    U+1D427𝐧\bfnMathematical Bold Small N
    U+1D428𝐨\bfoMathematical Bold Small O
    U+1D429𝐩\bfpMathematical Bold Small P
    U+1D42A𝐪\bfqMathematical Bold Small Q
    U+1D42B𝐫\bfrMathematical Bold Small R
    U+1D42C𝐬\bfsMathematical Bold Small S
    U+1D42D𝐭\bftMathematical Bold Small T
    U+1D42E𝐮\bfuMathematical Bold Small U
    U+1D42F𝐯\bfvMathematical Bold Small V
    U+1D430𝐰\bfwMathematical Bold Small W
    U+1D431𝐱\bfxMathematical Bold Small X
    U+1D432𝐲\bfyMathematical Bold Small Y
    U+1D433𝐳\bfzMathematical Bold Small Z
    U+1D434𝐴\itAMathematical Italic Capital A
    U+1D435𝐵\itBMathematical Italic Capital B
    U+1D436𝐶\itCMathematical Italic Capital C
    U+1D437𝐷\itDMathematical Italic Capital D
    U+1D438𝐸\itEMathematical Italic Capital E
    U+1D439𝐹\itFMathematical Italic Capital F
    U+1D43A𝐺\itGMathematical Italic Capital G
    U+1D43B𝐻\itHMathematical Italic Capital H
    U+1D43C𝐼\itIMathematical Italic Capital I
    U+1D43D𝐽\itJMathematical Italic Capital J
    U+1D43E𝐾\itKMathematical Italic Capital K
    U+1D43F𝐿\itLMathematical Italic Capital L
    U+1D440𝑀\itMMathematical Italic Capital M
    U+1D441𝑁\itNMathematical Italic Capital N
    U+1D442𝑂\itOMathematical Italic Capital O
    U+1D443𝑃\itPMathematical Italic Capital P
    U+1D444𝑄\itQMathematical Italic Capital Q
    U+1D445𝑅\itRMathematical Italic Capital R
    U+1D446𝑆\itSMathematical Italic Capital S
    U+1D447𝑇\itTMathematical Italic Capital T
    U+1D448𝑈\itUMathematical Italic Capital U
    U+1D449𝑉\itVMathematical Italic Capital V
    U+1D44A𝑊\itWMathematical Italic Capital W
    U+1D44B𝑋\itXMathematical Italic Capital X
    U+1D44C𝑌\itYMathematical Italic Capital Y
    U+1D44D𝑍\itZMathematical Italic Capital Z
    U+1D44E𝑎\itaMathematical Italic Small A
    U+1D44F𝑏\itbMathematical Italic Small B
    U+1D450𝑐\itcMathematical Italic Small C
    U+1D451𝑑\itdMathematical Italic Small D
    U+1D452𝑒\iteMathematical Italic Small E
    U+1D453𝑓\itfMathematical Italic Small F
    U+1D454𝑔\itgMathematical Italic Small G
    U+1D456𝑖\itiMathematical Italic Small I
    U+1D457𝑗\itjMathematical Italic Small J
    U+1D458𝑘\itkMathematical Italic Small K
    U+1D459𝑙\itlMathematical Italic Small L
    U+1D45A𝑚\itmMathematical Italic Small M
    U+1D45B𝑛\itnMathematical Italic Small N
    U+1D45C𝑜\itoMathematical Italic Small O
    U+1D45D𝑝\itpMathematical Italic Small P
    U+1D45E𝑞\itqMathematical Italic Small Q
    U+1D45F𝑟\itrMathematical Italic Small R
    U+1D460𝑠\itsMathematical Italic Small S
    U+1D461𝑡\ittMathematical Italic Small T
    U+1D462𝑢\ituMathematical Italic Small U
    U+1D463𝑣\itvMathematical Italic Small V
    U+1D464𝑤\itwMathematical Italic Small W
    U+1D465𝑥\itxMathematical Italic Small X
    U+1D466𝑦\ityMathematical Italic Small Y
    U+1D467𝑧\itzMathematical Italic Small Z
    U+1D468𝑨\biAMathematical Bold Italic Capital A
    U+1D469𝑩\biBMathematical Bold Italic Capital B
    U+1D46A𝑪\biCMathematical Bold Italic Capital C
    U+1D46B𝑫\biDMathematical Bold Italic Capital D
    U+1D46C𝑬\biEMathematical Bold Italic Capital E
    U+1D46D𝑭\biFMathematical Bold Italic Capital F
    U+1D46E𝑮\biGMathematical Bold Italic Capital G
    U+1D46F𝑯\biHMathematical Bold Italic Capital H
    U+1D470𝑰\biIMathematical Bold Italic Capital I
    U+1D471𝑱\biJMathematical Bold Italic Capital J
    U+1D472𝑲\biKMathematical Bold Italic Capital K
    U+1D473𝑳\biLMathematical Bold Italic Capital L
    U+1D474𝑴\biMMathematical Bold Italic Capital M
    U+1D475𝑵\biNMathematical Bold Italic Capital N
    U+1D476𝑶\biOMathematical Bold Italic Capital O
    U+1D477𝑷\biPMathematical Bold Italic Capital P
    U+1D478𝑸\biQMathematical Bold Italic Capital Q
    U+1D479𝑹\biRMathematical Bold Italic Capital R
    U+1D47A𝑺\biSMathematical Bold Italic Capital S
    U+1D47B𝑻\biTMathematical Bold Italic Capital T
    U+1D47C𝑼\biUMathematical Bold Italic Capital U
    U+1D47D𝑽\biVMathematical Bold Italic Capital V
    U+1D47E𝑾\biWMathematical Bold Italic Capital W
    U+1D47F𝑿\biXMathematical Bold Italic Capital X
    U+1D480𝒀\biYMathematical Bold Italic Capital Y
    U+1D481𝒁\biZMathematical Bold Italic Capital Z
    U+1D482𝒂\biaMathematical Bold Italic Small A
    U+1D483𝒃\bibMathematical Bold Italic Small B
    U+1D484𝒄\bicMathematical Bold Italic Small C
    U+1D485𝒅\bidMathematical Bold Italic Small D
    U+1D486𝒆\bieMathematical Bold Italic Small E
    U+1D487𝒇\bifMathematical Bold Italic Small F
    U+1D488𝒈\bigMathematical Bold Italic Small G
    U+1D489𝒉\bihMathematical Bold Italic Small H
    U+1D48A𝒊\biiMathematical Bold Italic Small I
    U+1D48B𝒋\bijMathematical Bold Italic Small J
    U+1D48C𝒌\bikMathematical Bold Italic Small K
    U+1D48D𝒍\bilMathematical Bold Italic Small L
    U+1D48E𝒎\bimMathematical Bold Italic Small M
    U+1D48F𝒏\binMathematical Bold Italic Small N
    U+1D490𝒐\bioMathematical Bold Italic Small O
    U+1D491𝒑\bipMathematical Bold Italic Small P
    U+1D492𝒒\biqMathematical Bold Italic Small Q
    U+1D493𝒓\birMathematical Bold Italic Small R
    U+1D494𝒔\bisMathematical Bold Italic Small S
    U+1D495𝒕\bitMathematical Bold Italic Small T
    U+1D496𝒖\biuMathematical Bold Italic Small U
    U+1D497𝒗\bivMathematical Bold Italic Small V
    U+1D498𝒘\biwMathematical Bold Italic Small W
    U+1D499𝒙\bixMathematical Bold Italic Small X
    U+1D49A𝒚\biyMathematical Bold Italic Small Y
    U+1D49B𝒛\bizMathematical Bold Italic Small Z
    U+1D49C𝒜\scrAMathematical Script Capital A
    U+1D49E𝒞\scrCMathematical Script Capital C
    U+1D49F𝒟\scrDMathematical Script Capital D
    U+1D4A2𝒢\scrGMathematical Script Capital G
    U+1D4A5𝒥\scrJMathematical Script Capital J
    U+1D4A6𝒦\scrKMathematical Script Capital K
    U+1D4A9𝒩\scrNMathematical Script Capital N
    U+1D4AA𝒪\scrOMathematical Script Capital O
    U+1D4AB𝒫\scrPMathematical Script Capital P
    U+1D4AC𝒬\scrQMathematical Script Capital Q
    U+1D4AE𝒮\scrSMathematical Script Capital S
    U+1D4AF𝒯\scrTMathematical Script Capital T
    U+1D4B0𝒰\scrUMathematical Script Capital U
    U+1D4B1𝒱\scrVMathematical Script Capital V
    U+1D4B2𝒲\scrWMathematical Script Capital W
    U+1D4B3𝒳\scrXMathematical Script Capital X
    U+1D4B4𝒴\scrYMathematical Script Capital Y
    U+1D4B5𝒵\scrZMathematical Script Capital Z
    U+1D4B6𝒶\scraMathematical Script Small A
    U+1D4B7𝒷\scrbMathematical Script Small B
    U+1D4B8𝒸\scrcMathematical Script Small C
    U+1D4B9𝒹\scrdMathematical Script Small D
    U+1D4BB𝒻\scrfMathematical Script Small F
    U+1D4BD𝒽\scrhMathematical Script Small H
    U+1D4BE𝒾\scriMathematical Script Small I
    U+1D4BF𝒿\scrjMathematical Script Small J
    U+1D4C0𝓀\scrkMathematical Script Small K
    U+1D4C1𝓁\scrlMathematical Script Small L
    U+1D4C2𝓂\scrmMathematical Script Small M
    U+1D4C3𝓃\scrnMathematical Script Small N
    U+1D4C5𝓅\scrpMathematical Script Small P
    U+1D4C6𝓆\scrqMathematical Script Small Q
    U+1D4C7𝓇\scrrMathematical Script Small R
    U+1D4C8𝓈\scrsMathematical Script Small S
    U+1D4C9𝓉\scrtMathematical Script Small T
    U+1D4CA𝓊\scruMathematical Script Small U
    U+1D4CB𝓋\scrvMathematical Script Small V
    U+1D4CC𝓌\scrwMathematical Script Small W
    U+1D4CD𝓍\scrxMathematical Script Small X
    U+1D4CE𝓎\scryMathematical Script Small Y
    U+1D4CF𝓏\scrzMathematical Script Small Z
    U+1D4D0𝓐\bscrAMathematical Bold Script Capital A
    U+1D4D1𝓑\bscrBMathematical Bold Script Capital B
    U+1D4D2𝓒\bscrCMathematical Bold Script Capital C
    U+1D4D3𝓓\bscrDMathematical Bold Script Capital D
    U+1D4D4𝓔\bscrEMathematical Bold Script Capital E
    U+1D4D5𝓕\bscrFMathematical Bold Script Capital F
    U+1D4D6𝓖\bscrGMathematical Bold Script Capital G
    U+1D4D7𝓗\bscrHMathematical Bold Script Capital H
    U+1D4D8𝓘\bscrIMathematical Bold Script Capital I
    U+1D4D9𝓙\bscrJMathematical Bold Script Capital J
    U+1D4DA𝓚\bscrKMathematical Bold Script Capital K
    U+1D4DB𝓛\bscrLMathematical Bold Script Capital L
    U+1D4DC𝓜\bscrMMathematical Bold Script Capital M
    U+1D4DD𝓝\bscrNMathematical Bold Script Capital N
    U+1D4DE𝓞\bscrOMathematical Bold Script Capital O
    U+1D4DF𝓟\bscrPMathematical Bold Script Capital P
    U+1D4E0𝓠\bscrQMathematical Bold Script Capital Q
    U+1D4E1𝓡\bscrRMathematical Bold Script Capital R
    U+1D4E2𝓢\bscrSMathematical Bold Script Capital S
    U+1D4E3𝓣\bscrTMathematical Bold Script Capital T
    U+1D4E4𝓤\bscrUMathematical Bold Script Capital U
    U+1D4E5𝓥\bscrVMathematical Bold Script Capital V
    U+1D4E6𝓦\bscrWMathematical Bold Script Capital W
    U+1D4E7𝓧\bscrXMathematical Bold Script Capital X
    U+1D4E8𝓨\bscrYMathematical Bold Script Capital Y
    U+1D4E9𝓩\bscrZMathematical Bold Script Capital Z
    U+1D4EA𝓪\bscraMathematical Bold Script Small A
    U+1D4EB𝓫\bscrbMathematical Bold Script Small B
    U+1D4EC𝓬\bscrcMathematical Bold Script Small C
    U+1D4ED𝓭\bscrdMathematical Bold Script Small D
    U+1D4EE𝓮\bscreMathematical Bold Script Small E
    U+1D4EF𝓯\bscrfMathematical Bold Script Small F
    U+1D4F0𝓰\bscrgMathematical Bold Script Small G
    U+1D4F1𝓱\bscrhMathematical Bold Script Small H
    U+1D4F2𝓲\bscriMathematical Bold Script Small I
    U+1D4F3𝓳\bscrjMathematical Bold Script Small J
    U+1D4F4𝓴\bscrkMathematical Bold Script Small K
    U+1D4F5𝓵\bscrlMathematical Bold Script Small L
    U+1D4F6𝓶\bscrmMathematical Bold Script Small M
    U+1D4F7𝓷\bscrnMathematical Bold Script Small N
    U+1D4F8𝓸\bscroMathematical Bold Script Small O
    U+1D4F9𝓹\bscrpMathematical Bold Script Small P
    U+1D4FA𝓺\bscrqMathematical Bold Script Small Q
    U+1D4FB𝓻\bscrrMathematical Bold Script Small R
    U+1D4FC𝓼\bscrsMathematical Bold Script Small S
    U+1D4FD𝓽\bscrtMathematical Bold Script Small T
    U+1D4FE𝓾\bscruMathematical Bold Script Small U
    U+1D4FF𝓿\bscrvMathematical Bold Script Small V
    U+1D500𝔀\bscrwMathematical Bold Script Small W
    U+1D501𝔁\bscrxMathematical Bold Script Small X
    U+1D502𝔂\bscryMathematical Bold Script Small Y
    U+1D503𝔃\bscrzMathematical Bold Script Small Z
    U+1D504𝔄\frakAMathematical Fraktur Capital A
    U+1D505𝔅\frakBMathematical Fraktur Capital B
    U+1D507𝔇\frakDMathematical Fraktur Capital D
    U+1D508𝔈\frakEMathematical Fraktur Capital E
    U+1D509𝔉\frakFMathematical Fraktur Capital F
    U+1D50A𝔊\frakGMathematical Fraktur Capital G
    U+1D50D𝔍\frakJMathematical Fraktur Capital J
    U+1D50E𝔎\frakKMathematical Fraktur Capital K
    U+1D50F𝔏\frakLMathematical Fraktur Capital L
    U+1D510𝔐\frakMMathematical Fraktur Capital M
    U+1D511𝔑\frakNMathematical Fraktur Capital N
    U+1D512𝔒\frakOMathematical Fraktur Capital O
    U+1D513𝔓\frakPMathematical Fraktur Capital P
    U+1D514𝔔\frakQMathematical Fraktur Capital Q
    U+1D516𝔖\frakSMathematical Fraktur Capital S
    U+1D517𝔗\frakTMathematical Fraktur Capital T
    U+1D518𝔘\frakUMathematical Fraktur Capital U
    U+1D519𝔙\frakVMathematical Fraktur Capital V
    U+1D51A𝔚\frakWMathematical Fraktur Capital W
    U+1D51B𝔛\frakXMathematical Fraktur Capital X
    U+1D51C𝔜\frakYMathematical Fraktur Capital Y
    U+1D51E𝔞\frakaMathematical Fraktur Small A
    U+1D51F𝔟\frakbMathematical Fraktur Small B
    U+1D520𝔠\frakcMathematical Fraktur Small C
    U+1D521𝔡\frakdMathematical Fraktur Small D
    U+1D522𝔢\frakeMathematical Fraktur Small E
    U+1D523𝔣\frakfMathematical Fraktur Small F
    U+1D524𝔤\frakgMathematical Fraktur Small G
    U+1D525𝔥\frakhMathematical Fraktur Small H
    U+1D526𝔦\frakiMathematical Fraktur Small I
    U+1D527𝔧\frakjMathematical Fraktur Small J
    U+1D528𝔨\frakkMathematical Fraktur Small K
    U+1D529𝔩\fraklMathematical Fraktur Small L
    U+1D52A𝔪\frakmMathematical Fraktur Small M
    U+1D52B𝔫\fraknMathematical Fraktur Small N
    U+1D52C𝔬\frakoMathematical Fraktur Small O
    U+1D52D𝔭\frakpMathematical Fraktur Small P
    U+1D52E𝔮\frakqMathematical Fraktur Small Q
    U+1D52F𝔯\frakrMathematical Fraktur Small R
    U+1D530𝔰\fraksMathematical Fraktur Small S
    U+1D531𝔱\fraktMathematical Fraktur Small T
    U+1D532𝔲\frakuMathematical Fraktur Small U
    U+1D533𝔳\frakvMathematical Fraktur Small V
    U+1D534𝔴\frakwMathematical Fraktur Small W
    U+1D535𝔵\frakxMathematical Fraktur Small X
    U+1D536𝔶\frakyMathematical Fraktur Small Y
    U+1D537𝔷\frakzMathematical Fraktur Small Z
    U+1D538𝔸\bbAMathematical Double-Struck Capital A
    U+1D539𝔹\bbBMathematical Double-Struck Capital B
    U+1D53B𝔻\bbDMathematical Double-Struck Capital D
    U+1D53C𝔼\bbEMathematical Double-Struck Capital E
    U+1D53D𝔽\bbFMathematical Double-Struck Capital F
    U+1D53E𝔾\bbGMathematical Double-Struck Capital G
    U+1D540𝕀\bbIMathematical Double-Struck Capital I
    U+1D541𝕁\bbJMathematical Double-Struck Capital J
    U+1D542𝕂\bbKMathematical Double-Struck Capital K
    U+1D543𝕃\bbLMathematical Double-Struck Capital L
    U+1D544𝕄\bbMMathematical Double-Struck Capital M
    U+1D546𝕆\bbOMathematical Double-Struck Capital O
    U+1D54A𝕊\bbSMathematical Double-Struck Capital S
    U+1D54B𝕋\bbTMathematical Double-Struck Capital T
    U+1D54C𝕌\bbUMathematical Double-Struck Capital U
    U+1D54D𝕍\bbVMathematical Double-Struck Capital V
    U+1D54E𝕎\bbWMathematical Double-Struck Capital W
    U+1D54F𝕏\bbXMathematical Double-Struck Capital X
    U+1D550𝕐\bbYMathematical Double-Struck Capital Y
    U+1D552𝕒\bbaMathematical Double-Struck Small A
    U+1D553𝕓\bbbMathematical Double-Struck Small B
    U+1D554𝕔\bbcMathematical Double-Struck Small C
    U+1D555𝕕\bbdMathematical Double-Struck Small D
    U+1D556𝕖\bbeMathematical Double-Struck Small E
    U+1D557𝕗\bbfMathematical Double-Struck Small F
    U+1D558𝕘\bbgMathematical Double-Struck Small G
    U+1D559𝕙\bbhMathematical Double-Struck Small H
    U+1D55A𝕚\bbiMathematical Double-Struck Small I
    U+1D55B𝕛\bbjMathematical Double-Struck Small J
    U+1D55C𝕜\bbkMathematical Double-Struck Small K
    U+1D55D𝕝\bblMathematical Double-Struck Small L
    U+1D55E𝕞\bbmMathematical Double-Struck Small M
    U+1D55F𝕟\bbnMathematical Double-Struck Small N
    U+1D560𝕠\bboMathematical Double-Struck Small O
    U+1D561𝕡\bbpMathematical Double-Struck Small P
    U+1D562𝕢\bbqMathematical Double-Struck Small Q
    U+1D563𝕣\bbrMathematical Double-Struck Small R
    U+1D564𝕤\bbsMathematical Double-Struck Small S
    U+1D565𝕥\bbtMathematical Double-Struck Small T
    U+1D566𝕦\bbuMathematical Double-Struck Small U
    U+1D567𝕧\bbvMathematical Double-Struck Small V
    U+1D568𝕨\bbwMathematical Double-Struck Small W
    U+1D569𝕩\bbxMathematical Double-Struck Small X
    U+1D56A𝕪\bbyMathematical Double-Struck Small Y
    U+1D56B𝕫\bbzMathematical Double-Struck Small Z
    U+1D56C𝕬\bfrakAMathematical Bold Fraktur Capital A
    U+1D56D𝕭\bfrakBMathematical Bold Fraktur Capital B
    U+1D56E𝕮\bfrakCMathematical Bold Fraktur Capital C
    U+1D56F𝕯\bfrakDMathematical Bold Fraktur Capital D
    U+1D570𝕰\bfrakEMathematical Bold Fraktur Capital E
    U+1D571𝕱\bfrakFMathematical Bold Fraktur Capital F
    U+1D572𝕲\bfrakGMathematical Bold Fraktur Capital G
    U+1D573𝕳\bfrakHMathematical Bold Fraktur Capital H
    U+1D574𝕴\bfrakIMathematical Bold Fraktur Capital I
    U+1D575𝕵\bfrakJMathematical Bold Fraktur Capital J
    U+1D576𝕶\bfrakKMathematical Bold Fraktur Capital K
    U+1D577𝕷\bfrakLMathematical Bold Fraktur Capital L
    U+1D578𝕸\bfrakMMathematical Bold Fraktur Capital M
    U+1D579𝕹\bfrakNMathematical Bold Fraktur Capital N
    U+1D57A𝕺\bfrakOMathematical Bold Fraktur Capital O
    U+1D57B𝕻\bfrakPMathematical Bold Fraktur Capital P
    U+1D57C𝕼\bfrakQMathematical Bold Fraktur Capital Q
    U+1D57D𝕽\bfrakRMathematical Bold Fraktur Capital R
    U+1D57E𝕾\bfrakSMathematical Bold Fraktur Capital S
    U+1D57F𝕿\bfrakTMathematical Bold Fraktur Capital T
    U+1D580𝖀\bfrakUMathematical Bold Fraktur Capital U
    U+1D581𝖁\bfrakVMathematical Bold Fraktur Capital V
    U+1D582𝖂\bfrakWMathematical Bold Fraktur Capital W
    U+1D583𝖃\bfrakXMathematical Bold Fraktur Capital X
    U+1D584𝖄\bfrakYMathematical Bold Fraktur Capital Y
    U+1D585𝖅\bfrakZMathematical Bold Fraktur Capital Z
    U+1D586𝖆\bfrakaMathematical Bold Fraktur Small A
    U+1D587𝖇\bfrakbMathematical Bold Fraktur Small B
    U+1D588𝖈\bfrakcMathematical Bold Fraktur Small C
    U+1D589𝖉\bfrakdMathematical Bold Fraktur Small D
    U+1D58A𝖊\bfrakeMathematical Bold Fraktur Small E
    U+1D58B𝖋\bfrakfMathematical Bold Fraktur Small F
    U+1D58C𝖌\bfrakgMathematical Bold Fraktur Small G
    U+1D58D𝖍\bfrakhMathematical Bold Fraktur Small H
    U+1D58E𝖎\bfrakiMathematical Bold Fraktur Small I
    U+1D58F𝖏\bfrakjMathematical Bold Fraktur Small J
    U+1D590𝖐\bfrakkMathematical Bold Fraktur Small K
    U+1D591𝖑\bfraklMathematical Bold Fraktur Small L
    U+1D592𝖒\bfrakmMathematical Bold Fraktur Small M
    U+1D593𝖓\bfraknMathematical Bold Fraktur Small N
    U+1D594𝖔\bfrakoMathematical Bold Fraktur Small O
    U+1D595𝖕\bfrakpMathematical Bold Fraktur Small P
    U+1D596𝖖\bfrakqMathematical Bold Fraktur Small Q
    U+1D597𝖗\bfrakrMathematical Bold Fraktur Small R
    U+1D598𝖘\bfraksMathematical Bold Fraktur Small S
    U+1D599𝖙\bfraktMathematical Bold Fraktur Small T
    U+1D59A𝖚\bfrakuMathematical Bold Fraktur Small U
    U+1D59B𝖛\bfrakvMathematical Bold Fraktur Small V
    U+1D59C𝖜\bfrakwMathematical Bold Fraktur Small W
    U+1D59D𝖝\bfrakxMathematical Bold Fraktur Small X
    U+1D59E𝖞\bfrakyMathematical Bold Fraktur Small Y
    U+1D59F𝖟\bfrakzMathematical Bold Fraktur Small Z
    U+1D5A0𝖠\sansAMathematical Sans-Serif Capital A
    U+1D5A1𝖡\sansBMathematical Sans-Serif Capital B
    U+1D5A2𝖢\sansCMathematical Sans-Serif Capital C
    U+1D5A3𝖣\sansDMathematical Sans-Serif Capital D
    U+1D5A4𝖤\sansEMathematical Sans-Serif Capital E
    U+1D5A5𝖥\sansFMathematical Sans-Serif Capital F
    U+1D5A6𝖦\sansGMathematical Sans-Serif Capital G
    U+1D5A7𝖧\sansHMathematical Sans-Serif Capital H
    U+1D5A8𝖨\sansIMathematical Sans-Serif Capital I
    U+1D5A9𝖩\sansJMathematical Sans-Serif Capital J
    U+1D5AA𝖪\sansKMathematical Sans-Serif Capital K
    U+1D5AB𝖫\sansLMathematical Sans-Serif Capital L
    U+1D5AC𝖬\sansMMathematical Sans-Serif Capital M
    U+1D5AD𝖭\sansNMathematical Sans-Serif Capital N
    U+1D5AE𝖮\sansOMathematical Sans-Serif Capital O
    U+1D5AF𝖯\sansPMathematical Sans-Serif Capital P
    U+1D5B0𝖰\sansQMathematical Sans-Serif Capital Q
    U+1D5B1𝖱\sansRMathematical Sans-Serif Capital R
    U+1D5B2𝖲\sansSMathematical Sans-Serif Capital S
    U+1D5B3𝖳\sansTMathematical Sans-Serif Capital T
    U+1D5B4𝖴\sansUMathematical Sans-Serif Capital U
    U+1D5B5𝖵\sansVMathematical Sans-Serif Capital V
    U+1D5B6𝖶\sansWMathematical Sans-Serif Capital W
    U+1D5B7𝖷\sansXMathematical Sans-Serif Capital X
    U+1D5B8𝖸\sansYMathematical Sans-Serif Capital Y
    U+1D5B9𝖹\sansZMathematical Sans-Serif Capital Z
    U+1D5BA𝖺\sansaMathematical Sans-Serif Small A
    U+1D5BB𝖻\sansbMathematical Sans-Serif Small B
    U+1D5BC𝖼\sanscMathematical Sans-Serif Small C
    U+1D5BD𝖽\sansdMathematical Sans-Serif Small D
    U+1D5BE𝖾\sanseMathematical Sans-Serif Small E
    U+1D5BF𝖿\sansfMathematical Sans-Serif Small F
    U+1D5C0𝗀\sansgMathematical Sans-Serif Small G
    U+1D5C1𝗁\sanshMathematical Sans-Serif Small H
    U+1D5C2𝗂\sansiMathematical Sans-Serif Small I
    U+1D5C3𝗃\sansjMathematical Sans-Serif Small J
    U+1D5C4𝗄\sanskMathematical Sans-Serif Small K
    U+1D5C5𝗅\sanslMathematical Sans-Serif Small L
    U+1D5C6𝗆\sansmMathematical Sans-Serif Small M
    U+1D5C7𝗇\sansnMathematical Sans-Serif Small N
    U+1D5C8𝗈\sansoMathematical Sans-Serif Small O
    U+1D5C9𝗉\sanspMathematical Sans-Serif Small P
    U+1D5CA𝗊\sansqMathematical Sans-Serif Small Q
    U+1D5CB𝗋\sansrMathematical Sans-Serif Small R
    U+1D5CC𝗌\sanssMathematical Sans-Serif Small S
    U+1D5CD𝗍\sanstMathematical Sans-Serif Small T
    U+1D5CE𝗎\sansuMathematical Sans-Serif Small U
    U+1D5CF𝗏\sansvMathematical Sans-Serif Small V
    U+1D5D0𝗐\sanswMathematical Sans-Serif Small W
    U+1D5D1𝗑\sansxMathematical Sans-Serif Small X
    U+1D5D2𝗒\sansyMathematical Sans-Serif Small Y
    U+1D5D3𝗓\sanszMathematical Sans-Serif Small Z
    U+1D5D4𝗔\bsansAMathematical Sans-Serif Bold Capital A
    U+1D5D5𝗕\bsansBMathematical Sans-Serif Bold Capital B
    U+1D5D6𝗖\bsansCMathematical Sans-Serif Bold Capital C
    U+1D5D7𝗗\bsansDMathematical Sans-Serif Bold Capital D
    U+1D5D8𝗘\bsansEMathematical Sans-Serif Bold Capital E
    U+1D5D9𝗙\bsansFMathematical Sans-Serif Bold Capital F
    U+1D5DA𝗚\bsansGMathematical Sans-Serif Bold Capital G
    U+1D5DB𝗛\bsansHMathematical Sans-Serif Bold Capital H
    U+1D5DC𝗜\bsansIMathematical Sans-Serif Bold Capital I
    U+1D5DD𝗝\bsansJMathematical Sans-Serif Bold Capital J
    U+1D5DE𝗞\bsansKMathematical Sans-Serif Bold Capital K
    U+1D5DF𝗟\bsansLMathematical Sans-Serif Bold Capital L
    U+1D5E0𝗠\bsansMMathematical Sans-Serif Bold Capital M
    U+1D5E1𝗡\bsansNMathematical Sans-Serif Bold Capital N
    U+1D5E2𝗢\bsansOMathematical Sans-Serif Bold Capital O
    U+1D5E3𝗣\bsansPMathematical Sans-Serif Bold Capital P
    U+1D5E4𝗤\bsansQMathematical Sans-Serif Bold Capital Q
    U+1D5E5𝗥\bsansRMathematical Sans-Serif Bold Capital R
    U+1D5E6𝗦\bsansSMathematical Sans-Serif Bold Capital S
    U+1D5E7𝗧\bsansTMathematical Sans-Serif Bold Capital T
    U+1D5E8𝗨\bsansUMathematical Sans-Serif Bold Capital U
    U+1D5E9𝗩\bsansVMathematical Sans-Serif Bold Capital V
    U+1D5EA𝗪\bsansWMathematical Sans-Serif Bold Capital W
    U+1D5EB𝗫\bsansXMathematical Sans-Serif Bold Capital X
    U+1D5EC𝗬\bsansYMathematical Sans-Serif Bold Capital Y
    U+1D5ED𝗭\bsansZMathematical Sans-Serif Bold Capital Z
    U+1D5EE𝗮\bsansaMathematical Sans-Serif Bold Small A
    U+1D5EF𝗯\bsansbMathematical Sans-Serif Bold Small B
    U+1D5F0𝗰\bsanscMathematical Sans-Serif Bold Small C
    U+1D5F1𝗱\bsansdMathematical Sans-Serif Bold Small D
    U+1D5F2𝗲\bsanseMathematical Sans-Serif Bold Small E
    U+1D5F3𝗳\bsansfMathematical Sans-Serif Bold Small F
    U+1D5F4𝗴\bsansgMathematical Sans-Serif Bold Small G
    U+1D5F5𝗵\bsanshMathematical Sans-Serif Bold Small H
    U+1D5F6𝗶\bsansiMathematical Sans-Serif Bold Small I
    U+1D5F7𝗷\bsansjMathematical Sans-Serif Bold Small J
    U+1D5F8𝗸\bsanskMathematical Sans-Serif Bold Small K
    U+1D5F9𝗹\bsanslMathematical Sans-Serif Bold Small L
    U+1D5FA𝗺\bsansmMathematical Sans-Serif Bold Small M
    U+1D5FB𝗻\bsansnMathematical Sans-Serif Bold Small N
    U+1D5FC𝗼\bsansoMathematical Sans-Serif Bold Small O
    U+1D5FD𝗽\bsanspMathematical Sans-Serif Bold Small P
    U+1D5FE𝗾\bsansqMathematical Sans-Serif Bold Small Q
    U+1D5FF𝗿\bsansrMathematical Sans-Serif Bold Small R
    U+1D600𝘀\bsanssMathematical Sans-Serif Bold Small S
    U+1D601𝘁\bsanstMathematical Sans-Serif Bold Small T
    U+1D602𝘂\bsansuMathematical Sans-Serif Bold Small U
    U+1D603𝘃\bsansvMathematical Sans-Serif Bold Small V
    U+1D604𝘄\bsanswMathematical Sans-Serif Bold Small W
    U+1D605𝘅\bsansxMathematical Sans-Serif Bold Small X
    U+1D606𝘆\bsansyMathematical Sans-Serif Bold Small Y
    U+1D607𝘇\bsanszMathematical Sans-Serif Bold Small Z
    U+1D608𝘈\isansAMathematical Sans-Serif Italic Capital A
    U+1D609𝘉\isansBMathematical Sans-Serif Italic Capital B
    U+1D60A𝘊\isansCMathematical Sans-Serif Italic Capital C
    U+1D60B𝘋\isansDMathematical Sans-Serif Italic Capital D
    U+1D60C𝘌\isansEMathematical Sans-Serif Italic Capital E
    U+1D60D𝘍\isansFMathematical Sans-Serif Italic Capital F
    U+1D60E𝘎\isansGMathematical Sans-Serif Italic Capital G
    U+1D60F𝘏\isansHMathematical Sans-Serif Italic Capital H
    U+1D610𝘐\isansIMathematical Sans-Serif Italic Capital I
    U+1D611𝘑\isansJMathematical Sans-Serif Italic Capital J
    U+1D612𝘒\isansKMathematical Sans-Serif Italic Capital K
    U+1D613𝘓\isansLMathematical Sans-Serif Italic Capital L
    U+1D614𝘔\isansMMathematical Sans-Serif Italic Capital M
    U+1D615𝘕\isansNMathematical Sans-Serif Italic Capital N
    U+1D616𝘖\isansOMathematical Sans-Serif Italic Capital O
    U+1D617𝘗\isansPMathematical Sans-Serif Italic Capital P
    U+1D618𝘘\isansQMathematical Sans-Serif Italic Capital Q
    U+1D619𝘙\isansRMathematical Sans-Serif Italic Capital R
    U+1D61A𝘚\isansSMathematical Sans-Serif Italic Capital S
    U+1D61B𝘛\isansTMathematical Sans-Serif Italic Capital T
    U+1D61C𝘜\isansUMathematical Sans-Serif Italic Capital U
    U+1D61D𝘝\isansVMathematical Sans-Serif Italic Capital V
    U+1D61E𝘞\isansWMathematical Sans-Serif Italic Capital W
    U+1D61F𝘟\isansXMathematical Sans-Serif Italic Capital X
    U+1D620𝘠\isansYMathematical Sans-Serif Italic Capital Y
    U+1D621𝘡\isansZMathematical Sans-Serif Italic Capital Z
    U+1D622𝘢\isansaMathematical Sans-Serif Italic Small A
    U+1D623𝘣\isansbMathematical Sans-Serif Italic Small B
    U+1D624𝘤\isanscMathematical Sans-Serif Italic Small C
    U+1D625𝘥\isansdMathematical Sans-Serif Italic Small D
    U+1D626𝘦\isanseMathematical Sans-Serif Italic Small E
    U+1D627𝘧\isansfMathematical Sans-Serif Italic Small F
    U+1D628𝘨\isansgMathematical Sans-Serif Italic Small G
    U+1D629𝘩\isanshMathematical Sans-Serif Italic Small H
    U+1D62A𝘪\isansiMathematical Sans-Serif Italic Small I
    U+1D62B𝘫\isansjMathematical Sans-Serif Italic Small J
    U+1D62C𝘬\isanskMathematical Sans-Serif Italic Small K
    U+1D62D𝘭\isanslMathematical Sans-Serif Italic Small L
    U+1D62E𝘮\isansmMathematical Sans-Serif Italic Small M
    U+1D62F𝘯\isansnMathematical Sans-Serif Italic Small N
    U+1D630𝘰\isansoMathematical Sans-Serif Italic Small O
    U+1D631𝘱\isanspMathematical Sans-Serif Italic Small P
    U+1D632𝘲\isansqMathematical Sans-Serif Italic Small Q
    U+1D633𝘳\isansrMathematical Sans-Serif Italic Small R
    U+1D634𝘴\isanssMathematical Sans-Serif Italic Small S
    U+1D635𝘵\isanstMathematical Sans-Serif Italic Small T
    U+1D636𝘶\isansuMathematical Sans-Serif Italic Small U
    U+1D637𝘷\isansvMathematical Sans-Serif Italic Small V
    U+1D638𝘸\isanswMathematical Sans-Serif Italic Small W
    U+1D639𝘹\isansxMathematical Sans-Serif Italic Small X
    U+1D63A𝘺\isansyMathematical Sans-Serif Italic Small Y
    U+1D63B𝘻\isanszMathematical Sans-Serif Italic Small Z
    U+1D63C𝘼\bisansAMathematical Sans-Serif Bold Italic Capital A
    U+1D63D𝘽\bisansBMathematical Sans-Serif Bold Italic Capital B
    U+1D63E𝘾\bisansCMathematical Sans-Serif Bold Italic Capital C
    U+1D63F𝘿\bisansDMathematical Sans-Serif Bold Italic Capital D
    U+1D640𝙀\bisansEMathematical Sans-Serif Bold Italic Capital E
    U+1D641𝙁\bisansFMathematical Sans-Serif Bold Italic Capital F
    U+1D642𝙂\bisansGMathematical Sans-Serif Bold Italic Capital G
    U+1D643𝙃\bisansHMathematical Sans-Serif Bold Italic Capital H
    U+1D644𝙄\bisansIMathematical Sans-Serif Bold Italic Capital I
    U+1D645𝙅\bisansJMathematical Sans-Serif Bold Italic Capital J
    U+1D646𝙆\bisansKMathematical Sans-Serif Bold Italic Capital K
    U+1D647𝙇\bisansLMathematical Sans-Serif Bold Italic Capital L
    U+1D648𝙈\bisansMMathematical Sans-Serif Bold Italic Capital M
    U+1D649𝙉\bisansNMathematical Sans-Serif Bold Italic Capital N
    U+1D64A𝙊\bisansOMathematical Sans-Serif Bold Italic Capital O
    U+1D64B𝙋\bisansPMathematical Sans-Serif Bold Italic Capital P
    U+1D64C𝙌\bisansQMathematical Sans-Serif Bold Italic Capital Q
    U+1D64D𝙍\bisansRMathematical Sans-Serif Bold Italic Capital R
    U+1D64E𝙎\bisansSMathematical Sans-Serif Bold Italic Capital S
    U+1D64F𝙏\bisansTMathematical Sans-Serif Bold Italic Capital T
    U+1D650𝙐\bisansUMathematical Sans-Serif Bold Italic Capital U
    U+1D651𝙑\bisansVMathematical Sans-Serif Bold Italic Capital V
    U+1D652𝙒\bisansWMathematical Sans-Serif Bold Italic Capital W
    U+1D653𝙓\bisansXMathematical Sans-Serif Bold Italic Capital X
    U+1D654𝙔\bisansYMathematical Sans-Serif Bold Italic Capital Y
    U+1D655𝙕\bisansZMathematical Sans-Serif Bold Italic Capital Z
    U+1D656𝙖\bisansaMathematical Sans-Serif Bold Italic Small A
    U+1D657𝙗\bisansbMathematical Sans-Serif Bold Italic Small B
    U+1D658𝙘\bisanscMathematical Sans-Serif Bold Italic Small C
    U+1D659𝙙\bisansdMathematical Sans-Serif Bold Italic Small D
    U+1D65A𝙚\bisanseMathematical Sans-Serif Bold Italic Small E
    U+1D65B𝙛\bisansfMathematical Sans-Serif Bold Italic Small F
    U+1D65C𝙜\bisansgMathematical Sans-Serif Bold Italic Small G
    U+1D65D𝙝\bisanshMathematical Sans-Serif Bold Italic Small H
    U+1D65E𝙞\bisansiMathematical Sans-Serif Bold Italic Small I
    U+1D65F𝙟\bisansjMathematical Sans-Serif Bold Italic Small J
    U+1D660𝙠\bisanskMathematical Sans-Serif Bold Italic Small K
    U+1D661𝙡\bisanslMathematical Sans-Serif Bold Italic Small L
    U+1D662𝙢\bisansmMathematical Sans-Serif Bold Italic Small M
    U+1D663𝙣\bisansnMathematical Sans-Serif Bold Italic Small N
    U+1D664𝙤\bisansoMathematical Sans-Serif Bold Italic Small O
    U+1D665𝙥\bisanspMathematical Sans-Serif Bold Italic Small P
    U+1D666𝙦\bisansqMathematical Sans-Serif Bold Italic Small Q
    U+1D667𝙧\bisansrMathematical Sans-Serif Bold Italic Small R
    U+1D668𝙨\bisanssMathematical Sans-Serif Bold Italic Small S
    U+1D669𝙩\bisanstMathematical Sans-Serif Bold Italic Small T
    U+1D66A𝙪\bisansuMathematical Sans-Serif Bold Italic Small U
    U+1D66B𝙫\bisansvMathematical Sans-Serif Bold Italic Small V
    U+1D66C𝙬\bisanswMathematical Sans-Serif Bold Italic Small W
    U+1D66D𝙭\bisansxMathematical Sans-Serif Bold Italic Small X
    U+1D66E𝙮\bisansyMathematical Sans-Serif Bold Italic Small Y
    U+1D66F𝙯\bisanszMathematical Sans-Serif Bold Italic Small Z
    U+1D670𝙰\ttAMathematical Monospace Capital A
    U+1D671𝙱\ttBMathematical Monospace Capital B
    U+1D672𝙲\ttCMathematical Monospace Capital C
    U+1D673𝙳\ttDMathematical Monospace Capital D
    U+1D674𝙴\ttEMathematical Monospace Capital E
    U+1D675𝙵\ttFMathematical Monospace Capital F
    U+1D676𝙶\ttGMathematical Monospace Capital G
    U+1D677𝙷\ttHMathematical Monospace Capital H
    U+1D678𝙸\ttIMathematical Monospace Capital I
    U+1D679𝙹\ttJMathematical Monospace Capital J
    U+1D67A𝙺\ttKMathematical Monospace Capital K
    U+1D67B𝙻\ttLMathematical Monospace Capital L
    U+1D67C𝙼\ttMMathematical Monospace Capital M
    U+1D67D𝙽\ttNMathematical Monospace Capital N
    U+1D67E𝙾\ttOMathematical Monospace Capital O
    U+1D67F𝙿\ttPMathematical Monospace Capital P
    U+1D680𝚀\ttQMathematical Monospace Capital Q
    U+1D681𝚁\ttRMathematical Monospace Capital R
    U+1D682𝚂\ttSMathematical Monospace Capital S
    U+1D683𝚃\ttTMathematical Monospace Capital T
    U+1D684𝚄\ttUMathematical Monospace Capital U
    U+1D685𝚅\ttVMathematical Monospace Capital V
    U+1D686𝚆\ttWMathematical Monospace Capital W
    U+1D687𝚇\ttXMathematical Monospace Capital X
    U+1D688𝚈\ttYMathematical Monospace Capital Y
    U+1D689𝚉\ttZMathematical Monospace Capital Z
    U+1D68A𝚊\ttaMathematical Monospace Small A
    U+1D68B𝚋\ttbMathematical Monospace Small B
    U+1D68C𝚌\ttcMathematical Monospace Small C
    U+1D68D𝚍\ttdMathematical Monospace Small D
    U+1D68E𝚎\tteMathematical Monospace Small E
    U+1D68F𝚏\ttfMathematical Monospace Small F
    U+1D690𝚐\ttgMathematical Monospace Small G
    U+1D691𝚑\tthMathematical Monospace Small H
    U+1D692𝚒\ttiMathematical Monospace Small I
    U+1D693𝚓\ttjMathematical Monospace Small J
    U+1D694𝚔\ttkMathematical Monospace Small K
    U+1D695𝚕\ttlMathematical Monospace Small L
    U+1D696𝚖\ttmMathematical Monospace Small M
    U+1D697𝚗\ttnMathematical Monospace Small N
    U+1D698𝚘\ttoMathematical Monospace Small O
    U+1D699𝚙\ttpMathematical Monospace Small P
    U+1D69A𝚚\ttqMathematical Monospace Small Q
    U+1D69B𝚛\ttrMathematical Monospace Small R
    U+1D69C𝚜\ttsMathematical Monospace Small S
    U+1D69D𝚝\tttMathematical Monospace Small T
    U+1D69E𝚞\ttuMathematical Monospace Small U
    U+1D69F𝚟\ttvMathematical Monospace Small V
    U+1D6A0𝚠\ttwMathematical Monospace Small W
    U+1D6A1𝚡\ttxMathematical Monospace Small X
    U+1D6A2𝚢\ttyMathematical Monospace Small Y
    U+1D6A3𝚣\ttzMathematical Monospace Small Z
    U+1D6A4𝚤\itimathMathematical Italic Small Dotless I
    U+1D6A5𝚥\itjmathMathematical Italic Small Dotless J
    U+1D6A8𝚨\bfAlphaMathematical Bold Capital Alpha
    U+1D6A9𝚩\bfBetaMathematical Bold Capital Beta
    U+1D6AA𝚪\bfGammaMathematical Bold Capital Gamma
    U+1D6AB𝚫\bfDeltaMathematical Bold Capital Delta
    U+1D6AC𝚬\bfEpsilonMathematical Bold Capital Epsilon
    U+1D6AD𝚭\bfZetaMathematical Bold Capital Zeta
    U+1D6AE𝚮\bfEtaMathematical Bold Capital Eta
    U+1D6AF𝚯\bfThetaMathematical Bold Capital Theta
    U+1D6B0𝚰\bfIotaMathematical Bold Capital Iota
    U+1D6B1𝚱\bfKappaMathematical Bold Capital Kappa
    U+1D6B2𝚲\bfLambdaMathematical Bold Capital Lamda
    U+1D6B3𝚳\bfMuMathematical Bold Capital Mu
    U+1D6B4𝚴\bfNuMathematical Bold Capital Nu
    U+1D6B5𝚵\bfXiMathematical Bold Capital Xi
    U+1D6B6𝚶\bfOmicronMathematical Bold Capital Omicron
    U+1D6B7𝚷\bfPiMathematical Bold Capital Pi
    U+1D6B8𝚸\bfRhoMathematical Bold Capital Rho
    U+1D6B9𝚹\bfvarThetaMathematical Bold Capital Theta Symbol
    U+1D6BA𝚺\bfSigmaMathematical Bold Capital Sigma
    U+1D6BB𝚻\bfTauMathematical Bold Capital Tau
    U+1D6BC𝚼\bfUpsilonMathematical Bold Capital Upsilon
    U+1D6BD𝚽\bfPhiMathematical Bold Capital Phi
    U+1D6BE𝚾\bfChiMathematical Bold Capital Chi
    U+1D6BF𝚿\bfPsiMathematical Bold Capital Psi
    U+1D6C0𝛀\bfOmegaMathematical Bold Capital Omega
    U+1D6C1𝛁\bfnablaMathematical Bold Nabla
    U+1D6C2𝛂\bfalphaMathematical Bold Small Alpha
    U+1D6C3𝛃\bfbetaMathematical Bold Small Beta
    U+1D6C4𝛄\bfgammaMathematical Bold Small Gamma
    U+1D6C5𝛅\bfdeltaMathematical Bold Small Delta
    U+1D6C6𝛆\bfvarepsilonMathematical Bold Small Epsilon
    U+1D6C7𝛇\bfzetaMathematical Bold Small Zeta
    U+1D6C8𝛈\bfetaMathematical Bold Small Eta
    U+1D6C9𝛉\bfthetaMathematical Bold Small Theta
    U+1D6CA𝛊\bfiotaMathematical Bold Small Iota
    U+1D6CB𝛋\bfkappaMathematical Bold Small Kappa
    U+1D6CC𝛌\bflambdaMathematical Bold Small Lamda
    U+1D6CD𝛍\bfmuMathematical Bold Small Mu
    U+1D6CE𝛎\bfnuMathematical Bold Small Nu
    U+1D6CF𝛏\bfxiMathematical Bold Small Xi
    U+1D6D0𝛐\bfomicronMathematical Bold Small Omicron
    U+1D6D1𝛑\bfpiMathematical Bold Small Pi
    U+1D6D2𝛒\bfrhoMathematical Bold Small Rho
    U+1D6D3𝛓\bfvarsigmaMathematical Bold Small Final Sigma
    U+1D6D4𝛔\bfsigmaMathematical Bold Small Sigma
    U+1D6D5𝛕\bftauMathematical Bold Small Tau
    U+1D6D6𝛖\bfupsilonMathematical Bold Small Upsilon
    U+1D6D7𝛗\bfvarphiMathematical Bold Small Phi
    U+1D6D8𝛘\bfchiMathematical Bold Small Chi
    U+1D6D9𝛙\bfpsiMathematical Bold Small Psi
    U+1D6DA𝛚\bfomegaMathematical Bold Small Omega
    U+1D6DB𝛛\bfpartialMathematical Bold Partial Differential
    U+1D6DC𝛜\bfepsilonMathematical Bold Epsilon Symbol
    U+1D6DD𝛝\bfvarthetaMathematical Bold Theta Symbol
    U+1D6DE𝛞\bfvarkappaMathematical Bold Kappa Symbol
    U+1D6DF𝛟\bfphiMathematical Bold Phi Symbol
    U+1D6E0𝛠\bfvarrhoMathematical Bold Rho Symbol
    U+1D6E1𝛡\bfvarpiMathematical Bold Pi Symbol
    U+1D6E2𝛢\itAlphaMathematical Italic Capital Alpha
    U+1D6E3𝛣\itBetaMathematical Italic Capital Beta
    U+1D6E4𝛤\itGammaMathematical Italic Capital Gamma
    U+1D6E5𝛥\itDeltaMathematical Italic Capital Delta
    U+1D6E6𝛦\itEpsilonMathematical Italic Capital Epsilon
    U+1D6E7𝛧\itZetaMathematical Italic Capital Zeta
    U+1D6E8𝛨\itEtaMathematical Italic Capital Eta
    U+1D6E9𝛩\itThetaMathematical Italic Capital Theta
    U+1D6EA𝛪\itIotaMathematical Italic Capital Iota
    U+1D6EB𝛫\itKappaMathematical Italic Capital Kappa
    U+1D6EC𝛬\itLambdaMathematical Italic Capital Lamda
    U+1D6ED𝛭\itMuMathematical Italic Capital Mu
    U+1D6EE𝛮\itNuMathematical Italic Capital Nu
    U+1D6EF𝛯\itXiMathematical Italic Capital Xi
    U+1D6F0𝛰\itOmicronMathematical Italic Capital Omicron
    U+1D6F1𝛱\itPiMathematical Italic Capital Pi
    U+1D6F2𝛲\itRhoMathematical Italic Capital Rho
    U+1D6F3𝛳\itvarThetaMathematical Italic Capital Theta Symbol
    U+1D6F4𝛴\itSigmaMathematical Italic Capital Sigma
    U+1D6F5𝛵\itTauMathematical Italic Capital Tau
    U+1D6F6𝛶\itUpsilonMathematical Italic Capital Upsilon
    U+1D6F7𝛷\itPhiMathematical Italic Capital Phi
    U+1D6F8𝛸\itChiMathematical Italic Capital Chi
    U+1D6F9𝛹\itPsiMathematical Italic Capital Psi
    U+1D6FA𝛺\itOmegaMathematical Italic Capital Omega
    U+1D6FB𝛻\itnablaMathematical Italic Nabla
    U+1D6FC𝛼\italphaMathematical Italic Small Alpha
    U+1D6FD𝛽\itbetaMathematical Italic Small Beta
    U+1D6FE𝛾\itgammaMathematical Italic Small Gamma
    U+1D6FF𝛿\itdeltaMathematical Italic Small Delta
    U+1D700𝜀\itvarepsilonMathematical Italic Small Epsilon
    U+1D701𝜁\itzetaMathematical Italic Small Zeta
    U+1D702𝜂\itetaMathematical Italic Small Eta
    U+1D703𝜃\itthetaMathematical Italic Small Theta
    U+1D704𝜄\itiotaMathematical Italic Small Iota
    U+1D705𝜅\itkappaMathematical Italic Small Kappa
    U+1D706𝜆\itlambdaMathematical Italic Small Lamda
    U+1D707𝜇\itmuMathematical Italic Small Mu
    U+1D708𝜈\itnuMathematical Italic Small Nu
    U+1D709𝜉\itxiMathematical Italic Small Xi
    U+1D70A𝜊\itomicronMathematical Italic Small Omicron
    U+1D70B𝜋\itpiMathematical Italic Small Pi
    U+1D70C𝜌\itrhoMathematical Italic Small Rho
    U+1D70D𝜍\itvarsigmaMathematical Italic Small Final Sigma
    U+1D70E𝜎\itsigmaMathematical Italic Small Sigma
    U+1D70F𝜏\ittauMathematical Italic Small Tau
    U+1D710𝜐\itupsilonMathematical Italic Small Upsilon
    U+1D711𝜑\itvarphiMathematical Italic Small Phi
    U+1D712𝜒\itchiMathematical Italic Small Chi
    U+1D713𝜓\itpsiMathematical Italic Small Psi
    U+1D714𝜔\itomegaMathematical Italic Small Omega
    U+1D715𝜕\itpartialMathematical Italic Partial Differential
    U+1D716𝜖\itepsilonMathematical Italic Epsilon Symbol
    U+1D717𝜗\itvarthetaMathematical Italic Theta Symbol
    U+1D718𝜘\itvarkappaMathematical Italic Kappa Symbol
    U+1D719𝜙\itphiMathematical Italic Phi Symbol
    U+1D71A𝜚\itvarrhoMathematical Italic Rho Symbol
    U+1D71B𝜛\itvarpiMathematical Italic Pi Symbol
    U+1D71C𝜜\biAlphaMathematical Bold Italic Capital Alpha
    U+1D71D𝜝\biBetaMathematical Bold Italic Capital Beta
    U+1D71E𝜞\biGammaMathematical Bold Italic Capital Gamma
    U+1D71F𝜟\biDeltaMathematical Bold Italic Capital Delta
    U+1D720𝜠\biEpsilonMathematical Bold Italic Capital Epsilon
    U+1D721𝜡\biZetaMathematical Bold Italic Capital Zeta
    U+1D722𝜢\biEtaMathematical Bold Italic Capital Eta
    U+1D723𝜣\biThetaMathematical Bold Italic Capital Theta
    U+1D724𝜤\biIotaMathematical Bold Italic Capital Iota
    U+1D725𝜥\biKappaMathematical Bold Italic Capital Kappa
    U+1D726𝜦\biLambdaMathematical Bold Italic Capital Lamda
    U+1D727𝜧\biMuMathematical Bold Italic Capital Mu
    U+1D728𝜨\biNuMathematical Bold Italic Capital Nu
    U+1D729𝜩\biXiMathematical Bold Italic Capital Xi
    U+1D72A𝜪\biOmicronMathematical Bold Italic Capital Omicron
    U+1D72B𝜫\biPiMathematical Bold Italic Capital Pi
    U+1D72C𝜬\biRhoMathematical Bold Italic Capital Rho
    U+1D72D𝜭\bivarThetaMathematical Bold Italic Capital Theta Symbol
    U+1D72E𝜮\biSigmaMathematical Bold Italic Capital Sigma
    U+1D72F𝜯\biTauMathematical Bold Italic Capital Tau
    U+1D730𝜰\biUpsilonMathematical Bold Italic Capital Upsilon
    U+1D731𝜱\biPhiMathematical Bold Italic Capital Phi
    U+1D732𝜲\biChiMathematical Bold Italic Capital Chi
    U+1D733𝜳\biPsiMathematical Bold Italic Capital Psi
    U+1D734𝜴\biOmegaMathematical Bold Italic Capital Omega
    U+1D735𝜵\binablaMathematical Bold Italic Nabla
    U+1D736𝜶\bialphaMathematical Bold Italic Small Alpha
    U+1D737𝜷\bibetaMathematical Bold Italic Small Beta
    U+1D738𝜸\bigammaMathematical Bold Italic Small Gamma
    U+1D739𝜹\bideltaMathematical Bold Italic Small Delta
    U+1D73A𝜺\bivarepsilonMathematical Bold Italic Small Epsilon
    U+1D73B𝜻\bizetaMathematical Bold Italic Small Zeta
    U+1D73C𝜼\bietaMathematical Bold Italic Small Eta
    U+1D73D𝜽\bithetaMathematical Bold Italic Small Theta
    U+1D73E𝜾\biiotaMathematical Bold Italic Small Iota
    U+1D73F𝜿\bikappaMathematical Bold Italic Small Kappa
    U+1D740𝝀\bilambdaMathematical Bold Italic Small Lamda
    U+1D741𝝁\bimuMathematical Bold Italic Small Mu
    U+1D742𝝂\binuMathematical Bold Italic Small Nu
    U+1D743𝝃\bixiMathematical Bold Italic Small Xi
    U+1D744𝝄\biomicronMathematical Bold Italic Small Omicron
    U+1D745𝝅\bipiMathematical Bold Italic Small Pi
    U+1D746𝝆\birhoMathematical Bold Italic Small Rho
    U+1D747𝝇\bivarsigmaMathematical Bold Italic Small Final Sigma
    U+1D748𝝈\bisigmaMathematical Bold Italic Small Sigma
    U+1D749𝝉\bitauMathematical Bold Italic Small Tau
    U+1D74A𝝊\biupsilonMathematical Bold Italic Small Upsilon
    U+1D74B𝝋\bivarphiMathematical Bold Italic Small Phi
    U+1D74C𝝌\bichiMathematical Bold Italic Small Chi
    U+1D74D𝝍\bipsiMathematical Bold Italic Small Psi
    U+1D74E𝝎\biomegaMathematical Bold Italic Small Omega
    U+1D74F𝝏\bipartialMathematical Bold Italic Partial Differential
    U+1D750𝝐\biepsilonMathematical Bold Italic Epsilon Symbol
    U+1D751𝝑\bivarthetaMathematical Bold Italic Theta Symbol
    U+1D752𝝒\bivarkappaMathematical Bold Italic Kappa Symbol
    U+1D753𝝓\biphiMathematical Bold Italic Phi Symbol
    U+1D754𝝔\bivarrhoMathematical Bold Italic Rho Symbol
    U+1D755𝝕\bivarpiMathematical Bold Italic Pi Symbol
    U+1D756𝝖\bsansAlphaMathematical Sans-Serif Bold Capital Alpha
    U+1D757𝝗\bsansBetaMathematical Sans-Serif Bold Capital Beta
    U+1D758𝝘\bsansGammaMathematical Sans-Serif Bold Capital Gamma
    U+1D759𝝙\bsansDeltaMathematical Sans-Serif Bold Capital Delta
    U+1D75A𝝚\bsansEpsilonMathematical Sans-Serif Bold Capital Epsilon
    U+1D75B𝝛\bsansZetaMathematical Sans-Serif Bold Capital Zeta
    U+1D75C𝝜\bsansEtaMathematical Sans-Serif Bold Capital Eta
    U+1D75D𝝝\bsansThetaMathematical Sans-Serif Bold Capital Theta
    U+1D75E𝝞\bsansIotaMathematical Sans-Serif Bold Capital Iota
    U+1D75F𝝟\bsansKappaMathematical Sans-Serif Bold Capital Kappa
    U+1D760𝝠\bsansLambdaMathematical Sans-Serif Bold Capital Lamda
    U+1D761𝝡\bsansMuMathematical Sans-Serif Bold Capital Mu
    U+1D762𝝢\bsansNuMathematical Sans-Serif Bold Capital Nu
    U+1D763𝝣\bsansXiMathematical Sans-Serif Bold Capital Xi
    U+1D764𝝤\bsansOmicronMathematical Sans-Serif Bold Capital Omicron
    U+1D765𝝥\bsansPiMathematical Sans-Serif Bold Capital Pi
    U+1D766𝝦\bsansRhoMathematical Sans-Serif Bold Capital Rho
    U+1D767𝝧\bsansvarThetaMathematical Sans-Serif Bold Capital Theta Symbol
    U+1D768𝝨\bsansSigmaMathematical Sans-Serif Bold Capital Sigma
    U+1D769𝝩\bsansTauMathematical Sans-Serif Bold Capital Tau
    U+1D76A𝝪\bsansUpsilonMathematical Sans-Serif Bold Capital Upsilon
    U+1D76B𝝫\bsansPhiMathematical Sans-Serif Bold Capital Phi
    U+1D76C𝝬\bsansChiMathematical Sans-Serif Bold Capital Chi
    U+1D76D𝝭\bsansPsiMathematical Sans-Serif Bold Capital Psi
    U+1D76E𝝮\bsansOmegaMathematical Sans-Serif Bold Capital Omega
    U+1D76F𝝯\bsansnablaMathematical Sans-Serif Bold Nabla
    U+1D770𝝰\bsansalphaMathematical Sans-Serif Bold Small Alpha
    U+1D771𝝱\bsansbetaMathematical Sans-Serif Bold Small Beta
    U+1D772𝝲\bsansgammaMathematical Sans-Serif Bold Small Gamma
    U+1D773𝝳\bsansdeltaMathematical Sans-Serif Bold Small Delta
    U+1D774𝝴\bsansvarepsilonMathematical Sans-Serif Bold Small Epsilon
    U+1D775𝝵\bsanszetaMathematical Sans-Serif Bold Small Zeta
    U+1D776𝝶\bsansetaMathematical Sans-Serif Bold Small Eta
    U+1D777𝝷\bsansthetaMathematical Sans-Serif Bold Small Theta
    U+1D778𝝸\bsansiotaMathematical Sans-Serif Bold Small Iota
    U+1D779𝝹\bsanskappaMathematical Sans-Serif Bold Small Kappa
    U+1D77A𝝺\bsanslambdaMathematical Sans-Serif Bold Small Lamda
    U+1D77B𝝻\bsansmuMathematical Sans-Serif Bold Small Mu
    U+1D77C𝝼\bsansnuMathematical Sans-Serif Bold Small Nu
    U+1D77D𝝽\bsansxiMathematical Sans-Serif Bold Small Xi
    U+1D77E𝝾\bsansomicronMathematical Sans-Serif Bold Small Omicron
    U+1D77F𝝿\bsanspiMathematical Sans-Serif Bold Small Pi
    U+1D780𝞀\bsansrhoMathematical Sans-Serif Bold Small Rho
    U+1D781𝞁\bsansvarsigmaMathematical Sans-Serif Bold Small Final Sigma
    U+1D782𝞂\bsanssigmaMathematical Sans-Serif Bold Small Sigma
    U+1D783𝞃\bsanstauMathematical Sans-Serif Bold Small Tau
    U+1D784𝞄\bsansupsilonMathematical Sans-Serif Bold Small Upsilon
    U+1D785𝞅\bsansvarphiMathematical Sans-Serif Bold Small Phi
    U+1D786𝞆\bsanschiMathematical Sans-Serif Bold Small Chi
    U+1D787𝞇\bsanspsiMathematical Sans-Serif Bold Small Psi
    U+1D788𝞈\bsansomegaMathematical Sans-Serif Bold Small Omega
    U+1D789𝞉\bsanspartialMathematical Sans-Serif Bold Partial Differential
    U+1D78A𝞊\bsansepsilonMathematical Sans-Serif Bold Epsilon Symbol
    U+1D78B𝞋\bsansvarthetaMathematical Sans-Serif Bold Theta Symbol
    U+1D78C𝞌\bsansvarkappaMathematical Sans-Serif Bold Kappa Symbol
    U+1D78D𝞍\bsansphiMathematical Sans-Serif Bold Phi Symbol
    U+1D78E𝞎\bsansvarrhoMathematical Sans-Serif Bold Rho Symbol
    U+1D78F𝞏\bsansvarpiMathematical Sans-Serif Bold Pi Symbol
    U+1D790𝞐\bisansAlphaMathematical Sans-Serif Bold Italic Capital Alpha
    U+1D791𝞑\bisansBetaMathematical Sans-Serif Bold Italic Capital Beta
    U+1D792𝞒\bisansGammaMathematical Sans-Serif Bold Italic Capital Gamma
    U+1D793𝞓\bisansDeltaMathematical Sans-Serif Bold Italic Capital Delta
    U+1D794𝞔\bisansEpsilonMathematical Sans-Serif Bold Italic Capital Epsilon
    U+1D795𝞕\bisansZetaMathematical Sans-Serif Bold Italic Capital Zeta
    U+1D796𝞖\bisansEtaMathematical Sans-Serif Bold Italic Capital Eta
    U+1D797𝞗\bisansThetaMathematical Sans-Serif Bold Italic Capital Theta
    U+1D798𝞘\bisansIotaMathematical Sans-Serif Bold Italic Capital Iota
    U+1D799𝞙\bisansKappaMathematical Sans-Serif Bold Italic Capital Kappa
    U+1D79A𝞚\bisansLambdaMathematical Sans-Serif Bold Italic Capital Lamda
    U+1D79B𝞛\bisansMuMathematical Sans-Serif Bold Italic Capital Mu
    U+1D79C𝞜\bisansNuMathematical Sans-Serif Bold Italic Capital Nu
    U+1D79D𝞝\bisansXiMathematical Sans-Serif Bold Italic Capital Xi
    U+1D79E𝞞\bisansOmicronMathematical Sans-Serif Bold Italic Capital Omicron
    U+1D79F𝞟\bisansPiMathematical Sans-Serif Bold Italic Capital Pi
    U+1D7A0𝞠\bisansRhoMathematical Sans-Serif Bold Italic Capital Rho
    U+1D7A1𝞡\bisansvarThetaMathematical Sans-Serif Bold Italic Capital Theta Symbol
    U+1D7A2𝞢\bisansSigmaMathematical Sans-Serif Bold Italic Capital Sigma
    U+1D7A3𝞣\bisansTauMathematical Sans-Serif Bold Italic Capital Tau
    U+1D7A4𝞤\bisansUpsilonMathematical Sans-Serif Bold Italic Capital Upsilon
    U+1D7A5𝞥\bisansPhiMathematical Sans-Serif Bold Italic Capital Phi
    U+1D7A6𝞦\bisansChiMathematical Sans-Serif Bold Italic Capital Chi
    U+1D7A7𝞧\bisansPsiMathematical Sans-Serif Bold Italic Capital Psi
    U+1D7A8𝞨\bisansOmegaMathematical Sans-Serif Bold Italic Capital Omega
    U+1D7A9𝞩\bisansnablaMathematical Sans-Serif Bold Italic Nabla
    U+1D7AA𝞪\bisansalphaMathematical Sans-Serif Bold Italic Small Alpha
    U+1D7AB𝞫\bisansbetaMathematical Sans-Serif Bold Italic Small Beta
    U+1D7AC𝞬\bisansgammaMathematical Sans-Serif Bold Italic Small Gamma
    U+1D7AD𝞭\bisansdeltaMathematical Sans-Serif Bold Italic Small Delta
    U+1D7AE𝞮\bisansvarepsilonMathematical Sans-Serif Bold Italic Small Epsilon
    U+1D7AF𝞯\bisanszetaMathematical Sans-Serif Bold Italic Small Zeta
    U+1D7B0𝞰\bisansetaMathematical Sans-Serif Bold Italic Small Eta
    U+1D7B1𝞱\bisansthetaMathematical Sans-Serif Bold Italic Small Theta
    U+1D7B2𝞲\bisansiotaMathematical Sans-Serif Bold Italic Small Iota
    U+1D7B3𝞳\bisanskappaMathematical Sans-Serif Bold Italic Small Kappa
    U+1D7B4𝞴\bisanslambdaMathematical Sans-Serif Bold Italic Small Lamda
    U+1D7B5𝞵\bisansmuMathematical Sans-Serif Bold Italic Small Mu
    U+1D7B6𝞶\bisansnuMathematical Sans-Serif Bold Italic Small Nu
    U+1D7B7𝞷\bisansxiMathematical Sans-Serif Bold Italic Small Xi
    U+1D7B8𝞸\bisansomicronMathematical Sans-Serif Bold Italic Small Omicron
    U+1D7B9𝞹\bisanspiMathematical Sans-Serif Bold Italic Small Pi
    U+1D7BA𝞺\bisansrhoMathematical Sans-Serif Bold Italic Small Rho
    U+1D7BB𝞻\bisansvarsigmaMathematical Sans-Serif Bold Italic Small Final Sigma
    U+1D7BC𝞼\bisanssigmaMathematical Sans-Serif Bold Italic Small Sigma
    U+1D7BD𝞽\bisanstauMathematical Sans-Serif Bold Italic Small Tau
    U+1D7BE𝞾\bisansupsilonMathematical Sans-Serif Bold Italic Small Upsilon
    U+1D7BF𝞿\bisansvarphiMathematical Sans-Serif Bold Italic Small Phi
    U+1D7C0𝟀\bisanschiMathematical Sans-Serif Bold Italic Small Chi
    U+1D7C1𝟁\bisanspsiMathematical Sans-Serif Bold Italic Small Psi
    U+1D7C2𝟂\bisansomegaMathematical Sans-Serif Bold Italic Small Omega
    U+1D7C3𝟃\bisanspartialMathematical Sans-Serif Bold Italic Partial Differential
    U+1D7C4𝟄\bisansepsilonMathematical Sans-Serif Bold Italic Epsilon Symbol
    U+1D7C5𝟅\bisansvarthetaMathematical Sans-Serif Bold Italic Theta Symbol
    U+1D7C6𝟆\bisansvarkappaMathematical Sans-Serif Bold Italic Kappa Symbol
    U+1D7C7𝟇\bisansphiMathematical Sans-Serif Bold Italic Phi Symbol
    U+1D7C8𝟈\bisansvarrhoMathematical Sans-Serif Bold Italic Rho Symbol
    U+1D7C9𝟉\bisansvarpiMathematical Sans-Serif Bold Italic Pi Symbol
    U+1D7CA𝟊\bfDigammaMathematical Bold Capital Digamma
    U+1D7CB𝟋\bfdigammaMathematical Bold Small Digamma
    U+1D7CE𝟎\bfzeroMathematical Bold Digit Zero
    U+1D7CF𝟏\bfoneMathematical Bold Digit One
    U+1D7D0𝟐\bftwoMathematical Bold Digit Two
    U+1D7D1𝟑\bfthreeMathematical Bold Digit Three
    U+1D7D2𝟒\bffourMathematical Bold Digit Four
    U+1D7D3𝟓\bffiveMathematical Bold Digit Five
    U+1D7D4𝟔\bfsixMathematical Bold Digit Six
    U+1D7D5𝟕\bfsevenMathematical Bold Digit Seven
    U+1D7D6𝟖\bfeightMathematical Bold Digit Eight
    U+1D7D7𝟗\bfnineMathematical Bold Digit Nine
    U+1D7D8𝟘\bbzeroMathematical Double-Struck Digit Zero
    U+1D7D9𝟙\bboneMathematical Double-Struck Digit One
    U+1D7DA𝟚\bbtwoMathematical Double-Struck Digit Two
    U+1D7DB𝟛\bbthreeMathematical Double-Struck Digit Three
    U+1D7DC𝟜\bbfourMathematical Double-Struck Digit Four
    U+1D7DD𝟝\bbfiveMathematical Double-Struck Digit Five
    U+1D7DE𝟞\bbsixMathematical Double-Struck Digit Six
    U+1D7DF𝟟\bbsevenMathematical Double-Struck Digit Seven
    U+1D7E0𝟠\bbeightMathematical Double-Struck Digit Eight
    U+1D7E1𝟡\bbnineMathematical Double-Struck Digit Nine
    U+1D7E2𝟢\sanszeroMathematical Sans-Serif Digit Zero
    U+1D7E3𝟣\sansoneMathematical Sans-Serif Digit One
    U+1D7E4𝟤\sanstwoMathematical Sans-Serif Digit Two
    U+1D7E5𝟥\sansthreeMathematical Sans-Serif Digit Three
    U+1D7E6𝟦\sansfourMathematical Sans-Serif Digit Four
    U+1D7E7𝟧\sansfiveMathematical Sans-Serif Digit Five
    U+1D7E8𝟨\sanssixMathematical Sans-Serif Digit Six
    U+1D7E9𝟩\sanssevenMathematical Sans-Serif Digit Seven
    U+1D7EA𝟪\sanseightMathematical Sans-Serif Digit Eight
    U+1D7EB𝟫\sansnineMathematical Sans-Serif Digit Nine
    U+1D7EC𝟬\bsanszeroMathematical Sans-Serif Bold Digit Zero
    U+1D7ED𝟭\bsansoneMathematical Sans-Serif Bold Digit One
    U+1D7EE𝟮\bsanstwoMathematical Sans-Serif Bold Digit Two
    U+1D7EF𝟯\bsansthreeMathematical Sans-Serif Bold Digit Three
    U+1D7F0𝟰\bsansfourMathematical Sans-Serif Bold Digit Four
    U+1D7F1𝟱\bsansfiveMathematical Sans-Serif Bold Digit Five
    U+1D7F2𝟲\bsanssixMathematical Sans-Serif Bold Digit Six
    U+1D7F3𝟳\bsanssevenMathematical Sans-Serif Bold Digit Seven
    U+1D7F4𝟴\bsanseightMathematical Sans-Serif Bold Digit Eight
    U+1D7F5𝟵\bsansnineMathematical Sans-Serif Bold Digit Nine
    U+1D7F6𝟶\ttzeroMathematical Monospace Digit Zero
    U+1D7F7𝟷\ttoneMathematical Monospace Digit One
    U+1D7F8𝟸\tttwoMathematical Monospace Digit Two
    U+1D7F9𝟹\ttthreeMathematical Monospace Digit Three
    U+1D7FA𝟺\ttfourMathematical Monospace Digit Four
    U+1D7FB𝟻\ttfiveMathematical Monospace Digit Five
    U+1D7FC𝟼\ttsixMathematical Monospace Digit Six
    U+1D7FD𝟽\ttsevenMathematical Monospace Digit Seven
    U+1D7FE𝟾\tteightMathematical Monospace Digit Eight
    U+1D7FF𝟿\ttnineMathematical Monospace Digit Nine
    U+1F004🀄\:mahjong:Mahjong Tile Red Dragon
    U+1F0CF🃏\:black_joker:Playing Card Black Joker
    U+1F170🅰\:a:Negative Squared Latin Capital Letter A
    U+1F171🅱\:b:Negative Squared Latin Capital Letter B
    U+1F17E🅾\:o2:Negative Squared Latin Capital Letter O
    U+1F17F🅿\:parking:Negative Squared Latin Capital Letter P
    U+1F18E🆎\:ab:Negative Squared Ab
    U+1F191🆑\:cl:Squared Cl
    U+1F192🆒\:cool:Squared Cool
    U+1F193🆓\:free:Squared Free
    U+1F194🆔\:id:Squared Id
    U+1F195🆕\:new:Squared New
    U+1F196🆖\:ng:Squared Ng
    U+1F197🆗\:ok:Squared Ok
    U+1F198🆘\:sos:Squared Sos
    U+1F199🆙\:up:Squared Up With Exclamation Mark
    U+1F19A🆚\:vs:Squared Vs
    U+1F201🈁\:koko:Squared Katakana Koko
    U+1F202🈂\:sa:Squared Katakana Sa
    U+1F21A🈚\:u7121:Squared Cjk Unified Ideograph-7121
    U+1F22F🈯\:u6307:Squared Cjk Unified Ideograph-6307
    U+1F232🈲\:u7981:Squared Cjk Unified Ideograph-7981
    U+1F233🈳\:u7a7a:Squared Cjk Unified Ideograph-7A7A
    U+1F234🈴\:u5408:Squared Cjk Unified Ideograph-5408
    U+1F235🈵\:u6e80:Squared Cjk Unified Ideograph-6E80
    U+1F236🈶\:u6709:Squared Cjk Unified Ideograph-6709
    U+1F237🈷\:u6708:Squared Cjk Unified Ideograph-6708
    U+1F238🈸\:u7533:Squared Cjk Unified Ideograph-7533
    U+1F239🈹\:u5272:Squared Cjk Unified Ideograph-5272
    U+1F23A🈺\:u55b6:Squared Cjk Unified Ideograph-55B6
    U+1F250🉐\:ideograph_advantage:Circled Ideograph Advantage
    U+1F251🉑\:accept:Circled Ideograph Accept
    U+1F300🌀\:cyclone:Cyclone
    U+1F301🌁\:foggy:Foggy
    U+1F302🌂\:closed_umbrella:Closed Umbrella
    U+1F303🌃\:night_with_stars:Night With Stars
    U+1F304🌄\:sunrise_over_mountains:Sunrise Over Mountains
    U+1F305🌅\:sunrise:Sunrise
    U+1F306🌆\:city_sunset:Cityscape At Dusk
    U+1F307🌇\:city_sunrise:Sunset Over Buildings
    U+1F308🌈\:rainbow:Rainbow
    U+1F309🌉\:bridge_at_night:Bridge At Night
    U+1F30A🌊\:ocean:Water Wave
    U+1F30B🌋\:volcano:Volcano
    U+1F30C🌌\:milky_way:Milky Way
    U+1F30D🌍\:earth_africa:Earth Globe Europe-Africa
    U+1F30E🌎\:earth_americas:Earth Globe Americas
    U+1F30F🌏\:earth_asia:Earth Globe Asia-Australia
    U+1F310🌐\:globe_with_meridians:Globe With Meridians
    U+1F311🌑\:new_moon:New Moon Symbol
    U+1F312🌒\:waxing_crescent_moon:Waxing Crescent Moon Symbol
    U+1F313🌓\:first_quarter_moon:First Quarter Moon Symbol
    U+1F314🌔\:moon:Waxing Gibbous Moon Symbol
    U+1F315🌕\:full_moon:Full Moon Symbol
    U+1F316🌖\:waning_gibbous_moon:Waning Gibbous Moon Symbol
    U+1F317🌗\:last_quarter_moon:Last Quarter Moon Symbol
    U+1F318🌘\:waning_crescent_moon:Waning Crescent Moon Symbol
    U+1F319🌙\:crescent_moon:Crescent Moon
    U+1F31A🌚\:new_moon_with_face:New Moon With Face
    U+1F31B🌛\:first_quarter_moon_with_face:First Quarter Moon With Face
    U+1F31C🌜\:last_quarter_moon_with_face:Last Quarter Moon With Face
    U+1F31D🌝\:full_moon_with_face:Full Moon With Face
    U+1F31E🌞\:sun_with_face:Sun With Face
    U+1F31F🌟\:star2:Glowing Star
    U+1F320🌠\:stars:Shooting Star
    U+1F32D🌭\:hotdog:Hot Dog
    U+1F32E🌮\:taco:Taco
    U+1F32F🌯\:burrito:Burrito
    U+1F330🌰\:chestnut:Chestnut
    U+1F331🌱\:seedling:Seedling
    U+1F332🌲\:evergreen_tree:Evergreen Tree
    U+1F333🌳\:deciduous_tree:Deciduous Tree
    U+1F334🌴\:palm_tree:Palm Tree
    U+1F335🌵\:cactus:Cactus
    U+1F337🌷\:tulip:Tulip
    U+1F338🌸\:cherry_blossom:Cherry Blossom
    U+1F339🌹\:rose:Rose
    U+1F33A🌺\:hibiscus:Hibiscus
    U+1F33B🌻\:sunflower:Sunflower
    U+1F33C🌼\:blossom:Blossom
    U+1F33D🌽\:corn:Ear Of Maize
    U+1F33E🌾\:ear_of_rice:Ear Of Rice
    U+1F33F🌿\:herb:Herb
    U+1F340🍀\:four_leaf_clover:Four Leaf Clover
    U+1F341🍁\:maple_leaf:Maple Leaf
    U+1F342🍂\:fallen_leaf:Fallen Leaf
    U+1F343🍃\:leaves:Leaf Fluttering In Wind
    U+1F344🍄\:mushroom:Mushroom
    U+1F345🍅\:tomato:Tomato
    U+1F346🍆\:eggplant:Aubergine
    U+1F347🍇\:grapes:Grapes
    U+1F348🍈\:melon:Melon
    U+1F349🍉\:watermelon:Watermelon
    U+1F34A🍊\:tangerine:Tangerine
    U+1F34B🍋\:lemon:Lemon
    U+1F34C🍌\:banana:Banana
    U+1F34D🍍\:pineapple:Pineapple
    U+1F34E🍎\:apple:Red Apple
    U+1F34F🍏\:green_apple:Green Apple
    U+1F350🍐\:pear:Pear
    U+1F351🍑\:peach:Peach
    U+1F352🍒\:cherries:Cherries
    U+1F353🍓\:strawberry:Strawberry
    U+1F354🍔\:hamburger:Hamburger
    U+1F355🍕\:pizza:Slice Of Pizza
    U+1F356🍖\:meat_on_bone:Meat On Bone
    U+1F357🍗\:poultry_leg:Poultry Leg
    U+1F358🍘\:rice_cracker:Rice Cracker
    U+1F359🍙\:rice_ball:Rice Ball
    U+1F35A🍚\:rice:Cooked Rice
    U+1F35B🍛\:curry:Curry And Rice
    U+1F35C🍜\:ramen:Steaming Bowl
    U+1F35D🍝\:spaghetti:Spaghetti
    U+1F35E🍞\:bread:Bread
    U+1F35F🍟\:fries:French Fries
    U+1F360🍠\:sweet_potato:Roasted Sweet Potato
    U+1F361🍡\:dango:Dango
    U+1F362🍢\:oden:Oden
    U+1F363🍣\:sushi:Sushi
    U+1F364🍤\:fried_shrimp:Fried Shrimp
    U+1F365🍥\:fish_cake:Fish Cake With Swirl Design
    U+1F366🍦\:icecream:Soft Ice Cream
    U+1F367🍧\:shaved_ice:Shaved Ice
    U+1F368🍨\:ice_cream:Ice Cream
    U+1F369🍩\:doughnut:Doughnut
    U+1F36A🍪\:cookie:Cookie
    U+1F36B🍫\:chocolate_bar:Chocolate Bar
    U+1F36C🍬\:candy:Candy
    U+1F36D🍭\:lollipop:Lollipop
    U+1F36E🍮\:custard:Custard
    U+1F36F🍯\:honey_pot:Honey Pot
    U+1F370🍰\:cake:Shortcake
    U+1F371🍱\:bento:Bento Box
    U+1F372🍲\:stew:Pot Of Food
    U+1F373🍳\:fried_egg:Cooking
    U+1F374🍴\:fork_and_knife:Fork And Knife
    U+1F375🍵\:tea:Teacup Without Handle
    U+1F376🍶\:sake:Sake Bottle And Cup
    U+1F377🍷\:wine_glass:Wine Glass
    U+1F378🍸\:cocktail:Cocktail Glass
    U+1F379🍹\:tropical_drink:Tropical Drink
    U+1F37A🍺\:beer:Beer Mug
    U+1F37B🍻\:beers:Clinking Beer Mugs
    U+1F37C🍼\:baby_bottle:Baby Bottle
    U+1F37E🍾\:champagne:Bottle With Popping Cork
    U+1F37F🍿\:popcorn:Popcorn
    U+1F380🎀\:ribbon:Ribbon
    U+1F381🎁\:gift:Wrapped Present
    U+1F382🎂\:birthday:Birthday Cake
    U+1F383🎃\:jack_o_lantern:Jack-O-Lantern
    U+1F384🎄\:christmas_tree:Christmas Tree
    U+1F385🎅\:santa:Father Christmas
    U+1F386🎆\:fireworks:Fireworks
    U+1F387🎇\:sparkler:Firework Sparkler
    U+1F388🎈\:balloon:Balloon
    U+1F389🎉\:tada:Party Popper
    U+1F38A🎊\:confetti_ball:Confetti Ball
    U+1F38B🎋\:tanabata_tree:Tanabata Tree
    U+1F38C🎌\:crossed_flags:Crossed Flags
    U+1F38D🎍\:bamboo:Pine Decoration
    U+1F38E🎎\:dolls:Japanese Dolls
    U+1F38F🎏\:flags:Carp Streamer
    U+1F390🎐\:wind_chime:Wind Chime
    U+1F391🎑\:rice_scene:Moon Viewing Ceremony
    U+1F392🎒\:school_satchel:School Satchel
    U+1F393🎓\:mortar_board:Graduation Cap
    U+1F3A0🎠\:carousel_horse:Carousel Horse
    U+1F3A1🎡\:ferris_wheel:Ferris Wheel
    U+1F3A2🎢\:roller_coaster:Roller Coaster
    U+1F3A3🎣\:fishing_pole_and_fish:Fishing Pole And Fish
    U+1F3A4🎤\:microphone:Microphone
    U+1F3A5🎥\:movie_camera:Movie Camera
    U+1F3A6🎦\:cinema:Cinema
    U+1F3A7🎧\:headphones:Headphone
    U+1F3A8🎨\:art:Artist Palette
    U+1F3A9🎩\:tophat:Top Hat
    U+1F3AA🎪\:circus_tent:Circus Tent
    U+1F3AB🎫\:ticket:Ticket
    U+1F3AC🎬\:clapper:Clapper Board
    U+1F3AD🎭\:performing_arts:Performing Arts
    U+1F3AE🎮\:video_game:Video Game
    U+1F3AF🎯\:dart:Direct Hit
    U+1F3B0🎰\:slot_machine:Slot Machine
    U+1F3B1🎱\:8ball:Billiards
    U+1F3B2🎲\:game_die:Game Die
    U+1F3B3🎳\:bowling:Bowling
    U+1F3B4🎴\:flower_playing_cards:Flower Playing Cards
    U+1F3B5🎵\:musical_note:Musical Note
    U+1F3B6🎶\:notes:Multiple Musical Notes
    U+1F3B7🎷\:saxophone:Saxophone
    U+1F3B8🎸\:guitar:Guitar
    U+1F3B9🎹\:musical_keyboard:Musical Keyboard
    U+1F3BA🎺\:trumpet:Trumpet
    U+1F3BB🎻\:violin:Violin
    U+1F3BC🎼\:musical_score:Musical Score
    U+1F3BD🎽\:running_shirt_with_sash:Running Shirt With Sash
    U+1F3BE🎾\:tennis:Tennis Racquet And Ball
    U+1F3BF🎿\:ski:Ski And Ski Boot
    U+1F3C0🏀\:basketball:Basketball And Hoop
    U+1F3C1🏁\:checkered_flag:Chequered Flag
    U+1F3C2🏂\:snowboarder:Snowboarder
    U+1F3C3🏃\:runner:Runner
    U+1F3C4🏄\:surfer:Surfer
    U+1F3C5🏅\:sports_medal:Sports Medal
    U+1F3C6🏆\:trophy:Trophy
    U+1F3C7🏇\:horse_racing:Horse Racing
    U+1F3C8🏈\:football:American Football
    U+1F3C9🏉\:rugby_football:Rugby Football
    U+1F3CA🏊\:swimmer:Swimmer
    U+1F3CF🏏\:cricket_bat_and_ball:Cricket Bat And Ball
    U+1F3D0🏐\:volleyball:Volleyball
    U+1F3D1🏑\:field_hockey_stick_and_ball:Field Hockey Stick And Ball
    U+1F3D2🏒\:ice_hockey_stick_and_puck:Ice Hockey Stick And Puck
    U+1F3D3🏓\:table_tennis_paddle_and_ball:Table Tennis Paddle And Ball
    U+1F3E0🏠\:house:House Building
    U+1F3E1🏡\:house_with_garden:House With Garden
    U+1F3E2🏢\:office:Office Building
    U+1F3E3🏣\:post_office:Japanese Post Office
    U+1F3E4🏤\:european_post_office:European Post Office
    U+1F3E5🏥\:hospital:Hospital
    U+1F3E6🏦\:bank:Bank
    U+1F3E7🏧\:atm:Automated Teller Machine
    U+1F3E8🏨\:hotel:Hotel
    U+1F3E9🏩\:love_hotel:Love Hotel
    U+1F3EA🏪\:convenience_store:Convenience Store
    U+1F3EB🏫\:school:School
    U+1F3EC🏬\:department_store:Department Store
    U+1F3ED🏭\:factory:Factory
    U+1F3EE🏮\:izakaya_lantern:Izakaya Lantern
    U+1F3EF🏯\:japanese_castle:Japanese Castle
    U+1F3F0🏰\:european_castle:European Castle
    U+1F3F4🏴\:waving_black_flag:Waving Black Flag
    U+1F3F8🏸\:badminton_racquet_and_shuttlecock:Badminton Racquet And Shuttlecock
    U+1F3F9🏹\:bow_and_arrow:Bow And Arrow
    U+1F3FA🏺\:amphora:Amphora
    U+1F3FB🏻\:skin-tone-2:Emoji Modifier Fitzpatrick Type-1-2
    U+1F3FC🏼\:skin-tone-3:Emoji Modifier Fitzpatrick Type-3
    U+1F3FD🏽\:skin-tone-4:Emoji Modifier Fitzpatrick Type-4
    U+1F3FE🏾\:skin-tone-5:Emoji Modifier Fitzpatrick Type-5
    U+1F3FF🏿\:skin-tone-6:Emoji Modifier Fitzpatrick Type-6
    U+1F400🐀\:rat:Rat
    U+1F401🐁\:mouse2:Mouse
    U+1F402🐂\:ox:Ox
    U+1F403🐃\:water_buffalo:Water Buffalo
    U+1F404🐄\:cow2:Cow
    U+1F405🐅\:tiger2:Tiger
    U+1F406🐆\:leopard:Leopard
    U+1F407🐇\:rabbit2:Rabbit
    U+1F408🐈\:cat2:Cat
    U+1F409🐉\:dragon:Dragon
    U+1F40A🐊\:crocodile:Crocodile
    U+1F40B🐋\:whale2:Whale
    U+1F40C🐌\:snail:Snail
    U+1F40D🐍\:snake:Snake
    U+1F40E🐎\:racehorse:Horse
    U+1F40F🐏\:ram:Ram
    U+1F410🐐\:goat:Goat
    U+1F411🐑\:sheep:Sheep
    U+1F412🐒\:monkey:Monkey
    U+1F413🐓\:rooster:Rooster
    U+1F414🐔\:chicken:Chicken
    U+1F415🐕\:dog2:Dog
    U+1F416🐖\:pig2:Pig
    U+1F417🐗\:boar:Boar
    U+1F418🐘\:elephant:Elephant
    U+1F419🐙\:octopus:Octopus
    U+1F41A🐚\:shell:Spiral Shell
    U+1F41B🐛\:bug:Bug
    U+1F41C🐜\:ant:Ant
    U+1F41D🐝\:bee:Honeybee
    U+1F41E🐞\:ladybug:Lady Beetle
    U+1F41F🐟\:fish:Fish
    U+1F420🐠\:tropical_fish:Tropical Fish
    U+1F421🐡\:blowfish:Blowfish
    U+1F422🐢\:turtle:Turtle
    U+1F423🐣\:hatching_chick:Hatching Chick
    U+1F424🐤\:baby_chick:Baby Chick
    U+1F425🐥\:hatched_chick:Front-Facing Baby Chick
    U+1F426🐦\:bird:Bird
    U+1F427🐧\:penguin:Penguin
    U+1F428🐨\:koala:Koala
    U+1F429🐩\:poodle:Poodle
    U+1F42A🐪\:dromedary_camel:Dromedary Camel
    U+1F42B🐫\:camel:Bactrian Camel
    U+1F42C🐬\:dolphin:Dolphin
    U+1F42D🐭\:mouse:Mouse Face
    U+1F42E🐮\:cow:Cow Face
    U+1F42F🐯\:tiger:Tiger Face
    U+1F430🐰\:rabbit:Rabbit Face
    U+1F431🐱\:cat:Cat Face
    U+1F432🐲\:dragon_face:Dragon Face
    U+1F433🐳\:whale:Spouting Whale
    U+1F434🐴\:horse:Horse Face
    U+1F435🐵\:monkey_face:Monkey Face
    U+1F436🐶\:dog:Dog Face
    U+1F437🐷\:pig:Pig Face
    U+1F438🐸\:frog:Frog Face
    U+1F439🐹\:hamster:Hamster Face
    U+1F43A🐺\:wolf:Wolf Face
    U+1F43B🐻\:bear:Bear Face
    U+1F43C🐼\:panda_face:Panda Face
    U+1F43D🐽\:pig_nose:Pig Nose
    U+1F43E🐾\:feet:Paw Prints
    U+1F440👀\:eyes:Eyes
    U+1F442👂\:ear:Ear
    U+1F443👃\:nose:Nose
    U+1F444👄\:lips:Mouth
    U+1F445👅\:tongue:Tongue
    U+1F446👆\:point_up_2:White Up Pointing Backhand Index
    U+1F447👇\:point_down:White Down Pointing Backhand Index
    U+1F448👈\:point_left:White Left Pointing Backhand Index
    U+1F449👉\:point_right:White Right Pointing Backhand Index
    U+1F44A👊\:facepunch:Fisted Hand Sign
    U+1F44B👋\:wave:Waving Hand Sign
    U+1F44C👌\:ok_hand:Ok Hand Sign
    U+1F44D👍\:+1:Thumbs Up Sign
    U+1F44E👎\:-1:Thumbs Down Sign
    U+1F44F👏\:clap:Clapping Hands Sign
    U+1F450👐\:open_hands:Open Hands Sign
    U+1F451👑\:crown:Crown
    U+1F452👒\:womans_hat:Womans Hat
    U+1F453👓\:eyeglasses:Eyeglasses
    U+1F454👔\:necktie:Necktie
    U+1F455👕\:shirt:T-Shirt
    U+1F456👖\:jeans:Jeans
    U+1F457👗\:dress:Dress
    U+1F458👘\:kimono:Kimono
    U+1F459👙\:bikini:Bikini
    U+1F45A👚\:womans_clothes:Womans Clothes
    U+1F45B👛\:purse:Purse
    U+1F45C👜\:handbag:Handbag
    U+1F45D👝\:pouch:Pouch
    U+1F45E👞\:mans_shoe:Mans Shoe
    U+1F45F👟\:athletic_shoe:Athletic Shoe
    U+1F460👠\:high_heel:High-Heeled Shoe
    U+1F461👡\:sandal:Womans Sandal
    U+1F462👢\:boot:Womans Boots
    U+1F463👣\:footprints:Footprints
    U+1F464👤\:bust_in_silhouette:Bust In Silhouette
    U+1F465👥\:busts_in_silhouette:Busts In Silhouette
    U+1F466👦\:boy:Boy
    U+1F467👧\:girl:Girl
    U+1F468👨\:man:Man
    U+1F469👩\:woman:Woman
    U+1F46A👪\:family:Family
    U+1F46B👫\:couple:, \:man_and_woman_holding_hands:Man And Woman Holding Hands
    U+1F46C👬\:two_men_holding_hands:Two Men Holding Hands
    U+1F46D👭\:two_women_holding_hands:Two Women Holding Hands
    U+1F46E👮\:cop:Police Officer
    U+1F46F👯\:dancers:Woman With Bunny Ears
    U+1F470👰\:bride_with_veil:Bride With Veil
    U+1F471👱\:person_with_blond_hair:Person With Blond Hair
    U+1F472👲\:man_with_gua_pi_mao:Man With Gua Pi Mao
    U+1F473👳\:man_with_turban:Man With Turban
    U+1F474👴\:older_man:Older Man
    U+1F475👵\:older_woman:Older Woman
    U+1F476👶\:baby:Baby
    U+1F477👷\:construction_worker:Construction Worker
    U+1F478👸\:princess:Princess
    U+1F479👹\:japanese_ogre:Japanese Ogre
    U+1F47A👺\:japanese_goblin:Japanese Goblin
    U+1F47B👻\:ghost:Ghost
    U+1F47C👼\:angel:Baby Angel
    U+1F47D👽\:alien:Extraterrestrial Alien
    U+1F47E👾\:space_invader:Alien Monster
    U+1F47F👿\:imp:Imp
    U+1F480💀\:skull:Skull
    U+1F481💁\:information_desk_person:Information Desk Person
    U+1F482💂\:guardsman:Guardsman
    U+1F483💃\:dancer:Dancer
    U+1F484💄\:lipstick:Lipstick
    U+1F485💅\:nail_care:Nail Polish
    U+1F486💆\:massage:Face Massage
    U+1F487💇\:haircut:Haircut
    U+1F488💈\:barber:Barber Pole
    U+1F489💉\:syringe:Syringe
    U+1F48A💊\:pill:Pill
    U+1F48B💋\:kiss:Kiss Mark
    U+1F48C💌\:love_letter:Love Letter
    U+1F48D💍\:ring:Ring
    U+1F48E💎\:gem:Gem Stone
    U+1F48F💏\:couplekiss:Kiss
    U+1F490💐\:bouquet:Bouquet
    U+1F491💑\:couple_with_heart:Couple With Heart
    U+1F492💒\:wedding:Wedding
    U+1F493💓\:heartbeat:Beating Heart
    U+1F494💔\:broken_heart:Broken Heart
    U+1F495💕\:two_hearts:Two Hearts
    U+1F496💖\:sparkling_heart:Sparkling Heart
    U+1F497💗\:heartpulse:Growing Heart
    U+1F498💘\:cupid:Heart With Arrow
    U+1F499💙\:blue_heart:Blue Heart
    U+1F49A💚\:green_heart:Green Heart
    U+1F49B💛\:yellow_heart:Yellow Heart
    U+1F49C💜\:purple_heart:Purple Heart
    U+1F49D💝\:gift_heart:Heart With Ribbon
    U+1F49E💞\:revolving_hearts:Revolving Hearts
    U+1F49F💟\:heart_decoration:Heart Decoration
    U+1F4A0💠\:diamond_shape_with_a_dot_inside:Diamond Shape With A Dot Inside
    U+1F4A1💡\:bulb:Electric Light Bulb
    U+1F4A2💢\:anger:Anger Symbol
    U+1F4A3💣\:bomb:Bomb
    U+1F4A4💤\:zzz:Sleeping Symbol
    U+1F4A5💥\:boom:Collision Symbol
    U+1F4A6💦\:sweat_drops:Splashing Sweat Symbol
    U+1F4A7💧\:droplet:Droplet
    U+1F4A8💨\:dash:Dash Symbol
    U+1F4A9💩\:hankey:Pile Of Poo
    U+1F4AA💪\:muscle:Flexed Biceps
    U+1F4AB💫\:dizzy:Dizzy Symbol
    U+1F4AC💬\:speech_balloon:Speech Balloon
    U+1F4AD💭\:thought_balloon:Thought Balloon
    U+1F4AE💮\:white_flower:White Flower
    U+1F4AF💯\:100:Hundred Points Symbol
    U+1F4B0💰\:moneybag:Money Bag
    U+1F4B1💱\:currency_exchange:Currency Exchange
    U+1F4B2💲\:heavy_dollar_sign:Heavy Dollar Sign
    U+1F4B3💳\:credit_card:Credit Card
    U+1F4B4💴\:yen:Banknote With Yen Sign
    U+1F4B5💵\:dollar:Banknote With Dollar Sign
    U+1F4B6💶\:euro:Banknote With Euro Sign
    U+1F4B7💷\:pound:Banknote With Pound Sign
    U+1F4B8💸\:money_with_wings:Money With Wings
    U+1F4B9💹\:chart:Chart With Upwards Trend And Yen Sign
    U+1F4BA💺\:seat:Seat
    U+1F4BB💻\:computer:Personal Computer
    U+1F4BC💼\:briefcase:Briefcase
    U+1F4BD💽\:minidisc:Minidisc
    U+1F4BE💾\:floppy_disk:Floppy Disk
    U+1F4BF💿\:cd:Optical Disc
    U+1F4C0📀\:dvd:Dvd
    U+1F4C1📁\:file_folder:File Folder
    U+1F4C2📂\:open_file_folder:Open File Folder
    U+1F4C3📃\:page_with_curl:Page With Curl
    U+1F4C4📄\:page_facing_up:Page Facing Up
    U+1F4C5📅\:date:Calendar
    U+1F4C6📆\:calendar:Tear-Off Calendar
    U+1F4C7📇\:card_index:Card Index
    U+1F4C8📈\:chart_with_upwards_trend:Chart With Upwards Trend
    U+1F4C9📉\:chart_with_downwards_trend:Chart With Downwards Trend
    U+1F4CA📊\:bar_chart:Bar Chart
    U+1F4CB📋\:clipboard:Clipboard
    U+1F4CC📌\:pushpin:Pushpin
    U+1F4CD📍\:round_pushpin:Round Pushpin
    U+1F4CE📎\:paperclip:Paperclip
    U+1F4CF📏\:straight_ruler:Straight Ruler
    U+1F4D0📐\:triangular_ruler:Triangular Ruler
    U+1F4D1📑\:bookmark_tabs:Bookmark Tabs
    U+1F4D2📒\:ledger:Ledger
    U+1F4D3📓\:notebook:Notebook
    U+1F4D4📔\:notebook_with_decorative_cover:Notebook With Decorative Cover
    U+1F4D5📕\:closed_book:Closed Book
    U+1F4D6📖\:book:Open Book
    U+1F4D7📗\:green_book:Green Book
    U+1F4D8📘\:blue_book:Blue Book
    U+1F4D9📙\:orange_book:Orange Book
    U+1F4DA📚\:books:Books
    U+1F4DB📛\:name_badge:Name Badge
    U+1F4DC📜\:scroll:Scroll
    U+1F4DD📝\:memo:Memo
    U+1F4DE📞\:telephone_receiver:Telephone Receiver
    U+1F4DF📟\:pager:Pager
    U+1F4E0📠\:fax:Fax Machine
    U+1F4E1📡\:satellite:, \:satellite_antenna:Satellite Antenna
    U+1F4E2📢\:loudspeaker:Public Address Loudspeaker
    U+1F4E3📣\:mega:Cheering Megaphone
    U+1F4E4📤\:outbox_tray:Outbox Tray
    U+1F4E5📥\:inbox_tray:Inbox Tray
    U+1F4E6📦\:package:Package
    U+1F4E7📧\:e-mail:E-Mail Symbol
    U+1F4E8📨\:incoming_envelope:Incoming Envelope
    U+1F4E9📩\:envelope_with_arrow:Envelope With Downwards Arrow Above
    U+1F4EA📪\:mailbox_closed:Closed Mailbox With Lowered Flag
    U+1F4EB📫\:mailbox:Closed Mailbox With Raised Flag
    U+1F4EC📬\:mailbox_with_mail:Open Mailbox With Raised Flag
    U+1F4ED📭\:mailbox_with_no_mail:Open Mailbox With Lowered Flag
    U+1F4EE📮\:postbox:Postbox
    U+1F4EF📯\:postal_horn:Postal Horn
    U+1F4F0📰\:newspaper:Newspaper
    U+1F4F1📱\:iphone:Mobile Phone
    U+1F4F2📲\:calling:Mobile Phone With Rightwards Arrow At Left
    U+1F4F3📳\:vibration_mode:Vibration Mode
    U+1F4F4📴\:mobile_phone_off:Mobile Phone Off
    U+1F4F5📵\:no_mobile_phones:No Mobile Phones
    U+1F4F6📶\:signal_strength:Antenna With Bars
    U+1F4F7📷\:camera:Camera
    U+1F4F8📸\:camera_with_flash:Camera With Flash
    U+1F4F9📹\:video_camera:Video Camera
    U+1F4FA📺\:tv:Television
    U+1F4FB📻\:radio:Radio
    U+1F4FC📼\:vhs:Videocassette
    U+1F4FF📿\:prayer_beads:Prayer Beads
    U+1F500🔀\:twisted_rightwards_arrows:Twisted Rightwards Arrows
    U+1F501🔁\:repeat:Clockwise Rightwards And Leftwards Open Circle Arrows
    U+1F502🔂\:repeat_one:Clockwise Rightwards And Leftwards Open Circle Arrows With Circled One Overlay
    U+1F503🔃\:arrows_clockwise:Clockwise Downwards And Upwards Open Circle Arrows
    U+1F504🔄\:arrows_counterclockwise:Anticlockwise Downwards And Upwards Open Circle Arrows
    U+1F505🔅\:low_brightness:Low Brightness Symbol
    U+1F506🔆\:high_brightness:High Brightness Symbol
    U+1F507🔇\:mute:Speaker With Cancellation Stroke
    U+1F508🔈\:speaker:Speaker
    U+1F509🔉\:sound:Speaker With One Sound Wave
    U+1F50A🔊\:loud_sound:Speaker With Three Sound Waves
    U+1F50B🔋\:battery:Battery
    U+1F50C🔌\:electric_plug:Electric Plug
    U+1F50D🔍\:mag:Left-Pointing Magnifying Glass
    U+1F50E🔎\:mag_right:Right-Pointing Magnifying Glass
    U+1F50F🔏\:lock_with_ink_pen:Lock With Ink Pen
    U+1F510🔐\:closed_lock_with_key:Closed Lock With Key
    U+1F511🔑\:key:Key
    U+1F512🔒\:lock:Lock
    U+1F513🔓\:unlock:Open Lock
    U+1F514🔔\:bell:Bell
    U+1F515🔕\:no_bell:Bell With Cancellation Stroke
    U+1F516🔖\:bookmark:Bookmark
    U+1F517🔗\:link:Link Symbol
    U+1F518🔘\:radio_button:Radio Button
    U+1F519🔙\:back:Back With Leftwards Arrow Above
    U+1F51A🔚\:end:End With Leftwards Arrow Above
    U+1F51B🔛\:on:On With Exclamation Mark With Left Right Arrow Above
    U+1F51C🔜\:soon:Soon With Rightwards Arrow Above
    U+1F51D🔝\:top:Top With Upwards Arrow Above
    U+1F51E🔞\:underage:No One Under Eighteen Symbol
    U+1F51F🔟\:keycap_ten:Keycap Ten
    U+1F520🔠\:capital_abcd:Input Symbol For Latin Capital Letters
    U+1F521🔡\:abcd:Input Symbol For Latin Small Letters
    U+1F522🔢\:1234:Input Symbol For Numbers
    U+1F523🔣\:symbols:Input Symbol For Symbols
    U+1F524🔤\:abc:Input Symbol For Latin Letters
    U+1F525🔥\:fire:Fire
    U+1F526🔦\:flashlight:Electric Torch
    U+1F527🔧\:wrench:Wrench
    U+1F528🔨\:hammer:Hammer
    U+1F529🔩\:nut_and_bolt:Nut And Bolt
    U+1F52A🔪\:hocho:Hocho
    U+1F52B🔫\:gun:Pistol
    U+1F52C🔬\:microscope:Microscope
    U+1F52D🔭\:telescope:Telescope
    U+1F52E🔮\:crystal_ball:Crystal Ball
    U+1F52F🔯\:six_pointed_star:Six Pointed Star With Middle Dot
    U+1F530🔰\:beginner:Japanese Symbol For Beginner
    U+1F531🔱\:trident:Trident Emblem
    U+1F532🔲\:black_square_button:Black Square Button
    U+1F533🔳\:white_square_button:White Square Button
    U+1F534🔴\:red_circle:Large Red Circle
    U+1F535🔵\:large_blue_circle:Large Blue Circle
    U+1F536🔶\:large_orange_diamond:Large Orange Diamond
    U+1F537🔷\:large_blue_diamond:Large Blue Diamond
    U+1F538🔸\:small_orange_diamond:Small Orange Diamond
    U+1F539🔹\:small_blue_diamond:Small Blue Diamond
    U+1F53A🔺\:small_red_triangle:Up-Pointing Red Triangle
    U+1F53B🔻\:small_red_triangle_down:Down-Pointing Red Triangle
    U+1F53C🔼\:arrow_up_small:Up-Pointing Small Red Triangle
    U+1F53D🔽\:arrow_down_small:Down-Pointing Small Red Triangle
    U+1F54B🕋\:kaaba:Kaaba
    U+1F54C🕌\:mosque:Mosque
    U+1F54D🕍\:synagogue:Synagogue
    U+1F54E🕎\:menorah_with_nine_branches:Menorah With Nine Branches
    U+1F550🕐\:clock1:Clock Face One Oclock
    U+1F551🕑\:clock2:Clock Face Two Oclock
    U+1F552🕒\:clock3:Clock Face Three Oclock
    U+1F553🕓\:clock4:Clock Face Four Oclock
    U+1F554🕔\:clock5:Clock Face Five Oclock
    U+1F555🕕\:clock6:Clock Face Six Oclock
    U+1F556🕖\:clock7:Clock Face Seven Oclock
    U+1F557🕗\:clock8:Clock Face Eight Oclock
    U+1F558🕘\:clock9:Clock Face Nine Oclock
    U+1F559🕙\:clock10:Clock Face Ten Oclock
    U+1F55A🕚\:clock11:Clock Face Eleven Oclock
    U+1F55B🕛\:clock12:Clock Face Twelve Oclock
    U+1F55C🕜\:clock130:Clock Face One-Thirty
    U+1F55D🕝\:clock230:Clock Face Two-Thirty
    U+1F55E🕞\:clock330:Clock Face Three-Thirty
    U+1F55F🕟\:clock430:Clock Face Four-Thirty
    U+1F560🕠\:clock530:Clock Face Five-Thirty
    U+1F561🕡\:clock630:Clock Face Six-Thirty
    U+1F562🕢\:clock730:Clock Face Seven-Thirty
    U+1F563🕣\:clock830:Clock Face Eight-Thirty
    U+1F564🕤\:clock930:Clock Face Nine-Thirty
    U+1F565🕥\:clock1030:Clock Face Ten-Thirty
    U+1F566🕦\:clock1130:Clock Face Eleven-Thirty
    U+1F567🕧\:clock1230:Clock Face Twelve-Thirty
    U+1F57A🕺\:man_dancing:Man Dancing
    U+1F595🖕\:middle_finger:Reversed Hand With Middle Finger Extended
    U+1F596🖖\:spock-hand:Raised Hand With Part Between Middle And Ring Fingers
    U+1F5A4🖤\:black_heart:Black Heart
    U+1F5FB🗻\:mount_fuji:Mount Fuji
    U+1F5FC🗼\:tokyo_tower:Tokyo Tower
    U+1F5FD🗽\:statue_of_liberty:Statue Of Liberty
    U+1F5FE🗾\:japan:Silhouette Of Japan
    U+1F5FF🗿\:moyai:Moyai
    U+1F600😀\:grinning:Grinning Face
    U+1F601😁\:grin:Grinning Face With Smiling Eyes
    U+1F602😂\:joy:Face With Tears Of Joy
    U+1F603😃\:smiley:Smiling Face With Open Mouth
    U+1F604😄\:smile:Smiling Face With Open Mouth And Smiling Eyes
    U+1F605😅\:sweat_smile:Smiling Face With Open Mouth And Cold Sweat
    U+1F606😆\:laughing:Smiling Face With Open Mouth And Tightly-Closed Eyes
    U+1F607😇\:innocent:Smiling Face With Halo
    U+1F608😈\:smiling_imp:Smiling Face With Horns
    U+1F609😉\:wink:Winking Face
    U+1F60A😊\:blush:Smiling Face With Smiling Eyes
    U+1F60B😋\:yum:Face Savouring Delicious Food
    U+1F60C😌\:relieved:Relieved Face
    U+1F60D😍\:heart_eyes:Smiling Face With Heart-Shaped Eyes
    U+1F60E😎\:sunglasses:Smiling Face With Sunglasses
    U+1F60F😏\:smirk:Smirking Face
    U+1F610😐\:neutral_face:Neutral Face
    U+1F611😑\:expressionless:Expressionless Face
    U+1F612😒\:unamused:Unamused Face
    U+1F613😓\:sweat:Face With Cold Sweat
    U+1F614😔\:pensive:Pensive Face
    U+1F615😕\:confused:Confused Face
    U+1F616😖\:confounded:Confounded Face
    U+1F617😗\:kissing:Kissing Face
    U+1F618😘\:kissing_heart:Face Throwing A Kiss
    U+1F619😙\:kissing_smiling_eyes:Kissing Face With Smiling Eyes
    U+1F61A😚\:kissing_closed_eyes:Kissing Face With Closed Eyes
    U+1F61B😛\:stuck_out_tongue:Face With Stuck-Out Tongue
    U+1F61C😜\:stuck_out_tongue_winking_eye:Face With Stuck-Out Tongue And Winking Eye
    U+1F61D😝\:stuck_out_tongue_closed_eyes:Face With Stuck-Out Tongue And Tightly-Closed Eyes
    U+1F61E😞\:disappointed:Disappointed Face
    U+1F61F😟\:worried:Worried Face
    U+1F620😠\:angry:Angry Face
    U+1F621😡\:rage:Pouting Face
    U+1F622😢\:cry:Crying Face
    U+1F623😣\:persevere:Persevering Face
    U+1F624😤\:triumph:Face With Look Of Triumph
    U+1F625😥\:disappointed_relieved:Disappointed But Relieved Face
    U+1F626😦\:frowning:Frowning Face With Open Mouth
    U+1F627😧\:anguished:Anguished Face
    U+1F628😨\:fearful:Fearful Face
    U+1F629😩\:weary:Weary Face
    U+1F62A😪\:sleepy:Sleepy Face
    U+1F62B😫\:tired_face:Tired Face
    U+1F62C😬\:grimacing:Grimacing Face
    U+1F62D😭\:sob:Loudly Crying Face
    U+1F62E😮\:open_mouth:Face With Open Mouth
    U+1F62F😯\:hushed:Hushed Face
    U+1F630😰\:cold_sweat:Face With Open Mouth And Cold Sweat
    U+1F631😱\:scream:Face Screaming In Fear
    U+1F632😲\:astonished:Astonished Face
    U+1F633😳\:flushed:Flushed Face
    U+1F634😴\:sleeping:Sleeping Face
    U+1F635😵\:dizzy_face:Dizzy Face
    U+1F636😶\:no_mouth:Face Without Mouth
    U+1F637😷\:mask:Face With Medical Mask
    U+1F638😸\:smile_cat:Grinning Cat Face With Smiling Eyes
    U+1F639😹\:joy_cat:Cat Face With Tears Of Joy
    U+1F63A😺\:smiley_cat:Smiling Cat Face With Open Mouth
    U+1F63B😻\:heart_eyes_cat:Smiling Cat Face With Heart-Shaped Eyes
    U+1F63C😼\:smirk_cat:Cat Face With Wry Smile
    U+1F63D😽\:kissing_cat:Kissing Cat Face With Closed Eyes
    U+1F63E😾\:pouting_cat:Pouting Cat Face
    U+1F63F😿\:crying_cat_face:Crying Cat Face
    U+1F640🙀\:scream_cat:Weary Cat Face
    U+1F641🙁\:slightly_frowning_face:Slightly Frowning Face
    U+1F642🙂\:slightly_smiling_face:Slightly Smiling Face
    U+1F643🙃\:upside_down_face:Upside-Down Face
    U+1F644🙄\:face_with_rolling_eyes:Face With Rolling Eyes
    U+1F645🙅\:no_good:Face With No Good Gesture
    U+1F646🙆\:ok_woman:Face With Ok Gesture
    U+1F647🙇\:bow:Person Bowing Deeply
    U+1F648🙈\:see_no_evil:See-No-Evil Monkey
    U+1F649🙉\:hear_no_evil:Hear-No-Evil Monkey
    U+1F64A🙊\:speak_no_evil:Speak-No-Evil Monkey
    U+1F64B🙋\:raising_hand:Happy Person Raising One Hand
    U+1F64C🙌\:raised_hands:Person Raising Both Hands In Celebration
    U+1F64D🙍\:person_frowning:Person Frowning
    U+1F64E🙎\:person_with_pouting_face:Person With Pouting Face
    U+1F64F🙏\:pray:Person With Folded Hands
    U+1F680🚀\:rocket:Rocket
    U+1F681🚁\:helicopter:Helicopter
    U+1F682🚂\:steam_locomotive:Steam Locomotive
    U+1F683🚃\:railway_car:Railway Car
    U+1F684🚄\:bullettrain_side:High-Speed Train
    U+1F685🚅\:bullettrain_front:High-Speed Train With Bullet Nose
    U+1F686🚆\:train2:Train
    U+1F687🚇\:metro:Metro
    U+1F688🚈\:light_rail:Light Rail
    U+1F689🚉\:station:Station
    U+1F68A🚊\:tram:Tram
    U+1F68B🚋\:train:Tram Car
    U+1F68C🚌\:bus:Bus
    U+1F68D🚍\:oncoming_bus:Oncoming Bus
    U+1F68E🚎\:trolleybus:Trolleybus
    U+1F68F🚏\:busstop:Bus Stop
    U+1F690🚐\:minibus:Minibus
    U+1F691🚑\:ambulance:Ambulance
    U+1F692🚒\:fire_engine:Fire Engine
    U+1F693🚓\:police_car:Police Car
    U+1F694🚔\:oncoming_police_car:Oncoming Police Car
    U+1F695🚕\:taxi:Taxi
    U+1F696🚖\:oncoming_taxi:Oncoming Taxi
    U+1F697🚗\:car:Automobile
    U+1F698🚘\:oncoming_automobile:Oncoming Automobile
    U+1F699🚙\:blue_car:Recreational Vehicle
    U+1F69A🚚\:truck:Delivery Truck
    U+1F69B🚛\:articulated_lorry:Articulated Lorry
    U+1F69C🚜\:tractor:Tractor
    U+1F69D🚝\:monorail:Monorail
    U+1F69E🚞\:mountain_railway:Mountain Railway
    U+1F69F🚟\:suspension_railway:Suspension Railway
    U+1F6A0🚠\:mountain_cableway:Mountain Cableway
    U+1F6A1🚡\:aerial_tramway:Aerial Tramway
    U+1F6A2🚢\:ship:Ship
    U+1F6A3🚣\:rowboat:Rowboat
    U+1F6A4🚤\:speedboat:Speedboat
    U+1F6A5🚥\:traffic_light:Horizontal Traffic Light
    U+1F6A6🚦\:vertical_traffic_light:Vertical Traffic Light
    U+1F6A7🚧\:construction:Construction Sign
    U+1F6A8🚨\:rotating_light:Police Cars Revolving Light
    U+1F6A9🚩\:triangular_flag_on_post:Triangular Flag On Post
    U+1F6AA🚪\:door:Door
    U+1F6AB🚫\:no_entry_sign:No Entry Sign
    U+1F6AC🚬\:smoking:Smoking Symbol
    U+1F6AD🚭\:no_smoking:No Smoking Symbol
    U+1F6AE🚮\:put_litter_in_its_place:Put Litter In Its Place Symbol
    U+1F6AF🚯\:do_not_litter:Do Not Litter Symbol
    U+1F6B0🚰\:potable_water:Potable Water Symbol
    U+1F6B1🚱\:non-potable_water:Non-Potable Water Symbol
    U+1F6B2🚲\:bike:Bicycle
    U+1F6B3🚳\:no_bicycles:No Bicycles
    U+1F6B4🚴\:bicyclist:Bicyclist
    U+1F6B5🚵\:mountain_bicyclist:Mountain Bicyclist
    U+1F6B6🚶\:walking:Pedestrian
    U+1F6B7🚷\:no_pedestrians:No Pedestrians
    U+1F6B8🚸\:children_crossing:Children Crossing
    U+1F6B9🚹\:mens:Mens Symbol
    U+1F6BA🚺\:womens:Womens Symbol
    U+1F6BB🚻\:restroom:Restroom
    U+1F6BC🚼\:baby_symbol:Baby Symbol
    U+1F6BD🚽\:toilet:Toilet
    U+1F6BE🚾\:wc:Water Closet
    U+1F6BF🚿\:shower:Shower
    U+1F6C0🛀\:bath:Bath
    U+1F6C1🛁\:bathtub:Bathtub
    U+1F6C2🛂\:passport_control:Passport Control
    U+1F6C3🛃\:customs:Customs
    U+1F6C4🛄\:baggage_claim:Baggage Claim
    U+1F6C5🛅\:left_luggage:Left Luggage
    U+1F6CC🛌\:sleeping_accommodation:Sleeping Accommodation
    U+1F6D0🛐\:place_of_worship:Place Of Worship
    U+1F6D1🛑\:octagonal_sign:Octagonal Sign
    U+1F6D2🛒\:shopping_trolley:Shopping Trolley
    U+1F6D5🛕\:hindu_temple:Hindu Temple
    U+1F6D6🛖\:hut:Hut
    U+1F6D7🛗\:elevator:Elevator
    U+1F6EB🛫\:airplane_departure:Airplane Departure
    U+1F6EC🛬\:airplane_arriving:Airplane Arriving
    U+1F6F4🛴\:scooter:Scooter
    U+1F6F5🛵\:motor_scooter:Motor Scooter
    U+1F6F6🛶\:canoe:Canoe
    U+1F6F7🛷\:sled:Sled
    U+1F6F8🛸\:flying_saucer:Flying Saucer
    U+1F6F9🛹\:skateboard:Skateboard
    U+1F6FA🛺\:auto_rickshaw:Auto Rickshaw
    U+1F6FB🛻\:pickup_truck:Pickup Truck
    U+1F6FC🛼\:roller_skate:Roller Skate
    U+1F7E0🟠\:large_orange_circle:Large Orange Circle
    U+1F7E1🟡\:large_yellow_circle:Large Yellow Circle
    U+1F7E2🟢\:large_green_circle:Large Green Circle
    U+1F7E3🟣\:large_purple_circle:Large Purple Circle
    U+1F7E4🟤\:large_brown_circle:Large Brown Circle
    U+1F7E5🟥\:large_red_square:Large Red Square
    U+1F7E6🟦\:large_blue_square:Large Blue Square
    U+1F7E7🟧\:large_orange_square:Large Orange Square
    U+1F7E8🟨\:large_yellow_square:Large Yellow Square
    U+1F7E9🟩\:large_green_square:Large Green Square
    U+1F7EA🟪\:large_purple_square:Large Purple Square
    U+1F7EB🟫\:large_brown_square:Large Brown Square
    U+1F90C🤌\:pinched_fingers:Pinched Fingers
    U+1F90D🤍\:white_heart:White Heart
    U+1F90E🤎\:brown_heart:Brown Heart
    U+1F90F🤏\:pinching_hand:Pinching Hand
    U+1F910🤐\:zipper_mouth_face:Zipper-Mouth Face
    U+1F911🤑\:money_mouth_face:Money-Mouth Face
    U+1F912🤒\:face_with_thermometer:Face With Thermometer
    U+1F913🤓\:nerd_face:Nerd Face
    U+1F914🤔\:thinking_face:Thinking Face
    U+1F915🤕\:face_with_head_bandage:Face With Head-Bandage
    U+1F916🤖\:robot_face:Robot Face
    U+1F917🤗\:hugging_face:Hugging Face
    U+1F918🤘\:the_horns:Sign Of The Horns
    U+1F919🤙\:call_me_hand:Call Me Hand
    U+1F91A🤚\:raised_back_of_hand:Raised Back Of Hand
    U+1F91B🤛\:left-facing_fist:Left-Facing Fist
    U+1F91C🤜\:right-facing_fist:Right-Facing Fist
    U+1F91D🤝\:handshake:Handshake
    U+1F91E🤞\:crossed_fingers:Hand With Index And Middle Fingers Crossed
    U+1F91F🤟\:i_love_you_hand_sign:I Love You Hand Sign
    U+1F920🤠\:face_with_cowboy_hat:Face With Cowboy Hat
    U+1F921🤡\:clown_face:Clown Face
    U+1F922🤢\:nauseated_face:Nauseated Face
    U+1F923🤣\:rolling_on_the_floor_laughing:Rolling On The Floor Laughing
    U+1F924🤤\:drooling_face:Drooling Face
    U+1F925🤥\:lying_face:Lying Face
    U+1F926🤦\:face_palm:Face Palm
    U+1F927🤧\:sneezing_face:Sneezing Face
    U+1F928🤨\:face_with_raised_eyebrow:Face With One Eyebrow Raised
    U+1F929🤩\:star-struck:Grinning Face With Star Eyes
    U+1F92A🤪\:zany_face:Grinning Face With One Large And One Small Eye
    U+1F92B🤫\:shushing_face:Face With Finger Covering Closed Lips
    U+1F92C🤬\:face_with_symbols_on_mouth:Serious Face With Symbols Covering Mouth
    U+1F92D🤭\:face_with_hand_over_mouth:Smiling Face With Smiling Eyes And Hand Covering Mouth
    U+1F92E🤮\:face_vomiting:Face With Open Mouth Vomiting
    U+1F92F🤯\:exploding_head:Shocked Face With Exploding Head
    U+1F930🤰\:pregnant_woman:Pregnant Woman
    U+1F931🤱\:breast-feeding:Breast-Feeding
    U+1F932🤲\:palms_up_together:Palms Up Together
    U+1F933🤳\:selfie:Selfie
    U+1F934🤴\:prince:Prince
    U+1F935🤵\:person_in_tuxedo:Man In Tuxedo
    U+1F936🤶\:mrs_claus:Mother Christmas
    U+1F937🤷\:shrug:Shrug
    U+1F938🤸\:person_doing_cartwheel:Person Doing Cartwheel
    U+1F939🤹\:juggling:Juggling
    U+1F93A🤺\:fencer:Fencer
    U+1F93C🤼\:wrestlers:Wrestlers
    U+1F93D🤽\:water_polo:Water Polo
    U+1F93E🤾\:handball:Handball
    U+1F93F🤿\:diving_mask:Diving Mask
    U+1F940🥀\:wilted_flower:Wilted Flower
    U+1F941🥁\:drum_with_drumsticks:Drum With Drumsticks
    U+1F942🥂\:clinking_glasses:Clinking Glasses
    U+1F943🥃\:tumbler_glass:Tumbler Glass
    U+1F944🥄\:spoon:Spoon
    U+1F945🥅\:goal_net:Goal Net
    U+1F947🥇\:first_place_medal:First Place Medal
    U+1F948🥈\:second_place_medal:Second Place Medal
    U+1F949🥉\:third_place_medal:Third Place Medal
    U+1F94A🥊\:boxing_glove:Boxing Glove
    U+1F94B🥋\:martial_arts_uniform:Martial Arts Uniform
    U+1F94C🥌\:curling_stone:Curling Stone
    U+1F94D🥍\:lacrosse:Lacrosse Stick And Ball
    U+1F94E🥎\:softball:Softball
    U+1F94F🥏\:flying_disc:Flying Disc
    U+1F950🥐\:croissant:Croissant
    U+1F951🥑\:avocado:Avocado
    U+1F952🥒\:cucumber:Cucumber
    U+1F953🥓\:bacon:Bacon
    U+1F954🥔\:potato:Potato
    U+1F955🥕\:carrot:Carrot
    U+1F956🥖\:baguette_bread:Baguette Bread
    U+1F957🥗\:green_salad:Green Salad
    U+1F958🥘\:shallow_pan_of_food:Shallow Pan Of Food
    U+1F959🥙\:stuffed_flatbread:Stuffed Flatbread
    U+1F95A🥚\:egg:Egg
    U+1F95B🥛\:glass_of_milk:Glass Of Milk
    U+1F95C🥜\:peanuts:Peanuts
    U+1F95D🥝\:kiwifruit:Kiwifruit
    U+1F95E🥞\:pancakes:Pancakes
    U+1F95F🥟\:dumpling:Dumpling
    U+1F960🥠\:fortune_cookie:Fortune Cookie
    U+1F961🥡\:takeout_box:Takeout Box
    U+1F962🥢\:chopsticks:Chopsticks
    U+1F963🥣\:bowl_with_spoon:Bowl With Spoon
    U+1F964🥤\:cup_with_straw:Cup With Straw
    U+1F965🥥\:coconut:Coconut
    U+1F966🥦\:broccoli:Broccoli
    U+1F967🥧\:pie:Pie
    U+1F968🥨\:pretzel:Pretzel
    U+1F969🥩\:cut_of_meat:Cut Of Meat
    U+1F96A🥪\:sandwich:Sandwich
    U+1F96B🥫\:canned_food:Canned Food
    U+1F96C🥬\:leafy_green:Leafy Green
    U+1F96D🥭\:mango:Mango
    U+1F96E🥮\:moon_cake:Moon Cake
    U+1F96F🥯\:bagel:Bagel
    U+1F970🥰\:smiling_face_with_3_hearts:Smiling Face With Smiling Eyes And Three Hearts
    U+1F971🥱\:yawning_face:Yawning Face
    U+1F972🥲\:smiling_face_with_tear:Smiling Face With Tear
    U+1F973🥳\:partying_face:Face With Party Horn And Party Hat
    U+1F974🥴\:woozy_face:Face With Uneven Eyes And Wavy Mouth
    U+1F975🥵\:hot_face:Overheated Face
    U+1F976🥶\:cold_face:Freezing Face
    U+1F977🥷\:ninja:Ninja
    U+1F978🥸\:disguised_face:Disguised Face
    U+1F97A🥺\:pleading_face:Face With Pleading Eyes
    U+1F97B🥻\:sari:Sari
    U+1F97C🥼\:lab_coat:Lab Coat
    U+1F97D🥽\:goggles:Goggles
    U+1F97E🥾\:hiking_boot:Hiking Boot
    U+1F97F🥿\:womans_flat_shoe:Flat Shoe
    U+1F980🦀\:crab:Crab
    U+1F981🦁\:lion_face:Lion Face
    U+1F982🦂\:scorpion:Scorpion
    U+1F983🦃\:turkey:Turkey
    U+1F984🦄\:unicorn_face:Unicorn Face
    U+1F985🦅\:eagle:Eagle
    U+1F986🦆\:duck:Duck
    U+1F987🦇\:bat:Bat
    U+1F988🦈\:shark:Shark
    U+1F989🦉\:owl:Owl
    U+1F98A🦊\:fox_face:Fox Face
    U+1F98B🦋\:butterfly:Butterfly
    U+1F98C🦌\:deer:Deer
    U+1F98D🦍\:gorilla:Gorilla
    U+1F98E🦎\:lizard:Lizard
    U+1F98F🦏\:rhinoceros:Rhinoceros
    U+1F990🦐\:shrimp:Shrimp
    U+1F991🦑\:squid:Squid
    U+1F992🦒\:giraffe_face:Giraffe Face
    U+1F993🦓\:zebra_face:Zebra Face
    U+1F994🦔\:hedgehog:Hedgehog
    U+1F995🦕\:sauropod:Sauropod
    U+1F996🦖\:t-rex:T-Rex
    U+1F997🦗\:cricket:Cricket
    U+1F998🦘\:kangaroo:Kangaroo
    U+1F999🦙\:llama:Llama
    U+1F99A🦚\:peacock:Peacock
    U+1F99B🦛\:hippopotamus:Hippopotamus
    U+1F99C🦜\:parrot:Parrot
    U+1F99D🦝\:raccoon:Raccoon
    U+1F99E🦞\:lobster:Lobster
    U+1F99F🦟\:mosquito:Mosquito
    U+1F9A0🦠\:microbe:Microbe
    U+1F9A1🦡\:badger:Badger
    U+1F9A2🦢\:swan:Swan
    U+1F9A3🦣\:mammoth:Mammoth
    U+1F9A4🦤\:dodo:Dodo
    U+1F9A5🦥\:sloth:Sloth
    U+1F9A6🦦\:otter:Otter
    U+1F9A7🦧\:orangutan:Orangutan
    U+1F9A8🦨\:skunk:Skunk
    U+1F9A9🦩\:flamingo:Flamingo
    U+1F9AA🦪\:oyster:Oyster
    U+1F9AB🦫\:beaver:Beaver
    U+1F9AC🦬\:bison:Bison
    U+1F9AD🦭\:seal:Seal
    U+1F9AE🦮\:guide_dog:Guide Dog
    U+1F9AF🦯\:probing_cane:Probing Cane
    U+1F9B4🦴\:bone:Bone
    U+1F9B5🦵\:leg:Leg
    U+1F9B6🦶\:foot:Foot
    U+1F9B7🦷\:tooth:Tooth
    U+1F9B8🦸\:superhero:Superhero
    U+1F9B9🦹\:supervillain:Supervillain
    U+1F9BA🦺\:safety_vest:Safety Vest
    U+1F9BB🦻\:ear_with_hearing_aid:Ear With Hearing Aid
    U+1F9BC🦼\:motorized_wheelchair:Motorized Wheelchair
    U+1F9BD🦽\:manual_wheelchair:Manual Wheelchair
    U+1F9BE🦾\:mechanical_arm:Mechanical Arm
    U+1F9BF🦿\:mechanical_leg:Mechanical Leg
    U+1F9C0🧀\:cheese_wedge:Cheese Wedge
    U+1F9C1🧁\:cupcake:Cupcake
    U+1F9C2🧂\:salt:Salt Shaker
    U+1F9C3🧃\:beverage_box:Beverage Box
    U+1F9C4🧄\:garlic:Garlic
    U+1F9C5🧅\:onion:Onion
    U+1F9C6🧆\:falafel:Falafel
    U+1F9C7🧇\:waffle:Waffle
    U+1F9C8🧈\:butter:Butter
    U+1F9C9🧉\:mate_drink:Mate Drink
    U+1F9CA🧊\:ice_cube:Ice Cube
    U+1F9CB🧋\:bubble_tea:Bubble Tea
    U+1F9CD🧍\:standing_person:Standing Person
    U+1F9CE🧎\:kneeling_person:Kneeling Person
    U+1F9CF🧏\:deaf_person:Deaf Person
    U+1F9D0🧐\:face_with_monocle:Face With Monocle
    U+1F9D1🧑\:adult:Adult
    U+1F9D2🧒\:child:Child
    U+1F9D3🧓\:older_adult:Older Adult
    U+1F9D4🧔\:bearded_person:Bearded Person
    U+1F9D5🧕\:person_with_headscarf:Person With Headscarf
    U+1F9D6🧖\:person_in_steamy_room:Person In Steamy Room
    U+1F9D7🧗\:person_climbing:Person Climbing
    U+1F9D8🧘\:person_in_lotus_position:Person In Lotus Position
    U+1F9D9🧙\:mage:Mage
    U+1F9DA🧚\:fairy:Fairy
    U+1F9DB🧛\:vampire:Vampire
    U+1F9DC🧜\:merperson:Merperson
    U+1F9DD🧝\:elf:Elf
    U+1F9DE🧞\:genie:Genie
    U+1F9DF🧟\:zombie:Zombie
    U+1F9E0🧠\:brain:Brain
    U+1F9E1🧡\:orange_heart:Orange Heart
    U+1F9E2🧢\:billed_cap:Billed Cap
    U+1F9E3🧣\:scarf:Scarf
    U+1F9E4🧤\:gloves:Gloves
    U+1F9E5🧥\:coat:Coat
    U+1F9E6🧦\:socks:Socks
    U+1F9E7🧧\:red_envelope:Red Gift Envelope
    U+1F9E8🧨\:firecracker:Firecracker
    U+1F9E9🧩\:jigsaw:Jigsaw Puzzle Piece
    U+1F9EA🧪\:test_tube:Test Tube
    U+1F9EB🧫\:petri_dish:Petri Dish
    U+1F9EC🧬\:dna:Dna Double Helix
    U+1F9ED🧭\:compass:Compass
    U+1F9EE🧮\:abacus:Abacus
    U+1F9EF🧯\:fire_extinguisher:Fire Extinguisher
    U+1F9F0🧰\:toolbox:Toolbox
    U+1F9F1🧱\:bricks:Brick
    U+1F9F2🧲\:magnet:Magnet
    U+1F9F3🧳\:luggage:Luggage
    U+1F9F4🧴\:lotion_bottle:Lotion Bottle
    U+1F9F5🧵\:thread:Spool Of Thread
    U+1F9F6🧶\:yarn:Ball Of Yarn
    U+1F9F7🧷\:safety_pin:Safety Pin
    U+1F9F8🧸\:teddy_bear:Teddy Bear
    U+1F9F9🧹\:broom:Broom
    U+1F9FA🧺\:basket:Basket
    U+1F9FB🧻\:roll_of_paper:Roll Of Paper
    U+1F9FC🧼\:soap:Bar Of Soap
    U+1F9FD🧽\:sponge:Sponge
    U+1F9FE🧾\:receipt:Receipt
    U+1F9FF🧿\:nazar_amulet:Nazar Amulet
    U+1FA70🩰\:ballet_shoes:Ballet Shoes
    U+1FA71🩱\:one-piece_swimsuit:One-Piece Swimsuit
    U+1FA72🩲\:briefs:Briefs
    U+1FA73🩳\:shorts:Shorts
    U+1FA74🩴\:thong_sandal:Thong Sandal
    U+1FA78🩸\:drop_of_blood:Drop Of Blood
    U+1FA79🩹\:adhesive_bandage:Adhesive Bandage
    U+1FA7A🩺\:stethoscope:Stethoscope
    U+1FA80🪀\:yo-yo:Yo-Yo
    U+1FA81🪁\:kite:Kite
    U+1FA82🪂\:parachute:Parachute
    U+1FA83🪃\:boomerang:Boomerang
    U+1FA84🪄\:magic_wand:Magic Wand
    U+1FA85🪅\:pinata:Pinata
    U+1FA86🪆\:nesting_dolls:Nesting Dolls
    U+1FA90🪐\:ringed_planet:Ringed Planet
    U+1FA91🪑\:chair:Chair
    U+1FA92🪒\:razor:Razor
    U+1FA93🪓\:axe:Axe
    U+1FA94🪔\:diya_lamp:Diya Lamp
    U+1FA95🪕\:banjo:Banjo
    U+1FA96🪖\:military_helmet:Military Helmet
    U+1FA97🪗\:accordion:Accordion
    U+1FA98🪘\:long_drum:Long Drum
    U+1FA99🪙\:coin:Coin
    U+1FA9A🪚\:carpentry_saw:Carpentry Saw
    U+1FA9B🪛\:screwdriver:Screwdriver
    U+1FA9C🪜\:ladder:Ladder
    U+1FA9D🪝\:hook:Hook
    U+1FA9E🪞\:mirror:Mirror
    U+1FA9F🪟\:window:Window
    U+1FAA0🪠\:plunger:Plunger
    U+1FAA1🪡\:sewing_needle:Sewing Needle
    U+1FAA2🪢\:knot:Knot
    U+1FAA3🪣\:bucket:Bucket
    U+1FAA4🪤\:mouse_trap:Mouse Trap
    U+1FAA5🪥\:toothbrush:Toothbrush
    U+1FAA6🪦\:headstone:Headstone
    U+1FAA7🪧\:placard:Placard
    U+1FAA8🪨\:rock:Rock
    U+1FAB0🪰\:fly:Fly
    U+1FAB1🪱\:worm:Worm
    U+1FAB2🪲\:beetle:Beetle
    U+1FAB3🪳\:cockroach:Cockroach
    U+1FAB4🪴\:potted_plant:Potted Plant
    U+1FAB5🪵\:wood:Wood
    U+1FAB6🪶\:feather:Feather
    U+1FAC0🫀\:anatomical_heart:Anatomical Heart
    U+1FAC1🫁\:lungs:Lungs
    U+1FAC2🫂\:people_hugging:People Hugging
    U+1FAD0🫐\:blueberries:Blueberries
    U+1FAD1🫑\:bell_pepper:Bell Pepper
    U+1FAD2🫒\:olive:Olive
    U+1FAD3🫓\:flatbread:Flatbread
    U+1FAD4🫔\:tamale:Tamale
    U+1FAD5🫕\:fondue:Fondue
    U+1FAD6🫖\:teapot:Teapot
    diff --git a/en/v1.12-dev/manual/variables-and-scoping/index.html b/en/v1.12-dev/manual/variables-and-scoping/index.html index e251176e5d83..f72f3a2cc5b9 100644 --- a/en/v1.12-dev/manual/variables-and-scoping/index.html +++ b/en/v1.12-dev/manual/variables-and-scoping/index.html @@ -301,4 +301,4 @@ julia> global x::Int ERROR: cannot set type for global x. It already has a value or is already set to a different type. Stacktrace: -[...] +[...] diff --git a/en/v1.12-dev/manual/variables/index.html b/en/v1.12-dev/manual/variables/index.html index 7bc09c49120c..5107d28a40fa 100644 --- a/en/v1.12-dev/manual/variables/index.html +++ b/en/v1.12-dev/manual/variables/index.html @@ -95,4 +95,4 @@ 3-element Vector{Int64}: 42 2 - 3

    That is, a[i] = value (an alias for setindex!) mutates an existing array object in memory, accessible via either a or b. Subsequently setting a = 3.14159 does not change this array, it simply binds a to a different object; the array is still accessible via b. Another common syntax to mutate an existing object is a.field = value (an alias for setproperty!), which can be used to change a mutable struct. There is also mutation via dot assignment, for example b .= 5:7 (which mutates our array b in-place to contain [5,6,7]), as part of Julia's vectorized "dot" syntax.

    When you call a function in Julia, it behaves as if you assigned the argument values to new variable names corresponding to the function arguments, as discussed in Argument-Passing Behavior. (By convention, functions that mutate one or more of their arguments have names ending with !.)

    Stylistic Conventions

    While Julia imposes few restrictions on valid names, it has become useful to adopt the following conventions:

    For more information about stylistic conventions, see the Style Guide.

    + 3

    That is, a[i] = value (an alias for setindex!) mutates an existing array object in memory, accessible via either a or b. Subsequently setting a = 3.14159 does not change this array, it simply binds a to a different object; the array is still accessible via b. Another common syntax to mutate an existing object is a.field = value (an alias for setproperty!), which can be used to change a mutable struct. There is also mutation via dot assignment, for example b .= 5:7 (which mutates our array b in-place to contain [5,6,7]), as part of Julia's vectorized "dot" syntax.

    When you call a function in Julia, it behaves as if you assigned the argument values to new variable names corresponding to the function arguments, as discussed in Argument-Passing Behavior. (By convention, functions that mutate one or more of their arguments have names ending with !.)

    Stylistic Conventions

    While Julia imposes few restrictions on valid names, it has become useful to adopt the following conventions:

    For more information about stylistic conventions, see the Style Guide.

    diff --git a/en/v1.12-dev/manual/workflow-tips/index.html b/en/v1.12-dev/manual/workflow-tips/index.html index e4c8bddcb5cf..ce1f380f166a 100644 --- a/en/v1.12-dev/manual/workflow-tips/index.html +++ b/en/v1.12-dev/manual/workflow-tips/index.html @@ -19,4 +19,4 @@ t("MyPkg")

    This will create a blank package, "MyPkg", in your .julia/dev directory. Note that PkgTemplates allows you to control many different options through its Template constructor.

    In step 2 below, edit MyPkg/src/MyPkg.jl to change the source code, and MyPkg/test/runtests.jl for the tests.

  • For "throw-away" projects, you can avoid any need for cleanup by doing your work in your temporary directory (e.g., /tmp).

    Navigate to your temporary directory and launch Julia, then do the following:

    pkg> generate MyPkg            # type ] to enter pkg mode
     julia> push!(LOAD_PATH, pwd())   # hit backspace to exit pkg mode

    If you restart your Julia session you'll have to re-issue that command modifying LOAD_PATH.

    In step 2 below, edit MyPkg/src/MyPkg.jl to change the source code, and create any test file of your choosing.

  • Develop your package

    Before loading any code, make sure you're running Revise: say using Revise or follow its documentation on configuring it to run automatically.

    Then navigate to the directory containing your test file (here assumed to be "runtests.jl") and do the following:

    julia> using MyPkg
     
    -julia> include("runtests.jl")

    You can iteratively modify the code in MyPkg in your editor and re-run the tests with include("runtests.jl"). You generally should not need to restart your Julia session to see the changes take effect (subject to a few limitations).

  • +julia> include("runtests.jl")

    You can iteratively modify the code in MyPkg in your editor and re-run the tests with include("runtests.jl"). You generally should not need to restart your Julia session to see the changes take effect (subject to a few limitations).

    diff --git a/en/v1.12-dev/search_index.js b/en/v1.12-dev/search_index.js index c973f697cb8d..43563411ff8d 100644 --- a/en/v1.12-dev/search_index.js +++ b/en/v1.12-dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"stdlib/CRC32c/","page":"CRC32c","title":"CRC32c","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/CRC32c/docs/src/index.md\"","category":"page"},{"location":"stdlib/CRC32c/#CRC32c","page":"CRC32c","title":"CRC32c","text":"","category":"section"},{"location":"stdlib/CRC32c/","page":"CRC32c","title":"CRC32c","text":"Standard library module for computing the CRC-32c checksum.","category":"page"},{"location":"stdlib/CRC32c/","page":"CRC32c","title":"CRC32c","text":"CRC32c.crc32c\nCRC32c.crc32c(::IO, ::Integer, ::UInt32)","category":"page"},{"location":"stdlib/CRC32c/#CRC32c.crc32c","page":"CRC32c","title":"CRC32c.crc32c","text":"crc32c(data, crc::UInt32=0x00000000)\n\nCompute the CRC-32c checksum of the given data, which can be an Array{UInt8}, a contiguous subarray thereof, or a String. Optionally, you can pass a starting crc integer to be mixed in with the checksum. The crc parameter can be used to compute a checksum on data divided into chunks: performing crc32c(data2, crc32c(data1)) is equivalent to the checksum of [data1; data2]. (Technically, a little-endian checksum is computed.)\n\nThere is also a method crc32c(io, nb, crc) to checksum nb bytes from a stream io, or crc32c(io, crc) to checksum all the remaining bytes. Hence you can do open(crc32c, filename) to checksum an entire file, or crc32c(seekstart(buf)) to checksum an IOBuffer without calling take!.\n\nFor a String, note that the result is specific to the UTF-8 encoding (a different checksum would be obtained from a different Unicode encoding). To checksum an a::Array of some other bitstype, you can do crc32c(reinterpret(UInt8,a)), but note that the result may be endian-dependent.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/CRC32c/#CRC32c.crc32c-Tuple{IO, Integer, UInt32}","page":"CRC32c","title":"CRC32c.crc32c","text":"crc32c(io::IO, [nb::Integer,] crc::UInt32=0x00000000)\n\nRead up to nb bytes from io and return the CRC-32c checksum, optionally mixed with a starting crc integer. If nb is not supplied, then io will be read until the end of the stream.\n\n\n\n\n\n","category":"method"},{"location":"manual/installation/#man-installation","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"There are many ways to install Julia. The following sections highlight the recommended method for each of the main supported platforms, and then present alternative ways that might be useful in specialized situations.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"The current installation recommendation is a solution based on Juliaup. If you installed Julia previously with a method that is not based on Juliaup and want to switch your system to an installation that is based on Juliaup, we recommend that you uninstall all previous Julia versions, ensure that you remove anything Julia related from your PATH variable and then install Julia with one of the methods described below.","category":"page"},{"location":"manual/installation/#Windows","page":"Installation","title":"Windows","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"On Windows Julia can be installed directly from the Windows store here. One can also install exactly the same version by executing","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"winget install julia -s msstore","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"in any shell.","category":"page"},{"location":"manual/installation/#Mac-and-Linux","page":"Installation","title":"Mac and Linux","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"Julia can be installed on Linux or Mac by executing","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"curl -fsSL https://install.julialang.org | sh","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"in a shell.","category":"page"},{"location":"manual/installation/#Command-line-arguments","page":"Installation","title":"Command line arguments","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"One can pass various command line arguments to the Julia installer. The syntax for installer arguments is","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"curl -fsSL https://install.julialang.org | sh -s -- ","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"Here should be replaced with one or more of the following arguments:","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--yes (or -y): Run the installer in a non-interactive mode. All","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"configuration values use their default or a value supplied as a command line argument.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--default-channel=: Configure the default Juliaup channel. For","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"example --default-channel lts would install the lts channel and configure it as the default.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--add-to-path=: Configure whether Julia should be added to the PATH","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"environment variable. Valid values are yes (default) and no.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--background-selfupdate=: Configure an optional CRON job that","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"auto-updates Juliaup if has a value larger than 0. The actual value controls how often the CRON job will run to check for a new Juliaup version in seconds. The default value is 0, i.e. no CRON job will be created.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--startup-selfupdate=: Configure how often Julia will check for new","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"versions of Juliaup when Julia is started. The default is every 1440 minutes.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"-p= (or --path): Configure where the Julia and Juliaup binaries are","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"installed. The default is ~/.juliaup.","category":"page"},{"location":"manual/installation/#Alternative-installation-methods","page":"Installation","title":"Alternative installation methods","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"Note that we recommend the following methods only if none of the installation methods described above work for your system.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"Some of the installation methods described below recommend installing a package called juliaup. Note that this nevertheless installs a fully functional Julia system, not just Juliaup.","category":"page"},{"location":"manual/installation/#App-Installer-(Windows)","page":"Installation","title":"App Installer (Windows)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"If the Windows Store is blocked on a system, we have an alternative MSIX App Installer based setup. To use the App Installer version, download this file and open it by double clicking on it.","category":"page"},{"location":"manual/installation/#MSI-Installer-(Windows)","page":"Installation","title":"MSI Installer (Windows)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"If neither the Windows Store nor the App Installer version work on your Windows system, you can also use a MSI based installer. Note that this installation methods comes with serious limitations and is generally not recommended unless no other method works. For example, there is no automatic update mechanism for Juliaup with this installation method. The 64 bit version of the MSI installer can be downloaded from here and the 32 bit version from here.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"By default the install will be a per-user install that does not require elevation. You can also do a system install by running the following command from a shell:","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"msiexec /i ALLUSERS=1","category":"page"},{"location":"manual/installation/#[Homebrew](https://brew.sh)-(Mac-and-Linux)","page":"Installation","title":"Homebrew (Mac and Linux)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"On systems with brew, you can install Julia by running","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"brew install juliaup","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"in a shell. Note that you will have to update Juliaup with standard brew commands.","category":"page"},{"location":"manual/installation/#[Arch-Linux-AUR](https://aur.archlinux.org/packages/juliaup/)-(Linux)","page":"Installation","title":"Arch Linux - AUR (Linux)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"On Arch Linux, Juliaup is available in the Arch User Repository (AUR).","category":"page"},{"location":"manual/installation/#[openSUSE-Tumbleweed](https://get.opensuse.org/tumbleweed/)-(Linux)","page":"Installation","title":"openSUSE Tumbleweed (Linux)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"On openSUSE Tumbleweed, you can install Julia by running","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"zypper install juliaup","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"in a shell with root privileges.","category":"page"},{"location":"manual/installation/#[cargo](https://crates.io/crates/juliaup/)-(Windows,-Mac-and-Linux)","page":"Installation","title":"cargo (Windows, Mac and Linux)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"To install Julia via Rust's cargo, run:","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"cargo install juliaup","category":"page"},{"location":"base/sort/#Sorting-and-Related-Functions","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Julia has an extensive, flexible API for sorting and interacting with already-sorted arrays of values. By default, Julia picks reasonable algorithms and sorts in ascending order:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort([2,3,1])\n3-element Vector{Int64}:\n 1\n 2\n 3","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"You can sort in reverse order as well:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort([2,3,1], rev=true)\n3-element Vector{Int64}:\n 3\n 2\n 1","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"sort constructs a sorted copy leaving its input unchanged. Use the \"bang\" version of the sort function to mutate an existing array:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> a = [2,3,1];\n\njulia> sort!(a);\n\njulia> a\n3-element Vector{Int64}:\n 1\n 2\n 3","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Instead of directly sorting an array, you can compute a permutation of the array's indices that puts the array into sorted order:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> v = randn(5)\n5-element Array{Float64,1}:\n 0.297288\n 0.382396\n -0.597634\n -0.0104452\n -0.839027\n\njulia> p = sortperm(v)\n5-element Array{Int64,1}:\n 5\n 3\n 4\n 1\n 2\n\njulia> v[p]\n5-element Array{Float64,1}:\n -0.839027\n -0.597634\n -0.0104452\n 0.297288\n 0.382396","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Arrays can be sorted according to an arbitrary transformation of their values:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort(v, by=abs)\n5-element Array{Float64,1}:\n -0.0104452\n 0.297288\n 0.382396\n -0.597634\n -0.839027","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Or in reverse order by a transformation:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort(v, by=abs, rev=true)\n5-element Array{Float64,1}:\n -0.839027\n -0.597634\n 0.382396\n 0.297288\n -0.0104452","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"If needed, the sorting algorithm can be chosen:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort(v, alg=InsertionSort)\n5-element Array{Float64,1}:\n -0.839027\n -0.597634\n -0.0104452\n 0.297288\n 0.382396","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"All the sorting and order related functions rely on a \"less than\" relation defining a strict weak order on the values to be manipulated. The isless function is invoked by default, but the relation can be specified via the lt keyword, a function that takes two array elements and returns true if and only if the first argument is \"less than\" the second. See sort! and Alternate Orderings for more information.","category":"page"},{"location":"base/sort/#Sorting-Functions","page":"Sorting and Related Functions","title":"Sorting Functions","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Base.sort!\nBase.sort\nBase.sortperm\nBase.InsertionSort\nBase.MergeSort\nBase.QuickSort\nBase.PartialQuickSort\nBase.Sort.sortperm!\nBase.Sort.sortslices","category":"page"},{"location":"base/sort/#Base.sort!","page":"Sorting and Related Functions","title":"Base.sort!","text":"sort!(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nSort the vector v in place. A stable algorithm is used by default: the ordering of elements that compare equal is preserved. A specific algorithm can be selected via the alg keyword (see Sorting Algorithms for available algorithms).\n\nElements are first transformed with the function by and then compared according to either the function lt or the ordering order. Finally, the resulting order is reversed if rev=true (this preserves forward stability: elements that compare equal are not reversed). The current implementation applies the by transformation before each comparison rather than once per element.\n\nPassing an lt other than isless along with an order other than Base.Order.Forward or Base.Order.Reverse is not permitted, otherwise all options are independent and can be used together in all possible combinations. Note that order can also include a \"by\" transformation, in which case it is applied after that defined with the by keyword. For more information on order values see the documentation on Alternate Orderings.\n\nRelations between two elements are defined as follows (with \"less\" and \"greater\" exchanged when rev=true):\n\nx is less than y if lt(by(x), by(y)) (or Base.Order.lt(order, by(x), by(y))) yields true.\nx is greater than y if y is less than x.\nx and y are equivalent if neither is less than the other (\"incomparable\" is sometimes used as a synonym for \"equivalent\").\n\nThe result of sort! is sorted in the sense that every element is greater than or equivalent to the previous one.\n\nThe lt function must define a strict weak order, that is, it must be\n\nirreflexive: lt(x, x) always yields false,\nasymmetric: if lt(x, y) yields true then lt(y, x) yields false,\ntransitive: lt(x, y) && lt(y, z) implies lt(x, z),\ntransitive in equivalence: !lt(x, y) && !lt(y, x) and !lt(y, z) && !lt(z, y) together imply !lt(x, z) && !lt(z, x). In words: if x and y are equivalent and y and z are equivalent then x and z must be equivalent.\n\nFor example < is a valid lt function for Int values but ≤ is not: it violates irreflexivity. For Float64 values even < is invalid as it violates the fourth condition: 1.0 and NaN are equivalent and so are NaN and 2.0 but 1.0 and 2.0 are not equivalent.\n\nSee also sort, sortperm, sortslices, partialsort!, partialsortperm, issorted, searchsorted, insorted, Base.Order.ord.\n\nExamples\n\njulia> v = [3, 1, 2]; sort!(v); v\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> v = [3, 1, 2]; sort!(v, rev = true); v\n3-element Vector{Int64}:\n 3\n 2\n 1\n\njulia> v = [(1, \"c\"), (3, \"a\"), (2, \"b\")]; sort!(v, by = x -> x[1]); v\n3-element Vector{Tuple{Int64, String}}:\n (1, \"c\")\n (2, \"b\")\n (3, \"a\")\n\njulia> v = [(1, \"c\"), (3, \"a\"), (2, \"b\")]; sort!(v, by = x -> x[2]); v\n3-element Vector{Tuple{Int64, String}}:\n (3, \"a\")\n (2, \"b\")\n (1, \"c\")\n\njulia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) # same as sort(0:3, by=abs(x->x-2))\n4-element Vector{Int64}:\n 2\n 1\n 3\n 0\n\njulia> sort([2, NaN, 1, NaN, 3]) # correct sort with default lt=isless\n5-element Vector{Float64}:\n 1.0\n 2.0\n 3.0\n NaN\n NaN\n\njulia> sort([2, NaN, 1, NaN, 3], lt=<) # wrong sort due to invalid lt. This behavior is undefined.\n5-element Vector{Float64}:\n 2.0\n NaN\n 1.0\n NaN\n 3.0\n\n\n\n\n\nsort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nSort the multidimensional array A along dimension dims. See the one-dimensional version of sort! for a description of possible keyword arguments.\n\nTo sort slices of an array, refer to sortslices.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nExamples\n\njulia> A = [4 3; 1 2]\n2×2 Matrix{Int64}:\n 4 3\n 1 2\n\njulia> sort!(A, dims = 1); A\n2×2 Matrix{Int64}:\n 1 2\n 4 3\n\njulia> sort!(A, dims = 2); A\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.sort","page":"Sorting and Related Functions","title":"Base.sort","text":"sort(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nVariant of sort! that returns a sorted copy of v leaving v itself unmodified.\n\nExamples\n\njulia> v = [3, 1, 2];\n\njulia> sort(v)\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> v\n3-element Vector{Int64}:\n 3\n 1\n 2\n\n\n\n\n\nsort(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nSort a multidimensional array A along the given dimension. See sort! for a description of possible keyword arguments.\n\nTo sort slices of an array, refer to sortslices.\n\nExamples\n\njulia> A = [4 3; 1 2]\n2×2 Matrix{Int64}:\n 4 3\n 1 2\n\njulia> sort(A, dims = 1)\n2×2 Matrix{Int64}:\n 1 2\n 4 3\n\njulia> sort(A, dims = 2)\n2×2 Matrix{Int64}:\n 3 4\n 1 2\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.sortperm","page":"Sorting and Related Functions","title":"Base.sortperm","text":"sortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])\n\nReturn a permutation vector or array I that puts A[I] in sorted order along the given dimension. If A has more than one dimension, then the dims keyword argument must be specified. The order is specified using the same keywords as sort!. The permutation is guaranteed to be stable even if the sorting algorithm is unstable: the indices of equal elements will appear in ascending order.\n\nSee also sortperm!, partialsortperm, invperm, indexin. To sort slices of an array, refer to sortslices.\n\ncompat: Julia 1.9\nThe method accepting dims requires at least Julia 1.9.\n\nExamples\n\njulia> v = [3, 1, 2];\n\njulia> p = sortperm(v)\n3-element Vector{Int64}:\n 2\n 3\n 1\n\njulia> v[p]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> A = [8 7; 5 6]\n2×2 Matrix{Int64}:\n 8 7\n 5 6\n\njulia> sortperm(A, dims = 1)\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\njulia> sortperm(A, dims = 2)\n2×2 Matrix{Int64}:\n 3 1\n 2 4\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.InsertionSort","page":"Sorting and Related Functions","title":"Base.Sort.InsertionSort","text":"InsertionSort\n\nUse the insertion sort algorithm.\n\nInsertion sort traverses the collection one element at a time, inserting each element into its correct, sorted position in the output vector.\n\nCharacteristics:\n\nstable: preserves the ordering of elements that compare equal\n\n(e.g. \"a\" and \"A\" in a sort of letters that ignores case).\n\nin-place in memory.\nquadratic performance in the number of elements to be sorted:\n\nit is well-suited to small collections but should not be used for large ones.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Sort.MergeSort","page":"Sorting and Related Functions","title":"Base.Sort.MergeSort","text":"MergeSort\n\nIndicate that a sorting function should use the merge sort algorithm. Merge sort divides the collection into subcollections and repeatedly merges them, sorting each subcollection at each step, until the entire collection has been recombined in sorted form.\n\nCharacteristics:\n\nstable: preserves the ordering of elements that compare equal (e.g. \"a\" and \"A\" in a sort of letters that ignores case).\nnot in-place in memory.\ndivide-and-conquer sort strategy.\ngood performance for large collections but typically not quite as fast as QuickSort.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Sort.QuickSort","page":"Sorting and Related Functions","title":"Base.Sort.QuickSort","text":"QuickSort\n\nIndicate that a sorting function should use the quick sort algorithm, which is not stable.\n\nCharacteristics:\n\nnot stable: does not preserve the ordering of elements that compare equal (e.g. \"a\" and \"A\" in a sort of letters that ignores case).\nin-place in memory.\ndivide-and-conquer: sort strategy similar to MergeSort.\ngood performance for large collections.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Sort.PartialQuickSort","page":"Sorting and Related Functions","title":"Base.Sort.PartialQuickSort","text":"PartialQuickSort{T <: Union{Integer,OrdinalRange}}\n\nIndicate that a sorting function should use the partial quick sort algorithm. PartialQuickSort(k) is like QuickSort, but is only required to find and sort the elements that would end up in v[k] were v fully sorted.\n\nCharacteristics:\n\nnot stable: does not preserve the ordering of elements that compare equal (e.g. \"a\" and \"A\" in a sort of letters that ignores case).\nin-place in memory.\ndivide-and-conquer: sort strategy similar to MergeSort.\n\nNote that PartialQuickSort(k) does not necessarily sort the whole array. For example,\n\njulia> x = rand(100);\n\njulia> k = 50:100;\n\njulia> s1 = sort(x; alg=QuickSort);\n\njulia> s2 = sort(x; alg=PartialQuickSort(k));\n\njulia> map(issorted, (s1, s2))\n(true, false)\n\njulia> map(x->issorted(x[k]), (s1, s2))\n(true, true)\n\njulia> s1[k] == s2[k]\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Sort.sortperm!","page":"Sorting and Related Functions","title":"Base.Sort.sortperm!","text":"sortperm!(ix, A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])\n\nLike sortperm, but accepts a preallocated index vector or array ix with the same axes as A. ix is initialized to contain the values LinearIndices(A).\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\ncompat: Julia 1.9\nThe method accepting dims requires at least Julia 1.9.\n\nExamples\n\njulia> v = [3, 1, 2]; p = zeros(Int, 3);\n\njulia> sortperm!(p, v); p\n3-element Vector{Int64}:\n 2\n 3\n 1\n\njulia> v[p]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> A = [8 7; 5 6]; p = zeros(Int,2, 2);\n\njulia> sortperm!(p, A; dims=1); p\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\njulia> sortperm!(p, A; dims=2); p\n2×2 Matrix{Int64}:\n 3 1\n 2 4\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.sortslices","page":"Sorting and Related Functions","title":"Base.sortslices","text":"sortslices(A; dims, alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nSort slices of an array A. The required keyword argument dims must be either an integer or a tuple of integers. It specifies the dimension(s) over which the slices are sorted.\n\nE.g., if A is a matrix, dims=1 will sort rows, dims=2 will sort columns. Note that the default comparison function on one dimensional slices sorts lexicographically.\n\nFor the remaining keyword arguments, see the documentation of sort!.\n\nExamples\n\njulia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1) # Sort rows\n3×3 Matrix{Int64}:\n -1 6 4\n 7 3 5\n 9 -2 8\n\njulia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, lt=(x,y)->isless(x[2],y[2]))\n3×3 Matrix{Int64}:\n 9 -2 8\n 7 3 5\n -1 6 4\n\njulia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, rev=true)\n3×3 Matrix{Int64}:\n 9 -2 8\n 7 3 5\n -1 6 4\n\njulia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2) # Sort columns\n3×3 Matrix{Int64}:\n 3 5 7\n -1 -4 6\n -2 8 9\n\njulia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, alg=InsertionSort, lt=(x,y)->isless(x[2],y[2]))\n3×3 Matrix{Int64}:\n 5 3 7\n -4 -1 6\n 8 -2 9\n\njulia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, rev=true)\n3×3 Matrix{Int64}:\n 7 5 3\n 6 -4 -1\n 9 8 -2\n\nHigher dimensions\n\nsortslices extends naturally to higher dimensions. E.g., if A is a a 2x2x2 array, sortslices(A, dims=3) will sort slices within the 3rd dimension, passing the 2x2 slices A[:, :, 1] and A[:, :, 2] to the comparison function. Note that while there is no default order on higher-dimensional slices, you may use the by or lt keyword argument to specify such an order.\n\nIf dims is a tuple, the order of the dimensions in dims is relevant and specifies the linear order of the slices. E.g., if A is three dimensional and dims is (1, 2), the orderings of the first two dimensions are re-arranged such that the slices (of the remaining third dimension) are sorted. If dims is (2, 1) instead, the same slices will be taken, but the result order will be row-major instead.\n\nHigher dimensional examples\n\njulia> A = [4 3; 2 1 ;;; 'A' 'B'; 'C' 'D']\n2×2×2 Array{Any, 3}:\n[:, :, 1] =\n 4 3\n 2 1\n\n[:, :, 2] =\n 'A' 'B'\n 'C' 'D'\n\njulia> sortslices(A, dims=(1,2))\n2×2×2 Array{Any, 3}:\n[:, :, 1] =\n 1 3\n 2 4\n\n[:, :, 2] =\n 'D' 'B'\n 'C' 'A'\n\njulia> sortslices(A, dims=(2,1))\n2×2×2 Array{Any, 3}:\n[:, :, 1] =\n 1 2\n 3 4\n\n[:, :, 2] =\n 'D' 'C'\n 'B' 'A'\n\njulia> sortslices(reshape([5; 4; 3; 2; 1], (1,1,5)), dims=3, by=x->x[1,1])\n1×1×5 Array{Int64, 3}:\n[:, :, 1] =\n 1\n\n[:, :, 2] =\n 2\n\n[:, :, 3] =\n 3\n\n[:, :, 4] =\n 4\n\n[:, :, 5] =\n 5\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Order-Related-Functions","page":"Sorting and Related Functions","title":"Order-Related Functions","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Base.issorted\nBase.Sort.searchsorted\nBase.Sort.searchsortedfirst\nBase.Sort.searchsortedlast\nBase.Sort.insorted\nBase.Sort.partialsort!\nBase.Sort.partialsort\nBase.Sort.partialsortperm\nBase.Sort.partialsortperm!","category":"page"},{"location":"base/sort/#Base.issorted","page":"Sorting and Related Functions","title":"Base.issorted","text":"issorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nTest whether a collection is in sorted order. The keywords modify what order is considered sorted, as described in the sort! documentation.\n\nExamples\n\njulia> issorted([1, 2, 3])\ntrue\n\njulia> issorted([(1, \"b\"), (2, \"a\")], by = x -> x[1])\ntrue\n\njulia> issorted([(1, \"b\"), (2, \"a\")], by = x -> x[2])\nfalse\n\njulia> issorted([(1, \"b\"), (2, \"a\")], by = x -> x[2], rev=true)\ntrue\n\njulia> issorted([1, 2, -2, 3], by=abs)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.searchsorted","page":"Sorting and Related Functions","title":"Base.Sort.searchsorted","text":"searchsorted(v, x; by=identity, lt=isless, rev=false)\n\nReturn the range of indices in v where values are equivalent to x, or an empty range located at the insertion point if v does not contain values equivalent to x. The vector v must be sorted according to the order defined by the keywords. Refer to sort! for the meaning of the keywords and the definition of equivalence. Note that the by function is applied to the searched value x as well as the values in v.\n\nThe range is generally found using binary search, but there are optimized implementations for some inputs.\n\nSee also: searchsortedfirst, sort!, insorted, findall.\n\nExamples\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 4) # single match\n3:3\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 5) # multiple matches\n4:5\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 3) # no match, insert in the middle\n3:2\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 9) # no match, insert at end\n7:6\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 0) # no match, insert at start\n1:0\n\njulia> searchsorted([1=>\"one\", 2=>\"two\", 2=>\"two\", 4=>\"four\"], 2=>\"two\", by=first) # compare the keys of the pairs\n2:3\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.searchsortedfirst","page":"Sorting and Related Functions","title":"Base.Sort.searchsortedfirst","text":"searchsortedfirst(v, x; by=identity, lt=isless, rev=false)\n\nReturn the index of the first value in v that is not ordered before x. If all values in v are ordered before x, return lastindex(v) + 1.\n\nThe vector v must be sorted according to the order defined by the keywords. insert!ing x at the returned index will maintain the sorted order. Refer to sort! for the meaning and use of the keywords. Note that the by function is applied to the searched value x as well as the values in v.\n\nThe index is generally found using binary search, but there are optimized implementations for some inputs.\n\nSee also: searchsortedlast, searchsorted, findfirst.\n\nExamples\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 4) # single match\n3\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 5) # multiple matches\n4\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 3) # no match, insert in the middle\n3\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 9) # no match, insert at end\n7\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 0) # no match, insert at start\n1\n\njulia> searchsortedfirst([1=>\"one\", 2=>\"two\", 4=>\"four\"], 3=>\"three\", by=first) # compare the keys of the pairs\n3\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.searchsortedlast","page":"Sorting and Related Functions","title":"Base.Sort.searchsortedlast","text":"searchsortedlast(v, x; by=identity, lt=isless, rev=false)\n\nReturn the index of the last value in v that is not ordered after x. If all values in v are ordered after x, return firstindex(v) - 1.\n\nThe vector v must be sorted according to the order defined by the keywords. insert!ing x immediately after the returned index will maintain the sorted order. Refer to sort! for the meaning and use of the keywords. Note that the by function is applied to the searched value x as well as the values in v.\n\nThe index is generally found using binary search, but there are optimized implementations for some inputs\n\nExamples\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 4) # single match\n3\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 5) # multiple matches\n5\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 3) # no match, insert in the middle\n2\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 9) # no match, insert at end\n6\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 0) # no match, insert at start\n0\n\njulia> searchsortedlast([1=>\"one\", 2=>\"two\", 4=>\"four\"], 3=>\"three\", by=first) # compare the keys of the pairs\n2\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.insorted","page":"Sorting and Related Functions","title":"Base.Sort.insorted","text":"insorted(x, v; by=identity, lt=isless, rev=false) -> Bool\n\nDetermine whether a vector v contains any value equivalent to x. The vector v must be sorted according to the order defined by the keywords. Refer to sort! for the meaning of the keywords and the definition of equivalence. Note that the by function is applied to the searched value x as well as the values in v.\n\nThe check is generally done using binary search, but there are optimized implementations for some inputs.\n\nSee also in.\n\nExamples\n\njulia> insorted(4, [1, 2, 4, 5, 5, 7]) # single match\ntrue\n\njulia> insorted(5, [1, 2, 4, 5, 5, 7]) # multiple matches\ntrue\n\njulia> insorted(3, [1, 2, 4, 5, 5, 7]) # no match\nfalse\n\njulia> insorted(9, [1, 2, 4, 5, 5, 7]) # no match\nfalse\n\njulia> insorted(0, [1, 2, 4, 5, 5, 7]) # no match\nfalse\n\njulia> insorted(2=>\"TWO\", [1=>\"one\", 2=>\"two\", 4=>\"four\"], by=first) # compare the keys of the pairs\ntrue\n\ncompat: Julia 1.6\ninsorted was added in Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.partialsort!","page":"Sorting and Related Functions","title":"Base.Sort.partialsort!","text":"partialsort!(v, k; by=identity, lt=isless, rev=false)\n\nPartially sort the vector v in place so that the value at index k (or range of adjacent values if k is a range) occurs at the position where it would appear if the array were fully sorted. If k is a single index, that value is returned; if k is a range, an array of values at those indices is returned. Note that partialsort! may not fully sort the input array.\n\nFor the keyword arguments, see the documentation of sort!.\n\nExamples\n\njulia> a = [1, 2, 4, 3, 4]\n5-element Vector{Int64}:\n 1\n 2\n 4\n 3\n 4\n\njulia> partialsort!(a, 4)\n4\n\njulia> a\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 4\n\njulia> a = [1, 2, 4, 3, 4]\n5-element Vector{Int64}:\n 1\n 2\n 4\n 3\n 4\n\njulia> partialsort!(a, 4, rev=true)\n2\n\njulia> a\n5-element Vector{Int64}:\n 4\n 4\n 3\n 2\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.partialsort","page":"Sorting and Related Functions","title":"Base.Sort.partialsort","text":"partialsort(v, k, by=identity, lt=isless, rev=false)\n\nVariant of partialsort! that copies v before partially sorting it, thereby returning the same thing as partialsort! but leaving v unmodified.\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.partialsortperm","page":"Sorting and Related Functions","title":"Base.Sort.partialsortperm","text":"partialsortperm(v, k; by=ientity, lt=isless, rev=false)\n\nReturn a partial permutation I of the vector v, so that v[I] returns values of a fully sorted version of v at index k. If k is a range, a vector of indices is returned; if k is an integer, a single index is returned. The order is specified using the same keywords as sort!. The permutation is stable: the indices of equal elements will appear in ascending order.\n\nThis function is equivalent to, but more efficient than, calling sortperm(...)[k].\n\nExamples\n\njulia> v = [3, 1, 2, 1];\n\njulia> v[partialsortperm(v, 1)]\n1\n\njulia> p = partialsortperm(v, 1:3)\n3-element view(::Vector{Int64}, 1:3) with eltype Int64:\n 2\n 4\n 3\n\njulia> v[p]\n3-element Vector{Int64}:\n 1\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.partialsortperm!","page":"Sorting and Related Functions","title":"Base.Sort.partialsortperm!","text":"partialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)\n\nLike partialsortperm, but accepts a preallocated index vector ix the same size as v, which is used to store (a permutation of) the indices of v.\n\nix is initialized to contain the indices of v.\n\n(Typically, the indices of v will be 1:length(v), although if v has an alternative array type with non-one-based indices, such as an OffsetArray, ix must share those same indices)\n\nUpon return, ix is guaranteed to have the indices k in their sorted positions, such that\n\npartialsortperm!(ix, v, k);\nv[ix[k]] == partialsort(v, k)\n\nThe return value is the kth element of ix if k is an integer, or view into ix if k is a range.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> v = [3, 1, 2, 1];\n\njulia> ix = Vector{Int}(undef, 4);\n\njulia> partialsortperm!(ix, v, 1)\n2\n\njulia> ix = [1:4;];\n\njulia> partialsortperm!(ix, v, 2:3)\n2-element view(::Vector{Int64}, 2:3) with eltype Int64:\n 4\n 3\n\n\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Sorting-Algorithms","page":"Sorting and Related Functions","title":"Sorting Algorithms","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"There are currently four sorting algorithms publicly available in base Julia:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"InsertionSort\nQuickSort\nPartialQuickSort(k)\nMergeSort","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"By default, the sort family of functions uses stable sorting algorithms that are fast on most inputs. The exact algorithm choice is an implementation detail to allow for future performance improvements. Currently, a hybrid of RadixSort, ScratchQuickSort, InsertionSort, and CountingSort is used based on input type, size, and composition. Implementation details are subject to change but currently available in the extended help of ??Base.DEFAULT_STABLE and the docstrings of internal sorting algorithms listed there.","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"You can explicitly specify your preferred algorithm with the alg keyword (e.g. sort!(v, alg=PartialQuickSort(10:20))) or reconfigure the default sorting algorithm for custom types by adding a specialized method to the Base.Sort.defalg function. For example, InlineStrings.jl defines the following method:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSort","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"compat: Julia 1.9\nThe default sorting algorithm (returned by Base.Sort.defalg) is guaranteed to be stable since Julia 1.9. Previous versions had unstable edge cases when sorting numeric arrays.","category":"page"},{"location":"base/sort/#Alternate-Orderings","page":"Sorting and Related Functions","title":"Alternate Orderings","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"By default, sort, searchsorted, and related functions use isless to compare two elements in order to determine which should come first. The Base.Order.Ordering abstract type provides a mechanism for defining alternate orderings on the same set of elements: when calling a sorting function like sort!, an instance of Ordering can be provided with the keyword argument order.","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Instances of Ordering define an order through the Base.Order.lt function, which works as a generalization of isless. This function's behavior on custom Orderings must satisfy all the conditions of a strict weak order. See sort! for details and examples of valid and invalid lt functions.","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Base.Order.Ordering\nBase.Order.lt\nBase.Order.ord\nBase.Order.Forward\nBase.Order.ReverseOrdering\nBase.Order.Reverse\nBase.Order.By\nBase.Order.Lt\nBase.Order.Perm","category":"page"},{"location":"base/sort/#Base.Order.Ordering","page":"Sorting and Related Functions","title":"Base.Order.Ordering","text":"Base.Order.Ordering\n\nAbstract type which represents a strict weak order on some set of elements. See sort! for more.\n\nUse Base.Order.lt to compare two elements according to the ordering.\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Order.lt","page":"Sorting and Related Functions","title":"Base.Order.lt","text":"lt(o::Ordering, a, b) -> Bool\n\nTest whether a is less than b according to the ordering o.\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Order.ord","page":"Sorting and Related Functions","title":"Base.Order.ord","text":"ord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)\n\nConstruct an Ordering object from the same arguments used by sort!. Elements are first transformed by the function by (which may be identity) and are then compared according to either the function lt or an existing ordering order. lt should be isless or a function that obeys the same rules as the lt parameter of sort!. Finally, the resulting order is reversed if rev=true.\n\nPassing an lt other than isless along with an order other than Base.Order.Forward or Base.Order.Reverse is not permitted, otherwise all options are independent and can be used together in all possible combinations.\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Order.Forward","page":"Sorting and Related Functions","title":"Base.Order.Forward","text":"Base.Order.Forward\n\nDefault ordering according to isless.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Order.ReverseOrdering","page":"Sorting and Related Functions","title":"Base.Order.ReverseOrdering","text":"ReverseOrdering(fwd::Ordering=Forward)\n\nA wrapper which reverses an ordering.\n\nFor a given Ordering o, the following holds for all a, b:\n\nlt(ReverseOrdering(o), a, b) == lt(o, b, a)\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Order.Reverse","page":"Sorting and Related Functions","title":"Base.Order.Reverse","text":"Base.Order.Reverse\n\nReverse ordering according to isless.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Order.By","page":"Sorting and Related Functions","title":"Base.Order.By","text":"By(by, order::Ordering=Forward)\n\nOrdering which applies order to elements after they have been transformed by the function by.\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Order.Lt","page":"Sorting and Related Functions","title":"Base.Order.Lt","text":"Lt(lt)\n\nOrdering that calls lt(a, b) to compare elements. lt must obey the same rules as the lt parameter of sort!.\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Order.Perm","page":"Sorting and Related Functions","title":"Base.Order.Perm","text":"Perm(order::Ordering, data::AbstractVector)\n\nOrdering on the indices of data where i is less than j if data[i] is less than data[j] according to order. In the case that data[i] and data[j] are equal, i and j are compared by numeric value.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Base64/","page":"Base64","title":"Base64","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Base64/docs/src/index.md\"","category":"page"},{"location":"stdlib/Base64/#Base64","page":"Base64","title":"Base64","text":"","category":"section"},{"location":"stdlib/Base64/","page":"Base64","title":"Base64","text":"Base64.Base64\nBase64.Base64EncodePipe\nBase64.base64encode\nBase64.Base64DecodePipe\nBase64.base64decode\nBase64.stringmime","category":"page"},{"location":"stdlib/Base64/#Base64.Base64","page":"Base64","title":"Base64.Base64","text":"Base64\n\nFunctionality for base64 encoding and decoding, a method to represent binary data using text, common on the web.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Base64/#Base64.Base64EncodePipe","page":"Base64","title":"Base64.Base64EncodePipe","text":"Base64EncodePipe(ostream)\n\nReturn a new write-only I/O stream, which converts any bytes written to it into base64-encoded ASCII bytes written to ostream. Calling close on the Base64EncodePipe stream is necessary to complete the encoding (but does not close ostream).\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> iob64_encode = Base64EncodePipe(io);\n\njulia> write(iob64_encode, \"Hello!\")\n6\n\njulia> close(iob64_encode);\n\njulia> str = String(take!(io))\n\"SGVsbG8h\"\n\njulia> String(base64decode(str))\n\"Hello!\"\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Base64/#Base64.base64encode","page":"Base64","title":"Base64.base64encode","text":"base64encode(writefunc, args...; context=nothing)\nbase64encode(args...; context=nothing)\n\nGiven a write-like function writefunc, which takes an I/O stream as its first argument, base64encode(writefunc, args...) calls writefunc to write args... to a base64-encoded string, and returns the string. base64encode(args...) is equivalent to base64encode(write, args...): it converts its arguments into bytes using the standard write functions and returns the base64-encoded string.\n\nThe optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to writefunc or write.\n\nSee also base64decode.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Base64/#Base64.Base64DecodePipe","page":"Base64","title":"Base64.Base64DecodePipe","text":"Base64DecodePipe(istream)\n\nReturn a new read-only I/O stream, which decodes base64-encoded data read from istream.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> iob64_decode = Base64DecodePipe(io);\n\njulia> write(io, \"SGVsbG8h\")\n8\n\njulia> seekstart(io);\n\njulia> String(read(iob64_decode))\n\"Hello!\"\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Base64/#Base64.base64decode","page":"Base64","title":"Base64.base64decode","text":"base64decode(string)\n\nDecode the base64-encoded string and returns a Vector{UInt8} of the decoded bytes.\n\nSee also base64encode.\n\nExamples\n\njulia> b = base64decode(\"SGVsbG8h\")\n6-element Vector{UInt8}:\n 0x48\n 0x65\n 0x6c\n 0x6c\n 0x6f\n 0x21\n\njulia> String(b)\n\"Hello!\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Base64/#Base64.stringmime","page":"Base64","title":"Base64.stringmime","text":"stringmime(mime, x; context=nothing)\n\nReturn an AbstractString containing the representation of x in the requested mime type. This is similar to repr(mime, x) except that binary data is base64-encoded as an ASCII string.\n\nThe optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to show.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/FileWatching/docs/src/index.md\"","category":"page"},{"location":"stdlib/FileWatching/#lib-filewatching","page":"File Events","title":"File Events","text":"","category":"section"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"FileWatching.poll_fd\nFileWatching.poll_file\nFileWatching.watch_file\nFileWatching.watch_folder\nFileWatching.unwatch_folder","category":"page"},{"location":"stdlib/FileWatching/#FileWatching.poll_fd","page":"File Events","title":"FileWatching.poll_fd","text":"poll_fd(fd, timeout_s::Real=-1; readable=false, writable=false)\n\nMonitor a file descriptor fd for changes in the read or write availability, and with a timeout given by timeout_s seconds.\n\nThe keyword arguments determine which of read and/or write status should be monitored; at least one of them must be set to true.\n\nThe returned value is an object with boolean fields readable, writable, and timedout, giving the result of the polling.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.poll_file","page":"File Events","title":"FileWatching.poll_file","text":"poll_file(path::AbstractString, interval_s::Real=5.007, timeout_s::Real=-1) -> (previous::StatStruct, current)\n\nMonitor a file for changes by polling every interval_s seconds until a change occurs or timeout_s seconds have elapsed. The interval_s should be a long period; the default is 5.007 seconds.\n\nReturns a pair of status objects (previous, current) when a change is detected. The previous status is always a StatStruct, but it may have all of the fields zeroed (indicating the file didn't previously exist, or wasn't previously accessible).\n\nThe current status object may be a StatStruct, an EOFError (indicating the timeout elapsed), or some other Exception subtype (if the stat operation failed - for example, if the path does not exist).\n\nTo determine when a file was modified, compare current isa StatStruct && mtime(prev) != mtime(current) to detect notification of changes. However, using watch_file for this operation is preferred, since it is more reliable and efficient, although in some situations it may not be available.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.watch_file","page":"File Events","title":"FileWatching.watch_file","text":"watch_file(path::AbstractString, timeout_s::Real=-1)\n\nWatch file or directory path for changes until a change occurs or timeout_s seconds have elapsed. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.\n\nThe returned value is an object with boolean fields renamed, changed, and timedout, giving the result of watching the file.\n\nThis behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.watch_folder","page":"File Events","title":"FileWatching.watch_folder","text":"watch_folder(path::AbstractString, timeout_s::Real=-1)\n\nWatches a file or directory path for changes until a change has occurred or timeout_s seconds have elapsed. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.\n\nThis will continuing tracking changes for path in the background until unwatch_folder is called on the same path.\n\nThe returned value is an pair where the first field is the name of the changed file (if available) and the second field is an object with boolean fields renamed, changed, and timedout, giving the event.\n\nThis behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.unwatch_folder","page":"File Events","title":"FileWatching.unwatch_folder","text":"unwatch_folder(path::AbstractString)\n\nStop background tracking of changes for path. It is not recommended to do this while another task is waiting for watch_folder to return on the same path, as the result may be unpredictable.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#Pidfile","page":"File Events","title":"Pidfile","text":"","category":"section"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"CurrentModule = FileWatching.Pidfile","category":"page"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"A simple utility tool for creating advisory pidfiles (lock files).","category":"page"},{"location":"stdlib/FileWatching/#Primary-Functions","page":"File Events","title":"Primary Functions","text":"","category":"section"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"mkpidlock\ntrymkpidlock\nclose(lock::LockMonitor)","category":"page"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.mkpidlock","page":"File Events","title":"FileWatching.Pidfile.mkpidlock","text":"mkpidlock([f::Function], at::String, [pid::Cint]; kwopts...)\nmkpidlock(at::String, proc::Process; kwopts...)\n\nCreate a pidfile lock for the path \"at\" for the current process or the process identified by pid or proc. Can take a function to execute once locked, for usage in do blocks, after which the lock will be automatically closed. If the lock fails and wait is false, then an error is thrown.\n\nThe lock will be released by either close, a finalizer, or shortly after proc exits. Make sure the return value is live through the end of the critical section of your program, so the finalizer does not reclaim it early.\n\nOptional keyword arguments:\n\nmode: file access mode (modified by the process umask). Defaults to world-readable.\npoll_interval: Specify the maximum time to between attempts (if watch_file doesn't work)\nstale_age: Delete an existing pidfile (ignoring the lock) if it is older than this many seconds, based on its mtime. The file won't be deleted until 5x longer than this if the pid in the file appears that it may be valid. Or 25x longer if refresh is overridden to 0 to disable lock refreshing. By default this is disabled (stale_age = 0), but a typical recommended value would be about 3-5x an estimated normal completion time.\nrefresh: Keeps a lock from becoming stale by updating the mtime every interval of time that passes. By default, this is set to stale_age/2, which is the recommended value.\nwait: If true, block until we get the lock, if false, raise error if lock fails.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.trymkpidlock","page":"File Events","title":"FileWatching.Pidfile.trymkpidlock","text":"trymkpidlock([f::Function], at::String, [pid::Cint]; kwopts...)\ntrymkpidlock(at::String, proc::Process; kwopts...)\n\nLike mkpidlock except returns false instead of waiting if the file is already locked.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#Base.close-Tuple{FileWatching.Pidfile.LockMonitor}","page":"File Events","title":"Base.close","text":"close(lock::LockMonitor)\n\nRelease a pidfile lock.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/FileWatching/#Helper-Functions","page":"File Events","title":"Helper Functions","text":"","category":"section"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"Pidfile.open_exclusive\nPidfile.tryopen_exclusive\nPidfile.write_pidfile\nPidfile.parse_pidfile\nPidfile.stale_pidfile\nPidfile.isvalidpid\nBase.touch(::Pidfile.LockMonitor)","category":"page"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.open_exclusive","page":"File Events","title":"FileWatching.Pidfile.open_exclusive","text":"open_exclusive(path::String; mode, poll_interval, wait, stale_age, refresh) :: File\n\nCreate a new a file for read-write advisory-exclusive access. If wait is false then error out if the lock files exist otherwise block until we get the lock.\n\nFor a description of the keyword arguments, see mkpidlock.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.tryopen_exclusive","page":"File Events","title":"FileWatching.Pidfile.tryopen_exclusive","text":"tryopen_exclusive(path::String, mode::Integer = 0o444) :: Union{Void, File}\n\nTry to create a new file for read-write advisory-exclusive access, return nothing if it already exists.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.write_pidfile","page":"File Events","title":"FileWatching.Pidfile.write_pidfile","text":"write_pidfile(io, pid)\n\nWrite our pidfile format to an open IO descriptor.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.parse_pidfile","page":"File Events","title":"FileWatching.Pidfile.parse_pidfile","text":"parse_pidfile(file::Union{IO, String}) => (pid, hostname, age)\n\nAttempt to parse our pidfile format, replaced an element with (0, \"\", 0.0), respectively, for any read that failed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.stale_pidfile","page":"File Events","title":"FileWatching.Pidfile.stale_pidfile","text":"stale_pidfile(path::String, stale_age::Real, refresh::Real) :: Bool\n\nHelper function for open_exclusive for deciding if a pidfile is stale.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.isvalidpid","page":"File Events","title":"FileWatching.Pidfile.isvalidpid","text":"isvalidpid(hostname::String, pid::Cuint) :: Bool\n\nAttempt to conservatively estimate whether pid is a valid process id.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#Base.Filesystem.touch-Tuple{FileWatching.Pidfile.LockMonitor}","page":"File Events","title":"Base.Filesystem.touch","text":"Base.touch(::Pidfile.LockMonitor)\n\nUpdate the mtime on the lock, to indicate it is still fresh.\n\nSee also the refresh keyword in the mkpidlock constructor.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Logging/docs/src/index.md\"","category":"page"},{"location":"stdlib/Logging/#man-logging","page":"Logging","title":"Logging","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The Logging module provides a way to record the history and progress of a computation as a log of events. Events are created by inserting a logging statement into the source code, for example:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"@warn \"Abandon printf debugging, all ye who enter here!\"\n┌ Warning: Abandon printf debugging, all ye who enter here!\n└ @ Main REPL[1]:1","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The system provides several advantages over peppering your source code with calls to println(). First, it allows you to control the visibility and presentation of messages without editing the source code. For example, in contrast to the @warn above","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"@debug \"The sum of some values $(sum(rand(100)))\"","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"will produce no output by default. Furthermore, it's very cheap to leave debug statements like this in the source code because the system avoids evaluating the message if it would later be ignored. In this case sum(rand(100)) and the associated string processing will never be executed unless debug logging is enabled.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Second, the logging tools allow you to attach arbitrary data to each event as a set of key–value pairs. This allows you to capture local variables and other program state for later analysis. For example, to attach the local array variable A and the sum of a vector v as the key s you can use","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"A = ones(Int, 4, 4)\nv = ones(100)\n@info \"Some variables\" A s=sum(v)\n\n# output\n┌ Info: Some variables\n│ A =\n│ 4×4 Matrix{Int64}:\n│ 1 1 1 1\n│ 1 1 1 1\n│ 1 1 1 1\n│ 1 1 1 1\n└ s = 100.0","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"All of the logging macros @debug, @info, @warn and @error share common features that are described in detail in the documentation for the more general macro @logmsg.","category":"page"},{"location":"stdlib/Logging/#Log-event-structure","page":"Logging","title":"Log event structure","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Each event generates several pieces of data, some provided by the user and some automatically extracted. Let's examine the user-defined data first:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The log level is a broad category for the message that is used for early filtering. There are several standard levels of type LogLevel; user-defined levels are also possible. Each is distinct in purpose:\nLogging.Debug (log level -1000) is information intended for the developer of the program. These events are disabled by default.\nLogging.Info (log level 0) is for general information to the user. Think of it as an alternative to using println directly.\nLogging.Warn (log level 1000) means something is wrong and action is likely required but that for now the program is still working.\nLogging.Error (log level 2000) means something is wrong and it is unlikely to be recovered, at least by this part of the code. Often this log-level is unneeded as throwing an exception can convey all the required information.\nThe message is an object describing the event. By convention AbstractStrings passed as messages are assumed to be in markdown format. Other types will be displayed using print(io, obj) or string(obj) for text-based output and possibly show(io,mime,obj) for other multimedia displays used in the installed logger.\nOptional key–value pairs allow arbitrary data to be attached to each event. Some keys have conventional meaning that can affect the way an event is interpreted (see @logmsg).","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The system also generates some standard information for each event:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The module in which the logging macro was expanded.\nThe file and line where the logging macro occurs in the source code.\nA message id that is a unique, fixed identifier for the source code statement where the logging macro appears. This identifier is designed to be fairly stable even if the source code of the file changes, as long as the logging statement itself remains the same.\nA group for the event, which is set to the base name of the file by default, without extension. This can be used to group messages into categories more finely than the log level (for example, all deprecation warnings have group :depwarn), or into logical groupings across or within modules.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Notice that some useful information such as the event time is not included by default. This is because such information can be expensive to extract and is also dynamically available to the current logger. It's simple to define a custom logger to augment event data with the time, backtrace, values of global variables and other useful information as required.","category":"page"},{"location":"stdlib/Logging/#Processing-log-events","page":"Logging","title":"Processing log events","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"As you can see in the examples, logging statements make no mention of where log events go or how they are processed. This is a key design feature that makes the system composable and natural for concurrent use. It does this by separating two different concerns:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Creating log events is the concern of the module author who needs to decide where events are triggered and which information to include.\nProcessing of log events — that is, display, filtering, aggregation and recording — is the concern of the application author who needs to bring multiple modules together into a cooperating application.","category":"page"},{"location":"stdlib/Logging/#Loggers","page":"Logging","title":"Loggers","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Processing of events is performed by a logger, which is the first piece of user configurable code to see the event. All loggers must be subtypes of AbstractLogger.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"When an event is triggered, the appropriate logger is found by looking for a task-local logger with the global logger as fallback. The idea here is that the application code knows how log events should be processed and exists somewhere at the top of the call stack. So we should look up through the call stack to discover the logger — that is, the logger should be dynamically scoped. (This is a point of contrast with logging frameworks where the logger is lexically scoped; provided explicitly by the module author or as a simple global variable. In such a system it's awkward to control logging while composing functionality from multiple modules.)","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The global logger may be set with global_logger, and task-local loggers controlled using with_logger. Newly spawned tasks inherit the logger of the parent task.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"There are three logger types provided by the library. ConsoleLogger is the default logger you see when starting the REPL. It displays events in a readable text format and tries to give simple but user friendly control over formatting and filtering. NullLogger is a convenient way to drop all messages where necessary; it is the logging equivalent of the devnull stream. SimpleLogger is a very simplistic text formatting logger, mainly useful for debugging the logging system itself.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Custom loggers should come with overloads for the functions described in the reference section.","category":"page"},{"location":"stdlib/Logging/#Early-filtering-and-message-handling","page":"Logging","title":"Early filtering and message handling","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"When an event occurs, a few steps of early filtering occur to avoid generating messages that will be discarded:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The message log level is checked against a global minimum level (set via disable_logging). This is a crude but extremely cheap global setting.\nThe current logger state is looked up and the message level checked against the logger's cached minimum level, as found by calling Logging.min_enabled_level. This behavior can be overridden via environment variables (more on this later).\nThe Logging.shouldlog function is called with the current logger, taking some minimal information (level, module, group, id) which can be computed statically. Most usefully, shouldlog is passed an event id which can be used to discard events early based on a cached predicate.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"If all these checks pass, the message and key–value pairs are evaluated in full and passed to the current logger via the Logging.handle_message function. handle_message() may perform additional filtering as required and display the event to the screen, save it to a file, etc.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Exceptions that occur while generating the log event are captured and logged by default. This prevents individual broken events from crashing the application, which is helpful when enabling little-used debug events in a production system. This behavior can be customized per logger type by extending Logging.catch_exceptions.","category":"page"},{"location":"stdlib/Logging/#Testing-log-events","page":"Logging","title":"Testing log events","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Log events are a side effect of running normal code, but you might find yourself wanting to test particular informational messages and warnings. The Test module provides a @test_logs macro that can be used to pattern match against the log event stream.","category":"page"},{"location":"stdlib/Logging/#Environment-variables","page":"Logging","title":"Environment variables","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Message filtering can be influenced through the JULIA_DEBUG environment variable, and serves as an easy way to enable debug logging for a file or module. Loading julia with JULIA_DEBUG=loading will activate @debug log messages in loading.jl. For example, in Linux shells:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"$ JULIA_DEBUG=loading julia -e 'using OhMyREPL'\n┌ Debug: Rejecting cache file /home/user/.julia/compiled/v0.7/OhMyREPL.ji due to it containing an invalid cache header\n└ @ Base loading.jl:1328\n[ Info: Recompiling stale cache file /home/user/.julia/compiled/v0.7/OhMyREPL.ji for module OhMyREPL\n┌ Debug: Rejecting cache file /home/user/.julia/compiled/v0.7/Tokenize.ji due to it containing an invalid cache header\n└ @ Base loading.jl:1328\n...","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"On windows, the same can be achieved in CMD via first running set JULIA_DEBUG=\"loading\" and in Powershell via $env:JULIA_DEBUG=\"loading\".","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Similarly, the environment variable can be used to enable debug logging of modules, such as Pkg, or module roots (see Base.moduleroot). To enable all debug logging, use the special value all.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"To turn debug logging on from the REPL, set ENV[\"JULIA_DEBUG\"] to the name of the module of interest. Functions defined in the REPL belong to module Main; logging for them can be enabled like this:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"julia> foo() = @debug \"foo\"\nfoo (generic function with 1 method)\n\njulia> foo()\n\njulia> ENV[\"JULIA_DEBUG\"] = Main\nMain\n\njulia> foo()\n┌ Debug: foo\n└ @ Main REPL[1]:1\n","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Use a comma separator to enable debug for multiple modules: JULIA_DEBUG=loading,Main.","category":"page"},{"location":"stdlib/Logging/#Examples","page":"Logging","title":"Examples","text":"","category":"section"},{"location":"stdlib/Logging/#Example:-Writing-log-events-to-a-file","page":"Logging","title":"Example: Writing log events to a file","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Sometimes it can be useful to write log events to a file. Here is an example of how to use a task-local and global logger to write information to a text file:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"# Load the logging module\njulia> using Logging\n\n# Open a textfile for writing\njulia> io = open(\"log.txt\", \"w+\")\nIOStream()\n\n# Create a simple logger\njulia> logger = SimpleLogger(io)\nSimpleLogger(IOStream(), Info, Dict{Any,Int64}())\n\n# Log a task-specific message\njulia> with_logger(logger) do\n @info(\"a context specific log message\")\n end\n\n# Write all buffered messages to the file\njulia> flush(io)\n\n# Set the global logger to logger\njulia> global_logger(logger)\nSimpleLogger(IOStream(), Info, Dict{Any,Int64}())\n\n# This message will now also be written to the file\njulia> @info(\"a global log message\")\n\n# Close the file\njulia> close(io)","category":"page"},{"location":"stdlib/Logging/#Example:-Enable-debug-level-messages","page":"Logging","title":"Example: Enable debug-level messages","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Here is an example of creating a ConsoleLogger that lets through any messages with log level higher than, or equal, to Logging.Debug.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"julia> using Logging\n\n# Create a ConsoleLogger that prints any log messages with level >= Debug to stderr\njulia> debuglogger = ConsoleLogger(stderr, Logging.Debug)\n\n# Enable debuglogger for a task\njulia> with_logger(debuglogger) do\n @debug \"a context specific log message\"\n end\n\n# Set the global logger\njulia> global_logger(debuglogger)","category":"page"},{"location":"stdlib/Logging/#Reference","page":"Logging","title":"Reference","text":"","category":"section"},{"location":"stdlib/Logging/#Logging-module","page":"Logging","title":"Logging module","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.Logging","category":"page"},{"location":"stdlib/Logging/#Logging.Logging","page":"Logging","title":"Logging.Logging","text":"Utilities for capturing, filtering and presenting streams of log events. Normally you don't need to import Logging to create log events; for this the standard logging macros such as @info are already exported by Base and available by default.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Logging/#Creating-events","page":"Logging","title":"Creating events","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.@logmsg\nLogging.LogLevel\nLogging.Debug\nLogging.Info\nLogging.Warn\nLogging.Error\nLogging.BelowMinLevel\nLogging.AboveMaxLevel","category":"page"},{"location":"stdlib/Logging/#Logging.@logmsg","page":"Logging","title":"Logging.@logmsg","text":"@debug message [key=value | value ...]\n@info message [key=value | value ...]\n@warn message [key=value | value ...]\n@error message [key=value | value ...]\n\n@logmsg level message [key=value | value ...]\n\nCreate a log record with an informational message. For convenience, four logging macros @debug, @info, @warn and @error are defined which log at the standard severity levels Debug, Info, Warn and Error. @logmsg allows level to be set programmatically to any LogLevel or custom log level types.\n\nmessage should be an expression which evaluates to a string which is a human readable description of the log event. By convention, this string will be formatted as markdown when presented.\n\nThe optional list of key=value pairs supports arbitrary user defined metadata which will be passed through to the logging backend as part of the log record. If only a value expression is supplied, a key representing the expression will be generated using Symbol. For example, x becomes x=x, and foo(10) becomes Symbol(\"foo(10)\")=foo(10). For splatting a list of key value pairs, use the normal splatting syntax, @info \"blah\" kws....\n\nThere are some keys which allow automatically generated log data to be overridden:\n\n_module=mod can be used to specify a different originating module from the source location of the message.\n_group=symbol can be used to override the message group (this is normally derived from the base name of the source file).\n_id=symbol can be used to override the automatically generated unique message identifier. This is useful if you need to very closely associate messages generated on different source lines.\n_file=string and _line=integer can be used to override the apparent source location of a log message.\n\nThere's also some key value pairs which have conventional meaning:\n\nmaxlog=integer should be used as a hint to the backend that the message should be displayed no more than maxlog times.\nexception=ex should be used to transport an exception with a log message, often used with @error. An associated backtrace bt may be attached using the tuple exception=(ex,bt).\n\nExamples\n\n@debug \"Verbose debugging information. Invisible by default\"\n@info \"An informational message\"\n@warn \"Something was odd. You should pay attention\"\n@error \"A non fatal error occurred\"\n\nx = 10\n@info \"Some variables attached to the message\" x a=42.0\n\n@debug begin\n sA = sum(A)\n \"sum(A) = $sA is an expensive operation, evaluated only when `shouldlog` returns true\"\nend\n\nfor i=1:10000\n @info \"With the default backend, you will only see (i = $i) ten times\" maxlog=10\n @debug \"Algorithm1\" i progress=i/10000\nend\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Logging/#Logging.LogLevel","page":"Logging","title":"Logging.LogLevel","text":"LogLevel(level)\n\nSeverity/verbosity of a log record.\n\nThe log level provides a key against which potential log records may be filtered, before any other work is done to construct the log record data structure itself.\n\nExamples\n\njulia> Logging.LogLevel(0) == Logging.Info\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Logging/#Logging.Debug","page":"Logging","title":"Logging.Debug","text":"Debug\n\nAlias for LogLevel(-1000).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.Info","page":"Logging","title":"Logging.Info","text":"Info\n\nAlias for LogLevel(0).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.Warn","page":"Logging","title":"Logging.Warn","text":"Warn\n\nAlias for LogLevel(1000).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.Error","page":"Logging","title":"Logging.Error","text":"Error\n\nAlias for LogLevel(2000).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.BelowMinLevel","page":"Logging","title":"Logging.BelowMinLevel","text":"BelowMinLevel\n\nAlias for LogLevel(-1_000_001).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.AboveMaxLevel","page":"Logging","title":"Logging.AboveMaxLevel","text":"AboveMaxLevel\n\nAlias for LogLevel(1_000_001).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#AbstractLogger-interface","page":"Logging","title":"Processing events with AbstractLogger","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Event processing is controlled by overriding functions associated with AbstractLogger:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Methods to implement Brief description\nLogging.handle_message Handle a log event\nLogging.shouldlog Early filtering of events\nLogging.min_enabled_level Lower bound for log level of accepted events\nOptional methods Default definition Brief description\nLogging.catch_exceptions true Catch exceptions during event evaluation","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.AbstractLogger\nLogging.handle_message\nLogging.shouldlog\nLogging.min_enabled_level\nLogging.catch_exceptions\nLogging.disable_logging","category":"page"},{"location":"stdlib/Logging/#Logging.AbstractLogger","page":"Logging","title":"Logging.AbstractLogger","text":"A logger controls how log records are filtered and dispatched. When a log record is generated, the logger is the first piece of user configurable code which gets to inspect the record and decide what to do with it.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Logging/#Logging.handle_message","page":"Logging","title":"Logging.handle_message","text":"handle_message(logger, level, message, _module, group, id, file, line; key1=val1, ...)\n\nLog a message to logger at level. The logical location at which the message was generated is given by module _module and group; the source location by file and line. id is an arbitrary unique value (typically a Symbol) to be used as a key to identify the log statement when filtering.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.shouldlog","page":"Logging","title":"Logging.shouldlog","text":"shouldlog(logger, level, _module, group, id)\n\nReturn true when logger accepts a message at level, generated for _module, group and with unique log identifier id.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.min_enabled_level","page":"Logging","title":"Logging.min_enabled_level","text":"min_enabled_level(logger)\n\nReturn the minimum enabled level for logger for early filtering. That is, the log level below or equal to which all messages are filtered.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.catch_exceptions","page":"Logging","title":"Logging.catch_exceptions","text":"catch_exceptions(logger)\n\nReturn true if the logger should catch exceptions which happen during log record construction. By default, messages are caught\n\nBy default all exceptions are caught to prevent log message generation from crashing the program. This lets users confidently toggle little-used functionality - such as debug logging - in a production system.\n\nIf you want to use logging as an audit trail you should disable this for your logger type.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.disable_logging","page":"Logging","title":"Logging.disable_logging","text":"disable_logging(level)\n\nDisable all log messages at log levels equal to or less than level. This is a global setting, intended to make debug logging extremely cheap when disabled.\n\nExamples\n\nLogging.disable_logging(Logging.Info) # Disable debug and info\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Using-Loggers","page":"Logging","title":"Using Loggers","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logger installation and inspection:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.global_logger\nLogging.with_logger\nLogging.current_logger","category":"page"},{"location":"stdlib/Logging/#Logging.global_logger","page":"Logging","title":"Logging.global_logger","text":"global_logger()\n\nReturn the global logger, used to receive messages when no specific logger exists for the current task.\n\nglobal_logger(logger)\n\nSet the global logger to logger, and return the previous global logger.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.with_logger","page":"Logging","title":"Logging.with_logger","text":"with_logger(function, logger)\n\nExecute function, directing all log messages to logger.\n\nExamples\n\nfunction test(x)\n @info \"x = $x\"\nend\n\nwith_logger(logger) do\n test(1)\n test([1,2])\nend\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.current_logger","page":"Logging","title":"Logging.current_logger","text":"current_logger()\n\nReturn the logger for the current task, or the global logger if none is attached to the task.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Loggers that are supplied with the system:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.NullLogger\nLogging.ConsoleLogger\nLogging.SimpleLogger","category":"page"},{"location":"stdlib/Logging/#Logging.NullLogger","page":"Logging","title":"Logging.NullLogger","text":"NullLogger()\n\nLogger which disables all messages and produces no output - the logger equivalent of /dev/null.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Logging/#Logging.ConsoleLogger","page":"Logging","title":"Logging.ConsoleLogger","text":"ConsoleLogger([stream,] min_level=Info; meta_formatter=default_metafmt,\n show_limited=true, right_justify=0)\n\nLogger with formatting optimized for readability in a text console, for example interactive work with the Julia REPL.\n\nLog levels less than min_level are filtered out.\n\nMessage formatting can be controlled by setting keyword arguments:\n\nmeta_formatter is a function which takes the log event metadata (level, _module, group, id, file, line) and returns a face name (used in the constructed AnnotatedString), prefix and suffix for the log message. The default is to prefix with the log level and a suffix containing the module, file and line location.\nshow_limited limits the printing of large data structures to something which can fit on the screen by setting the :limit IOContext key during formatting.\nright_justify is the integer column which log metadata is right justified at. The default is zero (metadata goes on its own line).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Logging/#Logging.SimpleLogger","page":"Logging","title":"Logging.SimpleLogger","text":"SimpleLogger([stream,] min_level=Info)\n\nSimplistic logger for logging all messages with level greater than or equal to min_level to stream. If stream is closed then messages with log level greater or equal to Warn will be logged to stderr and below to stdout.\n\n\n\n\n\n","category":"type"},{"location":"tutorials/creating-packages/#creating-packages-tutorial","page":"Creating Packages","title":"Creating Packages","text":"","category":"section"},{"location":"tutorials/creating-packages/#Generating-files-for-a-package","page":"Creating Packages","title":"Generating files for a package","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nThe PkgTemplates package offers an easy, repeatable, and customizable way to generate the files for a new package. It can also generate files needed for Documentation, CI, etc. We recommend that you use PkgTemplates for creating new packages instead of using the minimal pkg> generate functionality described below.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"To generate the bare minimum files for a new package, use pkg> generate.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"(@v1.8) pkg> generate HelloWorld","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"This creates a new project HelloWorld in a subdirectory by the same name, with the following files (visualized with the external tree command):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"shell> tree HelloWorld/\nHelloWorld/\n├── Project.toml\n└── src\n └── HelloWorld.jl\n\n2 directories, 2 files","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The Project.toml file contains the name of the package, its unique UUID, its version, the authors and potential dependencies:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"name = \"HelloWorld\"\nuuid = \"b4cd1eb8-1e24-11e8-3319-93036a3eb9f3\"\nversion = \"0.1.0\"\nauthors = [\"Some One \"]\n\n[deps]","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The content of src/HelloWorld.jl is:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module HelloWorld\n\ngreet() = print(\"Hello World!\")\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We can now activate the project by using the path to the directory where it is installed, and load the package:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"pkg> activate ./HelloWorld\n\njulia> import HelloWorld\n\njulia> HelloWorld.greet()\nHello World!","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"For the rest of the tutorial we enter inside the directory of the project, for convenience:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> cd(\"HelloWorld\")","category":"page"},{"location":"tutorials/creating-packages/#Adding-dependencies-to-the-project","page":"Creating Packages","title":"Adding dependencies to the project","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Let’s say we want to use the standard library package Random and the registered package JSON in our project. We simply add these packages (note how the prompt now shows the name of the newly generated project, since we activated it):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"(HelloWorld) pkg> add Random JSON\n Resolving package versions...\n Updating `~/HelloWorld/Project.toml`\n [682c06a0] + JSON v0.21.3\n [9a3f8284] + Random\n Updating `~/HelloWorld/Manifest.toml`\n [682c06a0] + JSON v0.21.3\n [69de0a69] + Parsers v2.4.0\n [ade2ca70] + Dates\n ...","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Both Random and JSON got added to the project’s Project.toml file, and the resulting dependencies got added to the Manifest.toml file. The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforces on its dependencies.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We can now use both Random and JSON in our project. Changing src/HelloWorld.jl to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module HelloWorld\n\nimport Random\nimport JSON\n\ngreet() = print(\"Hello World!\")\ngreet_alien() = print(\"Hello \", Random.randstring(8))\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"and reloading the package, the new greet_alien function that uses Random can be called:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> HelloWorld.greet_alien()\nHello aT157rHV","category":"page"},{"location":"tutorials/creating-packages/#Defining-a-public-API","page":"Creating Packages","title":"Defining a public API","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"If you want your package to be useful to other packages and you want folks to be able to easily update to newer version of your package when they come out, it is important to document what behavior will stay consistent across updates.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Unless you note otherwise, the public API of your package is defined as all the behavior you describe about public symbols. A public symbol is a symbol that is exported from your package with the export keyword or marked as public with the public keyword. When you change the behavior of something that was previously public so that the new version no longer conforms to the specifications provided in the old version, you should adjust your package version number according to Julia's variant on SemVer. If you would like to include a symbol in your public API without exporting it into the global namespace of folks who call using YourPackage, you should mark that symbol as public with public that_symbol. Symbols marked as public with the public keyword are just as public as those marked as public with the export keyword, but when folks call using YourPackage, they will still have to qualify access to those symbols with YourPackage.that_symbol.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Let's say we would like our greet function to be part of the public API, but not the greet_alien function. We could the write the following and release it as version 1.0.0.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module HelloWorld\n\nexport greet\n\nimport Random\nimport JSON\n\n\"Writes a friendly message.\"\ngreet() = print(\"Hello World!\")\n\n\"Greet an alien by a randomly generated name.\"\ngreet_alien() = print(\"Hello \", Random.randstring(8))\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Then, if we change greet to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"\"Writes a friendly message that is exactly three words long.\"\ngreet() = print(\"Hello Lovely World!\")","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We would release the new version as 1.1.0. This is not breaking because the new implementation conforms to the old documentation, but it does add a new feature, that the message must be three words long.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Later, we may wish to change greet_alien to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"\"Greet an alien by the name of \\\"Zork\\\".\"\ngreet_alien() = print(\"Hello Zork\")","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"And also export it by changing","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"export greet","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"export greet, greet_alien","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We should release this new version as 1.2.0 because it adds a new feature greet_alien to the public API. Even though greet_alien was documented before and the new version does not conform to the old documentation, this is not breaking because the old documentation was not attached to a symbol that was exported at the time so that documentation does not apply across released versions.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"However, if we now wish to change greet to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"\"Writes a friendly message that is exactly four words long.\"\ngreet() = print(\"Hello very lovely world\")","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"we would need to release the new version as 2.0.0. In version 1.1.0, we specified that the greeting would be three words long, and because greet was exported, that description also applies to all future versions until the next breaking release. Because this new version does not conform to the old specification, it must be tagged as a breaking change.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Please note that version numbers are free and unlimited. It is okay to use lots of them (e.g. version 6.62.8).","category":"page"},{"location":"tutorials/creating-packages/#Adding-a-build-step-to-the-package","page":"Creating Packages","title":"Adding a build step to the package","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The build step is executed the first time a package is installed or when explicitly invoked with build. A package is built by executing the file deps/build.jl.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> mkpath(\"deps\");\n\njulia> write(\"deps/build.jl\",\n \"\"\"\n println(\"I am being built...\")\n \"\"\");\n\n(HelloWorld) pkg> build\n Building HelloWorld → `deps/build.log`\n Resolving package versions...\n\njulia> print(readchomp(\"deps/build.log\"))\nI am being built...","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"If the build step fails, the output of the build step is printed to the console","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> write(\"deps/build.jl\",\n \"\"\"\n error(\"Ooops\")\n \"\"\");\n\n(HelloWorld) pkg> build\n Building HelloWorld → `~/HelloWorld/deps/build.log`\nERROR: Error building `HelloWorld`:\nERROR: LoadError: Ooops\nStacktrace:\n [1] error(s::String)\n @ Base ./error.jl:35\n [2] top-level scope\n @ ~/HelloWorld/deps/build.jl:1\n [3] include(fname::String)\n @ Base.MainInclude ./client.jl:476\n [4] top-level scope\n @ none:5\nin expression starting at /home/kc/HelloWorld/deps/build.jl:1","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"warning: Warning\nA build step should generally not create or modify any files in the package directory. If you need to store some files from the build step, use the Scratch.jl package.","category":"page"},{"location":"tutorials/creating-packages/#adding-tests-to-packages","page":"Creating Packages","title":"Adding tests to the package","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"When a package is tested the file test/runtests.jl is executed:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> mkpath(\"test\");\n\njulia> write(\"test/runtests.jl\",\n \"\"\"\n println(\"Testing...\")\n \"\"\");\n\n(HelloWorld) pkg> test\n Testing HelloWorld\n Resolving package versions...\nTesting...\n Testing HelloWorld tests passed","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Tests are run in a new Julia process, where the package itself, and any test-specific dependencies, are available, see below.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"warning: Warning\nTests should generally not create or modify any files in the package directory. If you need to store some files from the build step, use the Scratch.jl package.","category":"page"},{"location":"tutorials/creating-packages/#Test-specific-dependencies","page":"Creating Packages","title":"Test-specific dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"There are two ways of adding test-specific dependencies (dependencies that are not dependencies of the package but will still be available to load when the package is tested).","category":"page"},{"location":"tutorials/creating-packages/#target-based-test-specific-dependencies","page":"Creating Packages","title":"target based test specific dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Using this method of adding test-specific dependencies, the packages are added under an [extras] section and to a test target, e.g. to add Markdown and Test as test dependencies, add the following to the Project.toml file:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"[extras]\nMarkdown = \"d6f4376e-aef5-505a-96c1-9c027394607a\"\nTest = \"8dfed614-e22c-5e08-85e1-65c5234f0b40\"\n\n[targets]\ntest = [\"Markdown\", \"Test\"]","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Note that the only supported targets are test and build, the latter of which (not recommended) can be used for any deps/build.jl scripts.","category":"page"},{"location":"tutorials/creating-packages/#Alternative-approach:-test/Project.toml-file-test-specific-dependencies","page":"Creating Packages","title":"Alternative approach: test/Project.toml file test specific dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nThe exact interaction between Project.toml, test/Project.toml and their corresponding Manifest.tomls are not fully worked out and may be subject to change in future versions. The older method of adding test-specific dependencies, described in the previous section, will therefore be supported throughout all Julia 1.X releases.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"In Julia 1.2 and later test dependencies can be declared in test/Project.toml. When running tests, Pkg will automatically merge this and the package Projects to create the test environment.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nIf no test/Project.toml exists Pkg will use the target based test specific dependencies.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"To add a test-specific dependency, i.e. a dependency that is available only when testing, it is thus enough to add this dependency to the test/Project.toml project. This can be done from the Pkg REPL by activating this environment, and then use add as one normally does. Let's add the Test standard library as a test dependency:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"(HelloWorld) pkg> activate ./test\n[ Info: activating environment at `~/HelloWorld/test/Project.toml`.\n\n(test) pkg> add Test\n Resolving package versions...\n Updating `~/HelloWorld/test/Project.toml`\n [8dfed614] + Test\n Updating `~/HelloWorld/test/Manifest.toml`\n [...]","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We can now use Test in the test script and we can see that it gets installed when testing:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> write(\"test/runtests.jl\",\n \"\"\"\n using Test\n @test 1 == 1\n \"\"\");\n\n(test) pkg> activate .\n\n(HelloWorld) pkg> test\n Testing HelloWorld\n Resolving package versions...\n Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Project.toml`\n [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`]\n [8dfed614] + Test\n Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Manifest.toml`\n [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`]\n Testing HelloWorld tests passed```","category":"page"},{"location":"tutorials/creating-packages/#Compatibility-on-dependencies","page":"Creating Packages","title":"Compatibility on dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Every dependency should in general have a compatibility constraint on it. This is an important topic so there is a chapter in the package docs about it: Compatibility.","category":"page"},{"location":"tutorials/creating-packages/#Weak-dependencies","page":"Creating Packages","title":"Weak dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nThis is a somewhat advanced usage of Pkg which can be skipped for people new to Julia and Julia packages.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"compat: Compat\nThe described feature requires Julia 1.9+.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"A weak dependency is a dependency that will not automatically install when the package is installed but you can still control what versions of that package are allowed to be installed by setting compatibility on it. These are listed in the project file under the [weakdeps] section:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"[weakdeps]\nSomePackage = \"b3785f31-9d33-4cdf-bc73-f646780f1739\"\n\n[compat]\nSomePackage = \"1.2\"","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The current usage of this is almost solely limited to \"extensions\" which is described in the next section.","category":"page"},{"location":"tutorials/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)","page":"Creating Packages","title":"Conditional loading of code in packages (Extensions)","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nThis is a somewhat advanced usage of Pkg which can be skipped for people new to Julia and Julia packages.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"compat: Compat\nThe described feature requires Julia 1.9+.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Sometimes one wants to make two or more packages work well together, but may be reluctant (perhaps due to increased load times) to make one an unconditional dependency of the other. A package extension is a module in a file (similar to a package) that is automatically loaded when some other set of packages are loaded into the Julia session. This is very similar to functionality that the external package Requires.jl provides, but which is now available directly through Julia, and provides added benefits such as being able to precompile the extension.","category":"page"},{"location":"tutorials/creating-packages/#Code-structure","page":"Creating Packages","title":"Code structure","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"A useful application of extensions could be for a plotting package that should be able to plot objects from a wide variety of different Julia packages. Adding all those different Julia packages as dependencies of the plotting package could be expensive since they would end up getting loaded even if they were never used. Instead, the code required to plot objects for specific packages can be put into separate files (extensions) and these are loaded only when the packages that define the type(s) we want to plot are loaded.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Below is an example of how the code can be structured for a use case in which a Plotting package wants to be able to display objects defined in the external package Contour. The file and folder structure shown below is found in the Plotting package.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Project.toml:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"name = \"Plotting\"\nversion = \"0.1.0\"\nuuid = \"...\"\n\n[weakdeps]\nContour = \"d38c429a-6771-53c6-b99e-75d170b6e991\"\n\n[extensions]\n# name of extension to the left\n# extension dependencies required to load the extension to the right\n# use a list for multiple extension dependencies\nPlottingContourExt = \"Contour\"\n\n[compat]\nContour = \"0.6.2\"","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"src/Plotting.jl:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module Plotting\n\nfunction plot(x::Vector)\n # Some functionality for plotting a vector here\nend\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"ext/PlottingContourExt.jl (can also be in ext/PlottingContourExt/PlottingContourExt.jl):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module PlottingContourExt # Should be same name as the file (just like a normal package)\n\nusing Plotting, Contour\n\nfunction Plotting.plot(c::Contour.ContourCollection)\n # Some functionality for plotting a contour here\nend\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Extensions can have any arbitrary name (here PlottingContourExt), but using something similar to the format of this example that makes the extended functionality and dependency of the extension clear is likely a good idea.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"compat: Compat\nOften you will put the extension dependencies into the test target so they are loaded when running e.g. Pkg.test(). On earlier Julia versions this requires you to also put the package in the [extras] section. This is unfortunate but the project verifier on older Julia versions will complain if this is not done.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nIf you use a manifest generated by a Julia version that does not know about extensions with a Julia version that does know about them, the extensions will not load. This is because the manifest lacks some information that tells Julia when it should load these packages. So make sure you use a manifest generated at least the Julia version you are using.","category":"page"},{"location":"tutorials/creating-packages/#Behavior-of-extensions","page":"Creating Packages","title":"Behavior of extensions","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"A user that depends only on Plotting will not pay the cost of the \"extension\" inside the PlottingContourExt module. It is only when the Contour package actually gets loaded that the PlottingContourExt extension is loaded too and provides the new functionality.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"In our example, the new functionality is an additional method, which we add to an existing function from the parent package Plotting. Implementing such methods is among the most standard use cases of package extensions. Within the parent package, the function to extend can even be defined with zero methods, as follows:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"function plot end","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nIf one considers PlottingContourExt as a completely separate package, it could be argued that defining Plotting.plot(c::Contour.ContourCollection) is type piracy since PlottingContourExt owns neither the function Plotting.plot nor the type Contour.ContourCollection. However, for extensions, it is ok to assume that the extension owns the functions in its parent package.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"In other situations, one may need to define new symbols in the extension (types, structs, functions, etc.) instead of reusing those from the parent package. Such symbols are created in a separate module corresponding to the extension, namely PlottingContourExt, and thus not in Plotting itself. If extension symbols are needed in the parent package, one must call Base.get_extension to retrieve them. Here is an example showing how a custom type defined in PlottingContourExt can be accessed in Plotting:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"ext = Base.get_extension(@__MODULE__, :PlottingContourExt)\nif !isnothing(ext)\n ContourPlotType = ext.ContourPlotType\nend","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"On the other hand, accessing extension symbols from a third-party package (i.e. not the parent) is not a recommended practice at the moment.","category":"page"},{"location":"tutorials/creating-packages/#Backwards-compatibility","page":"Creating Packages","title":"Backwards compatibility","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"This section discusses various methods for using extensions on Julia versions that support them, while simultaneously providing similar functionality on older Julia versions.","category":"page"},{"location":"tutorials/creating-packages/#Requires.jl","page":"Creating Packages","title":"Requires.jl","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"This section is relevant if you are currently using Requires.jl but want to transition to using extensions (while still having Requires be used on Julia versions that do not support extensions). This is done by making the following changes (using the example above):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Add the following to the package file. This makes it so that Requires.jl loads and inserts the callback only when extensions are not supported\n# This symbol is only defined on Julia versions that support extensions\nif !isdefined(Base, :get_extension)\nusing Requires\nend\n\n@static if !isdefined(Base, :get_extension)\nfunction __init__()\n @require Contour = \"d38c429a-6771-53c6-b99e-75d170b6e991\" include(\"../ext/PlottingContourExt.jl\")\nend\nend\nor if you have other things in your __init__() function:\nif !isdefined(Base, :get_extension)\nusing Requires\nend\n\nfunction __init__()\n # Other init functionality here\n\n @static if !isdefined(Base, :get_extension)\n @require Contour = \"d38c429a-6771-53c6-b99e-75d170b6e991\" include(\"../ext/PlottingContourExt.jl\")\n end\nend\nMake the following change in the conditionally-loaded code:\nisdefined(Base, :get_extension) ? (using Contour) : (using ..Contour)\nAdd Requires to [weakdeps] in your Project.toml file, so that it is listed in both [deps] and [weakdeps]. Julia 1.9+ knows to not install it as a regular dependency, whereas earlier versions will consider it a dependency.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The package should now work with Requires.jl on Julia versions before extensions were introduced and with extensions on more recent Julia versions.","category":"page"},{"location":"tutorials/creating-packages/#Transition-from-normal-dependency-to-extension","page":"Creating Packages","title":"Transition from normal dependency to extension","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"This section is relevant if you have a normal dependency that you want to transition be an extension (while still having the dependency be a normal dependency on Julia versions that do not support extensions). This is done by making the following changes (using the example above):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Make sure that the package is both in the [deps] and [weakdeps] section. Newer Julia versions will ignore dependencies in [deps] that are also in [weakdeps].\nAdd the following to your main package file (typically at the bottom):\nif !isdefined(Base, :get_extension)\n include(\"../ext/PlottingContourExt.jl\")\nend","category":"page"},{"location":"tutorials/creating-packages/#Using-an-extension-while-supporting-older-Julia-versions","page":"Creating Packages","title":"Using an extension while supporting older Julia versions","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"In the case where one wants to use an extension (without worrying about the feature of the extension being available on older Julia versions) while still supporting older Julia versions the packages under [weakdeps] should be duplicated into [extras]. This is an unfortunate duplication, but without doing this the project verifier under older Julia versions will throw an error if it finds packages under [compat] that is not listed in [extras].","category":"page"},{"location":"tutorials/creating-packages/#Package-naming-rules","page":"Creating Packages","title":"Package naming rules","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Package names should be sensible to most Julia users, even to those who are not domain experts. The following rules apply to the General registry but may be useful for other package registries as well.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Since the General registry belongs to the entire community, people may have opinions about your package name when you publish it, especially if it's ambiguous or can be confused with something other than what it is. Usually, you will then get suggestions for a new name that may fit your package better.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Avoid jargon. In particular, avoid acronyms unless there is minimal possibility of confusion.\nIt's ok to say USA if you're talking about the USA.\nIt's not ok to say PMA, even if you're talking about positive mental attitude.\nAvoid using Julia in your package name or prefixing it with Ju.\nIt is usually clear from context and to your users that the package is a Julia package.\nPackage names already have a .jl extension, which communicates to users that Package.jl is a Julia package.\nHaving Julia in the name can imply that the package is connected to, or endorsed by, contributors to the Julia language itself.\nPackages that provide most of their functionality in association with a new type should have pluralized names.\nDataFrames provides the DataFrame type.\nBloomFilters provides the BloomFilter type.\nIn contrast, JuliaParser provides no new type, but instead new functionality in the JuliaParser.parse() function.\nErr on the side of clarity, even if clarity seems long-winded to you.\nRandomMatrices is a less ambiguous name than RndMat or RMT, even though the latter are shorter.\nA less systematic name may suit a package that implements one of several possible approaches to its domain.\nJulia does not have a single comprehensive plotting package. Instead, Gadfly, PyPlot, Winston and other packages each implement a unique approach based on a particular design philosophy.\nIn contrast, SortingAlgorithms provides a consistent interface to use many well-established sorting algorithms.\nPackages that wrap external libraries or programs can be named after those libraries or programs.\nCPLEX.jl wraps the CPLEX library, which can be identified easily in a web search.\nMATLAB.jl provides an interface to call the MATLAB engine from within Julia.\nAvoid naming a package closely to an existing package\nWebsocket is too close to WebSockets and can be confusing to users. Rather use a new name such as SimpleWebsockets.\nAvoid using a distinctive name that is already in use in a well known, unrelated project.\nDon't use the names Tkinter.jl, TkinterGUI.jl, etc. for a package that is unrelated to the popular tkinter python package, even if it provides bindings to Tcl/Tk. A package name of Tkinter.jl would only be appropriate if the package used Python's library to accomplish its work or was spearheaded by the same community of developers.\nIt's okay to name a package HTTP.jl even though it is unrelated to the popular rust crate http because in most usages the name \"http\" refers to the hypertext transfer protocol, not to the http rust crate.\nIt's okay to name a package OpenSSL.jl if it provides an interface to the OpenSSL library, even without explicit affiliation with the creators of the OpenSSL (provided there's no copyright or trademark infringement etc.)","category":"page"},{"location":"tutorials/creating-packages/#Registering-packages","page":"Creating Packages","title":"Registering packages","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Once a package is ready it can be registered with the General Registry (see also the FAQ). Currently, packages are submitted via Registrator. In addition to Registrator, TagBot helps manage the process of tagging releases.","category":"page"},{"location":"tutorials/creating-packages/#Best-Practices","page":"Creating Packages","title":"Best Practices","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Packages should avoid mutating their own state (writing to files within their package directory). Packages should, in general, not assume that they are located in a writable location (e.g. if installed as part of a system-wide depot) or even a stable one (e.g. if they are bundled into a system image by PackageCompiler.jl). To support the various use cases in the Julia package ecosystem, the Pkg developers have created a number of auxiliary packages and techniques to help package authors create self-contained, immutable, and relocatable packages:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Artifacts can be used to bundle chunks of data alongside your package, or even allow them to be downloaded on-demand. Prefer artifacts over attempting to open a file via a path such as joinpath(@__DIR__, \"data\", \"my_dataset.csv\") as this is non-relocatable. Once your package has been precompiled, the result of @__DIR__ will have been baked into your precompiled package data, and if you attempt to distribute this package, it will attempt to load files at the wrong location. Artifacts can be bundled and accessed easily using the artifact\"name\" string macro.\nScratch.jl provides the notion of \"scratch spaces\", mutable containers of data for packages. Scratch spaces are designed for data caches that are completely managed by a package and should be removed when the package itself is uninstalled. For important user-generated data, packages should continue to write out to a user-specified path that is not managed by Julia or Pkg.\nPreferences.jl allows packages to read and write preferences to the top-level Project.toml. These preferences can be read at runtime or compile-time, to enable or disable different aspects of package behavior. Packages previously would write out files to their own package directories to record options set by the user or environment, but this is highly discouraged now that Preferences is available.","category":"page"},{"location":"devdocs/valgrind/#Using-Valgrind-with-Julia","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Valgrind is a tool for memory debugging, memory leak detection, and profiling. This section describes things to keep in mind when using Valgrind to debug memory issues with Julia.","category":"page"},{"location":"devdocs/valgrind/#General-considerations","page":"Using Valgrind with Julia","title":"General considerations","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"By default, Valgrind assumes that there is no self modifying code in the programs it runs. This assumption works fine in most instances but fails miserably for a just-in-time compiler like julia. For this reason it is crucial to pass --smc-check=all-non-file to valgrind, else code may crash or behave unexpectedly (often in subtle ways).","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"In some cases, to better detect memory errors using Valgrind, it can help to compile julia with memory pools disabled. The compile-time flag MEMDEBUG disables memory pools in Julia, and MEMDEBUG2 disables memory pools in FemtoLisp. To build julia with both flags, add the following line to Make.user:","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"CFLAGS = -DMEMDEBUG -DMEMDEBUG2","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Another thing to note: if your program uses multiple worker processes, it is likely that you want all such worker processes to run under Valgrind, not just the parent process. To do this, pass --trace-children=yes to valgrind.","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Yet another thing to note: if using valgrind errors with Unable to find compatible target in system image, try rebuilding the sysimage with target generic or julia with JULIA_CPU_TARGET=generic.","category":"page"},{"location":"devdocs/valgrind/#Suppressions","page":"Using Valgrind with Julia","title":"Suppressions","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Valgrind will typically display spurious warnings as it runs. To reduce the number of such warnings, it helps to provide a suppressions file to Valgrind. A sample suppressions file is included in the Julia source distribution at contrib/valgrind-julia.supp.","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"The suppressions file can be used from the julia/ source directory as follows:","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"$ valgrind --smc-check=all-non-file --suppressions=contrib/valgrind-julia.supp ./julia progname.jl","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Any memory errors that are displayed should either be reported as bugs or contributed as additional suppressions. Note that some versions of Valgrind are shipped with insufficient default suppressions, so that may be one thing to consider before submitting any bugs.","category":"page"},{"location":"devdocs/valgrind/#Running-the-Julia-test-suite-under-Valgrind","page":"Using Valgrind with Julia","title":"Running the Julia test suite under Valgrind","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"It is possible to run the entire Julia test suite under Valgrind, but it does take quite some time (typically several hours). To do so, run the following command from the julia/test/ directory:","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"valgrind --smc-check=all-non-file --trace-children=yes --suppressions=$PWD/../contrib/valgrind-julia.supp ../julia runtests.jl all","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"If you would like to see a report of \"definite\" memory leaks, pass the flags --leak-check=full --show-leak-kinds=definite to valgrind as well.","category":"page"},{"location":"devdocs/valgrind/#Additional-spurious-warnings","page":"Using Valgrind with Julia","title":"Additional spurious warnings","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"This section covers Valgrind warnings that cannot be added to the suppressions file yet are nonetheless safe to ignore.","category":"page"},{"location":"devdocs/valgrind/#Unhandled-rr-system-calls","page":"Using Valgrind with Julia","title":"Unhandled rr system calls","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Valgrind will emit a warning if it encounters any of the system calls that are specific to rr, the Record and Replay Framework. In particular, a warning about an unhandled 1008 syscall will be shown when julia tries to detect whether it is running under rr:","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"--xxxxxx-- WARNING: unhandled amd64-linux syscall: 1008\n--xxxxxx-- You may be able to write your own handler.\n--xxxxxx-- Read the file README_MISSING_SYSCALL_OR_IOCTL.\n--xxxxxx-- Nevertheless we consider this a bug. Please report\n--xxxxxx-- it at http://valgrind.org/support/bug_reports.html.","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"This issue has been reported to the Valgrind developers as they have requested.","category":"page"},{"location":"devdocs/valgrind/#Caveats","page":"Using Valgrind with Julia","title":"Caveats","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Valgrind currently does not support multiple rounding modes, so code that adjusts the rounding mode will behave differently when run under Valgrind.","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"In general, if after setting --smc-check=all-non-file you find that your program behaves differently when run under Valgrind, it may help to pass --tool=none to valgrind as you investigate further. This will enable the minimal Valgrind machinery but will also run much faster than when the full memory checker is enabled.","category":"page"},{"location":"manual/metaprogramming/#Metaprogramming","page":"Metaprogramming","title":"Metaprogramming","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The strongest legacy of Lisp in the Julia language is its metaprogramming support. Like Lisp, Julia represents its own code as a data structure of the language itself. Since code is represented by objects that can be created and manipulated from within the language, it is possible for a program to transform and generate its own code. This allows sophisticated code generation without extra build steps, and also allows true Lisp-style macros operating at the level of abstract syntax trees. In contrast, preprocessor \"macro\" systems, like that of C and C++, perform textual manipulation and substitution before any actual parsing or interpretation occurs. Because all data types and code in Julia are represented by Julia data structures, powerful reflection capabilities are available to explore the internals of a program and its types just like any other data.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"warning: Warning\nMetaprogramming is a powerful tool, but it introduces complexity that can make code more difficult to understand. For example, it can be surprisingly hard to get scope rules correct. Metaprogramming should typically be used only when other approaches such as higher order functions and closures cannot be applied.eval and defining new macros should be typically used as a last resort. It is almost never a good idea to use Meta.parse or convert an arbitrary string into Julia code. For manipulating Julia code, use the Expr data structure directly to avoid the complexity of how Julia syntax is parsed.The best uses of metaprogramming often implement most of their functionality in runtime helper functions, striving to minimize the amount of code they generate.","category":"page"},{"location":"manual/metaprogramming/#Program-representation","page":"Metaprogramming","title":"Program representation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Every Julia program starts life as a string:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> prog = \"1 + 1\"\n\"1 + 1\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"What happens next?","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The next step is to parse each string into an object called an expression, represented by the Julia type Expr:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1 = Meta.parse(prog)\n:(1 + 1)\n\njulia> typeof(ex1)\nExpr","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Expr objects contain two parts:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"a Symbol identifying the kind of expression. A symbol is an interned string identifier (more discussion below).","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1.head\n:call","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"the expression arguments, which may be symbols, other expressions, or literal values:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1.args\n3-element Vector{Any}:\n :+\n 1\n 1","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Expressions may also be constructed directly in prefix notation:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex2 = Expr(:call, :+, 1, 1)\n:(1 + 1)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The two expressions constructed above – by parsing and by direct construction – are equivalent:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1 == ex2\ntrue","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The key point here is that Julia code is internally represented as a data structure that is accessible from the language itself.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The dump function provides indented and annotated display of Expr objects:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> dump(ex2)\nExpr\n head: Symbol call\n args: Array{Any}((3,))\n 1: Symbol +\n 2: Int64 1\n 3: Int64 1","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Expr objects may also be nested:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex3 = Meta.parse(\"(4 + 4) / 2\")\n:((4 + 4) / 2)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Another way to view expressions is with Meta.show_sexpr, which displays the S-expression form of a given Expr, which may look very familiar to users of Lisp. Here's an example illustrating the display on a nested Expr:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> Meta.show_sexpr(ex3)\n(:call, :/, (:call, :+, 4, 4), 2)","category":"page"},{"location":"manual/metaprogramming/#Symbols","page":"Metaprogramming","title":"Symbols","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The : character has two syntactic purposes in Julia. The first form creates a Symbol, an interned string used as one building-block of expressions, from valid identifiers:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> s = :foo\n:foo\n\njulia> typeof(s)\nSymbol","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The Symbol constructor takes any number of arguments and creates a new symbol by concatenating their string representations together:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> :foo === Symbol(\"foo\")\ntrue\n\njulia> Symbol(\"1foo\") # `:1foo` would not work, as `1foo` is not a valid identifier\nSymbol(\"1foo\")\n\njulia> Symbol(\"func\",10)\n:func10\n\njulia> Symbol(:var,'_',\"sym\")\n:var_sym","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In the context of an expression, symbols are used to indicate access to variables; when an expression is evaluated, a symbol is replaced with the value bound to that symbol in the appropriate scope.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Sometimes extra parentheses around the argument to : are needed to avoid ambiguity in parsing:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> :(:)\n:(:)\n\njulia> :(::)\n:(::)","category":"page"},{"location":"manual/metaprogramming/#Expressions-and-evaluation","page":"Metaprogramming","title":"Expressions and evaluation","text":"","category":"section"},{"location":"manual/metaprogramming/#Quoting","page":"Metaprogramming","title":"Quoting","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The second syntactic purpose of the : character is to create expression objects without using the explicit Expr constructor. This is referred to as quoting. The : character, followed by paired parentheses around a single statement of Julia code, produces an Expr object based on the enclosed code. Here is an example of the short form used to quote an arithmetic expression:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = :(a+b*c+1)\n:(a + b * c + 1)\n\njulia> typeof(ex)\nExpr","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"(to view the structure of this expression, try ex.head and ex.args, or use dump as above or Meta.@dump)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note that equivalent expressions may be constructed using Meta.parse or the direct Expr form:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> :(a + b*c + 1) ==\n Meta.parse(\"a + b*c + 1\") ==\n Expr(:call, :+, :a, Expr(:call, :*, :b, :c), 1)\ntrue","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Expressions provided by the parser generally only have symbols, other expressions, and literal values as their args, whereas expressions constructed by Julia code can have arbitrary run-time values without literal forms as args. In this specific example, + and a are symbols, *(b,c) is a subexpression, and 1 is a literal 64-bit signed integer.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"There is a second syntactic form of quoting for multiple expressions: blocks of code enclosed in quote ... end.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = quote\n x = 1\n y = 2\n x + y\n end\nquote\n #= none:2 =#\n x = 1\n #= none:3 =#\n y = 2\n #= none:4 =#\n x + y\nend\n\njulia> typeof(ex)\nExpr","category":"page"},{"location":"manual/metaprogramming/#man-expression-interpolation","page":"Metaprogramming","title":"Interpolation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Direct construction of Expr objects with value arguments is powerful, but Expr constructors can be tedious compared to \"normal\" Julia syntax. As an alternative, Julia allows interpolation of literals or expressions into quoted expressions. Interpolation is indicated by a prefix $.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In this example, the value of variable a is interpolated:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> a = 1;\n\njulia> ex = :($a + b)\n:(1 + b)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Interpolating into an unquoted expression is not supported and will cause a compile-time error:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> $a + b\nERROR: syntax: \"$\" expression outside quote","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In this example, the tuple (1,2,3) is interpolated as an expression into a conditional test:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = :(a in $:((1,2,3)) )\n:(a in (1, 2, 3))","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The use of $ for expression interpolation is intentionally reminiscent of string interpolation and command interpolation. Expression interpolation allows convenient, readable programmatic construction of complex Julia expressions.","category":"page"},{"location":"manual/metaprogramming/#Splatting-interpolation","page":"Metaprogramming","title":"Splatting interpolation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Notice that the $ interpolation syntax allows inserting only a single expression into an enclosing expression. Occasionally, you have an array of expressions and need them all to become arguments of the surrounding expression. This can be done with the syntax $(xs...). For example, the following code generates a function call where the number of arguments is determined programmatically:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> args = [:x, :y, :z];\n\njulia> :(f(1, $(args...)))\n:(f(1, x, y, z))","category":"page"},{"location":"manual/metaprogramming/#Nested-quote","page":"Metaprogramming","title":"Nested quote","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Naturally, it is possible for quote expressions to contain other quote expressions. Understanding how interpolation works in these cases can be a bit tricky. Consider this example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> x = :(1 + 2);\n\njulia> e = quote quote $x end end\nquote\n #= none:1 =#\n $(Expr(:quote, quote\n #= none:1 =#\n $(Expr(:$, :x))\nend))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Notice that the result contains $x, which means that x has not been evaluated yet. In other words, the $ expression \"belongs to\" the inner quote expression, and so its argument is only evaluated when the inner quote expression is:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> eval(e)\nquote\n #= none:1 =#\n 1 + 2\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"However, the outer quote expression is able to interpolate values inside the $ in the inner quote. This is done with multiple $s:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> e = quote quote $$x end end\nquote\n #= none:1 =#\n $(Expr(:quote, quote\n #= none:1 =#\n $(Expr(:$, :(1 + 2)))\nend))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Notice that (1 + 2) now appears in the result instead of the symbol x. Evaluating this expression yields an interpolated 3:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> eval(e)\nquote\n #= none:1 =#\n 3\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The intuition behind this behavior is that x is evaluated once for each $: one $ works similarly to eval(:x), giving x's value, while two $s do the equivalent of eval(eval(:x)).","category":"page"},{"location":"manual/metaprogramming/#man-quote-node","page":"Metaprogramming","title":"QuoteNode","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The usual representation of a quote form in an AST is an Expr with head :quote:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> dump(Meta.parse(\":(1+2)\"))\nExpr\n head: Symbol quote\n args: Array{Any}((1,))\n 1: Expr\n head: Symbol call\n args: Array{Any}((3,))\n 1: Symbol +\n 2: Int64 1\n 3: Int64 2","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"As we have seen, such expressions support interpolation with $. However, in some situations it is necessary to quote code without performing interpolation. This kind of quoting does not yet have syntax, but is represented internally as an object of type QuoteNode:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> eval(Meta.quot(Expr(:$, :(1+2))))\n3\n\njulia> eval(QuoteNode(Expr(:$, :(1+2))))\n:($(Expr(:$, :(1 + 2))))","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The parser yields QuoteNodes for simple quoted items like symbols:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> dump(Meta.parse(\":x\"))\nQuoteNode\n value: Symbol x","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"QuoteNode can also be used for certain advanced metaprogramming tasks.","category":"page"},{"location":"manual/metaprogramming/#Evaluating-expressions","page":"Metaprogramming","title":"Evaluating expressions","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Given an expression object, one can cause Julia to evaluate (execute) it at global scope using eval:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1 = :(1 + 2)\n:(1 + 2)\n\njulia> eval(ex1)\n3\n\njulia> ex = :(a + b)\n:(a + b)\n\njulia> eval(ex)\nERROR: UndefVarError: `b` not defined in `Main`\n[...]\n\njulia> a = 1; b = 2;\n\njulia> eval(ex)\n3","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Every module has its own eval function that evaluates expressions in its global scope. Expressions passed to eval are not limited to returning values – they can also have side-effects that alter the state of the enclosing module's environment:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = :(x = 1)\n:(x = 1)\n\njulia> x\nERROR: UndefVarError: `x` not defined in `Main`\n\njulia> eval(ex)\n1\n\njulia> x\n1","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here, the evaluation of an expression object causes a value to be assigned to the global variable x.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Since expressions are just Expr objects which can be constructed programmatically and then evaluated, it is possible to dynamically generate arbitrary code which can then be run using eval. Here is a simple example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> a = 1;\n\njulia> ex = Expr(:call, :+, a, :b)\n:(1 + b)\n\njulia> a = 0; b = 2;\n\njulia> eval(ex)\n3","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The value of a is used to construct the expression ex which applies the + function to the value 1 and the variable b. Note the important distinction between the way a and b are used:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The value of the variable a at expression construction time is used as an immediate value in the expression. Thus, the value of a when the expression is evaluated no longer matters: the value in the expression is already 1, independent of whatever the value of a might be.\nOn the other hand, the symbol :b is used in the expression construction, so the value of the variable b at that time is irrelevant – :b is just a symbol and the variable b need not even be defined. At expression evaluation time, however, the value of the symbol :b is resolved by looking up the value of the variable b.","category":"page"},{"location":"manual/metaprogramming/#Functions-on-Expressions","page":"Metaprogramming","title":"Functions on Expressions","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"As hinted above, one extremely useful feature of Julia is the capability to generate and manipulate Julia code within Julia itself. We have already seen one example of a function returning Expr objects: the Meta.parse function, which takes a string of Julia code and returns the corresponding Expr. A function can also take one or more Expr objects as arguments, and return another Expr. Here is a simple, motivating example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function math_expr(op, op1, op2)\n expr = Expr(:call, op, op1, op2)\n return expr\n end\nmath_expr (generic function with 1 method)\n\njulia> ex = math_expr(:+, 1, Expr(:call, :*, 4, 5))\n:(1 + 4 * 5)\n\njulia> eval(ex)\n21","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"As another example, here is a function that doubles any numeric argument, but leaves expressions alone:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function make_expr2(op, opr1, opr2)\n opr1f, opr2f = map(x -> isa(x, Number) ? 2*x : x, (opr1, opr2))\n retexpr = Expr(:call, op, opr1f, opr2f)\n return retexpr\n end\nmake_expr2 (generic function with 1 method)\n\njulia> make_expr2(:+, 1, 2)\n:(2 + 4)\n\njulia> ex = make_expr2(:+, 1, Expr(:call, :*, 5, 8))\n:(2 + 5 * 8)\n\njulia> eval(ex)\n42","category":"page"},{"location":"manual/metaprogramming/#man-macros","page":"Metaprogramming","title":"Macros","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros provide a mechanism to include generated code in the final body of a program. A macro maps a tuple of arguments to a returned expression, and the resulting expression is compiled directly rather than requiring a runtime eval call. Macro arguments may include expressions, literal values, and symbols.","category":"page"},{"location":"manual/metaprogramming/#Basics","page":"Metaprogramming","title":"Basics","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here is an extraordinarily simple macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro sayhello()\n return :( println(\"Hello, world!\") )\n end\n@sayhello (macro with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros have a dedicated character in Julia's syntax: the @ (at-sign), followed by the unique name declared in a macro NAME ... end block. In this example, the compiler will replace all instances of @sayhello with:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":":( println(\"Hello, world!\") )","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"When @sayhello is entered in the REPL, the expression executes immediately, thus we only see the evaluation result:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @sayhello()\nHello, world!","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Now, consider a slightly more complex macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro sayhello(name)\n return :( println(\"Hello, \", $name) )\n end\n@sayhello (macro with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This macro takes one argument: name. When @sayhello is encountered, the quoted expression is expanded to interpolate the value of the argument into the final expression:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @sayhello(\"human\")\nHello, human","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We can view the quoted return expression using the function macroexpand (important note: this is an extremely useful tool for debugging macros):","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = macroexpand(Main, :(@sayhello(\"human\")) )\n:(Main.println(\"Hello, \", \"human\"))\n\njulia> typeof(ex)\nExpr","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We can see that the \"human\" literal has been interpolated into the expression.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"There also exists a macro @macroexpand that is perhaps a bit more convenient than the macroexpand function:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @macroexpand @sayhello \"human\"\n:(println(\"Hello, \", \"human\"))","category":"page"},{"location":"manual/metaprogramming/#Hold-up:-why-macros?","page":"Metaprogramming","title":"Hold up: why macros?","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We have already seen a function f(::Expr...) -> Expr in a previous section. In fact, macroexpand is also such a function. So, why do macros exist?","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros are necessary because they execute when code is parsed, therefore, macros allow the programmer to generate and include fragments of customized code before the full program is run. To illustrate the difference, consider the following example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro twostep(arg)\n println(\"I execute at parse time. The argument is: \", arg)\n return :(println(\"I execute at runtime. The argument is: \", $arg))\n end\n@twostep (macro with 1 method)\n\njulia> ex = macroexpand(Main, :(@twostep :(1, 2, 3)) );\nI execute at parse time. The argument is: :((1, 2, 3))","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The first call to println is executed when macroexpand is called. The resulting expression contains only the second println:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> typeof(ex)\nExpr\n\njulia> ex\n:(println(\"I execute at runtime. The argument is: \", $(Expr(:copyast, :($(QuoteNode(:((1, 2, 3)))))))))\n\njulia> eval(ex)\nI execute at runtime. The argument is: (1, 2, 3)","category":"page"},{"location":"manual/metaprogramming/#Macro-invocation","page":"Metaprogramming","title":"Macro invocation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros are invoked with the following general syntax:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"@name expr1 expr2 ...\n@name(expr1, expr2, ...)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note the distinguishing @ before the macro name and the lack of commas between the argument expressions in the first form, and the lack of whitespace after @name in the second form. The two styles should not be mixed. For example, the following syntax is different from the examples above; it passes the tuple (expr1, expr2, ...) as one argument to the macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"@name (expr1, expr2, ...)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"An alternative way to invoke a macro over an array literal (or comprehension) is to juxtapose both without using parentheses. In this case, the array will be the only expression fed to the macro. The following syntax is equivalent (and different from @name [a b] * v):","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"@name[a b] * v\n@name([a b]) * v","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"It is important to emphasize that macros receive their arguments as expressions, literals, or symbols. One way to explore macro arguments is to call the show function within the macro body:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro showarg(x)\n show(x)\n # ... remainder of macro, returning an expression\n end\n@showarg (macro with 1 method)\n\njulia> @showarg(a)\n:a\n\njulia> @showarg(1+1)\n:(1 + 1)\n\njulia> @showarg(println(\"Yo!\"))\n:(println(\"Yo!\"))\n\njulia> @showarg(1) # Numeric literal\n1\n\njulia> @showarg(\"Yo!\") # String literal\n\"Yo!\"\n\njulia> @showarg(\"Yo! $(\"hello\")\") # String with interpolation is an Expr rather than a String\n:(\"Yo! $(\"hello\")\")","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In addition to the given argument list, every macro is passed extra arguments named __source__ and __module__.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The argument __source__ provides information (in the form of a LineNumberNode object) about the parser location of the @ sign from the macro invocation. This allows macros to include better error diagnostic information, and is commonly used by logging, string-parser macros, and docs, for example, as well as to implement the @__LINE__, @__FILE__, and @__DIR__ macros.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The location information can be accessed by referencing __source__.line and __source__.file:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro __LOCATION__(); return QuoteNode(__source__); end\n@__LOCATION__ (macro with 1 method)\n\njulia> dump(\n @__LOCATION__(\n ))\nLineNumberNode\n line: Int64 2\n file: Symbol none","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The argument __module__ provides information (in the form of a Module object) about the expansion context of the macro invocation. This allows macros to look up contextual information, such as existing bindings, or to insert the value as an extra argument to a runtime function call doing self-reflection in the current module.","category":"page"},{"location":"manual/metaprogramming/#Building-an-advanced-macro","page":"Metaprogramming","title":"Building an advanced macro","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here is a simplified definition of Julia's @assert macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro assert(ex)\n return :( $ex ? nothing : throw(AssertionError($(string(ex)))) )\n end\n@assert (macro with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This macro can be used like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @assert 1 == 1.0\n\njulia> @assert 1 == 0\nERROR: AssertionError: 1 == 0","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In place of the written syntax, the macro call is expanded at parse time to its returned result. This is equivalent to writing:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"1 == 1.0 ? nothing : throw(AssertionError(\"1 == 1.0\"))\n1 == 0 ? nothing : throw(AssertionError(\"1 == 0\"))","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"That is, in the first call, the expression :(1 == 1.0) is spliced into the test condition slot, while the value of string(:(1 == 1.0)) is spliced into the assertion message slot. The entire expression, thus constructed, is placed into the syntax tree where the @assert macro call occurs. Then at execution time, if the test expression evaluates to true, then nothing is returned, whereas if the test is false, an error is raised indicating the asserted expression that was false. Notice that it would not be possible to write this as a function, since only the value of the condition is available and it would be impossible to display the expression that computed it in the error message.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The actual definition of @assert in Julia Base is more complicated. It allows the user to optionally specify their own error message, instead of just printing the failed expression. Just like in functions with a variable number of arguments (Varargs Functions), this is specified with an ellipses following the last argument:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro assert(ex, msgs...)\n msg_body = isempty(msgs) ? ex : msgs[1]\n msg = string(msg_body)\n return :($ex ? nothing : throw(AssertionError($msg)))\n end\n@assert (macro with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Now @assert has two modes of operation, depending upon the number of arguments it receives! If there's only one argument, the tuple of expressions captured by msgs will be empty and it will behave the same as the simpler definition above. But now if the user specifies a second argument, it is printed in the message body instead of the failing expression. You can inspect the result of a macro expansion with the aptly named @macroexpand macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @macroexpand @assert a == b\n:(if Main.a == Main.b\n Main.nothing\n else\n Main.throw(Main.AssertionError(\"a == b\"))\n end)\n\njulia> @macroexpand @assert a==b \"a should equal b!\"\n:(if Main.a == Main.b\n Main.nothing\n else\n Main.throw(Main.AssertionError(\"a should equal b!\"))\n end)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"There is yet another case that the actual @assert macro handles: what if, in addition to printing \"a should equal b,\" we wanted to print their values? One might naively try to use string interpolation in the custom message, e.g., @assert a==b \"a ($a) should equal b ($b)!\", but this won't work as expected with the above macro. Can you see why? Recall from string interpolation that an interpolated string is rewritten to a call to string. Compare:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> typeof(:(\"a should equal b\"))\nString\n\njulia> typeof(:(\"a ($a) should equal b ($b)!\"))\nExpr\n\njulia> dump(:(\"a ($a) should equal b ($b)!\"))\nExpr\n head: Symbol string\n args: Array{Any}((5,))\n 1: String \"a (\"\n 2: Symbol a\n 3: String \") should equal b (\"\n 4: Symbol b\n 5: String \")!\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"So now instead of getting a plain string in msg_body, the macro is receiving a full expression that will need to be evaluated in order to display as expected. This can be spliced directly into the returned expression as an argument to the string call; see error.jl for the complete implementation.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The @assert macro makes great use of splicing into quoted expressions to simplify the manipulation of expressions inside the macro body.","category":"page"},{"location":"manual/metaprogramming/#Hygiene","page":"Metaprogramming","title":"Hygiene","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"An issue that arises in more complex macros is that of hygiene. In short, macros must ensure that the variables they introduce in their returned expressions do not accidentally clash with existing variables in the surrounding code they expand into. Conversely, the expressions that are passed into a macro as arguments are often expected to evaluate in the context of the surrounding code, interacting with and modifying the existing variables. Another concern arises from the fact that a macro may be called in a different module from where it was defined. In this case we need to ensure that all global variables are resolved to the correct module. Julia already has a major advantage over languages with textual macro expansion (like C) in that it only needs to consider the returned expression. All the other variables (such as msg in @assert above) follow the normal scoping block behavior.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"To demonstrate these issues, let us consider writing a @time macro that takes an expression as its argument, records the time, evaluates the expression, records the time again, prints the difference between the before and after times, and then has the value of the expression as its final value. The macro might look like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro time(ex)\n return quote\n local t0 = time_ns()\n local val = $ex\n local t1 = time_ns()\n println(\"elapsed time: \", (t1-t0)/1e9, \" seconds\")\n val\n end\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here, we want t0, t1, and val to be private temporary variables, and we want time_ns to refer to the time_ns function in Julia Base, not to any time_ns variable the user might have (the same applies to println). Imagine the problems that could occur if the user expression ex also contained assignments to a variable called t0, or defined its own time_ns variable. We might get errors, or mysteriously incorrect behavior.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Julia's macro expander solves these problems in the following way. First, variables within a macro result are classified as either local or global. A variable is considered local if it is assigned to (and not declared global), declared local, or used as a function argument name. Otherwise, it is considered global. Local variables are then renamed to be unique (using the gensym function, which generates new symbols), and global variables are resolved within the macro definition environment. Therefore both of the above concerns are handled; the macro's locals will not conflict with any user variables, and time_ns and println will refer to the Julia Base definitions.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"One problem remains however. Consider the following use of this macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"module MyModule\nimport Base.@time\n\ntime_ns() = ... # compute something\n\n@time time_ns()\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here the user expression ex is a call to time_ns, but not the same time_ns function that the macro uses. It clearly refers to MyModule.time_ns. Therefore we must arrange for the code in ex to be resolved in the macro call environment. This is done by \"escaping\" the expression with esc:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro time(ex)\n ...\n local val = $(esc(ex))\n ...\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"An expression wrapped in this manner is left alone by the macro expander and simply pasted into the output verbatim. Therefore it will be resolved in the macro call environment.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This escaping mechanism can be used to \"violate\" hygiene when necessary, in order to introduce or manipulate user variables. For example, the following macro sets x to zero in the call environment:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro zerox()\n return esc(:(x = 0))\n end\n@zerox (macro with 1 method)\n\njulia> function foo()\n x = 1\n @zerox\n return x # is zero\n end\nfoo (generic function with 1 method)\n\njulia> foo()\n0","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This kind of manipulation of variables should be used judiciously, but is occasionally quite handy.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Getting the hygiene rules correct can be a formidable challenge. Before using a macro, you might want to consider whether a function closure would be sufficient. Another useful strategy is to defer as much work as possible to runtime. For example, many macros simply wrap their arguments in a QuoteNode or other similar Expr. Some examples of this include @task body which simply returns schedule(Task(() -> $body)), and @eval expr, which simply returns eval(QuoteNode(expr)).","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"To demonstrate, we might rewrite the @time example above as:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro time(expr)\n return :(timeit(() -> $(esc(expr))))\nend\nfunction timeit(f)\n t0 = time_ns()\n val = f()\n t1 = time_ns()\n println(\"elapsed time: \", (t1-t0)/1e9, \" seconds\")\n return val\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"However, we don't do this for a good reason: wrapping the expr in a new scope block (the anonymous function) also slightly changes the meaning of the expression (the scope of any variables in it), while we want @time to be usable with minimum impact on the wrapped code.","category":"page"},{"location":"manual/metaprogramming/#Macros-and-dispatch","page":"Metaprogramming","title":"Macros and dispatch","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros, just like Julia functions, are generic. This means they can also have multiple method definitions, thanks to multiple dispatch:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro m end\n@m (macro with 0 methods)\n\njulia> macro m(args...)\n println(\"$(length(args)) arguments\")\n end\n@m (macro with 1 method)\n\njulia> macro m(x,y)\n println(\"Two arguments\")\n end\n@m (macro with 2 methods)\n\njulia> @m \"asd\"\n1 arguments\n\njulia> @m 1 2\nTwo arguments","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"However one should keep in mind, that macro dispatch is based on the types of AST that are handed to the macro, not the types that the AST evaluates to at runtime:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro m(::Int)\n println(\"An Integer\")\n end\n@m (macro with 3 methods)\n\njulia> @m 2\nAn Integer\n\njulia> x = 2\n2\n\njulia> @m x\n1 arguments","category":"page"},{"location":"manual/metaprogramming/#Code-Generation","page":"Metaprogramming","title":"Code Generation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"When a significant amount of repetitive boilerplate code is required, it is common to generate it programmatically to avoid redundancy. In most languages, this requires an extra build step, and a separate program to generate the repetitive code. In Julia, expression interpolation and eval allow such code generation to take place in the normal course of program execution. For example, consider the following custom type","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"struct MyNumber\n x::Float64\nend\n# output\n","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for which we want to add a number of methods to. We can do this programmatically in the following loop:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for op = (:sin, :cos, :tan, :log, :exp)\n eval(quote\n Base.$op(a::MyNumber) = MyNumber($op(a.x))\n end)\nend\n# output\n","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"and we can now use those functions with our custom type:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> x = MyNumber(π)\nMyNumber(3.141592653589793)\n\njulia> sin(x)\nMyNumber(1.2246467991473532e-16)\n\njulia> cos(x)\nMyNumber(-1.0)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In this manner, Julia acts as its own preprocessor, and allows code generation from inside the language. The above code could be written slightly more tersely using the : prefix quoting form:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for op = (:sin, :cos, :tan, :log, :exp)\n eval(:(Base.$op(a::MyNumber) = MyNumber($op(a.x))))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This sort of in-language code generation, however, using the eval(quote(...)) pattern, is common enough that Julia comes with a macro to abbreviate this pattern:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for op = (:sin, :cos, :tan, :log, :exp)\n @eval Base.$op(a::MyNumber) = MyNumber($op(a.x))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The @eval macro rewrites this call to be precisely equivalent to the above longer versions. For longer blocks of generated code, the expression argument given to @eval can be a block:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"@eval begin\n # multiple lines\nend","category":"page"},{"location":"manual/metaprogramming/#meta-non-standard-string-literals","page":"Metaprogramming","title":"Non-Standard String Literals","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Recall from Strings that string literals prefixed by an identifier are called non-standard string literals, and can have different semantics than un-prefixed string literals. For example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"r\"^\\s*(?:#|$)\" produces a regular expression object rather than a string\nb\"DATA\\xff\\u2200\" is a byte array literal for [68,65,84,65,255,226,136,128].","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Perhaps surprisingly, these behaviors are not hard-coded into the Julia parser or compiler. Instead, they are custom behaviors provided by a general mechanism that anyone can use: prefixed string literals are parsed as calls to specially-named macros. For example, the regular expression macro is just the following:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro r_str(p)\n Regex(p)\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"That's all. This macro says that the literal contents of the string literal r\"^\\s*(?:#|$)\" should be passed to the @r_str macro and the result of that expansion should be placed in the syntax tree where the string literal occurs. In other words, the expression r\"^\\s*(?:#|$)\" is equivalent to placing the following object directly into the syntax tree:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Regex(\"^\\\\s*(?:#|\\$)\")","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Not only is the string literal form shorter and far more convenient, but it is also more efficient: since the regular expression is compiled and the Regex object is actually created when the code is compiled, the compilation occurs only once, rather than every time the code is executed. Consider if the regular expression occurs in a loop:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for line = lines\n m = match(r\"^\\s*(?:#|$)\", line)\n if m === nothing\n # non-comment\n else\n # comment\n end\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Since the regular expression r\"^\\s*(?:#|$)\" is compiled and inserted into the syntax tree when this code is parsed, the expression is only compiled once instead of each time the loop is executed. In order to accomplish this without macros, one would have to write this loop like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"re = Regex(\"^\\\\s*(?:#|\\$)\")\nfor line = lines\n m = match(re, line)\n if m === nothing\n # non-comment\n else\n # comment\n end\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Moreover, if the compiler could not determine that the regex object was constant over all loops, certain optimizations might not be possible, making this version still less efficient than the more convenient literal form above. Of course, there are still situations where the non-literal form is more convenient: if one needs to interpolate a variable into the regular expression, one must take this more verbose approach; in cases where the regular expression pattern itself is dynamic, potentially changing upon each loop iteration, a new regular expression object must be constructed on each iteration. In the vast majority of use cases, however, regular expressions are not constructed based on run-time data. In this majority of cases, the ability to write regular expressions as compile-time values is invaluable.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The mechanism for user-defined string literals is deeply, profoundly powerful. Not only are Julia's non-standard literals implemented using it, but the command literal syntax (`echo \"Hello, $person\"`) is also implemented using the following innocuous-looking macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro cmd(str)\n :(cmd_gen($(shell_parse(str)[1])))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Of course, a large amount of complexity is hidden in the functions used in this macro definition, but they are just functions, written entirely in Julia. You can read their source and see precisely what they do – and all they do is construct expression objects to be inserted into your program's syntax tree.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Like string literals, command literals can also be prefixed by an identifier to form what are called non-standard command literals. These command literals are parsed as calls to specially-named macros. For example, the syntax custom`literal` is parsed as @custom_cmd \"literal\". Julia itself does not contain any non-standard command literals, but packages can make use of this syntax. Aside from the different syntax and the _cmd suffix instead of the _str suffix, non-standard command literals behave exactly like non-standard string literals.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In the event that two modules provide non-standard string or command literals with the same name, it is possible to qualify the string or command literal with a module name. For instance, if both Foo and Bar provide non-standard string literal @x_str, then one can write Foo.x\"literal\" or Bar.x\"literal\" to disambiguate between the two.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Another way to define a macro would be like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro foo_str(str, flag)\n # do stuff\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This macro can then be called with the following syntax:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"foo\"str\"flag","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The type of flag in the above mentioned syntax would be a String with contents of whatever trails after the string literal.","category":"page"},{"location":"manual/metaprogramming/#Generated-functions","page":"Metaprogramming","title":"Generated functions","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"A very special macro is @generated, which allows you to define so-called generated functions. These have the capability to generate specialized code depending on the types of their arguments with more flexibility and/or less code than what can be achieved with multiple dispatch. While macros work with expressions at parse time and cannot access the types of their inputs, a generated function gets expanded at a time when the types of the arguments are known, but the function is not yet compiled.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Instead of performing some calculation or action, a generated function declaration returns a quoted expression which then forms the body for the method corresponding to the types of the arguments. When a generated function is called, the expression it returns is compiled and then run. To make this efficient, the result is usually cached. And to make this inferable, only a limited subset of the language is usable. Thus, generated functions provide a flexible way to move work from run time to compile time, at the expense of greater restrictions on allowed constructs.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"When defining generated functions, there are five main differences to ordinary functions:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"You annotate the function declaration with the @generated macro. This adds some information to the AST that lets the compiler know that this is a generated function.\nIn the body of the generated function you only have access to the types of the arguments – not their values.\nInstead of calculating something or performing some action, you return a quoted expression which, when evaluated, does what you want.\nGenerated functions are only permitted to call functions that were defined before the definition of the generated function. (Failure to follow this may result in getting MethodErrors referring to functions from a future world-age.)\nGenerated functions must not mutate or observe any non-constant global state (including, for example, IO, locks, non-local dictionaries, or using hasmethod). This means they can only read global constants, and cannot have any side effects. In other words, they must be completely pure. Due to an implementation limitation, this also means that they currently cannot define a closure or generator.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"It's easiest to illustrate this with an example. We can declare a generated function foo as","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated function foo(x)\n Core.println(x)\n return :(x * x)\n end\nfoo (generic function with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note that the body returns a quoted expression, namely :(x * x), rather than just the value of x * x.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"From the caller's perspective, this is identical to a regular function; in fact, you don't have to know whether you're calling a regular or generated function. Let's see how foo behaves:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> x = foo(2); # note: output is from println() statement in the body\nInt64\n\njulia> x # now we print x\n4\n\njulia> y = foo(\"bar\");\nString\n\njulia> y\n\"barbar\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"So, we see that in the body of the generated function, x is the type of the passed argument, and the value returned by the generated function, is the result of evaluating the quoted expression we returned from the definition, now with the value of x.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"What happens if we evaluate foo again with a type that we have already used?","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> foo(4)\n16","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note that there is no printout of Int64. We can see that the body of the generated function was only executed once here, for the specific set of argument types, and the result was cached. After that, for this example, the expression returned from the generated function on the first invocation was re-used as the method body. However, the actual caching behavior is an implementation-defined performance optimization, so it is invalid to depend too closely on this behavior.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The number of times a generated function is generated might be only once, but it might also be more often, or appear to not happen at all. As a consequence, you should never write a generated function with side effects - when, and how often, the side effects occur is undefined. (This is true for macros too - and just like for macros, the use of eval in a generated function is a sign that you're doing something the wrong way.) However, unlike macros, the runtime system cannot correctly handle a call to eval, so it is disallowed.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"It is also important to see how @generated functions interact with method redefinition. Following the principle that a correct @generated function must not observe any mutable state or cause any mutation of global state, we see the following behavior. Observe that the generated function cannot call any method that was not defined prior to the definition of the generated function itself.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Initially f(x) has one definition","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> f(x) = \"original definition\";","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Define other operations that use f(x):","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> g(x) = f(x);\n\njulia> @generated gen1(x) = f(x);\n\njulia> @generated gen2(x) = :(f(x));","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We now add some new definitions for f(x):","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> f(x::Int) = \"definition for Int\";\n\njulia> f(x::Type{Int}) = \"definition for Type{Int}\";","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"and compare how these results differ:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> f(1)\n\"definition for Int\"\n\njulia> g(1)\n\"definition for Int\"\n\njulia> gen1(1)\n\"original definition\"\n\njulia> gen2(1)\n\"definition for Int\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Each method of a generated function has its own view of defined functions:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated gen1(x::Real) = f(x);\n\njulia> gen1(1)\n\"definition for Type{Int}\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The example generated function foo above did not do anything a normal function foo(x) = x * x could not do (except printing the type on the first invocation, and incurring higher overhead). However, the power of a generated function lies in its ability to compute different quoted expressions depending on the types passed to it:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated function bar(x)\n if x <: Integer\n return :(x ^ 2)\n else\n return :(x)\n end\n end\nbar (generic function with 1 method)\n\njulia> bar(4)\n16\n\njulia> bar(\"baz\")\n\"baz\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"(although of course this contrived example would be more easily implemented using multiple dispatch...)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Abusing this will corrupt the runtime system and cause undefined behavior:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated function baz(x)\n if rand() < .9\n return :(x^2)\n else\n return :(\"boo!\")\n end\n end\nbaz (generic function with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Since the body of the generated function is non-deterministic, its behavior, and the behavior of all subsequent code is undefined.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Don't copy these examples!","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"These examples are hopefully helpful to illustrate how generated functions work, both in the definition end and at the call site; however, don't copy them, for the following reasons:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"the foo function has side-effects (the call to Core.println), and it is undefined exactly when, how often or how many times these side-effects will occur\nthe bar function solves a problem that is better solved with multiple dispatch - defining bar(x) = x and bar(x::Integer) = x ^ 2 will do the same thing, but it is both simpler and faster.\nthe baz function is pathological","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note that the set of operations that should not be attempted in a generated function is unbounded, and the runtime system can currently only detect a subset of the invalid operations. There are many other operations that will simply corrupt the runtime system without notification, usually in subtle ways not obviously connected to the bad definition. Because the function generator is run during inference, it must respect all of the limitations of that code.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Some operations that should not be attempted include:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Caching of native pointers.\nInteracting with the contents or methods of Core.Compiler in any way.\nObserving any mutable state.\nInference on the generated function may be run at any time, including while your code is attempting to observe or mutate this state.\nTaking any locks: C code you call out to may use locks internally, (for example, it is not problematic to call malloc, even though most implementations require locks internally) but don't attempt to hold or acquire any while executing Julia code.\nCalling any function that is defined after the body of the generated function. This condition is relaxed for incrementally-loaded precompiled modules to allow calling any function in the module.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Alright, now that we have a better understanding of how generated functions work, let's use them to build some more advanced (and valid) functionality...","category":"page"},{"location":"manual/metaprogramming/#An-advanced-example","page":"Metaprogramming","title":"An advanced example","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Julia's base library has an internal sub2ind function to calculate a linear index into an n-dimensional array, based on a set of n multilinear indices - in other words, to calculate the index i that can be used to index into an array A using A[i], instead of A[x,y,z,...]. One possible implementation is the following:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function sub2ind_loop(dims::NTuple{N}, I::Integer...) where N\n ind = I[N] - 1\n for i = N-1:-1:1\n ind = I[i]-1 + dims[i]*ind\n end\n return ind + 1\n end;\n\njulia> sub2ind_loop((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The same thing can be done using recursion:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> sub2ind_rec(dims::Tuple{}) = 1;\n\njulia> sub2ind_rec(dims::Tuple{}, i1::Integer, I::Integer...) =\n i1 == 1 ? sub2ind_rec(dims, I...) : throw(BoundsError());\n\njulia> sub2ind_rec(dims::Tuple{Integer, Vararg{Integer}}, i1::Integer) = i1;\n\njulia> sub2ind_rec(dims::Tuple{Integer, Vararg{Integer}}, i1::Integer, I::Integer...) =\n i1 + dims[1] * (sub2ind_rec(Base.tail(dims), I...) - 1);\n\njulia> sub2ind_rec((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Both these implementations, although different, do essentially the same thing: a runtime loop over the dimensions of the array, collecting the offset in each dimension into the final index.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"However, all the information we need for the loop is embedded in the type information of the arguments. This allows the compiler to move the iteration to compile time and eliminate the runtime loops altogether. We can utilize generated functions to achieve a similar effect; in compiler parlance, we use generated functions to manually unroll the loop. The body becomes almost identical, but instead of calculating the linear index, we build up an expression that calculates the index:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N\n ex = :(I[$N] - 1)\n for i = (N - 1):-1:1\n ex = :(I[$i] - 1 + dims[$i] * $ex)\n end\n return :($ex + 1)\n end;\n\njulia> sub2ind_gen((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"What code will this generate?","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"An easy way to find out is to extract the body into another (regular) function:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function sub2ind_gen_impl(dims::Type{T}, I...) where T <: NTuple{N,Any} where N\n length(I) == N || return :(error(\"partial indexing is unsupported\"))\n ex = :(I[$N] - 1)\n for i = (N - 1):-1:1\n ex = :(I[$i] - 1 + dims[$i] * $ex)\n end\n return :($ex + 1)\n end;\n\njulia> @generated function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N\n return sub2ind_gen_impl(dims, I...)\n end;\n\njulia> sub2ind_gen((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We can now execute sub2ind_gen_impl and examine the expression it returns:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> sub2ind_gen_impl(Tuple{Int,Int}, Int, Int)\n:(((I[1] - 1) + dims[1] * (I[2] - 1)) + 1)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"So, the method body that will be used here doesn't include a loop at all - just indexing into the two tuples, multiplication and addition/subtraction. All the looping is performed compile-time, and we avoid looping during execution entirely. Thus, we only loop once per type, in this case once per N (except in edge cases where the function is generated more than once - see disclaimer above).","category":"page"},{"location":"manual/metaprogramming/#Optionally-generated-functions","page":"Metaprogramming","title":"Optionally-generated functions","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Generated functions can achieve high efficiency at run time, but come with a compile time cost: a new function body must be generated for every combination of concrete argument types. Typically, Julia is able to compile \"generic\" versions of functions that will work for any arguments, but with generated functions this is impossible. This means that programs making heavy use of generated functions might be impossible to statically compile.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"To solve this problem, the language provides syntax for writing normal, non-generated alternative implementations of generated functions. Applied to the sub2ind example above, it would look like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function sub2ind_gen_impl(dims::Type{T}, I...) where T <: NTuple{N,Any} where N\n ex = :(I[$N] - 1)\n for i = (N - 1):-1:1\n ex = :(I[$i] - 1 + dims[$i] * $ex)\n end\n return :($ex + 1)\n end;\n\njulia> function sub2ind_gen_fallback(dims::NTuple{N}, I) where N\n ind = I[N] - 1\n for i = (N - 1):-1:1\n ind = I[i] - 1 + dims[i]*ind\n end\n return ind + 1\n end;\n\njulia> function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N\n length(I) == N || error(\"partial indexing is unsupported\")\n if @generated\n return sub2ind_gen_impl(dims, I...)\n else\n return sub2ind_gen_fallback(dims, I)\n end\n end;\n\njulia> sub2ind_gen((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Internally, this code creates two implementations of the function: a generated one where the first block in if @generated is used, and a normal one where the else block is used. Inside the then part of the if @generated block, code has the same semantics as other generated functions: argument names refer to types, and the code should return an expression. Multiple if @generated blocks may occur, in which case the generated implementation uses all of the then blocks and the alternate implementation uses all of the else blocks.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Notice that we added an error check to the top of the function. This code will be common to both versions, and is run-time code in both versions (it will be quoted and returned as an expression from the generated version). That means that the values and types of local variables are not available at code generation time –- the code-generation code can only see the types of arguments.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In this style of definition, the code generation feature is essentially an optional optimization. The compiler will use it if convenient, but otherwise may choose to use the normal implementation instead. This style is preferred, since it allows the compiler to make more decisions and compile programs in more ways, and since normal code is more readable than code-generating code. However, which implementation is used depends on compiler implementation details, so it is essential for the two implementations to behave identically.","category":"page"},{"location":"devdocs/offset-arrays/#man-custom-indices","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Conventionally, Julia's arrays are indexed starting at 1, whereas some other languages start numbering at 0, and yet others (e.g., Fortran) allow you to specify arbitrary starting indices. While there is much merit in picking a standard (i.e., 1 for Julia), there are some algorithms which simplify considerably if you can index outside the range 1:size(A,d) (and not just 0:size(A,d)-1, either). To facilitate such computations, Julia supports arrays with arbitrary indices.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"The purpose of this page is to address the question, \"what do I have to do to support such arrays in my own code?\" First, let's address the simplest case: if you know that your code will never need to handle arrays with unconventional indexing, hopefully the answer is \"nothing.\" Old code, on conventional arrays, should function essentially without alteration as long as it was using the exported interfaces of Julia. If you find it more convenient to just force your users to supply traditional arrays where indexing starts at one, you can add","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base.require_one_based_indexing(arrays...)","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"where arrays... is a list of the array objects that you wish to check for anything that violates 1-based indexing.","category":"page"},{"location":"devdocs/offset-arrays/#Generalizing-existing-code","page":"Arrays with custom indices","title":"Generalizing existing code","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"As an overview, the steps are:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"replace many uses of size with axes\nreplace 1:length(A) with eachindex(A), or in some cases LinearIndices(A)\nreplace explicit allocations like Array{Int}(undef, size(B)) with similar(Array{Int}, axes(B))","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"These are described in more detail below.","category":"page"},{"location":"devdocs/offset-arrays/#Things-to-watch-out-for","page":"Arrays with custom indices","title":"Things to watch out for","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Because unconventional indexing breaks many people's assumptions that all arrays start indexing with 1, there is always the chance that using such arrays will trigger errors. The most frustrating bugs would be incorrect results or segfaults (total crashes of Julia). For example, consider the following function:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"function mycopy!(dest::AbstractVector, src::AbstractVector)\n length(dest) == length(src) || throw(DimensionMismatch(\"vectors must match\"))\n # OK, now we're safe to use @inbounds, right? (not anymore!)\n for i = 1:length(src)\n @inbounds dest[i] = src[i]\n end\n dest\nend","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"This code implicitly assumes that vectors are indexed from 1; if dest starts at a different index than src, there is a chance that this code would trigger a segfault. (If you do get segfaults, to help locate the cause try running julia with the option --check-bounds=yes.)","category":"page"},{"location":"devdocs/offset-arrays/#Using-axes-for-bounds-checks-and-loop-iteration","page":"Arrays with custom indices","title":"Using axes for bounds checks and loop iteration","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"axes(A) (reminiscent of size(A)) returns a tuple of AbstractUnitRange{<:Integer} objects, specifying the range of valid indices along each dimension of A. When A has unconventional indexing, the ranges may not start at 1. If you just want the range for a particular dimension d, there is axes(A, d).","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base implements a custom range type, OneTo, where OneTo(n) means the same thing as 1:n but in a form that guarantees (via the type system) that the lower index is 1. For any new AbstractArray type, this is the default returned by axes, and it indicates that this array type uses \"conventional\" 1-based indexing.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"For bounds checking, note that there are dedicated functions checkbounds and checkindex which can sometimes simplify such tests.","category":"page"},{"location":"devdocs/offset-arrays/#Linear-indexing-(LinearIndices)","page":"Arrays with custom indices","title":"Linear indexing (LinearIndices)","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Some algorithms are most conveniently (or efficiently) written in terms of a single linear index, A[i] even if A is multi-dimensional. Regardless of the array's native indices, linear indices always range from 1:length(A). However, this raises an ambiguity for one-dimensional arrays (a.k.a., AbstractVector): does v[i] mean linear indexing , or Cartesian indexing with the array's native indices?","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"For this reason, your best option may be to iterate over the array with eachindex(A), or, if you require the indices to be sequential integers, to get the index range by calling LinearIndices(A). This will return axes(A, 1) if A is an AbstractVector, and the equivalent of 1:length(A) otherwise.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"By this definition, 1-dimensional arrays always use Cartesian indexing with the array's native indices. To help enforce this, it's worth noting that the index conversion functions will throw an error if shape indicates a 1-dimensional array with unconventional indexing (i.e., is a Tuple{UnitRange} rather than a tuple of OneTo). For arrays with conventional indexing, these functions continue to work the same as always.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Using axes and LinearIndices, here is one way you could rewrite mycopy!:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"function mycopy!(dest::AbstractVector, src::AbstractVector)\n axes(dest) == axes(src) || throw(DimensionMismatch(\"vectors must match\"))\n for i in LinearIndices(src)\n @inbounds dest[i] = src[i]\n end\n dest\nend","category":"page"},{"location":"devdocs/offset-arrays/#Allocating-storage-using-generalizations-of-similar","page":"Arrays with custom indices","title":"Allocating storage using generalizations of similar","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Storage is often allocated with Array{Int}(undef, dims) or similar(A, args...). When the result needs to match the indices of some other array, this may not always suffice. The generic replacement for such patterns is to use similar(storagetype, shape). storagetype indicates the kind of underlying \"conventional\" behavior you'd like, e.g., Array{Int} or BitArray or even dims->zeros(Float32, dims) (which would allocate an all-zeros array). shape is a tuple of Integer or AbstractUnitRange values, specifying the indices that you want the result to use. Note that a convenient way of producing an all-zeros array that matches the indices of A is simply zeros(A).","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Let's walk through a couple of explicit examples. First, if A has conventional indices, then similar(Array{Int}, axes(A)) would end up calling Array{Int}(undef, size(A)), and thus return an array. If A is an AbstractArray type with unconventional indexing, then similar(Array{Int}, axes(A)) should return something that \"behaves like\" an Array{Int} but with a shape (including indices) that matches A. (The most obvious implementation is to allocate an Array{Int}(undef, size(A)) and then \"wrap\" it in a type that shifts the indices.)","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Note also that similar(Array{Int}, (axes(A, 2),)) would allocate an AbstractVector{Int} (i.e., 1-dimensional array) that matches the indices of the columns of A.","category":"page"},{"location":"devdocs/offset-arrays/#Writing-custom-array-types-with-non-1-indexing","page":"Arrays with custom indices","title":"Writing custom array types with non-1 indexing","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Most of the methods you'll need to define are standard for any AbstractArray type, see Abstract Arrays. This page focuses on the steps needed to define unconventional indexing.","category":"page"},{"location":"devdocs/offset-arrays/#Custom-AbstractUnitRange-types","page":"Arrays with custom indices","title":"Custom AbstractUnitRange types","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"If you're writing a non-1 indexed array type, you will want to specialize axes so it returns a UnitRange, or (perhaps better) a custom AbstractUnitRange. The advantage of a custom type is that it \"signals\" the allocation type for functions like similar. If we're writing an array type for which indexing will start at 0, we likely want to begin by creating a new AbstractUnitRange, ZeroRange, where ZeroRange(n) is equivalent to 0:n-1.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"In general, you should probably not export ZeroRange from your package: there may be other packages that implement their own ZeroRange, and having multiple distinct ZeroRange types is (perhaps counterintuitively) an advantage: ModuleA.ZeroRange indicates that similar should create a ModuleA.ZeroArray, whereas ModuleB.ZeroRange indicates a ModuleB.ZeroArray type. This design allows peaceful coexistence among many different custom array types.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Note that the Julia package CustomUnitRanges.jl can sometimes be used to avoid the need to write your own ZeroRange type.","category":"page"},{"location":"devdocs/offset-arrays/#Specializing-axes","page":"Arrays with custom indices","title":"Specializing axes","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Once you have your AbstractUnitRange type, then specialize axes:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base.axes(A::ZeroArray) = map(n->ZeroRange(n), A.size)","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"where here we imagine that ZeroArray has a field called size (there would be other ways to implement this).","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"In some cases, the fallback definition for axes(A, d):","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"axes(A::AbstractArray{T,N}, d) where {T,N} = d <= N ? axes(A)[d] : OneTo(1)","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"may not be what you want: you may need to specialize it to return something other than OneTo(1) when d > ndims(A). Likewise, in Base there is a dedicated function axes1 which is equivalent to axes(A, 1) but which avoids checking (at runtime) whether ndims(A) > 0. (This is purely a performance optimization.) It is defined as:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"axes1(A::AbstractArray{T,0}) where {T} = OneTo(1)\naxes1(A::AbstractArray) = axes(A)[1]","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"If the first of these (the zero-dimensional case) is problematic for your custom array type, be sure to specialize it appropriately.","category":"page"},{"location":"devdocs/offset-arrays/#Specializing-similar","page":"Arrays with custom indices","title":"Specializing similar","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Given your custom ZeroRange type, then you should also add the following two specializations for similar:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"function Base.similar(A::AbstractArray, T::Type, shape::Tuple{ZeroRange,Vararg{ZeroRange}})\n # body\nend\n\nfunction Base.similar(f::Union{Function,DataType}, shape::Tuple{ZeroRange,Vararg{ZeroRange}})\n # body\nend","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Both of these should allocate your custom array type.","category":"page"},{"location":"devdocs/offset-arrays/#Specializing-reshape","page":"Arrays with custom indices","title":"Specializing reshape","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Optionally, define a method","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base.reshape(A::AbstractArray, shape::Tuple{ZeroRange,Vararg{ZeroRange}}) = ...","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"and you can reshape an array so that the result has custom indices.","category":"page"},{"location":"devdocs/offset-arrays/#For-objects-that-mimic-AbstractArray-but-are-not-subtypes","page":"Arrays with custom indices","title":"For objects that mimic AbstractArray but are not subtypes","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"has_offset_axes depends on having axes defined for the objects you call it on. If there is some reason you don't have an axes method defined for your object, consider defining a method","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base.has_offset_axes(obj::MyNon1IndexedArraylikeObject) = true","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"This will allow code that assumes 1-based indexing to detect a problem and throw a helpful error, rather than returning incorrect results or segfaulting julia.","category":"page"},{"location":"devdocs/offset-arrays/#Catching-errors","page":"Arrays with custom indices","title":"Catching errors","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"If your new array type triggers errors in other code, one helpful debugging step can be to comment out @boundscheck in your getindex and setindex! implementation. This will ensure that every element access checks bounds. Or, restart julia with --check-bounds=yes.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"In some cases it may also be helpful to temporarily disable size and length for your new array type, since code that makes incorrect assumptions frequently uses these functions.","category":"page"},{"location":"devdocs/boundscheck/#Bounds-checking","page":"Bounds checking","title":"Bounds checking","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Like many modern programming languages, Julia uses bounds checking to ensure program safety when accessing arrays. In tight inner loops or other performance critical situations, you may wish to skip these bounds checks to improve runtime performance. For instance, in order to emit vectorized (SIMD) instructions, your loop body cannot contain branches, and thus cannot contain bounds checks. Consequently, Julia includes an @inbounds(...) macro to tell the compiler to skip such bounds checks within the given block. User-defined array types can use the @boundscheck(...) macro to achieve context-sensitive code selection.","category":"page"},{"location":"devdocs/boundscheck/#Eliding-bounds-checks","page":"Bounds checking","title":"Eliding bounds checks","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"The @boundscheck(...) macro marks blocks of code that perform bounds checking. When such blocks are inlined into an @inbounds(...) block, the compiler may remove these blocks. The compiler removes the @boundscheck block only if it is inlined into the calling function. For example, you might write the method sum as:","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"function sum(A::AbstractArray)\n r = zero(eltype(A))\n for i in eachindex(A)\n @inbounds r += A[i]\n end\n return r\nend","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"With a custom array-like type MyArray having:","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"@inline getindex(A::MyArray, i::Real) = (@boundscheck checkbounds(A, i); A.data[to_index(i)])","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Then when getindex is inlined into sum, the call to checkbounds(A, i) will be elided. If your function contains multiple layers of inlining, only @boundscheck blocks at most one level of inlining deeper are eliminated. The rule prevents unintended changes in program behavior from code further up the stack.","category":"page"},{"location":"devdocs/boundscheck/#Caution!","page":"Bounds checking","title":"Caution!","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"It is easy to accidentally expose unsafe operations with @inbounds. You might be tempted to write the above example as","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"function sum(A::AbstractArray)\n r = zero(eltype(A))\n for i in 1:length(A)\n @inbounds r += A[i]\n end\n return r\nend","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Which quietly assumes 1-based indexing and therefore exposes unsafe memory access when used with OffsetArrays:","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"julia> using OffsetArrays\n\njulia> sum(OffsetArray([1, 2, 3], -10))\n9164911648 # inconsistent results or segfault","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"While the original source of the error here is 1:length(A), the use of @inbounds increases the consequences from a bounds error to a less easily caught and debugged unsafe memory access. It is often difficult or impossible to prove that a method which uses @inbounds is safe, so one must weigh the benefits of performance improvements against the risk of segfaults and silent misbehavior, especially in public facing APIs.","category":"page"},{"location":"devdocs/boundscheck/#Propagating-inbounds","page":"Bounds checking","title":"Propagating inbounds","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"There may be certain scenarios where for code-organization reasons you want more than one layer between the @inbounds and @boundscheck declarations. For instance, the default getindex methods have the chain getindex(A::AbstractArray, i::Real) calls getindex(IndexStyle(A), A, i) calls _getindex(::IndexLinear, A, i).","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"To override the \"one layer of inlining\" rule, a function may be marked with Base.@propagate_inbounds to propagate an inbounds context (or out of bounds context) through one additional layer of inlining.","category":"page"},{"location":"devdocs/boundscheck/#The-bounds-checking-call-hierarchy","page":"Bounds checking","title":"The bounds checking call hierarchy","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"The overall hierarchy is:","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"checkbounds(A, I...) which calls\ncheckbounds(Bool, A, I...) which calls\ncheckbounds_indices(Bool, axes(A), I) which recursively calls\ncheckindex for each dimension","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Here A is the array, and I contains the \"requested\" indices. axes(A) returns a tuple of \"permitted\" indices of A.","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"checkbounds(A, I...) throws an error if the indices are invalid, whereas checkbounds(Bool, A, I...) returns false in that circumstance. checkbounds_indices discards any information about the array other than its axes tuple, and performs a pure indices-vs-indices comparison: this allows relatively few compiled methods to serve a huge variety of array types. Indices are specified as tuples, and are usually compared in a 1-1 fashion with individual dimensions handled by calling another important function, checkindex: typically,","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"checkbounds_indices(Bool, (IA1, IA...), (I1, I...)) = checkindex(Bool, IA1, I1) &\n checkbounds_indices(Bool, IA, I)","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"so checkindex checks a single dimension. All of these functions, including the unexported checkbounds_indices have docstrings accessible with ? .","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"If you have to customize bounds checking for a specific array type, you should specialize checkbounds(Bool, A, I...). However, in most cases you should be able to rely on checkbounds_indices as long as you supply useful axes for your array type.","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"If you have novel index types, first consider specializing checkindex, which handles a single index for a particular dimension of an array. If you have a custom multidimensional index type (similar to CartesianIndex), then you may have to consider specializing checkbounds_indices.","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Note this hierarchy has been designed to reduce the likelihood of method ambiguities. We try to make checkbounds the place to specialize on array type, and try to avoid specializations on index types; conversely, checkindex is intended to be specialized only on index type (especially, the last argument).","category":"page"},{"location":"devdocs/boundscheck/#Emit-bounds-checks","page":"Bounds checking","title":"Emit bounds checks","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Julia can be launched with --check-bounds={yes|no|auto} to emit bounds checks always, never, or respect @inbounds declarations.","category":"page"},{"location":"devdocs/build/build/#Building-Julia-(Detailed)","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"","category":"section"},{"location":"devdocs/build/build/#Downloading-the-Julia-source-code","page":"Building Julia (Detailed)","title":"Downloading the Julia source code","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you are behind a firewall, you may need to use the https protocol instead of the git protocol:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"git config --global url.\"https://\".insteadOf git://","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Be sure to also configure your system to use the appropriate proxy settings, e.g. by setting the https_proxy and http_proxy variables.","category":"page"},{"location":"devdocs/build/build/#Building-Julia","page":"Building Julia (Detailed)","title":"Building Julia","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"When compiled the first time, the build will automatically download pre-built external dependencies. If you prefer to build all the dependencies on your own, or are building on a system that cannot access the network during the build process, add the following in Make.user:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"USE_BINARYBUILDER=0","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Building Julia requires 5GiB if building all dependencies and approximately 4GiB of virtual memory.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"To perform a parallel build, use make -j N and supply the maximum number of concurrent processes. If the defaults in the build do not work for you, and you need to set specific make parameters, you can save them in Make.user, and place the file in the root of your Julia source. The build will automatically check for the existence of Make.user and use it if it exists.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"You can create out-of-tree builds of Julia by specifying make O= configure on the command line. This will create a directory mirror, with all of the necessary Makefiles to build Julia, in the specified directory. These builds will share the source files in Julia and deps/srccache. Each out-of-tree build directory can have its own Make.user file to override the global Make.user file in the top-level folder.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If everything works correctly, you will see a Julia banner and an interactive prompt into which you can enter expressions for evaluation. (Errors related to libraries might be caused by old, incompatible libraries sitting around in your PATH. In this case, try moving the julia directory earlier in the PATH). Note that most of the instructions above apply to unix systems.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"To run julia from anywhere you can:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"add an alias (in bash: echo \"alias julia='/path/to/install/folder/bin/julia'\" >> ~/.bashrc && source ~/.bashrc), or\nadd a soft link to the julia executable in the julia directory to /usr/local/bin (or any suitable directory already in your path), or\nadd the julia directory to your executable path for this shell session (in bash: export PATH=\"$(pwd):$PATH\" ; in csh or tcsh:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"set path= ( $path $cwd ) ), or","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"add the julia directory to your executable path permanently (e.g. in .bash_profile), or\nwrite prefix=/path/to/install/folder into Make.user and then run make install. If there is a version of Julia already installed in this folder, you should delete it before running make install.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Some of the options you can set to control the build of Julia are listed and documented at the beginning of the file Make.inc, but you should never edit it for this purpose, use Make.user instead.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Julia's Makefiles define convenient automatic rules called print- for printing the value of variables, replacing with the name of the variable to print the value of. For example","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"$ make print-JULIA_PRECOMPILE\nJULIA_PRECOMPILE=1","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"These rules are useful for debugging purposes.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Now you should be able to run Julia like this:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"julia","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you are building a Julia package for distribution on Linux, macOS, or Windows, take a look at the detailed notes in distributing.md.","category":"page"},{"location":"devdocs/build/build/#Updating-an-existing-source-tree","page":"Building Julia (Detailed)","title":"Updating an existing source tree","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you have previously downloaded julia using git clone, you can update the existing source tree using git pull rather than starting anew:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"cd julia\ngit pull && make","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Assuming that you had made no changes to the source tree that will conflict with upstream updates, these commands will trigger a build to update to the latest version.","category":"page"},{"location":"devdocs/build/build/#General-troubleshooting","page":"Building Julia (Detailed)","title":"General troubleshooting","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Over time, the base library may accumulate enough changes such that the bootstrapping process in building the system image will fail. If this happens, the build may fail with an error like\n *** This error is usually fixed by running 'make clean'. If the error persists, try 'make cleanall' ***\nAs described, running make clean && make is usually sufficient. Occasionally, the stronger cleanup done by make cleanall is needed.\nNew versions of external dependencies may be introduced which may occasionally cause conflicts with existing builds of older versions.\na. Special make targets exist to help wipe the existing build of a dependency. For example, make -C deps clean-llvm will clean out the existing build of llvm so that llvm will be rebuilt from the downloaded source distribution the next time make is called. make -C deps distclean-llvm is a stronger wipe which will also delete the downloaded source distribution, ensuring that a fresh copy of the source distribution will be downloaded and that any new patches will be applied the next time make is called.\nb. To delete existing binaries of julia and all its dependencies, delete the ./usr directory in the source tree.\nIf you've updated macOS recently, be sure to run xcode-select --install to update the command line tools. Otherwise, you could run into errors for missing headers and libraries, such as ld: library not found for -lcrt1.10.6.o.\nIf you've moved the source directory, you might get errors such as CMake Error: The current CMakeCache.txt directory ... is different than the directory ... where CMakeCache.txt was created., in which case you may delete the offending dependency under deps\nIn extreme cases, you may wish to reset the source tree to a pristine state. The following git commands may be helpful:\n git reset --hard #Forcibly remove any changes to any files under version control\n git clean -x -f -d #Forcibly remove any file or directory not under version control\nTo avoid losing work, make sure you know what these commands do before you run them. git will not be able to undo these changes!","category":"page"},{"location":"devdocs/build/build/#Platform-Specific-Notes","page":"Building Julia (Detailed)","title":"Platform-Specific Notes","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Notes for various operating systems:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Linux\nmacOS\nWindows\nFreeBSD","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Notes for various architectures:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"ARM","category":"page"},{"location":"devdocs/build/build/#Required-Build-Tools-and-External-Libraries","page":"Building Julia (Detailed)","title":"Required Build Tools and External Libraries","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Building Julia requires that the following software be installed:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"[GNU make] — building dependencies.\n[gcc & g++][gcc] (>= 7.1) or [Clang][clang] (>= 5.0, >= 9.3 for Apple Clang) — compiling and linking C, C++.\n[libatomic][gcc] — provided by [gcc] and needed to support atomic operations.\n[python] (>=2.7) — needed to build LLVM.\n[gfortran] — compiling and linking Fortran libraries.\n[perl] — preprocessing of header files of libraries.\n[wget], [curl], or [fetch] (FreeBSD) — to automatically download external libraries.\n[m4] — needed to build GMP.\n[awk] — helper tool for Makefiles.\n[patch] — for modifying source code.\n[cmake] (>= 3.4.3) — needed to build libgit2.\n[pkg-config] — needed to build libgit2 correctly, especially for proxy support.\n[powershell] (>= 3.0) — necessary only on Windows.\n[which] — needed for checking build dependencies.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"On Debian-based distributions (e.g. Ubuntu), you can easily install them with apt-get:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"sudo apt-get install build-essential libatomic1 python gfortran perl wget m4 cmake pkg-config curl","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Julia uses the following external libraries, which are automatically downloaded (or in a few cases, included in the Julia source repository) and then compiled from source the first time you run make. The specific version numbers of these libraries that Julia uses are listed in deps/$(libname).version:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"[LLVM] (15.0 + patches) — compiler infrastructure (see note below).\n[FemtoLisp] — packaged with Julia source, and used to implement the compiler front-end.\n[libuv] (custom fork) — portable, high-performance event-based I/O library.\n[OpenLibm] — portable libm library containing elementary math functions.\n[DSFMT] — fast Mersenne Twister pseudorandom number generator library.\n[OpenBLAS] — fast, open, and maintained [basic linear algebra subprograms (BLAS)]\n[LAPACK] — library of linear algebra routines for solving systems of simultaneous linear equations, least-squares solutions of linear systems of equations, eigenvalue problems, and singular value problems.\n[MKL] (optional) – OpenBLAS and LAPACK may be replaced by Intel's MKL library.\n[SuiteSparse] — library of linear algebra routines for sparse matrices.\n[PCRE] — Perl-compatible regular expressions library.\n[GMP] — GNU multiple precision arithmetic library, needed for BigInt support.\n[MPFR] — GNU multiple precision floating point library, needed for arbitrary precision floating point (BigFloat) support.\n[libgit2] — Git linkable library, used by Julia's package manager.\n[curl] — libcurl provides download and proxy support.\n[libssh2] — library for SSH transport, used by libgit2 for packages with SSH remotes.\n[mbedtls] — library used for cryptography and transport layer security, used by libssh2\n[utf8proc] — a library for processing UTF-8 encoded Unicode strings.\n[LLVM libunwind] — LLVM's fork of [libunwind], a library that determines the call-chain of a program.\n[ITTAPI] — Intel's Instrumentation and Tracing Technology and Just-In-Time API.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"[GNU make]: https://www.gnu.org/software/make [patch]: https://www.gnu.org/software/patch [wget]: https://www.gnu.org/software/wget [m4]: https://www.gnu.org/software/m4 [awk]: https://www.gnu.org/software/gawk [gcc]: https://gcc.gnu.org [clang]: https://clang.llvm.org [python]: https://www.python.org/ [gfortran]: https://gcc.gnu.org/fortran/ [curl]: https://curl.haxx.se [fetch]: https://www.freebsd.org/cgi/man.cgi?fetch(1) [perl]: https://www.perl.org [cmake]: https://www.cmake.org [OpenLibm]: https://github.com/JuliaLang/openlibm [DSFMT]: https://github.com/MersenneTwister-Lab/dSFMT [OpenBLAS]: https://github.com/xianyi/OpenBLAS [LAPACK]: https://www.netlib.org/lapack [MKL]: https://software.intel.com/en-us/articles/intel-mkl [SuiteSparse]: https://people.engr.tamu.edu/davis/suitesparse.html [PCRE]: https://www.pcre.org [LLVM]: https://www.llvm.org [LLVM libunwind]: https://github.com/llvm/llvm-project/tree/main/libunwind [FemtoLisp]: https://github.com/JeffBezanson/femtolisp [GMP]: https://gmplib.org [MPFR]: https://www.mpfr.org [libuv]: https://github.com/JuliaLang/libuv [libgit2]: https://libgit2.org/ [utf8proc]: https://julialang.org/utf8proc/ [libunwind]: https://www.nongnu.org/libunwind [libssh2]: https://www.libssh2.org [mbedtls]: https://tls.mbed.org/ [pkg-config]: https://www.freedesktop.org/wiki/Software/pkg-config/ [powershell]: https://docs.microsoft.com/en-us/powershell/scripting/wmf/overview [which]: https://carlowood.github.io/which/ [ITTAPI]: https://github.com/intel/ittapi","category":"page"},{"location":"devdocs/build/build/#Build-dependencies","page":"Building Julia (Detailed)","title":"Build dependencies","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you already have one or more of these packages installed on your system, you can prevent Julia from compiling duplicates of these libraries by passing USE_SYSTEM_...=1 to make or adding the line to Make.user. The complete list of possible flags can be found in Make.inc.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Please be aware that this procedure is not officially supported, as it introduces additional variability into the installation and versioning of the dependencies, and is recommended only for system package maintainers. Unexpected compile errors may result, as the build system will do no further checking to ensure the proper packages are installed.","category":"page"},{"location":"devdocs/build/build/#LLVM","page":"Building Julia (Detailed)","title":"LLVM","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"The most complicated dependency is LLVM, for which we require additional patches from upstream (LLVM is not backward compatible).","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"For packaging Julia with LLVM, we recommend either:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"bundling a Julia-only LLVM library inside the Julia package, or\nadding the patches to the LLVM package of the distribution.\nA complete list of patches is available in on Github see the julia-release/15.x branch.\nThe only Julia-specific patch is the lib renaming (llvm7-symver-jlprefix.patch), which should not be applied to a system LLVM.\nThe remaining patches are all upstream bug fixes, and have been contributed into upstream LLVM.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Using an unpatched or different version of LLVM will result in errors and/or poor performance. You can build a different version of LLVM from a remote Git repository with the following options in the Make.user file:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"# Force source build of LLVM\nUSE_BINARYBUILDER_LLVM = 0\n# Use Git for fetching LLVM source code\n# this is either `1` to get all of them\nDEPS_GIT = 1\n# or a space-separated list of specific dependencies to download with git\nDEPS_GIT = llvm\n\n# Other useful options:\n#URL of the Git repository you want to obtain LLVM from:\n# LLVM_GIT_URL = ...\n#Name of the alternate branch to clone from git\n# LLVM_BRANCH = julia-16.0.6-0\n#SHA hash of the alternate commit to check out automatically\n# LLVM_SHA1 = $(LLVM_BRANCH)\n#List of LLVM targets to build. It is strongly recommended to keep at least all the\n#default targets listed in `deps/llvm.mk`, even if you don't necessarily need all of them.\n# LLVM_TARGETS = ...\n#Use ccache for faster recompilation in case you need to restart a build.\n# USECCACHE = 1\n# CMAKE_GENERATOR=Ninja\n# LLVM_ASSERTIONS=1\n# LLVM_DEBUG=Symbols","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"The various build phases are controlled by specific files:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"deps/llvm.version : touch or change to checkout a new version, make get-llvm check-llvm\ndeps/srccache/llvm/source-extracted : result of make extract-llvm\ndeps/llvm/build_Release*/build-configured : result of make configure-llvm\ndeps/llvm/build_Release*/build-configured : result of make compile-llvm\nusr-staging/llvm/build_Release*.tgz : result of make stage-llvm (regenerate with make reinstall-llvm)\nusr/manifest/llvm : result of make install-llvm (regenerate with make uninstall-llvm)\nmake version-check-llvm : runs every time to warn the user if there are local modifications","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Though Julia can be built with newer LLVM versions, support for this should be regarded as experimental and not suitable for packaging.","category":"page"},{"location":"devdocs/build/build/#libuv","page":"Building Julia (Detailed)","title":"libuv","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Julia uses a custom fork of libuv. It is a small dependency, and can be safely bundled in the same package as Julia, and will not conflict with the system library. Julia builds should not try to use the system libuv.","category":"page"},{"location":"devdocs/build/build/#BLAS-and-LAPACK","page":"Building Julia (Detailed)","title":"BLAS and LAPACK","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"As a high-performance numerical language, Julia should be linked to a multi-threaded BLAS and LAPACK, such as OpenBLAS or ATLAS, which will provide much better performance than the reference libblas implementations which may be default on some systems.","category":"page"},{"location":"devdocs/build/build/#Source-distributions-of-releases","page":"Building Julia (Detailed)","title":"Source distributions of releases","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Each pre-release and release of Julia has a \"full\" source distribution and a \"light\" source distribution.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"The full source distribution contains the source code for Julia and all dependencies so that it can be built from source without an internet connection. The light source distribution does not include the source code of dependencies.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"For example, julia-1.0.0.tar.gz is the light source distribution for the v1.0.0 release of Julia, while julia-1.0.0-full.tar.gz is the full source distribution.","category":"page"},{"location":"devdocs/build/build/#Building-Julia-from-source-with-a-Git-checkout-of-a-stdlib","page":"Building Julia (Detailed)","title":"Building Julia from source with a Git checkout of a stdlib","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you need to build Julia from source with a Git checkout of a stdlib, then use make DEPS_GIT=NAME_OF_STDLIB when building Julia.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"For example, if you need to build Julia from source with a Git checkout of Pkg, then use make DEPS_GIT=Pkg when building Julia. The Pkg repo is in stdlib/Pkg, and created initially with a detached HEAD. If you're doing this from a pre-existing Julia repository, you may need to make clean beforehand.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you need to build Julia from source with Git checkouts of more than one stdlib, then DEPS_GIT should be a space-separated list of the stdlib names. For example, if you need to build Julia from source with a Git checkout of Pkg, Tar, and Downloads, then use make DEPS_GIT='Pkg Tar Downloads' when building Julia.","category":"page"},{"location":"devdocs/build/build/#Building-an-\"assert-build\"-of-Julia","page":"Building Julia (Detailed)","title":"Building an \"assert build\" of Julia","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"An \"assert build\" of Julia is a build that was built with both FORCE_ASSERTIONS=1 and LLVM_ASSERTIONS=1. To build an assert build, define both of the following variables in your Make.user file:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"FORCE_ASSERTIONS=1\nLLVM_ASSERTIONS=1","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Please note that assert builds of Julia will be slower than regular (non-assert) builds.","category":"page"},{"location":"devdocs/build/build/#Building-32-bit-Julia-on-a-64-bit-machine","page":"Building Julia (Detailed)","title":"Building 32-bit Julia on a 64-bit machine","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Occasionally, bugs specific to 32-bit architectures may arise, and when this happens it is useful to be able to debug the problem on your local machine. Since most modern 64-bit systems support running programs built for 32-bit ones, if you don't have to recompile Julia from source (e.g. you mainly need to inspect the behavior of a 32-bit Julia without having to touch the C code), you can likely use a 32-bit build of Julia for your system that you can obtain from the official downloads page. However, if you do need to recompile Julia from source one option is to use a Docker container of a 32-bit system. At least for now, building a 32-bit version of Julia is relatively straightforward using ubuntu 32-bit docker images. In brief, after setting up docker here are the required steps:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"$ docker pull i386/ubuntu\n$ docker run --platform i386 -i -t i386/ubuntu /bin/bash","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"At this point you should be in a 32-bit machine console (note that uname reports the host architecture, so will still say 64-bit, but this will not affect the Julia build). You can add packages and compile code; when you exit, all the changes will be lost, so be sure to finish your analysis in a single session or set up a copy/pastable script you can use to set up your environment.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"From this point, you should","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"# apt update","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"(Note that sudo isn't installed, but neither is it necessary since you are running as root, so you can omit sudo from all commands.)","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Then add all the build dependencies, a console-based editor of your choice, git, and anything else you'll need (e.g., gdb, rr, etc). Pick a directory to work in and git clone Julia, check out the branch you wish to debug, and build Julia as usual.","category":"page"},{"location":"devdocs/build/build/#Update-the-version-number-of-a-dependency","page":"Building Julia (Detailed)","title":"Update the version number of a dependency","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"There are two types of builds","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Build everything (deps/ and src/) from source code. (Add USE_BINARYBUILDER=0 to Make.user, see Building Julia)\nBuild from source (src/) with pre-compiled dependencies (default)","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"When you want to update the version number of a dependency in deps/, you may want to use the following checklist:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"### Check list\n\nVersion numbers:\n- [ ] `deps/$(libname).version`: `LIBNAME_VER`, `LIBNAME_BRANCH`, `LIBNAME_SHA1` and `LIBNAME_JLL_VER`\n- [ ] `stdlib/$(LIBNAME_JLL_NAME)_jll/Project.toml`: `version`\n\nChecksum:\n- [ ] `deps/checksums/$(libname)`\n- [ ] `deps/checksums/$(LIBNAME_JLL_NAME)-*/`: `md5` and `sha512`\n\nPatches:\n- [ ] `deps/$(libname).mk`\n- [ ] `deps/patches/$(libname)-*.patch`","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Note:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"For specific dependencies, some items in the checklist may not exist.\nFor checksum file, it may be a single file without a suffix, or a folder containing two files.","category":"page"},{"location":"devdocs/build/build/#Example:-OpenLibm","page":"Building Julia (Detailed)","title":"Example: OpenLibm","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Update Version numbers in deps/openlibm.version\nOPENLIBM_VER := 0.X.Y\nOPENLIBM_BRANCH = v0.X.Y\nOPENLIBM_SHA1 = new-sha1-hash\nUpdate Version number in stdlib/OpenLibm_jll/Project.toml\nversion = \"0.X.Y+0\"\nUpdate checksums in deps/checksums/openlibm\nmake -f contrib/refresh_checksums.mk openlibm\nCheck if the patch files deps/patches/openlibm-*.patch exist\nif patches don't exist, skip.\nif patches exist, check if they have been merged into the new version and need to be removed. When deleting a patch, remember to modify the corresponding Makefile file (deps/openlibm.mk).","category":"page"},{"location":"devdocs/build/freebsd/#FreeBSD","page":"FreeBSD","title":"FreeBSD","text":"","category":"section"},{"location":"devdocs/build/freebsd/","page":"FreeBSD","title":"FreeBSD","text":"Clang is the default compiler on FreeBSD 11.0-RELEASE and above. The remaining build tools are available from the Ports Collection, and can be installed using pkg install git gcc gmake cmake pkgconf. To build Julia, simply run gmake. (Note that gmake must be used rather than make, since make on FreeBSD corresponds to the incompatible BSD Make rather than GNU Make.)","category":"page"},{"location":"devdocs/build/freebsd/","page":"FreeBSD","title":"FreeBSD","text":"As mentioned above, it is important to note that the USE_SYSTEM_* flags should be used with caution on FreeBSD. This is because many system libraries, and even libraries from the Ports Collection, link to the system's libgcc_s.so.1, or to another library which links to the system libgcc_s. This library declares its GCC version to be 4.6, which is too old to build Julia, and conflicts with other libraries when linking. Thus it is highly recommended to simply allow Julia to build all of its dependencies. If you do choose to use the USE_SYSTEM_* flags, note that /usr/local is not on the compiler path by default, so you may need to add LDFLAGS=-L/usr/local/lib and CPPFLAGS=-I/usr/local/include to your Make.user, though doing so may interfere with other dependencies.","category":"page"},{"location":"devdocs/build/freebsd/","page":"FreeBSD","title":"FreeBSD","text":"Note that the x86 architecture does not support threading due to lack of compiler runtime library support, so you may need to set JULIA_THREADS=0 in your Make.user if you're on a 32-bit system.","category":"page"},{"location":"stdlib/Downloads/#Downloads","page":"Downloads","title":"Downloads","text":"","category":"section"},{"location":"stdlib/Downloads/","page":"Downloads","title":"Downloads","text":"Downloads.download\nDownloads.request\nDownloads.Response\nDownloads.RequestError\nDownloads.Downloader","category":"page"},{"location":"stdlib/Downloads/#Downloads.download","page":"Downloads","title":"Downloads.download","text":"download(url, [ output = tempname() ];\n [ method = \"GET\", ]\n [ headers = , ]\n [ timeout = , ]\n [ progress = , ]\n [ verbose = false, ]\n [ debug = , ]\n [ downloader = , ]\n) -> output\n\n url :: AbstractString\n output :: Union{AbstractString, AbstractCmd, IO}\n method :: AbstractString\n headers :: Union{AbstractVector, AbstractDict}\n timeout :: Real\n progress :: (total::Integer, now::Integer) --> Any\n verbose :: Bool\n debug :: (type, message) --> Any\n downloader :: Downloader\n\nDownload a file from the given url, saving it to output or if not specified, a temporary path. The output can also be an IO handle, in which case the body of the response is streamed to that handle and the handle is returned. If output is a command, the command is run and output is sent to it on stdin.\n\nIf the downloader keyword argument is provided, it must be a Downloader object. Resources and connections will be shared between downloads performed by the same Downloader and cleaned up automatically when the object is garbage collected or there have been no downloads performed with it for a grace period. See Downloader for more info about configuration and usage.\n\nIf the headers keyword argument is provided, it must be a vector or dictionary whose elements are all pairs of strings. These pairs are passed as headers when downloading URLs with protocols that supports them, such as HTTP/S.\n\nThe timeout keyword argument specifies a timeout for the download to complete in seconds, with a resolution of milliseconds. By default no timeout is set, but this can also be explicitly requested by passing a timeout value of Inf. Separately, if 20 seconds elapse without receiving any data, the download will timeout. See extended help for how to disable this timeout.\n\nIf the progress keyword argument is provided, it must be a callback function which will be called whenever there are updates about the size and status of the ongoing download. The callback must take two integer arguments: total and now which are the total size of the download in bytes, and the number of bytes which have been downloaded so far. Note that total starts out as zero and remains zero until the server gives an indication of the total size of the download (e.g. with a Content-Length header), which may never happen. So a well-behaved progress callback should handle a total size of zero gracefully.\n\nIf the verbose option is set to true, libcurl, which is used to implement the download functionality will print debugging information to stderr. If the debug option is set to a function accepting two String arguments, then the verbose option is ignored and instead the data that would have been printed to stderr is passed to the debug callback with type and message arguments. The type argument indicates what kind of event has occurred, and is one of: TEXT, HEADER IN, HEADER OUT, DATA IN, DATA OUT, SSL DATA IN or SSL DATA OUT. The message argument is the description of the debug event.\n\nExtended Help\n\nFor further customization, use a Downloader and easy_hooks. For example, to disable the 20 second timeout when no data is received, you may use the following:\n\ndownloader = Downloads.Downloader()\ndownloader.easy_hook = (easy, info) -> Downloads.Curl.setopt(easy, Downloads.Curl.CURLOPT_LOW_SPEED_TIME, 0)\n\nDownloads.download(\"https://httpbingo.julialang.org/delay/30\"; downloader)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Downloads/#Downloads.request","page":"Downloads","title":"Downloads.request","text":"request(url;\n [ input = , ]\n [ output = , ]\n [ method = input ? \"PUT\" : output ? \"GET\" : \"HEAD\", ]\n [ headers = , ]\n [ timeout = , ]\n [ progress = , ]\n [ verbose = false, ]\n [ debug = , ]\n [ throw = true, ]\n [ downloader = , ]\n) -> Union{Response, RequestError}\n\n url :: AbstractString\n input :: Union{AbstractString, AbstractCmd, IO}\n output :: Union{AbstractString, AbstractCmd, IO}\n method :: AbstractString\n headers :: Union{AbstractVector, AbstractDict}\n timeout :: Real\n progress :: (dl_total, dl_now, ul_total, ul_now) --> Any\n verbose :: Bool\n debug :: (type, message) --> Any\n throw :: Bool\n downloader :: Downloader\n\nMake a request to the given url, returning a Response object capturing the status, headers and other information about the response. The body of the response is written to output if specified and discarded otherwise. For HTTP/S requests, if an input stream is given, a PUT request is made; otherwise if an output stream is given, a GET request is made; if neither is given a HEAD request is made. For other protocols, appropriate default methods are used based on what combination of input and output are requested. The following options differ from the download function:\n\ninput allows providing a request body; if provided default to PUT request\nprogress is a callback taking four integers for upload and download progress\nthrow controls whether to throw or return a RequestError on request error\n\nNote that unlike download which throws an error if the requested URL could not be downloaded (indicated by non-2xx status code), request returns a Response object no matter what the status code of the response is. If there is an error with getting a response at all, then a RequestError is thrown or returned.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Downloads/#Downloads.Response","page":"Downloads","title":"Downloads.Response","text":"struct Response\n proto :: String\n url :: String\n status :: Int\n message :: String\n headers :: Vector{Pair{String,String}}\nend\n\nResponse is a type capturing the properties of a successful response to a request as an object. It has the following fields:\n\nproto: the protocol that was used to get the response\nurl: the URL that was ultimately requested after following redirects\nstatus: the status code of the response, indicating success, failure, etc.\nmessage: a textual message describing the nature of the response\nheaders: any headers that were returned with the response\n\nThe meaning and availability of some of these responses depends on the protocol used for the request. For many protocols, including HTTP/S and S/FTP, a 2xx status code indicates a successful response. For responses in protocols that do not support headers, the headers vector will be empty. HTTP/2 does not include a status message, only a status code, so the message will be empty.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Downloads/#Downloads.RequestError","page":"Downloads","title":"Downloads.RequestError","text":"struct RequestError <: ErrorException\n url :: String\n code :: Int\n message :: String\n response :: Response\nend\n\nRequestError is a type capturing the properties of a failed response to a request as an exception object:\n\nurl: the original URL that was requested without any redirects\ncode: the libcurl error code; 0 if a protocol-only error occurred\nmessage: the libcurl error message indicating what went wrong\nresponse: response object capturing what response info is available\n\nThe same RequestError type is thrown by download if the request was successful but there was a protocol-level error indicated by a status code that is not in the 2xx range, in which case code will be zero and the message field will be the empty string. The request API only throws a RequestError if the libcurl error code is non-zero, in which case the included response object is likely to have a status of zero and an empty message. There are, however, situations where a curl-level error is thrown due to a protocol error, in which case both the inner and outer code and message may be of interest.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Downloads/#Downloads.Downloader","page":"Downloads","title":"Downloads.Downloader","text":"Downloader(; [ grace::Real = 30 ])\n\nDownloader objects are used to perform individual download operations. Connections, name lookups and other resources are shared within a Downloader. These connections and resources are cleaned up after a configurable grace period (default: 30 seconds) since anything was downloaded with it, or when it is garbage collected, whichever comes first. If the grace period is set to zero, all resources will be cleaned up immediately as soon as there are no more ongoing downloads in progress. If the grace period is set to Inf then resources are not cleaned up until Downloader is garbage collected.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Random/docs/src/index.md\"","category":"page"},{"location":"stdlib/Random/#Random-Numbers","page":"Random Numbers","title":"Random Numbers","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"DocTestSetup = :(using Random)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random number generation in Julia uses the Xoshiro256++ algorithm by default, with per-Task state. Other RNG types can be plugged in by inheriting the AbstractRNG type; they can then be used to obtain multiple streams of random numbers.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The PRNGs (pseudorandom number generators) exported by the Random package are:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"TaskLocalRNG: a token that represents use of the currently active Task-local stream, deterministically seeded from the parent task, or by RandomDevice (with system randomness) at program start\nXoshiro: generates a high-quality stream of random numbers with a small state vector and high performance using the Xoshiro256++ algorithm\nRandomDevice: for OS-provided entropy. This may be used for cryptographically secure random numbers (CS(P)RNG).\nMersenneTwister: an alternate high-quality PRNG which was the default in older versions of Julia, and is also quite fast, but requires much more space to store the state vector and generate a random sequence.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Most functions related to random generation accept an optional AbstractRNG object as first argument. Some also accept dimension specifications dims... (which can also be given as a tuple) to generate arrays of random values. In a multi-threaded program, you should generally use different RNG objects from different threads or tasks in order to be thread-safe. However, the default RNG is thread-safe as of Julia 1.3 (using a per-thread RNG up to version 1.6, and per-task thereafter).","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The provided RNGs can generate uniform random numbers of the following types: Float16, Float32, Float64, BigFloat, Bool, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, BigInt (or complex numbers of those types). Random floating point numbers are generated uniformly in 0 1). As BigInt represents unbounded integers, the interval must be specified (e.g. rand(big.(1:6))).","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Additionally, normal and exponential distributions are implemented for some AbstractFloat and Complex types, see randn and randexp for details.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"To generate random numbers from other distributions, see the Distributions.jl package.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"warning: Warning\nBecause the precise way in which random numbers are generated is considered an implementation detail, bug fixes and speed improvements may change the stream of numbers that are generated after a version change. Relying on a specific seed or generated stream of numbers during unit testing is thus discouraged - consider testing properties of the methods in question instead.","category":"page"},{"location":"stdlib/Random/#Random-numbers-module","page":"Random Numbers","title":"Random numbers module","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.Random","category":"page"},{"location":"stdlib/Random/#Random.Random","page":"Random Numbers","title":"Random.Random","text":"Random\n\nSupport for generating random numbers. Provides rand, randn, AbstractRNG, Xoshiro, MersenneTwister, and RandomDevice.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Random/#Random-generation-functions","page":"Random Numbers","title":"Random generation functions","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.rand\nRandom.rand!\nRandom.bitrand\nRandom.randn\nRandom.randn!\nRandom.randexp\nRandom.randexp!\nRandom.randstring","category":"page"},{"location":"stdlib/Random/#Base.rand","page":"Random Numbers","title":"Base.rand","text":"rand([rng=default_rng()], [S], [dims...])\n\nPick a random element or array of random elements from the set of values specified by S; S can be\n\nan indexable collection (for example 1:9 or ('x', \"y\", :z))\nan AbstractDict or AbstractSet object\na string (considered as a collection of characters), or\na type from the list below, corresponding to the specified set of values\nconcrete integer types sample from typemin(S):typemax(S) (excepting BigInt which is not supported)\nconcrete floating point types sample from [0, 1)\nconcrete complex types Complex{T} if T is a sampleable type take their real and imaginary components independently from the set of values corresponding to T, but are not supported if T is not sampleable.\nall <:AbstractChar types sample from the set of valid Unicode scalars\na user-defined type and set of values; for implementation guidance please see Hooking into the Random API\na tuple type of known size and where each parameter of S is itself a sampleable type; return a value of type S. Note that tuple types such as Tuple{Vararg{T}} (unknown size) and Tuple{1:2} (parameterized with a value) are not supported\na Pair type, e.g. Pair{X, Y} such that rand is defined for X and Y, in which case random pairs are produced.\n\nS defaults to Float64. When only one argument is passed besides the optional rng and is a Tuple, it is interpreted as a collection of values (S) and not as dims.\n\nSee also randn for normally distributed numbers, and rand! and randn! for the in-place equivalents.\n\ncompat: Julia 1.1\nSupport for S as a tuple requires at least Julia 1.1.\n\ncompat: Julia 1.11\nSupport for S as a Tuple type requires at least Julia 1.11.\n\nExamples\n\njulia> rand(Int, 2)\n2-element Array{Int64,1}:\n 1339893410598768192\n 1575814717733606317\n\njulia> using Random\n\njulia> rand(Xoshiro(0), Dict(1=>2, 3=>4))\n3 => 4\n\njulia> rand((2, 3))\n3\n\njulia> rand(Float64, (2, 3))\n2×3 Array{Float64,2}:\n 0.999717 0.0143835 0.540787\n 0.696556 0.783855 0.938235\n\nnote: Note\nThe complexity of rand(rng, s::Union{AbstractDict,AbstractSet}) is linear in the length of s, unless an optimized method with constant complexity is available, which is the case for Dict, Set and dense BitSets. For more than a few calls, use rand(rng, collect(s)) instead, or either rand(rng, Dict(s)) or rand(rng, Set(s)) as appropriate.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.rand!","page":"Random Numbers","title":"Random.rand!","text":"rand!([rng=default_rng()], A, [S=eltype(A)])\n\nPopulate the array A with random values. If S is specified (S can be a type or a collection, cf. rand for details), the values are picked randomly from S. This is equivalent to copyto!(A, rand(rng, S, size(A))) but without allocating a new array.\n\nExamples\n\njulia> rand!(Xoshiro(123), zeros(5))\n5-element Vector{Float64}:\n 0.521213795535383\n 0.5868067574533484\n 0.8908786980927811\n 0.19090669902576285\n 0.5256623915420473\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.bitrand","page":"Random Numbers","title":"Random.bitrand","text":"bitrand([rng=default_rng()], [dims...])\n\nGenerate a BitArray of random boolean values.\n\nExamples\n\njulia> bitrand(Xoshiro(123), 10)\n10-element BitVector:\n 0\n 1\n 0\n 1\n 0\n 1\n 0\n 0\n 1\n 1\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Base.randn","page":"Random Numbers","title":"Base.randn","text":"randn([rng=default_rng()], [T=Float64], [dims...])\n\nGenerate a normally-distributed random number of type T with mean 0 and standard deviation 1. Given the optional dims argument(s), generate an array of size dims of such numbers. Julia's standard library supports randn for any floating-point type that implements rand, e.g. the Base types Float16, Float32, Float64 (the default), and BigFloat, along with their Complex counterparts.\n\n(When T is complex, the values are drawn from the circularly symmetric complex normal distribution of variance 1, corresponding to real and imaginary parts having independent normal distribution with mean zero and variance 1/2).\n\nSee also randn! to act in-place.\n\nExamples\n\nGenerating a single random number (with the default Float64 type):\n\njulia> randn()\n-0.942481877315864\n\nGenerating a matrix of normal random numbers (with the default Float64 type):\n\njulia> randn(2,3)\n2×3 Matrix{Float64}:\n 1.18786 -0.678616 1.49463\n -0.342792 -0.134299 -1.45005\n\nSetting up of the random number generator rng with a user-defined seed (for reproducible numbers) and using it to generate a random Float32 number or a matrix of ComplexF32 random numbers:\n\njulia> using Random\n\njulia> rng = Xoshiro(123);\n\njulia> randn(rng, Float32)\n-0.6457307f0\n\njulia> randn(rng, ComplexF32, (2, 3))\n2×3 Matrix{ComplexF32}:\n -1.03467-1.14806im 0.693657+0.056538im 0.291442+0.419454im\n -0.153912+0.34807im 1.0954-0.948661im -0.543347-0.0538589im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randn!","page":"Random Numbers","title":"Random.randn!","text":"randn!([rng=default_rng()], A::AbstractArray) -> A\n\nFill the array A with normally-distributed (mean 0, standard deviation 1) random numbers. Also see the rand function.\n\nExamples\n\njulia> randn!(Xoshiro(123), zeros(5))\n5-element Vector{Float64}:\n -0.6457306721039767\n -1.4632513788889214\n -1.6236037455860806\n -0.21766510678354617\n 0.4922456865251828\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randexp","page":"Random Numbers","title":"Random.randexp","text":"randexp([rng=default_rng()], [T=Float64], [dims...])\n\nGenerate a random number of type T according to the exponential distribution with scale 1. Optionally generate an array of such random numbers. The Base module currently provides an implementation for the types Float16, Float32, and Float64 (the default).\n\nExamples\n\njulia> rng = Xoshiro(123);\n\njulia> randexp(rng, Float32)\n1.1757717f0\n\njulia> randexp(rng, 3, 3)\n3×3 Matrix{Float64}:\n 1.37766 0.456653 0.236418\n 3.40007 0.229917 0.0684921\n 0.48096 0.577481 0.71835\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randexp!","page":"Random Numbers","title":"Random.randexp!","text":"randexp!([rng=default_rng()], A::AbstractArray) -> A\n\nFill the array A with random numbers following the exponential distribution (with scale 1).\n\nExamples\n\njulia> randexp!(Xoshiro(123), zeros(5))\n5-element Vector{Float64}:\n 1.1757716836348473\n 1.758884569451514\n 1.0083623637301151\n 0.3510644315565272\n 0.6348266443720407\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randstring","page":"Random Numbers","title":"Random.randstring","text":"randstring([rng=default_rng()], [chars], [len=8])\n\nCreate a random string of length len, consisting of characters from chars, which defaults to the set of upper- and lower-case letters and the digits 0-9. The optional rng argument specifies a random number generator, see Random Numbers.\n\nExamples\n\njulia> Random.seed!(3); randstring()\n\"Lxz5hUwn\"\n\njulia> randstring(Xoshiro(3), 'a':'z', 6)\n\"iyzcsm\"\n\njulia> randstring(\"ACGT\")\n\"TGCTCCTC\"\n\nnote: Note\nchars can be any collection of characters, of type Char or UInt8 (more efficient), provided rand can randomly pick characters from it.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Subsequences,-permutations-and-shuffling","page":"Random Numbers","title":"Subsequences, permutations and shuffling","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.randsubseq\nRandom.randsubseq!\nRandom.randperm\nRandom.randperm!\nRandom.randcycle\nRandom.randcycle!\nRandom.shuffle\nRandom.shuffle!","category":"page"},{"location":"stdlib/Random/#Random.randsubseq","page":"Random Numbers","title":"Random.randsubseq","text":"randsubseq([rng=default_rng(),] A, p) -> Vector\n\nReturn a vector consisting of a random subsequence of the given array A, where each element of A is included (in order) with independent probability p. (Complexity is linear in p*length(A), so this function is efficient even if p is small and A is large.) Technically, this process is known as \"Bernoulli sampling\" of A.\n\nExamples\n\njulia> randsubseq(Xoshiro(123), 1:8, 0.3)\n2-element Vector{Int64}:\n 4\n 7\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randsubseq!","page":"Random Numbers","title":"Random.randsubseq!","text":"randsubseq!([rng=default_rng(),] S, A, p)\n\nLike randsubseq, but the results are stored in S (which is resized as needed).\n\nExamples\n\njulia> S = Int64[];\n\njulia> randsubseq!(Xoshiro(123), S, 1:8, 0.3)\n2-element Vector{Int64}:\n 4\n 7\n\njulia> S\n2-element Vector{Int64}:\n 4\n 7\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randperm","page":"Random Numbers","title":"Random.randperm","text":"randperm([rng=default_rng(),] n::Integer)\n\nConstruct a random permutation of length n. The optional rng argument specifies a random number generator (see Random Numbers). The element type of the result is the same as the type of n.\n\nTo randomly permute an arbitrary vector, see shuffle or shuffle!.\n\ncompat: Julia 1.1\nIn Julia 1.1 randperm returns a vector v with eltype(v) == typeof(n) while in Julia 1.0 eltype(v) == Int.\n\nExamples\n\njulia> randperm(Xoshiro(123), 4)\n4-element Vector{Int64}:\n 1\n 4\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randperm!","page":"Random Numbers","title":"Random.randperm!","text":"randperm!([rng=default_rng(),] A::Array{<:Integer})\n\nConstruct in A a random permutation of length length(A). The optional rng argument specifies a random number generator (see Random Numbers). To randomly permute an arbitrary vector, see shuffle or shuffle!.\n\nExamples\n\njulia> randperm!(Xoshiro(123), Vector{Int}(undef, 4))\n4-element Vector{Int64}:\n 1\n 4\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randcycle","page":"Random Numbers","title":"Random.randcycle","text":"randcycle([rng=default_rng(),] n::Integer)\n\nConstruct a random cyclic permutation of length n. The optional rng argument specifies a random number generator, see Random Numbers. The element type of the result is the same as the type of n.\n\nHere, a \"cyclic permutation\" means that all of the elements lie within a single cycle. If n > 0, there are (n-1) possible cyclic permutations, which are sampled uniformly. If n == 0, randcycle returns an empty vector.\n\nrandcycle! is an in-place variant of this function.\n\ncompat: Julia 1.1\nIn Julia 1.1 and above, randcycle returns a vector v with eltype(v) == typeof(n) while in Julia 1.0 eltype(v) == Int.\n\nExamples\n\njulia> randcycle(Xoshiro(123), 6)\n6-element Vector{Int64}:\n 5\n 4\n 2\n 6\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randcycle!","page":"Random Numbers","title":"Random.randcycle!","text":"randcycle!([rng=default_rng(),] A::Array{<:Integer})\n\nConstruct in A a random cyclic permutation of length n = length(A). The optional rng argument specifies a random number generator, see Random Numbers.\n\nHere, a \"cyclic permutation\" means that all of the elements lie within a single cycle. If A is nonempty (n > 0), there are (n-1) possible cyclic permutations, which are sampled uniformly. If A is empty, randcycle! leaves it unchanged.\n\nrandcycle is a variant of this function that allocates a new vector.\n\nExamples\n\njulia> randcycle!(Xoshiro(123), Vector{Int}(undef, 6))\n6-element Vector{Int64}:\n 5\n 4\n 2\n 6\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.shuffle","page":"Random Numbers","title":"Random.shuffle","text":"shuffle([rng=default_rng(),] v::AbstractArray)\n\nReturn a randomly permuted copy of v. The optional rng argument specifies a random number generator (see Random Numbers). To permute v in-place, see shuffle!. To obtain randomly permuted indices, see randperm.\n\nExamples\n\njulia> shuffle(Xoshiro(123), Vector(1:10))\n10-element Vector{Int64}:\n 5\n 4\n 2\n 3\n 6\n 10\n 8\n 1\n 9\n 7\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.shuffle!","page":"Random Numbers","title":"Random.shuffle!","text":"shuffle!([rng=default_rng(),] v::AbstractArray)\n\nIn-place version of shuffle: randomly permute v in-place, optionally supplying the random-number generator rng.\n\nExamples\n\njulia> shuffle!(Xoshiro(123), Vector(1:10))\n10-element Vector{Int64}:\n 5\n 4\n 2\n 3\n 6\n 10\n 8\n 1\n 9\n 7\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Generators-(creation-and-seeding)","page":"Random Numbers","title":"Generators (creation and seeding)","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.default_rng\nRandom.seed!\nRandom.AbstractRNG\nRandom.TaskLocalRNG\nRandom.Xoshiro\nRandom.MersenneTwister\nRandom.RandomDevice","category":"page"},{"location":"stdlib/Random/#Random.default_rng","page":"Random Numbers","title":"Random.default_rng","text":"Random.default_rng() -> rng\n\nReturn the default global random number generator (RNG), which is used by rand-related functions when no explicit RNG is provided.\n\nWhen the Random module is loaded, the default RNG is randomly seeded, via Random.seed!(): this means that each time a new julia session is started, the first call to rand() produces a different result, unless seed!(seed) is called first.\n\nIt is thread-safe: distinct threads can safely call rand-related functions on default_rng() concurrently, e.g. rand(default_rng()).\n\nnote: Note\nThe type of the default RNG is an implementation detail. Across different versions of Julia, you should not expect the default RNG to always have the same type, nor that it will produce the same stream of random numbers for a given seed.\n\ncompat: Julia 1.3\nThis function was introduced in Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.seed!","page":"Random Numbers","title":"Random.seed!","text":"seed!([rng=default_rng()], seed) -> rng\nseed!([rng=default_rng()]) -> rng\n\nReseed the random number generator: rng will give a reproducible sequence of numbers if and only if a seed is provided. Some RNGs don't accept a seed, like RandomDevice. After the call to seed!, rng is equivalent to a newly created object initialized with the same seed. The types of accepted seeds depend on the type of rng, but in general, integer seeds should work.\n\nIf rng is not specified, it defaults to seeding the state of the shared task-local generator.\n\nExamples\n\njulia> Random.seed!(1234);\n\njulia> x1 = rand(2)\n2-element Vector{Float64}:\n 0.32597672886359486\n 0.5490511363155669\n\njulia> Random.seed!(1234);\n\njulia> x2 = rand(2)\n2-element Vector{Float64}:\n 0.32597672886359486\n 0.5490511363155669\n\njulia> x1 == x2\ntrue\n\njulia> rng = Xoshiro(1234); rand(rng, 2) == x1\ntrue\n\njulia> Xoshiro(1) == Random.seed!(rng, 1)\ntrue\n\njulia> rand(Random.seed!(rng), Bool) # not reproducible\ntrue\n\njulia> rand(Random.seed!(rng), Bool) # not reproducible either\nfalse\n\njulia> rand(Xoshiro(), Bool) # not reproducible either\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.AbstractRNG","page":"Random Numbers","title":"Random.AbstractRNG","text":"AbstractRNG\n\nSupertype for random number generators such as MersenneTwister and RandomDevice.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.TaskLocalRNG","page":"Random Numbers","title":"Random.TaskLocalRNG","text":"TaskLocalRNG\n\nThe TaskLocalRNG has state that is local to its task, not its thread. It is seeded upon task creation, from the state of its parent task. Therefore, task creation is an event that changes the parent's RNG state.\n\nAs an upside, the TaskLocalRNG is pretty fast, and permits reproducible multithreaded simulations (barring race conditions), independent of scheduler decisions. As long as the number of threads is not used to make decisions on task creation, simulation results are also independent of the number of available threads / CPUs. The random stream should not depend on hardware specifics, up to endianness and possibly word size.\n\nUsing or seeding the RNG of any other task than the one returned by current_task() is undefined behavior: it will work most of the time, and may sometimes fail silently.\n\nWhen seeding TaskLocalRNG() with seed!, the passed seed, if any, may be any integer.\n\ncompat: Julia 1.11\nSeeding TaskLocalRNG() with a negative integer seed requires at least Julia 1.11.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.Xoshiro","page":"Random Numbers","title":"Random.Xoshiro","text":"Xoshiro(seed::Union{Integer, AbstractString})\nXoshiro()\n\nXoshiro256++ is a fast pseudorandom number generator described by David Blackman and Sebastiano Vigna in \"Scrambled Linear Pseudorandom Number Generators\", ACM Trans. Math. Softw., 2021. Reference implementation is available at https://prng.di.unimi.it\n\nApart from the high speed, Xoshiro has a small memory footprint, making it suitable for applications where many different random states need to be held for long time.\n\nJulia's Xoshiro implementation has a bulk-generation mode; this seeds new virtual PRNGs from the parent, and uses SIMD to generate in parallel (i.e. the bulk stream consists of multiple interleaved xoshiro instances). The virtual PRNGs are discarded once the bulk request has been serviced (and should cause no heap allocations).\n\nIf no seed is provided, a randomly generated one is created (using entropy from the system). See the seed! function for reseeding an already existing Xoshiro object.\n\ncompat: Julia 1.11\nPassing a negative integer seed requires at least Julia 1.11.\n\nExamples\n\njulia> using Random\n\njulia> rng = Xoshiro(1234);\n\njulia> x1 = rand(rng, 2)\n2-element Vector{Float64}:\n 0.32597672886359486\n 0.5490511363155669\n\njulia> rng = Xoshiro(1234);\n\njulia> x2 = rand(rng, 2)\n2-element Vector{Float64}:\n 0.32597672886359486\n 0.5490511363155669\n\njulia> x1 == x2\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.MersenneTwister","page":"Random Numbers","title":"Random.MersenneTwister","text":"MersenneTwister(seed)\nMersenneTwister()\n\nCreate a MersenneTwister RNG object. Different RNG objects can have their own seeds, which may be useful for generating different streams of random numbers. The seed may be an integer, a string, or a vector of UInt32 integers. If no seed is provided, a randomly generated one is created (using entropy from the system). See the seed! function for reseeding an already existing MersenneTwister object.\n\ncompat: Julia 1.11\nPassing a negative integer seed requires at least Julia 1.11.\n\nExamples\n\njulia> rng = MersenneTwister(123);\n\njulia> x1 = rand(rng, 2)\n2-element Vector{Float64}:\n 0.37453777969575874\n 0.8735343642013971\n\njulia> x2 = rand(MersenneTwister(123), 2)\n2-element Vector{Float64}:\n 0.37453777969575874\n 0.8735343642013971\n\njulia> x1 == x2\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.RandomDevice","page":"Random Numbers","title":"Random.RandomDevice","text":"RandomDevice()\n\nCreate a RandomDevice RNG object. Two such objects will always generate different streams of random numbers. The entropy is obtained from the operating system.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#rand-api-hook","page":"Random Numbers","title":"Hooking into the Random API","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"There are two mostly orthogonal ways to extend Random functionalities:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"generating random values of custom types\ncreating new generators","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The API for 1) is quite functional, but is relatively recent so it may still have to evolve in subsequent releases of the Random module. For example, it's typically sufficient to implement one rand method in order to have all other usual methods work automatically.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The API for 2) is still rudimentary, and may require more work than strictly necessary from the implementer, in order to support usual types of generated values.","category":"page"},{"location":"stdlib/Random/#Generating-random-values-of-custom-types","page":"Random Numbers","title":"Generating random values of custom types","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Generating random values for some distributions may involve various trade-offs. Pre-computed values, such as an alias table for discrete distributions, or “squeezing” functions for univariate distributions, can speed up sampling considerably. How much information should be pre-computed can depend on the number of values we plan to draw from a distribution. Also, some random number generators can have certain properties that various algorithms may want to exploit.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The Random module defines a customizable framework for obtaining random values that can address these issues. Each invocation of rand generates a sampler which can be customized with the above trade-offs in mind, by adding methods to Sampler, which in turn can dispatch on the random number generator, the object that characterizes the distribution, and a suggestion for the number of repetitions. Currently, for the latter, Val{1} (for a single sample) and Val{Inf} (for an arbitrary number) are used, with Random.Repetition an alias for both.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The object returned by Sampler is then used to generate the random values. When implementing the random generation interface for a value X that can be sampled from, the implementer should define the method","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"rand(rng, sampler)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"for the particular sampler returned by Sampler(rng, X, repetition).","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Samplers can be arbitrary values that implement rand(rng, sampler), but for most applications the following predefined samplers may be sufficient:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"SamplerType{T}() can be used for implementing samplers that draw from type T (e.g. rand(Int)). This is the default returned by Sampler for types.\nSamplerTrivial(self) is a simple wrapper for self, which can be accessed with []. This is the recommended sampler when no pre-computed information is needed (e.g. rand(1:3)), and is the default returned by Sampler for values.\nSamplerSimple(self, data) also contains the additional data field, which can be used to store arbitrary pre-computed values, which should be computed in a custom method of Sampler.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"We provide examples for each of these. We assume here that the choice of algorithm is independent of the RNG, so we use AbstractRNG in our signatures.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.Sampler\nRandom.SamplerType\nRandom.SamplerTrivial\nRandom.SamplerSimple","category":"page"},{"location":"stdlib/Random/#Random.Sampler","page":"Random Numbers","title":"Random.Sampler","text":"Sampler(rng, x, repetition = Val(Inf))\n\nReturn a sampler object that can be used to generate random values from rng for x.\n\nWhen sp = Sampler(rng, x, repetition), rand(rng, sp) will be used to draw random values, and should be defined accordingly.\n\nrepetition can be Val(1) or Val(Inf), and should be used as a suggestion for deciding the amount of precomputation, if applicable.\n\nRandom.SamplerType and Random.SamplerTrivial are default fallbacks for types and values, respectively. Random.SamplerSimple can be used to store pre-computed values without defining extra types for only this purpose.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.SamplerType","page":"Random Numbers","title":"Random.SamplerType","text":"SamplerType{T}()\n\nA sampler for types, containing no other information. The default fallback for Sampler when called with types.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.SamplerTrivial","page":"Random Numbers","title":"Random.SamplerTrivial","text":"SamplerTrivial(x)\n\nCreate a sampler that just wraps the given value x. This is the default fall-back for values. The eltype of this sampler is equal to eltype(x).\n\nThe recommended use case is sampling from values without precomputed data.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.SamplerSimple","page":"Random Numbers","title":"Random.SamplerSimple","text":"SamplerSimple(x, data)\n\nCreate a sampler that wraps the given value x and the data. The eltype of this sampler is equal to eltype(x).\n\nThe recommended use case is sampling from values with precomputed data.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Decoupling pre-computation from actually generating the values is part of the API, and is also available to the user. As an example, assume that rand(rng, 1:20) has to be called repeatedly in a loop: the way to take advantage of this decoupling is as follows:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"rng = Xoshiro()\nsp = Random.Sampler(rng, 1:20) # or Random.Sampler(Xoshiro, 1:20)\nfor x in X\n n = rand(rng, sp) # similar to n = rand(rng, 1:20)\n # use n\nend","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"This is the mechanism that is also used in the standard library, e.g. by the default implementation of random array generation (like in rand(1:20, 10)).","category":"page"},{"location":"stdlib/Random/#Generating-values-from-a-type","page":"Random Numbers","title":"Generating values from a type","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Given a type T, it's currently assumed that if rand(T) is defined, an object of type T will be produced. SamplerType is the default sampler for types. In order to define random generation of values of type T, the rand(rng::AbstractRNG, ::Random.SamplerType{T}) method should be defined, and should return values what rand(rng, T) is expected to return.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Let's take the following example: we implement a Die type, with a variable number n of sides, numbered from 1 to n. We want rand(Die) to produce a Die with a random number of up to 20 sides (and at least 4):","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"struct Die\n nsides::Int # number of sides\nend\n\nRandom.rand(rng::AbstractRNG, ::Random.SamplerType{Die}) = Die(rand(rng, 4:20))\n\n# output\n","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Scalar and array methods for Die now work as expected:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"julia> rand(Die)\nDie(5)\n\njulia> rand(Xoshiro(0), Die)\nDie(10)\n\njulia> rand(Die, 3)\n3-element Vector{Die}:\n Die(9)\n Die(15)\n Die(14)\n\njulia> a = Vector{Die}(undef, 3); rand!(a)\n3-element Vector{Die}:\n Die(19)\n Die(7)\n Die(17)","category":"page"},{"location":"stdlib/Random/#A-simple-sampler-without-pre-computed-data","page":"Random Numbers","title":"A simple sampler without pre-computed data","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Here we define a sampler for a collection. If no pre-computed data is required, it can be implemented with a SamplerTrivial sampler, which is in fact the default fallback for values.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"In order to define random generation out of objects of type S, the following method should be defined: rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S}). Here, sp simply wraps an object of type S, which can be accessed via sp[]. Continuing the Die example, we want now to define rand(d::Die) to produce an Int corresponding to one of d's sides:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"julia> Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides);\n\njulia> rand(Die(4))\n1\n\njulia> rand(Die(4), 3)\n3-element Vector{Any}:\n 2\n 3\n 3","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Given a collection type S, it's currently assumed that if rand(::S) is defined, an object of type eltype(S) will be produced. In the last example, a Vector{Any} is produced; the reason is that eltype(Die) == Any. The remedy is to define Base.eltype(::Type{Die}) = Int.","category":"page"},{"location":"stdlib/Random/#Generating-values-for-an-AbstractFloat-type","page":"Random Numbers","title":"Generating values for an AbstractFloat type","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"AbstractFloat types are special-cased, because by default random values are not produced in the whole type domain, but rather in [0,1). The following method should be implemented for T <: AbstractFloat: Random.rand(::AbstractRNG, ::Random.SamplerTrivial{Random.CloseOpen01{T}})","category":"page"},{"location":"stdlib/Random/#An-optimized-sampler-with-pre-computed-data","page":"Random Numbers","title":"An optimized sampler with pre-computed data","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Consider a discrete distribution, where numbers 1:n are drawn with given probabilities that sum to one. When many values are needed from this distribution, the fastest method is using an alias table. We don't provide the algorithm for building such a table here, but suppose it is available in make_alias_table(probabilities) instead, and draw_number(rng, alias_table) can be used to draw a random number from it.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Suppose that the distribution is described by","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"struct DiscreteDistribution{V <: AbstractVector}\n probabilities::V\nend","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"and that we always want to build an alias table, regardless of the number of values needed (we learn how to customize this below). The methods","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.eltype(::Type{<:DiscreteDistribution}) = Int\n\nfunction Random.Sampler(::Type{<:AbstractRNG}, distribution::DiscreteDistribution, ::Repetition)\n SamplerSimple(distribution, make_alias_table(distribution.probabilities))\nend","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"should be defined to return a sampler with pre-computed data, then","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"function rand(rng::AbstractRNG, sp::SamplerSimple{<:DiscreteDistribution})\n draw_number(rng, sp.data)\nend","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"will be used to draw the values.","category":"page"},{"location":"stdlib/Random/#Custom-sampler-types","page":"Random Numbers","title":"Custom sampler types","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The SamplerSimple type is sufficient for most use cases with precomputed data. However, in order to demonstrate how to use custom sampler types, here we implement something similar to SamplerSimple.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Going back to our Die example: rand(::Die) uses random generation from a range, so there is an opportunity for this optimization. We call our custom sampler SamplerDie.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"import Random: Sampler, rand\n\nstruct SamplerDie <: Sampler{Int} # generates values of type Int\n die::Die\n sp::Sampler{Int} # this is an abstract type, so this could be improved\nend\n\nSampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) =\n SamplerDie(die, Sampler(RNG, 1:die.nsides, r))\n# the `r` parameter will be explained later on\n\nrand(rng::AbstractRNG, sp::SamplerDie) = rand(rng, sp.sp)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"It's now possible to get a sampler with sp = Sampler(rng, die), and use sp instead of die in any rand call involving rng. In the simplistic example above, die doesn't need to be stored in SamplerDie but this is often the case in practice.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Of course, this pattern is so frequent that the helper type used above, namely Random.SamplerSimple, is available, saving us the definition of SamplerDie: we could have implemented our decoupling with:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Sampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) =\n SamplerSimple(die, Sampler(RNG, 1:die.nsides, r))\n\nrand(rng::AbstractRNG, sp::SamplerSimple{Die}) = rand(rng, sp.data)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Here, sp.data refers to the second parameter in the call to the SamplerSimple constructor (in this case equal to Sampler(rng, 1:die.nsides, r)), while the Die object can be accessed via sp[].","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Like SamplerDie, any custom sampler must be a subtype of Sampler{T} where T is the type of the generated values. Note that SamplerSimple(x, data) isa Sampler{eltype(x)}, so this constrains what the first argument to SamplerSimple can be (it's recommended to use SamplerSimple like in the Die example, where x is simply forwarded while defining a Sampler method). Similarly, SamplerTrivial(x) isa Sampler{eltype(x)}.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Another helper type is currently available for other cases, Random.SamplerTag, but is considered as internal API, and can break at any time without proper deprecations.","category":"page"},{"location":"stdlib/Random/#Using-distinct-algorithms-for-scalar-or-array-generation","page":"Random Numbers","title":"Using distinct algorithms for scalar or array generation","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"In some cases, whether one wants to generate only a handful of values or a large number of values will have an impact on the choice of algorithm. This is handled with the third parameter of the Sampler constructor. Let's assume we defined two helper types for Die, say SamplerDie1 which should be used to generate only few random values, and SamplerDieMany for many values. We can use those types as follows:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{1}) = SamplerDie1(...)\nSampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{Inf}) = SamplerDieMany(...)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Of course, rand must also be defined on those types (i.e. rand(::AbstractRNG, ::SamplerDie1) and rand(::AbstractRNG, ::SamplerDieMany)). Note that, as usual, SamplerTrivial and SamplerSimple can be used if custom types are not necessary.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Note: Sampler(rng, x) is simply a shorthand for Sampler(rng, x, Val(Inf)), and Random.Repetition is an alias for Union{Val{1}, Val{Inf}}.","category":"page"},{"location":"stdlib/Random/#Creating-new-generators","page":"Random Numbers","title":"Creating new generators","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The API is not clearly defined yet, but as a rule of thumb:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"any rand method producing \"basic\" types (isbitstype integer and floating types in Base) should be defined for this specific RNG, if they are needed;\nother documented rand methods accepting an AbstractRNG should work out of the box, (provided the methods from 1) what are relied on are implemented), but can of course be specialized for this RNG if there is room for optimization;\ncopy for pseudo-RNGs should return an independent copy that generates the exact same random sequence as the original from that point when called in the same way. When this is not feasible (e.g. hardware-based RNGs), copy must not be implemented.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Concerning 1), a rand method may happen to work automatically, but it's not officially supported and may break without warnings in a subsequent release.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"To define a new rand method for an hypothetical MyRNG generator, and a value specification s (e.g. s == Int, or s == 1:10) of type S==typeof(s) or S==Type{s} if s is a type, the same two methods as we saw before must be defined:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Sampler(::Type{MyRNG}, ::S, ::Repetition), which returns an object of type say SamplerS\nrand(rng::MyRNG, sp::SamplerS)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"It can happen that Sampler(rng::AbstractRNG, ::S, ::Repetition) is already defined in the Random module. It would then be possible to skip step 1) in practice (if one wants to specialize generation for this particular RNG type), but the corresponding SamplerS type is considered as internal detail, and may be changed without warning.","category":"page"},{"location":"stdlib/Random/#Specializing-array-generation","page":"Random Numbers","title":"Specializing array generation","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"In some cases, for a given RNG type, generating an array of random values can be more efficient with a specialized method than by merely using the decoupling technique explained before. This is for example the case for MersenneTwister, which natively writes random values in an array.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"To implement this specialization for MyRNG and for a specification s, producing elements of type S, the following method can be defined: rand!(rng::MyRNG, a::AbstractArray{S}, ::SamplerS), where SamplerS is the type of the sampler returned by Sampler(MyRNG, s, Val(Inf)). Instead of AbstractArray, it's possible to implement the functionality only for a subtype, e.g. Array{S}. The non-mutating array method of rand will automatically call this specialization internally.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/Random/#Reproducibility","page":"Random Numbers","title":"Reproducibility","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"By using an RNG parameter initialized with a given seed, you can reproduce the same pseudorandom number sequence when running your program multiple times. However, a minor release of Julia (e.g. 1.3 to 1.4) may change the sequence of pseudorandom numbers generated from a specific seed, in particular if MersenneTwister is used. (Even if the sequence produced by a low-level function like rand does not change, the output of higher-level functions like randsubseq may change due to algorithm updates.) Rationale: guaranteeing that pseudorandom streams never change prohibits many algorithmic improvements.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"If you need to guarantee exact reproducibility of random data, it is advisable to simply save the data (e.g. as a supplementary attachment in a scientific publication). (You can also, of course, specify a particular Julia version and package manifest, especially if you require bit reproducibility.)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Software tests that rely on specific \"random\" data should also generally either save the data, embed it into the test code, or use third-party packages like StableRNGs.jl. On the other hand, tests that should pass for most random data (e.g. testing A \\ (A*x) ≈ x for a random matrix A = randn(n,n)) can use an RNG with a fixed seed to ensure that simply running the test many times does not encounter a failure due to very improbable data (e.g. an extremely ill-conditioned matrix).","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The statistical distribution from which random samples are drawn is guaranteed to be the same across any minor Julia releases.","category":"page"},{"location":"base/reflection/#Reflection-and-introspection","page":"Reflection and introspection","title":"Reflection and introspection","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Julia provides a variety of runtime reflection capabilities.","category":"page"},{"location":"base/reflection/#Module-bindings","page":"Reflection and introspection","title":"Module bindings","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The public names for a Module are available using names(m::Module), which will return an array of Symbol elements representing the public bindings. names(m::Module, all = true) returns symbols for all bindings in m, regardless of public status.","category":"page"},{"location":"base/reflection/#DataType-fields","page":"Reflection and introspection","title":"DataType fields","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The names of DataType fields may be interrogated using fieldnames. For example, given the following type, fieldnames(Point) returns a tuple of Symbols representing the field names:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> struct Point\n x::Int\n y\n end\n\njulia> fieldnames(Point)\n(:x, :y)","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The type of each field in a Point object is stored in the types field of the Point variable itself:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> Point.types\nsvec(Int64, Any)","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"While x is annotated as an Int, y was unannotated in the type definition, therefore y defaults to the Any type.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Types are themselves represented as a structure called DataType:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> typeof(Point)\nDataType","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Note that fieldnames(DataType) gives the names for each field of DataType itself, and one of these fields is the types field observed in the example above.","category":"page"},{"location":"base/reflection/#Subtypes","page":"Reflection and introspection","title":"Subtypes","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The direct subtypes of any DataType may be listed using subtypes. For example, the abstract DataType AbstractFloat has four (concrete) subtypes:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> InteractiveUtils.subtypes(AbstractFloat)\n5-element Vector{Any}:\n BigFloat\n Core.BFloat16\n Float16\n Float32\n Float64","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Any abstract subtype will also be included in this list, but further subtypes thereof will not; recursive application of subtypes may be used to inspect the full type tree.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Note that subtypes is located inside InteractiveUtils but is automatically exported when using the REPL.","category":"page"},{"location":"base/reflection/#DataType-layout","page":"Reflection and introspection","title":"DataType layout","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The internal representation of a DataType is critically important when interfacing with C code and several functions are available to inspect these details. isbitstype(T::DataType) returns true if T is stored with C-compatible alignment. fieldoffset(T::DataType, i::Integer) returns the (byte) offset for field i relative to the start of the type.","category":"page"},{"location":"base/reflection/#Function-methods","page":"Reflection and introspection","title":"Function methods","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The methods of any generic function may be listed using methods. The method dispatch table may be searched for methods accepting a given type using methodswith.","category":"page"},{"location":"base/reflection/#Expansion-and-lowering","page":"Reflection and introspection","title":"Expansion and lowering","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"As discussed in the Metaprogramming section, the macroexpand function gives the unquoted and interpolated expression (Expr) form for a given macro. To use macroexpand, quote the expression block itself (otherwise, the macro will be evaluated and the result will be passed instead!). For example:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> InteractiveUtils.macroexpand(@__MODULE__, :(@edit println(\"\")) )\n:(InteractiveUtils.edit(println, (Base.typesof)(\"\")))","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The functions Base.Meta.show_sexpr and dump are used to display S-expr style views and depth-nested detail views for any expression.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Finally, the Meta.lower function gives the lowered form of any expression and is of particular interest for understanding how language constructs map to primitive operations such as assignments, branches, and calls:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] ))\n:($(Expr(:thunk, CodeInfo(\n1 ─ %1 = 1 + 2\n│ %2 = sin(0.5)\n│ %3 = Base.vect(%1, %2)\n└── return %3\n))))","category":"page"},{"location":"base/reflection/#Intermediate-and-compiled-representations","page":"Reflection and introspection","title":"Intermediate and compiled representations","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Inspecting the lowered form for functions requires selection of the specific method to display, because generic functions may have many methods with different type signatures. For this purpose, method-specific code-lowering is available using code_lowered, and the type-inferred form is available using code_typed. code_warntype adds highlighting to the output of code_typed.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Closer to the machine, the LLVM intermediate representation of a function may be printed using by code_llvm, and finally the compiled machine code is available using code_native (this will trigger JIT compilation/code generation for any function which has not previously been called).","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"For convenience, there are macro versions of the above functions which take standard function calls and expand argument types automatically:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> @code_llvm +(1,1)\n; @ int.jl:87 within `+`\n; Function Attrs: sspstrong uwtable\ndefine i64 @\"julia_+_476\"(i64 signext %0, i64 signext %1) #0 {\ntop:\n %2 = add i64 %1, %0\n ret i64 %2\n}","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"For more information see @code_lowered, @code_typed, @code_warntype, @code_llvm, and @code_native.","category":"page"},{"location":"base/reflection/#Printing-of-debug-information","page":"Reflection and introspection","title":"Printing of debug information","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The aforementioned functions and macros take the keyword argument debuginfo that controls the level debug information printed.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> InteractiveUtils.@code_typed debuginfo=:source +(1,1)\nCodeInfo(\n @ int.jl:87 within `+`\n1 ─ %1 = Base.add_int(x, y)::Int64\n└── return %1\n) => Int64","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Possible values for debuginfo are: :none, :source, and :default. Per default debug information is not printed, but that can be changed by setting Base.IRShow.default_debuginfo[] = :source.","category":"page"},{"location":"stdlib/LibCURL/#LibCURL","page":"LibCURL","title":"LibCURL","text":"","category":"section"},{"location":"stdlib/LibCURL/","page":"LibCURL","title":"LibCURL","text":"This is a simple Julia wrapper around http://curl.haxx.se/libcurl/ generated using Clang.jl. Please see the libcurl API documentation for help on how to use this package.","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings","page":"StyledStrings","title":"StyledStrings","text":"","category":"section"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-styling","page":"StyledStrings","title":"Styling","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"When working with strings, formatting and styling often appear as a secondary concern.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"note: Note\nFor instance, when printing to a terminal you might want to sprinkle ANSI escape sequences in the output, when outputting HTML styling constructs (, etc.) serve a similar purpose, and so on. It is possible to simply insert the raw styling constructs into the string next to the content itself, but it quickly becomes apparent that this is not well suited for anything but the most basic use-cases. Not all terminals support the same ANSI codes, the styling constructs need to be painstakingly removed when calculating the width of already-styled content, and that's before you even get into handling multiple output formats.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Instead of leaving this headache to be widely experienced downstream, it is tackled head-on by the introduction of a special string type (AnnotatedString). This string type wraps any other string type and allows for formating information to be applied to regions (e.g. characters 1 through to 7 are bold and red).","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Regions of a string are styled by applying Faces to them —a structure that holds styling information— (think \"typeface\"). As a convenience, it is possible to name a face in the global faces dictionary instead of giving the Face directly.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Along with these capabilities, we also provide a convenient way for constructing AnnotatedStrings, detailed in Styled String Literals.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"julia> styled\"{yellow:hello} {blue:there}\"\n\"hello there\" # prints with colour in the REPL","category":"page"},{"location":"stdlib/StyledStrings/#Styling-via-[AnnotatedString](@ref-Base.AnnotatedString)s","page":"StyledStrings","title":"Styling via AnnotatedStrings","text":"","category":"section"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-faces","page":"StyledStrings","title":"Faces","text":"","category":"section"},{"location":"stdlib/StyledStrings/#The-Face-type","page":"StyledStrings","title":"The Face type","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"A Face specifies details of a typeface that text can be set in. It covers a set of basic attributes that generalise well across different formats, namely:","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"height\nweight\nslant\nforeground\nbackground\nunderline\nstrikethrough\ninverse\ninherit","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For details on the particular forms these attributes take, see the Face docstring, but of particular interest is inherit as it allows you to inherit attributes from other Faces.","category":"page"},{"location":"stdlib/StyledStrings/#The-global-faces-dictionary","page":"StyledStrings","title":"The global faces dictionary","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"To make referring to particular styles more convenient, there is a global Dict{Symbol, Face} that allows for Faces to be referred to simply by name. Packages can add faces to this dictionary via the addface! function, and the loaded faces can be easily customised.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"warning: Warning\nAny package registering new faces should ensure that they are prefixed by the package name, i.e. follow the format mypackage_myface. This is important for predictability, and to prevent name clashes.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"There is one set of exemptions to the package-prefix rule, the set of basic faces that are part of the default value of the faces dictionary.","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-basic-faces","page":"StyledStrings","title":"Basic faces","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Basic faces are intended represent a general idea, that is widely applicable.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For setting some text with a certain attribute, we have the bold, light, italic, underline, strikethrough, and inverse faces.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"There are also named faces for the 16 terminal colours: black, red, green, yellow, blue, magenta, cyan, white, bright_black/grey/gray, bright_red, bright_green, bright_blue, bright_magenta, bright_cyan, and bright_white.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For shadowed text (i.e. dim but there) there is the shadow face. To indicate a selected region, there is the region face. Similarly for emphasis and highlighting the emphasis and highlight faces are defined. There is also code for code-like text.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For visually indicating the severity of messages the error, warning, success, info, note, and tip faces are defined.","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-face-toml","page":"StyledStrings","title":"Customisation of faces (Faces.toml)","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"It is good for the name faces in the global face dictionary to be customizable. Theming and aesthetics are nice, and it is important for accessibility reasons too. A TOML file can be parsed into a list of Face specifications that are merged with the pre-existing entry in the face dictionary.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"A Face is represented in TOML like so:","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"[facename]\nattribute = \"value\"\n...\n\n[package.facename]\nattribute = \"value\"","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For example, if the shadow face is too hard to read it can be made brighter like so:","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"[shadow]\nforeground = \"white\"","category":"page"},{"location":"stdlib/StyledStrings/#Applying-faces-to-a-AnnotatedString","page":"StyledStrings","title":"Applying faces to a AnnotatedString","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"By convention, the :face attributes of a AnnotatedString hold information on the Faces that currently apply. This can be given in multiple forms, as a single Symbol naming a Faces in the global face dictionary, a Face itself, or a vector of either.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"The show(::IO, ::MIME\"text/plain\", ::AnnotatedString) and show(::IO, ::MIME\"text/html\", ::AnnotatedString) methods both look at the :face attributes and merge them all together when determining the overall styling.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"We can supply :face attributes to a AnnotatedString during construction, add them to the properties list afterwards, or use the convenient Styled String literals.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"julia> str1 = Base.AnnotatedString(\"blue text\", [(1:9, :face => :blue)])\n\"blue text\"\n\njulia> str2 = styled\"{blue:blue text}\"\n\"blue text\"\n\njulia> str1 == str2\ntrue\n\njulia> sprint(print, str1, context = :color => true)\n\"\\e[34mblue text\\e[39m\"\n\njulia> sprint(show, MIME(\"text/html\"), str1, context = :color => true)\n\"
    blue text
    \"","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstring-literals","page":"StyledStrings","title":"Styled String Literals","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"To ease construction of AnnotatedStrings with Faces applied, the styled\"...\" styled string literal allows for the content and attributes to be easily expressed together via a custom grammar.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Within a styled\"...\" literal, curly parenthesis are considered special characters and must be escaped in normal usage (\\{, \\}). This allows them to be used to express annotations with (nestable) {annotations...:text} constructs.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"The annotations... component is a comma-separated list of three types of annotations.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Face names\nInline Face expressions (key=val,...)\nkey=value pairs","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Interpolation is possible everywhere except for inline face keys.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For more information on the grammar, see the extended help of the styled\"...\" docstring.","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-api","page":"StyledStrings","title":"API reference","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"StyledStrings.@styled_str\nStyledStrings.Face\nStyledStrings.addface!\nStyledStrings.SimpleColor\nBase.parse(::Type{StyledStrings.SimpleColor}, ::String)\nBase.tryparse(::Type{StyledStrings.SimpleColor}, ::String)\nBase.merge(::StyledStrings.Face, ::StyledStrings.Face)","category":"page"},{"location":"stdlib/StyledStrings/#StyledStrings.@styled_str","page":"StyledStrings","title":"StyledStrings.@styled_str","text":"@styled_str -> AnnotatedString\n\nConstruct a styled string. Within the string, {:} structures apply the formatting to , according to the list of comma-separated specifications . Each spec can either take the form of a face name, an inline face specification, or a key=value pair. The value must be wrapped by {...} should it contain any of the characters ,=:{}.\n\nString interpolation with $ functions in the same way as regular strings, except quotes need to be escaped. Faces, keys, and values can also be interpolated with $.\n\nExample\n\nstyled\"The {bold:{italic:quick} {(foreground=#cd853f):brown} fox} jumped over the {link={https://en.wikipedia.org/wiki/Laziness}:lazy} dog\"\n\nExtended help\n\nThis macro can be described by the following EBNF grammar:\n\nstyledstring = { styled | interpolated | escaped | plain } ;\n\nspecialchar = '{' | '}' | '$' | '\\\"' ;\nanychar = [\\u0-\\u1fffff] ;\nalmostplain = { anychar - specialchar } ;\nplain = { anychar - specialchar } ;\nescaped = '\\\\', specialchar ;\n\ninterpolated = '$', ? expr ? | '$(', ? expr ?, ')' ;\n\nstyled = '{', ws, annotations, ':', content, '}' ;\ncontent = { interpolated | plain | escaped | styled } ;\nannotations = annotation | annotations, ws, ',', ws, annotation ;\nannotation = face | inlineface | keyvalue ;\nws = { ' ' | '\\t' | '\\n' } ; (* whitespace *)\n\nface = facename | interpolated ;\nfacename = [A-Za-z0-9_]+ ;\n\ninlineface = '(', ws, [ faceprop ], { ws, ',', faceprop }, ws, ')' ;\nfaceprop = [a-z]+, ws, '=', ws, ( [^,)]+ | interpolated) ;\n\nkeyvalue = key, ws, '=', ws, value ;\nkey = ( [^${}=,:], [^=,:]* ) | interpolated ;\nvalue = simplevalue | curlybraced | interpolated ;\ncurlybraced = '{' { escaped | plain } '}' ;\nsimplevalue = [^${},:], [^,:]* ;\n\nThe above grammar for inlineface is simplified, as the actual implementation is a bit more sophisticated. The full behaviour is given below.\n\nfaceprop = ( 'face', ws, '=', ws, ( ? string ? | interpolated ) ) |\n ( 'height', ws, '=', ws, ( ? number ? | interpolated ) ) |\n ( 'weight', ws, '=', ws, ( symbol | interpolated ) ) |\n ( 'slant', ws, '=', ws, ( symbol | interpolated ) ) |\n ( ( 'foreground' | 'fg' | 'background' | 'bg' ),\n ws, '=', ws, ( simplecolor | interpolated ) ) |\n ( 'underline', ws, '=', ws, ( underline | interpolated ) ) |\n ( 'strikethrough', ws, '=', ws, ( bool | interpolated ) ) |\n ( 'inverse', ws, '=', ws, ( bool | interpolated ) ) |\n ( 'inherit', ws, '=', ws, ( inherit | interpolated ) ) ;\n\nnothing = 'nothing' ;\nbool = 'true' | 'false' ;\nsymbol = [^ ,)]+ ;\nhexcolor = ('#' | '0x'), [0-9a-f]{6} ;\nsimplecolor = hexcolor | symbol | nothing ;\n\nunderline = nothing | bool | simplecolor | underlinestyled;\nunderlinestyled = '(', whitespace, ('' | nothing | simplecolor), whitespace,\n ',', whitespace, symbol, whitespace ')' ;\n\ninherit = ( '[', inheritval, { ',', inheritval }, ']' ) | inheritval;\ninheritval = whitespace, ':'?, symbol ;\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/StyledStrings/#StyledStrings.Face","page":"StyledStrings","title":"StyledStrings.Face","text":"A Face is a collection of graphical attributes for displaying text. Faces control how text is displayed in the terminal, and possibly other places too.\n\nMost of the time, a Face will be stored in the global faces dicts as a unique association with a face name Symbol, and will be most often referred to by this name instead of the Face object itself.\n\nAttributes\n\nAll attributes can be set via the keyword constructor, and default to nothing.\n\nheight (an Int or Float64): The height in either deci-pt (when an Int), or as a factor of the base size (when a Float64).\nweight (a Symbol): One of the symbols (from faintest to densest) :thin, :extralight, :light, :semilight, :normal, :medium, :semibold, :bold, :extrabold, or :black. In terminals any weight greater than :normal is displayed as bold, and in terminals that support variable-brightness text, any weight less than :normal is displayed as faint.\nslant (a Symbol): One of the symbols :italic, :oblique, or :normal.\nforeground (a SimpleColor): The text foreground color.\nbackground (a SimpleColor): The text background color.\nunderline, the text underline, which takes one of the following forms:\na Bool: Whether the text should be underlined or not.\n\na SimpleColor: The text should be underlined with this color.\n\na Tuple{Nothing, Symbol}: The text should be underlined using the style set by the Symbol, one of :straight, :double, :curly, :dotted, or :dashed.\n\na Tuple{SimpleColor, Symbol}: The text should be underlined in the specified SimpleColor, and using the style specified by the Symbol, as before.\nstrikethrough (a Bool): Whether the text should be struck through.\ninverse (a Bool): Whether the foreground and background colors should be inverted.\ninherit (a Vector{Symbol}): Names of faces to inherit from, with earlier faces taking priority. All faces inherit from the :default face.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/StyledStrings/#StyledStrings.addface!","page":"StyledStrings","title":"StyledStrings.addface!","text":"addface!(name::Symbol => default::Face)\n\nCreate a new face by the name name. So long as no face already exists by this name, default is added to both FACES.default and (a copy of) to FACES.current, with the current value returned.\n\nShould the face name already exist, nothing is returned.\n\nExamples\n\njulia> addface!(:mypkg_myface => Face(slant=:italic, underline=true))\nFace (sample)\n slant: italic\n underline: true\n\n\n\n\n\n","category":"function"},{"location":"stdlib/StyledStrings/#StyledStrings.SimpleColor","page":"StyledStrings","title":"StyledStrings.SimpleColor","text":"struct SimpleColor\n\nA basic representation of a color, intended for string styling purposes. It can either contain a named color (like :red), or an RGBTuple which is a NamedTuple specifying an r, g, b color with a bit-depth of 8.\n\nConstructors\n\nSimpleColor(name::Symbol) # e.g. :red\nSimpleColor(rgb::RGBTuple) # e.g. (r=1, b=2, g=3)\nSimpleColor(r::Integer, b::Integer, b::Integer)\nSimpleColor(rgb::UInt32) # e.g. 0x123456\n\nAlso see tryparse(SimpleColor, rgb::String).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/StyledStrings/#Base.parse-Tuple{Type{StyledStrings.SimpleColor}, String}","page":"StyledStrings","title":"Base.parse","text":"parse(::Type{SimpleColor}, rgb::String)\n\nAn analogue of tryparse(SimpleColor, rgb::String) (which see), that raises an error instead of returning nothing.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/StyledStrings/#Base.tryparse-Tuple{Type{StyledStrings.SimpleColor}, String}","page":"StyledStrings","title":"Base.tryparse","text":"tryparse(::Type{SimpleColor}, rgb::String)\n\nAttempt to parse rgb as a SimpleColor. If rgb starts with # and has a length of 7, it is converted into a RGBTuple-backed SimpleColor. If rgb starts with a-z, rgb is interpreted as a color name and converted to a Symbol-backed SimpleColor.\n\nOtherwise, nothing is returned.\n\nExamples\n\njulia> tryparse(SimpleColor, \"blue\")\nSimpleColor(blue)\n\njulia> tryparse(SimpleColor, \"#9558b2\")\nSimpleColor(#9558b2)\n\njulia> tryparse(SimpleColor, \"#nocolor\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/StyledStrings/#Base.merge-Tuple{StyledStrings.Face, StyledStrings.Face}","page":"StyledStrings","title":"Base.merge","text":"merge(initial::Face, others::Face...)\n\nMerge the properties of the initial face and others, with later faces taking priority.\n\n\n\n\n\n","category":"method"},{"location":"manual/variables/#man-variables","page":"Variables","title":"Variables","text":"","category":"section"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"A variable, in Julia, is a name associated (or bound) to a value. It's useful when you want to store a value (that you obtained after some math, for example) for later use. For example:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"# Assign the value 10 to the variable x\njulia> x = 10\n10\n\n# Doing math with x's value\njulia> x + 1\n11\n\n# Reassign x's value\njulia> x = 1 + 1\n2\n\n# You can assign values of other types, like strings of text\njulia> x = \"Hello World!\"\n\"Hello World!\"","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Julia provides an extremely flexible system for naming variables. Variable names are case-sensitive, and have no semantic meaning (that is, the language will not treat variables differently based on their names).","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> x = 1.0\n1.0\n\njulia> y = -3\n-3\n\njulia> Z = \"My string\"\n\"My string\"\n\njulia> customary_phrase = \"Hello world!\"\n\"Hello world!\"\n\njulia> UniversalDeclarationOfHumanRightsStart = \"人人生而自由,在尊严和权利上一律平等。\"\n\"人人生而自由,在尊严和权利上一律平等。\"","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Unicode names (in UTF-8 encoding) are allowed:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> δ = 0.00001\n1.0e-5\n\njulia> 안녕하세요 = \"Hello\"\n\"Hello\"","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"In the Julia REPL and several other Julia editing environments, you can type many Unicode math symbols by typing the backslashed LaTeX symbol name followed by tab. For example, the variable name δ can be entered by typing \\delta-tab, or even α̂⁽²⁾ by \\alpha-tab-\\hat- tab-\\^(2)-tab. (If you find a symbol somewhere, e.g. in someone else's code, that you don't know how to type, the REPL help will tell you: just type ? and then paste the symbol.)","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Julia will even let you shadow existing exported constants and functions with local ones (although this is not recommended to avoid potential confusions):","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> pi = 3\n3\n\njulia> pi\n3\n\njulia> sqrt = 4\n4\n\njulia> length() = 5\nlength (generic function with 1 method)\n\njulia> Base.length\nlength (generic function with 79 methods)","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"However, if you try to redefine a built-in constant or function already in use, Julia will give you an error:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> pi\nπ = 3.1415926535897...\n\njulia> pi = 3\nERROR: cannot assign a value to imported variable Base.pi from module Main\n\njulia> sqrt(100)\n10.0\n\njulia> sqrt = 4\nERROR: cannot assign a value to imported variable Base.sqrt from module Main","category":"page"},{"location":"manual/variables/#man-allowed-variable-names","page":"Variables","title":"Allowed Variable Names","text":"","category":"section"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Variable names must begin with a letter (A-Z or a-z), underscore, or a subset of Unicode code points greater than 00A0; in particular, Unicode character categories Lu/Ll/Lt/Lm/Lo/Nl (letters), Sc/So (currency and other symbols), and a few other letter-like characters (e.g. a subset of the Sm math symbols) are allowed. Subsequent characters may also include ! and digits (0-9 and other characters in categories Nd/No), as well as other Unicode code points: diacritics and other modifying marks (categories Mn/Mc/Me/Sk), some punctuation connectors (category Pc), primes, and a few other characters.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Operators like + are also valid identifiers, but are parsed specially. In some contexts, operators can be used just like variables; for example (+) refers to the addition function, and (+) = f will reassign it. Most of the Unicode infix operators (in category Sm), such as ⊕, are parsed as infix operators and are available for user-defined methods (e.g. you can use const ⊗ = kron to define ⊗ as an infix Kronecker product). Operators can also be suffixed with modifying marks, primes, and sub/superscripts, e.g. +̂ₐ″ is parsed as an infix operator with the same precedence as +. A space is required between an operator that ends with a subscript/superscript letter and a subsequent variable name. For example, if +ᵃ is an operator, then +ᵃx must be written as +ᵃ x to distinguish it from + ᵃx where ᵃx is the variable name.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"A particular class of variable names is one that contains only underscores. These identifiers are write-only. I.e. they can only be assigned values, which are immediately discarded, and their values cannot be used in any way.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> x, ___ = size([2 2; 1 1])\n(2, 2)\n\njulia> y = ___\nERROR: syntax: all-underscore identifiers are write-only and their values cannot be used in expressions\n\njulia> println(___)\nERROR: syntax: all-underscore identifiers are write-only and their values cannot be used in expressions","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"The only explicitly disallowed names for variables are the names of the built-in Keywords:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> else = false\nERROR: syntax: unexpected \"else\"\n\njulia> try = \"No\"\nERROR: syntax: unexpected \"=\"","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Some Unicode characters are considered to be equivalent in identifiers. Different ways of entering Unicode combining characters (e.g., accents) are treated as equivalent (specifically, Julia identifiers are NFC. Julia also includes a few non-standard equivalences for characters that are visually similar and are easily entered by some input methods. The Unicode characters ɛ (U+025B: Latin small letter open e) and µ (U+00B5: micro sign) are treated as equivalent to the corresponding Greek letters. The middle dot · (U+00B7) and the Greek interpunct · (U+0387) are both treated as the mathematical dot operator ⋅ (U+22C5). The minus sign − (U+2212) is treated as equivalent to the hyphen-minus sign - (U+002D).","category":"page"},{"location":"manual/variables/#man-assignment-expressions","page":"Variables","title":"Assignment expressions and assignment versus mutation","text":"","category":"section"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"An assignment variable = value \"binds\" the name variable to the value computed on the right-hand side, and the whole assignment is treated by Julia as an expression equal to the right-hand-side value. This means that assignments can be chained (the same value assigned to multiple variables with variable1 = variable2 = value) or used in other expressions, and is also why their result is shown in the REPL as the value of the right-hand side. (In general, the REPL displays the value of whatever expression you evaluate.) For example, here the value 4 of b = 2+2 is used in another arithmetic operation and assignment:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> a = (b = 2+2) + 3\n7\n\njulia> a\n7\n\njulia> b\n4","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"A common confusion is the distinction between assignment (giving a new \"name\" to a value) and mutation (changing a value). If you run a = 2 followed by a = 3, you have changed the \"name\" a to refer to a new value 3 … you haven't changed the number 2, so 2+2 will still give 4 and not 6! This distinction becomes more clear when dealing with mutable types like arrays, whose contents can be changed:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> a = [1,2,3] # an array of 3 integers\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> b = a # both b and a are names for the same array!\n3-element Vector{Int64}:\n 1\n 2\n 3","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Here, the line b = a does not make a copy of the array a, it simply binds the name b to the same array a: both b and a \"point\" to one array [1,2,3] in memory. In contrast, an assignment a[i] = value changes the contents of the array, and the modified array will be visible through both the names a and b:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> a[1] = 42 # change the first element\n42\n\njulia> a = 3.14159 # a is now the name of a different object\n3.14159\n\njulia> b # b refers to the original array object, which has been mutated\n3-element Vector{Int64}:\n 42\n 2\n 3","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"That is, a[i] = value (an alias for setindex!) mutates an existing array object in memory, accessible via either a or b. Subsequently setting a = 3.14159 does not change this array, it simply binds a to a different object; the array is still accessible via b. Another common syntax to mutate an existing object is a.field = value (an alias for setproperty!), which can be used to change a mutable struct. There is also mutation via dot assignment, for example b .= 5:7 (which mutates our array b in-place to contain [5,6,7]), as part of Julia's vectorized \"dot\" syntax.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"When you call a function in Julia, it behaves as if you assigned the argument values to new variable names corresponding to the function arguments, as discussed in Argument-Passing Behavior. (By convention, functions that mutate one or more of their arguments have names ending with !.)","category":"page"},{"location":"manual/variables/#Stylistic-Conventions","page":"Variables","title":"Stylistic Conventions","text":"","category":"section"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"While Julia imposes few restrictions on valid names, it has become useful to adopt the following conventions:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Names of variables are in lower case.\nWord separation can be indicated by underscores ('_'), but use of underscores is discouraged unless the name would be hard to read otherwise.\nNames of Types and Modules begin with a capital letter and word separation is shown with upper camel case instead of underscores.\nNames of functions and macros are in lower case, without underscores.\nFunctions that write to their arguments have names that end in !. These are sometimes called \"mutating\" or \"in-place\" functions because they are intended to produce changes in their arguments after the function is called, not just return a value.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"For more information about stylistic conventions, see the Style Guide.","category":"page"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/NEWS.md\"","category":"page"},{"location":"NEWS/#Julia-v1.12-Release-Notes","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"","category":"section"},{"location":"NEWS/#New-language-features","page":"Julia v1.12 Release Notes","title":"New language features","text":"","category":"section"},{"location":"NEWS/#Language-changes","page":"Julia v1.12 Release Notes","title":"Language changes","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"When methods are replaced with exactly equivalent ones, the old method is no longer deleted implicitly simultaneously, although the new method does take priority and become more specific than the old method. Thus if the new method is deleted later, the old method will resume operating. This can be useful to mocking frameworks (such as in SparseArrays, Pluto, and Mocking, among others), as they do not need to explicitly restore the old method. While inference and compilation still must be repeated with this, it also may pave the way for inference to be able to intelligently re-use the old results, once the new method is deleted. (#53415)\nMacro expansion will no longer eargerly recurse into into Expr(:toplevel) expressions returned from macros. Instead, macro expansion of :toplevel expressions will be delayed until evaluation time. This allows a later expression within a given :toplevel expression to make use of macros defined earlier in the same :toplevel expression. (#53515)","category":"page"},{"location":"NEWS/#Compiler/Runtime-improvements","page":"Julia v1.12 Release Notes","title":"Compiler/Runtime improvements","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"Generated LLVM IR now uses actual pointer types instead of passing pointers as integers. This affects llvmcall: Inline LLVM IR should be updated to use i8* or ptr instead of i32 or i64, and remove unneeded ptrtoint/inttoptr conversions. For compatibility, IR with integer pointers is still supported, but generates a deprecation warning. (#53687)","category":"page"},{"location":"NEWS/#Command-line-option-changes","page":"Julia v1.12 Release Notes","title":"Command-line option changes","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"The -m/--module flag can be passed to run the main function inside a package with a set of arguments. This main function should be declared using @main to indicate that it is an entry point.","category":"page"},{"location":"NEWS/#Multi-threading-changes","page":"Julia v1.12 Release Notes","title":"Multi-threading changes","text":"","category":"section"},{"location":"NEWS/#Build-system-changes","page":"Julia v1.12 Release Notes","title":"Build system changes","text":"","category":"section"},{"location":"NEWS/#New-library-functions","page":"Julia v1.12 Release Notes","title":"New library functions","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"logrange(start, stop; length) makes a range of constant ratio, instead of constant step (#39071)\nThe new isfull(c::Channel) function can be used to check if put!(c, some_value) will block. (#53159)\nwaitany(tasks; throw=false) and waitall(tasks; failfast=false, throw=false) which wait multiple tasks at once (#53341).","category":"page"},{"location":"NEWS/#New-library-features","page":"Julia v1.12 Release Notes","title":"New library features","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"invmod(n, T) where T is a native integer type now computes the modular inverse of n in the modular integer ring that T defines (#52180).\ninvmod(n) is an abbreviation for invmod(n, typeof(n)) for native integer types (#52180).\nreplace(string, pattern...) now supports an optional IO argument to write the output to a stream rather than returning a string (#48625).\nsizehint!(s, n) now supports an optional shrink argument to disable shrinking (#51929).\nNew function Docs.hasdoc(module, symbol) tells whether a name has a docstring (#52139).\nNew function Docs.undocumented_names(module) returns a module's undocumented public names (#52413).\nPassing an IOBuffer as a stdout argument for Process spawn now works as expected, synchronized with wait or success, so a Base.BufferStream is no longer required there for correctness to avoid data races (#52461).\nAfter a process exits, closewrite will no longer be automatically called on the stream passed to it. Call wait on the process instead to ensure the content is fully written, then call closewrite manually to avoid data-races. Or use the callback form of open to have all that handled automatically.\n@timed now additionally returns the elapsed compilation and recompilation time (#52889)\nfilter can now act on a NamedTuple (#50795).\ntempname can now take a suffix string to allow the file name to include a suffix and include that suffix in the uniquing checking (#53474)\nRegexMatch objects can now be used to construct NamedTuples and Dicts (#50988)","category":"page"},{"location":"NEWS/#Standard-library-changes","page":"Julia v1.12 Release Notes","title":"Standard library changes","text":"","category":"section"},{"location":"NEWS/#StyledStrings","page":"Julia v1.12 Release Notes","title":"StyledStrings","text":"","category":"section"},{"location":"NEWS/#JuliaSyntaxHighlighting","page":"Julia v1.12 Release Notes","title":"JuliaSyntaxHighlighting","text":"","category":"section"},{"location":"NEWS/#Package-Manager","page":"Julia v1.12 Release Notes","title":"Package Manager","text":"","category":"section"},{"location":"NEWS/#LinearAlgebra","page":"Julia v1.12 Release Notes","title":"LinearAlgebra","text":"","category":"section"},{"location":"NEWS/#Logging","page":"Julia v1.12 Release Notes","title":"Logging","text":"","category":"section"},{"location":"NEWS/#Printf","page":"Julia v1.12 Release Notes","title":"Printf","text":"","category":"section"},{"location":"NEWS/#Profile","page":"Julia v1.12 Release Notes","title":"Profile","text":"","category":"section"},{"location":"NEWS/#Random","page":"Julia v1.12 Release Notes","title":"Random","text":"","category":"section"},{"location":"NEWS/#REPL","page":"Julia v1.12 Release Notes","title":"REPL","text":"","category":"section"},{"location":"NEWS/#SuiteSparse","page":"Julia v1.12 Release Notes","title":"SuiteSparse","text":"","category":"section"},{"location":"NEWS/#SparseArrays","page":"Julia v1.12 Release Notes","title":"SparseArrays","text":"","category":"section"},{"location":"NEWS/#Test","page":"Julia v1.12 Release Notes","title":"Test","text":"","category":"section"},{"location":"NEWS/#Dates","page":"Julia v1.12 Release Notes","title":"Dates","text":"","category":"section"},{"location":"NEWS/#Statistics","page":"Julia v1.12 Release Notes","title":"Statistics","text":"","category":"section"},{"location":"NEWS/#Distributed","page":"Julia v1.12 Release Notes","title":"Distributed","text":"","category":"section"},{"location":"NEWS/#Unicode","page":"Julia v1.12 Release Notes","title":"Unicode","text":"","category":"section"},{"location":"NEWS/#DelimitedFiles","page":"Julia v1.12 Release Notes","title":"DelimitedFiles","text":"","category":"section"},{"location":"NEWS/#InteractiveUtils","page":"Julia v1.12 Release Notes","title":"InteractiveUtils","text":"","category":"section"},{"location":"NEWS/#Deprecated-or-removed","page":"Julia v1.12 Release Notes","title":"Deprecated or removed","text":"","category":"section"},{"location":"NEWS/#External-dependencies","page":"Julia v1.12 Release Notes","title":"External dependencies","text":"","category":"section"},{"location":"NEWS/#Tooling-Improvements","page":"Julia v1.12 Release Notes","title":"Tooling Improvements","text":"","category":"section"},{"location":"stdlib/InteractiveUtils/","page":"Interactive Utilities","title":"Interactive Utilities","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/InteractiveUtils/docs/src/index.md\"","category":"page"},{"location":"stdlib/InteractiveUtils/#man-interactive-utils","page":"Interactive Utilities","title":"Interactive Utilities","text":"","category":"section"},{"location":"stdlib/InteractiveUtils/","page":"Interactive Utilities","title":"Interactive Utilities","text":"The InteractiveUtils module provides utilities for interactive use of Julia, such as code introspection and clipboard access. It is intended for interactive work and is loaded automatically in interactive mode.","category":"page"},{"location":"stdlib/InteractiveUtils/","page":"Interactive Utilities","title":"Interactive Utilities","text":"InteractiveUtils.apropos\nInteractiveUtils.varinfo\nInteractiveUtils.versioninfo\nInteractiveUtils.methodswith\nInteractiveUtils.subtypes\nInteractiveUtils.supertypes\nInteractiveUtils.edit(::AbstractString, ::Integer)\nInteractiveUtils.edit(::Any)\nInteractiveUtils.@edit\nInteractiveUtils.define_editor\nInteractiveUtils.less(::AbstractString)\nInteractiveUtils.less(::Any)\nInteractiveUtils.@less\nInteractiveUtils.@which\nInteractiveUtils.@functionloc\nInteractiveUtils.@code_lowered\nInteractiveUtils.@code_typed\nInteractiveUtils.code_warntype\nInteractiveUtils.@code_warntype\nInteractiveUtils.code_llvm\nInteractiveUtils.@code_llvm\nInteractiveUtils.code_native\nInteractiveUtils.@code_native\nInteractiveUtils.@time_imports\nInteractiveUtils.clipboard","category":"page"},{"location":"stdlib/InteractiveUtils/#Base.Docs.apropos","page":"Interactive Utilities","title":"Base.Docs.apropos","text":"apropos([io::IO=stdout], pattern::Union{AbstractString,Regex})\n\nSearch available docstrings for entries containing pattern.\n\nWhen pattern is a string, case is ignored. Results are printed to io.\n\napropos can be called from the help mode in the REPL by wrapping the query in double quotes:\n\nhelp?> \"pattern\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.varinfo","page":"Interactive Utilities","title":"InteractiveUtils.varinfo","text":"varinfo(m::Module=Main, pattern::Regex=r\"\"; all=false, imported=false, recursive=false, sortby::Symbol=:name, minsize::Int=0)\n\nReturn a markdown table giving information about public global variables in a module, optionally restricted to those matching pattern.\n\nThe memory consumption estimate is an approximate lower bound on the size of the internal structure of the object.\n\nall : also list non-public objects defined in the module, deprecated objects, and compiler-generated objects.\nimported : also list objects explicitly imported from other modules.\nrecursive : recursively include objects in sub-modules, observing the same settings in each.\nsortby : the column to sort results by. Options are :name (default), :size, and :summary.\nminsize : only includes objects with size at least minsize bytes. Defaults to 0.\n\nThe output of varinfo is intended for display purposes only. See also names to get an array of symbols defined in a module, which is suitable for more general manipulations.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.versioninfo","page":"Interactive Utilities","title":"InteractiveUtils.versioninfo","text":"versioninfo(io::IO=stdout; verbose::Bool=false)\n\nPrint information about the version of Julia in use. The output is controlled with boolean keyword arguments:\n\nverbose: print all additional information\n\nwarning: Warning\nThe output of this function may contain sensitive information. Before sharing the output, please review the output and remove any data that should not be shared publicly.\n\nSee also: VERSION.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.methodswith","page":"Interactive Utilities","title":"InteractiveUtils.methodswith","text":"methodswith(typ[, module or function]; supertypes::Bool=false])\n\nReturn an array of methods with an argument of type typ.\n\nThe optional second argument restricts the search to a particular module or function (the default is all top-level modules).\n\nIf keyword supertypes is true, also return arguments with a parent type of typ, excluding type Any.\n\nSee also: methods.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.subtypes","page":"Interactive Utilities","title":"InteractiveUtils.subtypes","text":"subtypes(T::DataType)\n\nReturn a list of immediate subtypes of DataType T. Note that all currently loaded subtypes are included, including those not visible in the current module.\n\nSee also supertype, supertypes, methodswith.\n\nExamples\n\njulia> subtypes(Integer)\n3-element Vector{Any}:\n Bool\n Signed\n Unsigned\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.supertypes","page":"Interactive Utilities","title":"InteractiveUtils.supertypes","text":"supertypes(T::Type)\n\nReturn a tuple (T, ..., Any) of T and all its supertypes, as determined by successive calls to the supertype function, listed in order of <: and terminated by Any.\n\nSee also subtypes.\n\nExamples\n\njulia> supertypes(Int)\n(Int64, Signed, Integer, Real, Number, Any)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.edit-Tuple{AbstractString, Integer}","page":"Interactive Utilities","title":"InteractiveUtils.edit","text":"edit(path::AbstractString, line::Integer=0, column::Integer=0)\n\nEdit a file or directory optionally providing a line number to edit the file at. Return to the julia prompt when you quit the editor. The editor can be changed by setting JULIA_EDITOR, VISUAL or EDITOR as an environment variable.\n\nSee also InteractiveUtils.define_editor.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.edit-Tuple{Any}","page":"Interactive Utilities","title":"InteractiveUtils.edit","text":"edit(function, [types])\nedit(module)\n\nEdit the definition of a function, optionally specifying a tuple of types to indicate which method to edit. For modules, open the main source file. The module needs to be loaded with using or import first.\n\ncompat: Julia 1.1\nedit on modules requires at least Julia 1.1.\n\nTo ensure that the file can be opened at the given line, you may need to call InteractiveUtils.define_editor first.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@edit","page":"Interactive Utilities","title":"InteractiveUtils.@edit","text":"@edit\n\nEvaluates the arguments to the function or macro call, determines their types, and calls the edit function on the resulting expression.\n\nSee also: @less, @which.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.define_editor","page":"Interactive Utilities","title":"InteractiveUtils.define_editor","text":"define_editor(fn, pattern; wait=false)\n\nDefine a new editor matching pattern that can be used to open a file (possibly at a given line number) using fn.\n\nThe fn argument is a function that determines how to open a file with the given editor. It should take four arguments, as follows:\n\ncmd - a base command object for the editor\npath - the path to the source file to open\nline - the line number to open the editor at\ncolumn - the column number to open the editor at\n\nEditors which cannot open to a specific line with a command or a specific column may ignore the line and/or column argument. The fn callback must return either an appropriate Cmd object to open a file or nothing to indicate that they cannot edit this file. Use nothing to indicate that this editor is not appropriate for the current environment and another editor should be attempted. It is possible to add more general editing hooks that need not spawn external commands by pushing a callback directly to the vector EDITOR_CALLBACKS.\n\nThe pattern argument is a string, regular expression, or an array of strings and regular expressions. For the fn to be called, one of the patterns must match the value of EDITOR, VISUAL or JULIA_EDITOR. For strings, the string must equal the basename of the first word of the editor command, with its extension, if any, removed. E.g. \"vi\" doesn't match \"vim -g\" but matches \"/usr/bin/vi -m\"; it also matches vi.exe. If pattern is a regex it is matched against all of the editor command as a shell-escaped string. An array pattern matches if any of its items match. If multiple editors match, the one added most recently is used.\n\nBy default julia does not wait for the editor to close, running it in the background. However, if the editor is terminal based, you will probably want to set wait=true and julia will wait for the editor to close before resuming.\n\nIf one of the editor environment variables is set, but no editor entry matches it, the default editor entry is invoked:\n\n(cmd, path, line, column) -> `$cmd $path`\n\nNote that many editors are already defined. All of the following commands should already work:\n\nemacs\nemacsclient\nvim\nnvim\nnano\nmicro\nkak\nhelix\ntextmate\nmate\nkate\nsubl\natom\nnotepad++\nVisual Studio Code\nopen\npycharm\nbbedit\n\nExamples\n\nThe following defines the usage of terminal-based emacs:\n\ndefine_editor(\n r\"\\bemacs\\b.*\\s(-nw|--no-window-system)\\b\", wait=true) do cmd, path, line\n `$cmd +$line $path`\nend\n\ncompat: Julia 1.4\ndefine_editor was introduced in Julia 1.4.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.less-Tuple{AbstractString}","page":"Interactive Utilities","title":"InteractiveUtils.less","text":"less(file::AbstractString, [line::Integer])\n\nShow a file using the default pager, optionally providing a starting line number. Returns to the julia prompt when you quit the pager.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.less-Tuple{Any}","page":"Interactive Utilities","title":"InteractiveUtils.less","text":"less(function, [types])\n\nShow the definition of a function using the default pager, optionally specifying a tuple of types to indicate which method to see.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@less","page":"Interactive Utilities","title":"InteractiveUtils.@less","text":"@less\n\nEvaluates the arguments to the function or macro call, determines their types, and calls the less function on the resulting expression.\n\nSee also: @edit, @which, @code_lowered.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@which","page":"Interactive Utilities","title":"InteractiveUtils.@which","text":"@which\n\nApplied to a function or macro call, it evaluates the arguments to the specified call, and returns the Method object for the method that would be called for those arguments. Applied to a variable, it returns the module in which the variable was bound. It calls out to the which function.\n\nSee also: @less, @edit.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@functionloc","page":"Interactive Utilities","title":"InteractiveUtils.@functionloc","text":"@functionloc\n\nApplied to a function or macro call, it evaluates the arguments to the specified call, and returns a tuple (filename,line) giving the location for the method that would be called for those arguments. It calls out to the functionloc function.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_lowered","page":"Interactive Utilities","title":"InteractiveUtils.@code_lowered","text":"@code_lowered\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_lowered on the resulting expression.\n\nSee also: code_lowered, @code_warntype, @code_typed, @code_llvm, @code_native.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_typed","page":"Interactive Utilities","title":"InteractiveUtils.@code_typed","text":"@code_typed\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_typed on the resulting expression. Use the optional argument optimize with\n\n@code_typed optimize=true foo(x)\n\nto control whether additional optimizations, such as inlining, are also applied.\n\nSee also: code_typed, @code_warntype, @code_lowered, @code_llvm, @code_native.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.code_warntype","page":"Interactive Utilities","title":"InteractiveUtils.code_warntype","text":"code_warntype([io::IO], f, types; debuginfo=:default)\n\nPrints lowered and type-inferred ASTs for the methods matching the given generic function and type signature to io which defaults to stdout. The ASTs are annotated in such a way as to cause \"non-leaf\" types which may be problematic for performance to be emphasized (if color is available, displayed in red). This serves as a warning of potential type instability.\n\nNot all non-leaf types are particularly problematic for performance, and the performance characteristics of a particular type is an implementation detail of the compiler. code_warntype will err on the side of coloring types red if they might be a performance concern, so some types may be colored red even if they do not impact performance. Small unions of concrete types are usually not a concern, so these are highlighted in yellow.\n\nKeyword argument debuginfo may be one of :source or :none (default), to specify the verbosity of code comments.\n\nSee the @code_warntype section in the Performance Tips page of the manual for more information.\n\nSee also: @code_warntype, code_typed, code_lowered, code_llvm, code_native.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype","page":"Interactive Utilities","title":"InteractiveUtils.@code_warntype","text":"@code_warntype\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_warntype on the resulting expression.\n\nSee also: code_warntype, @code_typed, @code_lowered, @code_llvm, @code_native.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.code_llvm","page":"Interactive Utilities","title":"InteractiveUtils.code_llvm","text":"code_llvm([io=stdout,], f, types; raw=false, dump_module=false, optimize=true, debuginfo=:default)\n\nPrints the LLVM bitcodes generated for running the method matching the given generic function and type signature to io.\n\nIf the optimize keyword is unset, the code will be shown before LLVM optimizations. All metadata and dbg.* calls are removed from the printed bitcode. For the full IR, set the raw keyword to true. To dump the entire module that encapsulates the function (with declarations), set the dump_module keyword to true. Keyword argument debuginfo may be one of source (default) or none, to specify the verbosity of code comments.\n\nSee also: @code_llvm, code_warntype, code_typed, code_lowered, code_native.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_llvm","page":"Interactive Utilities","title":"InteractiveUtils.@code_llvm","text":"@code_llvm\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_llvm on the resulting expression. Set the optional keyword arguments raw, dump_module, debuginfo, optimize by putting them and their value before the function call, like this:\n\n@code_llvm raw=true dump_module=true debuginfo=:default f(x)\n@code_llvm optimize=false f(x)\n\noptimize controls whether additional optimizations, such as inlining, are also applied. raw makes all metadata and dbg.* calls visible. debuginfo may be one of :source (default) or :none, to specify the verbosity of code comments. dump_module prints the entire module that encapsulates the function.\n\nSee also: code_llvm, @code_warntype, @code_typed, @code_lowered, @code_native.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.code_native","page":"Interactive Utilities","title":"InteractiveUtils.code_native","text":"code_native([io=stdout,], f, types; syntax=:intel, debuginfo=:default, binary=false, dump_module=true)\n\nPrints the native assembly instructions generated for running the method matching the given generic function and type signature to io.\n\nSet assembly syntax by setting syntax to :intel (default) for intel syntax or :att for AT&T syntax.\nSpecify verbosity of code comments by setting debuginfo to :source (default) or :none.\nIf binary is true, also print the binary machine code for each instruction precedented by an abbreviated address.\nIf dump_module is false, do not print metadata such as rodata or directives.\nIf raw is false, uninteresting instructions (like the safepoint function prologue) are elided.\n\nSee also: @code_native, code_warntype, code_typed, code_lowered, code_llvm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_native","page":"Interactive Utilities","title":"InteractiveUtils.@code_native","text":"@code_native\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_native on the resulting expression.\n\nSet any of the optional keyword arguments syntax, debuginfo, binary or dump_module by putting it before the function call, like this:\n\n@code_native syntax=:intel debuginfo=:default binary=true dump_module=false f(x)\n\nSet assembly syntax by setting syntax to :intel (default) for Intel syntax or :att for AT&T syntax.\nSpecify verbosity of code comments by setting debuginfo to :source (default) or :none.\nIf binary is true, also print the binary machine code for each instruction precedented by an abbreviated address.\nIf dump_module is false, do not print metadata such as rodata or directives.\n\nSee also: code_native, @code_warntype, @code_typed, @code_lowered, @code_llvm.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@time_imports","page":"Interactive Utilities","title":"InteractiveUtils.@time_imports","text":"@time_imports\n\nA macro to execute an expression and produce a report of any time spent importing packages and their dependencies. Any compilation time will be reported as a percentage, and how much of which was recompilation, if any.\n\nOne line is printed per package or package extension. The duration shown is the time to import that package itself, not including the time to load any of its dependencies.\n\nOn Julia 1.9+ package extensions will show as Parent → Extension.\n\nnote: Note\nDuring the load process a package sequentially imports all of its dependencies, not just its direct dependencies.\n\njulia> @time_imports using CSV\n 50.7 ms Parsers 17.52% compilation time\n 0.2 ms DataValueInterfaces\n 1.6 ms DataAPI\n 0.1 ms IteratorInterfaceExtensions\n 0.1 ms TableTraits\n 17.5 ms Tables\n 26.8 ms PooledArrays\n 193.7 ms SentinelArrays 75.12% compilation time\n 8.6 ms InlineStrings\n 20.3 ms WeakRefStrings\n 2.0 ms TranscodingStreams\n 1.4 ms Zlib_jll\n 1.8 ms CodecZlib\n 0.8 ms Compat\n 13.1 ms FilePathsBase 28.39% compilation time\n 1681.2 ms CSV 92.40% compilation time\n\ncompat: Julia 1.8\nThis macro requires at least Julia 1.8\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.clipboard","page":"Interactive Utilities","title":"InteractiveUtils.clipboard","text":"clipboard(x)\n\nSend a printed form of x to the operating system clipboard (\"copy\").\n\n\n\n\n\nclipboard() -> String\n\nReturn a string with the contents of the operating system clipboard (\"paste\").\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Serialization/","page":"Serialization","title":"Serialization","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Serialization/docs/src/index.md\"","category":"page"},{"location":"stdlib/Serialization/#Serialization","page":"Serialization","title":"Serialization","text":"","category":"section"},{"location":"stdlib/Serialization/","page":"Serialization","title":"Serialization","text":"Provides serialization of Julia objects.","category":"page"},{"location":"stdlib/Serialization/","page":"Serialization","title":"Serialization","text":"Serialization.serialize\nSerialization.deserialize\nSerialization.writeheader","category":"page"},{"location":"stdlib/Serialization/#Serialization.serialize","page":"Serialization","title":"Serialization.serialize","text":"serialize(stream::IO, value)\n\nWrite an arbitrary value to a stream in an opaque format, such that it can be read back by deserialize. The read-back value will be as identical as possible to the original, but note that Ptr values are serialized as all-zero bit patterns (NULL).\n\nAn 8-byte identifying header is written to the stream first. To avoid writing the header, construct a Serializer and use it as the first argument to serialize instead. See also Serialization.writeheader.\n\nThe data format can change in minor (1.x) Julia releases, but files written by prior 1.x versions will remain readable. The main exception to this is when the definition of a type in an external package changes. If that occurs, it may be necessary to specify an explicit compatible version of the affected package in your environment. Renaming functions, even private functions, inside packages can also put existing files out of sync. Anonymous functions require special care: because their names are automatically generated, minor code changes can cause them to be renamed. Serializing anonymous functions should be avoided in files intended for long-term storage.\n\nIn some cases, the word size (32- or 64-bit) of the reading and writing machines must match. In rarer cases the OS or architecture must also match, for example when using packages that contain platform-dependent code.\n\n\n\n\n\nserialize(filename::AbstractString, value)\n\nOpen a file and serialize the given value to it.\n\ncompat: Julia 1.1\nThis method is available as of Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Serialization/#Serialization.deserialize","page":"Serialization","title":"Serialization.deserialize","text":"deserialize(stream)\n\nRead a value written by serialize. deserialize assumes the binary data read from stream is correct and has been serialized by a compatible implementation of serialize. deserialize is designed for simplicity and performance, and so does not validate the data read. Malformed data can result in process termination. The caller must ensure the integrity and correctness of data read from stream.\n\n\n\n\n\ndeserialize(filename::AbstractString)\n\nOpen a file and deserialize its contents.\n\ncompat: Julia 1.1\nThis method is available as of Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Serialization/#Serialization.writeheader","page":"Serialization","title":"Serialization.writeheader","text":"Serialization.writeheader(s::AbstractSerializer)\n\nWrite an identifying header to the specified serializer. The header consists of 8 bytes as follows:\n\nOffset Description\n0 tag byte (0x37)\n1-2 signature bytes \"JL\"\n3 protocol version\n4 bits 0-1: endianness: 0 = little, 1 = big\n4 bits 2-3: platform: 0 = 32-bit, 1 = 64-bit\n5-7 reserved\n\n\n\n\n\n","category":"function"},{"location":"tutorials/external/#External-Tutorials","page":"External Tutorials","title":"External Tutorials","text":"","category":"section"},{"location":"tutorials/external/","page":"External Tutorials","title":"External Tutorials","text":"We have created a non-exhaustive list of community provided Julia tutorials. Check them out to learn Julia through the lens of someone from the community.","category":"page"},{"location":"stdlib/Future/","page":"Future","title":"Future","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Future/docs/src/index.md\"","category":"page"},{"location":"stdlib/Future/#Future","page":"Future","title":"Future","text":"","category":"section"},{"location":"stdlib/Future/","page":"Future","title":"Future","text":"The Future module implements future behavior of already existing functions, which will replace the current version in a future release of Julia.","category":"page"},{"location":"stdlib/Future/","page":"Future","title":"Future","text":"Future.copy!\nFuture.randjump","category":"page"},{"location":"stdlib/Future/#Future.copy!","page":"Future","title":"Future.copy!","text":"Future.copy!(dst, src) -> dst\n\nCopy src into dst.\n\ncompat: Julia 1.1\nThis function has moved to Base with Julia 1.1, consider using copy!(dst, src) instead. Future.copy! will be deprecated in the future.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Future/#Future.randjump","page":"Future","title":"Future.randjump","text":"randjump(r::MersenneTwister, steps::Integer) -> MersenneTwister\n\nCreate an initialized MersenneTwister object, whose state is moved forward (without generating numbers) from r by steps steps. One such step corresponds to the generation of two Float64 numbers. For each different value of steps, a large polynomial has to be generated internally. One is already pre-computed for steps=big(10)^20.\n\n\n\n\n\n","category":"function"},{"location":"manual/documentation/#man-documentation","page":"Documentation","title":"Documentation","text":"","category":"section"},{"location":"manual/documentation/#Accessing-Documentation","page":"Documentation","title":"Accessing Documentation","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Documentation can be accessed at the REPL or in IJulia by typing ? followed by the name of a function or macro, and pressing Enter. For example,","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"?cos\n?@time\n?r\"\"","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"will show documentation for the relevant function, macro or string macro respectively. Most Julia environments provide a way to access documentation directly:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"VS Code shows documentation when you hover over a function name. You can also use the Julia panel in the sidebar to search for documentation.\nIn Pluto, open the \"Live Docs\" panel on the bottom right.\nIn Juno using Ctrl-J, Ctrl-D will show the documentation for the object under the cursor.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Docs.hasdoc(module, name)::Bool tells whether a name has a docstring. Docs.undocumented_names(module; all) returns the undocumented names in a module.","category":"page"},{"location":"manual/documentation/#Writing-Documentation","page":"Documentation","title":"Writing Documentation","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Julia enables package developers and users to document functions, types and other objects easily via a built-in documentation system.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"The basic syntax is simple: any string appearing just before an object (function, macro, type or instance) will be interpreted as documenting it (these are called docstrings). Note that no blank lines or comments may intervene between a docstring and the documented object. Here is a basic example:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"Tell whether there are too foo items in the array.\"\nfoo(xs::Array) = ...","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Documentation is interpreted as Markdown, so you can use indentation and code fences to delimit code examples from text. Technically, any object can be associated with any other as metadata; Markdown happens to be the default, but one can construct other string macros and pass them to the @doc macro just as well.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"note: Note\nMarkdown support is implemented in the Markdown standard library and for a full list of supported syntax see the documentation.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Here is a more complex example, still using Markdown:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"\"\"\n bar(x[, y])\n\nCompute the Bar index between `x` and `y`.\n\nIf `y` is unspecified, compute the Bar index between all pairs of columns of `x`.\n\n# Examples\n```julia-repl\njulia> bar([1, 2], [1, 2])\n1\n```\n\"\"\"\nfunction bar(x, y) ...","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"As in the example above, we recommend following some simple conventions when writing documentation:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Always show the signature of a function at the top of the documentation, with a four-space indent so that it is printed as Julia code.\nThis can be identical to the signature present in the Julia code (like mean(x::AbstractArray)), or a simplified form. Optional arguments should be represented with their default values (i.e. f(x, y=1)) when possible, following the actual Julia syntax. Optional arguments which do not have a default value should be put in brackets (i.e. f(x[, y]) and f(x[, y[, z]])). An alternative solution is to use several lines: one without optional arguments, the other(s) with them. This solution can also be used to document several related methods of a given function. When a function accepts many keyword arguments, only include a placeholder in the signature (i.e. f(x; )), and give the complete list under an # Arguments section (see point 4 below).\nInclude a single one-line sentence describing what the function does or what the object represents after the simplified signature block. If needed, provide more details in a second paragraph, after a blank line.\nThe one-line sentence should use the imperative form (\"Do this\", \"Return that\") instead of the third person (do not write \"Returns the length...\") when documenting functions. It should end with a period. If the meaning of a function cannot be summarized easily, splitting it into separate composable parts could be beneficial (this should not be taken as an absolute requirement for every single case though).\nDo not repeat yourself.\nSince the function name is given by the signature, there is no need to start the documentation with \"The function bar...\": go straight to the point. Similarly, if the signature specifies the types of the arguments, mentioning them in the description is redundant.\nOnly provide an argument list when really necessary.\nFor simple functions, it is often clearer to mention the role of the arguments directly in the description of the function's purpose. An argument list would only repeat information already provided elsewhere. However, providing an argument list can be a good idea for complex functions with many arguments (in particular keyword arguments). In that case, insert it after the general description of the function, under an # Arguments header, with one - bullet for each argument. The list should mention the types and default values (if any) of the arguments:\n\"\"\"\n...\n# Arguments\n- `n::Integer`: the number of elements to compute.\n- `dim::Integer=1`: the dimensions along which to perform the computation.\n...\n\"\"\"\nProvide hints to related functions.\nSometimes there are functions of related functionality. To increase discoverability please provide a short list of these in a See also paragraph.\nSee also [`bar!`](@ref), [`baz`](@ref), [`baaz`](@ref).\nInclude any code examples in an # Examples section.\nExamples should, whenever possible, be written as doctests. A doctest is a fenced code block (see Code blocks) starting with ```jldoctest and contains any number of julia> prompts together with inputs and expected outputs that mimic the Julia REPL.\nnote: Note\nDoctests are enabled by Documenter.jl. For more detailed documentation see Documenter's manual.\nFor example in the following docstring a variable a is defined and the expected result, as printed in a Julia REPL, appears afterwards:\n\"\"\"\nSome nice documentation here.\n\n# Examples\n```jldoctest\njulia> a = [1 2; 3 4]\n2×2 Array{Int64,2}:\n 1 2\n 3 4\n```\n\"\"\"\nwarning: Warning\nCalling rand and other RNG-related functions should be avoided in doctests since they will not produce consistent outputs during different Julia sessions. If you would like to show some random number generation related functionality, one option is to explicitly construct and seed your own RNG object (see Random) and pass it to the functions you are doctesting.Operating system word size (Int32 or Int64) as well as path separator differences (/ or \\) will also affect the reproducibility of some doctests.Note that whitespace in your doctest is significant! The doctest will fail if you misalign the output of pretty-printing an array, for example.\nYou can then run make -C doc doctest=true to run all the doctests in the Julia Manual and API documentation, which will ensure that your example works.\nTo indicate that the output result is truncated, you may write [...] at the line where checking should stop. This is useful to hide a stacktrace (which contains non-permanent references to lines of julia code) when the doctest shows that an exception is thrown, for example:\n```jldoctest\njulia> div(1, 0)\nERROR: DivideError: integer division error\n[...]\n```\nExamples that are untestable should be written within fenced code blocks starting with ```julia so that they are highlighted correctly in the generated documentation.\ntip: Tip\nWherever possible examples should be self-contained and runnable so that readers are able to try them out without having to include any dependencies.\nUse backticks to identify code and equations.\nJulia identifiers and code excerpts should always appear between backticks ` to enable highlighting. Equations in the LaTeX syntax can be inserted between double backticks ``. Use Unicode characters rather than their LaTeX escape sequence, i.e. ``α = 1`` rather than ``\\\\alpha = 1``.\nPlace the starting and ending \"\"\" characters on lines by themselves.\nThat is, write:\n\"\"\"\n...\n\n...\n\"\"\"\nf(x, y) = ...\nrather than:\n\"\"\"...\n\n...\"\"\"\nf(x, y) = ...\nThis makes it clearer where docstrings start and end.\nRespect the line length limit used in the surrounding code.\nDocstrings are edited using the same tools as code. Therefore, the same conventions should apply. It is recommended that lines are at most 92 characters wide.\nProvide information allowing custom types to implement the function in an # Implementation section. These implementation details are intended for developers rather than users, explaining e.g. which functions should be overridden and which functions automatically use appropriate fallbacks. Such details are best kept separate from the main description of the function's behavior.\nFor long docstrings, consider splitting the documentation with an # Extended help header. The typical help-mode will show only the material above the header; you can access the full help by adding a '?' at the beginning of the expression (i.e., \"??foo\" rather than \"?foo\").","category":"page"},{"location":"manual/documentation/#Functions-and-Methods","page":"Documentation","title":"Functions & Methods","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Functions in Julia may have multiple implementations, known as methods. While it's good practice for generic functions to have a single purpose, Julia allows methods to be documented individually if necessary. In general, only the most generic method should be documented, or even the function itself (i.e. the object created without any methods by function bar end). Specific methods should only be documented if their behaviour differs from the more generic ones. In any case, they should not repeat the information provided elsewhere. For example:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"\"\"\n *(x, y, z...)\n\nMultiplication operator. `x * y * z *...` calls this function with multiple\narguments, i.e. `*(x, y, z...)`.\n\"\"\"\nfunction *(x, y, z...)\n # ... [implementation sold separately] ...\nend\n\n\"\"\"\n *(x::AbstractString, y::AbstractString, z::AbstractString...)\n\nWhen applied to strings, concatenates them.\n\"\"\"\nfunction *(x::AbstractString, y::AbstractString, z::AbstractString...)\n # ... [insert secret sauce here] ...\nend\n\nhelp?> *\nsearch: * .*\n\n *(x, y, z...)\n\n Multiplication operator. x * y * z *... calls this function with multiple\n arguments, i.e. *(x,y,z...).\n\n *(x::AbstractString, y::AbstractString, z::AbstractString...)\n\n When applied to strings, concatenates them.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"When retrieving documentation for a generic function, the metadata for each method is concatenated with the catdoc function, which can of course be overridden for custom types.","category":"page"},{"location":"manual/documentation/#Advanced-Usage","page":"Documentation","title":"Advanced Usage","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"The @doc macro associates its first argument with its second in a per-module dictionary called META.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"To make it easier to write documentation, the parser treats the macro name @doc specially: if a call to @doc has one argument, but another expression appears after a single line break, then that additional expression is added as an argument to the macro. Therefore the following syntax is parsed as a 2-argument call to @doc:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"@doc raw\"\"\"\n...\n\"\"\"\nf(x) = x","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"This makes it possible to use expressions other than normal string literals (such as the raw\"\" string macro) as a docstring.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"When used for retrieving documentation, the @doc macro (or equally, the doc function) will search all META dictionaries for metadata relevant to the given object and return it. The returned object (some Markdown content, for example) will by default display itself intelligently. This design also makes it easy to use the doc system in a programmatic way; for example, to re-use documentation between different versions of a function:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"@doc \"...\" foo!\n@doc (@doc foo!) foo","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Or for use with Julia's metaprogramming functionality:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"for (f, op) in ((:add, :+), (:subtract, :-), (:multiply, :*), (:divide, :/))\n @eval begin\n $f(a, b) = $op(a, b)\n end\nend\n@doc \"`add(a, b)` adds `a` and `b` together\" add\n@doc \"`subtract(a, b)` subtracts `b` from `a`\" subtract","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Documentation in non-toplevel blocks, such as begin, if, for, let, and inner constructors, should be added to the documentation system via @doc as well. For example:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"if condition()\n @doc \"...\"\n f(x) = x\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"will add documentation to f(x) when condition() is true. Note that even if f(x) goes out of scope at the end of a block, its documentation will remain.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"It is possible to make use of metaprogramming to assist in the creation of documentation. When using string-interpolation within the docstring you will need to use an extra $ as shown with $($name):","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"for func in (:day, :dayofmonth)\n name = string(func)\n @eval begin\n @doc \"\"\"\n $($name)(dt::TimeType) -> Int64\n\n The day of month of a `Date` or `DateTime` as an `Int64`.\n \"\"\" $func(dt::Dates.TimeType)\n end\nend","category":"page"},{"location":"manual/documentation/#Dynamic-documentation","page":"Documentation","title":"Dynamic documentation","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Sometimes the appropriate documentation for an instance of a type depends on the field values of that instance, rather than just on the type itself. In these cases, you can add a method to Docs.getdoc for your custom type that returns the documentation on a per-instance basis. For instance,","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"struct MyType\n value::Int\nend\n\nDocs.getdoc(t::MyType) = \"Documentation for MyType with value $(t.value)\"\n\nx = MyType(1)\ny = MyType(2)","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"?x will display \"Documentation for MyType with value 1\" while ?y will display \"Documentation for MyType with value 2\".","category":"page"},{"location":"manual/documentation/#Syntax-Guide","page":"Documentation","title":"Syntax Guide","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"This guide provides a comprehensive overview of how to attach documentation to all Julia syntax constructs for which providing documentation is possible.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"In the following examples \"...\" is used to illustrate an arbitrary docstring.","category":"page"},{"location":"manual/documentation/#and-\\-characters","page":"Documentation","title":"$ and \\ characters","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"The $ and \\ characters are still parsed as string interpolation or start of an escape sequence in docstrings too. The raw\"\" string macro together with the @doc macro can be used to avoid having to escape them. This is handy when the docstrings include LaTeX or Julia source code examples containing interpolation:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"@doc raw\"\"\"\n```math\n\\LaTeX\n```\n\"\"\"\nfunction f end","category":"page"},{"location":"manual/documentation/#Functions-and-Methods-2","page":"Documentation","title":"Functions and Methods","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nfunction f end\n\n\"...\"\nf","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the function f. The first version is the preferred syntax, however both are equivalent.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nf(x) = x\n\n\"...\"\nfunction f(x)\n return x\nend\n\n\"...\"\nf(x)","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the method f(::Any).","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nf(x, y = 1) = x + y","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to two Methods, namely f(::Any) and f(::Any, ::Any).","category":"page"},{"location":"manual/documentation/#Macros","page":"Documentation","title":"Macros","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nmacro m(x) end","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the @m(::Any) macro definition.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\n:(@m1)\n\n\"...\"\nmacro m2 end","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the macros named @m1 and @m2.","category":"page"},{"location":"manual/documentation/#Types","page":"Documentation","title":"Types","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nabstract type T1 end\n\n\"...\"\nmutable struct T2\n ...\nend\n\n\"...\"\nstruct T3\n ...\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds the docstring \"...\" to types T1, T2, and T3.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nT1\n\n\"...\"\nT2\n\n\"...\"\nT3","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds the docstring \"...\" to types T1, T2, and T3. The previous version is the preferred syntax, however both are equivalent.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nstruct T\n \"x\"\n x\n \"y\"\n y\n\n @doc \"Inner constructor\"\n function T()\n new(...)\n end\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to type T, \"x\" to field T.x, \"y\" to field T.y, and \"Inner constructor\" to the inner constructor T(). Also applicable to mutable struct types.","category":"page"},{"location":"manual/documentation/#Modules","page":"Documentation","title":"Modules","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nmodule M end\n\nmodule M\n\n\"...\"\nM\n\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the Module M. Adding the docstring above the Module is the preferred syntax, however both are equivalent.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nbaremodule M\n# ...\nend\n\nbaremodule M\n\nimport Base: @doc\n\n\"...\"\nf(x) = x\n\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Documenting a baremodule by placing a docstring above the expression automatically imports @doc into the module. These imports must be done manually when the module expression is not documented.","category":"page"},{"location":"manual/documentation/#Global-Variables","page":"Documentation","title":"Global Variables","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nconst a = 1\n\n\"...\"\nb = 2\n\n\"...\"\nglobal c = 3","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the Bindings a, b, and c.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Bindings are used to store a reference to a particular Symbol in a Module without storing the referenced value itself.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"note: Note\nWhen a const definition is only used to define an alias of another definition, such as is the case with the function div and its alias ÷ in Base, do not document the alias and instead document the actual function.If the alias is documented and not the real definition then the docsystem (? mode) will not return the docstring attached to the alias when the real definition is searched for.For example you should write\"...\"\nf(x) = x + 1\nconst alias = frather thanf(x) = x + 1\n\"...\"\nconst alias = f","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nsym","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the value associated with sym. However, it is preferred that sym is documented where it is defined.","category":"page"},{"location":"manual/documentation/#Multiple-Objects","page":"Documentation","title":"Multiple Objects","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\na, b","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to a and b each of which should be a documentable expression. This syntax is equivalent to","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\na\n\n\"...\"\nb","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Any number of expressions many be documented together in this way. This syntax can be useful when two functions are related, such as non-mutating and mutating versions f and f!.","category":"page"},{"location":"manual/documentation/#Macro-generated-code","page":"Documentation","title":"Macro-generated code","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\n@m expression","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the expression generated by expanding @m expression. This allows for expressions decorated with @inline, @noinline, @generated, or any other macro to be documented in the same way as undecorated expressions.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Macro authors should take note that only macros that generate a single expression will automatically support docstrings. If a macro returns a block containing multiple subexpressions then the subexpression that should be documented must be marked using the @__doc__ macro.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"The @enum macro makes use of @__doc__ to allow for documenting Enums. Examining its definition should serve as an example of how to use @__doc__ correctly.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Core.@__doc__","category":"page"},{"location":"manual/documentation/#Core.@__doc__","page":"Documentation","title":"Core.@__doc__","text":"@__doc__(ex)\n\nLow-level macro used to mark expressions returned by a macro that should be documented. If more than one expression is marked then the same docstring is applied to each expression.\n\nmacro example(f)\n quote\n $(f)() = 0\n @__doc__ $(f)(x) = 1\n $(f)(x, y) = 2\n end |> esc\nend\n\n@__doc__ has no effect when a macro that uses it is not documented.\n\ncompat: Julia 1.12\nThis section documents a very subtle corner case that is only relevant to macros which themselves both define other macros and then attempt to use them within the same expansion. Such macros were impossible to write prior to Julia 1.12 and are still quite rare. If you are not writing such a macro, you may ignore this note.In versions prior to Julia 1.12, macroexpansion would recursively expand through Expr(:toplevel) blocks. This behavior was changed in Julia 1.12 to allow macros to recursively define other macros and use them in the same returned expression. However, to preserve backwards compatibility with existing uses of @__doc__, the doc system will still expand through Expr(:toplevel) blocks when looking for @__doc__ markers. As a result, macro-defining-macros will have an observable behavior difference when annotated with a docstring:julia> macro macroception()\n Expr(:toplevel, :(macro foo() 1 end), :(@foo))\nend\n\njulia> @macroception\n1\n\njulia> \"Docstring\" @macroception\nERROR: LoadError: UndefVarError: `@foo` not defined in `Main`The supported workaround is to manually expand the @__doc__ macro in the defining macro, which the docsystem will recognize and suppress the recursive expansion:julia> macro macroception()\n Expr(:toplevel,\n macroexpand(__module__, :(@__doc__ macro foo() 1 end); recursive=false),\n :(@foo))\nend\n\njulia> @macroception\n1\n\njulia> \"Docstring\" @macroception\n1\n\n\n\n\n\n","category":"macro"},{"location":"manual/noteworthy-differences/#Noteworthy-Differences-from-other-Languages","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"","category":"section"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-MATLAB","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from MATLAB","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Although MATLAB users may find Julia's syntax familiar, Julia is not a MATLAB clone. There are major syntactic and functional differences. The following are some noteworthy differences that may trip up Julia users accustomed to MATLAB:","category":"page"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia arrays are indexed with square brackets, A[i,j].\nJulia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well. To avoid this, use A = copy(B).\nJulia values are not copied when passed to a function. If a function modifies an array, the changes will be visible in the caller.\nJulia does not automatically grow arrays in an assignment statement. Whereas in MATLAB a(4) = 3.2 can create the array a = [0 0 0 3.2] and a(5) = 7 can grow it into a = [0 0 0 3.2 7], the corresponding Julia statement a[5] = 7 throws an error if the length of a is less than 5 or if this statement is the first use of the identifier a. Julia has push! and append!, which grow Vectors much more efficiently than MATLAB's a(end+1) = val.\nThe imaginary unit sqrt(-1) is represented in Julia as im, not i or j as in MATLAB.\nIn Julia, literal numbers without a decimal point (such as 42) create integers instead of floating point numbers. As a result, some operations can throw a domain error if they expect a float; for example, julia> a = -1; 2^a throws a domain error, as the result is not an integer (see the FAQ entry on domain errors for details).\nIn Julia, multiple values are returned and assigned as tuples, e.g. (a, b) = (1, 2) or a, b = 1, 2. MATLAB's nargout, which is often used in MATLAB to do optional work based on the number of returned values, does not exist in Julia. Instead, users can use optional and keyword arguments to achieve similar capabilities.\nJulia has true one-dimensional arrays. Column vectors are of size N, not Nx1. For example, rand(N) makes a 1-dimensional array.\nIn Julia, [x,y,z] will always construct a 3-element array containing x, y and z.\nTo concatenate in the first (\"vertical\") dimension use either vcat(x,y,z) or separate with semicolons ([x; y; z]).\nTo concatenate in the second (\"horizontal\") dimension use either hcat(x,y,z) or separate with spaces ([x y z]).\nTo construct block matrices (concatenating in the first two dimensions), use either hvcat or combine spaces and semicolons ([a b; c d]).\nIn Julia, a:b and a:b:c construct AbstractRange objects. To construct a full vector like in MATLAB, use collect(a:b). Generally, there is no need to call collect though. An AbstractRange object will act like a normal array in most cases but is more efficient because it lazily computes its values. This pattern of creating specialized objects instead of full arrays is used frequently, and is also seen in functions such as range, or with iterators such as enumerate, and zip. The special objects can mostly be used as if they were normal arrays.\nFunctions in Julia return values from their last expression or the return keyword instead of listing the names of variables to return in the function definition (see The return Keyword for details).\nA Julia script may contain any number of functions, and all definitions will be externally visible when the file is loaded. Function definitions can be loaded from files outside the current working directory.\nIn Julia, reductions such as sum, prod, and maximum are performed over every element of an array when called with a single argument, as in sum(A), even if A has more than one dimension.\nIn Julia, parentheses must be used to call a function with zero arguments, like in rand().\nJulia discourages the use of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end with semicolons. println or @printf can be used to print specific output.\nIn Julia, if A and B are arrays, logical comparison operations like A == B do not return an array of booleans. Instead, use A .== B, and similarly for the other boolean operators like <, >.\nIn Julia, when you want to apply a scalar-valued function elementwise to an array, use broadcasting syntax: f.(A) instead of f(A). In some cases, both operations are defined but mean different things: in MATLAB exp(A) applies elementwise and expm(A) is the matrix exponential, but in Julia exp.(A) applies elementwise and exp(A) is the matrix exponential.\nIn Julia, the operators &, |, and ⊻ (xor) perform the bitwise operations equivalent to and, or, and xor respectively in MATLAB, and have precedence similar to Python's bitwise operators (unlike C). They can operate on scalars or element-wise across arrays and can be used to combine logical arrays, but note the difference in order of operations: parentheses may be required (e.g., to select elements of A equal to 1 or 2 use (A .== 1) .| (A .== 2)).\nIn Julia, the elements of a collection can be passed as arguments to a function using the splat operator ..., as in xs=[1,2]; f(xs...).\nJulia's svd returns singular values as a vector instead of as a dense diagonal matrix.\nIn Julia, ... is not used to continue lines of code. Instead, incomplete expressions automatically continue onto the next line.\nIn both Julia and MATLAB, the variable ans is set to the value of the last expression issued in an interactive session. In Julia, unlike MATLAB, ans is not set when Julia code is run in non-interactive mode.\nJulia's structs do not support dynamically adding fields at runtime, unlike MATLAB's classes. Instead, use a Dict. Dict in Julia isn't ordered.\nIn Julia each module has its own global scope/namespace, whereas in MATLAB there is just one global scope.\nIn MATLAB, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression x(x>3) or in the statement x(x>3) = [] to modify x in-place. In contrast, Julia provides the higher order functions filter and filter!, allowing users to write filter(z->z>3, x) and filter!(z->z>3, x) as alternatives to the corresponding transliterations x[x.>3] and x = x[x.>3]. Using filter! reduces the use of temporary arrays.\nThe analogue of extracting (or \"dereferencing\") all elements of a cell array, e.g. in vertcat(A{:}) in MATLAB, is written using the splat operator in Julia, e.g. as vcat(A...).\nIn Julia, the adjoint function performs conjugate transposition; in MATLAB, adjoint provides the \"adjugate\" or classical adjoint, which is the transpose of the matrix of cofactors.\nIn Julia, a^b^c is evaluated a^(b^c) while in MATLAB it's (a^b)^c.","category":"page"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-R","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from R","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"One of Julia's goals is to provide an effective language for data analysis and statistical programming. For users coming to Julia from R, these are some noteworthy differences:","category":"page"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia's single quotes enclose characters, not strings.\nJulia can create substrings by indexing into strings. In R, strings must be converted into character vectors before creating substrings.\nIn Julia, like Python but unlike R, strings can be created with triple quotes \"\"\" ... \"\"\". This syntax is convenient for constructing strings that contain line breaks.\nIn Julia, varargs are specified using the splat operator ..., which always follows the name of a specific variable, unlike R, for which ... can occur in isolation.\nIn Julia, modulus is mod(a, b), not a %% b. % in Julia is the remainder operator.\nJulia constructs vectors using brackets. Julia's [1, 2, 3] is the equivalent of R's c(1, 2, 3).\nIn Julia, not all data structures support logical indexing. Furthermore, logical indexing in Julia is supported only with vectors of length equal to the object being indexed. For example:\nIn R, c(1, 2, 3, 4)[c(TRUE, FALSE)] is equivalent to c(1, 3).\nIn R, c(1, 2, 3, 4)[c(TRUE, FALSE, TRUE, FALSE)] is equivalent to c(1, 3).\nIn Julia, [1, 2, 3, 4][[true, false]] throws a BoundsError.\nIn Julia, [1, 2, 3, 4][[true, false, true, false]] produces [1, 3].\nLike many languages, Julia does not always allow operations on vectors of different lengths, unlike R where the vectors only need to share a common index range. For example, c(1, 2, 3, 4) + c(1, 2) is valid R but the equivalent [1, 2, 3, 4] + [1, 2] will throw an error in Julia.\nJulia allows an optional trailing comma when that comma does not change the meaning of code. This can cause confusion among R users when indexing into arrays. For example, x[1,] in R would return the first row of a matrix; in Julia, however, the comma is ignored, so x[1,] == x[1], and will return the first element. To extract a row, be sure to use :, as in x[1,:].\nJulia's map takes the function first, then its arguments, unlike lapply(, function, ...) in R. Similarly Julia's equivalent of apply(X, MARGIN, FUN, ...) in R is mapslices where the function is the first argument.\nMultivariate apply in R, e.g. mapply(choose, 11:13, 1:3), can be written as broadcast(binomial, 11:13, 1:3) in Julia. Equivalently Julia offers a shorter dot syntax for vectorizing functions binomial.(11:13, 1:3).\nJulia uses end to denote the end of conditional blocks, like if, loop blocks, like while/ for, and functions. In lieu of the one-line if ( cond ) statement, Julia allows statements of the form if cond; statement; end, cond && statement and !cond || statement. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g. cond && (x = value).\nIn Julia, <-, <<- and -> are not assignment operators.\nJulia's -> creates an anonymous function.\nJulia's * operator can perform matrix multiplication, unlike in R. If A and B are matrices, then A * B denotes a matrix multiplication in Julia, equivalent to R's A %*% B. In R, this same notation would perform an element-wise (Hadamard) product. To get the element-wise multiplication operation, you need to write A .* B in Julia.\nJulia performs matrix transposition using the transpose function and conjugated transposition using the ' operator or the adjoint function. Julia's transpose(A) is therefore equivalent to R's t(A). Additionally a non-recursive transpose in Julia is provided by the permutedims function.\nJulia does not require parentheses when writing if statements or for/while loops: use for i in [1, 2, 3] instead of for (i in c(1, 2, 3)) and if i == 1 instead of if (i == 1).\nJulia does not treat the numbers 0 and 1 as Booleans. You cannot write if (1) in Julia, because if statements accept only booleans. Instead, you can write if true, if Bool(1), or if 1==1.\nJulia does not provide nrow and ncol. Instead, use size(M, 1) for nrow(M) and size(M, 2) for ncol(M).\nJulia is careful to distinguish scalars, vectors and matrices. In R, 1 and c(1) are the same. In Julia, they cannot be used interchangeably.\nJulia's diag and diagm are not like R's.\nJulia cannot assign to the results of function calls on the left hand side of an assignment operation: you cannot write diag(M) = fill(1, n).\nJulia discourages populating the main namespace with functions. Most statistical functionality for Julia is found in packages under the JuliaStats organization. For example:\nFunctions pertaining to probability distributions are provided by the Distributions package.\nThe DataFrames package provides data frames.\nGeneralized linear models are provided by the GLM package.\nJulia provides tuples and real hash tables, but not R-style lists. When returning multiple items, you should typically use a tuple or a named tuple: instead of list(a = 1, b = 2), use (1, 2) or (a=1, b=2).\nJulia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that table(x::TypeA) and table(x::TypeB) act like R's table.TypeA(x) and table.TypeB(x).\nIn Julia, values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. This is very different from R and allows new functions to operate on large data structures much more efficiently.\nIn Julia, vectors and matrices are concatenated using hcat, vcat and hvcat, not c, rbind and cbind like in R.\nIn Julia, a range like a:b is not shorthand for a vector like in R, but is a specialized AbstractRange object that is used for iteration. To convert a range into a vector, use collect(a:b).\nThe : operator has a different precedence in R and Julia. In particular, in Julia arithmetic operators have higher precedence than the : operator, whereas the reverse is true in R. For example, 1:n-1 in Julia is equivalent to 1:(n-1) in R.\nJulia's max and min are the equivalent of pmax and pmin respectively in R, but both arguments need to have the same dimensions. While maximum and minimum replace max and min in R, there are important differences.\nJulia's sum, prod, maximum, and minimum are different from their counterparts in R. They all accept an optional keyword argument dims, which indicates the dimensions, over which the operation is carried out. For instance, let A = [1 2; 3 4] in Julia and B <- rbind(c(1,2),c(3,4)) be the same matrix in R. Then sum(A) gives the same result as sum(B), but sum(A, dims=1) is a row vector containing the sum over each column and sum(A, dims=2) is a column vector containing the sum over each row. This contrasts to the behavior of R, where separate colSums(B) and rowSums(B) functions provide these functionalities. If the dims keyword argument is a vector, then it specifies all the dimensions over which the sum is performed, while retaining the dimensions of the summed array, e.g. sum(A, dims=(1,2)) == hcat(10). It should be noted that there is no error checking regarding the second argument.\nJulia has several functions that can mutate their arguments. For example, it has both sort and sort!.\nIn R, performance requires vectorization. In Julia, almost the opposite is true: the best performing code is often achieved by using devectorized loops.\nJulia is eagerly evaluated and does not support R-style lazy evaluation. For most users, this means that there are very few unquoted expressions or column names.\nJulia does not support the NULL type. The closest equivalent is nothing, but it behaves like a scalar value rather than like a list. Use x === nothing instead of is.null(x).\nIn Julia, missing values are represented by the missing object rather than by NA. Use ismissing(x) (or ismissing.(x) for element-wise operation on vectors) instead of is.na(x). The skipmissing function is generally used instead of na.rm=TRUE (though in some particular cases functions take a skipmissing argument).\nJulia lacks the equivalent of R's assign or get.\nIn Julia, return does not require parentheses.\nIn R, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression x[x>3] or in the statement x = x[x>3] to modify x in-place. In contrast, Julia provides the higher order functions filter and filter!, allowing users to write filter(z->z>3, x) and filter!(z->z>3, x) as alternatives to the corresponding transliterations x[x.>3] and x = x[x.>3]. Using filter! reduces the use of temporary arrays.","category":"page"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-Python","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from Python","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia's for, if, while, etc. blocks are terminated by the end keyword. Indentation level is not significant as it is in Python. Unlike Python, Julia has no pass keyword.\nStrings are denoted by double quotation marks (\"text\") in Julia (with three double quotation marks for multi-line strings), whereas in Python they can be denoted either by single ('text') or double quotation marks (\"text\"). Single quotation marks are used for characters in Julia ('c').\nString concatenation is done with * in Julia, not + like in Python. Analogously, string repetition is done with ^, not *. Implicit string concatenation of string literals like in Python (e.g. 'ab' 'cd' == 'abcd') is not done in Julia.\nPython Lists—flexible but slow—correspond to the Julia Vector{Any} type or more generally Vector{T} where T is some non-concrete element type. \"Fast\" arrays like NumPy arrays that store elements in-place (i.e., dtype is np.float64, [('f1', np.uint64), ('f2', np.int32)], etc.) can be represented by Array{T} where T is a concrete, immutable element type. This includes built-in types like Float64, Int32, Int64 but also more complex types like Tuple{UInt64,Float64} and many user-defined types as well.\nIn Julia, indexing of arrays, strings, etc. is 1-based not 0-based.\nJulia's slice indexing includes the last element, unlike in Python. a[2:3] in Julia is a[1:3] in Python.\nUnlike Python, Julia allows AbstractArrays with arbitrary indexes. Python's special interpretation of negative indexing, a[-1] and a[-2], should be written a[end] and a[end-1] in Julia.\nJulia requires end for indexing until the last element. x[1:] in Python is equivalent to x[2:end] in Julia.\nIn Julia, : before any object creates a Symbol or quotes an expression; so, x[:5] is same as x[5]. If you want to get the first n elements of an array, then use range indexing.\nJulia's range indexing has the format of x[start:step:stop], whereas Python's format is x[start:(stop+1):step]. Hence, x[0:10:2] in Python is equivalent to x[1:2:10] in Julia. Similarly, x[::-1] in Python, which refers to the reversed array, is equivalent to x[end:-1:1] in Julia.\nIn Julia, ranges can be constructed independently as start:step:stop, the same syntax it uses in array-indexing. The range function is also supported.\nIn Julia, indexing a matrix with arrays like X[[1,2], [1,3]] refers to a sub-matrix that contains the intersections of the first and second rows with the first and third columns. In Python, X[[1,2], [1,3]] refers to a vector that contains the values of cell [1,1] and [2,3] in the matrix. X[[1,2], [1,3]] in Julia is equivalent with X[np.ix_([0,1],[0,2])] in Python. X[[0,1], [0,2]] in Python is equivalent with X[[CartesianIndex(1,1), CartesianIndex(2,3)]] in Julia.\nJulia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.\nJulia arrays are column-major (Fortran-ordered) whereas NumPy arrays are row-major (C-ordered) by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to NumPy (see relevant section of Performance Tips).\nJulia's updating operators (e.g. +=, -=, ...) are not in-place whereas NumPy's are. This means A = [1, 1]; B = A; B += [3, 3] doesn't change values in A, it rather rebinds the name B to the result of the right-hand side B = B + 3, which is a new array. For in-place operation, use B .+= 3 (see also dot operators), explicit loops, or InplaceOps.jl.\nJulia evaluates default values of function arguments every time the method is invoked, unlike in Python where the default values are evaluated only once when the function is defined. For example, the function f(x=rand()) = x returns a new random number every time it is invoked without argument. On the other hand, the function g(x=[1,2]) = push!(x,3) returns [1,2,3] every time it is called as g().\nIn Julia, keyword arguments must be passed using keywords, unlike Python in which it is usually possible to pass them positionally. Attempting to pass a keyword argument positionally alters the method signature leading to a MethodError or calling of the wrong method.\nIn Julia % is the remainder operator, whereas in Python it is the modulus.\nIn Julia, the commonly used Int type corresponds to the machine integer type (Int32 or Int64), unlike in Python, where int is an arbitrary length integer. This means in Julia the Int type will overflow, such that 2^64 == 0. If you need larger values use another appropriate type, such as Int128, BigInt or a floating point type like Float64.\nThe imaginary unit sqrt(-1) is represented in Julia as im, not j as in Python.\nIn Julia, the exponentiation operator is ^, not ** as in Python.\nJulia uses nothing of type Nothing to represent a null value, whereas Python uses None of type NoneType.\nIn Julia, the standard operators over a matrix type are matrix operations, whereas, in Python, the standard operators are element-wise operations. When both A and B are matrices, A * B in Julia performs matrix multiplication, not element-wise multiplication as in Python. A * B in Julia is equivalent with A @ B in Python, whereas A * B in Python is equivalent with A .* B in Julia.\nIn Julia, when you want to apply a scalar-valued function elementwise to an array, use broadcasting syntax: f.(A) instead of f(A). In some cases, both operations are defined but mean different things: numpy.exp(A) applies elementwise and scipy.linalg.expm(A) is the matrix exponential, but in Julia exp.(A) applies elementwise and exp(A) is the matrix exponential.\nThe adjoint operator ' in Julia returns an adjoint of a vector (a lazy representation of row vector), whereas the transpose operator .T over a vector in Python returns the original vector (non-op).\nIn Julia, a function may contain multiple concrete implementations (called methods), which are selected via multiple dispatch based on the types of all arguments to the call, as compared to functions in Python, which have a single implementation and no polymorphism (as opposed to Python method calls which use a different syntax and allows dispatch on the receiver of the method).\nThere are no classes in Julia. Instead there are structures (mutable or immutable), containing data but no methods.\nCalling a method of a class instance in Python (x = MyClass(*args); x.f(y)) corresponds to a function call in Julia, e.g. x = MyType(args...); f(x, y). In general, multiple dispatch is more flexible and powerful than the Python class system.\nJulia structures may have exactly one abstract supertype, whereas Python classes can inherit from one or more (abstract or concrete) superclasses.\nThe logical Julia program structure (Packages and Modules) is independent of the file structure, whereas the Python code structure is defined by directories (Packages) and files (Modules).\nIn Julia, it is idiomatic to split the text of large modules into multiple files, without introducing a new module per file. The code is reassembled inside a single module in a main file via include. While the Python equivalent (exec) is not typical for this use (it will silently clobber prior definitions), Julia programs are defined as a unit at the module level with using or import, which will only get executed once when first needed–like include in Python. Within those modules, the individual files that make up that module are loaded with include by listing them once in the intended order.\nThe ternary operator x > 0 ? 1 : -1 in Julia corresponds to a conditional expression in Python 1 if x > 0 else -1.\nIn Julia the @ symbol refers to a macro, whereas in Python it refers to a decorator.\nException handling in Julia is done using try — catch — finally, instead of try — except — finally. In contrast to Python, it is not recommended to use exception handling as part of the normal workflow in Julia (compared with Python, Julia is faster at ordinary control flow but slower at exception-catching).\nIn Julia loops are fast, there is no need to write \"vectorized\" code for performance reasons.\nBe careful with non-constant global variables in Julia, especially in tight loops. Since you can write close-to-metal code in Julia (unlike Python), the effect of globals can be drastic (see Performance Tips).\nIn Julia, rounding and truncation are explicit. Python's int(3.7) should be floor(Int, 3.7) or Int(floor(3.7)) and is distinguished from round(Int, 3.7). floor(x) and round(x) on their own return an integer value of the same type as x rather than always returning Int.\nIn Julia, parsing is explicit. Python's float(\"3.7\") would be parse(Float64, \"3.7\") in Julia.\nIn Python, the majority of values can be used in logical contexts (e.g. if \"a\": means the following block is executed, and if \"\": means it is not). In Julia, you need explicit conversion to Bool (e.g. if \"a\" throws an exception). If you want to test for a non-empty string in Julia, you would explicitly write if !isempty(\"\"). Perhaps surprisingly, in Python if \"False\" and bool(\"False\") both evaluate to True (because \"False\" is a non-empty string); in Julia, parse(Bool, \"false\") returns false.\nIn Julia, a new local scope is introduced by most code blocks, including loops and try — catch — finally. Note that comprehensions (list, generator, etc.) introduce a new local scope both in Python and Julia, whereas if blocks do not introduce a new local scope in both languages.","category":"page"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-C/C","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from C/C++","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia arrays are indexed with square brackets, and can have more than one dimension A[i,j]. This syntax is not just syntactic sugar for a reference to a pointer or address as in C/C++. See the manual entry about array construction.\nIn Julia, indexing of arrays, strings, etc. is 1-based not 0-based.\nJulia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well. Updating operators like += do not operate in-place, they are equivalent to A = A + B which rebinds the left-hand side to the result of the right-hand side expression.\nJulia arrays are column major (Fortran ordered) whereas C/C++ arrays are row major ordered by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to C/C++ (see relevant section of Performance Tips).\nJulia values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller.\nIn Julia, whitespace is significant, unlike C/C++, so care must be taken when adding/removing whitespace from a Julia program.\nIn Julia, literal numbers without a decimal point (such as 42) create signed integers, of type Int, but literals too large to fit in the machine word size will automatically be promoted to a larger size type, such as Int64 (if Int is Int32), Int128, or the arbitrarily large BigInt type. There are no numeric literal suffixes, such as L, LL, U, UL, ULL to indicate unsigned and/or signed vs. unsigned. Decimal literals are always signed, and hexadecimal literals (which start with 0x like C/C++), are unsigned, unless when they encode more than 128 bits, in which case they are of type BigInt. Hexadecimal literals also, unlike C/C++/Java and unlike decimal literals in Julia, have a type based on the length of the literal, including leading 0s. For example, 0x0 and 0x00 have type UInt8, 0x000 and 0x0000 have type UInt16, then literals with 5 to 8 hex digits have type UInt32, 9 to 16 hex digits type UInt64, 17 to 32 hex digits type UInt128, and more that 32 hex digits type BigInt. This needs to be taken into account when defining hexadecimal masks, for example ~0xf == 0xf0 is very different from ~0x000f == 0xfff0. 64 bit Float64 and 32 bit Float32 bit literals are expressed as 1.0 and 1.0f0 respectively. Floating point literals are rounded (and not promoted to the BigFloat type) if they can not be exactly represented. Floating point literals are closer in behavior to C/C++. Octal (prefixed with 0o) and binary (prefixed with 0b) literals are also treated as unsigned (or BigInt for more than 128 bits).\nIn Julia, the division operator / returns a floating point number when both operands are of integer type. To perform integer division, use div or ÷.\nIndexing an Array with floating point types is generally an error in Julia. The Julia equivalent of the C expression a[i / 2] is a[i ÷ 2 + 1], where i is of integer type.\nString literals can be delimited with either \" or \"\"\", \"\"\" delimited literals can contain \" characters without quoting it like \"\\\"\". String literals can have values of other variables or expressions interpolated into them, indicated by $variablename or $(expression), which evaluates the variable name or the expression in the context of the function.\n// indicates a Rational number, and not a single-line comment (which is # in Julia)\n#= indicates the start of a multiline comment, and =# ends it.\nFunctions in Julia return values from their last expression(s) or the return keyword. Multiple values can be returned from functions and assigned as tuples, e.g. (a, b) = myfunction() or a, b = myfunction(), instead of having to pass pointers to values as one would have to do in C/C++ (i.e. a = myfunction(&b).\nJulia does not require the use of semicolons to end statements. The results of expressions are not automatically printed (except at the interactive prompt, i.e. the REPL), and lines of code do not need to end with semicolons. println or @printf can be used to print specific output. In the REPL, ; can be used to suppress output. ; also has a different meaning within [ ], something to watch out for. ; can be used to separate expressions on a single line, but are not strictly necessary in many cases, and are more an aid to readability.\nIn Julia, the operator ⊻ (xor) performs the bitwise XOR operation, i.e. ^ in C/C++. Also, the bitwise operators do not have the same precedence as C/C++, so parenthesis may be required.\nJulia's ^ is exponentiation (pow), not bitwise XOR as in C/C++ (use ⊻, or xor, in Julia)\nJulia has two right-shift operators, >> and >>>. >> performs an arithmetic shift, >>> always performs a logical shift, unlike C/C++, where the meaning of >> depends on the type of the value being shifted.\nJulia's -> creates an anonymous function, it does not access a member via a pointer.\nJulia does not require parentheses when writing if statements or for/while loops: use for i in [1, 2, 3] instead of for (int i=1; i <= 3; i++) and if i == 1 instead of if (i == 1).\nJulia does not treat the numbers 0 and 1 as Booleans. You cannot write if (1) in Julia, because if statements accept only booleans. Instead, you can write if true, if Bool(1), or if 1==1.\nJulia uses end to denote the end of conditional blocks, like if, loop blocks, like while/ for, and functions. In lieu of the one-line if ( cond ) statement, Julia allows statements of the form if cond; statement; end, cond && statement and !cond || statement. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g. cond && (x = value), because of the operator precedence.\nJulia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.\nJulia macros operate on parsed expressions, rather than the text of the program, which allows them to perform sophisticated transformations of Julia code. Macro names start with the @ character, and have both a function-like syntax, @mymacro(arg1, arg2, arg3), and a statement-like syntax, @mymacro arg1 arg2 arg3. The forms are interchangeable; the function-like form is particularly useful if the macro appears within another expression, and is often clearest. The statement-like form is often used to annotate blocks, as in the distributed for construct: @distributed for i in 1:n; #= body =#; end. Where the end of the macro construct may be unclear, use the function-like form.\nJulia has an enumeration type, expressed using the macro @enum(name, value1, value2, ...) For example: @enum(Fruit, banana=1, apple, pear)\nBy convention, functions that modify their arguments have a ! at the end of the name, for example push!.\nIn C++, by default, you have static dispatch, i.e. you need to annotate a function as virtual, in order to have dynamic dispatch. On the other hand, in Julia every method is \"virtual\" (although it's more general than that since methods are dispatched on every argument type, not only this, using the most-specific-declaration rule).","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Namespaces","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Namespaces","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"C/C++ namespaces correspond roughly to Julia modules.\nThere are no private globals or fields in Julia. Everything is publicly accessible through fully qualified paths (or relative paths, if desired).\nusing MyNamespace::myfun (C++) corresponds roughly to import MyModule: myfun (Julia).\nusing namespace MyNamespace (C++) corresponds roughly to using MyModule (Julia)\nIn Julia, only exported symbols are made available to the calling module.\nIn C++, only elements found in the included (public) header files are made available.\nCaveat: import/using keywords (Julia) also load modules (see below).\nCaveat: import/using (Julia) works only at the global scope level (modules)\nIn C++, using namespace X works within arbitrary scopes (ex: function scope).","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Module-loading","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Module loading","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"When you think of a C/C++ \"library\", you are likely looking for a Julia \"package\".\nCaveat: C/C++ libraries often house multiple \"software modules\" whereas Julia \"packages\" typically house one.\nReminder: Julia modules are global scopes (not necessarily \"software modules\").\nInstead of build/make scripts, Julia uses \"Project Environments\" (sometimes called either \"Project\" or \"Environment\").\nBuild scripts are only needed for more complex applications (like those needing to compile or download C/C++ executables).\nTo develop application or project in Julia, you can initialize its root directory as a \"Project Environment\", and house application-specific code/packages there. This provides good control over project dependencies, and future reproducibility.\nAvailable packages are added to a \"Project Environment\" with the Pkg.add() function or Pkg REPL mode. (This does not load said package, however).\nThe list of available packages (direct dependencies) for a \"Project Environment\" are saved in its Project.toml file.\nThe full dependency information for a \"Project Environment\" is auto-generated & saved in its Manifest.toml file by Pkg.resolve().\nPackages (\"software modules\") available to the \"Project Environment\" are loaded with import or using.\nIn C/C++, you #include to get object/function declarations, and link in libraries when you build the executable.\nIn Julia, calling using/import again just brings the existing module into scope, but does not load it again (similar to adding the non-standard #pragma once to C/C++).\nDirectory-based package repositories (Julia) can be made available by adding repository paths to the Base.LOAD_PATH array.\nPackages from directory-based repositories do not require the Pkg.add() tool prior to being loaded with import or using. They are simply available to the project.\nDirectory-based package repositories are the quickest solution to developing local libraries of \"software modules\".","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Assembling-modules","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Assembling modules","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"In C/C++, .c/.cpp files are compiled & added to a library with build/make scripts.\nIn Julia, import [PkgName]/using [PkgName] statements load [PkgName].jl located in a package's [PkgName]/src/ subdirectory.\nIn turn, [PkgName].jl typically loads associated source files with calls to include \"[someotherfile].jl\".\ninclude \"./path/to/somefile.jl\" (Julia) is very similar to #include \"./path/to/somefile.jl\" (C/C++).\nHowever include \"...\" (Julia) is not used to include header files (not required).\nDo not use include \"...\" (Julia) to load code from other \"software modules\" (use import/using instead).\ninclude \"path/to/some/module.jl\" (Julia) would instantiate multiple versions of the same code in different modules (creating distinct types (etc.) with the same names).\ninclude \"somefile.jl\" is typically used to assemble multiple files within the same Julia package (\"software module\"). It is therefore relatively straightforward to ensure file are included only once (No #ifdef confusion).","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Module-interface","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Module interface","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"C++ exposes interfaces using \"public\" .h/.hpp files whereas Julia modules mark specific symbols that are intended for their users as publicor exported.\nOften, Julia modules simply add functionality by generating new \"methods\" to existing functions (ex: Base.push!).\nDevelopers of Julia packages therefore cannot rely on header files for interface documentation.\nInterfaces for Julia packages are typically described using docstrings, README.md, static web pages, ...\nSome developers choose not to export all symbols required to use their package/module, but should still mark unexported user facing symbols as public.\nUsers might be expected to access these components by qualifying functions/structs/... with the package/module name (ex: MyModule.run_this_task(...)).","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Quick-reference","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Quick reference","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Software Concept Julia C/C++\nunnamed scope begin ... end { ... }\nfunction scope function x() ... end int x() { ... }\nglobal scope module MyMod ... end namespace MyNS { ... }\nsoftware module A Julia \"package\" .h/.hpp files
    +compiled somelib.a\nassembling
    software modules SomePkg.jl: ...
    import(\"subfile1.jl\")
    import(\"subfile2.jl\")
    ... $(AR) *.o ⇒ somelib.a\nimport
    software module import SomePkg #include
    +link in somelib.a\nmodule library LOAD_PATH[], *Git repository,
    **custom package registry more .h/.hpp files
    +bigger compiled somebiglib.a","category":"page"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"* The Julia package manager supports registering multiple packages from a single Git repository.
    * This allows users to house a library of related packages in a single repository.
    ** Julia registries are primarily designed to provide versioning \\& distribution of packages.
    ** Custom package registries can be used to create a type of module library.","category":"page"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-Common-Lisp","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from Common Lisp","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia uses 1-based indexing for arrays by default, and it can also handle arbitrary index offsets.\nFunctions and variables share the same namespace (“Lisp-1”).\nThere is a Pair type, but it is not meant to be used as a COMMON-LISP:CONS. Various iterable collections can be used interchangeably in most parts of the language (eg splatting, tuples, etc). Tuples are the closest to Common Lisp lists for short collections of heterogeneous elements. Use NamedTuples in place of alists. For larger collections of homogeneous types, Arrays and Dicts should be used.\nThe typical Julia workflow for prototyping also uses continuous manipulation of the image, implemented with the Revise.jl package.\nFor performance, Julia prefers that operations have type stability. Where Common Lisp abstracts away from the underlying machine operations, Julia cleaves closer to them. For example:\nInteger division using / always returns a floating-point result, even if the computation is exact.\n// always returns a rational result\n÷ always returns a (truncated) integer result\nBignums are supported, but conversion is not automatic; ordinary integers overflow.\nComplex numbers are supported, but to get complex results, you need complex inputs.\nThere are multiple Complex and Rational types, with different component types.\nModules (namespaces) can be hierarchical. import and using have a dual role: they load the code and make it available in the namespace. import for only the module name is possible (roughly equivalent to ASDF:LOAD-OP). Slot names don't need to be exported separately. Global variables can't be assigned to from outside the module (except with eval(mod, :(var = val)) as an escape hatch).\nMacros start with @, and are not as seamlessly integrated into the language as Common Lisp; consequently, macro usage is not as widespread as in the latter. A form of hygiene for macros is supported by the language. Because of the different surface syntax, there is no equivalent to COMMON-LISP:&BODY.\nAll functions are generic and use multiple dispatch. Argument lists don't have to follow the same template, which leads to a powerful idiom (see do). Optional and keyword arguments are handled differently. Method ambiguities are not resolved like in the Common Lisp Object System, necessitating the definition of a more specific method for the intersection.\nSymbols do not belong to any package, and do not contain any values per se. M.var evaluates the symbol var in the module M.\nA functional programming style is fully supported by the language, including closures, but isn't always the idiomatic solution for Julia. Some workarounds may be necessary for performance when modifying captured variables.","category":"page"},{"location":"stdlib/LibGit2/","page":"LibGit2","title":"LibGit2","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/LibGit2/docs/src/index.md\"","category":"page"},{"location":"stdlib/LibGit2/#LibGit2","page":"LibGit2","title":"LibGit2","text":"","category":"section"},{"location":"stdlib/LibGit2/","page":"LibGit2","title":"LibGit2","text":"The LibGit2 module provides bindings to libgit2, a portable C library that implements core functionality for the Git version control system. These bindings are currently used to power Julia's package manager. It is expected that this module will eventually be moved into a separate package.","category":"page"},{"location":"stdlib/LibGit2/#Functionality","page":"LibGit2","title":"Functionality","text":"","category":"section"},{"location":"stdlib/LibGit2/","page":"LibGit2","title":"LibGit2","text":"Some of this documentation assumes some prior knowledge of the libgit2 API. For more information on some of the objects and methods referenced here, consult the upstream libgit2 API reference.","category":"page"},{"location":"stdlib/LibGit2/","page":"LibGit2","title":"LibGit2","text":"LibGit2.Buffer\nLibGit2.CheckoutOptions\nLibGit2.CloneOptions\nLibGit2.DescribeOptions\nLibGit2.DescribeFormatOptions\nLibGit2.DiffDelta\nLibGit2.DiffFile\nLibGit2.DiffOptionsStruct\nLibGit2.FetchHead\nLibGit2.FetchOptions\nLibGit2.GitAnnotated\nLibGit2.GitBlame\nLibGit2.GitBlob\nLibGit2.GitCommit\nLibGit2.GitConfig\nLibGit2.GitHash\nLibGit2.GitObject\nLibGit2.GitRemote\nLibGit2.GitRemoteAnon\nLibGit2.GitRepo\nLibGit2.GitRepoExt\nLibGit2.GitRevWalker\nLibGit2.GitShortHash\nLibGit2.GitSignature\nLibGit2.GitStatus\nLibGit2.GitTag\nLibGit2.GitTree\nLibGit2.IndexEntry\nLibGit2.IndexTime\nLibGit2.BlameOptions\nLibGit2.MergeOptions\nLibGit2.ProxyOptions\nLibGit2.PushOptions\nLibGit2.RebaseOperation\nLibGit2.RebaseOptions\nLibGit2.RemoteCallbacks\nLibGit2.SignatureStruct\nLibGit2.StatusEntry\nLibGit2.StatusOptions\nLibGit2.StrArrayStruct\nLibGit2.TimeStruct\nLibGit2.addfile\nLibGit2.add!\nLibGit2.add_fetch!\nLibGit2.add_push!\nLibGit2.addblob!\nLibGit2.author\nLibGit2.authors\nLibGit2.branch\nLibGit2.branch!\nLibGit2.checkout!\nLibGit2.clone\nLibGit2.commit\nLibGit2.committer\nLibGit2.count\nLibGit2.counthunks\nLibGit2.create_branch\nLibGit2.credentials_callback\nLibGit2.credentials_cb\nLibGit2.default_signature\nLibGit2.delete_branch\nLibGit2.diff_files\nLibGit2.entryid\nLibGit2.entrytype\nLibGit2.fetch\nLibGit2.fetchheads\nLibGit2.fetch_refspecs\nLibGit2.fetchhead_foreach_cb\nLibGit2.merge_base\nLibGit2.merge!(::LibGit2.GitRepo; ::Any...)\nLibGit2.merge!(::LibGit2.GitRepo, ::Vector{LibGit2.GitAnnotated}; ::LibGit2.MergeOptions, ::LibGit2.CheckoutOptions)\nLibGit2.merge!(::LibGit2.GitRepo, ::Vector{LibGit2.GitAnnotated}, ::Bool; ::LibGit2.MergeOptions, ::LibGit2.CheckoutOptions)\nLibGit2.ffmerge!\nLibGit2.fullname\nLibGit2.features\nLibGit2.filename\nLibGit2.filemode\nLibGit2.gitdir\nLibGit2.git_url\nLibGit2.@githash_str\nLibGit2.head\nLibGit2.head!\nLibGit2.head_oid\nLibGit2.headname\nLibGit2.init\nLibGit2.is_ancestor_of\nLibGit2.isbinary\nLibGit2.iscommit\nLibGit2.isdiff\nLibGit2.isdirty\nLibGit2.isorphan\nLibGit2.isset\nLibGit2.iszero\nLibGit2.lookup_branch\nLibGit2.map\nLibGit2.mirror_callback\nLibGit2.mirror_cb\nLibGit2.message\nLibGit2.merge_analysis\nLibGit2.name\nLibGit2.need_update\nLibGit2.objtype\nLibGit2.path\nLibGit2.peel\nLibGit2.posixpath\nLibGit2.push\nLibGit2.push!(::LibGit2.GitRevWalker, ::LibGit2.GitHash)\nLibGit2.push_head!\nLibGit2.push_refspecs\nLibGit2.raw\nLibGit2.read_tree!\nLibGit2.rebase!\nLibGit2.ref_list\nLibGit2.reftype\nLibGit2.remotes\nLibGit2.remove!\nLibGit2.reset\nLibGit2.reset!\nLibGit2.restore\nLibGit2.revcount\nLibGit2.set_remote_url\nLibGit2.shortname\nLibGit2.snapshot\nLibGit2.split_cfg_entry\nLibGit2.status\nLibGit2.stage\nLibGit2.tag_create\nLibGit2.tag_delete\nLibGit2.tag_list\nLibGit2.target\nLibGit2.toggle\nLibGit2.transact\nLibGit2.treewalk\nLibGit2.upstream\nLibGit2.update!\nLibGit2.url\nLibGit2.version\nLibGit2.with\nLibGit2.with_warn\nLibGit2.workdir\nLibGit2.GitObject(::LibGit2.GitTreeEntry)\nLibGit2.UserPasswordCredential\nLibGit2.SSHCredential\nLibGit2.isfilled\nLibGit2.CachedCredentials\nLibGit2.CredentialPayload\nLibGit2.approve\nLibGit2.reject\nLibGit2.Consts.GIT_CONFIG","category":"page"},{"location":"stdlib/LibGit2/#LibGit2.Buffer","page":"LibGit2","title":"LibGit2.Buffer","text":"LibGit2.Buffer\n\nA data buffer for exporting data from libgit2. Matches the git_buf struct.\n\nWhen fetching data from LibGit2, a typical usage would look like:\n\nbuf_ref = Ref(Buffer())\n@check ccall(..., (Ptr{Buffer},), buf_ref)\n# operation on buf_ref\nfree(buf_ref)\n\nIn particular, note that LibGit2.free should be called afterward on the Ref object.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.CheckoutOptions","page":"LibGit2","title":"LibGit2.CheckoutOptions","text":"LibGit2.CheckoutOptions\n\nMatches the git_checkout_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\ncheckout_strategy: determine how to handle conflicts and whether to force the checkout/recreate missing files.\ndisable_filters: if nonzero, do not apply filters like CLRF (to convert file newlines between UNIX and DOS).\ndir_mode: read/write/access mode for any directories involved in the checkout. Default is 0755.\nfile_mode: read/write/access mode for any files involved in the checkout. Default is 0755 or 0644, depending on the blob.\nfile_open_flags: bitflags used to open any files during the checkout.\nnotify_flags: Flags for what sort of conflicts the user should be notified about.\nnotify_cb: An optional callback function to notify the user if a checkout conflict occurs. If this function returns a non-zero value, the checkout will be cancelled.\nnotify_payload: Payload for the notify callback function.\nprogress_cb: An optional callback function to display checkout progress.\nprogress_payload: Payload for the progress callback.\npaths: If not empty, describes which paths to search during the checkout. If empty, the checkout will occur over all files in the repository.\nbaseline: Expected content of the workdir, captured in a (pointer to a) GitTree. Defaults to the state of the tree at HEAD.\nbaseline_index: Expected content of the workdir, captured in a (pointer to a) GitIndex. Defaults to the state of the index at HEAD.\ntarget_directory: If not empty, checkout to this directory instead of the workdir.\nancestor_label: In case of conflicts, the name of the common ancestor side.\nour_label: In case of conflicts, the name of \"our\" side.\ntheir_label: In case of conflicts, the name of \"their\" side.\nperfdata_cb: An optional callback function to display performance data.\nperfdata_payload: Payload for the performance callback.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.CloneOptions","page":"LibGit2","title":"LibGit2.CloneOptions","text":"LibGit2.CloneOptions\n\nMatches the git_clone_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\ncheckout_opts: The options for performing the checkout of the remote as part of the clone.\nfetch_opts: The options for performing the pre-checkout fetch of the remote as part of the clone.\nbare: If 0, clone the full remote repository. If non-zero, perform a bare clone, in which there is no local copy of the source files in the repository and the gitdir and workdir are the same.\nlocalclone: Flag whether to clone a local object database or do a fetch. The default is to let git decide. It will not use the git-aware transport for a local clone, but will use it for URLs which begin with file://.\ncheckout_branch: The name of the branch to checkout. If an empty string, the default branch of the remote will be checked out.\nrepository_cb: An optional callback which will be used to create the new repository into which the clone is made.\nrepository_cb_payload: The payload for the repository callback.\nremote_cb: An optional callback used to create the GitRemote before making the clone from it.\nremote_cb_payload: The payload for the remote callback.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DescribeOptions","page":"LibGit2","title":"LibGit2.DescribeOptions","text":"LibGit2.DescribeOptions\n\nMatches the git_describe_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nmax_candidates_tags: consider this many most recent tags in refs/tags to describe a commit. Defaults to 10 (so that the 10 most recent tags would be examined to see if they describe a commit).\ndescribe_strategy: whether to consider all entries in refs/tags (equivalent to git-describe --tags) or all entries in refs/ (equivalent to git-describe --all). The default is to only show annotated tags. If Consts.DESCRIBE_TAGS is passed, all tags, annotated or not, will be considered. If Consts.DESCRIBE_ALL is passed, any ref in refs/ will be considered.\npattern: only consider tags which match pattern. Supports glob expansion.\nonly_follow_first_parent: when finding the distance from a matching reference to the described object, only consider the distance from the first parent.\nshow_commit_oid_as_fallback: if no matching reference can be found which describes a commit, show the commit's GitHash instead of throwing an error (the default behavior).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DescribeFormatOptions","page":"LibGit2","title":"LibGit2.DescribeFormatOptions","text":"LibGit2.DescribeFormatOptions\n\nMatches the git_describe_format_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nabbreviated_size: lower bound on the size of the abbreviated GitHash to use, defaulting to 7.\nalways_use_long_format: set to 1 to use the long format for strings even if a short format can be used.\ndirty_suffix: if set, this will be appended to the end of the description string if the workdir is dirty.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DiffDelta","page":"LibGit2","title":"LibGit2.DiffDelta","text":"LibGit2.DiffDelta\n\nDescription of changes to one entry. Matches the git_diff_delta struct.\n\nThe fields represent:\n\nstatus: One of Consts.DELTA_STATUS, indicating whether the file has been added/modified/deleted.\nflags: Flags for the delta and the objects on each side. Determines whether to treat the file(s) as binary/text, whether they exist on each side of the diff, and whether the object ids are known to be correct.\nsimilarity: Used to indicate if a file has been renamed or copied.\nnfiles: The number of files in the delta (for instance, if the delta was run on a submodule commit id, it may contain more than one file).\nold_file: A DiffFile containing information about the file(s) before the changes.\nnew_file: A DiffFile containing information about the file(s) after the changes.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DiffFile","page":"LibGit2","title":"LibGit2.DiffFile","text":"LibGit2.DiffFile\n\nDescription of one side of a delta. Matches the git_diff_file struct.\n\nThe fields represent:\n\nid: the GitHash of the item in the diff. If the item is empty on this side of the diff (for instance, if the diff is of the removal of a file), this will be GitHash(0).\npath: a NULL terminated path to the item relative to the working directory of the repository.\nsize: the size of the item in bytes.\nflags: a combination of the git_diff_flag_t flags. The ith bit of this integer sets the ith flag.\nmode: the stat mode for the item.\nid_abbrev: only present in LibGit2 versions newer than or equal to 0.25.0. The length of the id field when converted using string. Usually equal to OID_HEXSZ (40).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DiffOptionsStruct","page":"LibGit2","title":"LibGit2.DiffOptionsStruct","text":"LibGit2.DiffOptionsStruct\n\nMatches the git_diff_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nflags: flags controlling which files will appear in the diff. Defaults to DIFF_NORMAL.\nignore_submodules: whether to look at files in submodules or not. Defaults to SUBMODULE_IGNORE_UNSPECIFIED, which means the submodule's configuration will control whether it appears in the diff or not.\npathspec: path to files to include in the diff. Default is to use all files in the repository.\nnotify_cb: optional callback which will notify the user of changes to the diff as file deltas are added to it.\nprogress_cb: optional callback which will display diff progress. Only relevant on libgit2 versions at least as new as 0.24.0.\npayload: the payload to pass to notify_cb and progress_cb.\ncontext_lines: the number of unchanged lines used to define the edges of a hunk. This is also the number of lines which will be shown before/after a hunk to provide context. Default is 3.\ninterhunk_lines: the maximum number of unchanged lines between two separate hunks allowed before the hunks will be combined. Default is 0.\nid_abbrev: sets the length of the abbreviated GitHash to print. Default is 7.\nmax_size: the maximum file size of a blob. Above this size, it will be treated as a binary blob. The default is 512 MB.\nold_prefix: the virtual file directory in which to place old files on one side of the diff. Default is \"a\".\nnew_prefix: the virtual file directory in which to place new files on one side of the diff. Default is \"b\".\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.FetchHead","page":"LibGit2","title":"LibGit2.FetchHead","text":"LibGit2.FetchHead\n\nContains the information about HEAD during a fetch, including the name and URL of the branch fetched from, the oid of the HEAD, and whether the fetched HEAD has been merged locally.\n\nThe fields represent:\n\nname: The name in the local reference database of the fetch head, for example, \"refs/heads/master\".\nurl: The URL of the fetch head.\noid: The GitHash of the tip of the fetch head.\nismerge: Boolean flag indicating whether the changes at the remote have been merged into the local copy yet or not. If true, the local copy is up to date with the remote fetch head.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.FetchOptions","page":"LibGit2","title":"LibGit2.FetchOptions","text":"LibGit2.FetchOptions\n\nMatches the git_fetch_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\ncallbacks: remote callbacks to use during the fetch.\nprune: whether to perform a prune after the fetch or not. The default is to use the setting from the GitConfig.\nupdate_fetchhead: whether to update the FetchHead after the fetch. The default is to perform the update, which is the normal git behavior.\ndownload_tags: whether to download tags present at the remote or not. The default is to request the tags for objects which are being downloaded anyway from the server.\nproxy_opts: options for connecting to the remote through a proxy. See ProxyOptions. Only present on libgit2 versions newer than or equal to 0.25.0.\ncustom_headers: any extra headers needed for the fetch. Only present on libgit2 versions newer than or equal to 0.24.0.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitAnnotated","page":"LibGit2","title":"LibGit2.GitAnnotated","text":"GitAnnotated(repo::GitRepo, commit_id::GitHash)\nGitAnnotated(repo::GitRepo, ref::GitReference)\nGitAnnotated(repo::GitRepo, fh::FetchHead)\nGitAnnotated(repo::GitRepo, committish::AbstractString)\n\nAn annotated git commit carries with it information about how it was looked up and why, so that rebase or merge operations have more information about the context of the commit. Conflict files contain information about the source/target branches in the merge which are conflicting, for instance. An annotated commit can refer to the tip of a remote branch, for instance when a FetchHead is passed, or to a branch head described using GitReference.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitBlame","page":"LibGit2","title":"LibGit2.GitBlame","text":"GitBlame(repo::GitRepo, path::AbstractString; options::BlameOptions=BlameOptions())\n\nConstruct a GitBlame object for the file at path, using change information gleaned from the history of repo. The GitBlame object records who changed which chunks of the file when, and how. options controls how to separate the contents of the file and which commits to probe - see BlameOptions for more information.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitBlob","page":"LibGit2","title":"LibGit2.GitBlob","text":"GitBlob(repo::GitRepo, hash::AbstractGitHash)\nGitBlob(repo::GitRepo, spec::AbstractString)\n\nReturn a GitBlob object from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitCommit","page":"LibGit2","title":"LibGit2.GitCommit","text":"GitCommit(repo::GitRepo, hash::AbstractGitHash)\nGitCommit(repo::GitRepo, spec::AbstractString)\n\nReturn a GitCommit object from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitConfig","page":"LibGit2","title":"LibGit2.GitConfig","text":"GitConfig(path::AbstractString, level::Consts.GIT_CONFIG=Consts.CONFIG_LEVEL_APP, force::Bool=false)\n\nCreate a new GitConfig by loading configuration information from the file at path. See addfile for more information about the level, repo and force options.\n\n\n\n\n\nGitConfig(repo::GitRepo)\n\nGet the stored configuration for the git repository repo. If repo does not have a specific configuration file set, the default git configuration will be used.\n\n\n\n\n\nGitConfig(level::Consts.GIT_CONFIG=Consts.CONFIG_LEVEL_DEFAULT)\n\nGet the default git configuration by loading the global and system configuration files into a prioritized configuration. This can be used to access default configuration options outside a specific git repository.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitHash","page":"LibGit2","title":"LibGit2.GitHash","text":"GitHash\n\nA git object identifier, based on the sha-1 hash. It is a 20 byte string (40 hex digits) used to identify a GitObject in a repository.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitObject","page":"LibGit2","title":"LibGit2.GitObject","text":"GitObject(repo::GitRepo, hash::AbstractGitHash)\nGitObject(repo::GitRepo, spec::AbstractString)\n\nReturn the specified object (GitCommit, GitBlob, GitTree or GitTag) from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitRemote","page":"LibGit2","title":"LibGit2.GitRemote","text":"GitRemote(repo::GitRepo, rmt_name::AbstractString, rmt_url::AbstractString) -> GitRemote\n\nLook up a remote git repository using its name and URL. Uses the default fetch refspec.\n\nExamples\n\nrepo = LibGit2.init(repo_path)\nremote = LibGit2.GitRemote(repo, \"upstream\", repo_url)\n\n\n\n\n\nGitRemote(repo::GitRepo, rmt_name::AbstractString, rmt_url::AbstractString, fetch_spec::AbstractString) -> GitRemote\n\nLook up a remote git repository using the repository's name and URL, as well as specifications for how to fetch from the remote (e.g. which remote branch to fetch from).\n\nExamples\n\nrepo = LibGit2.init(repo_path)\nrefspec = \"+refs/heads/mybranch:refs/remotes/origin/mybranch\"\nremote = LibGit2.GitRemote(repo, \"upstream\", repo_url, refspec)\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitRemoteAnon","page":"LibGit2","title":"LibGit2.GitRemoteAnon","text":"GitRemoteAnon(repo::GitRepo, url::AbstractString) -> GitRemote\n\nLook up a remote git repository using only its URL, not its name.\n\nExamples\n\nrepo = LibGit2.init(repo_path)\nremote = LibGit2.GitRemoteAnon(repo, repo_url)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.GitRepo","page":"LibGit2","title":"LibGit2.GitRepo","text":"LibGit2.GitRepo(path::AbstractString)\n\nOpen a git repository at path.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitRepoExt","page":"LibGit2","title":"LibGit2.GitRepoExt","text":"LibGit2.GitRepoExt(path::AbstractString, flags::Cuint = Cuint(Consts.REPOSITORY_OPEN_DEFAULT))\n\nOpen a git repository at path with extended controls (for instance, if the current user must be a member of a special access group to read path).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.GitRevWalker","page":"LibGit2","title":"LibGit2.GitRevWalker","text":"GitRevWalker(repo::GitRepo)\n\nA GitRevWalker walks through the revisions (i.e. commits) of a git repository repo. It is a collection of the commits in the repository, and supports iteration and calls to LibGit2.map and LibGit2.count (for instance, LibGit2.count could be used to determine what percentage of commits in a repository were made by a certain author).\n\ncnt = LibGit2.with(LibGit2.GitRevWalker(repo)) do walker\n LibGit2.count((oid,repo)->(oid == commit_oid1), walker, oid=commit_oid1, by=LibGit2.Consts.SORT_TIME)\nend\n\nHere, LibGit2.count finds the number of commits along the walk with a certain GitHash. Since the GitHash is unique to a commit, cnt will be 1.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitShortHash","page":"LibGit2","title":"LibGit2.GitShortHash","text":"GitShortHash(hash::GitHash, len::Integer)\n\nA shortened git object identifier, which can be used to identify a git object when it is unique, consisting of the initial len hexadecimal digits of hash (the remaining digits are ignored).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitSignature","page":"LibGit2","title":"LibGit2.GitSignature","text":"LibGit2.GitSignature\n\nThis is a Julia wrapper around a pointer to a git_signature object.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitStatus","page":"LibGit2","title":"LibGit2.GitStatus","text":"LibGit2.GitStatus(repo::GitRepo; status_opts=StatusOptions())\n\nCollect information about the status of each file in the git repository repo (e.g. is the file modified, staged, etc.). status_opts can be used to set various options, for instance whether or not to look at untracked files or whether to include submodules or not. See StatusOptions for more information.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitTag","page":"LibGit2","title":"LibGit2.GitTag","text":"GitTag(repo::GitRepo, hash::AbstractGitHash)\nGitTag(repo::GitRepo, spec::AbstractString)\n\nReturn a GitTag object from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitTree","page":"LibGit2","title":"LibGit2.GitTree","text":"GitTree(repo::GitRepo, hash::AbstractGitHash)\nGitTree(repo::GitRepo, spec::AbstractString)\n\nReturn a GitTree object from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.IndexEntry","page":"LibGit2","title":"LibGit2.IndexEntry","text":"LibGit2.IndexEntry\n\nIn-memory representation of a file entry in the index. Matches the git_index_entry struct.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.IndexTime","page":"LibGit2","title":"LibGit2.IndexTime","text":"LibGit2.IndexTime\n\nMatches the git_index_time struct.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.BlameOptions","page":"LibGit2","title":"LibGit2.BlameOptions","text":"LibGit2.BlameOptions\n\nMatches the git_blame_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nflags: one of Consts.BLAME_NORMAL or Consts.BLAME_FIRST_PARENT (the other blame flags are not yet implemented by libgit2).\nmin_match_characters: the minimum number of alphanumeric characters which much change in a commit in order for the change to be associated with that commit. The default is 20. Only takes effect if one of the Consts.BLAME_*_COPIES flags are used, which libgit2 does not implement yet.\nnewest_commit: the GitHash of the newest commit from which to look at changes.\noldest_commit: the GitHash of the oldest commit from which to look at changes.\nmin_line: the first line of the file from which to starting blaming. The default is 1.\nmax_line: the last line of the file to which to blame. The default is 0, meaning the last line of the file.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.MergeOptions","page":"LibGit2","title":"LibGit2.MergeOptions","text":"LibGit2.MergeOptions\n\nMatches the git_merge_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nflags: an enum for flags describing merge behavior. Defined in git_merge_flag_t. The corresponding Julia enum is GIT_MERGE and has values:\nMERGE_FIND_RENAMES: detect if a file has been renamed between the common ancestor and the \"ours\" or \"theirs\" side of the merge. Allows merges where a file has been renamed.\nMERGE_FAIL_ON_CONFLICT: exit immediately if a conflict is found rather than trying to resolve it.\nMERGE_SKIP_REUC: do not write the REUC extension on the index resulting from the merge.\nMERGE_NO_RECURSIVE: if the commits being merged have multiple merge bases, use the first one, rather than trying to recursively merge the bases.\nrename_threshold: how similar two files must to consider one a rename of the other. This is an integer that sets the percentage similarity. The default is 50.\ntarget_limit: the maximum number of files to compare with to look for renames. The default is 200.\nmetric: optional custom function to use to determine the similarity between two files for rename detection.\nrecursion_limit: the upper limit on the number of merges of common ancestors to perform to try to build a new virtual merge base for the merge. The default is no limit. This field is only present on libgit2 versions newer than 0.24.0.\ndefault_driver: the merge driver to use if both sides have changed. This field is only present on libgit2 versions newer than 0.25.0.\nfile_favor: how to handle conflicting file contents for the text driver.\nMERGE_FILE_FAVOR_NORMAL: if both sides of the merge have changes to a section, make a note of the conflict in the index which git checkout will use to create a merge file, which the user can then reference to resolve the conflicts. This is the default.\nMERGE_FILE_FAVOR_OURS: if both sides of the merge have changes to a section, use the version in the \"ours\" side of the merge in the index.\nMERGE_FILE_FAVOR_THEIRS: if both sides of the merge have changes to a section, use the version in the \"theirs\" side of the merge in the index.\nMERGE_FILE_FAVOR_UNION: if both sides of the merge have changes to a section, include each unique line from both sides in the file which is put into the index.\nfile_flags: guidelines for merging files.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.ProxyOptions","page":"LibGit2","title":"LibGit2.ProxyOptions","text":"LibGit2.ProxyOptions\n\nOptions for connecting through a proxy.\n\nMatches the git_proxy_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nproxytype: an enum for the type of proxy to use. Defined in git_proxy_t. The corresponding Julia enum is GIT_PROXY and has values:\nPROXY_NONE: do not attempt the connection through a proxy.\nPROXY_AUTO: attempt to figure out the proxy configuration from the git configuration.\nPROXY_SPECIFIED: connect using the URL given in the url field of this struct.\nDefault is to auto-detect the proxy type.\nurl: the URL of the proxy.\ncredential_cb: a pointer to a callback function which will be called if the remote requires authentication to connect.\ncertificate_cb: a pointer to a callback function which will be called if certificate verification fails. This lets the user decide whether or not to keep connecting. If the function returns 1, connecting will be allowed. If it returns 0, the connection will not be allowed. A negative value can be used to return errors.\npayload: the payload to be provided to the two callback functions.\n\nExamples\n\njulia> fo = LibGit2.FetchOptions(\n proxy_opts = LibGit2.ProxyOptions(url = Cstring(\"https://my_proxy_url.com\")))\n\njulia> fetch(remote, \"master\", options=fo)\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.PushOptions","page":"LibGit2","title":"LibGit2.PushOptions","text":"LibGit2.PushOptions\n\nMatches the git_push_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nparallelism: if a pack file must be created, this variable sets the number of worker threads which will be spawned by the packbuilder. If 0, the packbuilder will auto-set the number of threads to use. The default is 1.\ncallbacks: the callbacks (e.g. for authentication with the remote) to use for the push.\nproxy_opts: only relevant if the LibGit2 version is greater than or equal to 0.25.0. Sets options for using a proxy to communicate with a remote. See ProxyOptions for more information.\ncustom_headers: only relevant if the LibGit2 version is greater than or equal to 0.24.0. Extra headers needed for the push operation.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.RebaseOperation","page":"LibGit2","title":"LibGit2.RebaseOperation","text":"LibGit2.RebaseOperation\n\nDescribes a single instruction/operation to be performed during the rebase. Matches the git_rebase_operation struct.\n\nThe fields represent:\n\noptype: the type of rebase operation currently being performed. The options are:\nREBASE_OPERATION_PICK: cherry-pick the commit in question.\nREBASE_OPERATION_REWORD: cherry-pick the commit in question, but rewrite its message using the prompt.\nREBASE_OPERATION_EDIT: cherry-pick the commit in question, but allow the user to edit the commit's contents and its message.\nREBASE_OPERATION_SQUASH: squash the commit in question into the previous commit. The commit messages of the two commits will be merged.\nREBASE_OPERATION_FIXUP: squash the commit in question into the previous commit. Only the commit message of the previous commit will be used.\nREBASE_OPERATION_EXEC: do not cherry-pick a commit. Run a command and continue if the command exits successfully.\nid: the GitHash of the commit being worked on during this rebase step.\nexec: in case REBASE_OPERATION_EXEC is used, the command to run during this step (for instance, running the test suite after each commit).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.RebaseOptions","page":"LibGit2","title":"LibGit2.RebaseOptions","text":"LibGit2.RebaseOptions\n\nMatches the git_rebase_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nquiet: inform other git clients helping with/working on the rebase that the rebase should be done \"quietly\". Used for interoperability. The default is 1.\ninmemory: start an in-memory rebase. Callers working on the rebase can go through its steps and commit any changes, but cannot rewind HEAD or update the repository. The workdir will not be modified. Only present on libgit2 versions newer than or equal to 0.24.0.\nrewrite_notes_ref: name of the reference to notes to use to rewrite the commit notes as the rebase is finished.\nmerge_opts: merge options controlling how the trees will be merged at each rebase step. Only present on libgit2 versions newer than or equal to 0.24.0.\ncheckout_opts: checkout options for writing files when initializing the rebase, stepping through it, and aborting it. See CheckoutOptions for more information.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.RemoteCallbacks","page":"LibGit2","title":"LibGit2.RemoteCallbacks","text":"LibGit2.RemoteCallbacks\n\nCallback settings. Matches the git_remote_callbacks struct.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.SignatureStruct","page":"LibGit2","title":"LibGit2.SignatureStruct","text":"LibGit2.SignatureStruct\n\nAn action signature (e.g. for committers, taggers, etc). Matches the git_signature struct.\n\nThe fields represent:\n\nname: The full name of the committer or author of the commit.\nemail: The email at which the committer/author can be contacted.\nwhen: a TimeStruct indicating when the commit was authored/committed into the repository.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.StatusEntry","page":"LibGit2","title":"LibGit2.StatusEntry","text":"LibGit2.StatusEntry\n\nProviding the differences between the file as it exists in HEAD and the index, and providing the differences between the index and the working directory. Matches the git_status_entry struct.\n\nThe fields represent:\n\nstatus: contains the status flags for the file, indicating if it is current, or has been changed in some way in the index or work tree.\nhead_to_index: a pointer to a DiffDelta which encapsulates the difference(s) between the file as it exists in HEAD and in the index.\nindex_to_workdir: a pointer to a DiffDelta which encapsulates the difference(s) between the file as it exists in the index and in the workdir.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.StatusOptions","page":"LibGit2","title":"LibGit2.StatusOptions","text":"LibGit2.StatusOptions\n\nOptions to control how git_status_foreach_ext() will issue callbacks. Matches the git_status_opt_t struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nshow: a flag for which files to examine and in which order. The default is Consts.STATUS_SHOW_INDEX_AND_WORKDIR.\nflags: flags for controlling any callbacks used in a status call.\npathspec: an array of paths to use for path-matching. The behavior of the path-matching will vary depending on the values of show and flags.\nThe baseline is the tree to be used for comparison to the working directory and index; defaults to HEAD.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.StrArrayStruct","page":"LibGit2","title":"LibGit2.StrArrayStruct","text":"LibGit2.StrArrayStruct\n\nA LibGit2 representation of an array of strings. Matches the git_strarray struct.\n\nWhen fetching data from LibGit2, a typical usage would look like:\n\nsa_ref = Ref(StrArrayStruct())\n@check ccall(..., (Ptr{StrArrayStruct},), sa_ref)\nres = convert(Vector{String}, sa_ref[])\nfree(sa_ref)\n\nIn particular, note that LibGit2.free should be called afterward on the Ref object.\n\nConversely, when passing a vector of strings to LibGit2, it is generally simplest to rely on implicit conversion:\n\nstrs = String[...]\n@check ccall(..., (Ptr{StrArrayStruct},), strs)\n\nNote that no call to free is required as the data is allocated by Julia.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.TimeStruct","page":"LibGit2","title":"LibGit2.TimeStruct","text":"LibGit2.TimeStruct\n\nTime in a signature. Matches the git_time struct.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.addfile","page":"LibGit2","title":"LibGit2.addfile","text":"addfile(cfg::GitConfig, path::AbstractString,\n level::Consts.GIT_CONFIG=Consts.CONFIG_LEVEL_APP,\n repo::Union{GitRepo, Nothing} = nothing,\n force::Bool=false)\n\nAdd an existing git configuration file located at path to the current GitConfig cfg. If the file does not exist, it will be created.\n\nlevel sets the git configuration priority level and is determined by\n\nConsts.GIT_CONFIG.\n\nrepo is an optional repository to allow parsing of conditional includes.\nIf force is false and a configuration for the given priority level already exists,\n\naddfile will error. If force is true, the existing configuration will be replaced by the one in the file at path.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.add!","page":"LibGit2","title":"LibGit2.add!","text":"add!(repo::GitRepo, files::AbstractString...; flags::Cuint = Consts.INDEX_ADD_DEFAULT)\nadd!(idx::GitIndex, files::AbstractString...; flags::Cuint = Consts.INDEX_ADD_DEFAULT)\n\nAdd all the files with paths specified by files to the index idx (or the index of the repo). If the file already exists, the index entry will be updated. If the file does not exist already, it will be newly added into the index. files may contain glob patterns which will be expanded and any matching files will be added (unless INDEX_ADD_DISABLE_PATHSPEC_MATCH is set, see below). If a file has been ignored (in .gitignore or in the config), it will not be added, unless it is already being tracked in the index, in which case it will be updated. The keyword argument flags is a set of bit-flags which control the behavior with respect to ignored files:\n\nConsts.INDEX_ADD_DEFAULT - default, described above.\nConsts.INDEX_ADD_FORCE - disregard the existing ignore rules and force addition of the file to the index even if it is already ignored.\nConsts.INDEX_ADD_CHECK_PATHSPEC - cannot be used at the same time as INDEX_ADD_FORCE. Check that each file in files which exists on disk is not in the ignore list. If one of the files is ignored, the function will return EINVALIDSPEC.\nConsts.INDEX_ADD_DISABLE_PATHSPEC_MATCH - turn off glob matching, and only add files to the index which exactly match the paths specified in files.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.add_fetch!","page":"LibGit2","title":"LibGit2.add_fetch!","text":"add_fetch!(repo::GitRepo, rmt::GitRemote, fetch_spec::String)\n\nAdd a fetch refspec for the specified rmt. This refspec will contain information about which branch(es) to fetch from.\n\nExamples\n\njulia> LibGit2.add_fetch!(repo, remote, \"upstream\");\n\njulia> LibGit2.fetch_refspecs(remote)\nString[\"+refs/heads/*:refs/remotes/upstream/*\"]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.add_push!","page":"LibGit2","title":"LibGit2.add_push!","text":"add_push!(repo::GitRepo, rmt::GitRemote, push_spec::String)\n\nAdd a push refspec for the specified rmt. This refspec will contain information about which branch(es) to push to.\n\nExamples\n\njulia> LibGit2.add_push!(repo, remote, \"refs/heads/master\");\n\njulia> remote = LibGit2.get(LibGit2.GitRemote, repo, branch);\n\njulia> LibGit2.push_refspecs(remote)\nString[\"refs/heads/master\"]\n\nnote: Note\nYou may need to close and reopen the GitRemote in question after updating its push refspecs in order for the change to take effect and for calls to push to work.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.addblob!","page":"LibGit2","title":"LibGit2.addblob!","text":"LibGit2.addblob!(repo::GitRepo, path::AbstractString)\n\nRead the file at path and adds it to the object database of repo as a loose blob. Return the GitHash of the resulting blob.\n\nExamples\n\nhash_str = string(commit_oid)\nblob_file = joinpath(repo_path, \".git\", \"objects\", hash_str[1:2], hash_str[3:end])\nid = LibGit2.addblob!(repo, blob_file)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.author","page":"LibGit2","title":"LibGit2.author","text":"author(c::GitCommit)\n\nReturn the Signature of the author of the commit c. The author is the person who made changes to the relevant file(s). See also committer.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.authors","page":"LibGit2","title":"LibGit2.authors","text":"authors(repo::GitRepo) -> Vector{Signature}\n\nReturn all authors of commits to the repo repository.\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nrepo_file = open(joinpath(repo_path, test_file), \"a\")\n\nprintln(repo_file, commit_msg)\nflush(repo_file)\nLibGit2.add!(repo, test_file)\nsig = LibGit2.Signature(\"TEST\", \"TEST@TEST.COM\", round(time(), 0), 0)\ncommit_oid1 = LibGit2.commit(repo, \"commit1\"; author=sig, committer=sig)\nprintln(repo_file, randstring(10))\nflush(repo_file)\nLibGit2.add!(repo, test_file)\ncommit_oid2 = LibGit2.commit(repo, \"commit2\"; author=sig, committer=sig)\n\n# will be a Vector of [sig, sig]\nauths = LibGit2.authors(repo)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.branch","page":"LibGit2","title":"LibGit2.branch","text":"branch(repo::GitRepo)\n\nEquivalent to git branch. Create a new branch from the current HEAD.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.branch!","page":"LibGit2","title":"LibGit2.branch!","text":"branch!(repo::GitRepo, branch_name::AbstractString, commit::AbstractString=\"\"; kwargs...)\n\nCheckout a new git branch in the repo repository. commit is the GitHash, in string form, which will be the start of the new branch. If commit is an empty string, the current HEAD will be used.\n\nThe keyword arguments are:\n\ntrack::AbstractString=\"\": the name of the remote branch this new branch should track, if any. If empty (the default), no remote branch will be tracked.\nforce::Bool=false: if true, branch creation will be forced.\nset_head::Bool=true: if true, after the branch creation finishes the branch head will be set as the HEAD of repo.\n\nEquivalent to git checkout [-b|-B] [] [--track ].\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nLibGit2.branch!(repo, \"new_branch\", set_head=false)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.checkout!","page":"LibGit2","title":"LibGit2.checkout!","text":"checkout!(repo::GitRepo, commit::AbstractString=\"\"; force::Bool=true)\n\nEquivalent to git checkout [-f] --detach . Checkout the git commit commit (a GitHash in string form) in repo. If force is true, force the checkout and discard any current changes. Note that this detaches the current HEAD.\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nopen(joinpath(LibGit2.path(repo), \"file1\"), \"w\") do f\n write(f, \"111\n\")\nend\nLibGit2.add!(repo, \"file1\")\ncommit_oid = LibGit2.commit(repo, \"add file1\")\nopen(joinpath(LibGit2.path(repo), \"file1\"), \"w\") do f\n write(f, \"112\n\")\nend\n# would fail without the force=true\n# since there are modifications to the file\nLibGit2.checkout!(repo, string(commit_oid), force=true)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.clone","page":"LibGit2","title":"LibGit2.clone","text":"clone(repo_url::AbstractString, repo_path::AbstractString, clone_opts::CloneOptions)\n\nClone the remote repository at repo_url (which can be a remote URL or a path on the local filesystem) to repo_path (which must be a path on the local filesystem). Options for the clone, such as whether to perform a bare clone or not, are set by CloneOptions.\n\nExamples\n\nrepo_url = \"https://github.com/JuliaLang/Example.jl\"\nrepo = LibGit2.clone(repo_url, \"/home/me/projects/Example\")\n\n\n\n\n\nclone(repo_url::AbstractString, repo_path::AbstractString; kwargs...)\n\nClone a remote repository located at repo_url to the local filesystem location repo_path.\n\nThe keyword arguments are:\n\nbranch::AbstractString=\"\": which branch of the remote to clone, if not the default repository branch (usually master).\nisbare::Bool=false: if true, clone the remote as a bare repository, which will make repo_path itself the git directory instead of repo_path/.git. This means that a working tree cannot be checked out. Plays the role of the git CLI argument --bare.\nremote_cb::Ptr{Cvoid}=C_NULL: a callback which will be used to create the remote before it is cloned. If C_NULL (the default), no attempt will be made to create the remote - it will be assumed to already exist.\ncredentials::Creds=nothing: provides credentials and/or settings when authenticating against a private repository.\ncallbacks::Callbacks=Callbacks(): user provided callbacks and payloads.\n\nEquivalent to git clone [-b ] [--bare] .\n\nExamples\n\nrepo_url = \"https://github.com/JuliaLang/Example.jl\"\nrepo1 = LibGit2.clone(repo_url, \"test_path\")\nrepo2 = LibGit2.clone(repo_url, \"test_path\", isbare=true)\njulia_url = \"https://github.com/JuliaLang/julia\"\njulia_repo = LibGit2.clone(julia_url, \"julia_path\", branch=\"release-0.6\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.commit","page":"LibGit2","title":"LibGit2.commit","text":"commit(repo::GitRepo, msg::AbstractString; kwargs...) -> GitHash\n\nWrapper around git_commit_create. Create a commit in the repository repo. msg is the commit message. Return the OID of the new commit.\n\nThe keyword arguments are:\n\nrefname::AbstractString=Consts.HEAD_FILE: if not NULL, the name of the reference to update to point to the new commit. For example, \"HEAD\" will update the HEAD of the current branch. If the reference does not yet exist, it will be created.\nauthor::Signature = Signature(repo) is a Signature containing information about the person who authored the commit.\ncommitter::Signature = Signature(repo) is a Signature containing information about the person who committed the commit to the repository. Not necessarily the same as author, for instance if author emailed a patch to committer who committed it.\ntree_id::GitHash = GitHash() is a git tree to use to create the commit, showing its ancestry and relationship with any other history. tree must belong to repo.\nparent_ids::Vector{GitHash}=GitHash[] is a list of commits by GitHash to use as parent commits for the new one, and may be empty. A commit might have multiple parents if it is a merge commit, for example.\n\n\n\n\n\nLibGit2.commit(rb::GitRebase, sig::GitSignature)\n\nCommit the current patch to the rebase rb, using sig as the committer. Is silent if the commit has already been applied.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.committer","page":"LibGit2","title":"LibGit2.committer","text":"committer(c::GitCommit)\n\nReturn the Signature of the committer of the commit c. The committer is the person who committed the changes originally authored by the author, but need not be the same as the author, for example, if the author emailed a patch to a committer who committed it.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.count","page":"LibGit2","title":"LibGit2.count","text":"LibGit2.count(f::Function, walker::GitRevWalker; oid::GitHash=GitHash(), by::Cint=Consts.SORT_NONE, rev::Bool=false)\n\nUsing the GitRevWalker walker to \"walk\" over every commit in the repository's history, find the number of commits which return true when f is applied to them. The keyword arguments are: * oid: The GitHash of the commit to begin the walk from. The default is to use push_head! and therefore the HEAD commit and all its ancestors. * by: The sorting method. The default is not to sort. Other options are to sort by topology (LibGit2.Consts.SORT_TOPOLOGICAL), to sort forwards in time (LibGit2.Consts.SORT_TIME, most ancient first) or to sort backwards in time (LibGit2.Consts.SORT_REVERSE, most recent first). * rev: Whether to reverse the sorted order (for instance, if topological sorting is used).\n\nExamples\n\ncnt = LibGit2.with(LibGit2.GitRevWalker(repo)) do walker\n LibGit2.count((oid, repo)->(oid == commit_oid1), walker, oid=commit_oid1, by=LibGit2.Consts.SORT_TIME)\nend\n\nLibGit2.count finds the number of commits along the walk with a certain GitHash commit_oid1, starting the walk from that commit and moving forwards in time from it. Since the GitHash is unique to a commit, cnt will be 1.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.counthunks","page":"LibGit2","title":"LibGit2.counthunks","text":"counthunks(blame::GitBlame)\n\nReturn the number of distinct \"hunks\" with a file. A hunk may contain multiple lines. A hunk is usually a piece of a file that was added/changed/removed together, for example, a function added to a source file or an inner loop that was optimized out of that function later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.create_branch","page":"LibGit2","title":"LibGit2.create_branch","text":"LibGit2.create_branch(repo::GitRepo, bname::AbstractString, commit_obj::GitCommit; force::Bool=false)\n\nCreate a new branch in the repository repo with name bname, which points to commit commit_obj (which has to be part of repo). If force is true, overwrite an existing branch named bname if it exists. If force is false and a branch already exists named bname, this function will throw an error.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.credentials_callback","page":"LibGit2","title":"LibGit2.credentials_callback","text":"credential_callback(...) -> Cint\n\nA LibGit2 credential callback function which provides different credential acquisition functionality w.r.t. a connection protocol. The payload_ptr is required to contain a LibGit2.CredentialPayload object which will keep track of state and settings.\n\nThe allowed_types contains a bitmask of LibGit2.Consts.GIT_CREDTYPE values specifying which authentication methods should be attempted.\n\nCredential authentication is done in the following order (if supported):\n\nSSH agent\nSSH private/public key pair\nUsername/password plain text\n\nIf a user is presented with a credential prompt they can abort the prompt by typing ^D (pressing the control key together with the d key).\n\nNote: Due to the specifics of the libgit2 authentication procedure, when authentication fails, this function is called again without any indication whether authentication was successful or not. To avoid an infinite loop from repeatedly using the same faulty credentials, we will keep track of state using the payload.\n\nFor addition details see the LibGit2 guide on authenticating against a server.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.credentials_cb","page":"LibGit2","title":"LibGit2.credentials_cb","text":"C function pointer for credentials_callback\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.default_signature","page":"LibGit2","title":"LibGit2.default_signature","text":"Return signature object. Free it after use.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.delete_branch","page":"LibGit2","title":"LibGit2.delete_branch","text":"LibGit2.delete_branch(branch::GitReference)\n\nDelete the branch pointed to by branch.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.diff_files","page":"LibGit2","title":"LibGit2.diff_files","text":"diff_files(repo::GitRepo, branch1::AbstractString, branch2::AbstractString; kwarg...) -> Vector{AbstractString}\n\nShow which files have changed in the git repository repo between branches branch1 and branch2.\n\nThe keyword argument is:\n\nfilter::Set{Consts.DELTA_STATUS}=Set([Consts.DELTA_ADDED, Consts.DELTA_MODIFIED, Consts.DELTA_DELETED])), and it sets options for the diff. The default is to show files added, modified, or deleted.\n\nReturn only the names of the files which have changed, not their contents.\n\nExamples\n\nLibGit2.branch!(repo, \"branch/a\")\nLibGit2.branch!(repo, \"branch/b\")\n# add a file to repo\nopen(joinpath(LibGit2.path(repo),\"file\"),\"w\") do f\n write(f, \"hello repo\n\")\nend\nLibGit2.add!(repo, \"file\")\nLibGit2.commit(repo, \"add file\")\n# returns [\"file\"]\nfilt = Set([LibGit2.Consts.DELTA_ADDED])\nfiles = LibGit2.diff_files(repo, \"branch/a\", \"branch/b\", filter=filt)\n# returns [] because existing files weren't modified\nfilt = Set([LibGit2.Consts.DELTA_MODIFIED])\nfiles = LibGit2.diff_files(repo, \"branch/a\", \"branch/b\", filter=filt)\n\nEquivalent to git diff --name-only --diff-filter= .\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.entryid","page":"LibGit2","title":"LibGit2.entryid","text":"entryid(te::GitTreeEntry)\n\nReturn the GitHash of the object to which te refers.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.entrytype","page":"LibGit2","title":"LibGit2.entrytype","text":"entrytype(te::GitTreeEntry)\n\nReturn the type of the object to which te refers. The result will be one of the types which objtype returns, e.g. a GitTree or GitBlob.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fetch","page":"LibGit2","title":"LibGit2.fetch","text":"fetch(rmt::GitRemote, refspecs; options::FetchOptions=FetchOptions(), msg=\"\")\n\nFetch from the specified rmt remote git repository, using refspecs to determine which remote branch(es) to fetch. The keyword arguments are:\n\noptions: determines the options for the fetch, e.g. whether to prune afterwards. See FetchOptions for more information.\nmsg: a message to insert into the reflogs.\n\n\n\n\n\nfetch(repo::GitRepo; kwargs...)\n\nFetches updates from an upstream of the repository repo.\n\nThe keyword arguments are:\n\nremote::AbstractString=\"origin\": which remote, specified by name, of repo to fetch from. If this is empty, the URL will be used to construct an anonymous remote.\nremoteurl::AbstractString=\"\": the URL of remote. If not specified, will be assumed based on the given name of remote.\nrefspecs=AbstractString[]: determines properties of the fetch.\ncredentials=nothing: provides credentials and/or settings when authenticating against a private remote.\ncallbacks=Callbacks(): user provided callbacks and payloads.\n\nEquivalent to git fetch [|] [].\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fetchheads","page":"LibGit2","title":"LibGit2.fetchheads","text":"fetchheads(repo::GitRepo) -> Vector{FetchHead}\n\nReturn the list of all the fetch heads for repo, each represented as a FetchHead, including their names, URLs, and merge statuses.\n\nExamples\n\njulia> fetch_heads = LibGit2.fetchheads(repo);\n\njulia> fetch_heads[1].name\n\"refs/heads/master\"\n\njulia> fetch_heads[1].ismerge\ntrue\n\njulia> fetch_heads[2].name\n\"refs/heads/test_branch\"\n\njulia> fetch_heads[2].ismerge\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fetch_refspecs","page":"LibGit2","title":"LibGit2.fetch_refspecs","text":"fetch_refspecs(rmt::GitRemote) -> Vector{String}\n\nGet the fetch refspecs for the specified rmt. These refspecs contain information about which branch(es) to fetch from.\n\nExamples\n\njulia> remote = LibGit2.get(LibGit2.GitRemote, repo, \"upstream\");\n\njulia> LibGit2.add_fetch!(repo, remote, \"upstream\");\n\njulia> LibGit2.fetch_refspecs(remote)\nString[\"+refs/heads/*:refs/remotes/upstream/*\"]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fetchhead_foreach_cb","page":"LibGit2","title":"LibGit2.fetchhead_foreach_cb","text":"C function pointer for fetchhead_foreach_callback\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.merge_base","page":"LibGit2","title":"LibGit2.merge_base","text":"merge_base(repo::GitRepo, one::AbstractString, two::AbstractString) -> GitHash\n\nFind a merge base (a common ancestor) between the commits one and two. one and two may both be in string form. Return the GitHash of the merge base.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.merge!-Tuple{GitRepo}","page":"LibGit2","title":"LibGit2.merge!","text":"merge!(repo::GitRepo; kwargs...) -> Bool\n\nPerform a git merge on the repository repo, merging commits with diverging history into the current branch. Return true if the merge succeeded, false if not.\n\nThe keyword arguments are:\n\ncommittish::AbstractString=\"\": Merge the named commit(s) in committish.\nbranch::AbstractString=\"\": Merge the branch branch and all its commits since it diverged from the current branch.\nfastforward::Bool=false: If fastforward is true, only merge if the merge is a fast-forward (the current branch head is an ancestor of the commits to be merged), otherwise refuse to merge and return false. This is equivalent to the git CLI option --ff-only.\nmerge_opts::MergeOptions=MergeOptions(): merge_opts specifies options for the merge, such as merge strategy in case of conflicts.\ncheckout_opts::CheckoutOptions=CheckoutOptions(): checkout_opts specifies options for the checkout step.\n\nEquivalent to git merge [--ff-only] [ | ].\n\nnote: Note\nIf you specify a branch, this must be done in reference format, since the string will be turned into a GitReference. For example, if you wanted to merge branch branch_a, you would call merge!(repo, branch=\"refs/heads/branch_a\").\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.merge!-Tuple{GitRepo, Vector{LibGit2.GitAnnotated}}","page":"LibGit2","title":"LibGit2.merge!","text":"merge!(repo::GitRepo, anns::Vector{GitAnnotated}; kwargs...) -> Bool\n\nMerge changes from the annotated commits (captured as GitAnnotated objects) anns into the HEAD of the repository repo. The keyword arguments are:\n\nmerge_opts::MergeOptions = MergeOptions(): options for how to perform the merge, including whether fastforwarding is allowed. See MergeOptions for more information.\ncheckout_opts::CheckoutOptions = CheckoutOptions(): options for how to perform the checkout. See CheckoutOptions for more information.\n\nanns may refer to remote or local branch heads. Return true if the merge is successful, otherwise return false (for instance, if no merge is possible because the branches have no common ancestor).\n\nExamples\n\nupst_ann = LibGit2.GitAnnotated(repo, \"branch/a\")\n\n# merge the branch in\nLibGit2.merge!(repo, [upst_ann])\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.merge!-Tuple{GitRepo, Vector{LibGit2.GitAnnotated}, Bool}","page":"LibGit2","title":"LibGit2.merge!","text":"merge!(repo::GitRepo, anns::Vector{GitAnnotated}, fastforward::Bool; kwargs...) -> Bool\n\nMerge changes from the annotated commits (captured as GitAnnotated objects) anns into the HEAD of the repository repo. If fastforward is true, only a fastforward merge is allowed. In this case, if conflicts occur, the merge will fail. Otherwise, if fastforward is false, the merge may produce a conflict file which the user will need to resolve.\n\nThe keyword arguments are:\n\nmerge_opts::MergeOptions = MergeOptions(): options for how to perform the merge, including whether fastforwarding is allowed. See MergeOptions for more information.\ncheckout_opts::CheckoutOptions = CheckoutOptions(): options for how to perform the checkout. See CheckoutOptions for more information.\n\nanns may refer to remote or local branch heads. Return true if the merge is successful, otherwise return false (for instance, if no merge is possible because the branches have no common ancestor).\n\nExamples\n\nupst_ann_1 = LibGit2.GitAnnotated(repo, \"branch/a\")\n\n# merge the branch in, fastforward\nLibGit2.merge!(repo, [upst_ann_1], true)\n\n# merge conflicts!\nupst_ann_2 = LibGit2.GitAnnotated(repo, \"branch/b\")\n# merge the branch in, try to fastforward\nLibGit2.merge!(repo, [upst_ann_2], true) # will return false\nLibGit2.merge!(repo, [upst_ann_2], false) # will return true\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.ffmerge!","page":"LibGit2","title":"LibGit2.ffmerge!","text":"ffmerge!(repo::GitRepo, ann::GitAnnotated)\n\nFastforward merge changes into current HEAD. This is only possible if the commit referred to by ann is descended from the current HEAD (e.g. if pulling changes from a remote branch which is simply ahead of the local branch tip).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fullname","page":"LibGit2","title":"LibGit2.fullname","text":"LibGit2.fullname(ref::GitReference)\n\nReturn the name of the reference pointed to by the symbolic reference ref. If ref is not a symbolic reference, return an empty string.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.features","page":"LibGit2","title":"LibGit2.features","text":"features()\n\nReturn a list of git features the current version of libgit2 supports, such as threading or using HTTPS or SSH.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.filename","page":"LibGit2","title":"LibGit2.filename","text":"filename(te::GitTreeEntry)\n\nReturn the filename of the object on disk to which te refers.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.filemode","page":"LibGit2","title":"LibGit2.filemode","text":"filemode(te::GitTreeEntry) -> Cint\n\nReturn the UNIX filemode of the object on disk to which te refers as an integer.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.gitdir","page":"LibGit2","title":"LibGit2.gitdir","text":"LibGit2.gitdir(repo::GitRepo)\n\nReturn the location of the \"git\" files of repo:\n\nfor normal repositories, this is the location of the .git folder.\nfor bare repositories, this is the location of the repository itself.\n\nSee also workdir, path.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.git_url","page":"LibGit2","title":"LibGit2.git_url","text":"LibGit2.git_url(; kwargs...) -> String\n\nCreate a string based upon the URL components provided. When the scheme keyword is not provided the URL produced will use the alternative scp-like syntax.\n\nKeywords\n\nscheme::AbstractString=\"\": the URL scheme which identifies the protocol to be used. For HTTP use \"http\", SSH use \"ssh\", etc. When scheme is not provided the output format will be \"ssh\" but using the scp-like syntax.\nusername::AbstractString=\"\": the username to use in the output if provided.\npassword::AbstractString=\"\": the password to use in the output if provided.\nhost::AbstractString=\"\": the hostname to use in the output. A hostname is required to be specified.\nport::Union{AbstractString,Integer}=\"\": the port number to use in the output if provided. Cannot be specified when using the scp-like syntax.\npath::AbstractString=\"\": the path to use in the output if provided.\n\nwarning: Warning\nAvoid using passwords in URLs. Unlike the credential objects, Julia is not able to securely zero or destroy the sensitive data after use and the password may remain in memory; possibly to be exposed by an uninitialized memory.\n\nExamples\n\njulia> LibGit2.git_url(username=\"git\", host=\"github.com\", path=\"JuliaLang/julia.git\")\n\"git@github.com:JuliaLang/julia.git\"\n\njulia> LibGit2.git_url(scheme=\"https\", host=\"github.com\", path=\"/JuliaLang/julia.git\")\n\"https://github.com/JuliaLang/julia.git\"\n\njulia> LibGit2.git_url(scheme=\"ssh\", username=\"git\", host=\"github.com\", port=2222, path=\"JuliaLang/julia.git\")\n\"ssh://git@github.com:2222/JuliaLang/julia.git\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.@githash_str","page":"LibGit2","title":"LibGit2.@githash_str","text":"@githash_str -> AbstractGitHash\n\nConstruct a git hash object from the given string, returning a GitShortHash if the string is shorter than 40 hexadecimal digits, otherwise a GitHash.\n\nExamples\n\njulia> LibGit2.githash\"d114feb74ce633\"\nGitShortHash(\"d114feb74ce633\")\n\njulia> LibGit2.githash\"d114feb74ce63307afe878a5228ad014e0289a85\"\nGitHash(\"d114feb74ce63307afe878a5228ad014e0289a85\")\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/LibGit2/#LibGit2.head","page":"LibGit2","title":"LibGit2.head","text":"LibGit2.head(repo::GitRepo) -> GitReference\n\nReturn a GitReference to the current HEAD of repo.\n\n\n\n\n\nhead(pkg::AbstractString) -> String\n\nReturn current HEAD GitHash of the pkg repo as a string.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.head!","page":"LibGit2","title":"LibGit2.head!","text":"LibGit2.head!(repo::GitRepo, ref::GitReference) -> GitReference\n\nSet the HEAD of repo to the object pointed to by ref.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.head_oid","page":"LibGit2","title":"LibGit2.head_oid","text":"LibGit2.head_oid(repo::GitRepo) -> GitHash\n\nLookup the object id of the current HEAD of git repository repo.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.headname","page":"LibGit2","title":"LibGit2.headname","text":"LibGit2.headname(repo::GitRepo)\n\nLookup the name of the current HEAD of git repository repo. If repo is currently detached, return the name of the HEAD it's detached from.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.init","page":"LibGit2","title":"LibGit2.init","text":"LibGit2.init(path::AbstractString, bare::Bool=false) -> GitRepo\n\nOpen a new git repository at path. If bare is false, the working tree will be created in path/.git. If bare is true, no working directory will be created.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.is_ancestor_of","page":"LibGit2","title":"LibGit2.is_ancestor_of","text":"is_ancestor_of(a::AbstractString, b::AbstractString, repo::GitRepo) -> Bool\n\nReturn true if a, a GitHash in string form, is an ancestor of b, a GitHash in string form.\n\nExamples\n\njulia> repo = GitRepo(repo_path);\n\njulia> LibGit2.add!(repo, test_file1);\n\njulia> commit_oid1 = LibGit2.commit(repo, \"commit1\");\n\njulia> LibGit2.add!(repo, test_file2);\n\njulia> commit_oid2 = LibGit2.commit(repo, \"commit2\");\n\njulia> LibGit2.is_ancestor_of(string(commit_oid1), string(commit_oid2), repo)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isbinary","page":"LibGit2","title":"LibGit2.isbinary","text":"isbinary(blob::GitBlob) -> Bool\n\nUse a heuristic to guess if a file is binary: searching for NULL bytes and looking for a reasonable ratio of printable to non-printable characters among the first 8000 bytes.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.iscommit","page":"LibGit2","title":"LibGit2.iscommit","text":"iscommit(id::AbstractString, repo::GitRepo) -> Bool\n\nCheck if commit id (which is a GitHash in string form) is in the repository.\n\nExamples\n\njulia> repo = GitRepo(repo_path);\n\njulia> LibGit2.add!(repo, test_file);\n\njulia> commit_oid = LibGit2.commit(repo, \"add test_file\");\n\njulia> LibGit2.iscommit(string(commit_oid), repo)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isdiff","page":"LibGit2","title":"LibGit2.isdiff","text":"LibGit2.isdiff(repo::GitRepo, treeish::AbstractString, pathspecs::AbstractString=\"\"; cached::Bool=false)\n\nChecks if there are any differences between the tree specified by treeish and the tracked files in the working tree (if cached=false) or the index (if cached=true). pathspecs are the specifications for options for the diff.\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nLibGit2.isdiff(repo, \"HEAD\") # should be false\nopen(joinpath(repo_path, new_file), \"a\") do f\n println(f, \"here's my cool new file\")\nend\nLibGit2.isdiff(repo, \"HEAD\") # now true\n\nEquivalent to git diff-index [-- ].\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isdirty","page":"LibGit2","title":"LibGit2.isdirty","text":"LibGit2.isdirty(repo::GitRepo, pathspecs::AbstractString=\"\"; cached::Bool=false) -> Bool\n\nCheck if there have been any changes to tracked files in the working tree (if cached=false) or the index (if cached=true). pathspecs are the specifications for options for the diff.\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nLibGit2.isdirty(repo) # should be false\nopen(joinpath(repo_path, new_file), \"a\") do f\n println(f, \"here's my cool new file\")\nend\nLibGit2.isdirty(repo) # now true\nLibGit2.isdirty(repo, new_file) # now true\n\nEquivalent to git diff-index HEAD [-- ].\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isorphan","page":"LibGit2","title":"LibGit2.isorphan","text":"LibGit2.isorphan(repo::GitRepo)\n\nCheck if the current branch is an \"orphan\" branch, i.e. has no commits. The first commit to this branch will have no parents.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isset","page":"LibGit2","title":"LibGit2.isset","text":"isset(val::Integer, flag::Integer)\n\nTest whether the bits of val indexed by flag are set (1) or unset (0).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.iszero","page":"LibGit2","title":"LibGit2.iszero","text":"iszero(id::GitHash) -> Bool\n\nDetermine whether all hexadecimal digits of the given GitHash are zero.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.lookup_branch","page":"LibGit2","title":"LibGit2.lookup_branch","text":"lookup_branch(repo::GitRepo, branch_name::AbstractString, remote::Bool=false) -> Union{GitReference, Nothing}\n\nDetermine if the branch specified by branch_name exists in the repository repo. If remote is true, repo is assumed to be a remote git repository. Otherwise, it is part of the local filesystem.\n\nReturn either a GitReference to the requested branch if it exists, or nothing if not.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.map","page":"LibGit2","title":"LibGit2.map","text":"LibGit2.map(f::Function, walker::GitRevWalker; oid::GitHash=GitHash(), range::AbstractString=\"\", by::Cint=Consts.SORT_NONE, rev::Bool=false)\n\nUsing the GitRevWalker walker to \"walk\" over every commit in the repository's history, apply f to each commit in the walk. The keyword arguments are: * oid: The GitHash of the commit to begin the walk from. The default is to use push_head! and therefore the HEAD commit and all its ancestors. * range: A range of GitHashs in the format oid1..oid2. f will be applied to all commits between the two. * by: The sorting method. The default is not to sort. Other options are to sort by topology (LibGit2.Consts.SORT_TOPOLOGICAL), to sort forwards in time (LibGit2.Consts.SORT_TIME, most ancient first) or to sort backwards in time (LibGit2.Consts.SORT_REVERSE, most recent first). * rev: Whether to reverse the sorted order (for instance, if topological sorting is used).\n\nExamples\n\noids = LibGit2.with(LibGit2.GitRevWalker(repo)) do walker\n LibGit2.map((oid, repo)->string(oid), walker, by=LibGit2.Consts.SORT_TIME)\nend\n\nHere, LibGit2.map visits each commit using the GitRevWalker and finds its GitHash.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.mirror_callback","page":"LibGit2","title":"LibGit2.mirror_callback","text":"Mirror callback function\n\nFunction sets +refs/*:refs/* refspecs and mirror flag for remote reference.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.mirror_cb","page":"LibGit2","title":"LibGit2.mirror_cb","text":"C function pointer for mirror_callback\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.message","page":"LibGit2","title":"LibGit2.message","text":"message(c::GitCommit, raw::Bool=false)\n\nReturn the commit message describing the changes made in commit c. If raw is false, return a slightly \"cleaned up\" message (which has any leading newlines removed). If raw is true, the message is not stripped of any such newlines.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.merge_analysis","page":"LibGit2","title":"LibGit2.merge_analysis","text":"merge_analysis(repo::GitRepo, anns::Vector{GitAnnotated}) -> analysis, preference\n\nRun analysis on the branches pointed to by the annotated branch tips anns and determine under what circumstances they can be merged. For instance, if anns[1] is simply an ancestor of ann[2], then merge_analysis will report that a fast-forward merge is possible.\n\nReturn two outputs, analysis and preference. analysis has several possible values: * MERGE_ANALYSIS_NONE: it is not possible to merge the elements of anns. * MERGE_ANALYSIS_NORMAL: a regular merge, when HEAD and the commits that the user wishes to merge have all diverged from a common ancestor. In this case the changes have to be resolved and conflicts may occur. * MERGE_ANALYSIS_UP_TO_DATE: all the input commits the user wishes to merge can be reached from HEAD, so no merge needs to be performed. * MERGE_ANALYSIS_FASTFORWARD: the input commit is a descendant of HEAD and so no merge needs to be performed - instead, the user can simply checkout the input commit(s). * MERGE_ANALYSIS_UNBORN: the HEAD of the repository refers to a commit which does not exist. It is not possible to merge, but it may be possible to checkout the input commits. preference also has several possible values: * MERGE_PREFERENCE_NONE: the user has no preference. * MERGE_PREFERENCE_NO_FASTFORWARD: do not allow any fast-forward merges. * MERGE_PREFERENCE_FASTFORWARD_ONLY: allow only fast-forward merges and no other type (which may introduce conflicts). preference can be controlled through the repository or global git configuration.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.name","page":"LibGit2","title":"LibGit2.name","text":"LibGit2.name(ref::GitReference)\n\nReturn the full name of ref.\n\n\n\n\n\nname(rmt::GitRemote)\n\nGet the name of a remote repository, for instance \"origin\". If the remote is anonymous (see GitRemoteAnon) the name will be an empty string \"\".\n\nExamples\n\njulia> repo_url = \"https://github.com/JuliaLang/Example.jl\";\n\njulia> repo = LibGit2.clone(cache_repo, \"test_directory\");\n\njulia> remote = LibGit2.GitRemote(repo, \"origin\", repo_url);\n\njulia> name(remote)\n\"origin\"\n\n\n\n\n\nLibGit2.name(tag::GitTag)\n\nThe name of tag (e.g. \"v0.5\").\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.need_update","page":"LibGit2","title":"LibGit2.need_update","text":"need_update(repo::GitRepo)\n\nEquivalent to git update-index. Return true if repo needs updating.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.objtype","page":"LibGit2","title":"LibGit2.objtype","text":"objtype(obj_type::Consts.OBJECT)\n\nReturn the type corresponding to the enum value.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.path","page":"LibGit2","title":"LibGit2.path","text":"LibGit2.path(repo::GitRepo)\n\nReturn the base file path of the repository repo.\n\nfor normal repositories, this will typically be the parent directory of the \".git\" directory (note: this may be different than the working directory, see workdir for more details).\nfor bare repositories, this is the location of the \"git\" files.\n\nSee also gitdir, workdir.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.peel","page":"LibGit2","title":"LibGit2.peel","text":"peel([T,] ref::GitReference)\n\nRecursively peel ref until an object of type T is obtained. If no T is provided, then ref will be peeled until an object other than a GitTag is obtained.\n\nA GitTag will be peeled to the object it references.\nA GitCommit will be peeled to a GitTree.\n\nnote: Note\nOnly annotated tags can be peeled to GitTag objects. Lightweight tags (the default) are references under refs/tags/ which point directly to GitCommit objects.\n\n\n\n\n\npeel([T,] obj::GitObject)\n\nRecursively peel obj until an object of type T is obtained. If no T is provided, then obj will be peeled until the type changes.\n\nA GitTag will be peeled to the object it references.\nA GitCommit will be peeled to a GitTree.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.posixpath","page":"LibGit2","title":"LibGit2.posixpath","text":"LibGit2.posixpath(path)\n\nStandardise the path string path to use POSIX separators.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.push","page":"LibGit2","title":"LibGit2.push","text":"push(rmt::GitRemote, refspecs; force::Bool=false, options::PushOptions=PushOptions())\n\nPush to the specified rmt remote git repository, using refspecs to determine which remote branch(es) to push to. The keyword arguments are:\n\nforce: if true, a force-push will occur, disregarding conflicts.\noptions: determines the options for the push, e.g. which proxy headers to use. See PushOptions for more information.\n\nnote: Note\nYou can add information about the push refspecs in two other ways: by setting an option in the repository's GitConfig (with push.default as the key) or by calling add_push!. Otherwise you will need to explicitly specify a push refspec in the call to push for it to have any effect, like so: LibGit2.push(repo, refspecs=[\"refs/heads/master\"]).\n\n\n\n\n\npush(repo::GitRepo; kwargs...)\n\nPushes updates to an upstream of repo.\n\nThe keyword arguments are:\n\nremote::AbstractString=\"origin\": the name of the upstream remote to push to.\nremoteurl::AbstractString=\"\": the URL of remote.\nrefspecs=AbstractString[]: determines properties of the push.\nforce::Bool=false: determines if the push will be a force push, overwriting the remote branch.\ncredentials=nothing: provides credentials and/or settings when authenticating against a private remote.\ncallbacks=Callbacks(): user provided callbacks and payloads.\n\nEquivalent to git push [|] [].\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.push!-Tuple{LibGit2.GitRevWalker, LibGit2.GitHash}","page":"LibGit2","title":"LibGit2.push!","text":"LibGit2.push!(w::GitRevWalker, cid::GitHash)\n\nStart the GitRevWalker walker at commit cid. This function can be used to apply a function to all commits since a certain year, by passing the first commit of that year as cid and then passing the resulting w to LibGit2.map.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.push_head!","page":"LibGit2","title":"LibGit2.push_head!","text":"LibGit2.push_head!(w::GitRevWalker)\n\nPush the HEAD commit and its ancestors onto the GitRevWalker w. This ensures that HEAD and all its ancestor commits will be encountered during the walk.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.push_refspecs","page":"LibGit2","title":"LibGit2.push_refspecs","text":"push_refspecs(rmt::GitRemote) -> Vector{String}\n\nGet the push refspecs for the specified rmt. These refspecs contain information about which branch(es) to push to.\n\nExamples\n\njulia> remote = LibGit2.get(LibGit2.GitRemote, repo, \"upstream\");\n\njulia> LibGit2.add_push!(repo, remote, \"refs/heads/master\");\n\njulia> close(remote);\n\njulia> remote = LibGit2.get(LibGit2.GitRemote, repo, \"upstream\");\n\njulia> LibGit2.push_refspecs(remote)\nString[\"refs/heads/master\"]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.raw","page":"LibGit2","title":"LibGit2.raw","text":"raw(id::GitHash) -> Vector{UInt8}\n\nObtain the raw bytes of the GitHash as a vector of length 20.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.read_tree!","page":"LibGit2","title":"LibGit2.read_tree!","text":"LibGit2.read_tree!(idx::GitIndex, tree::GitTree)\nLibGit2.read_tree!(idx::GitIndex, treehash::AbstractGitHash)\n\nRead the tree tree (or the tree pointed to by treehash in the repository owned by idx) into the index idx. The current index contents will be replaced.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.rebase!","page":"LibGit2","title":"LibGit2.rebase!","text":"LibGit2.rebase!(repo::GitRepo, upstream::AbstractString=\"\", newbase::AbstractString=\"\")\n\nAttempt an automatic merge rebase of the current branch, from upstream if provided, or otherwise from the upstream tracking branch. newbase is the branch to rebase onto. By default this is upstream.\n\nIf any conflicts arise which cannot be automatically resolved, the rebase will abort, leaving the repository and working tree in its original state, and the function will throw a GitError. This is roughly equivalent to the following command line statement:\n\ngit rebase --merge []\nif [ -d \".git/rebase-merge\" ]; then\n git rebase --abort\nfi\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.ref_list","page":"LibGit2","title":"LibGit2.ref_list","text":"LibGit2.ref_list(repo::GitRepo) -> Vector{String}\n\nGet a list of all reference names in the repo repository.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.reftype","page":"LibGit2","title":"LibGit2.reftype","text":"LibGit2.reftype(ref::GitReference) -> Cint\n\nReturn a Cint corresponding to the type of ref:\n\n0 if the reference is invalid\n1 if the reference is an object id\n2 if the reference is symbolic\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.remotes","page":"LibGit2","title":"LibGit2.remotes","text":"LibGit2.remotes(repo::GitRepo)\n\nReturn a vector of the names of the remotes of repo.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.remove!","page":"LibGit2","title":"LibGit2.remove!","text":"remove!(repo::GitRepo, files::AbstractString...)\nremove!(idx::GitIndex, files::AbstractString...)\n\nRemove all the files with paths specified by files in the index idx (or the index of the repo).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.reset","page":"LibGit2","title":"LibGit2.reset","text":"reset(val::Integer, flag::Integer)\n\nUnset the bits of val indexed by flag, returning them to 0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.reset!","page":"LibGit2","title":"LibGit2.reset!","text":"reset!(payload, [config]) -> CredentialPayload\n\nReset the payload state back to the initial values so that it can be used again within the credential callback. If a config is provided the configuration will also be updated.\n\n\n\n\n\nUpdates some entries, determined by the pathspecs, in the index from the target commit tree.\n\n\n\n\n\nSets the current head to the specified commit oid and optionally resets the index and working tree to match.\n\n\n\n\n\ngit reset [] [–] ... \n\n\n\n\n\nreset!(repo::GitRepo, id::GitHash, mode::Cint=Consts.RESET_MIXED)\n\nReset the repository repo to its state at id, using one of three modes set by mode:\n\nConsts.RESET_SOFT - move HEAD to id.\nConsts.RESET_MIXED - default, move HEAD to id and reset the index to id.\nConsts.RESET_HARD - move HEAD to id, reset the index to id, and discard all working changes.\n\nExamples\n\n# fetch changes\nLibGit2.fetch(repo)\nisfile(joinpath(repo_path, our_file)) # will be false\n\n# fastforward merge the changes\nLibGit2.merge!(repo, fastforward=true)\n\n# because there was not any file locally, but there is\n# a file remotely, we need to reset the branch\nhead_oid = LibGit2.head_oid(repo)\nnew_head = LibGit2.reset!(repo, head_oid, LibGit2.Consts.RESET_HARD)\n\nIn this example, the remote which is being fetched from does have a file called our_file in its index, which is why we must reset.\n\nEquivalent to git reset [--soft | --mixed | --hard] .\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nhead_oid = LibGit2.head_oid(repo)\nopen(joinpath(repo_path, \"file1\"), \"w\") do f\n write(f, \"111\n\")\nend\nLibGit2.add!(repo, \"file1\")\nmode = LibGit2.Consts.RESET_HARD\n# will discard the changes to file1\n# and unstage it\nnew_head = LibGit2.reset!(repo, head_oid, mode)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.restore","page":"LibGit2","title":"LibGit2.restore","text":"restore(s::State, repo::GitRepo)\n\nReturn a repository repo to a previous State s, for example the HEAD of a branch before a merge attempt. s can be generated using the snapshot function.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.revcount","page":"LibGit2","title":"LibGit2.revcount","text":"LibGit2.revcount(repo::GitRepo, commit1::AbstractString, commit2::AbstractString)\n\nList the number of revisions between commit1 and commit2 (committish OIDs in string form). Since commit1 and commit2 may be on different branches, revcount performs a \"left-right\" revision list (and count), returning a tuple of Ints - the number of left and right commits, respectively. A left (or right) commit refers to which side of a symmetric difference in a tree the commit is reachable from.\n\nEquivalent to git rev-list --left-right --count .\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nrepo_file = open(joinpath(repo_path, test_file), \"a\")\nprintln(repo_file, \"hello world\")\nflush(repo_file)\nLibGit2.add!(repo, test_file)\ncommit_oid1 = LibGit2.commit(repo, \"commit 1\")\nprintln(repo_file, \"hello world again\")\nflush(repo_file)\nLibGit2.add!(repo, test_file)\ncommit_oid2 = LibGit2.commit(repo, \"commit 2\")\nLibGit2.revcount(repo, string(commit_oid1), string(commit_oid2))\n\nThis will return (-1, 0).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.set_remote_url","page":"LibGit2","title":"LibGit2.set_remote_url","text":"set_remote_url(repo::GitRepo, remote_name, url)\nset_remote_url(repo::String, remote_name, url)\n\nSet both the fetch and push url for remote_name for the GitRepo or the git repository located at path. Typically git repos use \"origin\" as the remote name.\n\nExamples\n\nrepo_path = joinpath(tempdir(), \"Example\")\nrepo = LibGit2.init(repo_path)\nLibGit2.set_remote_url(repo, \"upstream\", \"https://github.com/JuliaLang/Example.jl\")\nLibGit2.set_remote_url(repo_path, \"upstream2\", \"https://github.com/JuliaLang/Example2.jl\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.shortname","page":"LibGit2","title":"LibGit2.shortname","text":"LibGit2.shortname(ref::GitReference)\n\nReturn a shortened version of the name of ref that's \"human-readable\".\n\njulia> repo = GitRepo(path_to_repo);\n\njulia> branch_ref = LibGit2.head(repo);\n\njulia> LibGit2.name(branch_ref)\n\"refs/heads/master\"\n\njulia> LibGit2.shortname(branch_ref)\n\"master\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.snapshot","page":"LibGit2","title":"LibGit2.snapshot","text":"snapshot(repo::GitRepo) -> State\n\nTake a snapshot of the current state of the repository repo, storing the current HEAD, index, and any uncommitted work. The output State can be used later during a call to restore to return the repository to the snapshotted state.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.split_cfg_entry","page":"LibGit2","title":"LibGit2.split_cfg_entry","text":"LibGit2.split_cfg_entry(ce::LibGit2.ConfigEntry) -> Tuple{String,String,String,String}\n\nBreak the ConfigEntry up to the following pieces: section, subsection, name, and value.\n\nExamples\n\nGiven the git configuration file containing:\n\n[credential \"https://example.com\"]\n username = me\n\nThe ConfigEntry would look like the following:\n\njulia> entry\nConfigEntry(\"credential.https://example.com.username\", \"me\")\n\njulia> LibGit2.split_cfg_entry(entry)\n(\"credential\", \"https://example.com\", \"username\", \"me\")\n\nRefer to the git config syntax documentation for more details.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.status","page":"LibGit2","title":"LibGit2.status","text":"LibGit2.status(repo::GitRepo, path::String) -> Union{Cuint, Cvoid}\n\nLookup the status of the file at path in the git repository repo. For instance, this can be used to check if the file at path has been modified and needs to be staged and committed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.stage","page":"LibGit2","title":"LibGit2.stage","text":"stage(ie::IndexEntry) -> Cint\n\nGet the stage number of ie. The stage number 0 represents the current state of the working tree, but other numbers can be used in the case of a merge conflict. In such a case, the various stage numbers on an IndexEntry describe which side(s) of the conflict the current state of the file belongs to. Stage 0 is the state before the attempted merge, stage 1 is the changes which have been made locally, stages 2 and larger are for changes from other branches (for instance, in the case of a multi-branch \"octopus\" merge, stages 2, 3, and 4 might be used).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.tag_create","page":"LibGit2","title":"LibGit2.tag_create","text":"LibGit2.tag_create(repo::GitRepo, tag::AbstractString, commit; kwargs...)\n\nCreate a new git tag tag (e.g. \"v0.5\") in the repository repo, at the commit commit.\n\nThe keyword arguments are:\n\nmsg::AbstractString=\"\": the message for the tag.\nforce::Bool=false: if true, existing references will be overwritten.\nsig::Signature=Signature(repo): the tagger's signature.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.tag_delete","page":"LibGit2","title":"LibGit2.tag_delete","text":"LibGit2.tag_delete(repo::GitRepo, tag::AbstractString)\n\nRemove the git tag tag from the repository repo.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.tag_list","page":"LibGit2","title":"LibGit2.tag_list","text":"LibGit2.tag_list(repo::GitRepo) -> Vector{String}\n\nGet a list of all tags in the git repository repo.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.target","page":"LibGit2","title":"LibGit2.target","text":"LibGit2.target(tag::GitTag)\n\nThe GitHash of the target object of tag.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.toggle","page":"LibGit2","title":"LibGit2.toggle","text":"toggle(val::Integer, flag::Integer)\n\nFlip the bits of val indexed by flag, so that if a bit is 0 it will be 1 after the toggle, and vice-versa.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.transact","page":"LibGit2","title":"LibGit2.transact","text":"transact(f::Function, repo::GitRepo)\n\nApply function f to the git repository repo, taking a snapshot before applying f. If an error occurs within f, repo will be returned to its snapshot state using restore. The error which occurred will be rethrown, but the state of repo will not be corrupted.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.treewalk","page":"LibGit2","title":"LibGit2.treewalk","text":"treewalk(f, tree::GitTree, post::Bool=false)\n\nTraverse the entries in tree and its subtrees in post or pre order. Preorder means beginning at the root and then traversing the leftmost subtree (and recursively on down through that subtree's leftmost subtrees) and moving right through the subtrees. Postorder means beginning at the bottom of the leftmost subtree, traversing upwards through it, then traversing the next right subtree (again beginning at the bottom) and finally visiting the tree root last of all.\n\nThe function parameter f should have following signature:\n\n(String, GitTreeEntry) -> Cint\n\nA negative value returned from f stops the tree walk. A positive value means that the entry will be skipped if post is false.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.upstream","page":"LibGit2","title":"LibGit2.upstream","text":"upstream(ref::GitReference) -> Union{GitReference, Nothing}\n\nDetermine if the branch containing ref has a specified upstream branch.\n\nReturn either a GitReference to the upstream branch if it exists, or nothing if the requested branch does not have an upstream counterpart.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.update!","page":"LibGit2","title":"LibGit2.update!","text":"update!(repo::GitRepo, files::AbstractString...)\nupdate!(idx::GitIndex, files::AbstractString...)\n\nUpdate all the files with paths specified by files in the index idx (or the index of the repo). Match the state of each file in the index with the current state on disk, removing it if it has been removed on disk, or updating its entry in the object database.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.url","page":"LibGit2","title":"LibGit2.url","text":"url(rmt::GitRemote)\n\nGet the fetch URL of a remote git repository.\n\nExamples\n\njulia> repo_url = \"https://github.com/JuliaLang/Example.jl\";\n\njulia> repo = LibGit2.init(mktempdir());\n\njulia> remote = LibGit2.GitRemote(repo, \"origin\", repo_url);\n\njulia> LibGit2.url(remote)\n\"https://github.com/JuliaLang/Example.jl\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.version","page":"LibGit2","title":"LibGit2.version","text":"version() -> VersionNumber\n\nReturn the version of libgit2 in use, as a VersionNumber.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.with","page":"LibGit2","title":"LibGit2.with","text":"with(f::Function, obj)\n\nResource management helper function. Applies f to obj, making sure to call close on obj after f successfully returns or throws an error. Ensures that allocated git resources are finalized as soon as they are no longer needed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.with_warn","page":"LibGit2","title":"LibGit2.with_warn","text":"with_warn(f::Function, ::Type{T}, args...)\n\nResource management helper function. Apply f to args, first constructing an instance of type T from args. Makes sure to call close on the resulting object after f successfully returns or throws an error. Ensures that allocated git resources are finalized as soon as they are no longer needed. If an error is thrown by f, a warning is shown containing the error.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.workdir","page":"LibGit2","title":"LibGit2.workdir","text":"LibGit2.workdir(repo::GitRepo)\n\nReturn the location of the working directory of repo. This will throw an error for bare repositories.\n\nnote: Note\nThis will typically be the parent directory of gitdir(repo), but can be different in some cases: e.g. if either the core.worktree configuration variable or the GIT_WORK_TREE environment variable is set.\n\nSee also gitdir, path.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.GitObject-Tuple{LibGit2.GitTreeEntry}","page":"LibGit2","title":"LibGit2.GitObject","text":"(::Type{T})(te::GitTreeEntry) where T<:GitObject\n\nGet the git object to which te refers and return it as its actual type (the type entrytype would show), for instance a GitBlob or GitTag.\n\nExamples\n\ntree = LibGit2.GitTree(repo, \"HEAD^{tree}\")\ntree_entry = tree[1]\nblob = LibGit2.GitBlob(tree_entry)\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.UserPasswordCredential","page":"LibGit2","title":"LibGit2.UserPasswordCredential","text":"Credential that support only user and password parameters\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.SSHCredential","page":"LibGit2","title":"LibGit2.SSHCredential","text":"SSH credential type\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.isfilled","page":"LibGit2","title":"LibGit2.isfilled","text":"isfilled(cred::AbstractCredential) -> Bool\n\nVerifies that a credential is ready for use in authentication.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.CachedCredentials","page":"LibGit2","title":"LibGit2.CachedCredentials","text":"Caches credential information for re-use\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.CredentialPayload","page":"LibGit2","title":"LibGit2.CredentialPayload","text":"LibGit2.CredentialPayload\n\nRetains the state between multiple calls to the credential callback for the same URL. A CredentialPayload instance is expected to be reset! whenever it will be used with a different URL.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.approve","page":"LibGit2","title":"LibGit2.approve","text":"approve(payload::CredentialPayload; shred::Bool=true) -> Nothing\n\nStore the payload credential for re-use in a future authentication. Should only be called when authentication was successful.\n\nThe shred keyword controls whether sensitive information in the payload credential field should be destroyed. Should only be set to false during testing.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.reject","page":"LibGit2","title":"LibGit2.reject","text":"reject(payload::CredentialPayload; shred::Bool=true) -> Nothing\n\nDiscard the payload credential from begin re-used in future authentication. Should only be called when authentication was unsuccessful.\n\nThe shred keyword controls whether sensitive information in the payload credential field should be destroyed. Should only be set to false during testing.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.Consts.GIT_CONFIG","page":"LibGit2","title":"LibGit2.Consts.GIT_CONFIG","text":"Priority level of a config file.\n\nThese priority levels correspond to the natural escalation logic (from higher to lower) when searching for config entries in git.\n\nCONFIG_LEVEL_DEFAULT - Open the global, XDG and system configuration files if any available.\nCONFIG_LEVEL_PROGRAMDATA - System-wide on Windows, for compatibility with portable git\nCONFIG_LEVEL_SYSTEM - System-wide configuration file; /etc/gitconfig on Linux systems\nCONFIG_LEVEL_XDG - XDG compatible configuration file; typically ~/.config/git/config\nCONFIG_LEVEL_GLOBAL - User-specific configuration file (also called Global configuration file); typically ~/.gitconfig\nCONFIG_LEVEL_LOCAL - Repository specific configuration file; $WORK_DIR/.git/config on non-bare repos\nCONFIG_LEVEL_APP - Application specific configuration file; freely defined by applications\nCONFIG_HIGHEST_LEVEL - Represents the highest level available config file (i.e. the most specific config file available that actually is loaded)\n\n\n\n\n\n","category":"type"},{"location":"base/punctuation/#man-punctuation","page":"Punctuation","title":"Punctuation","text":"","category":"section"},{"location":"base/punctuation/","page":"Punctuation","title":"Punctuation","text":"Extended documentation for mathematical symbols & functions is here.","category":"page"},{"location":"base/punctuation/","page":"Punctuation","title":"Punctuation","text":"symbol meaning\n@ the at-sign marks a macro invocation; optionally followed by an argument list\n! an exclamation mark is a prefix operator for logical negation (\"not\")\na! function names that end with an exclamation mark modify one or more of their arguments by convention\n# the number sign (or hash or pound) character begins single line comments\n#= when followed by an equals sign, it begins a multi-line comment (these are nestable)\n=# end a multi-line comment by immediately preceding the number sign with an equals sign\n$ the dollar sign is used for string and expression interpolation\n% the percent symbol is the remainder operator\n^ the caret is the exponentiation operator\n& single ampersand is bitwise and\n&& double ampersands is short-circuiting boolean and\n| single pipe character is bitwise or\n|| double pipe characters is short-circuiting boolean or\n⊻ the unicode xor character is bitwise exclusive or\n~ the tilde is an operator for bitwise not\n' a trailing apostrophe is the adjoint (that is, the complex transpose) operator Aᴴ\n* the asterisk is used for multiplication, including matrix multiplication and string concatenation\n/ forward slash divides the argument on its left by the one on its right\n\\ backslash operator divides the argument on its right by the one on its left, commonly used to solve matrix equations\n() parentheses with no arguments constructs an empty Tuple\n(a,...) parentheses with comma-separated arguments constructs a tuple containing its arguments\n(a=1,...) parentheses with comma-separated assignments constructs a NamedTuple\n(x;y) parentheses can also be used to group one or more semicolon separated expressions\na[] array indexing (calling getindex or setindex!)\n[,] vector literal constructor (calling vect)\n[;] vertical concatenation (calling vcat or hvcat)\n[ ] with space-separated expressions, horizontal concatenation (calling hcat or hvcat)\nT{ } curly braces following a type list that type's parameters\n{} curly braces can also be used to group multiple where expressions in function declarations\n; semicolons separate statements, begin a list of keyword arguments in function declarations or calls, or are used to separate array literals for vertical concatenation\n, commas separate function arguments or tuple or array components\n? the question mark delimits the ternary conditional operator (used like: conditional ? if_true : if_false)\n\" \" the single double-quote character delimits String literals\n\"\"\" \"\"\" three double-quote characters delimits string literals that may contain \" and ignore leading indentation\n' ' the single-quote character delimits Char (that is, character) literals\n` ` the backtick character delimits external process (Cmd) literals\nA... triple periods are a postfix operator that \"splat\" their arguments' contents into many arguments of a function call or declare a varargs function that \"slurps\" up many arguments into a single tuple\na.b single periods access named fields in objects/modules (calling getproperty or setproperty!)\nf.() periods may also prefix parentheses (like f.(...)) or infix operators (like .+) to perform the function element-wise (calling broadcast)\na:b colons (:) used as a binary infix operator construct a range from a to b (inclusive) with fixed step size 1\na:s:b colons (:) used as a ternary infix operator construct a range from a to b (inclusive) with step size s\n: when used by themselves, Colons represent all indices within a dimension, frequently combined with indexing\n:: double-colons represent a type annotation or typeassert, depending on context, frequently used when declaring function arguments\n:( ) quoted expression\n:a Symbol a\n<: subtype operator\n>: supertype operator (reverse of subtype operator)\n= single equals sign is assignment\n== double equals sign is value equality comparison\n=== triple equals sign is programmatically identical equality comparison\n=> right arrow using an equals sign defines a Pair typically used to populate dictionaries\n-> right arrow using a hyphen defines an anonymous function on a single line\n|> pipe operator passes output from the left argument to input of the right argument, usually a function\n∘ function composition operator (typed with \\circ{tab}) combines two functions as though they are a single larger function\n_ underscores may be assigned values which will not be saved, often used to ignore multiple return values or create repetitive comprehensions","category":"page"},{"location":"devdocs/build/linux/#Linux","page":"Linux","title":"Linux","text":"","category":"section"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"GCC version 4.7 or later is required to build Julia.\nTo use external shared libraries not in the system library search path, set USE_SYSTEM_XXX=1 and LDFLAGS=-Wl,-rpath,/path/to/dir/contains/libXXX.so in Make.user.\nInstead of setting LDFLAGS, putting the library directory into the environment variable LD_LIBRARY_PATH (at both compile and run time) also works.\nThe USE_SYSTEM_* flags should be used with caution. These are meant only for troubleshooting, porting, and packaging, where package maintainers work closely with the Julia developers to make sure that Julia is built correctly. Production use cases should use the officially provided binaries. Issues arising from the use of these flags will generally not be accepted.\nSee also the external dependencies.","category":"page"},{"location":"devdocs/build/linux/#Architecture-Customization","page":"Linux","title":"Architecture Customization","text":"","category":"section"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"Julia can be built for a non-generic architecture by configuring the ARCH Makefile variable in a Make.user file. See the appropriate section of Make.inc for additional customization options, such as MARCH and JULIA_CPU_TARGET.","category":"page"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"For example, to build for Pentium 4, set MARCH=pentium4 and install the necessary system libraries for linking. On Ubuntu, these may include lib32gfortran-6-dev, lib32gcc1, and lib32stdc++6, among others.","category":"page"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"You can also set MARCH=native in Make.user for a maximum-performance build customized for the current machine CPU.","category":"page"},{"location":"devdocs/build/linux/#Linux-Build-Troubleshooting","page":"Linux","title":"Linux Build Troubleshooting","text":"","category":"section"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"Problem Possible Solution\nOpenBLAS build failure Set one of the following build options in Make.user and build again:
    • OPENBLAS_TARGET_ARCH=BARCELONA (AMD CPUs) or OPENBLAS_TARGET_ARCH=NEHALEM (Intel CPUs)
        Set OPENBLAS_DYNAMIC_ARCH = 0 to disable compiling multiple architectures in a single binary.
    • OPENBLAS_NO_AVX2 = 1 disables AVX2 instructions, allowing OpenBLAS to compile with OPENBLAS_DYNAMIC_ARCH = 1 using old versions of binutils
    • USE_SYSTEM_BLAS=1 uses the system provided libblas
      • Set LIBBLAS=-lopenblas and LIBBLASNAME=libopenblas to force the use of the system provided OpenBLAS when multiple BLAS versions are installed.

    If you get an error that looks like ../kernel/x86_64/dgemm_kernel_4x4_haswell.S:1709: Error: no such instruction: `vpermpd $ 0xb1,%ymm0,%ymm0', then you need to set OPENBLAS_DYNAMIC_ARCH = 0 or OPENBLAS_NO_AVX2 = 1, or you need a newer version of binutils (2.18 or newer). (Issue #7653)

    If the linker cannot find gfortran and you get an error like julia /usr/bin/x86_64-linux-gnu-ld: cannot find -lgfortran, check the path with gfortran -print-file-name=libgfortran.so and use the output to export something similar to this: export LDFLAGS=-L/usr/lib/gcc/x86_64-linux-gnu/8/. See Issue #6150.

    \nIllegal Instruction error Check if your CPU supports AVX while your OS does not (e.g. through virtualization, as described in this issue).","category":"page"},{"location":"manual/multi-threading/#man-multithreading","page":"Multi-Threading","title":"Multi-Threading","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Visit this blog post for a presentation of Julia multi-threading features.","category":"page"},{"location":"manual/multi-threading/#Starting-Julia-with-multiple-threads","page":"Multi-Threading","title":"Starting Julia with multiple threads","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"By default, Julia starts up with a single thread of execution. This can be verified by using the command Threads.nthreads():","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> Threads.nthreads()\n1","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The number of execution threads is controlled either by using the -t/--threads command line argument or by using the JULIA_NUM_THREADS environment variable. When both are specified, then -t/--threads takes precedence.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The number of threads can either be specified as an integer (--threads=4) or as auto (--threads=auto), where auto tries to infer a useful default number of threads to use (see Command-line Options for more details).","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.5\nThe -t/--threads command line argument requires at least Julia 1.5. In older versions you must use the environment variable instead.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.7\nUsing auto as value of the environment variable JULIA_NUM_THREADS requires at least Julia 1.7. In older versions, this value is ignored.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Lets start Julia with 4 threads:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"$ julia --threads 4","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Let's verify there are 4 threads at our disposal.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> Threads.nthreads()\n4","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"But we are currently on the master thread. To check, we use the function Threads.threadid","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> Threads.threadid()\n1","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nIf you prefer to use the environment variable you can set it as follows in Bash (Linux/macOS):export JULIA_NUM_THREADS=4C shell on Linux/macOS, CMD on Windows:set JULIA_NUM_THREADS=4Powershell on Windows:$env:JULIA_NUM_THREADS=4Note that this must be done before starting Julia.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nThe number of threads specified with -t/--threads is propagated to worker processes that are spawned using the -p/--procs or --machine-file command line options. For example, julia -p2 -t2 spawns 1 main process with 2 worker processes, and all three processes have 2 threads enabled. For more fine grained control over worker threads use addprocs and pass -t/--threads as exeflags.","category":"page"},{"location":"manual/multi-threading/#Multiple-GC-Threads","page":"Multi-Threading","title":"Multiple GC Threads","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The Garbage Collector (GC) can use multiple threads. The amount used is either half the number of compute worker threads or configured by either the --gcthreads command line argument or by using the JULIA_NUM_GC_THREADS environment variable.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.10\nThe --gcthreads command line argument requires at least Julia 1.10.","category":"page"},{"location":"manual/multi-threading/#man-threadpools","page":"Multi-Threading","title":"Threadpools","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"When a program's threads are busy with many tasks to run, tasks may experience delays which may negatively affect the responsiveness and interactivity of the program. To address this, you can specify that a task is interactive when you Threads.@spawn it:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"using Base.Threads\n@spawn :interactive f()","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Interactive tasks should avoid performing high latency operations, and if they are long duration tasks, should yield frequently.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Julia may be started with one or more threads reserved to run interactive tasks:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"$ julia --threads 3,1","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The environment variable JULIA_NUM_THREADS can also be used similarly:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"export JULIA_NUM_THREADS=3,1","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"This starts Julia with 3 threads in the :default threadpool and 1 thread in the :interactive threadpool:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> using Base.Threads\n\njulia> nthreadpools()\n2\n\njulia> threadpool() # the main thread is in the interactive thread pool\n:interactive\n\njulia> nthreads(:default)\n3\n\njulia> nthreads(:interactive)\n1\n\njulia> nthreads()\n3","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nThe zero-argument version of nthreads returns the number of threads in the default pool.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nDepending on whether Julia has been started with interactive threads, the main thread is either in the default or interactive thread pool.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Either or both numbers can be replaced with the word auto, which causes Julia to choose a reasonable default.","category":"page"},{"location":"manual/multi-threading/#The-@threads-Macro","page":"Multi-Threading","title":"The @threads Macro","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Let's work a simple example using our native threads. Let us create an array of zeros:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> a = zeros(10)\n10-element Vector{Float64}:\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Let us operate on this array simultaneously using 4 threads. We'll have each thread write its thread ID into each location.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Julia supports parallel loops using the Threads.@threads macro. This macro is affixed in front of a for loop to indicate to Julia that the loop is a multi-threaded region:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> Threads.@threads for i = 1:10\n a[i] = Threads.threadid()\n end","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The iteration space is split among the threads, after which each thread writes its thread ID to its assigned locations:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> a\n10-element Vector{Float64}:\n 1.0\n 1.0\n 1.0\n 2.0\n 2.0\n 2.0\n 3.0\n 3.0\n 4.0\n 4.0","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Note that Threads.@threads does not have an optional reduction parameter like @distributed.","category":"page"},{"location":"manual/multi-threading/#Using-@threads-without-data-races","page":"Multi-Threading","title":"Using @threads without data-races","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The concept of a data-race is elaborated on in \"Communication and data races between threads\". For now, just known that a data race can result in incorrect results and dangerous errors.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Lets say we want to make the function sum_single below multithreaded.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> function sum_single(a)\n s = 0\n for i in a\n s += i\n end\n s\n end\nsum_single (generic function with 1 method)\n\njulia> sum_single(1:1_000_000)\n500000500000","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Simply adding @threads exposes a data race with multiple threads reading and writing s at the same time.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> function sum_multi_bad(a)\n s = 0\n Threads.@threads for i in a\n s += i\n end\n s\n end\nsum_multi_bad (generic function with 1 method)\n\njulia> sum_multi_bad(1:1_000_000)\n70140554652","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Note that the result is not 500000500000 as it should be, and will most likely change each evaluation.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"To fix this, buffers that are specific to the task may be used to segment the sum into chunks that are race-free. Here sum_single is reused, with its own internal buffer s. The input vector a is split into at most nthreads() chunks for parallel work. We then use Threads.@spawn to create tasks that individually sum each chunk. Finally, we sum the results from each task using sum_single again:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> function sum_multi_good(a)\n chunks = Iterators.partition(a, cld(length(a), Threads.nthreads()))\n tasks = map(chunks) do chunk\n Threads.@spawn sum_single(chunk)\n end\n chunk_sums = fetch.(tasks)\n return sum_single(chunk_sums)\n end\nsum_multi_good (generic function with 1 method)\n\njulia> sum_multi_good(1:1_000_000)\n500000500000","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nBuffers should not be managed based on threadid() i.e. buffers = zeros(Threads.nthreads()) because concurrent tasks can yield, meaning multiple concurrent tasks may use the same buffer on a given thread, introducing risk of data races. Further, when more than one thread is available tasks may change thread at yield points, which is known as task migration.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Another option is the use of atomic operations on variables shared across tasks/threads, which may be more performant depending on the characteristics of the operations.","category":"page"},{"location":"manual/multi-threading/#man-communication-and-data-races","page":"Multi-Threading","title":"Communication and data-races between threads","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Although Julia's threads can communicate through shared memory, it is notoriously difficult to write correct and data-race free multi-threaded code. Julia's Channels are thread-safe and may be used to communicate safely. There are also sections below that explain how to use locks and atomics to avoid data-races.","category":"page"},{"location":"manual/multi-threading/#Data-race-freedom","page":"Multi-Threading","title":"Data-race freedom","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"You are entirely responsible for ensuring that your program is data-race free, and nothing promised here can be assumed if you do not observe that requirement. The observed results may be highly unintuitive.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"If data-races are introduced, Julia is not memory safe. Be very careful about reading any data if another thread might write to it, as it could result in segmentation faults or worse. Below are a couple of unsafe ways to access global variables from different threads:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Thread 1:\nglobal b = false\nglobal a = rand()\nglobal b = true\n\nThread 2:\nwhile !b; end\nbad_read1(a) # it is NOT safe to access `a` here!\n\nThread 3:\nwhile !@isdefined(a); end\nbad_read2(a) # it is NOT safe to access `a` here","category":"page"},{"location":"manual/multi-threading/#man-using-locks","page":"Multi-Threading","title":"Using locks to avoid data-races","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"An important tool to avoid data-races, and thereby write thread-safe code, is the concept of a \"lock\". A lock can be locked and unlocked. If a thread has locked a lock, and not unlocked it, it is said to \"hold\" the lock. If there is only one lock, and we write code the requires holding the lock to access some data, we can ensure that multiple threads will never access the same data simultaneously. Note that the link between a lock and a variable is made by the programmer, and not the program.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"For example, we can create a lock my_lock, and lock it while we mutate a variable my_variable. This is done most simply with the @lock macro:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> my_lock = ReentrantLock();\n\njulia> my_variable = [1, 2, 3];\n\njulia> @lock my_lock my_variable[1] = 100\n100","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"By using a similar pattern with the same lock and variable, but on another thread, the operations are free from data-races.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"We could have performed the operation above with the functional version of lock, in the following two ways:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> lock(my_lock) do\n my_variable[1] = 100\n end\n100\n\njulia> begin\n lock(my_lock)\n try\n my_variable[1] = 100\n finally\n unlock(my_lock)\n end\n end\n100","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"All three options are equivalent. Note how the final version requires an explicit try-block to ensure that the lock is always unlocked, whereas the first two version do this internally. One should always use the lock pattern above when changing data (such as assigning to a global or closure variable) accessed by other threads. Failing to do this could have unforeseen and serious consequences.","category":"page"},{"location":"manual/multi-threading/#man-atomic-operations","page":"Multi-Threading","title":"Atomic Operations","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Julia supports accessing and modifying values atomically, that is, in a thread-safe way to avoid race conditions. A value (which must be of a primitive type) can be wrapped as Threads.Atomic to indicate it must be accessed in this way. Here we can see an example:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> i = Threads.Atomic{Int}(0);\n\njulia> ids = zeros(4);\n\njulia> old_is = zeros(4);\n\njulia> Threads.@threads for id in 1:4\n old_is[id] = Threads.atomic_add!(i, id)\n ids[id] = id\n end\n\njulia> old_is\n4-element Vector{Float64}:\n 0.0\n 1.0\n 7.0\n 3.0\n\njulia> i[]\n 10\n\njulia> ids\n4-element Vector{Float64}:\n 1.0\n 2.0\n 3.0\n 4.0","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Had we tried to do the addition without the atomic tag, we might have gotten the wrong answer due to a race condition. An example of what would happen if we didn't avoid the race:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> using Base.Threads\n\njulia> Threads.nthreads()\n4\n\njulia> acc = Ref(0)\nBase.RefValue{Int64}(0)\n\njulia> @threads for i in 1:1000\n acc[] += 1\n end\n\njulia> acc[]\n926\n\njulia> acc = Atomic{Int64}(0)\nAtomic{Int64}(0)\n\njulia> @threads for i in 1:1000\n atomic_add!(acc, 1)\n end\n\njulia> acc[]\n1000","category":"page"},{"location":"manual/multi-threading/#man-atomics","page":"Multi-Threading","title":"Per-field atomics","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"We can also use atomics on a more granular level using the @atomic, @atomicswap, @atomicreplace macros, and @atomiconce macros.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Specific details of the memory model and other details of the design are written in the Julia Atomics Manifesto, which will later be published formally.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Any field in a struct declaration can be decorated with @atomic, and then any write must be marked with @atomic also, and must use one of the defined atomic orderings (:monotonic, :acquire, :release, :acquire_release, or :sequentially_consistent). Any read of an atomic field can also be annotated with an atomic ordering constraint, or will be done with monotonic (relaxed) ordering if unspecified.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.7\nPer-field atomics requires at least Julia 1.7.","category":"page"},{"location":"manual/multi-threading/#Side-effects-and-mutable-function-arguments","page":"Multi-Threading","title":"Side effects and mutable function arguments","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"When using multi-threading we have to be careful when using functions that are not pure as we might get a wrong answer. For instance functions that have a name ending with ! by convention modify their arguments and thus are not pure.","category":"page"},{"location":"manual/multi-threading/#@threadcall","page":"Multi-Threading","title":"@threadcall","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"External libraries, such as those called via ccall, pose a problem for Julia's task-based I/O mechanism. If a C library performs a blocking operation, that prevents the Julia scheduler from executing any other tasks until the call returns. (Exceptions are calls into custom C code that call back into Julia, which may then yield, or C code that calls jl_yield(), the C equivalent of yield.)","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The @threadcall macro provides a way to avoid stalling execution in such a scenario. It schedules a C function for execution in a separate thread. A threadpool with a default size of 4 is used for this. The size of the threadpool is controlled via environment variable UV_THREADPOOL_SIZE. While waiting for a free thread, and during function execution once a thread is available, the requesting task (on the main Julia event loop) yields to other tasks. Note that @threadcall does not return until the execution is complete. From a user point of view, it is therefore a blocking call like other Julia APIs.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"It is very important that the called function does not call back into Julia, as it will segfault.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"@threadcall may be removed/changed in future versions of Julia.","category":"page"},{"location":"manual/multi-threading/#Caveats","page":"Multi-Threading","title":"Caveats","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"At this time, most operations in the Julia runtime and standard libraries can be used in a thread-safe manner, if the user code is data-race free. However, in some areas work on stabilizing thread support is ongoing. Multi-threaded programming has many inherent difficulties, and if a program using threads exhibits unusual or undesirable behavior (e.g. crashes or mysterious results), thread interactions should typically be suspected first.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"There are a few specific limitations and warnings to be aware of when using threads in Julia:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base collection types require manual locking if used simultaneously by multiple threads where at least one thread modifies the collection (common examples include push! on arrays, or inserting items into a Dict).\nThe schedule used by @spawn is nondeterministic and should not be relied on.\nCompute-bound, non-memory-allocating tasks can prevent garbage collection from running in other threads that are allocating memory. In these cases it may be necessary to insert a manual call to GC.safepoint() to allow GC to run. This limitation will be removed in the future.\nAvoid running top-level operations, e.g. include, or eval of type, method, and module definitions in parallel.\nBe aware that finalizers registered by a library may break if threads are enabled. This may require some transitional work across the ecosystem before threading can be widely adopted with confidence. See the section on the safe use of finalizers for further details.","category":"page"},{"location":"manual/multi-threading/#man-task-migration","page":"Multi-Threading","title":"Task Migration","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"After a task starts running on a certain thread it may move to a different thread if the task yields.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Such tasks may have been started with @spawn or @threads, although the :static schedule option for @threads does freeze the threadid.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"This means that in most cases threadid() should not be treated as constant within a task, and therefore should not be used to index into a vector of buffers or stateful objects.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.7\nTask migration was introduced in Julia 1.7. Before this tasks always remained on the same thread that they were started on.","category":"page"},{"location":"manual/multi-threading/#man-finalizers","page":"Multi-Threading","title":"Safe use of Finalizers","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Because finalizers can interrupt any code, they must be very careful in how they interact with any global state. Unfortunately, the main reason that finalizers are used is to update global state (a pure function is generally rather pointless as a finalizer). This leads us to a bit of a conundrum. There are a few approaches to dealing with this problem:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"When single-threaded, code could call the internal jl_gc_enable_finalizers C function to prevent finalizers from being scheduled inside a critical region. Internally, this is used inside some functions (such as our C locks) to prevent recursion when doing certain operations (incremental package loading, codegen, etc.). The combination of a lock and this flag can be used to make finalizers safe.\nA second strategy, employed by Base in a couple places, is to explicitly delay a finalizer until it may be able to acquire its lock non-recursively. The following example demonstrates how this strategy could be applied to Distributed.finalize_ref:\nfunction finalize_ref(r::AbstractRemoteRef)\n if r.where > 0 # Check if the finalizer is already run\n if islocked(client_refs) || !trylock(client_refs)\n # delay finalizer for later if we aren't free to acquire the lock\n finalizer(finalize_ref, r)\n return nothing\n end\n try # `lock` should always be followed by `try`\n if r.where > 0 # Must check again here\n # Do actual cleanup here\n r.where = 0\n end\n finally\n unlock(client_refs)\n end\n end\n nothing\nend\nA related third strategy is to use a yield-free queue. We don't currently have a lock-free queue implemented in Base, but Base.IntrusiveLinkedListSynchronized{T} is suitable. This can frequently be a good strategy to use for code with event loops. For example, this strategy is employed by Gtk.jl to manage lifetime ref-counting. In this approach, we don't do any explicit work inside the finalizer, and instead add it to a queue to run at a safer time. In fact, Julia's task scheduler already uses this, so defining the finalizer as x -> @spawn do_cleanup(x) is one example of this approach. Note however that this doesn't control which thread do_cleanup runs on, so do_cleanup would still need to acquire a lock. That doesn't need to be true if you implement your own queue, as you can explicitly only drain that queue from your thread.","category":"page"},{"location":"manual/methods/#Methods","page":"Methods","title":"Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Recall from Functions that a function is an object that maps a tuple of arguments to a return value, or throws an exception if no appropriate value can be returned. It is common for the same conceptual function or operation to be implemented quite differently for different types of arguments: adding two integers is very different from adding two floating-point numbers, both of which are distinct from adding an integer to a floating-point number. Despite their implementation differences, these operations all fall under the general concept of \"addition\". Accordingly, in Julia, these behaviors all belong to a single object: the + function.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"To facilitate using many different implementations of the same concept smoothly, functions need not be defined all at once, but can rather be defined piecewise by providing specific behaviors for certain combinations of argument types and counts. A definition of one possible behavior for a function is called a method. Thus far, we have presented only examples of functions defined with a single method, applicable to all types of arguments. However, the signatures of method definitions can be annotated to indicate the types of arguments in addition to their number, and more than a single method definition may be provided. When a function is applied to a particular tuple of arguments, the most specific method applicable to those arguments is applied. Thus, the overall behavior of a function is a patchwork of the behaviors of its various method definitions. If the patchwork is well designed, even though the implementations of the methods may be quite different, the outward behavior of the function will appear seamless and consistent.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The choice of which method to execute when a function is applied is called dispatch. Julia allows the dispatch process to choose which of a function's methods to call based on the number of arguments given, and on the types of all of the function's arguments. This is different than traditional object-oriented languages, where dispatch occurs based only on the first argument, which often has a special argument syntax, and is sometimes implied rather than explicitly written as an argument. [1] Using all of a function's arguments to choose which method should be invoked, rather than just the first, is known as multiple dispatch. Multiple dispatch is particularly useful for mathematical code, where it makes little sense to artificially deem the operations to \"belong\" to one argument more than any of the others: does the addition operation in x + y belong to x any more than it does to y? The implementation of a mathematical operator generally depends on the types of all of its arguments. Even beyond mathematical operations, however, multiple dispatch ends up being a powerful and convenient paradigm for structuring and organizing programs.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"[1]: In C++ or Java, for example, in a method call like obj.meth(arg1,arg2), the object obj \"receives\" the method call and is implicitly passed to the method via the this keyword, rather than as an explicit method argument. When the current this object is the receiver of a method call, it can be omitted altogether, writing just meth(arg1,arg2), with this implied as the receiving object.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"note: Note\nAll the examples in this chapter assume that you are defining methods for a function in the same module. If you want to add methods to a function in another module, you have to import it or use the name qualified with module names. See the section on namespace management.","category":"page"},{"location":"manual/methods/#Defining-Methods","page":"Methods","title":"Defining Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Until now, we have, in our examples, defined only functions with a single method having unconstrained argument types. Such functions behave just like they would in traditional dynamically typed languages. Nevertheless, we have used multiple dispatch and methods almost continually without being aware of it: all of Julia's standard functions and operators, like the aforementioned + function, have many methods defining their behavior over various possible combinations of argument type and count.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When defining a function, one can optionally constrain the types of parameters it is applicable to, using the :: type-assertion operator, introduced in the section on Composite Types:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x::Float64, y::Float64) = 2x + y\nf (generic function with 1 method)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This function definition applies only to calls where x and y are both values of type Float64:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(2.0, 3.0)\n7.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Applying it to any other types of arguments will result in a MethodError:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(2.0, 3)\nERROR: MethodError: no method matching f(::Float64, ::Int64)\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(::Float64, !Matched::Float64)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> f(Float32(2.0), 3.0)\nERROR: MethodError: no method matching f(::Float32, ::Float64)\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(!Matched::Float64, ::Float64)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> f(2.0, \"3.0\")\nERROR: MethodError: no method matching f(::Float64, ::String)\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(::Float64, !Matched::Float64)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> f(\"2.0\", \"3.0\")\nERROR: MethodError: no method matching f(::String, ::String)\nThe function `f` exists, but no method is defined for this combination of argument types.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"As you can see, the arguments must be precisely of type Float64. Other numeric types, such as integers or 32-bit floating-point values, are not automatically converted to 64-bit floating-point, nor are strings parsed as numbers. Because Float64 is a concrete type and concrete types cannot be subclassed in Julia, such a definition can only be applied to arguments that are exactly of type Float64. It may often be useful, however, to write more general methods where the declared parameter types are abstract:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x::Number, y::Number) = 2x - y\nf (generic function with 2 methods)\n\njulia> f(2.0, 3)\n1.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This method definition applies to any pair of arguments that are instances of Number. They need not be of the same type, so long as they are each numeric values. The problem of handling disparate numeric types is delegated to the arithmetic operations in the expression 2x - y.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"To define a function with multiple methods, one simply defines the function multiple times, with different numbers and types of arguments. The first method definition for a function creates the function object, and subsequent method definitions add new methods to the existing function object. The most specific method definition matching the number and types of the arguments will be executed when the function is applied. Thus, the two method definitions above, taken together, define the behavior for f over all pairs of instances of the abstract type Number – but with a different behavior specific to pairs of Float64 values. If one of the arguments is a 64-bit float but the other one is not, then the f(Float64,Float64) method cannot be called and the more general f(Number,Number) method must be used:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(2.0, 3.0)\n7.0\n\njulia> f(2, 3.0)\n1.0\n\njulia> f(2.0, 3)\n1.0\n\njulia> f(2, 3)\n1","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The 2x + y definition is only used in the first case, while the 2x - y definition is used in the others. No automatic casting or conversion of function arguments is ever performed: all conversion in Julia is non-magical and completely explicit. Conversion and Promotion, however, shows how clever application of sufficiently advanced technology can be indistinguishable from magic. [Clarke61]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For non-numeric values, and for fewer or more than two arguments, the function f remains undefined, and applying it will still result in a MethodError:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(\"foo\", 3)\nERROR: MethodError: no method matching f(::String, ::Int64)\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(!Matched::Number, ::Number)\n @ Main none:1\n f(!Matched::Float64, !Matched::Float64)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> f()\nERROR: MethodError: no method matching f()\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(!Matched::Float64, !Matched::Float64)\n @ Main none:1\n f(!Matched::Number, !Matched::Number)\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"You can easily see which methods exist for a function by entering the function object itself in an interactive session:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f\nf (generic function with 2 methods)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This output tells us that f is a function object with two methods. To find out what the signatures of those methods are, use the methods function:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> methods(f)\n# 2 methods for generic function \"f\" from Main:\n [1] f(x::Float64, y::Float64)\n @ none:1\n [2] f(x::Number, y::Number)\n @ none:1","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"which shows that f has two methods, one taking two Float64 arguments and one taking arguments of type Number. It also indicates the file and line number where the methods were defined: because these methods were defined at the REPL, we get the apparent line number none:1.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In the absence of a type declaration with ::, the type of a method parameter is Any by default, meaning that it is unconstrained since all values in Julia are instances of the abstract type Any. Thus, we can define a catch-all method for f like so:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x,y) = println(\"Whoa there, Nelly.\")\nf (generic function with 3 methods)\n\njulia> methods(f)\n# 3 methods for generic function \"f\" from Main:\n [1] f(x::Float64, y::Float64)\n @ none:1\n [2] f(x::Number, y::Number)\n @ none:1\n [3] f(x, y)\n @ none:1\n\njulia> f(\"foo\", 1)\nWhoa there, Nelly.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This catch-all is less specific than any other possible method definition for a pair of parameter values, so it will only be called on pairs of arguments to which no other method definition applies.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Note that in the signature of the third method, there is no type specified for the arguments x and y. This is a shortened way of expressing f(x::Any, y::Any).","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Although it seems a simple concept, multiple dispatch on the types of values is perhaps the single most powerful and central feature of the Julia language. Core operations typically have dozens of methods:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> methods(+)\n# 180 methods for generic function \"+\":\n[1] +(x::Bool, z::Complex{Bool}) in Base at complex.jl:227\n[2] +(x::Bool, y::Bool) in Base at bool.jl:89\n[3] +(x::Bool) in Base at bool.jl:86\n[4] +(x::Bool, y::T) where T<:AbstractFloat in Base at bool.jl:96\n[5] +(x::Bool, z::Complex) in Base at complex.jl:234\n[6] +(a::Float16, b::Float16) in Base at float.jl:373\n[7] +(x::Float32, y::Float32) in Base at float.jl:375\n[8] +(x::Float64, y::Float64) in Base at float.jl:376\n[9] +(z::Complex{Bool}, x::Bool) in Base at complex.jl:228\n[10] +(z::Complex{Bool}, x::Real) in Base at complex.jl:242\n[11] +(x::Char, y::Integer) in Base at char.jl:40\n[12] +(c::BigInt, x::BigFloat) in Base.MPFR at mpfr.jl:307\n[13] +(a::BigInt, b::BigInt, c::BigInt, d::BigInt, e::BigInt) in Base.GMP at gmp.jl:392\n[14] +(a::BigInt, b::BigInt, c::BigInt, d::BigInt) in Base.GMP at gmp.jl:391\n[15] +(a::BigInt, b::BigInt, c::BigInt) in Base.GMP at gmp.jl:390\n[16] +(x::BigInt, y::BigInt) in Base.GMP at gmp.jl:361\n[17] +(x::BigInt, c::Union{UInt16, UInt32, UInt64, UInt8}) in Base.GMP at gmp.jl:398\n...\n[180] +(a, b, c, xs...) in Base at operators.jl:424","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Multiple dispatch together with the flexible parametric type system give Julia its ability to abstractly express high-level algorithms decoupled from implementation details.","category":"page"},{"location":"manual/methods/#man-method-specializations","page":"Methods","title":"Method specializations","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When you create multiple methods of the same function, this is sometimes called \"specialization.\" In this case, you're specializing the function by adding additional methods to it: each new method is a new specialization of the function. As shown above, these specializations are returned by methods.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"There's another kind of specialization that occurs without programmer intervention: Julia's compiler can automatically specialize the method for the specific argument types used. Such specializations are not listed by methods, as this doesn't create new Methods, but tools like @code_typed allow you to inspect such specializations.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For example, if you create a method","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"mysum(x::Real, y::Real) = x + y","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"you've given the function mysum one new method (possibly its only method), and that method takes any pair of Real number inputs. But if you then execute","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> mysum(1, 2)\n3\n\njulia> mysum(1.0, 2.0)\n3.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Julia will compile mysum twice, once for x::Int, y::Int and again for x::Float64, y::Float64. The point of compiling twice is performance: the methods that get called for + (which mysum uses) vary depending on the specific types of x and y, and by compiling different specializations Julia can do all the method lookup ahead of time. This allows the program to run much more quickly, since it does not have to bother with method lookup while it is running. Julia's automatic specialization allows you to write generic algorithms and expect that the compiler will generate efficient, specialized code to handle each case you need.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In cases where the number of potential specializations might be effectively unlimited, Julia may avoid this default specialization. See Be aware of when Julia avoids specializing for more information.","category":"page"},{"location":"manual/methods/#man-ambiguities","page":"Methods","title":"Method Ambiguities","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"It is possible to define a set of function methods such that there is no unique most specific method applicable to some combinations of arguments:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> g(x::Float64, y) = 2x + y\ng (generic function with 1 method)\n\njulia> g(x, y::Float64) = x + 2y\ng (generic function with 2 methods)\n\njulia> g(2.0, 3)\n7.0\n\njulia> g(2, 3.0)\n8.0\n\njulia> g(2.0, 3.0)\nERROR: MethodError: g(::Float64, ::Float64) is ambiguous.\n\nCandidates:\n g(x, y::Float64)\n @ Main none:1\n g(x::Float64, y)\n @ Main none:1\n\nPossible fix, define\n g(::Float64, ::Float64)\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Here the call g(2.0, 3.0) could be handled by either the g(::Float64, ::Any) or the g(::Any, ::Float64) method. The order in which the methods are defined does not matter and neither is more specific than the other. In such cases, Julia raises a MethodError rather than arbitrarily picking a method. You can avoid method ambiguities by specifying an appropriate method for the intersection case:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> g(x::Float64, y::Float64) = 2x + 2y\ng (generic function with 3 methods)\n\njulia> g(2.0, 3)\n7.0\n\njulia> g(2, 3.0)\n8.0\n\njulia> g(2.0, 3.0)\n10.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"It is recommended that the disambiguating method be defined first, since otherwise the ambiguity exists, if transiently, until the more specific method is defined.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In more complex cases, resolving method ambiguities involves a certain element of design; this topic is explored further below.","category":"page"},{"location":"manual/methods/#Parametric-Methods","page":"Methods","title":"Parametric Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Method definitions can optionally have type parameters qualifying the signature:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> same_type(x::T, y::T) where {T} = true\nsame_type (generic function with 1 method)\n\njulia> same_type(x,y) = false\nsame_type (generic function with 2 methods)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The first method applies whenever both arguments are of the same concrete type, regardless of what type that is, while the second method acts as a catch-all, covering all other cases. Thus, overall, this defines a boolean function that checks whether its two arguments are of the same type:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> same_type(1, 2)\ntrue\n\njulia> same_type(1, 2.0)\nfalse\n\njulia> same_type(1.0, 2.0)\ntrue\n\njulia> same_type(\"foo\", 2.0)\nfalse\n\njulia> same_type(\"foo\", \"bar\")\ntrue\n\njulia> same_type(Int32(1), Int64(2))\nfalse","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Such definitions correspond to methods whose type signatures are UnionAll types (see UnionAll Types).","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This kind of definition of function behavior by dispatch is quite common – idiomatic, even – in Julia. Method type parameters are not restricted to being used as the types of arguments: they can be used anywhere a value would be in the signature of the function or body of the function. Here's an example where the method type parameter T is used as the type parameter to the parametric type Vector{T} in the method signature:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> function myappend(v::Vector{T}, x::T) where {T}\n return [v..., x]\n end\nmyappend (generic function with 1 method)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The type parameter T in this example ensures that the added element x is a subtype of the existing eltype of the vector v. The where keyword introduces a list of those constraints after the method signature definition. This works the same for one-line definitions, as seen above, and must appear before the return type declaration, if present, as illustrated below:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> (myappend(v::Vector{T}, x::T)::Vector) where {T} = [v..., x]\nmyappend (generic function with 1 method)\n\njulia> myappend([1,2,3],4)\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> myappend([1,2,3],2.5)\nERROR: MethodError: no method matching myappend(::Vector{Int64}, ::Float64)\nThe function `myappend` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n myappend(::Vector{T}, !Matched::T) where T\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> myappend([1.0,2.0,3.0],4.0)\n4-element Vector{Float64}:\n 1.0\n 2.0\n 3.0\n 4.0\n\njulia> myappend([1.0,2.0,3.0],4)\nERROR: MethodError: no method matching myappend(::Vector{Float64}, ::Int64)\nThe function `myappend` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n myappend(::Vector{T}, !Matched::T) where T\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"If the type of the appended element does not match the element type of the vector it is appended to, a MethodError is raised. In the following example, the method's type parameter T is used as the return value:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> mytypeof(x::T) where {T} = T\nmytypeof (generic function with 1 method)\n\njulia> mytypeof(1)\nInt64\n\njulia> mytypeof(1.0)\nFloat64","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Just as you can put subtype constraints on type parameters in type declarations (see Parametric Types), you can also constrain type parameters of methods:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> same_type_numeric(x::T, y::T) where {T<:Number} = true\nsame_type_numeric (generic function with 1 method)\n\njulia> same_type_numeric(x::Number, y::Number) = false\nsame_type_numeric (generic function with 2 methods)\n\njulia> same_type_numeric(1, 2)\ntrue\n\njulia> same_type_numeric(1, 2.0)\nfalse\n\njulia> same_type_numeric(1.0, 2.0)\ntrue\n\njulia> same_type_numeric(\"foo\", 2.0)\nERROR: MethodError: no method matching same_type_numeric(::String, ::Float64)\nThe function `same_type_numeric` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n same_type_numeric(!Matched::T, ::T) where T<:Number\n @ Main none:1\n same_type_numeric(!Matched::Number, ::Number)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> same_type_numeric(\"foo\", \"bar\")\nERROR: MethodError: no method matching same_type_numeric(::String, ::String)\nThe function `same_type_numeric` exists, but no method is defined for this combination of argument types.\n\njulia> same_type_numeric(Int32(1), Int64(2))\nfalse","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The same_type_numeric function behaves much like the same_type function defined above, but is only defined for pairs of numbers.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Parametric methods allow the same syntax as where expressions used to write types (see UnionAll Types). If there is only a single parameter, the enclosing curly braces (in where {T}) can be omitted, but are often preferred for clarity. Multiple parameters can be separated with commas, e.g. where {T, S<:Real}, or written using nested where, e.g. where S<:Real where T.","category":"page"},{"location":"manual/methods/#Redefining-Methods","page":"Methods","title":"Redefining Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When redefining a method or adding new methods, it is important to realize that these changes don't take effect immediately. This is key to Julia's ability to statically infer and compile code to run fast, without the usual JIT tricks and overhead. Indeed, any new method definition won't be visible to the current runtime environment, including Tasks and Threads (and any previously defined @generated functions). Let's start with an example to see what this means:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> function tryeval()\n @eval newfun() = 1\n newfun()\n end\ntryeval (generic function with 1 method)\n\njulia> tryeval()\nERROR: MethodError: no method matching newfun()\nThe applicable method may be too new: running in world age xxxx1, while current world is xxxx2.\nClosest candidates are:\n newfun() at none:1 (method too new to be called from this world context.)\n in tryeval() at none:1\n ...\n\njulia> newfun()\n1","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In this example, observe that the new definition for newfun has been created, but can't be immediately called. The new global is immediately visible to the tryeval function, so you could write return newfun (without parentheses). But neither you, nor any of your callers, nor the functions they call, or etc. can call this new method definition!","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"But there's an exception: future calls to newfun from the REPL work as expected, being able to both see and call the new definition of newfun.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"However, future calls to tryeval will continue to see the definition of newfun as it was at the previous statement at the REPL, and thus before that call to tryeval.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"You may want to try this for yourself to see how it works.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The implementation of this behavior is a \"world age counter\". This monotonically increasing value tracks each method definition operation. This allows describing \"the set of method definitions visible to a given runtime environment\" as a single number, or \"world age\". It also allows comparing the methods available in two worlds just by comparing their ordinal value. In the example above, we see that the \"current world\" (in which the method newfun exists), is one greater than the task-local \"runtime world\" that was fixed when the execution of tryeval started.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Sometimes it is necessary to get around this (for example, if you are implementing the above REPL). Fortunately, there is an easy solution: call the function using Base.invokelatest:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> function tryeval2()\n @eval newfun2() = 2\n Base.invokelatest(newfun2)\n end\ntryeval2 (generic function with 1 method)\n\njulia> tryeval2()\n2","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Finally, let's take a look at some more complex examples where this rule comes into play. Define a function f(x), which initially has one method:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x) = \"original definition\"\nf (generic function with 1 method)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Start some other operations that use f(x):","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> g(x) = f(x)\ng (generic function with 1 method)\n\njulia> t = @async f(wait()); yield();","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Now we add some new methods to f(x):","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x::Int) = \"definition for Int\"\nf (generic function with 2 methods)\n\njulia> f(x::Type{Int}) = \"definition for Type{Int}\"\nf (generic function with 3 methods)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Compare how these results differ:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(1)\n\"definition for Int\"\n\njulia> g(1)\n\"definition for Int\"\n\njulia> fetch(schedule(t, 1))\n\"original definition\"\n\njulia> t = @async f(wait()); yield();\n\njulia> fetch(schedule(t, 1))\n\"definition for Int\"","category":"page"},{"location":"manual/methods/#Design-Patterns-with-Parametric-Methods","page":"Methods","title":"Design Patterns with Parametric Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"While complex dispatch logic is not required for performance or usability, sometimes it can be the best way to express some algorithm. Here are a few common design patterns that come up sometimes when using dispatch in this way.","category":"page"},{"location":"manual/methods/#Extracting-the-type-parameter-from-a-super-type","page":"Methods","title":"Extracting the type parameter from a super-type","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Here is a correct code template for returning the element-type T of any arbitrary subtype of AbstractArray that has well-defined element type:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"abstract type AbstractArray{T, N} end\neltype(::Type{<:AbstractArray{T}}) where {T} = T","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"using so-called triangular dispatch. Note that UnionAll types, for example eltype(AbstractArray{T} where T <: Integer), do not match the above method. The implementation of eltype in Base adds a fallback method to Any for such cases.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"One common mistake is to try and get the element-type by using introspection:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"eltype_wrong(::Type{A}) where {A<:AbstractArray} = A.parameters[1]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"However, it is not hard to construct cases where this will fail:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"struct BitVector <: AbstractArray{Bool, 1}; end","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Here we have created a type BitVector which has no parameters, but where the element-type is still fully specified, with T equal to Bool!","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Another mistake is to try to walk up the type hierarchy using supertype:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"eltype_wrong(::Type{AbstractArray{T}}) where {T} = T\neltype_wrong(::Type{AbstractArray{T, N}}) where {T, N} = T\neltype_wrong(::Type{A}) where {A<:AbstractArray} = eltype_wrong(supertype(A))","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"While this works for declared types, it fails for types without supertypes:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> eltype_wrong(Union{AbstractArray{Int}, AbstractArray{Float64}})\nERROR: MethodError: no method matching supertype(::Type{Union{AbstractArray{Float64,N} where N, AbstractArray{Int64,N} where N}})\nClosest candidates are:\n supertype(::DataType) at operators.jl:43\n supertype(::UnionAll) at operators.jl:48","category":"page"},{"location":"manual/methods/#Building-a-similar-type-with-a-different-type-parameter","page":"Methods","title":"Building a similar type with a different type parameter","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When building generic code, there is often a need for constructing a similar object with some change made to the layout of the type, also necessitating a change of the type parameters. For instance, you might have some sort of abstract array with an arbitrary element type and want to write your computation on it with a specific element type. We must implement a method for each AbstractArray{T} subtype that describes how to compute this type transform. There is no general transform of one subtype into another subtype with a different parameter.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The subtypes of AbstractArray typically implement two methods to achieve this: A method to convert the input array to a subtype of a specific AbstractArray{T, N} abstract type; and a method to make a new uninitialized array with a specific element type. Sample implementations of these can be found in Julia Base. Here is a basic example usage of them, guaranteeing that input and output are of the same type:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"input = convert(AbstractArray{Eltype}, input)\noutput = similar(input, Eltype)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"As an extension of this, in cases where the algorithm needs a copy of the input array, convert is insufficient as the return value may alias the original input. Combining similar (to make the output array) and copyto! (to fill it with the input data) is a generic way to express the requirement for a mutable copy of the input argument:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"copy_with_eltype(input, Eltype) = copyto!(similar(input, Eltype), input)","category":"page"},{"location":"manual/methods/#Iterated-dispatch","page":"Methods","title":"Iterated dispatch","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In order to dispatch a multi-level parametric argument list, often it is best to separate each level of dispatch into distinct functions. This may sound similar in approach to single-dispatch, but as we shall see below, it is still more flexible.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For example, trying to dispatch on the element-type of an array will often run into ambiguous situations. Instead, common code will dispatch first on the container type, then recurse down to a more specific method based on eltype. In most cases, the algorithms lend themselves conveniently to this hierarchical approach, while in other cases, this rigor must be resolved manually. This dispatching branching can be observed, for example, in the logic to sum two matrices:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"# First dispatch selects the map algorithm for element-wise summation.\n+(a::Matrix, b::Matrix) = map(+, a, b)\n# Then dispatch handles each element and selects the appropriate\n# common element type for the computation.\n+(a, b) = +(promote(a, b)...)\n# Once the elements have the same type, they can be added.\n# For example, via primitive operations exposed by the processor.\n+(a::Float64, b::Float64) = Core.add(a, b)","category":"page"},{"location":"manual/methods/#Trait-based-dispatch","page":"Methods","title":"Trait-based dispatch","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"A natural extension to the iterated dispatch above is to add a layer to method selection that allows to dispatch on sets of types which are independent from the sets defined by the type hierarchy. We could construct such a set by writing out a Union of the types in question, but then this set would not be extensible as Union-types cannot be altered after creation. However, such an extensible set can be programmed with a design pattern often referred to as a \"Holy-trait\".","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This pattern is implemented by defining a generic function which computes a different singleton value (or type) for each trait-set to which the function arguments may belong to. If this function is pure there is no impact on performance compared to normal dispatch.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The example in the previous section glossed over the implementation details of map and promote, which both operate in terms of these traits. When iterating over a matrix, such as in the implementation of map, one important question is what order to use to traverse the data. When AbstractArray subtypes implement the Base.IndexStyle trait, other functions such as map can dispatch on this information to pick the best algorithm (see Abstract Array Interface). This means that each subtype does not need to implement a custom version of map, since the generic definitions + trait classes will enable the system to select the fastest version. Here is a toy implementation of map illustrating the trait-based dispatch:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"map(f, a::AbstractArray, b::AbstractArray) = map(Base.IndexStyle(a, b), f, a, b)\n# generic implementation:\nmap(::Base.IndexCartesian, f, a::AbstractArray, b::AbstractArray) = ...\n# linear-indexing implementation (faster)\nmap(::Base.IndexLinear, f, a::AbstractArray, b::AbstractArray) = ...","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This trait-based approach is also present in the promote mechanism employed by the scalar +. It uses promote_type, which returns the optimal common type to compute the operation given the two types of the operands. This makes it possible to reduce the problem of implementing every function for every pair of possible type arguments, to the much smaller problem of implementing a conversion operation from each type to a common type, plus a table of preferred pair-wise promotion rules.","category":"page"},{"location":"manual/methods/#Output-type-computation","page":"Methods","title":"Output-type computation","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The discussion of trait-based promotion provides a transition into our next design pattern: computing the output element type for a matrix operation.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For implementing primitive operations, such as addition, we use the promote_type function to compute the desired output type. (As before, we saw this at work in the promote call in the call to +).","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For more complex functions on matrices, it may be necessary to compute the expected return type for a more complex sequence of operations. This is often performed by the following steps:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Write a small function op that expresses the set of operations performed by the kernel of the algorithm.\nCompute the element type R of the result matrix as promote_op(op, argument_types...), where argument_types is computed from eltype applied to each input array.\nBuild the output matrix as similar(R, dims), where dims are the desired dimensions of the output array.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For a more specific example, a generic square-matrix multiply pseudo-code might look like:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function matmul(a::AbstractMatrix, b::AbstractMatrix)\n op = (ai, bi) -> ai * bi + ai * bi\n\n ## this is insufficient because it assumes `one(eltype(a))` is constructable:\n # R = typeof(op(one(eltype(a)), one(eltype(b))))\n\n ## this fails because it assumes `a[1]` exists and is representative of all elements of the array\n # R = typeof(op(a[1], b[1]))\n\n ## this is incorrect because it assumes that `+` calls `promote_type`\n ## but this is not true for some types, such as Bool:\n # R = promote_type(ai, bi)\n\n # this is wrong, since depending on the return value\n # of type-inference is very brittle (as well as not being optimizable):\n # R = Base.return_types(op, (eltype(a), eltype(b)))\n\n ## but, finally, this works:\n R = promote_op(op, eltype(a), eltype(b))\n ## although sometimes it may give a larger type than desired\n ## it will always give a correct type\n\n output = similar(b, R, (size(a, 1), size(b, 2)))\n if size(a, 2) > 0\n for j in 1:size(b, 2)\n for i in 1:size(a, 1)\n ## here we don't use `ab = zero(R)`,\n ## since `R` might be `Any` and `zero(Any)` is not defined\n ## we also must declare `ab::R` to make the type of `ab` constant in the loop,\n ## since it is possible that typeof(a * b) != typeof(a * b + a * b) == R\n ab::R = a[i, 1] * b[1, j]\n for k in 2:size(a, 2)\n ab += a[i, k] * b[k, j]\n end\n output[i, j] = ab\n end\n end\n end\n return output\nend","category":"page"},{"location":"manual/methods/#Separate-convert-and-kernel-logic","page":"Methods","title":"Separate convert and kernel logic","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"One way to significantly cut down on compile-times and testing complexity is to isolate the logic for converting to the desired type and the computation. This lets the compiler specialize and inline the conversion logic independent from the rest of the body of the larger kernel.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This is a common pattern seen when converting from a larger class of types to the one specific argument type that is actually supported by the algorithm:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"complexfunction(arg::Int) = ...\ncomplexfunction(arg::Any) = complexfunction(convert(Int, arg))\n\nmatmul(a::T, b::T) = ...\nmatmul(a, b) = matmul(promote(a, b)...)","category":"page"},{"location":"manual/methods/#Parametrically-constrained-Varargs-methods","page":"Methods","title":"Parametrically-constrained Varargs methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Function parameters can also be used to constrain the number of arguments that may be supplied to a \"varargs\" function (Varargs Functions). The notation Vararg{T,N} is used to indicate such a constraint. For example:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> bar(a,b,x::Vararg{Any,2}) = (a,b,x)\nbar (generic function with 1 method)\n\njulia> bar(1,2,3)\nERROR: MethodError: no method matching bar(::Int64, ::Int64, ::Int64)\nThe function `bar` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n bar(::Any, ::Any, ::Any, !Matched::Any)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> bar(1,2,3,4)\n(1, 2, (3, 4))\n\njulia> bar(1,2,3,4,5)\nERROR: MethodError: no method matching bar(::Int64, ::Int64, ::Int64, ::Int64, ::Int64)\nThe function `bar` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n bar(::Any, ::Any, ::Any, ::Any)\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"More usefully, it is possible to constrain varargs methods by a parameter. For example:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function getindex(A::AbstractArray{T,N}, indices::Vararg{Number,N}) where {T,N}","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"would be called only when the number of indices matches the dimensionality of the array.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When only the type of supplied arguments needs to be constrained Vararg{T} can be equivalently written as T.... For instance f(x::Int...) = x is a shorthand for f(x::Vararg{Int}) = x.","category":"page"},{"location":"manual/methods/#Note-on-Optional-and-keyword-Arguments","page":"Methods","title":"Note on Optional and keyword Arguments","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"As mentioned briefly in Functions, optional arguments are implemented as syntax for multiple method definitions. For example, this definition:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(a=1,b=2) = a+2b","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"translates to the following three methods:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(a,b) = a+2b\nf(a) = f(a,2)\nf() = f(1,2)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This means that calling f() is equivalent to calling f(1,2). In this case the result is 5, because f(1,2) invokes the first method of f above. However, this need not always be the case. If you define a fourth method that is more specialized for integers:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(a::Int,b::Int) = a-2b","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"then the result of both f() and f(1,2) is -3. In other words, optional arguments are tied to a function, not to any specific method of that function. It depends on the types of the optional arguments which method is invoked. When optional arguments are defined in terms of a global variable, the type of the optional argument may even change at run-time.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Keyword arguments behave quite differently from ordinary positional arguments. In particular, they do not participate in method dispatch. Methods are dispatched based only on positional arguments, with keyword arguments processed after the matching method is identified.","category":"page"},{"location":"manual/methods/#Function-like-objects","page":"Methods","title":"Function-like objects","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Methods are associated with types, so it is possible to make any arbitrary Julia object \"callable\" by adding methods to its type. (Such \"callable\" objects are sometimes called \"functors.\")","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For example, you can define a type that stores the coefficients of a polynomial, but behaves like a function evaluating the polynomial:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> struct Polynomial{R}\n coeffs::Vector{R}\n end\n\njulia> function (p::Polynomial)(x)\n v = p.coeffs[end]\n for i = (length(p.coeffs)-1):-1:1\n v = v*x + p.coeffs[i]\n end\n return v\n end\n\njulia> (p::Polynomial)() = p(5)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Notice that the function is specified by type instead of by name. As with normal functions there is a terse syntax form. In the function body, p will refer to the object that was called. A Polynomial can be used as follows:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> p = Polynomial([1,10,100])\nPolynomial{Int64}([1, 10, 100])\n\njulia> p(3)\n931\n\njulia> p()\n2551","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This mechanism is also the key to how type constructors and closures (inner functions that refer to their surrounding environment) work in Julia.","category":"page"},{"location":"manual/methods/#Empty-generic-functions","page":"Methods","title":"Empty generic functions","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Occasionally it is useful to introduce a generic function without yet adding methods. This can be used to separate interface definitions from implementations. It might also be done for the purpose of documentation or code readability. The syntax for this is an empty function block without a tuple of arguments:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function emptyfunc end","category":"page"},{"location":"manual/methods/#man-method-design-ambiguities","page":"Methods","title":"Method design and the avoidance of ambiguities","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Julia's method polymorphism is one of its most powerful features, yet exploiting this power can pose design challenges. In particular, in more complex method hierarchies it is not uncommon for ambiguities to arise.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Above, it was pointed out that one can resolve ambiguities like","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x, y::Int) = 1\nf(x::Int, y) = 2","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"by defining a method","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::Int, y::Int) = 3","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This is often the right strategy; however, there are circumstances where following this advice mindlessly can be counterproductive. In particular, the more methods a generic function has, the more possibilities there are for ambiguities. When your method hierarchies get more complicated than this simple example, it can be worth your while to think carefully about alternative strategies.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Below we discuss particular challenges and some alternative ways to resolve such issues.","category":"page"},{"location":"manual/methods/#Tuple-and-NTuple-arguments","page":"Methods","title":"Tuple and NTuple arguments","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Tuple (and NTuple) arguments present special challenges. For example,","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::NTuple{N,Int}) where {N} = 1\nf(x::NTuple{N,Float64}) where {N} = 2","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"are ambiguous because of the possibility that N == 0: there are no elements to determine whether the Int or Float64 variant should be called. To resolve the ambiguity, one approach is define a method for the empty tuple:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::Tuple{}) = 3","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Alternatively, for all methods but one you can insist that there is at least one element in the tuple:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::NTuple{N,Int}) where {N} = 1 # this is the fallback\nf(x::Tuple{Float64, Vararg{Float64}}) = 2 # this requires at least one Float64","category":"page"},{"location":"manual/methods/#man-methods-orthogonalize","page":"Methods","title":"Orthogonalize your design","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When you might be tempted to dispatch on two or more arguments, consider whether a \"wrapper\" function might make for a simpler design. For example, instead of writing multiple variants:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::A, y::A) = ...\nf(x::A, y::B) = ...\nf(x::B, y::A) = ...\nf(x::B, y::B) = ...","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"you might consider defining","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::A, y::A) = ...\nf(x, y) = f(g(x), g(y))","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"where g converts the argument to type A. This is a very specific example of the more general principle of orthogonal design, in which separate concepts are assigned to separate methods. Here, g will most likely need a fallback definition","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"g(x::A) = x","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"A related strategy exploits promote to bring x and y to a common type:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::T, y::T) where {T} = ...\nf(x, y) = f(promote(x, y)...)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"One risk with this design is the possibility that if there is no suitable promotion method converting x and y to the same type, the second method will recurse on itself infinitely and trigger a stack overflow.","category":"page"},{"location":"manual/methods/#Dispatch-on-one-argument-at-a-time","page":"Methods","title":"Dispatch on one argument at a time","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"If you need to dispatch on multiple arguments, and there are many fallbacks with too many combinations to make it practical to define all possible variants, then consider introducing a \"name cascade\" where (for example) you dispatch on the first argument and then call an internal method:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::A, y) = _fA(x, y)\nf(x::B, y) = _fB(x, y)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Then the internal methods _fA and _fB can dispatch on y without concern about ambiguities with each other with respect to x.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Be aware that this strategy has at least one major disadvantage: in many cases, it is not possible for users to further customize the behavior of f by defining further specializations of your exported function f. Instead, they have to define specializations for your internal methods _fA and _fB, and this blurs the lines between exported and internal methods.","category":"page"},{"location":"manual/methods/#Abstract-containers-and-element-types","page":"Methods","title":"Abstract containers and element types","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Where possible, try to avoid defining methods that dispatch on specific element types of abstract containers. For example,","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"-(A::AbstractArray{T}, b::Date) where {T<:Date}","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"generates ambiguities for anyone who defines a method","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"-(A::MyArrayType{T}, b::T) where {T}","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The best approach is to avoid defining either of these methods: instead, rely on a generic method -(A::AbstractArray, b) and make sure this method is implemented with generic calls (like similar and -) that do the right thing for each container type and element type separately. This is just a more complex variant of the advice to orthogonalize your methods.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When this approach is not possible, it may be worth starting a discussion with other developers about resolving the ambiguity; just because one method was defined first does not necessarily mean that it can't be modified or eliminated. As a last resort, one developer can define the \"band-aid\" method","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"-(A::MyArrayType{T}, b::Date) where {T<:Date} = ...","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"that resolves the ambiguity by brute force.","category":"page"},{"location":"manual/methods/#Complex-method-\"cascades\"-with-default-arguments","page":"Methods","title":"Complex method \"cascades\" with default arguments","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"If you are defining a method \"cascade\" that supplies defaults, be careful about dropping any arguments that correspond to potential defaults. For example, suppose you're writing a digital filtering algorithm and you have a method that handles the edges of the signal by applying padding:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function myfilter(A, kernel, ::Replicate)\n Apadded = replicate_edges(A, size(kernel))\n myfilter(Apadded, kernel) # now perform the \"real\" computation\nend","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This will run afoul of a method that supplies default padding:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"myfilter(A, kernel) = myfilter(A, kernel, Replicate()) # replicate the edge by default","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Together, these two methods generate an infinite recursion with A constantly growing bigger.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The better design would be to define your call hierarchy like this:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"struct NoPad end # indicate that no padding is desired, or that it's already applied\n\nmyfilter(A, kernel) = myfilter(A, kernel, Replicate()) # default boundary conditions\n\nfunction myfilter(A, kernel, ::Replicate)\n Apadded = replicate_edges(A, size(kernel))\n myfilter(Apadded, kernel, NoPad()) # indicate the new boundary conditions\nend\n\n# other padding methods go here\n\nfunction myfilter(A, kernel, ::NoPad)\n # Here's the \"real\" implementation of the core computation\nend","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"NoPad is supplied in the same argument position as any other kind of padding, so it keeps the dispatch hierarchy well organized and with reduced likelihood of ambiguities. Moreover, it extends the \"public\" myfilter interface: a user who wants to control the padding explicitly can call the NoPad variant directly.","category":"page"},{"location":"manual/methods/#Defining-methods-in-local-scope","page":"Methods","title":"Defining methods in local scope","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"You can define methods within a local scope, for example","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> function f(x)\n g(y::Int) = y + x\n g(y) = y - x\n g\n end\nf (generic function with 1 method)\n\njulia> h = f(3);\n\njulia> h(4)\n7\n\njulia> h(4.0)\n1.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"However, you should not define local methods conditionally or subject to control flow, as in","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function f2(inc)\n if inc\n g(x) = x + 1\n else\n g(x) = x - 1\n end\nend\n\nfunction f3()\n function g end\n return g\n g() = 0\nend","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"as it is not clear what function will end up getting defined. In the future, it might be an error to define local methods in this manner.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For cases like this use anonymous functions instead:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function f2(inc)\n g = if inc\n x -> x + 1\n else\n x -> x - 1\n end\nend","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"[Clarke61]: Arthur C. Clarke, Profiles of the Future (1961): Clarke's Third Law.","category":"page"},{"location":"manual/command-line-interface/#cli","page":"Command-line Interface","title":"Command-line Interface","text":"","category":"section"},{"location":"manual/command-line-interface/#Using-arguments-inside-scripts","page":"Command-line Interface","title":"Using arguments inside scripts","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"When running a script using julia, you can pass additional arguments to your script:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia script.jl arg1 arg2...","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"These additional command-line arguments are passed in the global constant ARGS. The name of the script itself is passed in as the global PROGRAM_FILE. Note that ARGS is also set when a Julia expression is given using the -e option on the command line (see the julia help output below) but PROGRAM_FILE will be empty. For example, to just print the arguments given to a script, you could do this:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'println(PROGRAM_FILE); for x in ARGS; println(x); end' foo bar\n\nfoo\nbar","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Or you could put that code into a script and run it:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ echo 'println(PROGRAM_FILE); for x in ARGS; println(x); end' > script.jl\n$ julia script.jl foo bar\nscript.jl\nfoo\nbar","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"The -- delimiter can be used to separate command-line arguments intended for the script file from arguments intended for Julia:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia --color=yes -O -- script.jl arg1 arg2..","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"See also Scripting for more information on writing Julia scripts.","category":"page"},{"location":"manual/command-line-interface/#The-Main.main-entry-point","page":"Command-line Interface","title":"The Main.main entry point","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"As of Julia, 1.11, Base exports the macro @main. This macro expands to the symbol main, but at the conclusion of executing a script or expression, julia will attempt to execute the function Main.main(ARGS) if such a function has been defined and this behavior was opted into by using the @main macro.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"This feature is intended to aid in the unification of compiled and interactive workflows. In compiled workflows, loading the code that defines the main function may be spatially and temporally separated from the invocation. However, for interactive workflows, the behavior is equivalent to explicitly calling exit(main(ARGS)) at the end of the evaluated script or expression.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"compat: Julia 1.11\nThe special entry point Main.main was added in Julia 1.11. For compatibility with prior julia versions, add an explicit @isdefined(var\"@main\") ? (@main) : exit(main(ARGS)) at the end of your scripts.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"To see this feature in action, consider the following definition, which will execute the print function despite there being no explicit call to main:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e '(@main)(ARGS) = println(\"Hello World!\")'\nHello World!\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Only the main binding in the Main module has this behavior and only if the macro @main was used within the defining module.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"For example, using hello instead of main will not result in the hello function executing:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'hello(ARGS) = println(\"Hello World!\")'\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"and neither will a plain definition of main:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'main(ARGS) = println(\"Hello World!\")'\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"However, the opt-in need not occur at definition time:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'main(ARGS) = println(\"Hello World!\"); @main'\nHello World!\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"The main binding may be imported from a package. A hello world package defined as","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"module Hello\n\nexport main\n(@main)(ARGS) = println(\"Hello from the package!\")\n\nend","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"may be used as:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'using Hello'\nHello from the package!\n$ julia -e 'import Hello' # N.B.: Execution depends on the binding not whether the package is loaded\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"However, note that the current best practice recommendation is to not mix application and reusable library code in the same package. Helper applications may be distributed as separate packages or as scripts with separate main entry points in a package's bin folder.","category":"page"},{"location":"manual/command-line-interface/#Parallel-mode","page":"Command-line Interface","title":"Parallel mode","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Julia can be started in parallel mode with either the -p or the --machine-file options. -p n will launch an additional n worker processes, while --machine-file file will launch a worker for each line in file file. The machines defined in file must be accessible via a password-less ssh login, with Julia installed at the same location as the current host. Each machine definition takes the form [count*][user@]host[:port] [bind_addr[:port]]. user defaults to current user, port to the standard ssh port. count is the number of workers to spawn on the node, and defaults to 1. The optional bind-to bind_addr[:port] specifies the IP address and port that other workers should use to connect to this worker.","category":"page"},{"location":"manual/command-line-interface/#Startup-file","page":"Command-line Interface","title":"Startup file","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"If you have code that you want executed whenever Julia is run, you can put it in ~/.julia/config/startup.jl:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ echo 'println(\"Greetings! 你好! 안녕하세요?\")' > ~/.julia/config/startup.jl\n$ julia\nGreetings! 你好! 안녕하세요?\n\n...","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Note that although you should have a ~/.julia directory once you've run Julia for the first time, you may need to create the ~/.julia/config folder and the ~/.julia/config/startup.jl file if you use it.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"To have startup code run only in The Julia REPL (and not when julia is e.g. run on a script), use atreplinit in startup.jl:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"atreplinit() do repl\n # ...\nend","category":"page"},{"location":"manual/command-line-interface/#command-line-interface","page":"Command-line Interface","title":"Command-line switches for Julia","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"There are various ways to run Julia code and provide options, similar to those available for the perl and ruby programs:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"julia [switches] -- [programfile] [args...]","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"The following is a complete list of command-line switches available when launching julia (a '*' marks the default value, if applicable; settings marked '($)' may trigger package precompilation):","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Switch Description\n-v, --version Display version information\n-h, --help Print command-line options (this message).\n--help-hidden Uncommon options not shown by -h\n--project[={|@.}] Set as the active project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.\n-J, --sysimage Start up with the given system image file\n-H, --home Set location of julia executable\n--startup-file={yes*|no} Load JULIA_DEPOT_PATH/config/startup.jl; if JULIA_DEPOT_PATH environment variable is unset, load ~/.julia/config/startup.jl\n--handle-signals={yes*|no} Enable or disable Julia's default signal handlers\n--sysimage-native-code={yes*|no} Use native code from system image if available\n`–compiled-modules={yes*|no|existing strict}`\n`–pkgimages={yes*|no existing}`\n-e, --eval Evaluate \n-E, --print Evaluate and display the result\n-L, --load Load immediately on all processors\n-t, --threads {N|auto} Enable N threads; auto tries to infer a useful default number of threads to use but the exact behavior might change in the future. Currently, auto uses the number of CPUs assigned to this julia process based on the OS-specific affinity assignment interface, if supported (Linux and Windows). If this is not supported (macOS) or process affinity is not configured, it uses the number of CPU threads.\n--gcthreads=N[,M] Use N threads for the mark phase of GC and M (0 or 1) threads for the concurrent sweeping phase of GC. N is set to half of the number of compute threads and M is set to 0 if unspecified.\n-p, --procs {N|auto} Integer value N launches N additional local worker processes; auto launches as many workers as the number of local CPU threads (logical cores)\n--machine-file Run processes on hosts listed in \n-i Interactive mode; REPL runs and isinteractive() is true\n-q, --quiet Quiet startup: no banner, suppress REPL warnings\n--banner={yes|no|auto*} Enable or disable startup banner\n--color={yes|no|auto*} Enable or disable color text\n--history-file={yes*|no} Load or save history\n--depwarn={yes|no*|error} Enable or disable syntax and method deprecation warnings (error turns warnings into errors)\n--warn-overwrite={yes|no*} Enable or disable method overwrite warnings\n--warn-scope={yes*|no} Enable or disable warning for ambiguous top-level scope\n-C, --cpu-target Limit usage of CPU features up to ; set to help to see the available options\n-O, --optimize={0,1,2*,3} Set the optimization level (level is 3 if -O is used without a level) ($)\n--min-optlevel={0*,1,2,3} Set the lower bound on per-module optimization\n-g, --debug-info={0,1*,2} Set the level of debug info generation (level is 2 if -g is used without a level) ($)\n--inline={yes|no} Control whether inlining is permitted, including overriding @inline declarations\n--check-bounds={yes|no|auto*} Emit bounds checks always, never, or respect @inbounds declarations ($)\n--math-mode={ieee,fast} Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)\n--code-coverage[={none*|user|all}] Count executions of source lines (omitting setting is equivalent to user)\n--code-coverage=@ Count executions but only in files that fall under the given file path/directory. The @ prefix is required to select this option. A @ with no path will track the current directory.\n--code-coverage=tracefile.info Append coverage information to the LCOV tracefile (filename supports format tokens).\n--track-allocation[={none*|user|all}] Count bytes allocated by each source line (omitting setting is equivalent to \"user\")\n--track-allocation=@ Count bytes but only in files that fall under the given file path/directory. The @ prefix is required to select this option. A @ with no path will track the current directory.\n--bug-report=KIND Launch a bug report session. It can be used to start a REPL, run a script, or evaluate expressions. It first tries to use BugReporting.jl installed in current environment and falls back to the latest compatible BugReporting.jl if not. For more information, see --bug-report=help.\n--compile={yes*|no|all|min} Enable or disable JIT compiler, or request exhaustive or minimal compilation\n--output-o Generate an object file (including system image data)\n--output-ji Generate a system image data file (.ji)\n--strip-metadata Remove docstrings and source location info from system image\n--strip-ir Remove IR (intermediate representation) of compiled functions\n--output-unopt-bc Generate unoptimized LLVM bitcode (.bc)\n--output-bc Generate LLVM bitcode (.bc)\n--output-asm Generate an assembly file (.s)\n--output-incremental={yes|no*} Generate an incremental output file (rather than complete)\n--trace-compile={stderr,name} Print precompile statements for methods compiled during execution or save to a path\n--image-codegen Force generate code in imaging mode\n--heap-size-hint= Forces garbage collection if memory usage is higher than the given value. The value may be specified as a number of bytes, optionally in units of KB, MB, GB, or TB, or as a percentage of physical memory with %.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"compat: Julia 1.1\nIn Julia 1.0, the default --project=@. option did not search up from the root directory of a Git repository for the Project.toml file. From Julia 1.1 forward, it does.","category":"page"},{"location":"devdocs/sanitizers/#Sanitizer-support","page":"Sanitizer support","title":"Sanitizer support","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Sanitizers can be used in custom Julia builds to make it easier to detect certain kinds of errors in Julia's internal C/C++ code.","category":"page"},{"location":"devdocs/sanitizers/#Address-Sanitizer:-easy-build","page":"Sanitizer support","title":"Address Sanitizer: easy build","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"From a source-checkout of Julia, you should be able to build a version supporting address sanitization in Julia and LLVM as follows:","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"$ mkdir /tmp/julia\n$ contrib/asan/build.sh /tmp/julia/","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Here we've chosen /tmp/julia as a build directory, but you can choose whatever you wish. Once built, run the workload you wish to test with /tmp/julia/julia. Memory bugs will result in errors.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"If you require customization or further detail, see the documentation below.","category":"page"},{"location":"devdocs/sanitizers/#General-considerations","page":"Sanitizer support","title":"General considerations","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Using Clang's sanitizers obviously requires you to use Clang (USECLANG=1), but there's another catch: most sanitizers require a run-time library, provided by the host compiler, while the instrumented code generated by Julia's JIT relies on functionality from that library. This implies that the LLVM version of your host compiler must match that of the LLVM library used within Julia.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"An easy solution is to have a dedicated build folder for providing a matching toolchain, by building with BUILD_LLVM_CLANG=1. You can then refer to this toolchain from another build folder by specifying USECLANG=1 while overriding the CC and CXX variables.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"The sanitizers error out when they detect a shared library being opened using RTLD_DEEPBIND (ref: google/sanitizers#611). Since libblastrampoline by default uses RTLD_DEEPBIND, we need to set the environment variable LBT_USE_RTLD_DEEPBIND=0 when using a sanitizer.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"To use one of of the sanitizers set SANITIZE=1 and then the appropriate flag for the sanitizer you want to use.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"On macOS, this might need some extra flags also to work. Altogether, it might look like this, plus one or more of the SANITIZE_* flags listed below:","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"make -C deps USE_BINARYBUILDER_LLVM=0 LLVM_VER=svn stage-llvm\n\nmake -C src SANITIZE=1 USECLANG=1 \\\n CC=~+/deps/scratch/llvm-svn/build_Release/bin/clang \\\n CXX=~+/deps/scratch/llvm-svn/build_Release/bin/clang++ \\\n CPPFLAGS=\"-isysroot $(xcode-select -p)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk\" \\\n CXXFLAGS=\"-isystem $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1\"","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"(or put these into your Make.user, so you don't need to remember them every time).","category":"page"},{"location":"devdocs/sanitizers/#Address-Sanitizer-(ASAN)","page":"Sanitizer support","title":"Address Sanitizer (ASAN)","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"For detecting or debugging memory bugs, you can use Clang's address sanitizer (ASAN). By compiling with SANITIZE_ADDRESS=1 you enable ASAN for the Julia compiler and its generated code. In addition, you can specify LLVM_SANITIZE=1 to sanitize the LLVM library as well. Note that these options incur a high performance and memory cost. For example, using ASAN for Julia and LLVM makes testall1 take 8-10 times as long while using 20 times as much memory (this can be reduced to respectively a factor of 3 and 4 by using the options described below).","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"By default, Julia sets the allow_user_segv_handler=1 ASAN flag, which is required for signal delivery to work properly. You can define other options using the ASAN_OPTIONS environment flag, in which case you'll need to repeat the default option mentioned before. For example, memory usage can be reduced by specifying fast_unwind_on_malloc=0 and malloc_context_size=2, at the cost of backtrace accuracy. For now, Julia also sets detect_leaks=0, but this should be removed in the future.","category":"page"},{"location":"devdocs/sanitizers/#Example-setup","page":"Sanitizer support","title":"Example setup","text":"","category":"section"},{"location":"devdocs/sanitizers/#Step-1:-Install-toolchain","page":"Sanitizer support","title":"Step 1: Install toolchain","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Checkout a Git worktree (or create out-of-tree build directory) at $TOOLCHAIN_WORKTREE and create a config file $TOOLCHAIN_WORKTREE/Make.user with","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"USE_BINARYBUILDER_LLVM=1\nBUILD_LLVM_CLANG=1","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Run:","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"cd $TOOLCHAIN_WORKTREE\nmake -C deps install-llvm install-clang install-llvm-tools","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"to install toolchain binaries in $TOOLCHAIN_WORKTREE/usr/tools","category":"page"},{"location":"devdocs/sanitizers/#Step-2:-Build-Julia-with-ASAN","page":"Sanitizer support","title":"Step 2: Build Julia with ASAN","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Checkout a Git worktree (or create out-of-tree build directory) at $BUILD_WORKTREE and create a config file $BUILD_WORKTREE/Make.user with","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"TOOLCHAIN=$(TOOLCHAIN_WORKTREE)/usr/tools\n\n# use our new toolchain\nUSECLANG=1\noverride CC=$(TOOLCHAIN)/clang\noverride CXX=$(TOOLCHAIN)/clang++\nexport ASAN_SYMBOLIZER_PATH=$(TOOLCHAIN)/llvm-symbolizer\n\nUSE_BINARYBUILDER_LLVM=1\n\noverride SANITIZE=1\noverride SANITIZE_ADDRESS=1\n\n# make the GC use regular malloc/frees, which are hooked by ASAN\noverride WITH_GC_DEBUG_ENV=1\n\n# default to a debug build for better line number reporting\noverride JULIA_BUILD_MODE=debug\n\n# make ASAN consume less memory\nexport ASAN_OPTIONS=detect_leaks=0:fast_unwind_on_malloc=0:allow_user_segv_handler=1:malloc_context_size=2\n\nJULIA_PRECOMPILE=1\n\n# tell libblastrampoline to not use RTLD_DEEPBIND\nexport LBT_USE_RTLD_DEEPBIND=0","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Run:","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"cd $BUILD_WORKTREE\nmake debug","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"to build julia-debug with ASAN.","category":"page"},{"location":"devdocs/sanitizers/#Memory-Sanitizer-(MSAN)","page":"Sanitizer support","title":"Memory Sanitizer (MSAN)","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"For detecting use of uninitialized memory, you can use Clang's memory sanitizer (MSAN) by compiling with SANITIZE_MEMORY=1.","category":"page"},{"location":"devdocs/sanitizers/#Thread-Sanitizer-(TSAN)","page":"Sanitizer support","title":"Thread Sanitizer (TSAN)","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"For debugging data-races and other threading related issues you can use Clang's thread sanitizer (TSAN) by compiling with SANITIZE_THREAD=1.","category":"page"},{"location":"devdocs/build/arm/#ARM-(Linux)","page":"ARM (Linux)","title":"ARM (Linux)","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia fully supports ARMv8 (AArch64) processors, and supports ARMv7 and ARMv6 (AArch32) with some caveats. This file provides general guidelines for compilation, in addition to instructions for specific devices.","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"A list of known issues for ARM is available. If you encounter difficulties, please create an issue including the output from cat /proc/cpuinfo.","category":"page"},{"location":"devdocs/build/arm/#32-bit-(ARMv6,-ARMv7)","page":"ARM (Linux)","title":"32-bit (ARMv6, ARMv7)","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia has been successfully compiled on several variants of the following ARMv6 & ARMv7 devices:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"ARMv7 / Cortex A15 Samsung Chromebooks running Ubuntu Linux under Crouton;\nRaspberry Pi.\nOdroid.","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia requires at least the armv6 and vfpv2 instruction sets. It's recommended to use armv7-a. armv5 or soft float are not supported.","category":"page"},{"location":"devdocs/build/arm/#Raspberry-Pi-1-/-Raspberry-Pi-Zero","page":"ARM (Linux)","title":"Raspberry Pi 1 / Raspberry Pi Zero","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"If the type of ARM CPU used in the Raspberry Pi is not detected by LLVM, then explicitly set the CPU target by adding the following to Make.user:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"JULIA_CPU_TARGET=arm1176jzf-s","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"To complete the build, you may need to increase the swap file size. To do so, edit /etc/dphys-swapfile, changing the line:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"CONF_SWAPSIZE=100","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"to:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"CONF_SWAPSIZE=512","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"before restarting the swapfile service:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"sudo /etc/init.d/dphys-swapfile stop\nsudo /etc/init.d/dphys-swapfile start","category":"page"},{"location":"devdocs/build/arm/#Raspberry-Pi-2","page":"ARM (Linux)","title":"Raspberry Pi 2","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"The type of ARM CPU used in the Raspberry Pi 2 is not detected by LLVM. Explicitly set the CPU target by adding the following to Make.user:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"JULIA_CPU_TARGET=cortex-a7","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Depending on the exact compiler and distribution, there might be a build failure due to unsupported inline assembly. In that case, add MCPU=armv7-a to Make.user.","category":"page"},{"location":"devdocs/build/arm/#AArch64-(ARMv8)","page":"ARM (Linux)","title":"AArch64 (ARMv8)","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia has been successfully built on the following ARMv8 devices:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"nVidia Jetson TX1 & TX2;\nX-Gene 1;\nOverdrive 3000;\nCavium ThunderX on packet.net.","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Compilation on ARMv8-A requires that Make.user is configured as follows:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"MCPU=armv8-a","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Starting from Julia v1.10, JITLink is automatically enabled on this architecture for all operating systems when linking to LLVM 15 or later versions. Due to a bug in LLVM memory manager, non-trivial workloads may generate too many memory mappings that on Linux can exceed the limit of memory mappings (mmap) set in the file /proc/sys/vm/max_map_count, resulting in an error like","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"JIT session error: Cannot allocate memory","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Should this happen, ask your system administrator to increase the limit of memory mappings for example with the command","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"sysctl -w vm.max_map_count=262144","category":"page"},{"location":"devdocs/build/arm/#nVidia-Jetson-TX2","page":"ARM (Linux)","title":"nVidia Jetson TX2","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia builds and runs on the nVidia Jetson TX2 platform with minimal configuration changes.","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"After configuring Make.user as per the AArch64 instructions in this document, follow the general build instructions. The majority of the build dependencies specified in the instructions are installed by the default configuration flashed by Jetpack 3.0. The remaining tools can be installed by issuing the following command:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"sudo apt-get install gfortran wget cmake","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"A full parallel build, including LLVM, will complete in around two hours. All tests pass and CUDA functionality is available through, e.g., CUDAdrv.","category":"page"},{"location":"stdlib/Dates/#Dates","page":"Dates","title":"Dates","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"DocTestSetup = :(using Dates)","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The Dates module provides two types for working with dates: Date and DateTime, representing day and millisecond precision, respectively; both are subtypes of the abstract TimeType. The motivation for distinct types is simple: some operations are much simpler, both in terms of code and mental reasoning, when the complexities of greater precision don't have to be dealt with. For example, since the Date type only resolves to the precision of a single date (i.e. no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer time, and leap seconds are unnecessary and avoided.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Both Date and DateTime are basically immutable Int64 wrappers. The single instant field of either type is actually a UTInstant{P} type, which represents a continuously increasing machine timeline based on the UT second [1]. The DateTime type is not aware of time zones (naive, in Python parlance), analogous to a LocalDateTime in Java 8. Additional time zone functionality can be added through the TimeZones.jl package, which compiles the IANA time zone database. Both Date and DateTime are based on the ISO 8601 standard, which follows the proleptic Gregorian calendar. One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. The ISO standard, however, states that 1 BC/BCE is year zero, so 0000-12-31 is the day before 0001-01-01, and year -0001 (yes, negative one for the year) is 2 BC/BCE, year -0002 is 3 BC/BCE, etc.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"[1]: The notion of the UT second is actually quite fundamental. There are basically two different notions of time generally accepted, one based on the physical rotation of the earth (one full rotation = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! Think about it, a \"UT second\", as defined relative to the rotation of the earth, may have a different absolute length depending on the day! Anyway, the fact that Date and DateTime are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds and all their complexity can be avoided. This basis of time is formally called UT or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every day has 24 hours and leads to more natural calculations when working with calendar dates.","category":"page"},{"location":"stdlib/Dates/#Constructors","page":"Dates","title":"Constructors","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Date and DateTime types can be constructed by integer or Period types, by parsing, or through adjusters (more on those later):","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> DateTime(2013)\n2013-01-01T00:00:00\n\njulia> DateTime(2013,7)\n2013-07-01T00:00:00\n\njulia> DateTime(2013,7,1)\n2013-07-01T00:00:00\n\njulia> DateTime(2013,7,1,12)\n2013-07-01T12:00:00\n\njulia> DateTime(2013,7,1,12,30)\n2013-07-01T12:30:00\n\njulia> DateTime(2013,7,1,12,30,59)\n2013-07-01T12:30:59\n\njulia> DateTime(2013,7,1,12,30,59,1)\n2013-07-01T12:30:59.001\n\njulia> Date(2013)\n2013-01-01\n\njulia> Date(2013,7)\n2013-07-01\n\njulia> Date(2013,7,1)\n2013-07-01\n\njulia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1))\n2013-07-01\n\njulia> Date(Dates.Month(7),Dates.Year(2013))\n2013-07-01","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Date or DateTime parsing is accomplished by the use of format strings. Format strings work by the notion of defining delimited or fixed-width \"slots\" that contain a period to parse and passing the text to parse and format string to a Date or DateTime constructor, of the form Date(\"2015-01-01\",dateformat\"y-m-d\") or DateTime(\"20150101\",dateformat\"yyyymmdd\").","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent periods; so \"y-m-d\" lets the parser know that between the first and second slots in a date string like \"2014-07-16\", it should find the - character. The y, m, and d characters let the parser know which periods to parse in each slot.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As in the case of constructors above such as Date(2013), delimited DateFormats allow for missing parts of dates and times so long as the preceding parts are given. The other parts are given the usual default values. For example, Date(\"1981-03\", dateformat\"y-m-d\") returns 1981-03-01, whilst Date(\"31/12\", dateformat\"d/m/y\") gives 0001-12-31. (Note that the default year is 1 AD/CE.) An empty string, however, always throws an ArgumentError.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Fixed-width slots are specified by repeating the period character the number of times corresponding to the width with no delimiter between characters. So dateformat\"yyyymmdd\" would correspond to a date string like \"20140716\". The parser distinguishes a fixed-width slot by the absence of a delimiter, noting the transition \"yyyymm\" from one period character to the next.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Support for text-form month parsing is also supported through the u and U characters, for abbreviated and full-length month names, respectively. By default, only English month names are supported, so u corresponds to \"Jan\", \"Feb\", \"Mar\", etc. And U corresponds to \"January\", \"February\", \"March\", etc. Similar to other name=>value mapping functions dayname and monthname, custom locales can be loaded by passing in the locale=>Dict{String,Int} mapping to the MONTHTOVALUEABBR and MONTHTOVALUE dicts for abbreviated and full-name month names, respectively.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The above examples used the dateformat\"\" string macro. This macro creates a DateFormat object once when the macro is expanded and uses the same DateFormat object even if a code snippet is run multiple times.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> for i = 1:10^5\n Date(\"2015-01-01\", dateformat\"y-m-d\")\n end","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Or you can create the DateFormat object explicitly:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> df = DateFormat(\"y-m-d\");\n\njulia> dt = Date(\"2015-01-01\",df)\n2015-01-01\n\njulia> dt2 = Date(\"2015-01-02\",df)\n2015-01-02","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Alternatively, use broadcasting:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> years = [\"2015\", \"2016\"];\n\njulia> Date.(years, DateFormat(\"yyyy\"))\n2-element Vector{Date}:\n 2015-01-01\n 2016-01-01","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"For convenience, you may pass the format string directly (e.g., Date(\"2015-01-01\",\"y-m-d\")), although this form incurs performance costs if you are parsing the same format repeatedly, as it internally creates a new DateFormat object each time.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As well as via the constructors, a Date or DateTime can be constructed from strings using the parse and tryparse functions, but with an optional third argument of type DateFormat specifying the format; for example, parse(Date, \"06.23.2013\", dateformat\"m.d.y\"), or tryparse(DateTime, \"1999-12-31T23:59:59\") which uses the default format. The notable difference between the functions is that with tryparse, an error is not thrown if the string is empty or in an invalid format; instead nothing is returned.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"compat: Julia 1.9\nBefore Julia 1.9, empty strings could be passed to constructors and parse without error, returning as appropriate DateTime(1), Date(1) or Time(0). Likewise, tryparse did not return nothing.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"A full suite of parsing and formatting tests and examples is available in stdlib/Dates/test/io.jl.","category":"page"},{"location":"stdlib/Dates/#Durations/Comparisons","page":"Dates","title":"Durations/Comparisons","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Finding the length of time between two Date or DateTime is straightforward given their underlying representation as UTInstant{Day} and UTInstant{Millisecond}, respectively. The difference between Date is returned in the number of Day, and DateTime in the number of Millisecond. Similarly, comparing TimeType is a simple matter of comparing the underlying machine instants (which in turn compares the internal Int64 values).","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> dt = Date(2012,2,29)\n2012-02-29\n\njulia> dt2 = Date(2000,2,1)\n2000-02-01\n\njulia> dump(dt)\nDate\n instant: Dates.UTInstant{Day}\n periods: Day\n value: Int64 734562\n\njulia> dump(dt2)\nDate\n instant: Dates.UTInstant{Day}\n periods: Day\n value: Int64 730151\n\njulia> dt > dt2\ntrue\n\njulia> dt != dt2\ntrue\n\njulia> dt + dt2\nERROR: MethodError: no method matching +(::Date, ::Date)\n[...]\n\njulia> dt * dt2\nERROR: MethodError: no method matching *(::Date, ::Date)\n[...]\n\njulia> dt / dt2\nERROR: MethodError: no method matching /(::Date, ::Date)\n\njulia> dt - dt2\n4411 days\n\njulia> dt2 - dt\n-4411 days\n\njulia> dt = DateTime(2012,2,29)\n2012-02-29T00:00:00\n\njulia> dt2 = DateTime(2000,2,1)\n2000-02-01T00:00:00\n\njulia> dt - dt2\n381110400000 milliseconds","category":"page"},{"location":"stdlib/Dates/#Accessor-Functions","page":"Dates","title":"Accessor Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Because the Date and DateTime types are stored as single Int64 values, date parts or fields can be retrieved through accessor functions. The lowercase accessors return the field as an integer:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> t = Date(2014, 1, 31)\n2014-01-31\n\njulia> Dates.year(t)\n2014\n\njulia> Dates.month(t)\n1\n\njulia> Dates.week(t)\n5\n\njulia> Dates.day(t)\n31","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"While propercase return the same value in the corresponding Period type:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.Year(t)\n2014 years\n\njulia> Dates.Day(t)\n31 days","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Compound methods are provided because it is more efficient to access multiple fields at the same time than individually:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.yearmonth(t)\n(2014, 1)\n\njulia> Dates.monthday(t)\n(1, 31)\n\njulia> Dates.yearmonthday(t)\n(2014, 1, 31)","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"One may also access the underlying UTInstant or integer value:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> dump(t)\nDate\n instant: Dates.UTInstant{Day}\n periods: Day\n value: Int64 735264\n\njulia> t.instant\nDates.UTInstant{Day}(Day(735264))\n\njulia> Dates.value(t)\n735264","category":"page"},{"location":"stdlib/Dates/#Query-Functions","page":"Dates","title":"Query Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Query functions provide calendrical information about a TimeType. They include information about the day of the week:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> t = Date(2014, 1, 31)\n2014-01-31\n\njulia> Dates.dayofweek(t)\n5\n\njulia> Dates.dayname(t)\n\"Friday\"\n\njulia> Dates.dayofweekofmonth(t) # 5th Friday of January\n5","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Month of the year:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.monthname(t)\n\"January\"\n\njulia> Dates.daysinmonth(t)\n31","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As well as information about the TimeType's year and quarter:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.isleapyear(t)\nfalse\n\njulia> Dates.dayofyear(t)\n31\n\njulia> Dates.quarterofyear(t)\n1\n\njulia> Dates.dayofquarter(t)\n31","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The dayname and monthname methods can also take an optional locale keyword that can be used to return the name of the day or month of the year for other languages/locales. There are also versions of these functions returning the abbreviated names, namely dayabbr and monthabbr. First the mapping is loaded into the LOCALES variable:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> french_months = [\"janvier\", \"février\", \"mars\", \"avril\", \"mai\", \"juin\",\n \"juillet\", \"août\", \"septembre\", \"octobre\", \"novembre\", \"décembre\"];\n\njulia> french_months_abbrev = [\"janv\",\"févr\",\"mars\",\"avril\",\"mai\",\"juin\",\n \"juil\",\"août\",\"sept\",\"oct\",\"nov\",\"déc\"];\n\njulia> french_days = [\"lundi\",\"mardi\",\"mercredi\",\"jeudi\",\"vendredi\",\"samedi\",\"dimanche\"];\n\njulia> Dates.LOCALES[\"french\"] = Dates.DateLocale(french_months, french_months_abbrev, french_days, [\"\"]);","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The above mentioned functions can then be used to perform the queries:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.dayname(t;locale=\"french\")\n\"vendredi\"\n\njulia> Dates.monthname(t;locale=\"french\")\n\"janvier\"\n\njulia> Dates.monthabbr(t;locale=\"french\")\n\"janv\"","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Since the abbreviated versions of the days are not loaded, trying to use the function dayabbr will throw an error.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.dayabbr(t;locale=\"french\")\nERROR: BoundsError: attempt to access 1-element Vector{String} at index [5]\nStacktrace:\n[...]","category":"page"},{"location":"stdlib/Dates/#TimeType-Period-Arithmetic","page":"Dates","title":"TimeType-Period Arithmetic","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"It's good practice when using any language/date framework to be familiar with how date-period arithmetic is handled as there are some tricky issues to deal with (though much less so for day-precision types).","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The Dates module approach tries to follow the simple principle of trying to change as little as possible when doing Period arithmetic. This approach is also often known as calendrical arithmetic or what you would probably guess if someone were to ask you the same calculation in a conversation. Why all the fuss about this? Let's take a classic example: add 1 month to January 31st, 2014. What's the answer? Javascript will say March 3 (assumes 31 days). PHP says March 2 (assumes 30 days). The fact is, there is no right answer. In the Dates module, it gives the result of February 28th. How does it figure that out? Consider the classic 7-7-7 gambling game in casinos.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. Then the day number is checked if it is greater than the last valid day of the new month; if it is (as in the case above), the day number is adjusted down to the last valid day (28). What are the ramifications with this approach? Go ahead and add another month to our date, 2014-02-28 + Month(1) == 2014-03-28. What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things in different orders results in different outcomes). For example:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1)\n2014-02-28\n\njulia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1)\n2014-03-01","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"What's going on there? In the first line, we're adding 1 day to January 29th, which results in 2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. In the second example, we add 1 month first, where we get 2014-02-29, which adjusts down to 2014-02-28, and then add 1 day, which results in 2014-03-01. One design principle that helps in this case is that, in the presence of multiple Periods, the operations will be ordered by the Periods' types, not their value or positional order; this means Year will always be added first, then Month, then Week, etc. Hence the following does result in associativity and Just Works:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1)\n2014-03-01\n\njulia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1)\n2014-03-01","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Tricky? Perhaps. What is an innocent Dates user to do? The bottom line is to be aware that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected results, but otherwise, everything should work as expected. Thankfully, that's pretty much the extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the \"joys\" of dealing with daylight savings, leap seconds, etc.).","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As a bonus, all period arithmetic objects work directly with ranges:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3)\nDate(\"2014-01-29\"):Day(1):Date(\"2014-02-03\")\n\njulia> collect(dr)\n6-element Vector{Date}:\n 2014-01-29\n 2014-01-30\n 2014-01-31\n 2014-02-01\n 2014-02-02\n 2014-02-03\n\njulia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29)\nDate(\"2014-01-29\"):Month(1):Date(\"2014-07-29\")\n\njulia> collect(dr)\n7-element Vector{Date}:\n 2014-01-29\n 2014-02-28\n 2014-03-29\n 2014-04-29\n 2014-05-29\n 2014-06-29\n 2014-07-29","category":"page"},{"location":"stdlib/Dates/#Adjuster-Functions","page":"Dates","title":"Adjuster Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As convenient as date-period arithmetic is, often the kinds of calculations needed on dates take on a calendrical or temporal nature rather than a fixed number of periods. Holidays are a perfect example; most follow rules such as \"Memorial Day = Last Monday of May\", or \"Thanksgiving = 4th Thursday of November\". These kinds of temporal expressions deal with rules relative to the calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The Dates module provides the adjuster API through several convenient methods that aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal with the first and last of weeks, months, quarters, and years. They each take a single TimeType as input and return or adjust to the first or last of the desired period relative to the input.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week\n2014-07-14\n\njulia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month\n2014-07-31\n\njulia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter\n2014-09-30","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The next two higher-order methods, tonext, and toprev, generalize working with temporal expressions by taking a DateFunction as first argument, along with a starting TimeType. A DateFunction is just a function, usually anonymous, that takes a single TimeType as input and returns a Bool, true indicating a satisfied adjustment criterion. For example:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday\n\njulia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday\n2014-07-15\n\njulia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments\n2014-07-15","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"This is useful with the do-block syntax for more complex temporal expressions:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.tonext(Date(2014,7,13)) do x\n # Return true on the 4th Thursday of November (Thanksgiving)\n Dates.dayofweek(x) == Dates.Thursday &&\n Dates.dayofweekofmonth(x) == 4 &&\n Dates.month(x) == Dates.November\n end\n2014-11-27","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The Base.filter method can be used to obtain all valid dates/moments in a specified range:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"# Pittsburgh street cleaning; Every 2nd Tuesday from April to November\n# Date range from January 1st, 2014 to January 1st, 2015\njulia> dr = Dates.Date(2014):Day(1):Dates.Date(2015);\n\njulia> filter(dr) do x\n Dates.dayofweek(x) == Dates.Tue &&\n Dates.April <= Dates.month(x) <= Dates.Nov &&\n Dates.dayofweekofmonth(x) == 2\n end\n8-element Vector{Date}:\n 2014-04-08\n 2014-05-13\n 2014-06-10\n 2014-07-08\n 2014-08-12\n 2014-09-09\n 2014-10-14\n 2014-11-11","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Additional examples and tests are available in stdlib/Dates/test/adjusters.jl.","category":"page"},{"location":"stdlib/Dates/#Period-Types","page":"Dates","title":"Period Types","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. Or a year could represent 365 or 366 days in the case of a leap year. Period types are simple Int64 wrappers and are constructed by wrapping any Int64 convertible type, i.e. Year(1) or Month(3.0). Arithmetic between Period of the same type behave like integers, and limited Period-Real arithmetic is available. You can extract the underlying integer with Dates.value.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> y1 = Dates.Year(1)\n1 year\n\njulia> y2 = Dates.Year(2)\n2 years\n\njulia> y3 = Dates.Year(10)\n10 years\n\njulia> y1 + y2\n3 years\n\njulia> div(y3,y2)\n5\n\njulia> y3 - y2\n8 years\n\njulia> y3 % y2\n0 years\n\njulia> div(y3,3) # mirrors integer division\n3 years\n\njulia> Dates.value(Dates.Millisecond(10))\n10","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Representing periods or durations that are not integer multiples of the basic types can be achieved with the Dates.CompoundPeriod type. Compound periods may be constructed manually from simple Period types. Additionally, the canonicalize function can be used to break down a period into a Dates.CompoundPeriod. This is particularly useful to convert a duration, e.g., a difference of two DateTime, into a more convenient representation.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> cp = Dates.CompoundPeriod(Day(1),Minute(1))\n1 day, 1 minute\n\njulia> t1 = DateTime(2018,8,8,16,58,00)\n2018-08-08T16:58:00\n\njulia> t2 = DateTime(2021,6,23,10,00,00)\n2021-06-23T10:00:00\n\njulia> canonicalize(t2-t1) # creates a CompoundPeriod\n149 weeks, 6 days, 17 hours, 2 minutes","category":"page"},{"location":"stdlib/Dates/#Rounding","page":"Dates","title":"Rounding","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Date and DateTime values can be rounded to a specified resolution (e.g., 1 month or 15 minutes) with floor, ceil, or round:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> floor(Date(1985, 8, 16), Dates.Month)\n1985-08-01\n\njulia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15))\n2013-02-13T00:45:00\n\njulia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day)\n2016-08-07T00:00:00","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Unlike the numeric round method, which breaks ties toward the even number by default, the TimeTyperound method uses the RoundNearestTiesUp rounding mode. (It's difficult to guess what breaking ties to nearest \"even\" TimeType would entail.) Further details on the available RoundingMode s can be found in the API reference.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Rounding should generally behave as expected, but there are a few cases in which the expected behaviour is not obvious.","category":"page"},{"location":"stdlib/Dates/#Rounding-Epoch","page":"Dates","title":"Rounding Epoch","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"In many cases, the resolution specified for rounding (e.g., Dates.Second(30)) divides evenly into the next largest period (in this case, Dates.Minute(1)). But rounding behaviour in cases in which this is not true may lead to confusion. What is the expected result of rounding a DateTime to the nearest 10 hours?","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10))\n2016-07-17T12:00:00","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"That may seem confusing, given that the hour (12) is not divisible by 10. The reason that 2016-07-17T12:00:00 was chosen is that it is 17,676,660 hours after 0000-01-01T00:00:00, and 17,676,660 is divisible by 10.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As Julia Date and DateTime values are represented according to the ISO 8601 standard, 0000-01-01T00:00:00 was chosen as base (or \"rounding epoch\") from which to begin the count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly from Julia's internal representation of Date s using Rata Die notation; but since the ISO 8601 standard is most visible to the end user, 0000-01-01T00:00:00 was chosen as the rounding epoch instead of the 0000-12-31T00:00:00 used internally to minimize confusion.)","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The only exception to the use of 0000-01-01T00:00:00 as the rounding epoch is when rounding to weeks. Rounding to the nearest week will always return a Monday (the first day of the week as specified by ISO 8601). For this reason, we use 0000-01-03T00:00:00 (the first day of the first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Here is a related case in which the expected behaviour is not necessarily obvious: What happens when we round to the nearest P(2), where P is a Period type? In some cases (specifically, when P <: Dates.TimePeriod) the answer is clear:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2))\n2016-07-17T08:00:00\n\njulia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2))\n2016-07-17T08:56:00","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"This seems obvious, because two of each of these periods still divides evenly into the next larger order period. But in the case of two months (which still divides evenly into one year), the answer may be surprising:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2))\n2016-07-01T00:00:00","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Why round to the first day in July, even though it is month 7 (an odd number)? The key is that months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds (the first of which are assigned 0).","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"This means that rounding a DateTime to an even multiple of seconds, minutes, hours, or years (because the ISO 8601 specification includes a year zero) will result in a DateTime with an even value in that field, while rounding a DateTime to an even multiple of months will result in the months field having an odd value. Because both months and years may contain an irregular number of days, whether rounding to an even number of days will result in an even value in the days field is uncertain.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"See the API reference for additional information on methods exported from the Dates module.","category":"page"},{"location":"stdlib/Dates/#stdlib-dates-api","page":"Dates","title":"API reference","text":"","category":"section"},{"location":"stdlib/Dates/#Dates-and-Time-Types","page":"Dates","title":"Dates and Time Types","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.Period\nDates.CompoundPeriod\nDates.Instant\nDates.UTInstant\nDates.TimeType\nDates.DateTime\nDates.Date\nDates.Time\nDates.TimeZone\nDates.UTC","category":"page"},{"location":"stdlib/Dates/#Dates.Period","page":"Dates","title":"Dates.Period","text":"Period\nYear\nQuarter\nMonth\nWeek\nDay\nHour\nMinute\nSecond\nMillisecond\nMicrosecond\nNanosecond\n\nPeriod types represent discrete, human representations of time.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.CompoundPeriod","page":"Dates","title":"Dates.CompoundPeriod","text":"CompoundPeriod\n\nA CompoundPeriod is useful for expressing time periods that are not a fixed multiple of smaller periods. For example, \"a year and a day\" is not a fixed number of days, but can be expressed using a CompoundPeriod. In fact, a CompoundPeriod is automatically generated by addition of different period types, e.g. Year(1) + Day(1) produces a CompoundPeriod result.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.Instant","page":"Dates","title":"Dates.Instant","text":"Instant\n\nInstant types represent integer-based, machine representations of time as continuous timelines starting from an epoch.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.UTInstant","page":"Dates","title":"Dates.UTInstant","text":"UTInstant{T}\n\nThe UTInstant represents a machine timeline based on UT time (1 day = one revolution of the earth). The T is a Period parameter that indicates the resolution or precision of the instant.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.TimeType","page":"Dates","title":"Dates.TimeType","text":"TimeType\n\nTimeType types wrap Instant machine instances to provide human representations of the machine instant. Time, DateTime and Date are subtypes of TimeType.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.DateTime","page":"Dates","title":"Dates.DateTime","text":"DateTime\n\nDateTime represents a point in time according to the proleptic Gregorian calendar. The finest resolution of the time is millisecond (i.e., microseconds or nanoseconds cannot be represented by this type). The type supports fixed-point arithmetic, and thus is prone to underflowing (and overflowing). A notable consequence is rounding when adding a Microsecond or a Nanosecond:\n\njulia> dt = DateTime(2023, 8, 19, 17, 45, 32, 900)\n2023-08-19T17:45:32.900\n\njulia> dt + Millisecond(1)\n2023-08-19T17:45:32.901\n\njulia> dt + Microsecond(1000) # 1000us == 1ms\n2023-08-19T17:45:32.901\n\njulia> dt + Microsecond(999) # 999us rounded to 1000us\n2023-08-19T17:45:32.901\n\njulia> dt + Microsecond(1499) # 1499 rounded to 1000us\n2023-08-19T17:45:32.901\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.Date","page":"Dates","title":"Dates.Date","text":"Date\n\nDate wraps a UTInstant{Day} and interprets it according to the proleptic Gregorian calendar.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.Time","page":"Dates","title":"Dates.Time","text":"Time\n\nTime wraps a Nanosecond and represents a specific moment in a 24-hour day.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.TimeZone","page":"Dates","title":"Dates.TimeZone","text":"TimeZone\n\nGeographic zone generally based on longitude determining what the time is at a certain location. Some time zones observe daylight savings (eg EST -> EDT). For implementations and more support, see the TimeZones.jl package\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.UTC","page":"Dates","title":"Dates.UTC","text":"UTC\n\nUTC, or Coordinated Universal Time, is the TimeZone from which all others are measured. It is associated with the time at 0° longitude. It is not adjusted for daylight savings.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates-Functions","page":"Dates","title":"Dates Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.DateTime(::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64)\nDates.DateTime(::Dates.Period)\nDates.DateTime(::Function, ::Any...)\nDates.DateTime(::Dates.TimeType)\nDates.DateTime(::AbstractString, ::AbstractString)\nDates.format(::Dates.TimeType, ::AbstractString)\nDates.DateFormat\nDates.@dateformat_str\nDates.DateTime(::AbstractString, ::Dates.DateFormat)\nDates.Date(::Int64, ::Int64, ::Int64)\nDates.Date(::Dates.Period)\nDates.Date(::Function, ::Any, ::Any, ::Any)\nDates.Date(::Dates.TimeType)\nDates.Date(::AbstractString, ::AbstractString)\nDates.Date(::AbstractString, ::Dates.DateFormat)\nDates.Time(::Int64::Int64, ::Int64, ::Int64, ::Int64, ::Int64)\nDates.Time(::Dates.TimePeriod)\nDates.Time(::Function, ::Any...)\nDates.Time(::Dates.DateTime)\nDates.Time(::AbstractString, ::AbstractString)\nDates.Time(::AbstractString, ::Dates.DateFormat)\nDates.now()\nDates.now(::Type{Dates.UTC})\nBase.eps(::Union{Type{DateTime}, Type{Date}, Type{Time}, TimeType})","category":"page"},{"location":"stdlib/Dates/#Dates.DateTime-NTuple{7, Int64}","page":"Dates","title":"Dates.DateTime","text":"DateTime(y, [m, d, h, mi, s, ms]) -> DateTime\n\nConstruct a DateTime type by parts. Arguments must be convertible to Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{Period}","page":"Dates","title":"Dates.DateTime","text":"DateTime(periods::Period...) -> DateTime\n\nConstruct a DateTime type by Period type parts. Arguments may be in any order. DateTime parts not provided will default to the value of Dates.default(period).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{Function, Vararg{Any}}","page":"Dates","title":"Dates.DateTime","text":"DateTime(f::Function, y[, m, d, h, mi, s]; step=Day(1), limit=10000) -> DateTime\n\nCreate a DateTime through the adjuster API. The starting point will be constructed from the provided y, m, d... arguments, and will be adjusted until f::Function returns true. The step size in adjusting can be provided manually through the step keyword. limit provides a limit to the max number of iterations the adjustment API will pursue before throwing an error (in the case that f::Function is never satisfied).\n\nExamples\n\njulia> DateTime(dt -> second(dt) == 40, 2010, 10, 20, 10; step = Second(1))\n2010-10-20T10:00:40\n\njulia> DateTime(dt -> hour(dt) == 20, 2010, 10, 20, 10; step = Hour(1), limit = 5)\nERROR: ArgumentError: Adjustment limit reached: 5 iterations\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{TimeType}","page":"Dates","title":"Dates.DateTime","text":"DateTime(dt::Date) -> DateTime\n\nConvert a Date to a DateTime. The hour, minute, second, and millisecond parts of the new DateTime are assumed to be zero.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{AbstractString, AbstractString}","page":"Dates","title":"Dates.DateTime","text":"DateTime(dt::AbstractString, format::AbstractString; locale=\"english\") -> DateTime\n\nConstruct a DateTime by parsing the dt date time string following the pattern given in the format string (see DateFormat for syntax).\n\nnote: Note\nThis method creates a DateFormat object each time it is called. It is recommended that you create a DateFormat object instead and use that as the second argument to avoid performance loss when using the same format repeatedly.\n\nExamples\n\njulia> DateTime(\"2020-01-01\", \"yyyy-mm-dd\")\n2020-01-01T00:00:00\n\njulia> a = (\"2020-01-01\", \"2020-01-02\");\n\njulia> [DateTime(d, dateformat\"yyyy-mm-dd\") for d ∈ a] # preferred\n2-element Vector{DateTime}:\n 2020-01-01T00:00:00\n 2020-01-02T00:00:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.format-Tuple{TimeType, AbstractString}","page":"Dates","title":"Dates.format","text":"format(dt::TimeType, format::AbstractString; locale=\"english\") -> AbstractString\n\nConstruct a string by using a TimeType object and applying the provided format. The following character codes can be used to construct the format string:\n\nCode Examples Comment\ny 6 Numeric year with a fixed width\nY 1996 Numeric year with a minimum width\nm 1, 12 Numeric month with a minimum width\nu Jan Month name shortened to 3-chars according to the locale\nU January Full month name according to the locale keyword\nd 1, 31 Day of the month with a minimum width\nH 0, 23 Hour (24-hour clock) with a minimum width\nM 0, 59 Minute with a minimum width\nS 0, 59 Second with a minimum width\ns 000, 500 Millisecond with a minimum width of 3\ne Mon, Tue Abbreviated days of the week\nE Monday Full day of week name\n\nThe number of sequential code characters indicate the width of the code. A format of yyyy-mm specifies that the code y should have a width of four while m a width of two. Codes that yield numeric digits have an associated mode: fixed-width or minimum-width. The fixed-width mode left-pads the value with zeros when it is shorter than the specified width and truncates the value when longer. Minimum-width mode works the same as fixed-width except that it does not truncate values longer than the width.\n\nWhen creating a format you can use any non-code characters as a separator. For example to generate the string \"1996-01-15T00:00:00\" you could use format: \"yyyy-mm-ddTHH:MM:SS\". Note that if you need to use a code character as a literal you can use the escape character backslash. The string \"1996y01m\" can be produced with the format \"yyyy\\ymm\\m\".\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateFormat","page":"Dates","title":"Dates.DateFormat","text":"DateFormat(format::AbstractString, locale=\"english\") -> DateFormat\n\nConstruct a date formatting object that can be used for parsing date strings or formatting a date object as a string. The following character codes can be used to construct the format string:\n\nCode Matches Comment\nY 1996, 96 Returns year of 1996, 0096\ny 1996, 96 Same as Y on parse but discards excess digits on format\nm 1, 01 Matches 1 or 2-digit months\nu Jan Matches abbreviated months according to the locale keyword\nU January Matches full month names according to the locale keyword\nd 1, 01 Matches 1 or 2-digit days\nH 00 Matches hours (24-hour clock)\nI 00 For outputting hours with 12-hour clock\nM 00 Matches minutes\nS 00 Matches seconds\ns .500 Matches milliseconds\ne Mon, Tues Matches abbreviated days of the week\nE Monday Matches full name days of the week\np AM Matches AM/PM (case-insensitive)\nyyyymmdd 19960101 Matches fixed-width year, month, and day\n\nCharacters not listed above are normally treated as delimiters between date and time slots. For example a dt string of \"1996-01-15T00:00:00.0\" would have a format string like \"y-m-dTH:M:S.s\". If you need to use a code character as a delimiter you can escape it using backslash. The date \"1995y01m\" would have the format \"y\\ym\\m\".\n\nNote that 12:00AM corresponds 00:00 (midnight), and 12:00PM corresponds to 12:00 (noon). When parsing a time with a p specifier, any hour (either H or I) is interpreted as as a 12-hour clock, so the I code is mainly useful for output.\n\nCreating a DateFormat object is expensive. Whenever possible, create it once and use it many times or try the dateformat\"\" string macro. Using this macro creates the DateFormat object once at macro expansion time and reuses it later. There are also several pre-defined formatters, listed later.\n\nSee DateTime and format for how to use a DateFormat object to parse and write Date strings respectively.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.@dateformat_str","page":"Dates","title":"Dates.@dateformat_str","text":"dateformat\"Y-m-d H:M:S\"\n\nCreate a DateFormat object. Similar to DateFormat(\"Y-m-d H:M:S\") but creates the DateFormat object once during macro expansion.\n\nSee DateFormat for details about format specifiers.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{AbstractString, DateFormat}","page":"Dates","title":"Dates.DateTime","text":"DateTime(dt::AbstractString, df::DateFormat=ISODateTimeFormat) -> DateTime\n\nConstruct a DateTime by parsing the dt date time string following the pattern given in the DateFormat object, or dateformat\"yyyy-mm-dd\\THH:MM:SS.s\" if omitted.\n\nSimilar to DateTime(::AbstractString, ::AbstractString) but more efficient when repeatedly parsing similarly formatted date time strings with a pre-created DateFormat object.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{Int64, Int64, Int64}","page":"Dates","title":"Dates.Date","text":"Date(y, [m, d]) -> Date\n\nConstruct a Date type by parts. Arguments must be convertible to Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{Period}","page":"Dates","title":"Dates.Date","text":"Date(period::Period...) -> Date\n\nConstruct a Date type by Period type parts. Arguments may be in any order. Date parts not provided will default to the value of Dates.default(period).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{Function, Any, Any, Any}","page":"Dates","title":"Dates.Date","text":"Date(f::Function, y[, m, d]; step=Day(1), limit=10000) -> Date\n\nCreate a Date through the adjuster API. The starting point will be constructed from the provided y, m, d arguments, and will be adjusted until f::Function returns true. The step size in adjusting can be provided manually through the step keyword. limit provides a limit to the max number of iterations the adjustment API will pursue before throwing an error (given that f::Function is never satisfied).\n\nExamples\n\njulia> Date(date -> week(date) == 20, 2010, 01, 01)\n2010-05-17\n\njulia> Date(date -> year(date) == 2010, 2000, 01, 01)\n2010-01-01\n\njulia> Date(date -> month(date) == 10, 2000, 01, 01; limit = 5)\nERROR: ArgumentError: Adjustment limit reached: 5 iterations\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{TimeType}","page":"Dates","title":"Dates.Date","text":"Date(dt::DateTime) -> Date\n\nConvert a DateTime to a Date. The hour, minute, second, and millisecond parts of the DateTime are truncated, so only the year, month and day parts are used in construction.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{AbstractString, AbstractString}","page":"Dates","title":"Dates.Date","text":"Date(d::AbstractString, format::AbstractString; locale=\"english\") -> Date\n\nConstruct a Date by parsing the d date string following the pattern given in the format string (see DateFormat for syntax).\n\nnote: Note\nThis method creates a DateFormat object each time it is called. It is recommended that you create a DateFormat object instead and use that as the second argument to avoid performance loss when using the same format repeatedly.\n\nExamples\n\njulia> Date(\"2020-01-01\", \"yyyy-mm-dd\")\n2020-01-01\n\njulia> a = (\"2020-01-01\", \"2020-01-02\");\n\njulia> [Date(d, dateformat\"yyyy-mm-dd\") for d ∈ a] # preferred\n2-element Vector{Date}:\n 2020-01-01\n 2020-01-02\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{AbstractString, DateFormat}","page":"Dates","title":"Dates.Date","text":"Date(d::AbstractString, df::DateFormat=ISODateFormat) -> Date\n\nConstruct a Date by parsing the d date string following the pattern given in the DateFormat object, or dateformat\"yyyy-mm-dd\" if omitted.\n\nSimilar to Date(::AbstractString, ::AbstractString) but more efficient when repeatedly parsing similarly formatted date strings with a pre-created DateFormat object.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-NTuple{5, Int64}","page":"Dates","title":"Dates.Time","text":"Time(h, [mi, s, ms, us, ns]) -> Time\n\nConstruct a Time type by parts. Arguments must be convertible to Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{TimePeriod}","page":"Dates","title":"Dates.Time","text":"Time(period::TimePeriod...) -> Time\n\nConstruct a Time type by Period type parts. Arguments may be in any order. Time parts not provided will default to the value of Dates.default(period).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{Function, Vararg{Any}}","page":"Dates","title":"Dates.Time","text":"Time(f::Function, h, mi=0; step::Period=Second(1), limit::Int=10000)\nTime(f::Function, h, mi, s; step::Period=Millisecond(1), limit::Int=10000)\nTime(f::Function, h, mi, s, ms; step::Period=Microsecond(1), limit::Int=10000)\nTime(f::Function, h, mi, s, ms, us; step::Period=Nanosecond(1), limit::Int=10000)\n\nCreate a Time through the adjuster API. The starting point will be constructed from the provided h, mi, s, ms, us arguments, and will be adjusted until f::Function returns true. The step size in adjusting can be provided manually through the step keyword. limit provides a limit to the max number of iterations the adjustment API will pursue before throwing an error (in the case that f::Function is never satisfied). Note that the default step will adjust to allow for greater precision for the given arguments; i.e. if hour, minute, and second arguments are provided, the default step will be Millisecond(1) instead of Second(1).\n\nExamples\n\njulia> Time(t -> minute(t) == 30, 20)\n20:30:00\n\njulia> Time(t -> minute(t) == 0, 20)\n20:00:00\n\njulia> Time(t -> hour(t) == 10, 3; limit = 5)\nERROR: ArgumentError: Adjustment limit reached: 5 iterations\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{DateTime}","page":"Dates","title":"Dates.Time","text":"Time(dt::DateTime) -> Time\n\nConvert a DateTime to a Time. The hour, minute, second, and millisecond parts of the DateTime are used to create the new Time. Microsecond and nanoseconds are zero by default.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{AbstractString, AbstractString}","page":"Dates","title":"Dates.Time","text":"Time(t::AbstractString, format::AbstractString; locale=\"english\") -> Time\n\nConstruct a Time by parsing the t time string following the pattern given in the format string (see DateFormat for syntax).\n\nnote: Note\nThis method creates a DateFormat object each time it is called. It is recommended that you create a DateFormat object instead and use that as the second argument to avoid performance loss when using the same format repeatedly.\n\nExamples\n\njulia> Time(\"12:34pm\", \"HH:MMp\")\n12:34:00\n\njulia> a = (\"12:34pm\", \"2:34am\");\n\njulia> [Time(d, dateformat\"HH:MMp\") for d ∈ a] # preferred\n2-element Vector{Time}:\n 12:34:00\n 02:34:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{AbstractString, DateFormat}","page":"Dates","title":"Dates.Time","text":"Time(t::AbstractString, df::DateFormat=ISOTimeFormat) -> Time\n\nConstruct a Time by parsing the t date time string following the pattern given in the DateFormat object, or dateformat\"HH:MM:SS.s\" if omitted.\n\nSimilar to Time(::AbstractString, ::AbstractString) but more efficient when repeatedly parsing similarly formatted time strings with a pre-created DateFormat object.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.now-Tuple{}","page":"Dates","title":"Dates.now","text":"now() -> DateTime\n\nReturn a DateTime corresponding to the user's system time including the system timezone locale.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.now-Tuple{Type{UTC}}","page":"Dates","title":"Dates.now","text":"now(::Type{UTC}) -> DateTime\n\nReturn a DateTime corresponding to the user's system time as UTC/GMT. For other time zones, see the TimeZones.jl package.\n\nExamples\n\njulia> now(UTC)\n2023-01-04T10:52:24.864\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.eps-Tuple{Union{Type{Date}, Type{DateTime}, Type{Time}, TimeType}}","page":"Dates","title":"Base.eps","text":"eps(::Type{DateTime}) -> Millisecond\neps(::Type{Date}) -> Day\neps(::Type{Time}) -> Nanosecond\neps(::TimeType) -> Period\n\nReturn the smallest unit value supported by the TimeType.\n\nExamples\n\njulia> eps(DateTime)\n1 millisecond\n\njulia> eps(Date)\n1 day\n\njulia> eps(Time)\n1 nanosecond\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Accessor-Functions-2","page":"Dates","title":"Accessor Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.year\nDates.month\nDates.week\nDates.day\nDates.hour\nDates.minute\nDates.second\nDates.millisecond\nDates.microsecond\nDates.nanosecond\nDates.Year(::Dates.TimeType)\nDates.Month(::Dates.TimeType)\nDates.Week(::Dates.TimeType)\nDates.Day(::Dates.TimeType)\nDates.Hour(::DateTime)\nDates.Minute(::DateTime)\nDates.Second(::DateTime)\nDates.Millisecond(::DateTime)\nDates.Microsecond(::Dates.Time)\nDates.Nanosecond(::Dates.Time)\nDates.yearmonth\nDates.monthday\nDates.yearmonthday","category":"page"},{"location":"stdlib/Dates/#Dates.year","page":"Dates","title":"Dates.year","text":"year(dt::TimeType) -> Int64\n\nThe year of a Date or DateTime as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.month","page":"Dates","title":"Dates.month","text":"month(dt::TimeType) -> Int64\n\nThe month of a Date or DateTime as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.week","page":"Dates","title":"Dates.week","text":"week(dt::TimeType) -> Int64\n\nReturn the ISO week date of a Date or DateTime as an Int64. Note that the first week of a year is the week that contains the first Thursday of the year, which can result in dates prior to January 4th being in the last week of the previous year. For example, week(Date(2005, 1, 1)) is the 53rd week of 2004.\n\nExamples\n\njulia> week(Date(1989, 6, 22))\n25\n\njulia> week(Date(2005, 1, 1))\n53\n\njulia> week(Date(2004, 12, 31))\n53\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.day","page":"Dates","title":"Dates.day","text":"day(dt::TimeType) -> Int64\n\nThe day of month of a Date or DateTime as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.hour","page":"Dates","title":"Dates.hour","text":"hour(dt::DateTime) -> Int64\n\nThe hour of day of a DateTime as an Int64.\n\n\n\n\n\nhour(t::Time) -> Int64\n\nThe hour of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.minute","page":"Dates","title":"Dates.minute","text":"minute(dt::DateTime) -> Int64\n\nThe minute of a DateTime as an Int64.\n\n\n\n\n\nminute(t::Time) -> Int64\n\nThe minute of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.second","page":"Dates","title":"Dates.second","text":"second(dt::DateTime) -> Int64\n\nThe second of a DateTime as an Int64.\n\n\n\n\n\nsecond(t::Time) -> Int64\n\nThe second of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.millisecond","page":"Dates","title":"Dates.millisecond","text":"millisecond(dt::DateTime) -> Int64\n\nThe millisecond of a DateTime as an Int64.\n\n\n\n\n\nmillisecond(t::Time) -> Int64\n\nThe millisecond of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.microsecond","page":"Dates","title":"Dates.microsecond","text":"microsecond(t::Time) -> Int64\n\nThe microsecond of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.nanosecond","page":"Dates","title":"Dates.nanosecond","text":"nanosecond(t::Time) -> Int64\n\nThe nanosecond of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.Year-Tuple{TimeType}","page":"Dates","title":"Dates.Year","text":"Year(v)\n\nConstruct a Year object with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Month-Tuple{TimeType}","page":"Dates","title":"Dates.Month","text":"Month(v)\n\nConstruct a Month object with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Week-Tuple{TimeType}","page":"Dates","title":"Dates.Week","text":"Week(v)\n\nConstruct a Week object with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Day-Tuple{TimeType}","page":"Dates","title":"Dates.Day","text":"Day(v)\n\nConstruct a Day object with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Hour-Tuple{DateTime}","page":"Dates","title":"Dates.Hour","text":"Hour(dt::DateTime) -> Hour\n\nThe hour part of a DateTime as a Hour.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Minute-Tuple{DateTime}","page":"Dates","title":"Dates.Minute","text":"Minute(dt::DateTime) -> Minute\n\nThe minute part of a DateTime as a Minute.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Second-Tuple{DateTime}","page":"Dates","title":"Dates.Second","text":"Second(dt::DateTime) -> Second\n\nThe second part of a DateTime as a Second.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Millisecond-Tuple{DateTime}","page":"Dates","title":"Dates.Millisecond","text":"Millisecond(dt::DateTime) -> Millisecond\n\nThe millisecond part of a DateTime as a Millisecond.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Microsecond-Tuple{Time}","page":"Dates","title":"Dates.Microsecond","text":"Microsecond(dt::Time) -> Microsecond\n\nThe microsecond part of a Time as a Microsecond.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Nanosecond-Tuple{Time}","page":"Dates","title":"Dates.Nanosecond","text":"Nanosecond(dt::Time) -> Nanosecond\n\nThe nanosecond part of a Time as a Nanosecond.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.yearmonth","page":"Dates","title":"Dates.yearmonth","text":"yearmonth(dt::TimeType) -> (Int64, Int64)\n\nSimultaneously return the year and month parts of a Date or DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.monthday","page":"Dates","title":"Dates.monthday","text":"monthday(dt::TimeType) -> (Int64, Int64)\n\nSimultaneously return the month and day parts of a Date or DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.yearmonthday","page":"Dates","title":"Dates.yearmonthday","text":"yearmonthday(dt::TimeType) -> (Int64, Int64, Int64)\n\nSimultaneously return the year, month and day parts of a Date or DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Query-Functions-2","page":"Dates","title":"Query Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.dayname\nDates.dayabbr\nDates.dayofweek\nDates.dayofmonth\nDates.dayofweekofmonth\nDates.daysofweekinmonth\nDates.monthname\nDates.monthabbr\nDates.daysinmonth\nDates.isleapyear\nDates.dayofyear\nDates.daysinyear\nDates.quarterofyear\nDates.dayofquarter","category":"page"},{"location":"stdlib/Dates/#Dates.dayname","page":"Dates","title":"Dates.dayname","text":"dayname(dt::TimeType; locale=\"english\") -> String\ndayname(day::Integer; locale=\"english\") -> String\n\nReturn the full day name corresponding to the day of the week of the Date or DateTime in the given locale. Also accepts Integer.\n\nExamples\n\njulia> dayname(Date(\"2000-01-01\"))\n\"Saturday\"\n\njulia> dayname(4)\n\"Thursday\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayabbr","page":"Dates","title":"Dates.dayabbr","text":"dayabbr(dt::TimeType; locale=\"english\") -> String\ndayabbr(day::Integer; locale=\"english\") -> String\n\nReturn the abbreviated name corresponding to the day of the week of the Date or DateTime in the given locale. Also accepts Integer.\n\nExamples\n\njulia> dayabbr(Date(\"2000-01-01\"))\n\"Sat\"\n\njulia> dayabbr(3)\n\"Wed\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofweek","page":"Dates","title":"Dates.dayofweek","text":"dayofweek(dt::TimeType) -> Int64\n\nReturn the day of the week as an Int64 with 1 = Monday, 2 = Tuesday, etc..\n\nExamples\n\njulia> dayofweek(Date(\"2000-01-01\"))\n6\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofmonth","page":"Dates","title":"Dates.dayofmonth","text":"dayofmonth(dt::TimeType) -> Int64\n\nThe day of month of a Date or DateTime as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofweekofmonth","page":"Dates","title":"Dates.dayofweekofmonth","text":"dayofweekofmonth(dt::TimeType) -> Int\n\nFor the day of week of dt, return which number it is in dt's month. So if the day of the week of dt is Monday, then 1 = First Monday of the month, 2 = Second Monday of the month, etc. In the range 1:5.\n\nExamples\n\njulia> dayofweekofmonth(Date(\"2000-02-01\"))\n1\n\njulia> dayofweekofmonth(Date(\"2000-02-08\"))\n2\n\njulia> dayofweekofmonth(Date(\"2000-02-15\"))\n3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.daysofweekinmonth","page":"Dates","title":"Dates.daysofweekinmonth","text":"daysofweekinmonth(dt::TimeType) -> Int\n\nFor the day of week of dt, return the total number of that day of the week in dt's month. Returns 4 or 5. Useful in temporal expressions for specifying the last day of a week in a month by including dayofweekofmonth(dt) == daysofweekinmonth(dt) in the adjuster function.\n\nExamples\n\njulia> daysofweekinmonth(Date(\"2005-01-01\"))\n5\n\njulia> daysofweekinmonth(Date(\"2005-01-04\"))\n4\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.monthname","page":"Dates","title":"Dates.monthname","text":"monthname(dt::TimeType; locale=\"english\") -> String\nmonthname(month::Integer, locale=\"english\") -> String\n\nReturn the full name of the month of the Date or DateTime or Integer in the given locale.\n\nExamples\n\njulia> monthname(Date(\"2005-01-04\"))\n\"January\"\n\njulia> monthname(2)\n\"February\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.monthabbr","page":"Dates","title":"Dates.monthabbr","text":"monthabbr(dt::TimeType; locale=\"english\") -> String\nmonthabbr(month::Integer, locale=\"english\") -> String\n\nReturn the abbreviated month name of the Date or DateTime or Integer in the given locale.\n\nExamples\n\njulia> monthabbr(Date(\"2005-01-04\"))\n\"Jan\"\n\njulia> monthabbr(2)\n\"Feb\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.daysinmonth","page":"Dates","title":"Dates.daysinmonth","text":"daysinmonth(dt::TimeType) -> Int\n\nReturn the number of days in the month of dt. Value will be 28, 29, 30, or 31.\n\nExamples\n\njulia> daysinmonth(Date(\"2000-01\"))\n31\n\njulia> daysinmonth(Date(\"2001-02\"))\n28\n\njulia> daysinmonth(Date(\"2000-02\"))\n29\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.isleapyear","page":"Dates","title":"Dates.isleapyear","text":"isleapyear(dt::TimeType) -> Bool\n\nReturn true if the year of dt is a leap year.\n\nExamples\n\njulia> isleapyear(Date(\"2004\"))\ntrue\n\njulia> isleapyear(Date(\"2005\"))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofyear","page":"Dates","title":"Dates.dayofyear","text":"dayofyear(dt::TimeType) -> Int\n\nReturn the day of the year for dt with January 1st being day 1.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.daysinyear","page":"Dates","title":"Dates.daysinyear","text":"daysinyear(dt::TimeType) -> Int\n\nReturn 366 if the year of dt is a leap year, otherwise return 365.\n\nExamples\n\njulia> daysinyear(1999)\n365\n\njulia> daysinyear(2000)\n366\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.quarterofyear","page":"Dates","title":"Dates.quarterofyear","text":"quarterofyear(dt::TimeType) -> Int\n\nReturn the quarter that dt resides in. Range of value is 1:4.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofquarter","page":"Dates","title":"Dates.dayofquarter","text":"dayofquarter(dt::TimeType) -> Int\n\nReturn the day of the current quarter of dt. Range of value is 1:92.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Adjuster-Functions-2","page":"Dates","title":"Adjuster Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Base.trunc(::Dates.TimeType, ::Type{Dates.Period})\nDates.firstdayofweek\nDates.lastdayofweek\nDates.firstdayofmonth\nDates.lastdayofmonth\nDates.firstdayofyear\nDates.lastdayofyear\nDates.firstdayofquarter\nDates.lastdayofquarter\nDates.tonext(::Dates.TimeType, ::Int)\nDates.toprev(::Dates.TimeType, ::Int)\nDates.tofirst\nDates.tolast\nDates.tonext(::Function, ::Dates.TimeType)\nDates.toprev(::Function, ::Dates.TimeType)","category":"page"},{"location":"stdlib/Dates/#Base.trunc-Tuple{TimeType, Type{Period}}","page":"Dates","title":"Base.trunc","text":"trunc(dt::TimeType, ::Type{Period}) -> TimeType\n\nTruncates the value of dt according to the provided Period type.\n\nExamples\n\njulia> trunc(DateTime(\"1996-01-01T12:30:00\"), Day)\n1996-01-01T00:00:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.firstdayofweek","page":"Dates","title":"Dates.firstdayofweek","text":"firstdayofweek(dt::TimeType) -> TimeType\n\nAdjusts dt to the Monday of its week.\n\nExamples\n\njulia> firstdayofweek(DateTime(\"1996-01-05T12:30:00\"))\n1996-01-01T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.lastdayofweek","page":"Dates","title":"Dates.lastdayofweek","text":"lastdayofweek(dt::TimeType) -> TimeType\n\nAdjusts dt to the Sunday of its week.\n\nExamples\n\njulia> lastdayofweek(DateTime(\"1996-01-05T12:30:00\"))\n1996-01-07T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.firstdayofmonth","page":"Dates","title":"Dates.firstdayofmonth","text":"firstdayofmonth(dt::TimeType) -> TimeType\n\nAdjusts dt to the first day of its month.\n\nExamples\n\njulia> firstdayofmonth(DateTime(\"1996-05-20\"))\n1996-05-01T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.lastdayofmonth","page":"Dates","title":"Dates.lastdayofmonth","text":"lastdayofmonth(dt::TimeType) -> TimeType\n\nAdjusts dt to the last day of its month.\n\nExamples\n\njulia> lastdayofmonth(DateTime(\"1996-05-20\"))\n1996-05-31T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.firstdayofyear","page":"Dates","title":"Dates.firstdayofyear","text":"firstdayofyear(dt::TimeType) -> TimeType\n\nAdjusts dt to the first day of its year.\n\nExamples\n\njulia> firstdayofyear(DateTime(\"1996-05-20\"))\n1996-01-01T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.lastdayofyear","page":"Dates","title":"Dates.lastdayofyear","text":"lastdayofyear(dt::TimeType) -> TimeType\n\nAdjusts dt to the last day of its year.\n\nExamples\n\njulia> lastdayofyear(DateTime(\"1996-05-20\"))\n1996-12-31T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.firstdayofquarter","page":"Dates","title":"Dates.firstdayofquarter","text":"firstdayofquarter(dt::TimeType) -> TimeType\n\nAdjusts dt to the first day of its quarter.\n\nExamples\n\njulia> firstdayofquarter(DateTime(\"1996-05-20\"))\n1996-04-01T00:00:00\n\njulia> firstdayofquarter(DateTime(\"1996-08-20\"))\n1996-07-01T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.lastdayofquarter","page":"Dates","title":"Dates.lastdayofquarter","text":"lastdayofquarter(dt::TimeType) -> TimeType\n\nAdjusts dt to the last day of its quarter.\n\nExamples\n\njulia> lastdayofquarter(DateTime(\"1996-05-20\"))\n1996-06-30T00:00:00\n\njulia> lastdayofquarter(DateTime(\"1996-08-20\"))\n1996-09-30T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.tonext-Tuple{TimeType, Int64}","page":"Dates","title":"Dates.tonext","text":"tonext(dt::TimeType, dow::Int; same::Bool=false) -> TimeType\n\nAdjusts dt to the next day of week corresponding to dow with 1 = Monday, 2 = Tuesday, etc. Setting same=true allows the current dt to be considered as the next dow, allowing for no adjustment to occur.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.toprev-Tuple{TimeType, Int64}","page":"Dates","title":"Dates.toprev","text":"toprev(dt::TimeType, dow::Int; same::Bool=false) -> TimeType\n\nAdjusts dt to the previous day of week corresponding to dow with 1 = Monday, 2 = Tuesday, etc. Setting same=true allows the current dt to be considered as the previous dow, allowing for no adjustment to occur.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.tofirst","page":"Dates","title":"Dates.tofirst","text":"tofirst(dt::TimeType, dow::Int; of=Month) -> TimeType\n\nAdjusts dt to the first dow of its month. Alternatively, of=Year will adjust to the first dow of the year.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.tolast","page":"Dates","title":"Dates.tolast","text":"tolast(dt::TimeType, dow::Int; of=Month) -> TimeType\n\nAdjusts dt to the last dow of its month. Alternatively, of=Year will adjust to the last dow of the year.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.tonext-Tuple{Function, TimeType}","page":"Dates","title":"Dates.tonext","text":"tonext(func::Function, dt::TimeType; step=Day(1), limit=10000, same=false) -> TimeType\n\nAdjusts dt by iterating at most limit iterations by step increments until func returns true. func must take a single TimeType argument and return a Bool. same allows dt to be considered in satisfying func.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.toprev-Tuple{Function, TimeType}","page":"Dates","title":"Dates.toprev","text":"toprev(func::Function, dt::TimeType; step=Day(-1), limit=10000, same=false) -> TimeType\n\nAdjusts dt by iterating at most limit iterations by step increments until func returns true. func must take a single TimeType argument and return a Bool. same allows dt to be considered in satisfying func.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Periods","page":"Dates","title":"Periods","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.Period(::Any)\nDates.CompoundPeriod(::Vector{<:Dates.Period})\nDates.canonicalize\nDates.value\nDates.default\nDates.periods","category":"page"},{"location":"stdlib/Dates/#Dates.Period-Tuple{Any}","page":"Dates","title":"Dates.Period","text":"Year(v)\nQuarter(v)\nMonth(v)\nWeek(v)\nDay(v)\nHour(v)\nMinute(v)\nSecond(v)\nMillisecond(v)\nMicrosecond(v)\nNanosecond(v)\n\nConstruct a Period type with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.CompoundPeriod-Tuple{Vector{<:Period}}","page":"Dates","title":"Dates.CompoundPeriod","text":"CompoundPeriod(periods) -> CompoundPeriod\n\nConstruct a CompoundPeriod from a Vector of Periods. All Periods of the same type will be added together.\n\nExamples\n\njulia> Dates.CompoundPeriod(Dates.Hour(12), Dates.Hour(13))\n25 hours\n\njulia> Dates.CompoundPeriod(Dates.Hour(-1), Dates.Minute(1))\n-1 hour, 1 minute\n\njulia> Dates.CompoundPeriod(Dates.Month(1), Dates.Week(-2))\n1 month, -2 weeks\n\njulia> Dates.CompoundPeriod(Dates.Minute(50000))\n50000 minutes\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.canonicalize","page":"Dates","title":"Dates.canonicalize","text":"canonicalize(::CompoundPeriod) -> CompoundPeriod\n\nReduces the CompoundPeriod into its canonical form by applying the following rules:\n\nAny Period large enough be partially representable by a coarser Period will be broken into multiple Periods (eg. Hour(30) becomes Day(1) + Hour(6))\nPeriods with opposite signs will be combined when possible (eg. Hour(1) - Day(1) becomes -Hour(23))\n\nExamples\n\njulia> canonicalize(Dates.CompoundPeriod(Dates.Hour(12), Dates.Hour(13)))\n1 day, 1 hour\n\njulia> canonicalize(Dates.CompoundPeriod(Dates.Hour(-1), Dates.Minute(1)))\n-59 minutes\n\njulia> canonicalize(Dates.CompoundPeriod(Dates.Month(1), Dates.Week(-2)))\n1 month, -2 weeks\n\njulia> canonicalize(Dates.CompoundPeriod(Dates.Minute(50000)))\n4 weeks, 6 days, 17 hours, 20 minutes\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.value","page":"Dates","title":"Dates.value","text":"Dates.value(x::Period) -> Int64\n\nFor a given period, return the value associated with that period. For example, value(Millisecond(10)) returns 10 as an integer.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.default","page":"Dates","title":"Dates.default","text":"default(p::Period) -> Period\n\nReturn a sensible \"default\" value for the input Period by returning T(1) for Year, Month, and Day, and T(0) for Hour, Minute, Second, and Millisecond.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.periods","page":"Dates","title":"Dates.periods","text":"Dates.periods(::CompoundPeriod) -> Vector{Period}\n\nReturn the Vector of Periods that comprise the given CompoundPeriod.\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Rounding-Functions","page":"Dates","title":"Rounding Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Date and DateTime values can be rounded to a specified resolution (e.g., 1 month or 15 minutes) with floor, ceil, or round.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Base.floor(::Dates.TimeType, ::Dates.Period)\nBase.ceil(::Dates.TimeType, ::Dates.Period)\nBase.round(::Dates.TimeType, ::Dates.Period, ::RoundingMode{:NearestTiesUp})","category":"page"},{"location":"stdlib/Dates/#Base.floor-Tuple{TimeType, Period}","page":"Dates","title":"Base.floor","text":"floor(dt::TimeType, p::Period) -> TimeType\n\nReturn the nearest Date or DateTime less than or equal to dt at resolution p.\n\nFor convenience, p may be a type instead of a value: floor(dt, Dates.Hour) is a shortcut for floor(dt, Dates.Hour(1)).\n\njulia> floor(Date(1985, 8, 16), Month)\n1985-08-01\n\njulia> floor(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))\n2013-02-13T00:30:00\n\njulia> floor(DateTime(2016, 8, 6, 12, 0, 0), Day)\n2016-08-06T00:00:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.ceil-Tuple{TimeType, Period}","page":"Dates","title":"Base.ceil","text":"ceil(dt::TimeType, p::Period) -> TimeType\n\nReturn the nearest Date or DateTime greater than or equal to dt at resolution p.\n\nFor convenience, p may be a type instead of a value: ceil(dt, Dates.Hour) is a shortcut for ceil(dt, Dates.Hour(1)).\n\njulia> ceil(Date(1985, 8, 16), Month)\n1985-09-01\n\njulia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))\n2013-02-13T00:45:00\n\njulia> ceil(DateTime(2016, 8, 6, 12, 0, 0), Day)\n2016-08-07T00:00:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.round-Tuple{TimeType, Period, RoundingMode{:NearestTiesUp}}","page":"Dates","title":"Base.round","text":"round(dt::TimeType, p::Period, [r::RoundingMode]) -> TimeType\n\nReturn the Date or DateTime nearest to dt at resolution p. By default (RoundNearestTiesUp), ties (e.g., rounding 9:30 to the nearest hour) will be rounded up.\n\nFor convenience, p may be a type instead of a value: round(dt, Dates.Hour) is a shortcut for round(dt, Dates.Hour(1)).\n\njulia> round(Date(1985, 8, 16), Month)\n1985-08-01\n\njulia> round(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))\n2013-02-13T00:30:00\n\njulia> round(DateTime(2016, 8, 6, 12, 0, 0), Day)\n2016-08-07T00:00:00\n\nValid rounding modes for round(::TimeType, ::Period, ::RoundingMode) are RoundNearestTiesUp (default), RoundDown (floor), and RoundUp (ceil).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Most Period values can also be rounded to a specified resolution:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Base.floor(::Dates.ConvertiblePeriod, ::T) where T <: Dates.ConvertiblePeriod\nBase.ceil(::Dates.ConvertiblePeriod, ::Dates.ConvertiblePeriod)\nBase.round(::Dates.ConvertiblePeriod, ::Dates.ConvertiblePeriod, ::RoundingMode{:NearestTiesUp})","category":"page"},{"location":"stdlib/Dates/#Base.floor-Union{Tuple{T}, Tuple{Union{Day, Week, TimePeriod}, T}} where T<:Union{Day, Week, TimePeriod}","page":"Dates","title":"Base.floor","text":"floor(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> T\n\nRound x down to the nearest multiple of precision. If x and precision are different subtypes of Period, the return value will have the same type as precision.\n\nFor convenience, precision may be a type instead of a value: floor(x, Dates.Hour) is a shortcut for floor(x, Dates.Hour(1)).\n\njulia> floor(Day(16), Week)\n2 weeks\n\njulia> floor(Minute(44), Minute(15))\n30 minutes\n\njulia> floor(Hour(36), Day)\n1 day\n\nRounding to a precision of Months or Years is not supported, as these Periods are of inconsistent length.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.ceil-Tuple{Union{Day, Week, TimePeriod}, Union{Day, Week, TimePeriod}}","page":"Dates","title":"Base.ceil","text":"ceil(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> T\n\nRound x up to the nearest multiple of precision. If x and precision are different subtypes of Period, the return value will have the same type as precision.\n\nFor convenience, precision may be a type instead of a value: ceil(x, Dates.Hour) is a shortcut for ceil(x, Dates.Hour(1)).\n\njulia> ceil(Day(16), Week)\n3 weeks\n\njulia> ceil(Minute(44), Minute(15))\n45 minutes\n\njulia> ceil(Hour(36), Day)\n2 days\n\nRounding to a precision of Months or Years is not supported, as these Periods are of inconsistent length.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.round-Tuple{Union{Day, Week, TimePeriod}, Union{Day, Week, TimePeriod}, RoundingMode{:NearestTiesUp}}","page":"Dates","title":"Base.round","text":"round(x::Period, precision::T, [r::RoundingMode]) where T <: Union{TimePeriod, Week, Day} -> T\n\nRound x to the nearest multiple of precision. If x and precision are different subtypes of Period, the return value will have the same type as precision. By default (RoundNearestTiesUp), ties (e.g., rounding 90 minutes to the nearest hour) will be rounded up.\n\nFor convenience, precision may be a type instead of a value: round(x, Dates.Hour) is a shortcut for round(x, Dates.Hour(1)).\n\njulia> round(Day(16), Week)\n2 weeks\n\njulia> round(Minute(44), Minute(15))\n45 minutes\n\njulia> round(Hour(36), Day)\n2 days\n\nValid rounding modes for round(::Period, ::T, ::RoundingMode) are RoundNearestTiesUp (default), RoundDown (floor), and RoundUp (ceil).\n\nRounding to a precision of Months or Years is not supported, as these Periods are of inconsistent length.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The following functions are not exported:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.floorceil\nDates.epochdays2date\nDates.epochms2datetime\nDates.date2epochdays\nDates.datetime2epochms","category":"page"},{"location":"stdlib/Dates/#Dates.floorceil","page":"Dates","title":"Dates.floorceil","text":"floorceil(dt::TimeType, p::Period) -> (TimeType, TimeType)\n\nSimultaneously return the floor and ceil of a Date or DateTime at resolution p. More efficient than calling both floor and ceil individually.\n\n\n\n\n\nfloorceil(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> (T, T)\n\nSimultaneously return the floor and ceil of Period at resolution p. More efficient than calling both floor and ceil individually.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.epochdays2date","page":"Dates","title":"Dates.epochdays2date","text":"epochdays2date(days) -> Date\n\nTake the number of days since the rounding epoch (0000-01-01T00:00:00) and return the corresponding Date.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.epochms2datetime","page":"Dates","title":"Dates.epochms2datetime","text":"epochms2datetime(milliseconds) -> DateTime\n\nTake the number of milliseconds since the rounding epoch (0000-01-01T00:00:00) and return the corresponding DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.date2epochdays","page":"Dates","title":"Dates.date2epochdays","text":"date2epochdays(dt::Date) -> Int64\n\nTake the given Date and return the number of days since the rounding epoch (0000-01-01T00:00:00) as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.datetime2epochms","page":"Dates","title":"Dates.datetime2epochms","text":"datetime2epochms(dt::DateTime) -> Int64\n\nTake the given DateTime and return the number of milliseconds since the rounding epoch (0000-01-01T00:00:00) as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Conversion-Functions","page":"Dates","title":"Conversion Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.today\nDates.unix2datetime\nDates.datetime2unix\nDates.julian2datetime\nDates.datetime2julian\nDates.rata2datetime\nDates.datetime2rata","category":"page"},{"location":"stdlib/Dates/#Dates.today","page":"Dates","title":"Dates.today","text":"today() -> Date\n\nReturn the date portion of now().\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.unix2datetime","page":"Dates","title":"Dates.unix2datetime","text":"unix2datetime(x) -> DateTime\n\nTake the number of seconds since unix epoch 1970-01-01T00:00:00 and convert to the corresponding DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.datetime2unix","page":"Dates","title":"Dates.datetime2unix","text":"datetime2unix(dt::DateTime) -> Float64\n\nTake the given DateTime and return the number of seconds since the unix epoch 1970-01-01T00:00:00 as a Float64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.julian2datetime","page":"Dates","title":"Dates.julian2datetime","text":"julian2datetime(julian_days) -> DateTime\n\nTake the number of Julian calendar days since epoch -4713-11-24T12:00:00 and return the corresponding DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.datetime2julian","page":"Dates","title":"Dates.datetime2julian","text":"datetime2julian(dt::DateTime) -> Float64\n\nTake the given DateTime and return the number of Julian calendar days since the julian epoch -4713-11-24T12:00:00 as a Float64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.rata2datetime","page":"Dates","title":"Dates.rata2datetime","text":"rata2datetime(days) -> DateTime\n\nTake the number of Rata Die days since epoch 0000-12-31T00:00:00 and return the corresponding DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.datetime2rata","page":"Dates","title":"Dates.datetime2rata","text":"datetime2rata(dt::TimeType) -> Int64\n\nReturn the number of Rata Die days since epoch from the given Date or DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Constants","page":"Dates","title":"Constants","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Days of the Week:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Variable Abbr. Value (Int)\nMonday Mon 1\nTuesday Tue 2\nWednesday Wed 3\nThursday Thu 4\nFriday Fri 5\nSaturday Sat 6\nSunday Sun 7","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Months of the Year:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Variable Abbr. Value (Int)\nJanuary Jan 1\nFebruary Feb 2\nMarch Mar 3\nApril Apr 4\nMay May 5\nJune Jun 6\nJuly Jul 7\nAugust Aug 8\nSeptember Sep 9\nOctober Oct 10\nNovember Nov 11\nDecember Dec 12","category":"page"},{"location":"stdlib/Dates/#Common-Date-Formatters","page":"Dates","title":"Common Date Formatters","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"ISODateTimeFormat\nISODateFormat\nISOTimeFormat\nRFC1123Format","category":"page"},{"location":"stdlib/Dates/#Dates.ISODateTimeFormat","page":"Dates","title":"Dates.ISODateTimeFormat","text":"Dates.ISODateTimeFormat\n\nDescribes the ISO8601 formatting for a date and time. This is the default value for Dates.format of a DateTime.\n\nExamples\n\njulia> Dates.format(DateTime(2018, 8, 8, 12, 0, 43, 1), ISODateTimeFormat)\n\"2018-08-08T12:00:43.001\"\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Dates/#Dates.ISODateFormat","page":"Dates","title":"Dates.ISODateFormat","text":"Dates.ISODateFormat\n\nDescribes the ISO8601 formatting for a date. This is the default value for Dates.format of a Date.\n\nExamples\n\njulia> Dates.format(Date(2018, 8, 8), ISODateFormat)\n\"2018-08-08\"\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Dates/#Dates.ISOTimeFormat","page":"Dates","title":"Dates.ISOTimeFormat","text":"Dates.ISOTimeFormat\n\nDescribes the ISO8601 formatting for a time. This is the default value for Dates.format of a Time.\n\nExamples\n\njulia> Dates.format(Time(12, 0, 43, 1), ISOTimeFormat)\n\"12:00:43.001\"\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Dates/#Dates.RFC1123Format","page":"Dates","title":"Dates.RFC1123Format","text":"Dates.RFC1123Format\n\nDescribes the RFC1123 formatting for a date and time.\n\nExamples\n\njulia> Dates.format(DateTime(2018, 8, 8, 12, 0, 43, 1), RFC1123Format)\n\"Wed, 08 Aug 2018 12:00:43\"\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/TOML/docs/src/index.md\"","category":"page"},{"location":"stdlib/TOML/#TOML","page":"TOML","title":"TOML","text":"","category":"section"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"TOML.jl is a Julia standard library for parsing and writing TOML v1.0 files.","category":"page"},{"location":"stdlib/TOML/#Parsing-TOML-data","page":"TOML","title":"Parsing TOML data","text":"","category":"section"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> data = \"\"\"\n [database]\n server = \"192.168.1.1\"\n ports = [ 8001, 8001, 8002 ]\n \"\"\";\n\njulia> TOML.parse(data)\nDict{String, Any} with 1 entry:\n \"database\" => Dict{String, Any}(\"server\"=>\"192.168.1.1\", \"ports\"=>[8001, 8001…","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"To parse a file, use TOML.parsefile. If the file has a syntax error, an exception is thrown:","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> TOML.parse(\"\"\"\n value = 0.0.0\n \"\"\")\nERROR: TOML Parser error:\nnone:1:16 error: failed to parse value\n value = 0.0.0\n ^\n[...]","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"There are other versions of the parse functions (TOML.tryparse and TOML.tryparsefile) that instead of throwing exceptions on parser error returns a TOML.ParserError with information:","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> err = TOML.tryparse(\"\"\"\n value = 0.0.0\n \"\"\");\n\njulia> err.type\nErrGenericValueError::ErrorType = 14\n\njulia> err.line\n1\n\njulia> err.column\n16","category":"page"},{"location":"stdlib/TOML/#Exporting-data-to-TOML-file","page":"TOML","title":"Exporting data to TOML file","text":"","category":"section"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"The TOML.print function is used to print (or serialize) data into TOML format.","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> data = Dict(\n \"names\" => [\"Julia\", \"Julio\"],\n \"age\" => [10, 20],\n );\n\njulia> TOML.print(data)\nnames = [\"Julia\", \"Julio\"]\nage = [10, 20]\n\njulia> fname = tempname();\n\njulia> open(fname, \"w\") do io\n TOML.print(io, data)\n end\n\njulia> TOML.parsefile(fname)\nDict{String, Any} with 2 entries:\n \"names\" => [\"Julia\", \"Julio\"]\n \"age\" => [10, 20]","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"Keys can be sorted according to some value","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> TOML.print(Dict(\n \"abc\" => 1,\n \"ab\" => 2,\n \"abcd\" => 3,\n ); sorted=true, by=length)\nab = 2\nabc = 1\nabcd = 3","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"For custom structs, pass a function that converts the struct to a supported type","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> struct MyStruct\n a::Int\n b::String\n end\n\njulia> TOML.print(Dict(\"foo\" => MyStruct(5, \"bar\"))) do x\n x isa MyStruct && return [x.a, x.b]\n error(\"unhandled type $(typeof(x))\")\n end\nfoo = [5, \"bar\"]","category":"page"},{"location":"stdlib/TOML/#References","page":"TOML","title":"References","text":"","category":"section"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"TOML.parse\nTOML.parsefile\nTOML.tryparse\nTOML.tryparsefile\nTOML.print\nTOML.Parser\nTOML.ParserError","category":"page"},{"location":"stdlib/TOML/#TOML.parse","page":"TOML","title":"TOML.parse","text":"parse(x::Union{AbstractString, IO})\nparse(p::Parser, x::Union{AbstractString, IO})\n\nParse the string or stream x, and return the resulting table (dictionary). Throw a ParserError upon failure.\n\nSee also TOML.tryparse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.parsefile","page":"TOML","title":"TOML.parsefile","text":"parsefile(f::AbstractString)\nparsefile(p::Parser, f::AbstractString)\n\nParse file f and return the resulting table (dictionary). Throw a ParserError upon failure.\n\nSee also TOML.tryparsefile.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.tryparse","page":"TOML","title":"TOML.tryparse","text":"tryparse(x::Union{AbstractString, IO})\ntryparse(p::Parser, x::Union{AbstractString, IO})\n\nParse the string or stream x, and return the resulting table (dictionary). Return a ParserError upon failure.\n\nSee also TOML.parse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.tryparsefile","page":"TOML","title":"TOML.tryparsefile","text":"tryparsefile(f::AbstractString)\ntryparsefile(p::Parser, f::AbstractString)\n\nParse file f and return the resulting table (dictionary). Return a ParserError upon failure.\n\nSee also TOML.parsefile.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.print","page":"TOML","title":"TOML.print","text":"print([to_toml::Function], io::IO [=stdout], data::AbstractDict; sorted=false, by=identity, inline_tables::IdSet{<:AbstractDict})\n\nWrite data as TOML syntax to the stream io. If the keyword argument sorted is set to true, sort tables according to the function given by the keyword argument by. If the keyword argument inline_tables is given, it should be a set of tables that should be printed \"inline\".\n\nThe following data types are supported: AbstractDict, AbstractVector, AbstractString, Integer, AbstractFloat, Bool, Dates.DateTime, Dates.Time, Dates.Date. Note that the integers and floats need to be convertible to Float64 and Int64 respectively. For other data types, pass the function to_toml that takes the data types and returns a value of a supported type.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.Parser","page":"TOML","title":"TOML.Parser","text":"Parser()\n\nConstructor for a TOML Parser. Note that in most cases one does not need to explicitly create a Parser but instead one directly use use TOML.parsefile or TOML.parse. Using an explicit parser will however reuse some internal data structures which can be beneficial for performance if a larger number of small files are parsed.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/TOML/#TOML.ParserError","page":"TOML","title":"TOML.ParserError","text":"ParserError\n\nType that is returned from tryparse and tryparsefile when parsing fails. It contains (among others) the following fields:\n\npos, the position in the string when the error happened\ntable, the result that so far was successfully parsed\ntype, an error type, different for different types of errors\n\n\n\n\n\n","category":"type"},{"location":"manual/asynchronous-programming/#man-asynchronous","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"When a program needs to interact with the outside world, for example communicating with another machine over the internet, operations in the program may need to happen in an unpredictable order. Say your program needs to download a file. We would like to initiate the download operation, perform other operations while we wait for it to complete, and then resume the code that needs the downloaded file when it is available. This sort of scenario falls in the domain of asynchronous programming, sometimes also referred to as concurrent programming (since, conceptually, multiple things are happening at once).","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"To address these scenarios, Julia provides Tasks (also known by several other names, such as symmetric coroutines, lightweight threads, cooperative multitasking, or one-shot continuations). When a piece of computing work (in practice, executing a particular function) is designated as a Task, it becomes possible to interrupt it by switching to another Task. The original Task can later be resumed, at which point it will pick up right where it left off. At first, this may seem similar to a function call. However there are two key differences. First, switching tasks does not use any space, so any number of task switches can occur without consuming the call stack. Second, switching among tasks can occur in any order, unlike function calls, where the called function must finish executing before control returns to the calling function.","category":"page"},{"location":"manual/asynchronous-programming/#Basic-Task-operations","page":"Asynchronous Programming","title":"Basic Task operations","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"You can think of a Task as a handle to a unit of computational work to be performed. It has a create-start-run-finish lifecycle. Tasks are created by calling the Task constructor on a 0-argument function to run, or using the @task macro:","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> t = @task begin; sleep(5); println(\"done\"); end\nTask (runnable) @0x00007f13a40c0eb0","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"@task x is equivalent to Task(()->x).","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"This task will wait for five seconds, and then print done. However, it has not started running yet. We can run it whenever we're ready by calling schedule:","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> schedule(t);","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"If you try this in the REPL, you will see that schedule returns immediately. That is because it simply adds t to an internal queue of tasks to run. Then, the REPL will print the next prompt and wait for more input. Waiting for keyboard input provides an opportunity for other tasks to run, so at that point t will start. t calls sleep, which sets a timer and stops execution. If other tasks have been scheduled, they could run then. After five seconds, the timer fires and restarts t, and you will see done printed. t is then finished.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"The wait function blocks the calling task until some other task finishes. So for example if you type","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> schedule(t); wait(t)","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"instead of only calling schedule, you will see a five second pause before the next input prompt appears. That is because the REPL is waiting for t to finish before proceeding.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"It is common to want to create a task and schedule it right away, so the macro @async is provided for that purpose –- @async x is equivalent to schedule(@task x).","category":"page"},{"location":"manual/asynchronous-programming/#Communicating-with-Channels","page":"Asynchronous Programming","title":"Communicating with Channels","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"In some problems, the various pieces of required work are not naturally related by function calls; there is no obvious \"caller\" or \"callee\" among the jobs that need to be done. An example is the producer-consumer problem, where one complex procedure is generating values and another complex procedure is consuming them. The consumer cannot simply call a producer function to get a value, because the producer may have more values to generate and so might not yet be ready to return. With tasks, the producer and consumer can both run as long as they need to, passing values back and forth as necessary.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Julia provides a Channel mechanism for solving this problem. A Channel is a waitable first-in first-out queue which can have multiple tasks reading from and writing to it.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Let's define a producer task, which produces values via the put! call. To consume values, we need to schedule the producer to run in a new task. A special Channel constructor which accepts a 1-arg function as an argument can be used to run a task bound to a channel. We can then take! values repeatedly from the channel object:","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> function producer(c::Channel)\n put!(c, \"start\")\n for n=1:4\n put!(c, 2n)\n end\n put!(c, \"stop\")\n end;\n\njulia> chnl = Channel(producer);\n\njulia> take!(chnl)\n\"start\"\n\njulia> take!(chnl)\n2\n\njulia> take!(chnl)\n4\n\njulia> take!(chnl)\n6\n\njulia> take!(chnl)\n8\n\njulia> take!(chnl)\n\"stop\"","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"One way to think of this behavior is that producer was able to return multiple times. Between calls to put!, the producer's execution is suspended and the consumer has control.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"The returned Channel can be used as an iterable object in a for loop, in which case the loop variable takes on all the produced values. The loop is terminated when the channel is closed.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> for x in Channel(producer)\n println(x)\n end\nstart\n2\n4\n6\n8\nstop","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Note that we did not have to explicitly close the channel in the producer. This is because the act of binding a Channel to a Task associates the open lifetime of a channel with that of the bound task. The channel object is closed automatically when the task terminates. Multiple channels can be bound to a task, and vice-versa.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"While the Task constructor expects a 0-argument function, the Channel method that creates a task-bound channel expects a function that accepts a single argument of type Channel. A common pattern is for the producer to be parameterized, in which case a partial function application is needed to create a 0 or 1 argument anonymous function.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"For Task objects this can be done either directly or by use of a convenience macro:","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"function mytask(myarg)\n ...\nend\n\ntaskHdl = Task(() -> mytask(7))\n# or, equivalently\ntaskHdl = @task mytask(7)","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"To orchestrate more advanced work distribution patterns, bind and schedule can be used in conjunction with Task and Channel constructors to explicitly link a set of channels with a set of producer/consumer tasks.","category":"page"},{"location":"manual/asynchronous-programming/#More-on-Channels","page":"Asynchronous Programming","title":"More on Channels","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"A channel can be visualized as a pipe, i.e., it has a write end and a read end :","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Multiple writers in different tasks can write to the same channel concurrently via put! calls.\nMultiple readers in different tasks can read data concurrently via take! calls.\nAs an example:\n# Given Channels c1 and c2,\nc1 = Channel(32)\nc2 = Channel(32)\n\n# and a function `foo` which reads items from c1, processes the item read\n# and writes a result to c2,\nfunction foo()\n while true\n data = take!(c1)\n [...] # process data\n put!(c2, result) # write out result\n end\nend\n\n# we can schedule `n` instances of `foo` to be active concurrently.\nfor _ in 1:n\n errormonitor(@async foo())\nend\nChannels are created via the Channel{T}(sz) constructor. The channel will only hold objects of type T. If the type is not specified, the channel can hold objects of any type. sz refers to the maximum number of elements that can be held in the channel at any time. For example, Channel(32) creates a channel that can hold a maximum of 32 objects of any type. A Channel{MyType}(64) can hold up to 64 objects of MyType at any time.\nIf a Channel is empty, readers (on a take! call) will block until data is available (see isempty).\nIf a Channel is full, writers (on a put! call) will block until space becomes available (see isfull).\nisready tests for the presence of any object in the channel, while wait waits for an object to become available.\nNote that if another task is currently waiting to put! an object into a channel, a channel can have more items available than its capacity.\nA Channel is in an open state initially. This means that it can be read from and written to freely via take! and put! calls. close closes a Channel. On a closed Channel, put! will fail. For example:\njulia> c = Channel(2);\n\njulia> put!(c, 1) # `put!` on an open channel succeeds\n1\n\njulia> close(c);\n\njulia> put!(c, 2) # `put!` on a closed channel throws an exception.\nERROR: InvalidStateException: Channel is closed.\nStacktrace:\n[...]\ntake! and fetch (which retrieves but does not remove the value) on a closed channel successfully return any existing values until it is emptied. Continuing the above example:\njulia> fetch(c) # Any number of `fetch` calls succeed.\n1\n\njulia> fetch(c)\n1\n\njulia> take!(c) # The first `take!` removes the value.\n1\n\njulia> take!(c) # No more data available on a closed channel.\nERROR: InvalidStateException: Channel is closed.\nStacktrace:\n[...]","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Consider a simple example using channels for inter-task communication. We start 4 tasks to process data from a single jobs channel. Jobs, identified by an id (job_id), are written to the channel. Each task in this simulation reads a job_id, waits for a random amount of time and writes back a tuple of job_id and the simulated time to the results channel. Finally all the results are printed out.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> const jobs = Channel{Int}(32);\n\njulia> const results = Channel{Tuple}(32);\n\njulia> function do_work()\n for job_id in jobs\n exec_time = rand()\n sleep(exec_time) # simulates elapsed time doing actual work\n # typically performed externally.\n put!(results, (job_id, exec_time))\n end\n end;\n\njulia> function make_jobs(n)\n for i in 1:n\n put!(jobs, i)\n end\n end;\n\njulia> n = 12;\n\njulia> errormonitor(@async make_jobs(n)); # feed the jobs channel with \"n\" jobs\n\njulia> for i in 1:4 # start 4 tasks to process requests in parallel\n errormonitor(@async do_work())\n end\n\njulia> @elapsed while n > 0 # print out results\n job_id, exec_time = take!(results)\n println(\"$job_id finished in $(round(exec_time; digits=2)) seconds\")\n global n = n - 1\n end\n4 finished in 0.22 seconds\n3 finished in 0.45 seconds\n1 finished in 0.5 seconds\n7 finished in 0.14 seconds\n2 finished in 0.78 seconds\n5 finished in 0.9 seconds\n9 finished in 0.36 seconds\n6 finished in 0.87 seconds\n8 finished in 0.79 seconds\n10 finished in 0.64 seconds\n12 finished in 0.5 seconds\n11 finished in 0.97 seconds\n0.029772311","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Instead of errormonitor(t), a more robust solution may be to use bind(results, t), as that will not only log any unexpected failures, but also force the associated resources to close and propagate the exception everywhere.","category":"page"},{"location":"manual/asynchronous-programming/#More-task-operations","page":"Asynchronous Programming","title":"More task operations","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Task operations are built on a low-level primitive called yieldto. yieldto(task, value) suspends the current task, switches to the specified task, and causes that task's last yieldto call to return the specified value. Notice that yieldto is the only operation required to use task-style control flow; instead of calling and returning we are always just switching to a different task. This is why this feature is also called \"symmetric coroutines\"; each task is switched to and from using the same mechanism.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"yieldto is powerful, but most uses of tasks do not invoke it directly. Consider why this might be. If you switch away from the current task, you will probably want to switch back to it at some point, but knowing when to switch back, and knowing which task has the responsibility of switching back, can require considerable coordination. For example, put! and take! are blocking operations, which, when used in the context of channels maintain state to remember who the consumers are. Not needing to manually keep track of the consuming task is what makes put! easier to use than the low-level yieldto.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"In addition to yieldto, a few other basic functions are needed to use tasks effectively.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"current_task gets a reference to the currently-running task.\nistaskdone queries whether a task has exited.\nistaskstarted queries whether a task has run yet.\ntask_local_storage manipulates a key-value store specific to the current task.","category":"page"},{"location":"manual/asynchronous-programming/#Tasks-and-events","page":"Asynchronous Programming","title":"Tasks and events","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Most task switches occur as a result of waiting for events such as I/O requests, and are performed by a scheduler included in Julia Base. The scheduler maintains a queue of runnable tasks, and executes an event loop that restarts tasks based on external events such as message arrival.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"The basic function for waiting for an event is wait. Several objects implement wait; for example, given a Process object, wait will wait for it to exit. wait is often implicit; for example, a wait can happen inside a call to read to wait for data to be available.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"In all of these cases, wait ultimately operates on a Condition object, which is in charge of queueing and restarting tasks. When a task calls wait on a Condition, the task is marked as non-runnable, added to the condition's queue, and switches to the scheduler. The scheduler will then pick another task to run, or block waiting for external events. If all goes well, eventually an event handler will call notify on the condition, which causes tasks waiting for that condition to become runnable again.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"A task created explicitly by calling Task is initially not known to the scheduler. This allows you to manage tasks manually using yieldto if you wish. However, when such a task waits for an event, it still gets restarted automatically when the event happens, as you would expect.","category":"page"},{"location":"base/strings/#lib-strings","page":"Strings","title":"Strings","text":"","category":"section"},{"location":"base/strings/","page":"Strings","title":"Strings","text":"Core.AbstractString\nCore.AbstractChar\nCore.Char\nBase.codepoint\nBase.length(::AbstractString)\nBase.sizeof(::AbstractString)\nBase.:*(::Union{AbstractChar, AbstractString}, ::Union{AbstractChar, AbstractString}...)\nBase.:^(::Union{AbstractString, AbstractChar}, ::Integer)\nBase.string\nBase.repeat(::AbstractString, ::Integer)\nBase.repeat(::AbstractChar, ::Integer)\nBase.repr(::Any)\nCore.String(::AbstractString)\nBase.SubString\nBase.LazyString\nBase.@lazy_str\nBase.AnnotatedString\nBase.AnnotatedChar\nBase.annotatedstring\nBase.annotations\nBase.annotate!\nBase.transcode\nBase.unsafe_string\nBase.ncodeunits(::AbstractString)\nBase.codeunit\nBase.codeunits\nBase.ascii\nBase.Regex\nBase.@r_str\nBase.SubstitutionString\nBase.@s_str\nBase.@raw_str\nBase.@b_str\nBase.Docs.@html_str\nBase.Docs.@text_str\nBase.isvalid(::Any)\nBase.isvalid(::Any, ::Any)\nBase.isvalid(::AbstractString, ::Integer)\nBase.match\nBase.eachmatch\nBase.RegexMatch\nBase.keys(::RegexMatch)\nBase.isless(::AbstractString, ::AbstractString)\nBase.:(==)(::AbstractString, ::AbstractString)\nBase.cmp(::AbstractString, ::AbstractString)\nBase.lpad\nBase.rpad\nBase.findfirst(::AbstractString, ::AbstractString)\nBase.findnext(::AbstractString, ::AbstractString, ::Integer)\nBase.findnext(::AbstractChar, ::AbstractString, ::Integer)\nBase.findlast(::AbstractString, ::AbstractString)\nBase.findlast(::AbstractChar, ::AbstractString)\nBase.findprev(::AbstractString, ::AbstractString, ::Integer)\nBase.occursin\nBase.reverse(::Union{String,SubString{String}})\nBase.replace(::IO, s::AbstractString, ::Pair...)\nBase.eachsplit\nBase.eachrsplit\nBase.split\nBase.rsplit\nBase.strip\nBase.lstrip\nBase.rstrip\nBase.startswith\nBase.endswith\nBase.contains\nBase.first(::AbstractString, ::Integer)\nBase.last(::AbstractString, ::Integer)\nBase.uppercase\nBase.lowercase\nBase.titlecase\nBase.uppercasefirst\nBase.lowercasefirst\nBase.join\nBase.chop\nBase.chopprefix\nBase.chopsuffix\nBase.chomp\nBase.thisind\nBase.nextind(::AbstractString, ::Integer, ::Integer)\nBase.prevind(::AbstractString, ::Integer, ::Integer)\nBase.textwidth\nBase.isascii\nBase.iscntrl\nBase.isdigit\nBase.isletter\nBase.islowercase\nBase.isnumeric\nBase.isprint\nBase.ispunct\nBase.isspace\nBase.isuppercase\nBase.isxdigit\nBase.escape_string\nBase.escape_raw_string\nBase.unescape_string","category":"page"},{"location":"base/strings/#Core.AbstractString","page":"Strings","title":"Core.AbstractString","text":"The AbstractString type is the supertype of all string implementations in Julia. Strings are encodings of sequences of Unicode code points as represented by the AbstractChar type. Julia makes a few assumptions about strings:\n\nStrings are encoded in terms of fixed-size \"code units\"\nCode units can be extracted with codeunit(s, i)\nThe first code unit has index 1\nThe last code unit has index ncodeunits(s)\nAny index i such that 1 ≤ i ≤ ncodeunits(s) is in bounds\nString indexing is done in terms of these code units:\nCharacters are extracted by s[i] with a valid string index i\nEach AbstractChar in a string is encoded by one or more code units\nOnly the index of the first code unit of an AbstractChar is a valid index\nThe encoding of an AbstractChar is independent of what precedes or follows it\nString encodings are self-synchronizing – i.e. isvalid(s, i) is O(1)\n\nSome string functions that extract code units, characters or substrings from strings error if you pass them out-of-bounds or invalid string indices. This includes codeunit(s, i) and s[i]. Functions that do string index arithmetic take a more relaxed approach to indexing and give you the closest valid string index when in-bounds, or when out-of-bounds, behave as if there were an infinite number of characters padding each side of the string. Usually these imaginary padding characters have code unit length 1 but string types may choose different \"imaginary\" character sizes as makes sense for their implementations (e.g. substrings may pass index arithmetic through to the underlying string they provide a view into). Relaxed indexing functions include those intended for index arithmetic: thisind, nextind and prevind. This model allows index arithmetic to work with out-of-bounds indices as intermediate values so long as one never uses them to retrieve a character, which often helps avoid needing to code around edge cases.\n\nSee also codeunit, ncodeunits, thisind, nextind, prevind.\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Core.AbstractChar","page":"Strings","title":"Core.AbstractChar","text":"The AbstractChar type is the supertype of all character implementations in Julia. A character represents a Unicode code point, and can be converted to an integer via the codepoint function in order to obtain the numerical value of the code point, or constructed from the same integer. These numerical values determine how characters are compared with < and ==, for example. New T <: AbstractChar types should define a codepoint(::T) method and a T(::UInt32) constructor, at minimum.\n\nA given AbstractChar subtype may be capable of representing only a subset of Unicode, in which case conversion from an unsupported UInt32 value may throw an error. Conversely, the built-in Char type represents a superset of Unicode (in order to losslessly encode invalid byte streams), in which case conversion of a non-Unicode value to UInt32 throws an error. The isvalid function can be used to check which codepoints are representable in a given AbstractChar type.\n\nInternally, an AbstractChar type may use a variety of encodings. Conversion via codepoint(char) will not reveal this encoding because it always returns the Unicode value of the character. print(io, c) of any c::AbstractChar produces an encoding determined by io (UTF-8 for all built-in IO types), via conversion to Char if necessary.\n\nwrite(io, c), in contrast, may emit an encoding depending on typeof(c), and read(io, typeof(c)) should read the same encoding as write. New AbstractChar types must provide their own implementations of write and read.\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Core.Char","page":"Strings","title":"Core.Char","text":"Char(c::Union{Number,AbstractChar})\n\nChar is a 32-bit AbstractChar type that is the default representation of characters in Julia. Char is the type used for character literals like 'x' and it is also the element type of String.\n\nIn order to losslessly represent arbitrary byte streams stored in a String, a Char value may store information that cannot be converted to a Unicode codepoint — converting such a Char to UInt32 will throw an error. The isvalid(c::Char) function can be used to query whether c represents a valid Unicode character.\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.codepoint","page":"Strings","title":"Base.codepoint","text":"codepoint(c::AbstractChar) -> Integer\n\nReturn the Unicode codepoint (an unsigned integer) corresponding to the character c (or throw an exception if c does not represent a valid character). For Char, this is a UInt32 value, but AbstractChar types that represent only a subset of Unicode may return a different-sized integer (e.g. UInt8).\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.length-Tuple{AbstractString}","page":"Strings","title":"Base.length","text":"length(s::AbstractString) -> Int\nlength(s::AbstractString, i::Integer, j::Integer) -> Int\n\nReturn the number of characters in string s from indices i through j.\n\nThis is computed as the number of code unit indices from i to j which are valid character indices. With only a single string argument, this computes the number of characters in the entire string. With i and j arguments it computes the number of indices between i and j inclusive that are valid indices in the string s. In addition to in-bounds values, i may take the out-of-bounds value ncodeunits(s) + 1 and j may take the out-of-bounds value 0.\n\nnote: Note\nThe time complexity of this operation is linear in general. That is, it will take the time proportional to the number of bytes or characters in the string because it counts the value on the fly. This is in contrast to the method for arrays, which is a constant-time operation.\n\nSee also isvalid, ncodeunits, lastindex, thisind, nextind, prevind.\n\nExamples\n\njulia> length(\"jμΛIα\")\n5\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.sizeof-Tuple{AbstractString}","page":"Strings","title":"Base.sizeof","text":"sizeof(str::AbstractString)\n\nSize, in bytes, of the string str. Equal to the number of code units in str multiplied by the size, in bytes, of one code unit in str.\n\nExamples\n\njulia> sizeof(\"\")\n0\n\njulia> sizeof(\"∀\")\n3\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.:*-Tuple{Union{AbstractChar, AbstractString}, Vararg{Union{AbstractChar, AbstractString}}}","page":"Strings","title":"Base.:*","text":"*(s::Union{AbstractString, AbstractChar}, t::Union{AbstractString, AbstractChar}...) -> AbstractString\n\nConcatenate strings and/or characters, producing a String or AnnotatedString (as appropriate). This is equivalent to calling the string or annotatedstring function on the arguments. Concatenation of built-in string types always produces a value of type String but other string types may choose to return a string of a different type as appropriate.\n\nExamples\n\njulia> \"Hello \" * \"world\"\n\"Hello world\"\n\njulia> 'j' * \"ulia\"\n\"julia\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.:^-Tuple{Union{AbstractChar, AbstractString}, Integer}","page":"Strings","title":"Base.:^","text":"^(s::Union{AbstractString,AbstractChar}, n::Integer) -> AbstractString\n\nRepeat a string or character n times. This can also be written as repeat(s, n).\n\nSee also repeat.\n\nExamples\n\njulia> \"Test \"^3\n\"Test Test Test \"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.string","page":"Strings","title":"Base.string","text":"string(n::Integer; base::Integer = 10, pad::Integer = 1)\n\nConvert an integer n to a string in the given base, optionally specifying a number of digits to pad to.\n\nSee also digits, bitstring, count_zeros.\n\nExamples\n\njulia> string(5, base = 13, pad = 4)\n\"0005\"\n\njulia> string(-13, base = 5, pad = 4)\n\"-0023\"\n\n\n\n\n\nstring(xs...)\n\nCreate a string from any values using the print function.\n\nstring should usually not be defined directly. Instead, define a method print(io::IO, x::MyType). If string(x) for a certain type needs to be highly efficient, then it may make sense to add a method to string and define print(io::IO, x::MyType) = print(io, string(x)) to ensure the functions are consistent.\n\nSee also: String, repr, sprint, show.\n\nExamples\n\njulia> string(\"a\", 1, true)\n\"a1true\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.repeat-Tuple{AbstractString, Integer}","page":"Strings","title":"Base.repeat","text":"repeat(s::AbstractString, r::Integer)\n\nRepeat a string r times. This can be written as s^r.\n\nSee also ^.\n\nExamples\n\njulia> repeat(\"ha\", 3)\n\"hahaha\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.repeat-Tuple{AbstractChar, Integer}","page":"Strings","title":"Base.repeat","text":"repeat(c::AbstractChar, r::Integer) -> String\n\nRepeat a character r times. This can equivalently be accomplished by calling c^r.\n\nExamples\n\njulia> repeat('A', 3)\n\"AAA\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.repr-Tuple{Any}","page":"Strings","title":"Base.repr","text":"repr(x; context=nothing)\n\nCreate a string from any value using the show function. You should not add methods to repr; define a show method instead.\n\nThe optional keyword argument context can be set to a :key=>value pair, a tuple of :key=>value pairs, or an IO or IOContext object whose attributes are used for the I/O stream passed to show.\n\nNote that repr(x) is usually similar to how the value of x would be entered in Julia. See also repr(MIME(\"text/plain\"), x) to instead return a \"pretty-printed\" version of x designed more for human consumption, equivalent to the REPL display of x.\n\ncompat: Julia 1.7\nPassing a tuple to keyword context requires Julia 1.7 or later.\n\nExamples\n\njulia> repr(1)\n\"1\"\n\njulia> repr(zeros(3))\n\"[0.0, 0.0, 0.0]\"\n\njulia> repr(big(1/3))\n\"0.333333333333333314829616256247390992939472198486328125\"\n\njulia> repr(big(1/3), context=:compact => true)\n\"0.333333\"\n\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Core.String-Tuple{AbstractString}","page":"Strings","title":"Core.String","text":"String(s::AbstractString)\n\nCreate a new String from an existing AbstractString.\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.SubString","page":"Strings","title":"Base.SubString","text":"SubString(s::AbstractString, i::Integer, j::Integer=lastindex(s))\nSubString(s::AbstractString, r::UnitRange{<:Integer})\n\nLike getindex, but returns a view into the parent string s within range i:j or r respectively instead of making a copy.\n\nThe @views macro converts any string slices s[i:j] into substrings SubString(s, i, j) in a block of code.\n\nExamples\n\njulia> SubString(\"abc\", 1, 2)\n\"ab\"\n\njulia> SubString(\"abc\", 1:2)\n\"ab\"\n\njulia> SubString(\"abc\", 2)\n\"bc\"\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.LazyString","page":"Strings","title":"Base.LazyString","text":"LazyString <: AbstractString\n\nA lazy representation of string interpolation. This is useful when a string needs to be constructed in a context where performing the actual interpolation and string construction is unnecessary or undesirable (e.g. in error paths of functions).\n\nThis type is designed to be cheap to construct at runtime, trying to offload as much work as possible to either the macro or later printing operations.\n\nExamples\n\njulia> n = 5; str = LazyString(\"n is \", n)\n\"n is 5\"\n\nSee also @lazy_str.\n\ncompat: Julia 1.8\nLazyString requires Julia 1.8 or later.\n\nExtended help\n\nSafety properties for concurrent programs\n\nA lazy string itself does not introduce any concurrency problems even if it is printed in multiple Julia tasks. However, if print methods on a captured value can have a concurrency issue when invoked without synchronizations, printing the lazy string may cause an issue. Furthermore, the print methods on the captured values may be invoked multiple times, though only exactly one result will be returned.\n\ncompat: Julia 1.9\nLazyString is safe in the above sense in Julia 1.9 and later.\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.@lazy_str","page":"Strings","title":"Base.@lazy_str","text":"lazy\"str\"\n\nCreate a LazyString using regular string interpolation syntax. Note that interpolations are evaluated at LazyString construction time, but printing is delayed until the first access to the string.\n\nSee LazyString documentation for the safety properties for concurrent programs.\n\nExamples\n\njulia> n = 5; str = lazy\"n is $n\"\n\"n is 5\"\n\njulia> typeof(str)\nLazyString\n\ncompat: Julia 1.8\nlazy\"str\" requires Julia 1.8 or later.\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.AnnotatedString","page":"Strings","title":"Base.AnnotatedString","text":"AnnotatedString{S <: AbstractString} <: AbstractString\n\nA string with metadata, in the form of annotated regions.\n\nMore specifically, this is a simple wrapper around any other AbstractString that allows for regions of the wrapped string to be annotated with labeled values.\n\n C\n ┌──────┸─────────┐\n \"this is an example annotated string\"\n └──┰────────┼─────┘ │\n A └─────┰─────────┘\n B\n\nThe above diagram represents a AnnotatedString where three ranges have been annotated (labeled A, B, and C). Each annotation holds a label (Symbol) and a value (Any), paired together as a Pair{Symbol, <:Any}.\n\nLabels do not need to be unique, the same region can hold multiple annotations with the same label.\n\nSee also AnnotatedChar, annotatedstring, annotations, and annotate!.\n\nwarning: Warning\nWhile the constructors are part of the Base public API, the fields of AnnotatedString are not. This is to allow for potential future changes in the implementation of this type. Instead use the annotations, and annotate! getter/setter functions.\n\nConstructors\n\nAnnotatedString(s::S<:AbstractString) -> AnnotatedString{S}\nAnnotatedString(s::S<:AbstractString, annotations::Vector{Tuple{UnitRange{Int}, Pair{Symbol, <:Any}}})\n\nA AnnotatedString can also be created with annotatedstring, which acts much like string but preserves any annotations present in the arguments.\n\nExamples\n\njulia> AnnotatedString(\"this is an example annotated string\",\n [(1:18, :A => 1), (12:28, :B => 2), (18:35, :C => 3)])\n\"this is an example annotated string\"\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.AnnotatedChar","page":"Strings","title":"Base.AnnotatedChar","text":"AnnotatedChar{S <: AbstractChar} <: AbstractChar\n\nA Char with annotations.\n\nMore specifically, this is a simple wrapper around any other AbstractChar, which holds a list of arbitrary labeled annotations (Pair{Symbol, <:Any}) with the wrapped character.\n\nSee also: AnnotatedString, annotatedstring, annotations, and annotate!.\n\nwarning: Warning\nWhile the constructors are part of the Base public API, the fields of AnnotatedChar are not. This it to allow for potential future changes in the implementation of this type. Instead use the annotations, and annotate! getter/setter functions.\n\nConstructors\n\nAnnotatedChar(s::S) -> AnnotatedChar{S}\nAnnotatedChar(s::S, annotations::Vector{Pair{Symbol, <:Any}})\n\nExamples\n\njulia> AnnotatedChar('j', :label => 1)\n'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.annotatedstring","page":"Strings","title":"Base.annotatedstring","text":"annotatedstring(values...)\n\nCreate a AnnotatedString from any number of values using their printed representation.\n\nThis acts like string, but takes care to preserve any annotations present (in the form of AnnotatedString or AnnotatedChar values).\n\nSee also AnnotatedString and AnnotatedChar.\n\nExamples\n\njulia> annotatedstring(\"now a AnnotatedString\")\n\"now a AnnotatedString\"\n\njulia> annotatedstring(AnnotatedString(\"annotated\", [(1:9, :label => 1)]), \", and unannotated\")\n\"annotated, and unannotated\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.annotations","page":"Strings","title":"Base.annotations","text":"annotations(str::Union{AnnotatedString, SubString{AnnotatedString}},\n [position::Union{Integer, UnitRange}]) ->\n Vector{Tuple{UnitRange{Int}, Pair{Symbol, Any}}}\n\nGet all annotations that apply to str. Should position be provided, only annotations that overlap with position will be returned.\n\nAnnotations are provided together with the regions they apply to, in the form of a vector of region–annotation tuples.\n\nSee also: annotate!.\n\n\n\n\n\nannotations(chr::AnnotatedChar) -> Vector{Pair{Symbol, Any}}\n\nGet all annotations of chr, in the form of a vector of annotation pairs.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.annotate!","page":"Strings","title":"Base.annotate!","text":"annotate!(str::AnnotatedString, [range::UnitRange{Int}], label::Symbol => value)\nannotate!(str::SubString{AnnotatedString}, [range::UnitRange{Int}], label::Symbol => value)\n\nAnnotate a range of str (or the entire string) with a labeled value (label => value). To remove existing label annotations, use a value of nothing.\n\n\n\n\n\nannotate!(char::AnnotatedChar, label::Symbol => value)\n\nAnnotate char with the pair label => value.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.transcode","page":"Strings","title":"Base.transcode","text":"transcode(T, src)\n\nConvert string data between Unicode encodings. src is either a String or a Vector{UIntXX} of UTF-XX code units, where XX is 8, 16, or 32. T indicates the encoding of the return value: String to return a (UTF-8 encoded) String or UIntXX to return a Vector{UIntXX} of UTF-XX data. (The alias Cwchar_t can also be used as the integer type, for converting wchar_t* strings used by external C libraries.)\n\nThe transcode function succeeds as long as the input data can be reasonably represented in the target encoding; it always succeeds for conversions between UTF-XX encodings, even for invalid Unicode data.\n\nOnly conversion to/from UTF-8 is currently supported.\n\nExamples\n\njulia> str = \"αβγ\"\n\"αβγ\"\n\njulia> transcode(UInt16, str)\n3-element Vector{UInt16}:\n 0x03b1\n 0x03b2\n 0x03b3\n\njulia> transcode(String, transcode(UInt16, str))\n\"αβγ\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.unsafe_string","page":"Strings","title":"Base.unsafe_string","text":"unsafe_string(p::Ptr{UInt8}, [length::Integer])\n\nCopy a string from the address of a C-style (NUL-terminated) string encoded as UTF-8. (The pointer can be safely freed afterwards.) If length is specified (the length of the data in bytes), the string does not have to be NUL-terminated.\n\nThis function is labeled \"unsafe\" because it will crash if p is not a valid memory address to data of the requested length.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.ncodeunits-Tuple{AbstractString}","page":"Strings","title":"Base.ncodeunits","text":"ncodeunits(s::AbstractString) -> Int\n\nReturn the number of code units in a string. Indices that are in bounds to access this string must satisfy 1 ≤ i ≤ ncodeunits(s). Not all such indices are valid – they may not be the start of a character, but they will return a code unit value when calling codeunit(s,i).\n\nExamples\n\njulia> ncodeunits(\"The Julia Language\")\n18\n\njulia> ncodeunits(\"∫eˣ\")\n6\n\njulia> ncodeunits('∫'), ncodeunits('e'), ncodeunits('ˣ')\n(3, 1, 2)\n\nSee also codeunit, checkbounds, sizeof, length, lastindex.\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.codeunit","page":"Strings","title":"Base.codeunit","text":"codeunit(s::AbstractString) -> Type{<:Union{UInt8, UInt16, UInt32}}\n\nReturn the code unit type of the given string object. For ASCII, Latin-1, or UTF-8 encoded strings, this would be UInt8; for UCS-2 and UTF-16 it would be UInt16; for UTF-32 it would be UInt32. The code unit type need not be limited to these three types, but it's hard to think of widely used string encodings that don't use one of these units. codeunit(s) is the same as typeof(codeunit(s,1)) when s is a non-empty string.\n\nSee also ncodeunits.\n\n\n\n\n\ncodeunit(s::AbstractString, i::Integer) -> Union{UInt8, UInt16, UInt32}\n\nReturn the code unit value in the string s at index i. Note that\n\ncodeunit(s, i) :: codeunit(s)\n\nI.e. the value returned by codeunit(s, i) is of the type returned by codeunit(s).\n\nExamples\n\njulia> a = codeunit(\"Hello\", 2)\n0x65\n\njulia> typeof(a)\nUInt8\n\nSee also ncodeunits, checkbounds.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.codeunits","page":"Strings","title":"Base.codeunits","text":"codeunits(s::AbstractString)\n\nObtain a vector-like object containing the code units of a string. Returns a CodeUnits wrapper by default, but codeunits may optionally be defined for new string types if necessary.\n\nExamples\n\njulia> codeunits(\"Juλia\")\n6-element Base.CodeUnits{UInt8, String}:\n 0x4a\n 0x75\n 0xce\n 0xbb\n 0x69\n 0x61\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.ascii","page":"Strings","title":"Base.ascii","text":"ascii(s::AbstractString)\n\nConvert a string to String type and check that it contains only ASCII data, otherwise throwing an ArgumentError indicating the position of the first non-ASCII byte.\n\nSee also the isascii predicate to filter or replace non-ASCII characters.\n\nExamples\n\njulia> ascii(\"abcdeγfgh\")\nERROR: ArgumentError: invalid ASCII at index 6 in \"abcdeγfgh\"\nStacktrace:\n[...]\n\njulia> ascii(\"abcdefgh\")\n\"abcdefgh\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Regex","page":"Strings","title":"Base.Regex","text":"Regex(pattern[, flags]) <: AbstractPattern\n\nA type representing a regular expression. Regex objects can be used to match strings with match.\n\nRegex objects can be created using the @r_str string macro. The Regex(pattern[, flags]) constructor is usually used if the pattern string needs to be interpolated. See the documentation of the string macro for details on flags.\n\nnote: Note\nTo escape interpolated variables use \\Q and \\E (e.g. Regex(\"\\\\Q$x\\\\E\"))\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.@r_str","page":"Strings","title":"Base.@r_str","text":"@r_str -> Regex\n\nConstruct a regex, such as r\"^[a-z]*$\", without interpolation and unescaping (except for quotation mark \" which still has to be escaped). The regex also accepts one or more flags, listed after the ending quote, to change its behaviour:\n\ni enables case-insensitive matching\nm treats the ^ and $ tokens as matching the start and end of individual lines, as opposed to the whole string.\ns allows the . modifier to match newlines.\nx enables \"free-spacing mode\": whitespace between regex tokens is ignored except when escaped with \\, and # in the regex is treated as starting a comment (which is ignored to the line ending).\na enables ASCII mode (disables UTF and UCP modes). By default \\B, \\b, \\D, \\d, \\S, \\s, \\W, \\w, etc. match based on Unicode character properties. With this option, these sequences only match ASCII characters. This includes \\u also, which will emit the specified character value directly as a single byte, and not attempt to encode it into UTF-8. Importantly, this option allows matching against invalid UTF-8 strings, by treating both matcher and target as simple bytes (as if they were ISO/IEC 8859-1 / Latin-1 bytes) instead of as character encodings. In this case, this option is often combined with s. This option can be further refined by starting the pattern with (UCP) or (UTF).\n\nSee Regex if interpolation is needed.\n\nExamples\n\njulia> match(r\"a+.*b+.*?d$\"ism, \"Goodbye,\\nOh, angry,\\nBad world\\n\")\nRegexMatch(\"angry,\\nBad world\")\n\nThis regex has the first three flags enabled.\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.SubstitutionString","page":"Strings","title":"Base.SubstitutionString","text":"SubstitutionString(substr) <: AbstractString\n\nStores the given string substr as a SubstitutionString, for use in regular expression substitutions. Most commonly constructed using the @s_str macro.\n\nExamples\n\njulia> SubstitutionString(\"Hello \\\\g, it's \\\\1\")\ns\"Hello \\g, it's \\1\"\n\njulia> subst = s\"Hello \\g, it's \\1\"\ns\"Hello \\g, it's \\1\"\n\njulia> typeof(subst)\nSubstitutionString{String}\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.@s_str","page":"Strings","title":"Base.@s_str","text":"@s_str -> SubstitutionString\n\nConstruct a substitution string, used for regular expression substitutions. Within the string, sequences of the form \\N refer to the Nth capture group in the regex, and \\g refers to a named capture group with name groupname.\n\nExamples\n\njulia> msg = \"#Hello# from Julia\";\n\njulia> replace(msg, r\"#(.+)# from (?\\w+)\" => s\"FROM: \\g; MESSAGE: \\1\")\n\"FROM: Julia; MESSAGE: Hello\"\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.@raw_str","page":"Strings","title":"Base.@raw_str","text":"@raw_str -> String\n\nCreate a raw string without interpolation and unescaping. The exception is that quotation marks still must be escaped. Backslashes escape both quotation marks and other backslashes, but only when a sequence of backslashes precedes a quote character. Thus, 2n backslashes followed by a quote encodes n backslashes and the end of the literal while 2n+1 backslashes followed by a quote encodes n backslashes followed by a quote character.\n\nExamples\n\njulia> println(raw\"\\ $x\")\n\\ $x\n\njulia> println(raw\"\\\"\")\n\"\n\njulia> println(raw\"\\\\\\\"\")\n\\\"\n\njulia> println(raw\"\\\\x \\\\\\\"\")\n\\\\x \\\"\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.@b_str","page":"Strings","title":"Base.@b_str","text":"@b_str\n\nCreate an immutable byte (UInt8) vector using string syntax.\n\nExamples\n\njulia> v = b\"12\\x01\\x02\"\n4-element Base.CodeUnits{UInt8, String}:\n 0x31\n 0x32\n 0x01\n 0x02\n\njulia> v[2]\n0x32\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.Docs.@html_str","page":"Strings","title":"Base.Docs.@html_str","text":"@html_str -> Docs.HTML\n\nCreate an HTML object from a literal string.\n\nExamples\n\njulia> html\"Julia\"\nHTML{String}(\"Julia\")\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.Docs.@text_str","page":"Strings","title":"Base.Docs.@text_str","text":"@text_str -> Docs.Text\n\nCreate a Text object from a literal string.\n\nExamples\n\njulia> text\"Julia\"\nJulia\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.isvalid-Tuple{Any}","page":"Strings","title":"Base.isvalid","text":"isvalid(value) -> Bool\n\nReturn true if the given value is valid for its type, which currently can be either AbstractChar or String or SubString{String}.\n\nExamples\n\njulia> isvalid(Char(0xd800))\nfalse\n\njulia> isvalid(SubString(String(UInt8[0xfe,0x80,0x80,0x80,0x80,0x80]),1,2))\nfalse\n\njulia> isvalid(Char(0xd799))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.isvalid-Tuple{Any, Any}","page":"Strings","title":"Base.isvalid","text":"isvalid(T, value) -> Bool\n\nReturn true if the given value is valid for that type. Types currently can be either AbstractChar or String. Values for AbstractChar can be of type AbstractChar or UInt32. Values for String can be of that type, SubString{String}, Vector{UInt8}, or a contiguous subarray thereof.\n\nExamples\n\njulia> isvalid(Char, 0xd800)\nfalse\n\njulia> isvalid(String, SubString(\"thisisvalid\",1,5))\ntrue\n\njulia> isvalid(Char, 0xd799)\ntrue\n\ncompat: Julia 1.6\nSupport for subarray values was added in Julia 1.6.\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.isvalid-Tuple{AbstractString, Integer}","page":"Strings","title":"Base.isvalid","text":"isvalid(s::AbstractString, i::Integer) -> Bool\n\nPredicate indicating whether the given index is the start of the encoding of a character in s or not. If isvalid(s, i) is true then s[i] will return the character whose encoding starts at that index, if it's false, then s[i] will raise an invalid index error or a bounds error depending on if i is in bounds. In order for isvalid(s, i) to be an O(1) function, the encoding of s must be self-synchronizing. This is a basic assumption of Julia's generic string support.\n\nSee also getindex, iterate, thisind, nextind, prevind, length.\n\nExamples\n\njulia> str = \"αβγdef\";\n\njulia> isvalid(str, 1)\ntrue\n\njulia> str[1]\n'α': Unicode U+03B1 (category Ll: Letter, lowercase)\n\njulia> isvalid(str, 2)\nfalse\n\njulia> str[2]\nERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'α', [3]=>'β'\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.match","page":"Strings","title":"Base.match","text":"match(r::Regex, s::AbstractString[, idx::Integer[, addopts]])\n\nSearch for the first match of the regular expression r in s and return a RegexMatch object containing the match, or nothing if the match failed. The optional idx argument specifies an index at which to start the search. The matching substring can be retrieved by accessing m.match, the captured sequences can be retrieved by accessing m.captures. The resulting RegexMatch object can be used to construct other collections: e.g. Tuple(m), NamedTuple(m).\n\ncompat: Julia 1.11\nConstructing NamedTuples and Dicts requires Julia 1.11\n\nExamples\n\njulia> rx = r\"a(.)a\"\nr\"a(.)a\"\n\njulia> m = match(rx, \"cabac\")\nRegexMatch(\"aba\", 1=\"b\")\n\njulia> m.captures\n1-element Vector{Union{Nothing, SubString{String}}}:\n \"b\"\n\njulia> m.match\n\"aba\"\n\njulia> match(rx, \"cabac\", 3) === nothing\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.eachmatch","page":"Strings","title":"Base.eachmatch","text":"eachmatch(r::Regex, s::AbstractString; overlap::Bool=false)\n\nSearch for all matches of the regular expression r in s and return an iterator over the matches. If overlap is true, the matching sequences are allowed to overlap indices in the original string, otherwise they must be from distinct character ranges.\n\nExamples\n\njulia> rx = r\"a.a\"\nr\"a.a\"\n\njulia> m = eachmatch(rx, \"a1a2a3a\")\nBase.RegexMatchIterator{String}(r\"a.a\", \"a1a2a3a\", false)\n\njulia> collect(m)\n2-element Vector{RegexMatch}:\n RegexMatch(\"a1a\")\n RegexMatch(\"a3a\")\n\njulia> collect(eachmatch(rx, \"a1a2a3a\", overlap = true))\n3-element Vector{RegexMatch}:\n RegexMatch(\"a1a\")\n RegexMatch(\"a2a\")\n RegexMatch(\"a3a\")\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.RegexMatch","page":"Strings","title":"Base.RegexMatch","text":"RegexMatch <: AbstractMatch\n\nA type representing a single match to a Regex found in a string. Typically created from the match function.\n\nThe match field stores the substring of the entire matched string. The captures field stores the substrings for each capture group, indexed by number. To index by capture group name, the entire match object should be indexed instead, as shown in the examples. The location of the start of the match is stored in the offset field. The offsets field stores the locations of the start of each capture group, with 0 denoting a group that was not captured.\n\nThis type can be used as an iterator over the capture groups of the Regex, yielding the substrings captured in each group. Because of this, the captures of a match can be destructured. If a group was not captured, nothing will be yielded instead of a substring.\n\nMethods that accept a RegexMatch object are defined for iterate, length, eltype, keys, haskey, and getindex, where keys are the names or numbers of a capture group. See keys for more information.\n\nTuple(m), NamedTuple(m), and Dict(m) can be used to construct more flexible collection types from RegexMatch objects.\n\ncompat: Julia 1.11\nConstructing NamedTuples and Dicts from RegexMatches requires Julia 1.11\n\nExamples\n\njulia> m = match(r\"(?\\d+):(?\\d+)(am|pm)?\", \"11:30 in the morning\")\nRegexMatch(\"11:30\", hour=\"11\", minute=\"30\", 3=nothing)\n\njulia> m.match\n\"11:30\"\n\njulia> m.captures\n3-element Vector{Union{Nothing, SubString{String}}}:\n \"11\"\n \"30\"\n nothing\n\n\njulia> m[\"minute\"]\n\"30\"\n\njulia> hr, min, ampm = m; # destructure capture groups by iteration\n\njulia> hr\n\"11\"\n\njulia> Dict(m)\nDict{Any, Union{Nothing, SubString{String}}} with 3 entries:\n \"hour\" => \"11\"\n 3 => nothing\n \"minute\" => \"30\"\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.keys-Tuple{RegexMatch}","page":"Strings","title":"Base.keys","text":"keys(m::RegexMatch) -> Vector\n\nReturn a vector of keys for all capture groups of the underlying regex. A key is included even if the capture group fails to match. That is, idx will be in the return value even if m[idx] == nothing.\n\nUnnamed capture groups will have integer keys corresponding to their index. Named capture groups will have string keys.\n\ncompat: Julia 1.7\nThis method was added in Julia 1.7\n\nExamples\n\njulia> keys(match(r\"(?\\d+):(?\\d+)(am|pm)?\", \"11:30\"))\n3-element Vector{Any}:\n \"hour\"\n \"minute\"\n 3\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.isless-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.isless","text":"isless(a::AbstractString, b::AbstractString) -> Bool\n\nTest whether string a comes before string b in alphabetical order (technically, in lexicographical order by Unicode code points).\n\nExamples\n\njulia> isless(\"a\", \"b\")\ntrue\n\njulia> isless(\"β\", \"α\")\nfalse\n\njulia> isless(\"a\", \"a\")\nfalse\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.:==-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.:==","text":"==(a::AbstractString, b::AbstractString) -> Bool\n\nTest whether two strings are equal character by character (technically, Unicode code point by code point). Should either string be a AnnotatedString the string properties must match too.\n\nExamples\n\njulia> \"abc\" == \"abc\"\ntrue\n\njulia> \"abc\" == \"αβγ\"\nfalse\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.cmp-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.cmp","text":"cmp(a::AbstractString, b::AbstractString) -> Int\n\nCompare two strings. Return 0 if both strings have the same length and the character at each index is the same in both strings. Return -1 if a is a prefix of b, or if a comes before b in alphabetical order. Return 1 if b is a prefix of a, or if b comes before a in alphabetical order (technically, lexicographical order by Unicode code points).\n\nExamples\n\njulia> cmp(\"abc\", \"abc\")\n0\n\njulia> cmp(\"ab\", \"abc\")\n-1\n\njulia> cmp(\"abc\", \"ab\")\n1\n\njulia> cmp(\"ab\", \"ac\")\n-1\n\njulia> cmp(\"ac\", \"ab\")\n1\n\njulia> cmp(\"α\", \"a\")\n1\n\njulia> cmp(\"b\", \"β\")\n-1\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.lpad","page":"Strings","title":"Base.lpad","text":"lpad(s, n::Integer, p::Union{AbstractChar,AbstractString}=' ') -> String\n\nStringify s and pad the resulting string on the left with p to make it n characters (in textwidth) long. If s is already n characters long, an equal string is returned. Pad with spaces by default.\n\nExamples\n\njulia> lpad(\"March\", 10)\n\" March\"\n\ncompat: Julia 1.7\nIn Julia 1.7, this function was changed to use textwidth rather than a raw character (codepoint) count.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.rpad","page":"Strings","title":"Base.rpad","text":"rpad(s, n::Integer, p::Union{AbstractChar,AbstractString}=' ') -> String\n\nStringify s and pad the resulting string on the right with p to make it n characters (in textwidth) long. If s is already n characters long, an equal string is returned. Pad with spaces by default.\n\nExamples\n\njulia> rpad(\"March\", 20)\n\"March \"\n\ncompat: Julia 1.7\nIn Julia 1.7, this function was changed to use textwidth rather than a raw character (codepoint) count.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.findfirst-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.findfirst","text":"findfirst(pattern::AbstractString, string::AbstractString)\nfindfirst(pattern::AbstractPattern, string::String)\n\nFind the first occurrence of pattern in string. Equivalent to findnext(pattern, string, firstindex(s)).\n\nExamples\n\njulia> findfirst(\"z\", \"Hello to the world\") # returns nothing, but not printed in the REPL\n\njulia> findfirst(\"Julia\", \"JuliaLang\")\n1:5\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findnext-Tuple{AbstractString, AbstractString, Integer}","page":"Strings","title":"Base.findnext","text":"findnext(pattern::AbstractString, string::AbstractString, start::Integer)\nfindnext(pattern::AbstractPattern, string::String, start::Integer)\n\nFind the next occurrence of pattern in string starting at position start. pattern can be either a string, or a regular expression, in which case string must be of type String.\n\nThe return value is a range of indices where the matching sequence is found, such that s[findnext(x, s, i)] == x:\n\nfindnext(\"substring\", string, i) == start:stop such that string[start:stop] == \"substring\" and i <= start, or nothing if unmatched.\n\nExamples\n\njulia> findnext(\"z\", \"Hello to the world\", 1) === nothing\ntrue\n\njulia> findnext(\"o\", \"Hello to the world\", 6)\n8:8\n\njulia> findnext(\"Lang\", \"JuliaLang\", 2)\n6:9\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findnext-Tuple{AbstractChar, AbstractString, Integer}","page":"Strings","title":"Base.findnext","text":"findnext(ch::AbstractChar, string::AbstractString, start::Integer)\n\nFind the next occurrence of character ch in string starting at position start.\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\nExamples\n\njulia> findnext('z', \"Hello to the world\", 1) === nothing\ntrue\n\njulia> findnext('o', \"Hello to the world\", 6)\n8\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findlast-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.findlast","text":"findlast(pattern::AbstractString, string::AbstractString)\n\nFind the last occurrence of pattern in string. Equivalent to findprev(pattern, string, lastindex(string)).\n\nExamples\n\njulia> findlast(\"o\", \"Hello to the world\")\n15:15\n\njulia> findfirst(\"Julia\", \"JuliaLang\")\n1:5\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findlast-Tuple{AbstractChar, AbstractString}","page":"Strings","title":"Base.findlast","text":"findlast(ch::AbstractChar, string::AbstractString)\n\nFind the last occurrence of character ch in string.\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\nExamples\n\njulia> findlast('p', \"happy\")\n4\n\njulia> findlast('z', \"happy\") === nothing\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findprev-Tuple{AbstractString, AbstractString, Integer}","page":"Strings","title":"Base.findprev","text":"findprev(pattern::AbstractString, string::AbstractString, start::Integer)\n\nFind the previous occurrence of pattern in string starting at position start.\n\nThe return value is a range of indices where the matching sequence is found, such that s[findprev(x, s, i)] == x:\n\nfindprev(\"substring\", string, i) == start:stop such that string[start:stop] == \"substring\" and stop <= i, or nothing if unmatched.\n\nExamples\n\njulia> findprev(\"z\", \"Hello to the world\", 18) === nothing\ntrue\n\njulia> findprev(\"o\", \"Hello to the world\", 18)\n15:15\n\njulia> findprev(\"Julia\", \"JuliaLang\", 6)\n1:5\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.occursin","page":"Strings","title":"Base.occursin","text":"occursin(needle::Union{AbstractString,AbstractPattern,AbstractChar}, haystack::AbstractString)\n\nDetermine whether the first argument is a substring of the second. If needle is a regular expression, checks whether haystack contains a match.\n\nExamples\n\njulia> occursin(\"Julia\", \"JuliaLang is pretty cool!\")\ntrue\n\njulia> occursin('a', \"JuliaLang is pretty cool!\")\ntrue\n\njulia> occursin(r\"a.a\", \"aba\")\ntrue\n\njulia> occursin(r\"a.a\", \"abba\")\nfalse\n\nSee also contains.\n\n\n\n\n\noccursin(haystack)\n\nCreate a function that checks whether its argument occurs in haystack, i.e. a function equivalent to needle -> occursin(needle, haystack).\n\nThe returned function is of type Base.Fix2{typeof(occursin)}.\n\ncompat: Julia 1.6\nThis method requires Julia 1.6 or later.\n\nExamples\n\njulia> search_f = occursin(\"JuliaLang is a programming language\");\n\njulia> search_f(\"JuliaLang\")\ntrue\n\njulia> search_f(\"Python\")\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.reverse-Tuple{Union{SubString{String}, String}}","page":"Strings","title":"Base.reverse","text":"reverse(s::AbstractString) -> AbstractString\n\nReverses a string. Technically, this function reverses the codepoints in a string and its main utility is for reversed-order string processing, especially for reversed regular-expression searches. See also reverseind to convert indices in s to indices in reverse(s) and vice-versa, and graphemes from module Unicode to operate on user-visible \"characters\" (graphemes) rather than codepoints. See also Iterators.reverse for reverse-order iteration without making a copy. Custom string types must implement the reverse function themselves and should typically return a string with the same type and encoding. If they return a string with a different encoding, they must also override reverseind for that string type to satisfy s[reverseind(s,i)] == reverse(s)[i].\n\nExamples\n\njulia> reverse(\"JuliaLang\")\n\"gnaLailuJ\"\n\nnote: Note\nThe examples below may be rendered differently on different systems. The comments indicate how they're supposed to be rendered\n\nCombining characters can lead to surprising results:\n\njulia> reverse(\"ax̂e\") # hat is above x in the input, above e in the output\n\"êxa\"\n\njulia> using Unicode\n\njulia> join(reverse(collect(graphemes(\"ax̂e\")))) # reverses graphemes; hat is above x in both in- and output\n\"ex̂a\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.replace-Tuple{IO, AbstractString, Vararg{Pair}}","page":"Strings","title":"Base.replace","text":"replace([io::IO], s::AbstractString, pat=>r, [pat2=>r2, ...]; [count::Integer])\n\nSearch for the given pattern pat in s, and replace each occurrence with r. If count is provided, replace at most count occurrences. pat may be a single character, a vector or a set of characters, a string, or a regular expression. If r is a function, each occurrence is replaced with r(s) where s is the matched substring (when pat is a AbstractPattern or AbstractString) or character (when pat is an AbstractChar or a collection of AbstractChar). If pat is a regular expression and r is a SubstitutionString, then capture group references in r are replaced with the corresponding matched text. To remove instances of pat from string, set r to the empty String (\"\").\n\nThe return value is a new string after the replacements. If the io::IO argument is supplied, the transformed string is instead written to io (returning io). (For example, this can be used in conjunction with an IOBuffer to re-use a pre-allocated buffer array in-place.)\n\nMultiple patterns can be specified, and they will be applied left-to-right simultaneously, so only one pattern will be applied to any character, and the patterns will only be applied to the input text, not the replacements.\n\ncompat: Julia 1.7\nSupport for multiple patterns requires version 1.7.\n\ncompat: Julia 1.10\nThe io::IO argument requires version 1.10.\n\nExamples\n\njulia> replace(\"Python is a programming language.\", \"Python\" => \"Julia\")\n\"Julia is a programming language.\"\n\njulia> replace(\"The quick foxes run quickly.\", \"quick\" => \"slow\", count=1)\n\"The slow foxes run quickly.\"\n\njulia> replace(\"The quick foxes run quickly.\", \"quick\" => \"\", count=1)\n\"The foxes run quickly.\"\n\njulia> replace(\"The quick foxes run quickly.\", r\"fox(es)?\" => s\"bus\\1\")\n\"The quick buses run quickly.\"\n\njulia> replace(\"abcabc\", \"a\" => \"b\", \"b\" => \"c\", r\".+\" => \"a\")\n\"bca\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.eachsplit","page":"Strings","title":"Base.eachsplit","text":"eachsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)\neachsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false)\n\nSplit str on occurrences of the delimiter(s) dlm and return an iterator over the substrings. dlm can be any of the formats allowed by findnext's first argument (i.e. as a string, regular expression or a function), or as a single character or collection of characters.\n\nIf dlm is omitted, it defaults to isspace.\n\nThe optional keyword arguments are:\n\nlimit: the maximum size of the result. limit=0 implies no maximum (default)\nkeepempty: whether empty fields should be kept in the result. Default is false without a dlm argument, true with a dlm argument.\n\nSee also split.\n\ncompat: Julia 1.8\nThe eachsplit function requires at least Julia 1.8.\n\nExamples\n\njulia> a = \"Ma.rch\"\n\"Ma.rch\"\n\njulia> b = eachsplit(a, \".\")\nBase.SplitIterator{String, String}(\"Ma.rch\", \".\", 0, true)\n\njulia> collect(b)\n2-element Vector{SubString{String}}:\n \"Ma\"\n \"rch\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.eachrsplit","page":"Strings","title":"Base.eachrsplit","text":"eachrsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)\neachrsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false)\n\nReturn an iterator over SubStrings of str, produced when splitting on the delimiter(s) dlm, and yielded in reverse order (from right to left). dlm can be any of the formats allowed by findprev's first argument (i.e. a string, a single character or a function), or a collection of characters.\n\nIf dlm is omitted, it defaults to isspace, and keepempty default to false.\n\nThe optional keyword arguments are:\n\nIf limit > 0, the iterator will split at most limit - 1 times before returning the rest of the string unsplit. limit < 1 implies no cap to splits (default).\nkeepempty: whether empty fields should be returned when iterating Default is false without a dlm argument, true with a dlm argument.\n\nNote that unlike split, rsplit and eachsplit, this function iterates the substrings right to left as they occur in the input.\n\nSee also eachsplit, rsplit.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nExamples\n\njulia> a = \"Ma.r.ch\";\n\njulia> collect(eachrsplit(a, \".\")) == [\"ch\", \"r\", \"Ma\"]\ntrue\n\njulia> collect(eachrsplit(a, \".\"; limit=2)) == [\"ch\", \"Ma.r\"]\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.split","page":"Strings","title":"Base.split","text":"split(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)\nsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false)\n\nSplit str into an array of substrings on occurrences of the delimiter(s) dlm. dlm can be any of the formats allowed by findnext's first argument (i.e. as a string, regular expression or a function), or as a single character or collection of characters.\n\nIf dlm is omitted, it defaults to isspace.\n\nThe optional keyword arguments are:\n\nlimit: the maximum size of the result. limit=0 implies no maximum (default)\nkeepempty: whether empty fields should be kept in the result. Default is false without a dlm argument, true with a dlm argument.\n\nSee also rsplit, eachsplit.\n\nExamples\n\njulia> a = \"Ma.rch\"\n\"Ma.rch\"\n\njulia> split(a, \".\")\n2-element Vector{SubString{String}}:\n \"Ma\"\n \"rch\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.rsplit","page":"Strings","title":"Base.rsplit","text":"rsplit(s::AbstractString; limit::Integer=0, keepempty::Bool=false)\nrsplit(s::AbstractString, chars; limit::Integer=0, keepempty::Bool=true)\n\nSimilar to split, but starting from the end of the string.\n\nExamples\n\njulia> a = \"M.a.r.c.h\"\n\"M.a.r.c.h\"\n\njulia> rsplit(a, \".\")\n5-element Vector{SubString{String}}:\n \"M\"\n \"a\"\n \"r\"\n \"c\"\n \"h\"\n\njulia> rsplit(a, \".\"; limit=1)\n1-element Vector{SubString{String}}:\n \"M.a.r.c.h\"\n\njulia> rsplit(a, \".\"; limit=2)\n2-element Vector{SubString{String}}:\n \"M.a.r.c\"\n \"h\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.strip","page":"Strings","title":"Base.strip","text":"strip([pred=isspace,] str::AbstractString) -> SubString\nstrip(str::AbstractString, chars) -> SubString\n\nRemove leading and trailing characters from str, either those specified by chars or those for which the function pred returns true.\n\nThe default behaviour is to remove leading and trailing whitespace and delimiters: see isspace for precise details.\n\nThe optional chars argument specifies which characters to remove: it can be a single character, vector or set of characters.\n\nSee also lstrip and rstrip.\n\ncompat: Julia 1.2\nThe method which accepts a predicate function requires Julia 1.2 or later.\n\nExamples\n\njulia> strip(\"{3, 5}\\n\", ['{', '}', '\\n'])\n\"3, 5\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.lstrip","page":"Strings","title":"Base.lstrip","text":"lstrip([pred=isspace,] str::AbstractString) -> SubString\nlstrip(str::AbstractString, chars) -> SubString\n\nRemove leading characters from str, either those specified by chars or those for which the function pred returns true.\n\nThe default behaviour is to remove leading whitespace and delimiters: see isspace for precise details.\n\nThe optional chars argument specifies which characters to remove: it can be a single character, or a vector or set of characters.\n\nSee also strip and rstrip.\n\nExamples\n\njulia> a = lpad(\"March\", 20)\n\" March\"\n\njulia> lstrip(a)\n\"March\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.rstrip","page":"Strings","title":"Base.rstrip","text":"rstrip([pred=isspace,] str::AbstractString) -> SubString\nrstrip(str::AbstractString, chars) -> SubString\n\nRemove trailing characters from str, either those specified by chars or those for which the function pred returns true.\n\nThe default behaviour is to remove trailing whitespace and delimiters: see isspace for precise details.\n\nThe optional chars argument specifies which characters to remove: it can be a single character, or a vector or set of characters.\n\nSee also strip and lstrip.\n\nExamples\n\njulia> a = rpad(\"March\", 20)\n\"March \"\n\njulia> rstrip(a)\n\"March\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.startswith","page":"Strings","title":"Base.startswith","text":"startswith(s::AbstractString, prefix::Union{AbstractString,Base.Chars})\n\nReturn true if s starts with prefix, which can be a string, a character, or a tuple/vector/set of characters. If prefix is a tuple/vector/set of characters, test whether the first character of s belongs to that set.\n\nSee also endswith, contains.\n\nExamples\n\njulia> startswith(\"JuliaLang\", \"Julia\")\ntrue\n\n\n\n\n\nstartswith(io::IO, prefix::Union{AbstractString,Base.Chars})\n\nCheck if an IO object starts with a prefix, which can be either a string, a character, or a tuple/vector/set of characters. See also peek.\n\n\n\n\n\nstartswith(prefix)\n\nCreate a function that checks whether its argument starts with prefix, i.e. a function equivalent to y -> startswith(y, prefix).\n\nThe returned function is of type Base.Fix2{typeof(startswith)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.5\nThe single argument startswith(prefix) requires at least Julia 1.5.\n\nExamples\n\njulia> startswith(\"Julia\")(\"JuliaLang\")\ntrue\n\njulia> startswith(\"Julia\")(\"Ends with Julia\")\nfalse\n\n\n\n\n\nstartswith(s::AbstractString, prefix::Regex)\n\nReturn true if s starts with the regex pattern, prefix.\n\nnote: Note\nstartswith does not compile the anchoring into the regular expression, but instead passes the anchoring as match_option to PCRE. If compile time is amortized, occursin(r\"^...\", s) is faster than startswith(s, r\"...\").\n\nSee also occursin and endswith.\n\ncompat: Julia 1.2\nThis method requires at least Julia 1.2.\n\nExamples\n\njulia> startswith(\"JuliaLang\", r\"Julia|Romeo\")\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.endswith","page":"Strings","title":"Base.endswith","text":"endswith(s::AbstractString, suffix::Union{AbstractString,Base.Chars})\n\nReturn true if s ends with suffix, which can be a string, a character, or a tuple/vector/set of characters. If suffix is a tuple/vector/set of characters, test whether the last character of s belongs to that set.\n\nSee also startswith, contains.\n\nExamples\n\njulia> endswith(\"Sunday\", \"day\")\ntrue\n\n\n\n\n\nendswith(suffix)\n\nCreate a function that checks whether its argument ends with suffix, i.e. a function equivalent to y -> endswith(y, suffix).\n\nThe returned function is of type Base.Fix2{typeof(endswith)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.5\nThe single argument endswith(suffix) requires at least Julia 1.5.\n\nExamples\n\njulia> endswith(\"Julia\")(\"Ends with Julia\")\ntrue\n\njulia> endswith(\"Julia\")(\"JuliaLang\")\nfalse\n\n\n\n\n\nendswith(s::AbstractString, suffix::Regex)\n\nReturn true if s ends with the regex pattern, suffix.\n\nnote: Note\nendswith does not compile the anchoring into the regular expression, but instead passes the anchoring as match_option to PCRE. If compile time is amortized, occursin(r\"...$\", s) is faster than endswith(s, r\"...\").\n\nSee also occursin and startswith.\n\ncompat: Julia 1.2\nThis method requires at least Julia 1.2.\n\nExamples\n\njulia> endswith(\"JuliaLang\", r\"Lang|Roberts\")\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.contains","page":"Strings","title":"Base.contains","text":"contains(haystack::AbstractString, needle)\n\nReturn true if haystack contains needle. This is the same as occursin(needle, haystack), but is provided for consistency with startswith(haystack, needle) and endswith(haystack, needle).\n\nSee also occursin, in, issubset.\n\nExamples\n\njulia> contains(\"JuliaLang is pretty cool!\", \"Julia\")\ntrue\n\njulia> contains(\"JuliaLang is pretty cool!\", 'a')\ntrue\n\njulia> contains(\"aba\", r\"a.a\")\ntrue\n\njulia> contains(\"abba\", r\"a.a\")\nfalse\n\ncompat: Julia 1.5\nThe contains function requires at least Julia 1.5.\n\n\n\n\n\ncontains(needle)\n\nCreate a function that checks whether its argument contains needle, i.e. a function equivalent to haystack -> contains(haystack, needle).\n\nThe returned function is of type Base.Fix2{typeof(contains)}, which can be used to implement specialized methods.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.first-Tuple{AbstractString, Integer}","page":"Strings","title":"Base.first","text":"first(s::AbstractString, n::Integer)\n\nGet a string consisting of the first n characters of s.\n\nExamples\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 0)\n\"\"\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 1)\n\"∀\"\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 3)\n\"∀ϵ≠\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.last-Tuple{AbstractString, Integer}","page":"Strings","title":"Base.last","text":"last(s::AbstractString, n::Integer)\n\nGet a string consisting of the last n characters of s.\n\nExamples\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 0)\n\"\"\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 1)\n\"0\"\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 3)\n\"²>0\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.Unicode.uppercase","page":"Strings","title":"Base.Unicode.uppercase","text":"uppercase(c::AbstractChar)\n\nConvert c to uppercase.\n\nSee also lowercase, titlecase.\n\nExamples\n\njulia> uppercase('a')\n'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)\n\njulia> uppercase('ê')\n'Ê': Unicode U+00CA (category Lu: Letter, uppercase)\n\n\n\n\n\nuppercase(s::AbstractString)\n\nReturn s with all characters converted to uppercase.\n\nSee also lowercase, titlecase, uppercasefirst.\n\nExamples\n\njulia> uppercase(\"Julia\")\n\"JULIA\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.lowercase","page":"Strings","title":"Base.Unicode.lowercase","text":"lowercase(c::AbstractChar)\n\nConvert c to lowercase.\n\nSee also uppercase, titlecase.\n\nExamples\n\njulia> lowercase('A')\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> lowercase('Ö')\n'ö': Unicode U+00F6 (category Ll: Letter, lowercase)\n\n\n\n\n\nlowercase(s::AbstractString)\n\nReturn s with all characters converted to lowercase.\n\nSee also uppercase, titlecase, lowercasefirst.\n\nExamples\n\njulia> lowercase(\"STRINGS AND THINGS\")\n\"strings and things\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.titlecase","page":"Strings","title":"Base.Unicode.titlecase","text":"titlecase(c::AbstractChar)\n\nConvert c to titlecase. This may differ from uppercase for digraphs, compare the example below.\n\nSee also uppercase, lowercase.\n\nExamples\n\njulia> titlecase('a')\n'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)\n\njulia> titlecase('dž')\n'Dž': Unicode U+01C5 (category Lt: Letter, titlecase)\n\njulia> uppercase('dž')\n'DŽ': Unicode U+01C4 (category Lu: Letter, uppercase)\n\n\n\n\n\ntitlecase(s::AbstractString; [wordsep::Function], strict::Bool=true) -> String\n\nCapitalize the first character of each word in s; if strict is true, every other character is converted to lowercase, otherwise they are left unchanged. By default, all non-letters beginning a new grapheme are considered as word separators; a predicate can be passed as the wordsep keyword to determine which characters should be considered as word separators. See also uppercasefirst to capitalize only the first character in s.\n\nSee also uppercase, lowercase, uppercasefirst.\n\nExamples\n\njulia> titlecase(\"the JULIA programming language\")\n\"The Julia Programming Language\"\n\njulia> titlecase(\"ISS - international space station\", strict=false)\n\"ISS - International Space Station\"\n\njulia> titlecase(\"a-a b-b\", wordsep = c->c==' ')\n\"A-a B-b\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.uppercasefirst","page":"Strings","title":"Base.Unicode.uppercasefirst","text":"uppercasefirst(s::AbstractString) -> String\n\nReturn s with the first character converted to uppercase (technically \"title case\" for Unicode). See also titlecase to capitalize the first character of every word in s.\n\nSee also lowercasefirst, uppercase, lowercase, titlecase.\n\nExamples\n\njulia> uppercasefirst(\"python\")\n\"Python\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.lowercasefirst","page":"Strings","title":"Base.Unicode.lowercasefirst","text":"lowercasefirst(s::AbstractString)\n\nReturn s with the first character converted to lowercase.\n\nSee also uppercasefirst, uppercase, lowercase, titlecase.\n\nExamples\n\njulia> lowercasefirst(\"Julia\")\n\"julia\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.join","page":"Strings","title":"Base.join","text":"join([io::IO,] iterator [, delim [, last]])\n\nJoin any iterator into a single string, inserting the given delimiter (if any) between adjacent items. If last is given, it will be used instead of delim between the last two items. Each item of iterator is converted to a string via print(io::IOBuffer, x). If io is given, the result is written to io rather than returned as a String.\n\nExamples\n\njulia> join([\"apples\", \"bananas\", \"pineapples\"], \", \", \" and \")\n\"apples, bananas and pineapples\"\n\njulia> join([1,2,3,4,5])\n\"12345\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.chop","page":"Strings","title":"Base.chop","text":"chop(s::AbstractString; head::Integer = 0, tail::Integer = 1)\n\nRemove the first head and the last tail characters from s. The call chop(s) removes the last character from s. If it is requested to remove more characters than length(s) then an empty string is returned.\n\nSee also chomp, startswith, first.\n\nExamples\n\njulia> a = \"March\"\n\"March\"\n\njulia> chop(a)\n\"Marc\"\n\njulia> chop(a, head = 1, tail = 2)\n\"ar\"\n\njulia> chop(a, head = 5, tail = 5)\n\"\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.chopprefix","page":"Strings","title":"Base.chopprefix","text":"chopprefix(s::AbstractString, prefix::Union{AbstractString,Regex}) -> SubString\n\nRemove the prefix prefix from s. If s does not start with prefix, a string equal to s is returned.\n\nSee also chopsuffix.\n\ncompat: Julia 1.8\nThis function is available as of Julia 1.8.\n\nExamples\n\njulia> chopprefix(\"Hamburger\", \"Ham\")\n\"burger\"\n\njulia> chopprefix(\"Hamburger\", \"hotdog\")\n\"Hamburger\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.chopsuffix","page":"Strings","title":"Base.chopsuffix","text":"chopsuffix(s::AbstractString, suffix::Union{AbstractString,Regex}) -> SubString\n\nRemove the suffix suffix from s. If s does not end with suffix, a string equal to s is returned.\n\nSee also chopprefix.\n\ncompat: Julia 1.8\nThis function is available as of Julia 1.8.\n\nExamples\n\njulia> chopsuffix(\"Hamburger\", \"er\")\n\"Hamburg\"\n\njulia> chopsuffix(\"Hamburger\", \"hotdog\")\n\"Hamburger\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.chomp","page":"Strings","title":"Base.chomp","text":"chomp(s::AbstractString) -> SubString\n\nRemove a single trailing newline from a string.\n\nSee also chop.\n\nExamples\n\njulia> chomp(\"Hello\\n\")\n\"Hello\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.thisind","page":"Strings","title":"Base.thisind","text":"thisind(s::AbstractString, i::Integer) -> Int\n\nIf i is in bounds in s return the index of the start of the character whose encoding code unit i is part of. In other words, if i is the start of a character, return i; if i is not the start of a character, rewind until the start of a character and return that index. If i is equal to 0 or ncodeunits(s)+1 return i. In all other cases throw BoundsError.\n\nExamples\n\njulia> thisind(\"α\", 0)\n0\n\njulia> thisind(\"α\", 1)\n1\n\njulia> thisind(\"α\", 2)\n1\n\njulia> thisind(\"α\", 3)\n3\n\njulia> thisind(\"α\", 4)\nERROR: BoundsError: attempt to access 2-codeunit String at index [4]\n[...]\n\njulia> thisind(\"α\", -1)\nERROR: BoundsError: attempt to access 2-codeunit String at index [-1]\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.nextind-Tuple{AbstractString, Integer, Integer}","page":"Strings","title":"Base.nextind","text":"nextind(str::AbstractString, i::Integer, n::Integer=1) -> Int\n\nCase n == 1\nIf i is in bounds in s return the index of the start of the character whose encoding starts after index i. In other words, if i is the start of a character, return the start of the next character; if i is not the start of a character, move forward until the start of a character and return that index. If i is equal to 0 return 1. If i is in bounds but greater or equal to lastindex(str) return ncodeunits(str)+1. Otherwise throw BoundsError.\nCase n > 1\nBehaves like applying n times nextind for n==1. The only difference is that if n is so large that applying nextind would reach ncodeunits(str)+1 then each remaining iteration increases the returned value by 1. This means that in this case nextind can return a value greater than ncodeunits(str)+1.\nCase n == 0\nReturn i only if i is a valid index in s or is equal to 0. Otherwise StringIndexError or BoundsError is thrown.\n\nExamples\n\njulia> nextind(\"α\", 0)\n1\n\njulia> nextind(\"α\", 1)\n3\n\njulia> nextind(\"α\", 3)\nERROR: BoundsError: attempt to access 2-codeunit String at index [3]\n[...]\n\njulia> nextind(\"α\", 0, 2)\n3\n\njulia> nextind(\"α\", 1, 2)\n4\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.prevind-Tuple{AbstractString, Integer, Integer}","page":"Strings","title":"Base.prevind","text":"prevind(str::AbstractString, i::Integer, n::Integer=1) -> Int\n\nCase n == 1\nIf i is in bounds in s return the index of the start of the character whose encoding starts before index i. In other words, if i is the start of a character, return the start of the previous character; if i is not the start of a character, rewind until the start of a character and return that index. If i is equal to 1 return 0. If i is equal to ncodeunits(str)+1 return lastindex(str). Otherwise throw BoundsError.\nCase n > 1\nBehaves like applying n times prevind for n==1. The only difference is that if n is so large that applying prevind would reach 0 then each remaining iteration decreases the returned value by 1. This means that in this case prevind can return a negative value.\nCase n == 0\nReturn i only if i is a valid index in str or is equal to ncodeunits(str)+1. Otherwise StringIndexError or BoundsError is thrown.\n\nExamples\n\njulia> prevind(\"α\", 3)\n1\n\njulia> prevind(\"α\", 1)\n0\n\njulia> prevind(\"α\", 0)\nERROR: BoundsError: attempt to access 2-codeunit String at index [0]\n[...]\n\njulia> prevind(\"α\", 2, 2)\n0\n\njulia> prevind(\"α\", 2, 3)\n-1\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.Unicode.textwidth","page":"Strings","title":"Base.Unicode.textwidth","text":"textwidth(c)\n\nGive the number of columns needed to print a character.\n\nExamples\n\njulia> textwidth('α')\n1\n\njulia> textwidth('⛵')\n2\n\n\n\n\n\ntextwidth(s::AbstractString)\n\nGive the number of columns needed to print a string.\n\nExamples\n\njulia> textwidth(\"March\")\n5\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.isascii","page":"Strings","title":"Base.isascii","text":"isascii(c::Union{AbstractChar,AbstractString}) -> Bool\n\nTest whether a character belongs to the ASCII character set, or whether this is true for all elements of a string.\n\nExamples\n\njulia> isascii('a')\ntrue\n\njulia> isascii('α')\nfalse\n\njulia> isascii(\"abc\")\ntrue\n\njulia> isascii(\"αβγ\")\nfalse\n\nFor example, isascii can be used as a predicate function for filter or replace to remove or replace non-ASCII characters, respectively:\n\njulia> filter(isascii, \"abcdeγfgh\") # discard non-ASCII chars\n\"abcdefgh\"\n\njulia> replace(\"abcdeγfgh\", !isascii=>' ') # replace non-ASCII chars with spaces\n\"abcde fgh\"\n\n\n\n\n\nisascii(cu::AbstractVector{CU}) where {CU <: Integer} -> Bool\n\nTest whether all values in the vector belong to the ASCII character set (0x00 to 0x7f). This function is intended to be used by other string implementations that need a fast ASCII check.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.iscntrl","page":"Strings","title":"Base.Unicode.iscntrl","text":"iscntrl(c::AbstractChar) -> Bool\n\nTests whether a character is a control character. Control characters are the non-printing characters of the Latin-1 subset of Unicode.\n\nExamples\n\njulia> iscntrl('\\x01')\ntrue\n\njulia> iscntrl('a')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isdigit","page":"Strings","title":"Base.Unicode.isdigit","text":"isdigit(c::AbstractChar) -> Bool\n\nTests whether a character is a decimal digit (0-9).\n\nSee also: isletter.\n\nExamples\n\njulia> isdigit('❤')\nfalse\n\njulia> isdigit('9')\ntrue\n\njulia> isdigit('α')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isletter","page":"Strings","title":"Base.Unicode.isletter","text":"isletter(c::AbstractChar) -> Bool\n\nTest whether a character is a letter. A character is classified as a letter if it belongs to the Unicode general category Letter, i.e. a character whose category code begins with 'L'.\n\nSee also: isdigit.\n\nExamples\n\njulia> isletter('❤')\nfalse\n\njulia> isletter('α')\ntrue\n\njulia> isletter('9')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.islowercase","page":"Strings","title":"Base.Unicode.islowercase","text":"islowercase(c::AbstractChar) -> Bool\n\nTests whether a character is a lowercase letter (according to the Unicode standard's Lowercase derived property).\n\nSee also isuppercase.\n\nExamples\n\njulia> islowercase('α')\ntrue\n\njulia> islowercase('Γ')\nfalse\n\njulia> islowercase('❤')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isnumeric","page":"Strings","title":"Base.Unicode.isnumeric","text":"isnumeric(c::AbstractChar) -> Bool\n\nTests whether a character is numeric. A character is classified as numeric if it belongs to the Unicode general category Number, i.e. a character whose category code begins with 'N'.\n\nNote that this broad category includes characters such as ¾ and ௰. Use isdigit to check whether a character is a decimal digit between 0 and 9.\n\nExamples\n\njulia> isnumeric('௰')\ntrue\n\njulia> isnumeric('9')\ntrue\n\njulia> isnumeric('α')\nfalse\n\njulia> isnumeric('❤')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isprint","page":"Strings","title":"Base.Unicode.isprint","text":"isprint(c::AbstractChar) -> Bool\n\nTests whether a character is printable, including spaces, but not a control character.\n\nExamples\n\njulia> isprint('\\x01')\nfalse\n\njulia> isprint('A')\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.ispunct","page":"Strings","title":"Base.Unicode.ispunct","text":"ispunct(c::AbstractChar) -> Bool\n\nTests whether a character belongs to the Unicode general category Punctuation, i.e. a character whose category code begins with 'P'.\n\nExamples\n\njulia> ispunct('α')\nfalse\n\njulia> ispunct('/')\ntrue\n\njulia> ispunct(';')\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isspace","page":"Strings","title":"Base.Unicode.isspace","text":"isspace(c::AbstractChar) -> Bool\n\nTests whether a character is any whitespace character. Includes ASCII characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' ', Latin-1 character U+0085, and characters in Unicode category Zs.\n\nExamples\n\njulia> isspace('\\n')\ntrue\n\njulia> isspace('\\r')\ntrue\n\njulia> isspace(' ')\ntrue\n\njulia> isspace('\\x20')\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isuppercase","page":"Strings","title":"Base.Unicode.isuppercase","text":"isuppercase(c::AbstractChar) -> Bool\n\nTests whether a character is an uppercase letter (according to the Unicode standard's Uppercase derived property).\n\nSee also islowercase.\n\nExamples\n\njulia> isuppercase('γ')\nfalse\n\njulia> isuppercase('Γ')\ntrue\n\njulia> isuppercase('❤')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isxdigit","page":"Strings","title":"Base.Unicode.isxdigit","text":"isxdigit(c::AbstractChar) -> Bool\n\nTest whether a character is a valid hexadecimal digit. Note that this does not include x (as in the standard 0x prefix).\n\nExamples\n\njulia> isxdigit('a')\ntrue\n\njulia> isxdigit('x')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.escape_string","page":"Strings","title":"Base.escape_string","text":"escape_string(str::AbstractString[, esc]; keep = ())::AbstractString\nescape_string(io, str::AbstractString[, esc]; keep = ())::Nothing\n\nGeneral escaping of traditional C and Unicode escape sequences. The first form returns the escaped string, the second prints the result to io.\n\nBackslashes (\\) are escaped with a double-backslash (\"\\\\\"). Non-printable characters are escaped either with their standard C escape codes, \"\\0\" for NUL (if unambiguous), unicode code point (\"\\u\" prefix) or hex (\"\\x\" prefix).\n\nThe optional esc argument specifies any additional characters that should also be escaped by a prepending backslash (\" is also escaped by default in the first form).\n\nThe argument keep specifies a collection of characters which are to be kept as they are. Notice that esc has precedence here.\n\nSee also unescape_string for the reverse operation.\n\ncompat: Julia 1.7\nThe keep argument is available as of Julia 1.7.\n\nExamples\n\njulia> escape_string(\"aaa\\nbbb\")\n\"aaa\\\\nbbb\"\n\njulia> escape_string(\"aaa\\nbbb\"; keep = '\\n')\n\"aaa\\nbbb\"\n\njulia> escape_string(\"\\xfe\\xff\") # invalid utf-8\n\"\\\\xfe\\\\xff\"\n\njulia> escape_string(string('\\u2135','\\0')) # unambiguous\n\"ℵ\\\\0\"\n\njulia> escape_string(string('\\u2135','\\0','0')) # \\0 would be ambiguous\n\"ℵ\\\\x000\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.escape_raw_string","page":"Strings","title":"Base.escape_raw_string","text":"escape_raw_string(s::AbstractString, delim='\"') -> AbstractString\nescape_raw_string(io, s::AbstractString, delim='\"')\n\nEscape a string in the manner used for parsing raw string literals. For each double-quote (\") character in input string s (or delim if specified), this function counts the number n of preceding backslash (\\) characters, and then increases there the number of backslashes from n to 2n+1 (even for n = 0). It also doubles a sequence of backslashes at the end of the string.\n\nThis escaping convention is used in raw strings and other non-standard string literals. (It also happens to be the escaping convention expected by the Microsoft C/C++ compiler runtime when it parses a command-line string into the argv[] array.)\n\nSee also escape_string.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.unescape_string","page":"Strings","title":"Base.unescape_string","text":"unescape_string(str::AbstractString, keep = ())::AbstractString\nunescape_string(io, s::AbstractString, keep = ())::Nothing\n\nGeneral unescaping of traditional C and Unicode escape sequences. The first form returns the escaped string, the second prints the result to io. The argument keep specifies a collection of characters which (along with backlashes) are to be kept as they are.\n\nThe following escape sequences are recognised:\n\nEscaped backslash (\\\\)\nEscaped double-quote (\\\")\nStandard C escape sequences (\\a, \\b, \\t, \\n, \\v, \\f, \\r, \\e)\nUnicode BMP code points (\\u with 1-4 trailing hex digits)\nAll Unicode code points (\\U with 1-8 trailing hex digits; max value = 0010ffff)\nHex bytes (\\x with 1-2 trailing hex digits)\nOctal bytes (\\ with 1-3 trailing octal digits)\n\nSee also escape_string.\n\nExamples\n\njulia> unescape_string(\"aaa\\\\nbbb\") # C escape sequence\n\"aaa\\nbbb\"\n\njulia> unescape_string(\"\\\\u03c0\") # unicode\n\"π\"\n\njulia> unescape_string(\"\\\\101\") # octal\n\"A\"\n\njulia> unescape_string(\"aaa \\\\g \\\\n\", ['g']) # using `keep` argument\n\"aaa \\\\g \\n\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/","page":"Dynamic Linker","title":"Dynamic Linker","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Libdl/docs/src/index.md\"","category":"page"},{"location":"stdlib/Libdl/","page":"Dynamic Linker","title":"Dynamic Linker","text":"Libdl","category":"page"},{"location":"stdlib/Libdl/#Libdl","page":"Dynamic Linker","title":"Libdl","text":"The Libdl module in Julia provides specialized and lower-level facilities for dynamic linking with shared libraries. While Julia inherently supports linking to runtime shared libraries through the ccall intrinsic, Libdl extends this capability by offering additional, more granular control. It enables users to search for shared libraries both in memory and the filesystem, manually load them with specific runtime linker options, and look up library symbols as low-level pointers.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Libdl/#Dynamic-Linker","page":"Dynamic Linker","title":"Dynamic Linker","text":"","category":"section"},{"location":"stdlib/Libdl/","page":"Dynamic Linker","title":"Dynamic Linker","text":"Libdl.dlopen\nLibdl.dlopen_e\nLibdl.RTLD_NOW\nLibdl.dlsym\nLibdl.dlsym_e\nLibdl.dlclose\nLibdl.dlext\nLibdl.dllist\nLibdl.dlpath\nLibdl.find_library\nLibdl.DL_LOAD_PATH","category":"page"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlopen","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlopen","text":"dlopen(libfile::AbstractString [, flags::Integer]; throw_error:Bool = true)\n\nLoad a shared library, returning an opaque handle.\n\nThe extension given by the constant dlext (.so, .dll, or .dylib) can be omitted from the libfile string, as it is automatically appended if needed. If libfile is not an absolute path name, then the paths in the array DL_LOAD_PATH are searched for libfile, followed by the system load path.\n\nThe optional flags argument is a bitwise-or of zero or more of RTLD_LOCAL, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, and RTLD_FIRST. These are converted to the corresponding flags of the POSIX (and/or GNU libc and/or MacOS) dlopen command, if possible, or are ignored if the specified functionality is not available on the current platform. The default flags are platform specific. On MacOS the default dlopen flags are RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL while on other platforms the defaults are RTLD_LAZY|RTLD_DEEPBIND|RTLD_LOCAL. An important usage of these flags is to specify non default behavior for when the dynamic library loader binds library references to exported symbols and if the bound references are put into process local or global scope. For instance RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL allows the library's symbols to be available for usage in other shared libraries, addressing situations where there are dependencies between shared libraries.\n\nIf the library cannot be found, this method throws an error, unless the keyword argument throw_error is set to false, in which case this method returns nothing.\n\nnote: Note\nFrom Julia 1.6 on, this method replaces paths starting with @executable_path/ with the path to the Julia executable, allowing for relocatable relative-path loads. In Julia 1.5 and earlier, this only worked on macOS.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlopen_e","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlopen_e","text":"dlopen_e(libfile::AbstractString [, flags::Integer])\n\nSimilar to dlopen, except returns C_NULL instead of raising errors. This method is now deprecated in favor of dlopen(libfile::AbstractString [, flags::Integer]; throw_error=false).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.RTLD_NOW","page":"Dynamic Linker","title":"Base.Libc.Libdl.RTLD_NOW","text":"RTLD_DEEPBIND\nRTLD_FIRST\nRTLD_GLOBAL\nRTLD_LAZY\nRTLD_LOCAL\nRTLD_NODELETE\nRTLD_NOLOAD\nRTLD_NOW\n\nEnum constant for dlopen. See your platform man page for details, if applicable.\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlsym","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlsym","text":"dlsym(handle, sym; throw_error::Bool = true)\n\nLook up a symbol from a shared library handle, return callable function pointer on success.\n\nIf the symbol cannot be found, this method throws an error, unless the keyword argument throw_error is set to false, in which case this method returns nothing.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlsym_e","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlsym_e","text":"dlsym_e(handle, sym)\n\nLook up a symbol from a shared library handle, silently return C_NULL on lookup failure. This method is now deprecated in favor of dlsym(handle, sym; throw_error=false).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlclose","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlclose","text":"dlclose(handle)\n\nClose shared library referenced by handle.\n\n\n\n\n\ndlclose(::Nothing)\n\nFor the very common pattern usage pattern of\n\ntry\n hdl = dlopen(library_name)\n ... do something\nfinally\n dlclose(hdl)\nend\n\nWe define a dlclose() method that accepts a parameter of type Nothing, so that user code does not have to change its behavior for the case that library_name was not found.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlext","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlext","text":"dlext\n\nFile extension for dynamic libraries (e.g. dll, dylib, so) on the current platform.\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dllist","page":"Dynamic Linker","title":"Base.Libc.Libdl.dllist","text":"dllist()\n\nReturn the paths of dynamic libraries currently loaded in a Vector{String}.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlpath","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlpath","text":"dlpath(handle::Ptr{Cvoid})\n\nGiven a library handle from dlopen, return the full path.\n\n\n\n\n\ndlpath(libname::Union{AbstractString, Symbol})\n\nGet the full path of the library libname.\n\nExamples\n\njulia> dlpath(\"libjulia\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.find_library","page":"Dynamic Linker","title":"Base.Libc.Libdl.find_library","text":"find_library(names [, locations])\n\nSearches for the first library in names in the paths in the locations list, DL_LOAD_PATH, or system library paths (in that order) which can successfully be dlopen'd. On success, the return value will be one of the names (potentially prefixed by one of the paths in locations). This string can be assigned to a global const and used as the library name in future ccall's. On failure, it returns the empty string.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.DL_LOAD_PATH","page":"Dynamic Linker","title":"Base.DL_LOAD_PATH","text":"DL_LOAD_PATH\n\nWhen calling dlopen, the paths in this list will be searched first, in order, before searching the system locations for a valid library handle.\n\n\n\n\n\n","category":"constant"},{"location":"base/arrays/#lib-arrays","page":"Arrays","title":"Arrays","text":"","category":"section"},{"location":"base/arrays/#Constructors-and-Types","page":"Arrays","title":"Constructors and Types","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Core.AbstractArray\nBase.AbstractVector\nBase.AbstractMatrix\nBase.AbstractVecOrMat\nCore.Array\nCore.Array(::UndefInitializer, ::Any)\nCore.Array(::Nothing, ::Any)\nCore.Array(::Missing, ::Any)\nCore.UndefInitializer\nCore.undef\nBase.Vector\nBase.Vector(::UndefInitializer, ::Any)\nBase.Vector(::Nothing, ::Any)\nBase.Vector(::Missing, ::Any)\nBase.Matrix\nBase.Matrix(::UndefInitializer, ::Any, ::Any)\nBase.Matrix(::Nothing, ::Any, ::Any)\nBase.Matrix(::Missing, ::Any, ::Any)\nBase.VecOrMat\nCore.DenseArray\nBase.DenseVector\nBase.DenseMatrix\nBase.DenseVecOrMat\nBase.StridedArray\nBase.StridedVector\nBase.StridedMatrix\nBase.StridedVecOrMat\nBase.Memory\nBase.MemoryRef\nBase.Slices\nBase.RowSlices\nBase.ColumnSlices\nBase.getindex(::Type, ::Any...)\nBase.zeros\nBase.ones\nBase.BitArray\nBase.BitArray(::UndefInitializer, ::Integer...)\nBase.BitArray(::Any)\nBase.trues\nBase.falses\nBase.fill\nBase.fill!\nBase.empty\nBase.similar","category":"page"},{"location":"base/arrays/#Core.AbstractArray","page":"Arrays","title":"Core.AbstractArray","text":"AbstractArray{T,N}\n\nSupertype for N-dimensional arrays (or array-like types) with elements of type T. Array and other types are subtypes of this. See the manual section on the AbstractArray interface.\n\nSee also: AbstractVector, AbstractMatrix, eltype, ndims.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.AbstractVector","page":"Arrays","title":"Base.AbstractVector","text":"AbstractVector{T}\n\nSupertype for one-dimensional arrays (or array-like types) with elements of type T. Alias for AbstractArray{T,1}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.AbstractMatrix","page":"Arrays","title":"Base.AbstractMatrix","text":"AbstractMatrix{T}\n\nSupertype for two-dimensional arrays (or array-like types) with elements of type T. Alias for AbstractArray{T,2}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.AbstractVecOrMat","page":"Arrays","title":"Base.AbstractVecOrMat","text":"AbstractVecOrMat{T}\n\nUnion type of AbstractVector{T} and AbstractMatrix{T}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.Array","page":"Arrays","title":"Core.Array","text":"Array{T,N} <: AbstractArray{T,N}\n\nN-dimensional dense array with elements of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.Array-Tuple{UndefInitializer, Any}","page":"Arrays","title":"Core.Array","text":"Array{T}(undef, dims)\nArray{T,N}(undef, dims)\n\nConstruct an uninitialized N-dimensional Array containing elements of type T. N can either be supplied explicitly, as in Array{T,N}(undef, dims), or be determined by the length or number of dims. dims may be a tuple or a series of integer arguments corresponding to the lengths in each dimension. If the rank N is supplied explicitly, then it must match the length or number of dims. Here undef is the UndefInitializer.\n\nExamples\n\njulia> A = Array{Float64, 2}(undef, 2, 3) # N given explicitly\n2×3 Matrix{Float64}:\n 6.90198e-310 6.90198e-310 6.90198e-310\n 6.90198e-310 6.90198e-310 0.0\n\njulia> B = Array{Float64}(undef, 4) # N determined by the input\n4-element Vector{Float64}:\n 2.360075077e-314\n NaN\n 2.2671131793e-314\n 2.299821756e-314\n\njulia> similar(B, 2, 4, 1) # use typeof(B), and the given size\n2×4×1 Array{Float64, 3}:\n[:, :, 1] =\n 2.26703e-314 2.26708e-314 0.0 2.80997e-314\n 0.0 2.26703e-314 2.26708e-314 0.0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Core.Array-Tuple{Nothing, Any}","page":"Arrays","title":"Core.Array","text":"Array{T}(nothing, dims)\nArray{T,N}(nothing, dims)\n\nConstruct an N-dimensional Array containing elements of type T, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.\n\nExamples\n\njulia> Array{Union{Nothing, String}}(nothing, 2)\n2-element Vector{Union{Nothing, String}}:\n nothing\n nothing\n\njulia> Array{Union{Nothing, Int}}(nothing, 2, 3)\n2×3 Matrix{Union{Nothing, Int64}}:\n nothing nothing nothing\n nothing nothing nothing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Core.Array-Tuple{Missing, Any}","page":"Arrays","title":"Core.Array","text":"Array{T}(missing, dims)\nArray{T,N}(missing, dims)\n\nConstruct an N-dimensional Array containing elements of type T, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.\n\nExamples\n\njulia> Array{Union{Missing, String}}(missing, 2)\n2-element Vector{Union{Missing, String}}:\n missing\n missing\n\njulia> Array{Union{Missing, Int}}(missing, 2, 3)\n2×3 Matrix{Union{Missing, Int64}}:\n missing missing missing\n missing missing missing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Core.UndefInitializer","page":"Arrays","title":"Core.UndefInitializer","text":"UndefInitializer\n\nSingleton type used in array initialization, indicating the array-constructor-caller would like an uninitialized array. See also undef, an alias for UndefInitializer().\n\nExamples\n\njulia> Array{Float64, 1}(UndefInitializer(), 3)\n3-element Array{Float64, 1}:\n 2.2752528595e-314\n 2.202942107e-314\n 2.275252907e-314\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.undef","page":"Arrays","title":"Core.undef","text":"undef\n\nAlias for UndefInitializer(), which constructs an instance of the singleton type UndefInitializer, used in array initialization to indicate the array-constructor-caller would like an uninitialized array.\n\nSee also: missing, similar.\n\nExamples\n\njulia> Array{Float64, 1}(undef, 3)\n3-element Vector{Float64}:\n 2.2752528595e-314\n 2.202942107e-314\n 2.275252907e-314\n\n\n\n\n\n","category":"constant"},{"location":"base/arrays/#Base.Vector","page":"Arrays","title":"Base.Vector","text":"Vector{T} <: AbstractVector{T}\n\nOne-dimensional dense array with elements of type T, often used to represent a mathematical vector. Alias for Array{T,1}.\n\nSee also empty, similar and zero for creating vectors.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Vector-Tuple{UndefInitializer, Any}","page":"Arrays","title":"Base.Vector","text":"Vector{T}(undef, n)\n\nConstruct an uninitialized Vector{T} of length n.\n\nExamples\n\njulia> Vector{Float64}(undef, 3)\n3-element Array{Float64, 1}:\n 6.90966e-310\n 6.90966e-310\n 6.90966e-310\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Vector-Tuple{Nothing, Any}","page":"Arrays","title":"Base.Vector","text":"Vector{T}(nothing, m)\n\nConstruct a Vector{T} of length m, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.\n\nExamples\n\njulia> Vector{Union{Nothing, String}}(nothing, 2)\n2-element Vector{Union{Nothing, String}}:\n nothing\n nothing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Vector-Tuple{Missing, Any}","page":"Arrays","title":"Base.Vector","text":"Vector{T}(missing, m)\n\nConstruct a Vector{T} of length m, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.\n\nExamples\n\njulia> Vector{Union{Missing, String}}(missing, 2)\n2-element Vector{Union{Missing, String}}:\n missing\n missing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Matrix","page":"Arrays","title":"Base.Matrix","text":"Matrix{T} <: AbstractMatrix{T}\n\nTwo-dimensional dense array with elements of type T, often used to represent a mathematical matrix. Alias for Array{T,2}.\n\nSee also fill, zeros, undef and similar for creating matrices.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Matrix-Tuple{UndefInitializer, Any, Any}","page":"Arrays","title":"Base.Matrix","text":"Matrix{T}(undef, m, n)\n\nConstruct an uninitialized Matrix{T} of size m×n.\n\nExamples\n\njulia> Matrix{Float64}(undef, 2, 3)\n2×3 Array{Float64, 2}:\n 2.36365e-314 2.28473e-314 5.0e-324\n 2.26704e-314 2.26711e-314 NaN\n\njulia> similar(ans, Int32, 2, 2)\n2×2 Matrix{Int32}:\n 490537216 1277177453\n 1 1936748399\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Matrix-Tuple{Nothing, Any, Any}","page":"Arrays","title":"Base.Matrix","text":"Matrix{T}(nothing, m, n)\n\nConstruct a Matrix{T} of size m×n, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.\n\nExamples\n\njulia> Matrix{Union{Nothing, String}}(nothing, 2, 3)\n2×3 Matrix{Union{Nothing, String}}:\n nothing nothing nothing\n nothing nothing nothing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Matrix-Tuple{Missing, Any, Any}","page":"Arrays","title":"Base.Matrix","text":"Matrix{T}(missing, m, n)\n\nConstruct a Matrix{T} of size m×n, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.\n\nExamples\n\njulia> Matrix{Union{Missing, String}}(missing, 2, 3)\n2×3 Matrix{Union{Missing, String}}:\n missing missing missing\n missing missing missing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.VecOrMat","page":"Arrays","title":"Base.VecOrMat","text":"VecOrMat{T}\n\nUnion type of Vector{T} and Matrix{T} which allows functions to accept either a Matrix or a Vector.\n\nExamples\n\njulia> Vector{Float64} <: VecOrMat{Float64}\ntrue\n\njulia> Matrix{Float64} <: VecOrMat{Float64}\ntrue\n\njulia> Array{Float64, 3} <: VecOrMat{Float64}\nfalse\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.DenseArray","page":"Arrays","title":"Core.DenseArray","text":"DenseArray{T, N} <: AbstractArray{T,N}\n\nN-dimensional dense array with elements of type T. The elements of a dense array are stored contiguously in memory.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.DenseVector","page":"Arrays","title":"Base.DenseVector","text":"DenseVector{T}\n\nOne-dimensional DenseArray with elements of type T. Alias for DenseArray{T,1}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.DenseMatrix","page":"Arrays","title":"Base.DenseMatrix","text":"DenseMatrix{T}\n\nTwo-dimensional DenseArray with elements of type T. Alias for DenseArray{T,2}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.DenseVecOrMat","page":"Arrays","title":"Base.DenseVecOrMat","text":"DenseVecOrMat{T}\n\nUnion type of DenseVector{T} and DenseMatrix{T}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.StridedArray","page":"Arrays","title":"Base.StridedArray","text":"StridedArray{T, N}\n\nA hard-coded Union of common array types that follow the strided array interface, with elements of type T and N dimensions.\n\nIf A is a StridedArray, then its elements are stored in memory with offsets, which may vary between dimensions but are constant within a dimension. For example, A could have stride 2 in dimension 1, and stride 3 in dimension 2. Incrementing A along dimension d jumps in memory by [stride(A, d)] slots. Strided arrays are particularly important and useful because they can sometimes be passed directly as pointers to foreign language libraries like BLAS.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.StridedVector","page":"Arrays","title":"Base.StridedVector","text":"StridedVector{T}\n\nOne dimensional StridedArray with elements of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.StridedMatrix","page":"Arrays","title":"Base.StridedMatrix","text":"StridedMatrix{T}\n\nTwo dimensional StridedArray with elements of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.StridedVecOrMat","page":"Arrays","title":"Base.StridedVecOrMat","text":"StridedVecOrMat{T}\n\nUnion type of StridedVector and StridedMatrix with elements of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.Memory","page":"Arrays","title":"Core.Memory","text":"Memory{T} == GenericMemory{:not_atomic, T, Core.CPU}\n\nOne-dimensional dense array with elements of type T.\n\ncompat: Julia 1.11\nThis type requires Julia 1.11 or later.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.MemoryRef","page":"Arrays","title":"Core.MemoryRef","text":"MemoryRef(memory)\n\nConstruct a MemoryRef from a memory object. This does not fail, but the resulting memory may point out-of-bounds if the memory is empty.\n\n\n\n\n\nMemoryRef(::Memory, index::Integer)\nMemoryRef(::MemoryRef, index::Integer)\n\nConstruct a MemoryRef from a memory object and an offset index (1-based) which can also be negative. This always returns an inbounds object, and will throw an error if that is not possible (because the index would result in a shift out-of-bounds of the underlying memory).\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Slices","page":"Arrays","title":"Base.Slices","text":"Slices{P,SM,AX,S,N} <: AbstractSlices{S,N}\n\nAn AbstractArray of slices into a parent array over specified dimension(s), returning views that select all the data from the other dimension(s).\n\nThese should typically be constructed by eachslice, eachcol or eachrow.\n\nparent(s::Slices) will return the parent array.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.RowSlices","page":"Arrays","title":"Base.RowSlices","text":"RowSlices{M,AX,S}\n\nA special case of Slices that is a vector of row slices of a matrix, as constructed by eachrow.\n\nparent can be used to get the underlying matrix.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.ColumnSlices","page":"Arrays","title":"Base.ColumnSlices","text":"ColumnSlices{M,AX,S}\n\nA special case of Slices that is a vector of column slices of a matrix, as constructed by eachcol.\n\nparent can be used to get the underlying matrix.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.getindex-Tuple{Type, Vararg{Any}}","page":"Arrays","title":"Base.getindex","text":"getindex(type[, elements...])\n\nConstruct a 1-d array of the specified type. This is usually called with the syntax Type[]. Element values can be specified using Type[a,b,c,...].\n\nExamples\n\njulia> Int8[1, 2, 3]\n3-element Vector{Int8}:\n 1\n 2\n 3\n\njulia> getindex(Int8, 1, 2, 3)\n3-element Vector{Int8}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.zeros","page":"Arrays","title":"Base.zeros","text":"zeros([T=Float64,] dims::Tuple)\nzeros([T=Float64,] dims...)\n\nCreate an Array, with element type T, of all zeros with size specified by dims. See also fill, ones, zero.\n\nExamples\n\njulia> zeros(1)\n1-element Vector{Float64}:\n 0.0\n\njulia> zeros(Int8, 2, 3)\n2×3 Matrix{Int8}:\n 0 0 0\n 0 0 0\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.ones","page":"Arrays","title":"Base.ones","text":"ones([T=Float64,] dims::Tuple)\nones([T=Float64,] dims...)\n\nCreate an Array, with element type T, of all ones with size specified by dims. See also fill, zeros.\n\nExamples\n\njulia> ones(1,2)\n1×2 Matrix{Float64}:\n 1.0 1.0\n\njulia> ones(ComplexF64, 2, 3)\n2×3 Matrix{ComplexF64}:\n 1.0+0.0im 1.0+0.0im 1.0+0.0im\n 1.0+0.0im 1.0+0.0im 1.0+0.0im\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.BitArray","page":"Arrays","title":"Base.BitArray","text":"BitArray{N} <: AbstractArray{Bool, N}\n\nSpace-efficient N-dimensional boolean array, using just one bit for each boolean value.\n\nBitArrays pack up to 64 values into every 8 bytes, resulting in an 8x space efficiency over Array{Bool, N} and allowing some operations to work on 64 values at once.\n\nBy default, Julia returns BitArrays from broadcasting operations that generate boolean elements (including dotted-comparisons like .==) as well as from the functions trues and falses.\n\nnote: Note\nDue to its packed storage format, concurrent access to the elements of a BitArray where at least one of them is a write is not thread-safe.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.BitArray-Tuple{UndefInitializer, Vararg{Integer}}","page":"Arrays","title":"Base.BitArray","text":"BitArray(undef, dims::Integer...)\nBitArray{N}(undef, dims::NTuple{N,Int})\n\nConstruct an undef BitArray with the given dimensions. Behaves identically to the Array constructor. See undef.\n\nExamples\n\njulia> BitArray(undef, 2, 2)\n2×2 BitMatrix:\n 0 0\n 0 0\n\njulia> BitArray(undef, (3, 1))\n3×1 BitMatrix:\n 0\n 0\n 0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.BitArray-Tuple{Any}","page":"Arrays","title":"Base.BitArray","text":"BitArray(itr)\n\nConstruct a BitArray generated by the given iterable object. The shape is inferred from the itr object.\n\nExamples\n\njulia> BitArray([1 0; 0 1])\n2×2 BitMatrix:\n 1 0\n 0 1\n\njulia> BitArray(x+y == 3 for x = 1:2, y = 1:3)\n2×3 BitMatrix:\n 0 1 0\n 1 0 0\n\njulia> BitArray(x+y == 3 for x = 1:2 for y = 1:3)\n6-element BitVector:\n 0\n 1\n 0\n 1\n 0\n 0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.trues","page":"Arrays","title":"Base.trues","text":"trues(dims)\n\nCreate a BitArray with all values set to true.\n\nExamples\n\njulia> trues(2,3)\n2×3 BitMatrix:\n 1 1 1\n 1 1 1\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.falses","page":"Arrays","title":"Base.falses","text":"falses(dims)\n\nCreate a BitArray with all values set to false.\n\nExamples\n\njulia> falses(2,3)\n2×3 BitMatrix:\n 0 0 0\n 0 0 0\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.fill","page":"Arrays","title":"Base.fill","text":"fill(value, dims::Tuple)\nfill(value, dims...)\n\nCreate an array of size dims with every location set to value.\n\nFor example, fill(1.0, (5,5)) returns a 5×5 array of floats, with 1.0 in every location of the array.\n\nThe dimension lengths dims may be specified as either a tuple or a sequence of arguments. An N-length tuple or N arguments following the value specify an N-dimensional array. Thus, a common idiom for creating a zero-dimensional array with its only location set to x is fill(x).\n\nEvery location of the returned array is set to (and is thus === to) the value that was passed; this means that if the value is itself modified, all elements of the filled array will reflect that modification because they're still that very value. This is of no concern with fill(1.0, (5,5)) as the value 1.0 is immutable and cannot itself be modified, but can be unexpected with mutable values like — most commonly — arrays. For example, fill([], 3) places the very same empty array in all three locations of the returned vector:\n\njulia> v = fill([], 3)\n3-element Vector{Vector{Any}}:\n []\n []\n []\n\njulia> v[1] === v[2] === v[3]\ntrue\n\njulia> value = v[1]\nAny[]\n\njulia> push!(value, 867_5309)\n1-element Vector{Any}:\n 8675309\n\njulia> v\n3-element Vector{Vector{Any}}:\n [8675309]\n [8675309]\n [8675309]\n\nTo create an array of many independent inner arrays, use a comprehension instead. This creates a new and distinct array on each iteration of the loop:\n\njulia> v2 = [[] for _ in 1:3]\n3-element Vector{Vector{Any}}:\n []\n []\n []\n\njulia> v2[1] === v2[2] === v2[3]\nfalse\n\njulia> push!(v2[1], 8675309)\n1-element Vector{Any}:\n 8675309\n\njulia> v2\n3-element Vector{Vector{Any}}:\n [8675309]\n []\n []\n\nSee also: fill!, zeros, ones, similar.\n\nExamples\n\njulia> fill(1.0, (2,3))\n2×3 Matrix{Float64}:\n 1.0 1.0 1.0\n 1.0 1.0 1.0\n\njulia> fill(42)\n0-dimensional Array{Int64, 0}:\n42\n\njulia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector\n2-element Vector{Vector{Float64}}:\n [0.0, 0.0]\n [0.0, 0.0]\n\njulia> A[1][1] = 42; # modifies the filled value to be [42.0, 0.0]\n\njulia> A # both A[1] and A[2] are the very same vector\n2-element Vector{Vector{Float64}}:\n [42.0, 0.0]\n [42.0, 0.0]\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.fill!","page":"Arrays","title":"Base.fill!","text":"fill!(A, x)\n\nFill array A with the value x. If x is an object reference, all elements will refer to the same object. fill!(A, Foo()) will return A filled with the result of evaluating Foo() once.\n\nExamples\n\njulia> A = zeros(2,3)\n2×3 Matrix{Float64}:\n 0.0 0.0 0.0\n 0.0 0.0 0.0\n\njulia> fill!(A, 2.)\n2×3 Matrix{Float64}:\n 2.0 2.0 2.0\n 2.0 2.0 2.0\n\njulia> a = [1, 1, 1]; A = fill!(Vector{Vector{Int}}(undef, 3), a); a[1] = 2; A\n3-element Vector{Vector{Int64}}:\n [2, 1, 1]\n [2, 1, 1]\n [2, 1, 1]\n\njulia> x = 0; f() = (global x += 1; x); fill!(Vector{Int}(undef, 3), f())\n3-element Vector{Int64}:\n 1\n 1\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.empty","page":"Arrays","title":"Base.empty","text":"empty(x::Tuple)\n\nReturn an empty tuple, ().\n\n\n\n\n\nempty(v::AbstractVector, [eltype])\n\nCreate an empty vector similar to v, optionally changing the eltype.\n\nSee also: empty!, isempty, isassigned.\n\nExamples\n\njulia> empty([1.0, 2.0, 3.0])\nFloat64[]\n\njulia> empty([1.0, 2.0, 3.0], String)\nString[]\n\n\n\n\n\nempty(a::AbstractDict, [index_type=keytype(a)], [value_type=valtype(a)])\n\nCreate an empty AbstractDict container which can accept indices of type index_type and values of type value_type. The second and third arguments are optional and default to the input's keytype and valtype, respectively. (If only one of the two types is specified, it is assumed to be the value_type, and the index_type we default to keytype(a)).\n\nCustom AbstractDict subtypes may choose which specific dictionary type is best suited to return for the given index and value types, by specializing on the three-argument signature. The default is to return an empty Dict.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.similar","page":"Arrays","title":"Base.similar","text":"similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}\n\nCreate an uninitialized mutable array with the given element type, index type, and size, based upon the given source SparseMatrixCSC. The new sparse matrix maintains the structure of the original sparse matrix, except in the case where dimensions of the output matrix are different from the output.\n\nThe output matrix has zeros in the same locations as the input, but uninitialized values for the nonzero locations.\n\n\n\n\n\nsimilar(array, [element_type=eltype(array)], [dims=size(array)])\n\nCreate an uninitialized mutable array with the given element type and size, based upon the given source array. The second and third arguments are both optional, defaulting to the given array's eltype and size. The dimensions may be specified either as a single tuple argument or as a series of integer arguments.\n\nCustom AbstractArray subtypes may choose which specific array type is best-suited to return for the given element type and dimensionality. If they do not specialize this method, the default is an Array{element_type}(undef, dims...).\n\nFor example, similar(1:10, 1, 4) returns an uninitialized Array{Int,2} since ranges are neither mutable nor support 2 dimensions:\n\njulia> similar(1:10, 1, 4)\n1×4 Matrix{Int64}:\n 4419743872 4374413872 4419743888 0\n\nConversely, similar(trues(10,10), 2) returns an uninitialized BitVector with two elements since BitArrays are both mutable and can support 1-dimensional arrays:\n\njulia> similar(trues(10,10), 2)\n2-element BitVector:\n 0\n 0\n\nSince BitArrays can only store elements of type Bool, however, if you request a different element type it will create a regular Array instead:\n\njulia> similar(falses(10), Float64, 2, 4)\n2×4 Matrix{Float64}:\n 2.18425e-314 2.18425e-314 2.18425e-314 2.18425e-314\n 2.18425e-314 2.18425e-314 2.18425e-314 2.18425e-314\n\nSee also: undef, isassigned.\n\n\n\n\n\nsimilar(storagetype, axes)\n\nCreate an uninitialized mutable array analogous to that specified by storagetype, but with axes specified by the last argument.\n\nExamples:\n\nsimilar(Array{Int}, axes(A))\n\ncreates an array that \"acts like\" an Array{Int} (and might indeed be backed by one), but which is indexed identically to A. If A has conventional indexing, this will be identical to Array{Int}(undef, size(A)), but if A has unconventional indexing then the indices of the result will match A.\n\nsimilar(BitArray, (axes(A, 2),))\n\nwould create a 1-dimensional logical array whose indices match those of the columns of A.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Basic-functions","page":"Arrays","title":"Basic functions","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.ndims\nBase.size\nBase.axes(::Any)\nBase.axes(::AbstractArray, ::Any)\nBase.length(::AbstractArray)\nBase.keys(::AbstractArray)\nBase.eachindex\nBase.IndexStyle\nBase.IndexLinear\nBase.IndexCartesian\nBase.conj!\nBase.stride\nBase.strides","category":"page"},{"location":"base/arrays/#Base.ndims","page":"Arrays","title":"Base.ndims","text":"ndims(A::AbstractArray) -> Integer\n\nReturn the number of dimensions of A.\n\nSee also: size, axes.\n\nExamples\n\njulia> A = fill(1, (3,4,5));\n\njulia> ndims(A)\n3\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.size","page":"Arrays","title":"Base.size","text":"size(A::AbstractArray, [dim])\n\nReturn a tuple containing the dimensions of A. Optionally you can specify a dimension to just get the length of that dimension.\n\nNote that size may not be defined for arrays with non-standard indices, in which case axes may be useful. See the manual chapter on arrays with custom indices.\n\nSee also: length, ndims, eachindex, sizeof.\n\nExamples\n\njulia> A = fill(1, (2,3,4));\n\njulia> size(A)\n(2, 3, 4)\n\njulia> size(A, 2)\n3\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.axes-Tuple{Any}","page":"Arrays","title":"Base.axes","text":"axes(A)\n\nReturn the tuple of valid indices for array A.\n\nSee also: size, keys, eachindex.\n\nExamples\n\njulia> A = fill(1, (5,6,7));\n\njulia> axes(A)\n(Base.OneTo(5), Base.OneTo(6), Base.OneTo(7))\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.axes-Tuple{AbstractArray, Any}","page":"Arrays","title":"Base.axes","text":"axes(A, d)\n\nReturn the valid range of indices for array A along dimension d.\n\nSee also size, and the manual chapter on arrays with custom indices.\n\nExamples\n\njulia> A = fill(1, (5,6,7));\n\njulia> axes(A, 2)\nBase.OneTo(6)\n\njulia> axes(A, 4) == 1:1 # all dimensions d > ndims(A) have size 1\ntrue\n\nUsage note\n\nEach of the indices has to be an AbstractUnitRange{<:Integer}, but at the same time can be a type that uses custom indices. So, for example, if you need a subset, use generalized indexing constructs like begin/end or firstindex/lastindex:\n\nix = axes(v, 1)\nix[2:end] # will work for eg Vector, but may fail in general\nix[(begin+1):end] # works for generalized indexes\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.length-Tuple{AbstractArray}","page":"Arrays","title":"Base.length","text":"length(A::AbstractArray)\n\nReturn the number of elements in the array, defaults to prod(size(A)).\n\nExamples\n\njulia> length([1, 2, 3, 4])\n4\n\njulia> length([1 2; 3 4])\n4\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.keys-Tuple{AbstractArray}","page":"Arrays","title":"Base.keys","text":"keys(a::AbstractArray)\n\nReturn an efficient array describing all valid indices for a arranged in the shape of a itself.\n\nThe keys of 1-dimensional arrays (vectors) are integers, whereas all other N-dimensional arrays use CartesianIndex to describe their locations. Often the special array types LinearIndices and CartesianIndices are used to efficiently represent these arrays of integers and CartesianIndexes, respectively.\n\nNote that the keys of an array might not be the most efficient index type; for maximum performance use eachindex instead.\n\nExamples\n\njulia> keys([4, 5, 6])\n3-element LinearIndices{1, Tuple{Base.OneTo{Int64}}}:\n 1\n 2\n 3\n\njulia> keys([4 5; 6 7])\nCartesianIndices((2, 2))\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.eachindex","page":"Arrays","title":"Base.eachindex","text":"eachindex(A...)\neachindex(::IndexStyle, A::AbstractArray...)\n\nCreate an iterable object for visiting each index of an AbstractArray A in an efficient manner. For array types that have opted into fast linear indexing (like Array), this is simply the range 1:length(A) if they use 1-based indexing. For array types that have not opted into fast linear indexing, a specialized Cartesian range is typically returned to efficiently index into the array with indices specified for every dimension.\n\nIn general eachindex accepts arbitrary iterables, including strings and dictionaries, and returns an iterator object supporting arbitrary index types (e.g. unevenly spaced or non-integer indices).\n\nIf A is AbstractArray it is possible to explicitly specify the style of the indices that should be returned by eachindex by passing a value having IndexStyle type as its first argument (typically IndexLinear() if linear indices are required or IndexCartesian() if Cartesian range is wanted).\n\nIf you supply more than one AbstractArray argument, eachindex will create an iterable object that is fast for all arguments (typically a UnitRange if all inputs have fast linear indexing, a CartesianIndices otherwise). If the arrays have different sizes and/or dimensionalities, a DimensionMismatch exception will be thrown.\n\nSee also pairs(A) to iterate over indices and values together, and axes(A, 2) for valid indices along one dimension.\n\nExamples\n\njulia> A = [10 20; 30 40];\n\njulia> for i in eachindex(A) # linear indexing\n println(\"A[\", i, \"] == \", A[i])\n end\nA[1] == 10\nA[2] == 30\nA[3] == 20\nA[4] == 40\n\njulia> for i in eachindex(view(A, 1:2, 1:1)) # Cartesian indexing\n println(i)\n end\nCartesianIndex(1, 1)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.IndexStyle","page":"Arrays","title":"Base.IndexStyle","text":"IndexStyle(A)\nIndexStyle(typeof(A))\n\nIndexStyle specifies the \"native indexing style\" for array A. When you define a new AbstractArray type, you can choose to implement either linear indexing (with IndexLinear) or cartesian indexing. If you decide to only implement linear indexing, then you must set this trait for your array type:\n\nBase.IndexStyle(::Type{<:MyArray}) = IndexLinear()\n\nThe default is IndexCartesian().\n\nJulia's internal indexing machinery will automatically (and invisibly) recompute all indexing operations into the preferred style. This allows users to access elements of your array using any indexing style, even when explicit methods have not been provided.\n\nIf you define both styles of indexing for your AbstractArray, this trait can be used to select the most performant indexing style. Some methods check this trait on their inputs, and dispatch to different algorithms depending on the most efficient access pattern. In particular, eachindex creates an iterator whose type depends on the setting of this trait.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.IndexLinear","page":"Arrays","title":"Base.IndexLinear","text":"IndexLinear()\n\nSubtype of IndexStyle used to describe arrays which are optimally indexed by one linear index.\n\nA linear indexing style uses one integer index to describe the position in the array (even if it's a multidimensional array) and column-major ordering is used to efficiently access the elements. This means that requesting eachindex from an array that is IndexLinear will return a simple one-dimensional range, even if it is multidimensional.\n\nA custom array that reports its IndexStyle as IndexLinear only needs to implement indexing (and indexed assignment) with a single Int index; all other indexing expressions — including multidimensional accesses — will be recomputed to the linear index. For example, if A were a 2×3 custom matrix with linear indexing, and we referenced A[1, 3], this would be recomputed to the equivalent linear index and call A[5] since 1 + 2*(3 - 1) = 5.\n\nSee also IndexCartesian.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.IndexCartesian","page":"Arrays","title":"Base.IndexCartesian","text":"IndexCartesian()\n\nSubtype of IndexStyle used to describe arrays which are optimally indexed by a Cartesian index. This is the default for new custom AbstractArray subtypes.\n\nA Cartesian indexing style uses multiple integer indices to describe the position in a multidimensional array, with exactly one index per dimension. This means that requesting eachindex from an array that is IndexCartesian will return a range of CartesianIndices.\n\nA N-dimensional custom array that reports its IndexStyle as IndexCartesian needs to implement indexing (and indexed assignment) with exactly N Int indices; all other indexing expressions — including linear indexing — will be recomputed to the equivalent Cartesian location. For example, if A were a 2×3 custom matrix with cartesian indexing, and we referenced A[5], this would be recomputed to the equivalent Cartesian index and call A[1, 3] since 5 = 1 + 2*(3 - 1).\n\nIt is significantly more expensive to compute Cartesian indices from a linear index than it is to go the other way. The former operation requires division — a very costly operation — whereas the latter only uses multiplication and addition and is essentially free. This asymmetry means it is far more costly to use linear indexing with an IndexCartesian array than it is to use Cartesian indexing with an IndexLinear array.\n\nSee also IndexLinear.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.conj!","page":"Arrays","title":"Base.conj!","text":"conj!(A)\n\nTransform an array to its complex conjugate in-place.\n\nSee also conj.\n\nExamples\n\njulia> A = [1+im 2-im; 2+2im 3+im]\n2×2 Matrix{Complex{Int64}}:\n 1+1im 2-1im\n 2+2im 3+1im\n\njulia> conj!(A);\n\njulia> A\n2×2 Matrix{Complex{Int64}}:\n 1-1im 2+1im\n 2-2im 3-1im\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.stride","page":"Arrays","title":"Base.stride","text":"stride(A, k::Integer)\n\nReturn the distance in memory (in number of elements) between adjacent elements in dimension k.\n\nSee also: strides.\n\nExamples\n\njulia> A = fill(1, (3,4,5));\n\njulia> stride(A,2)\n3\n\njulia> stride(A,3)\n12\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.strides","page":"Arrays","title":"Base.strides","text":"strides(A)\n\nReturn a tuple of the memory strides in each dimension.\n\nSee also: stride.\n\nExamples\n\njulia> A = fill(1, (3,4,5));\n\njulia> strides(A)\n(1, 3, 12)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Broadcast-and-vectorization","page":"Arrays","title":"Broadcast and vectorization","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"See also the dot syntax for vectorizing functions; for example, f.(args...) implicitly calls broadcast(f, args...). Rather than relying on \"vectorized\" methods of functions like sin to operate on arrays, you should use sin.(a) to vectorize via broadcast.","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.broadcast\nBase.Broadcast.broadcast!\nBase.@__dot__","category":"page"},{"location":"base/arrays/#Base.Broadcast.broadcast","page":"Arrays","title":"Base.Broadcast.broadcast","text":"broadcast(f, As...)\n\nBroadcast the function f over the arrays, tuples, collections, Refs and/or scalars As.\n\nBroadcasting applies the function f over the elements of the container arguments and the scalars themselves in As. Singleton and missing dimensions are expanded to match the extents of the other arguments by virtually repeating the value. By default, only a limited number of types are considered scalars, including Numbers, Strings, Symbols, Types, Functions and some common singletons like missing and nothing. All other arguments are iterated over or indexed into elementwise.\n\nThe resulting container type is established by the following rules:\n\nIf all the arguments are scalars or zero-dimensional arrays, it returns an unwrapped scalar.\nIf at least one argument is a tuple and all others are scalars or zero-dimensional arrays, it returns a tuple.\nAll other combinations of arguments default to returning an Array, but custom container types can define their own implementation and promotion-like rules to customize the result when they appear as arguments.\n\nA special syntax exists for broadcasting: f.(args...) is equivalent to broadcast(f, args...), and nested f.(g.(args...)) calls are fused into a single broadcast loop.\n\nExamples\n\njulia> A = [1, 2, 3, 4, 5]\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n\njulia> B = [1 2; 3 4; 5 6; 7 8; 9 10]\n5×2 Matrix{Int64}:\n 1 2\n 3 4\n 5 6\n 7 8\n 9 10\n\njulia> broadcast(+, A, B)\n5×2 Matrix{Int64}:\n 2 3\n 5 6\n 8 9\n 11 12\n 14 15\n\njulia> parse.(Int, [\"1\", \"2\"])\n2-element Vector{Int64}:\n 1\n 2\n\njulia> abs.((1, -2))\n(1, 2)\n\njulia> broadcast(+, 1.0, (0, -2.0))\n(1.0, -1.0)\n\njulia> (+).([[0,2], [1,3]], Ref{Vector{Int}}([1,-1]))\n2-element Vector{Vector{Int64}}:\n [1, 1]\n [2, 2]\n\njulia> string.((\"one\",\"two\",\"three\",\"four\"), \": \", 1:4)\n4-element Vector{String}:\n \"one: 1\"\n \"two: 2\"\n \"three: 3\"\n \"four: 4\"\n\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.broadcast!","page":"Arrays","title":"Base.Broadcast.broadcast!","text":"broadcast!(f, dest, As...)\n\nLike broadcast, but store the result of broadcast(f, As...) in the dest array. Note that dest is only used to store the result, and does not supply arguments to f unless it is also listed in the As, as in broadcast!(f, A, A, B) to perform A[:] = broadcast(f, A, B).\n\nExamples\n\njulia> A = [1.0; 0.0]; B = [0.0; 0.0];\n\njulia> broadcast!(+, B, A, (0, -2.0));\n\njulia> B\n2-element Vector{Float64}:\n 1.0\n -2.0\n\njulia> A\n2-element Vector{Float64}:\n 1.0\n 0.0\n\njulia> broadcast!(+, A, A, (0, -2.0));\n\njulia> A\n2-element Vector{Float64}:\n 1.0\n -2.0\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.@__dot__","page":"Arrays","title":"Base.Broadcast.@__dot__","text":"@. expr\n\nConvert every function call or operator in expr into a \"dot call\" (e.g. convert f(x) to f.(x)), and convert every assignment in expr to a \"dot assignment\" (e.g. convert += to .+=).\n\nIf you want to avoid adding dots for selected function calls in expr, splice those function calls in with $. For example, @. sqrt(abs($sort(x))) is equivalent to sqrt.(abs.(sort(x))) (no dot for sort).\n\n(@. is equivalent to a call to @__dot__.)\n\nExamples\n\njulia> x = 1.0:3.0; y = similar(x);\n\njulia> @. y = x + 3 * sin(x)\n3-element Vector{Float64}:\n 3.5244129544236893\n 4.727892280477045\n 3.4233600241796016\n\n\n\n\n\n","category":"macro"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"For specializing broadcast on custom types, see","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.BroadcastStyle\nBase.Broadcast.AbstractArrayStyle\nBase.Broadcast.ArrayStyle\nBase.Broadcast.DefaultArrayStyle\nBase.Broadcast.broadcastable\nBase.Broadcast.combine_axes\nBase.Broadcast.combine_styles\nBase.Broadcast.result_style","category":"page"},{"location":"base/arrays/#Base.Broadcast.BroadcastStyle","page":"Arrays","title":"Base.Broadcast.BroadcastStyle","text":"BroadcastStyle is an abstract type and trait-function used to determine behavior of objects under broadcasting. BroadcastStyle(typeof(x)) returns the style associated with x. To customize the broadcasting behavior of a type, one can declare a style by defining a type/method pair\n\nstruct MyContainerStyle <: BroadcastStyle end\nBase.BroadcastStyle(::Type{<:MyContainer}) = MyContainerStyle()\n\nOne then writes method(s) (at least similar) operating on Broadcasted{MyContainerStyle}. There are also several pre-defined subtypes of BroadcastStyle that you may be able to leverage; see the Interfaces chapter for more information.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Broadcast.AbstractArrayStyle","page":"Arrays","title":"Base.Broadcast.AbstractArrayStyle","text":"Broadcast.AbstractArrayStyle{N} <: BroadcastStyle is the abstract supertype for any style associated with an AbstractArray type. The N parameter is the dimensionality, which can be handy for AbstractArray types that only support specific dimensionalities:\n\nstruct SparseMatrixStyle <: Broadcast.AbstractArrayStyle{2} end\nBase.BroadcastStyle(::Type{<:SparseMatrixCSC}) = SparseMatrixStyle()\n\nFor AbstractArray types that support arbitrary dimensionality, N can be set to Any:\n\nstruct MyArrayStyle <: Broadcast.AbstractArrayStyle{Any} end\nBase.BroadcastStyle(::Type{<:MyArray}) = MyArrayStyle()\n\nIn cases where you want to be able to mix multiple AbstractArrayStyles and keep track of dimensionality, your style needs to support a Val constructor:\n\nstruct MyArrayStyleDim{N} <: Broadcast.AbstractArrayStyle{N} end\n(::Type{<:MyArrayStyleDim})(::Val{N}) where N = MyArrayStyleDim{N}()\n\nNote that if two or more AbstractArrayStyle subtypes conflict, broadcasting machinery will fall back to producing Arrays. If this is undesirable, you may need to define binary BroadcastStyle rules to control the output type.\n\nSee also Broadcast.DefaultArrayStyle.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Broadcast.ArrayStyle","page":"Arrays","title":"Base.Broadcast.ArrayStyle","text":"Broadcast.ArrayStyle{MyArrayType}() is a BroadcastStyle indicating that an object behaves as an array for broadcasting. It presents a simple way to construct Broadcast.AbstractArrayStyles for specific AbstractArray container types. Broadcast styles created this way lose track of dimensionality; if keeping track is important for your type, you should create your own custom Broadcast.AbstractArrayStyle.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Broadcast.DefaultArrayStyle","page":"Arrays","title":"Base.Broadcast.DefaultArrayStyle","text":"Broadcast.DefaultArrayStyle{N}() is a BroadcastStyle indicating that an object behaves as an N-dimensional array for broadcasting. Specifically, DefaultArrayStyle is used for any AbstractArray type that hasn't defined a specialized style, and in the absence of overrides from other broadcast arguments the resulting output type is Array. When there are multiple inputs to broadcast, DefaultArrayStyle \"loses\" to any other Broadcast.ArrayStyle.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Broadcast.broadcastable","page":"Arrays","title":"Base.Broadcast.broadcastable","text":"Broadcast.broadcastable(x)\n\nReturn either x or an object like x such that it supports axes, indexing, and its type supports ndims.\n\nIf x supports iteration, the returned value should have the same axes and indexing behaviors as collect(x).\n\nIf x is not an AbstractArray but it supports axes, indexing, and its type supports ndims, then broadcastable(::typeof(x)) may be implemented to just return itself. Further, if x defines its own BroadcastStyle, then it must define its broadcastable method to return itself for the custom style to have any effect.\n\nExamples\n\njulia> Broadcast.broadcastable([1,2,3]) # like `identity` since arrays already support axes and indexing\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> Broadcast.broadcastable(Int) # Types don't support axes, indexing, or iteration but are commonly used as scalars\nBase.RefValue{Type{Int64}}(Int64)\n\njulia> Broadcast.broadcastable(\"hello\") # Strings break convention of matching iteration and act like a scalar instead\nBase.RefValue{String}(\"hello\")\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.combine_axes","page":"Arrays","title":"Base.Broadcast.combine_axes","text":"combine_axes(As...) -> Tuple\n\nDetermine the result axes for broadcasting across all values in As.\n\njulia> Broadcast.combine_axes([1], [1 2; 3 4; 5 6])\n(Base.OneTo(3), Base.OneTo(2))\n\njulia> Broadcast.combine_axes(1, 1, 1)\n()\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.combine_styles","page":"Arrays","title":"Base.Broadcast.combine_styles","text":"combine_styles(cs...) -> BroadcastStyle\n\nDecides which BroadcastStyle to use for any number of value arguments. Uses BroadcastStyle to get the style for each argument, and uses result_style to combine styles.\n\nExamples\n\njulia> Broadcast.combine_styles([1], [1 2; 3 4])\nBase.Broadcast.DefaultArrayStyle{2}()\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.result_style","page":"Arrays","title":"Base.Broadcast.result_style","text":"result_style(s1::BroadcastStyle[, s2::BroadcastStyle]) -> BroadcastStyle\n\nTakes one or two BroadcastStyles and combines them using BroadcastStyle to determine a common BroadcastStyle.\n\nExamples\n\njulia> Broadcast.result_style(Broadcast.DefaultArrayStyle{0}(), Broadcast.DefaultArrayStyle{3}())\nBase.Broadcast.DefaultArrayStyle{3}()\n\njulia> Broadcast.result_style(Broadcast.Unknown(), Broadcast.DefaultArrayStyle{1}())\nBase.Broadcast.DefaultArrayStyle{1}()\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Indexing-and-assignment","page":"Arrays","title":"Indexing and assignment","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.getindex(::AbstractArray, ::Any...)\nBase.setindex!(::AbstractArray, ::Any, ::Any...)\nBase.nextind\nBase.prevind\nBase.copyto!(::AbstractArray, ::CartesianIndices, ::AbstractArray, ::CartesianIndices)\nBase.copy!\nBase.isassigned\nBase.Colon\nBase.CartesianIndex\nBase.CartesianIndices\nBase.Dims\nBase.LinearIndices\nBase.to_indices\nBase.checkbounds\nBase.checkindex\nBase.elsize","category":"page"},{"location":"base/arrays/#Base.getindex-Tuple{AbstractArray, Vararg{Any}}","page":"Arrays","title":"Base.getindex","text":"getindex(A, inds...)\n\nReturn a subset of array A as selected by the indices inds.\n\nEach index may be any supported index type, such as an Integer, CartesianIndex, range, or array of supported indices. A : may be used to select all elements along a specific dimension, and a boolean array (e.g. an Array{Bool} or a BitArray) may be used to filter for elements where the corresponding index is true.\n\nWhen inds selects multiple elements, this function returns a newly allocated array. To index multiple elements without making a copy, use view instead.\n\nSee the manual section on array indexing for details.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> getindex(A, 1)\n1\n\njulia> getindex(A, [2, 1])\n2-element Vector{Int64}:\n 3\n 1\n\njulia> getindex(A, 2:4)\n3-element Vector{Int64}:\n 3\n 2\n 4\n\njulia> getindex(A, 2, 1)\n3\n\njulia> getindex(A, CartesianIndex(2, 1))\n3\n\njulia> getindex(A, :, 2)\n2-element Vector{Int64}:\n 2\n 4\n\njulia> getindex(A, 2, :)\n2-element Vector{Int64}:\n 3\n 4\n\njulia> getindex(A, A .> 2)\n2-element Vector{Int64}:\n 3\n 4\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.setindex!-Tuple{AbstractArray, Any, Vararg{Any}}","page":"Arrays","title":"Base.setindex!","text":"setindex!(A, X, inds...)\nA[inds...] = X\n\nStore values from array X within some subset of A as specified by inds. The syntax A[inds...] = X is equivalent to (setindex!(A, X, inds...); X).\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = zeros(2,2);\n\njulia> setindex!(A, [10, 20], [1, 2]);\n\njulia> A[[3, 4]] = [30, 40];\n\njulia> A\n2×2 Matrix{Float64}:\n 10.0 30.0\n 20.0 40.0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.nextind","page":"Arrays","title":"Base.nextind","text":"nextind(A, i)\n\nReturn the index after i in A. The returned index is often equivalent to `i\n\n1for an integeri`. This function can be useful for generic code.\n\nwarning: Warning\nThe returned index might be out of bounds. Consider using checkbounds.\n\nSee also: prevind.\n\nExamples\n\njulia> x = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> nextind(x, 1) # valid result\n2\n\njulia> nextind(x, 4) # invalid result\n5\n\njulia> nextind(x, CartesianIndex(1, 1)) # valid result\nCartesianIndex(2, 1)\n\njulia> nextind(x, CartesianIndex(2, 2)) # invalid result\nCartesianIndex(1, 3)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.prevind","page":"Arrays","title":"Base.prevind","text":"prevind(A, i)\n\nReturn the index before i in A. The returned index is often equivalent to `i\n\n1for an integeri`. This function can be useful for generic code.\n\nwarning: Warning\nThe returned index might be out of bounds. Consider using checkbounds.\n\nSee also: nextind.\n\nExamples\n\njulia> x = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> prevind(x, 4) # valid result\n3\n\njulia> prevind(x, 1) # invalid result\n0\n\njulia> prevind(x, CartesianIndex(2, 2)) # valid result\nCartesianIndex(1, 2)\n\njulia> prevind(x, CartesianIndex(1, 1)) # invalid result\nCartesianIndex(2, 0)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.copyto!-Tuple{AbstractArray, CartesianIndices, AbstractArray, CartesianIndices}","page":"Arrays","title":"Base.copyto!","text":"copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest\n\nCopy the block of src in the range of Rsrc to the block of dest in the range of Rdest. The sizes of the two regions must match.\n\nExamples\n\njulia> A = zeros(5, 5);\n\njulia> B = [1 2; 3 4];\n\njulia> Ainds = CartesianIndices((2:3, 2:3));\n\njulia> Binds = CartesianIndices(B);\n\njulia> copyto!(A, Ainds, B, Binds)\n5×5 Matrix{Float64}:\n 0.0 0.0 0.0 0.0 0.0\n 0.0 1.0 2.0 0.0 0.0\n 0.0 3.0 4.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.copy!","page":"Arrays","title":"Base.copy!","text":"copy!(dst, src) -> dst\n\nIn-place copy of src into dst, discarding any pre-existing elements in dst. If dst and src are of the same type, dst == src should hold after the call. If dst and src are multidimensional arrays, they must have equal axes.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also copyto!.\n\ncompat: Julia 1.1\nThis method requires at least Julia 1.1. In Julia 1.0 this method is available from the Future standard library as Future.copy!.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.isassigned","page":"Arrays","title":"Base.isassigned","text":"isassigned(array, i) -> Bool\n\nTest whether the given array has a value associated with index i. Return false if the index is out of bounds, or has an undefined reference.\n\nExamples\n\njulia> isassigned(rand(3, 3), 5)\ntrue\n\njulia> isassigned(rand(3, 3), 3 * 3 + 1)\nfalse\n\njulia> mutable struct Foo end\n\njulia> v = similar(rand(3), Foo)\n3-element Vector{Foo}:\n #undef\n #undef\n #undef\n\njulia> isassigned(v, 1)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Colon","page":"Arrays","title":"Base.Colon","text":"Colon()\n\nColons (:) are used to signify indexing entire objects or dimensions at once.\n\nVery few operations are defined on Colons directly; instead they are converted by to_indices to an internal vector type (Base.Slice) to represent the collection of indices they span before being used.\n\nThe singleton instance of Colon is also a function used to construct ranges; see :.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.IteratorsMD.CartesianIndex","page":"Arrays","title":"Base.IteratorsMD.CartesianIndex","text":"CartesianIndex(i, j, k...) -> I\nCartesianIndex((i, j, k...)) -> I\n\nCreate a multidimensional index I, which can be used for indexing a multidimensional array A. In particular, A[I] is equivalent to A[i,j,k...]. One can freely mix integer and CartesianIndex indices; for example, A[Ipre, i, Ipost] (where Ipre and Ipost are CartesianIndex indices and i is an Int) can be a useful expression when writing algorithms that work along a single dimension of an array of arbitrary dimensionality.\n\nA CartesianIndex is sometimes produced by eachindex, and always when iterating with an explicit CartesianIndices.\n\nAn I::CartesianIndex is treated as a \"scalar\" (not a container) for broadcast. In order to iterate over the components of a CartesianIndex, convert it to a tuple with Tuple(I).\n\nExamples\n\njulia> A = reshape(Vector(1:16), (2, 2, 2, 2))\n2×2×2×2 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 3\n 2 4\n\n[:, :, 2, 1] =\n 5 7\n 6 8\n\n[:, :, 1, 2] =\n 9 11\n 10 12\n\n[:, :, 2, 2] =\n 13 15\n 14 16\n\njulia> A[CartesianIndex((1, 1, 1, 1))]\n1\n\njulia> A[CartesianIndex((1, 1, 1, 2))]\n9\n\njulia> A[CartesianIndex((1, 1, 2, 1))]\n5\n\ncompat: Julia 1.10\nUsing a CartesianIndex as a \"scalar\" for broadcast requires Julia 1.10; in previous releases, use Ref(I).\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.IteratorsMD.CartesianIndices","page":"Arrays","title":"Base.IteratorsMD.CartesianIndices","text":"CartesianIndices(sz::Dims) -> R\nCartesianIndices((istart:[istep:]istop, jstart:[jstep:]jstop, ...)) -> R\n\nDefine a region R spanning a multidimensional rectangular range of integer indices. These are most commonly encountered in the context of iteration, where for I in R ... end will return CartesianIndex indices I equivalent to the nested loops\n\nfor j = jstart:jstep:jstop\n for i = istart:istep:istop\n ...\n end\nend\n\nConsequently these can be useful for writing algorithms that work in arbitrary dimensions.\n\nCartesianIndices(A::AbstractArray) -> R\n\nAs a convenience, constructing a CartesianIndices from an array makes a range of its indices.\n\ncompat: Julia 1.6\nThe step range method CartesianIndices((istart:istep:istop, jstart:[jstep:]jstop, ...)) requires at least Julia 1.6.\n\nExamples\n\njulia> foreach(println, CartesianIndices((2, 2, 2)))\nCartesianIndex(1, 1, 1)\nCartesianIndex(2, 1, 1)\nCartesianIndex(1, 2, 1)\nCartesianIndex(2, 2, 1)\nCartesianIndex(1, 1, 2)\nCartesianIndex(2, 1, 2)\nCartesianIndex(1, 2, 2)\nCartesianIndex(2, 2, 2)\n\njulia> CartesianIndices(fill(1, (2,3)))\nCartesianIndices((2, 3))\n\nConversion between linear and cartesian indices\n\nLinear index to cartesian index conversion exploits the fact that a CartesianIndices is an AbstractArray and can be indexed linearly:\n\njulia> cartesian = CartesianIndices((1:3, 1:2))\nCartesianIndices((1:3, 1:2))\n\njulia> cartesian[4]\nCartesianIndex(1, 2)\n\njulia> cartesian = CartesianIndices((1:2:5, 1:2))\nCartesianIndices((1:2:5, 1:2))\n\njulia> cartesian[2, 2]\nCartesianIndex(3, 2)\n\nBroadcasting\n\nCartesianIndices support broadcasting arithmetic (+ and -) with a CartesianIndex.\n\ncompat: Julia 1.1\nBroadcasting of CartesianIndices requires at least Julia 1.1.\n\njulia> CIs = CartesianIndices((2:3, 5:6))\nCartesianIndices((2:3, 5:6))\n\njulia> CI = CartesianIndex(3, 4)\nCartesianIndex(3, 4)\n\njulia> CIs .+ CI\nCartesianIndices((5:6, 9:10))\n\nFor cartesian to linear index conversion, see LinearIndices.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Dims","page":"Arrays","title":"Base.Dims","text":"Dims{N}\n\nAn NTuple of N Ints used to represent the dimensions of an AbstractArray.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.LinearIndices","page":"Arrays","title":"Base.LinearIndices","text":"LinearIndices(A::AbstractArray)\n\nReturn a LinearIndices array with the same shape and axes as A, holding the linear index of each entry in A. Indexing this array with cartesian indices allows mapping them to linear indices.\n\nFor arrays with conventional indexing (indices start at 1), or any multidimensional array, linear indices range from 1 to length(A). However, for AbstractVectors linear indices are axes(A, 1), and therefore do not start at 1 for vectors with unconventional indexing.\n\nCalling this function is the \"safe\" way to write algorithms that exploit linear indexing.\n\nExamples\n\njulia> A = fill(1, (5,6,7));\n\njulia> b = LinearIndices(A);\n\njulia> extrema(b)\n(1, 210)\n\nLinearIndices(inds::CartesianIndices) -> R\nLinearIndices(sz::Dims) -> R\nLinearIndices((istart:istop, jstart:jstop, ...)) -> R\n\nReturn a LinearIndices array with the specified shape or axes.\n\nExamples\n\nThe main purpose of this constructor is intuitive conversion from cartesian to linear indexing:\n\njulia> linear = LinearIndices((1:3, 1:2))\n3×2 LinearIndices{2, Tuple{UnitRange{Int64}, UnitRange{Int64}}}:\n 1 4\n 2 5\n 3 6\n\njulia> linear[1,2]\n4\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.to_indices","page":"Arrays","title":"Base.to_indices","text":"to_indices(A, I::Tuple)\n\nConvert the tuple I to a tuple of indices for use in indexing into array A.\n\nThe returned tuple must only contain either Ints or AbstractArrays of scalar indices that are supported by array A. It will error upon encountering a novel index type that it does not know how to process.\n\nFor simple index types, it defers to the unexported Base.to_index(A, i) to process each index i. While this internal function is not intended to be called directly, Base.to_index may be extended by custom array or index types to provide custom indexing behaviors.\n\nMore complicated index types may require more context about the dimension into which they index. To support those cases, to_indices(A, I) calls to_indices(A, axes(A), I), which then recursively walks through both the given tuple of indices and the dimensional indices of A in tandem. As such, not all index types are guaranteed to propagate to Base.to_index.\n\nExamples\n\njulia> A = zeros(1,2,3,4);\n\njulia> to_indices(A, (1,1,2,2))\n(1, 1, 2, 2)\n\njulia> to_indices(A, (1,1,2,20)) # no bounds checking\n(1, 1, 2, 20)\n\njulia> to_indices(A, (CartesianIndex((1,)), 2, CartesianIndex((3,4)))) # exotic index\n(1, 2, 3, 4)\n\njulia> to_indices(A, ([1,1], 1:2, 3, 4))\n([1, 1], 1:2, 3, 4)\n\njulia> to_indices(A, (1,2)) # no shape checking\n(1, 2)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.checkbounds","page":"Arrays","title":"Base.checkbounds","text":"checkbounds(Bool, A, I...)\n\nReturn true if the specified indices I are in bounds for the given array A. Subtypes of AbstractArray should specialize this method if they need to provide custom bounds checking behaviors; however, in many cases one can rely on A's indices and checkindex.\n\nSee also checkindex.\n\nExamples\n\njulia> A = rand(3, 3);\n\njulia> checkbounds(Bool, A, 2)\ntrue\n\njulia> checkbounds(Bool, A, 3, 4)\nfalse\n\njulia> checkbounds(Bool, A, 1:3)\ntrue\n\njulia> checkbounds(Bool, A, 1:3, 2:4)\nfalse\n\n\n\n\n\ncheckbounds(A, I...)\n\nThrow an error if the specified indices I are not in bounds for the given array A.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.checkindex","page":"Arrays","title":"Base.checkindex","text":"checkindex(Bool, inds::AbstractUnitRange, index)\n\nReturn true if the given index is within the bounds of inds. Custom types that would like to behave as indices for all arrays can extend this method in order to provide a specialized bounds checking implementation.\n\nSee also checkbounds.\n\nExamples\n\njulia> checkindex(Bool, 1:20, 8)\ntrue\n\njulia> checkindex(Bool, 1:20, 21)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.elsize","page":"Arrays","title":"Base.elsize","text":"elsize(type)\n\nCompute the memory stride in bytes between consecutive elements of eltype stored inside the given type, if the array elements are stored densely with a uniform linear stride.\n\nExamples\n\njulia> Base.elsize(rand(Float32, 10))\n4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Views-(SubArrays-and-other-view-types)","page":"Arrays","title":"Views (SubArrays and other view types)","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"A “view” is a data structure that acts like an array (it is a subtype of AbstractArray), but the underlying data is actually part of another array.","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"For example, if x is an array and v = @view x[1:10], then v acts like a 10-element array, but its data is actually accessing the first 10 elements of x. Writing to a view, e.g. v[3] = 2, writes directly to the underlying array x (in this case modifying x[3]).","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Slicing operations like x[1:10] create a copy by default in Julia. @view x[1:10] changes it to make a view. The @views macro can be used on a whole block of code (e.g. @views function foo() .... end or @views begin ... end) to change all the slicing operations in that block to use views. Sometimes making a copy of the data is faster and sometimes using a view is faster, as described in the performance tips.","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.view\nBase.@view\nBase.@views\nBase.parent\nBase.parentindices\nBase.selectdim\nBase.reinterpret\nBase.reshape\nBase.dropdims\nBase.vec\nBase.SubArray\nBase.wrap","category":"page"},{"location":"base/arrays/#Base.view","page":"Arrays","title":"Base.view","text":"view(A, inds...)\n\nLike getindex, but returns a lightweight array that lazily references (or is effectively a view into) the parent array A at the given index or indices inds instead of eagerly extracting elements or constructing a copied subset. Calling getindex or setindex! on the returned value (often a SubArray) computes the indices to access or modify the parent array on the fly. The behavior is undefined if the shape of the parent array is changed after view is called because there is no bound check for the parent array; e.g., it may cause a segmentation fault.\n\nSome immutable parent arrays (like ranges) may choose to simply recompute a new array in some circumstances instead of returning a SubArray if doing so is efficient and provides compatible semantics.\n\ncompat: Julia 1.6\nIn Julia 1.6 or later, view can be called on an AbstractString, returning a SubString.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> b = view(A, :, 1)\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 1\n 3\n\njulia> fill!(b, 0)\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 0\n 0\n\njulia> A # Note A has changed even though we modified b\n2×2 Matrix{Int64}:\n 0 2\n 0 4\n\njulia> view(2:5, 2:3) # returns a range as type is immutable\n3:4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.@view","page":"Arrays","title":"Base.@view","text":"@view A[inds...]\n\nTransform the indexing expression A[inds...] into the equivalent view call.\n\nThis can only be applied directly to a single indexing expression and is particularly helpful for expressions that include the special begin or end indexing syntaxes like A[begin, 2:end-1] (as those are not supported by the normal view function).\n\nNote that @view cannot be used as the target of a regular assignment (e.g., @view(A[1, 2:end]) = ...), nor would the un-decorated indexed assignment (A[1, 2:end] = ...) or broadcasted indexed assignment (A[1, 2:end] .= ...) make a copy. It can be useful, however, for updating broadcasted assignments like @view(A[1, 2:end]) .+= 1 because this is a simple syntax for @view(A[1, 2:end]) .= @view(A[1, 2:end]) + 1, and the indexing expression on the right-hand side would otherwise make a copy without the @view.\n\nSee also @views to switch an entire block of code to use views for non-scalar indexing.\n\ncompat: Julia 1.5\nUsing begin in an indexing expression to refer to the first index requires at least Julia 1.5.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> b = @view A[:, 1]\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 1\n 3\n\njulia> fill!(b, 0)\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 0\n 0\n\njulia> A\n2×2 Matrix{Int64}:\n 0 2\n 0 4\n\n\n\n\n\n","category":"macro"},{"location":"base/arrays/#Base.@views","page":"Arrays","title":"Base.@views","text":"@views expression\n\nConvert every array-slicing operation in the given expression (which may be a begin/end block, loop, function, etc.) to return a view. Scalar indices, non-array types, and explicit getindex calls (as opposed to array[...]) are unaffected.\n\nSimilarly, @views converts string slices into SubString views.\n\nnote: Note\nThe @views macro only affects array[...] expressions that appear explicitly in the given expression, not array slicing that occurs in functions called by that code.\n\ncompat: Julia 1.5\nUsing begin in an indexing expression to refer to the first index was implemented in Julia 1.4, but was only supported by @views starting in Julia 1.5.\n\nExamples\n\njulia> A = zeros(3, 3);\n\njulia> @views for row in 1:3\n b = A[row, :] # b is a view, not a copy\n b .= row # assign every element to the row index\n end\n\njulia> A\n3×3 Matrix{Float64}:\n 1.0 1.0 1.0\n 2.0 2.0 2.0\n 3.0 3.0 3.0\n\n\n\n\n\n","category":"macro"},{"location":"base/arrays/#Base.parent","page":"Arrays","title":"Base.parent","text":"parent(A)\n\nReturn the underlying parent object of the view. This parent of objects of types SubArray, SubString, ReshapedArray or LinearAlgebra.Transpose is what was passed as an argument to view, reshape, transpose, etc. during object creation. If the input is not a wrapped object, return the input itself. If the input is wrapped multiple times, only the outermost wrapper will be removed.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> V = view(A, 1:2, :)\n2×2 view(::Matrix{Int64}, 1:2, :) with eltype Int64:\n 1 2\n 3 4\n\njulia> parent(V)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.parentindices","page":"Arrays","title":"Base.parentindices","text":"parentindices(A)\n\nReturn the indices in the parent which correspond to the view A.\n\nExamples\n\njulia> A = [1 2; 3 4];\n\njulia> V = view(A, 1, :)\n2-element view(::Matrix{Int64}, 1, :) with eltype Int64:\n 1\n 2\n\njulia> parentindices(V)\n(1, Base.Slice(Base.OneTo(2)))\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.selectdim","page":"Arrays","title":"Base.selectdim","text":"selectdim(A, d::Integer, i)\n\nReturn a view of all the data of A where the index for dimension d equals i.\n\nEquivalent to view(A,:,:,...,i,:,:,...) where i is in position d.\n\nSee also: eachslice.\n\nExamples\n\njulia> A = [1 2 3 4; 5 6 7 8]\n2×4 Matrix{Int64}:\n 1 2 3 4\n 5 6 7 8\n\njulia> selectdim(A, 2, 3)\n2-element view(::Matrix{Int64}, :, 3) with eltype Int64:\n 3\n 7\n\njulia> selectdim(A, 2, 3:4)\n2×2 view(::Matrix{Int64}, :, 3:4) with eltype Int64:\n 3 4\n 7 8\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.reinterpret","page":"Arrays","title":"Base.reinterpret","text":"reinterpret(::Type{Out}, x::In)\n\nChange the type-interpretation of the binary data in the isbits value x to that of the isbits type Out. The size (ignoring padding) of Out has to be the same as that of the type of x. For example, reinterpret(Float32, UInt32(7)) interprets the 4 bytes corresponding to UInt32(7) as a Float32. Note that reinterpret(In, reinterpret(Out, x)) === x\n\njulia> reinterpret(Float32, UInt32(7))\n1.0f-44\n\njulia> reinterpret(NTuple{2, UInt8}, 0x1234)\n(0x34, 0x12)\n\njulia> reinterpret(UInt16, (0x34, 0x12))\n0x1234\n\njulia> reinterpret(Tuple{UInt16, UInt8}, (0x01, 0x0203))\n(0x0301, 0x02)\n\nnote: Note\nThe treatment of padding differs from reinterpret(::DataType, ::AbstractArray).\n\nwarning: Warning\nUse caution if some combinations of bits in Out are not considered valid and would otherwise be prevented by the type's constructors and methods. Unexpected behavior may result without additional validation.\n\n\n\n\n\nreinterpret(T::DataType, A::AbstractArray)\n\nConstruct a view of the array with the same binary data as the given array, but with T as element type.\n\nThis function also works on \"lazy\" array whose elements are not computed until they are explicitly retrieved. For instance, reinterpret on the range 1:6 works similarly as on the dense vector collect(1:6):\n\njulia> reinterpret(Float32, UInt32[1 2 3 4 5])\n1×5 reinterpret(Float32, ::Matrix{UInt32}):\n 1.0f-45 3.0f-45 4.0f-45 6.0f-45 7.0f-45\n\njulia> reinterpret(Complex{Int}, 1:6)\n3-element reinterpret(Complex{Int64}, ::UnitRange{Int64}):\n 1 + 2im\n 3 + 4im\n 5 + 6im\n\nIf the location of padding bits does not line up between T and eltype(A), the resulting array will be read-only or write-only, to prevent invalid bits from being written to or read from, respectively.\n\njulia> a = reinterpret(Tuple{UInt8, UInt32}, UInt32[1, 2])\n1-element reinterpret(Tuple{UInt8, UInt32}, ::Vector{UInt32}):\n (0x01, 0x00000002)\n\njulia> a[1] = 3\nERROR: Padding of type Tuple{UInt8, UInt32} is not compatible with type UInt32.\n\njulia> b = reinterpret(UInt32, Tuple{UInt8, UInt32}[(0x01, 0x00000002)]); # showing will error\n\njulia> b[1]\nERROR: Padding of type UInt32 is not compatible with type Tuple{UInt8, UInt32}.\n\n\n\n\n\nreinterpret(reshape, T, A::AbstractArray{S}) -> B\n\nChange the type-interpretation of A while consuming or adding a \"channel dimension.\"\n\nIf sizeof(T) = n*sizeof(S) for n>1, A's first dimension must be of size n and B lacks A's first dimension. Conversely, if sizeof(S) = n*sizeof(T) for n>1, B gets a new first dimension of size n. The dimensionality is unchanged if sizeof(T) == sizeof(S).\n\ncompat: Julia 1.6\nThis method requires at least Julia 1.6.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> reinterpret(reshape, Complex{Int}, A) # the result is a vector\n2-element reinterpret(reshape, Complex{Int64}, ::Matrix{Int64}) with eltype Complex{Int64}:\n 1 + 3im\n 2 + 4im\n\njulia> a = [(1,2,3), (4,5,6)]\n2-element Vector{Tuple{Int64, Int64, Int64}}:\n (1, 2, 3)\n (4, 5, 6)\n\njulia> reinterpret(reshape, Int, a) # the result is a matrix\n3×2 reinterpret(reshape, Int64, ::Vector{Tuple{Int64, Int64, Int64}}) with eltype Int64:\n 1 4\n 2 5\n 3 6\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.reshape","page":"Arrays","title":"Base.reshape","text":"reshape(A, dims...) -> AbstractArray\nreshape(A, dims) -> AbstractArray\n\nReturn an array with the same data as A, but with different dimension sizes or number of dimensions. The two arrays share the same underlying data, so that the result is mutable if and only if A is mutable, and setting elements of one alters the values of the other.\n\nThe new dimensions may be specified either as a list of arguments or as a shape tuple. At most one dimension may be specified with a :, in which case its length is computed such that its product with all the specified dimensions is equal to the length of the original array A. The total number of elements must not change.\n\nExamples\n\njulia> A = Vector(1:16)\n16-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n 11\n 12\n 13\n 14\n 15\n 16\n\njulia> reshape(A, (4, 4))\n4×4 Matrix{Int64}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> reshape(A, 2, :)\n2×8 Matrix{Int64}:\n 1 3 5 7 9 11 13 15\n 2 4 6 8 10 12 14 16\n\njulia> reshape(1:6, 2, 3)\n2×3 reshape(::UnitRange{Int64}, 2, 3) with eltype Int64:\n 1 3 5\n 2 4 6\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.dropdims","page":"Arrays","title":"Base.dropdims","text":"dropdims(A; dims)\n\nReturn an array with the same data as A, but with the dimensions specified by dims removed. size(A,d) must equal 1 for every d in dims, and repeated dimensions or numbers outside 1:ndims(A) are forbidden.\n\nThe result shares the same underlying data as A, such that the result is mutable if and only if A is mutable, and setting elements of one alters the values of the other.\n\nSee also: reshape, vec.\n\nExamples\n\njulia> a = reshape(Vector(1:4),(2,2,1,1))\n2×2×1×1 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 3\n 2 4\n\njulia> b = dropdims(a; dims=3)\n2×2×1 Array{Int64, 3}:\n[:, :, 1] =\n 1 3\n 2 4\n\njulia> b[1,1,1] = 5; a\n2×2×1×1 Array{Int64, 4}:\n[:, :, 1, 1] =\n 5 3\n 2 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.vec","page":"Arrays","title":"Base.vec","text":"vec(a::AbstractArray) -> AbstractVector\n\nReshape the array a as a one-dimensional column vector. Return a if it is already an AbstractVector. The resulting array shares the same underlying data as a, so it will only be mutable if a is mutable, in which case modifying one will also modify the other.\n\nExamples\n\njulia> a = [1 2 3; 4 5 6]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> vec(a)\n6-element Vector{Int64}:\n 1\n 4\n 2\n 5\n 3\n 6\n\njulia> vec(1:3)\n1:3\n\nSee also reshape, dropdims.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.SubArray","page":"Arrays","title":"Base.SubArray","text":"SubArray{T,N,P,I,L} <: AbstractArray{T,N}\n\nN-dimensional view into a parent array (of type P) with an element type T, restricted by a tuple of indices (of type I). L is true for types that support fast linear indexing, and false otherwise.\n\nConstruct SubArrays using the view function.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.wrap","page":"Arrays","title":"Base.wrap","text":"wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)\n\nCreate an array of size dims using m as the underlying memory. This can be thought of as a safe version of unsafe_wrap utilizing Memory or MemoryRef instead of raw pointers.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Concatenation-and-permutation","page":"Arrays","title":"Concatenation and permutation","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.cat\nBase.vcat\nBase.hcat\nBase.hvcat\nBase.hvncat\nBase.stack\nBase.vect\nBase.circshift\nBase.circshift!\nBase.circcopy!\nBase.findall(::Any)\nBase.findall(::Function, ::Any)\nBase.findfirst(::Any)\nBase.findfirst(::Function, ::Any)\nBase.findlast(::Any)\nBase.findlast(::Function, ::Any)\nBase.findnext(::Any, ::Integer)\nBase.findnext(::Function, ::Any, ::Integer)\nBase.findprev(::Any, ::Integer)\nBase.findprev(::Function, ::Any, ::Integer)\nBase.permutedims\nBase.permutedims!\nBase.PermutedDimsArray\nBase.promote_shape","category":"page"},{"location":"base/arrays/#Base.cat","page":"Arrays","title":"Base.cat","text":"cat(A...; dims)\n\nConcatenate the input arrays along the dimensions specified in dims.\n\nAlong a dimension d in dims, the size of the output array is sum(size(a,d) for a in A). Along other dimensions, all input arrays should have the same size, which will also be the size of the output array along those dimensions.\n\nIf dims is a single number, the different arrays are tightly packed along that dimension. If dims is an iterable containing several dimensions, the positions along these dimensions are increased simultaneously for each input array, filling with zero elsewhere. This allows one to construct block-diagonal matrices as cat(matrices...; dims=(1,2)), and their higher-dimensional analogues.\n\nThe special case dims=1 is vcat, and dims=2 is hcat. See also hvcat, hvncat, stack, repeat.\n\nThe keyword also accepts Val(dims).\n\ncompat: Julia 1.8\nFor multiple dimensions dims = Val(::Tuple) was added in Julia 1.8.\n\nExamples\n\nConcatenate two arrays in different dimensions:\n\njulia> a = [1 2 3]\n1×3 Matrix{Int64}:\n 1 2 3\n\njulia> b = [4 5 6]\n1×3 Matrix{Int64}:\n 4 5 6\n\njulia> cat(a, b; dims=1)\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> cat(a, b; dims=2)\n1×6 Matrix{Int64}:\n 1 2 3 4 5 6\n\njulia> cat(a, b; dims=(1, 2))\n2×6 Matrix{Int64}:\n 1 2 3 0 0 0\n 0 0 0 4 5 6\n\nExtended Help\n\nConcatenate 3D arrays:\n\njulia> a = ones(2, 2, 3);\n\njulia> b = ones(2, 2, 4);\n\njulia> c = cat(a, b; dims=3);\n\njulia> size(c) == (2, 2, 7)\ntrue\n\nConcatenate arrays of different sizes:\n\njulia> cat([1 2; 3 4], [pi, pi], fill(10, 2,3,1); dims=2) # same as hcat\n2×6×1 Array{Float64, 3}:\n[:, :, 1] =\n 1.0 2.0 3.14159 10.0 10.0 10.0\n 3.0 4.0 3.14159 10.0 10.0 10.0\n\nConstruct a block diagonal matrix:\n\njulia> cat(true, trues(2,2), trues(4)', dims=(1,2)) # block-diagonal\n4×7 Matrix{Bool}:\n 1 0 0 0 0 0 0\n 0 1 1 0 0 0 0\n 0 1 1 0 0 0 0\n 0 0 0 1 1 1 1\n\njulia> cat(1, [2], [3;;]; dims=Val(2))\n1×3 Matrix{Int64}:\n 1 2 3\n\nnote: Note\ncat does not join two strings, you may want to use *.\n\njulia> a = \"aaa\";\n\njulia> b = \"bbb\";\n\njulia> cat(a, b; dims=1)\n2-element Vector{String}:\n \"aaa\"\n \"bbb\"\n\njulia> cat(a, b; dims=2)\n1×2 Matrix{String}:\n \"aaa\" \"bbb\"\n\njulia> a * b\n\"aaabbb\"\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.vcat","page":"Arrays","title":"Base.vcat","text":"vcat(A...)\n\nConcatenate arrays or numbers vertically. Equivalent to cat(A...; dims=1), and to the syntax [a; b; c].\n\nTo concatenate a large vector of arrays, reduce(vcat, A) calls an efficient method when A isa AbstractVector{<:AbstractVecOrMat}, rather than working pairwise.\n\nSee also hcat, Iterators.flatten, stack.\n\nExamples\n\njulia> v = vcat([1,2], [3,4])\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> v == vcat(1, 2, [3,4]) # accepts numbers\ntrue\n\njulia> v == [1; 2; [3,4]] # syntax for the same operation\ntrue\n\njulia> summary(ComplexF64[1; 2; [3,4]]) # syntax for supplying the element type\n\"4-element Vector{ComplexF64}\"\n\njulia> vcat(range(1, 2, length=3)) # collects lazy ranges\n3-element Vector{Float64}:\n 1.0\n 1.5\n 2.0\n\njulia> two = ([10, 20, 30]', Float64[4 5 6; 7 8 9]) # row vector and a matrix\n([10 20 30], [4.0 5.0 6.0; 7.0 8.0 9.0])\n\njulia> vcat(two...)\n3×3 Matrix{Float64}:\n 10.0 20.0 30.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> vs = [[1, 2], [3, 4], [5, 6]];\n\njulia> reduce(vcat, vs) # more efficient than vcat(vs...)\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\njulia> ans == collect(Iterators.flatten(vs))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.hcat","page":"Arrays","title":"Base.hcat","text":"hcat(A...)\n\nConcatenate arrays or numbers horizontally. Equivalent to cat(A...; dims=2), and to the syntax [a b c] or [a;; b;; c].\n\nFor a large vector of arrays, reduce(hcat, A) calls an efficient method when A isa AbstractVector{<:AbstractVecOrMat}. For a vector of vectors, this can also be written stack(A).\n\nSee also vcat, hvcat.\n\nExamples\n\njulia> hcat([1,2], [3,4], [5,6])\n2×3 Matrix{Int64}:\n 1 3 5\n 2 4 6\n\njulia> hcat(1, 2, [30 40], [5, 6, 7]') # accepts numbers\n1×7 Matrix{Int64}:\n 1 2 30 40 5 6 7\n\njulia> ans == [1 2 [30 40] [5, 6, 7]'] # syntax for the same operation\ntrue\n\njulia> Float32[1 2 [30 40] [5, 6, 7]'] # syntax for supplying the eltype\n1×7 Matrix{Float32}:\n 1.0 2.0 30.0 40.0 5.0 6.0 7.0\n\njulia> ms = [zeros(2,2), [1 2; 3 4], [50 60; 70 80]];\n\njulia> reduce(hcat, ms) # more efficient than hcat(ms...)\n2×6 Matrix{Float64}:\n 0.0 0.0 1.0 2.0 50.0 60.0\n 0.0 0.0 3.0 4.0 70.0 80.0\n\njulia> stack(ms) |> summary # disagrees on a vector of matrices\n\"2×2×3 Array{Float64, 3}\"\n\njulia> hcat(Int[], Int[], Int[]) # empty vectors, each of size (0,)\n0×3 Matrix{Int64}\n\njulia> hcat([1.1, 9.9], Matrix(undef, 2, 0)) # hcat with empty 2×0 Matrix\n2×1 Matrix{Any}:\n 1.1\n 9.9\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.hvcat","page":"Arrays","title":"Base.hvcat","text":"hvcat(blocks_per_row::Union{Tuple{Vararg{Int}}, Int}, values...)\n\nHorizontal and vertical concatenation in one call. This function is called for block matrix syntax. The first argument specifies the number of arguments to concatenate in each block row. If the first argument is a single integer n, then all block rows are assumed to have n block columns.\n\nExamples\n\njulia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6\n(1, 2, 3, 4, 5, 6)\n\njulia> [a b c; d e f]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> hvcat((3,3), a,b,c,d,e,f)\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> [a b; c d; e f]\n3×2 Matrix{Int64}:\n 1 2\n 3 4\n 5 6\n\njulia> hvcat((2,2,2), a,b,c,d,e,f)\n3×2 Matrix{Int64}:\n 1 2\n 3 4\n 5 6\njulia> hvcat((2,2,2), a,b,c,d,e,f) == hvcat(2, a,b,c,d,e,f)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.hvncat","page":"Arrays","title":"Base.hvncat","text":"hvncat(dim::Int, row_first, values...)\nhvncat(dims::Tuple{Vararg{Int}}, row_first, values...)\nhvncat(shape::Tuple{Vararg{Tuple}}, row_first, values...)\n\nHorizontal, vertical, and n-dimensional concatenation of many values in one call.\n\nThis function is called for block matrix syntax. The first argument either specifies the shape of the concatenation, similar to hvcat, as a tuple of tuples, or the dimensions that specify the key number of elements along each axis, and is used to determine the output dimensions. The dims form is more performant, and is used by default when the concatenation operation has the same number of elements along each axis (e.g., [a b; c d;;; e f ; g h]). The shape form is used when the number of elements along each axis is unbalanced (e.g., [a b ; c]). Unbalanced syntax needs additional validation overhead. The dim form is an optimization for concatenation along just one dimension. row_first indicates how values are ordered. The meaning of the first and second elements of shape are also swapped based on row_first.\n\nExamples\n\njulia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6\n(1, 2, 3, 4, 5, 6)\n\njulia> [a b c;;; d e f]\n1×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 2 3\n\n[:, :, 2] =\n 4 5 6\n\njulia> hvncat((2,1,3), false, a,b,c,d,e,f)\n2×1×3 Array{Int64, 3}:\n[:, :, 1] =\n 1\n 2\n\n[:, :, 2] =\n 3\n 4\n\n[:, :, 3] =\n 5\n 6\n\njulia> [a b;;; c d;;; e f]\n1×2×3 Array{Int64, 3}:\n[:, :, 1] =\n 1 2\n\n[:, :, 2] =\n 3 4\n\n[:, :, 3] =\n 5 6\n\njulia> hvncat(((3, 3), (3, 3), (6,)), true, a, b, c, d, e, f)\n1×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 2 3\n\n[:, :, 2] =\n 4 5 6\n\nExamples for construction of the arguments\n\n[a b c ; d e f ;;;\n g h i ; j k l ;;;\n m n o ; p q r ;;;\n s t u ; v w x]\n⇒ dims = (2, 3, 4)\n\n[a b ; c ;;; d ;;;;]\n ___ _ _\n 2 1 1 = elements in each row (2, 1, 1)\n _______ _\n 3 1 = elements in each column (3, 1)\n _____________\n 4 = elements in each 3d slice (4,)\n _____________\n 4 = elements in each 4d slice (4,)\n⇒ shape = ((2, 1, 1), (3, 1), (4,), (4,)) with `row_first` = true\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.stack","page":"Arrays","title":"Base.stack","text":"stack(iter; [dims])\n\nCombine a collection of arrays (or other iterable objects) of equal size into one larger array, by arranging them along one or more new dimensions.\n\nBy default the axes of the elements are placed first, giving size(result) = (size(first(iter))..., size(iter)...). This has the same order of elements as Iterators.flatten(iter).\n\nWith keyword dims::Integer, instead the ith element of iter becomes the slice selectdim(result, dims, i), so that size(result, dims) == length(iter). In this case stack reverses the action of eachslice with the same dims.\n\nThe various cat functions also combine arrays. However, these all extend the arrays' existing (possibly trivial) dimensions, rather than placing the arrays along new dimensions. They also accept arrays as separate arguments, rather than a single collection.\n\ncompat: Julia 1.9\nThis function requires at least Julia 1.9.\n\nExamples\n\njulia> vecs = (1:2, [30, 40], Float32[500, 600]);\n\njulia> mat = stack(vecs)\n2×3 Matrix{Float32}:\n 1.0 30.0 500.0\n 2.0 40.0 600.0\n\njulia> mat == hcat(vecs...) == reduce(hcat, collect(vecs))\ntrue\n\njulia> vec(mat) == vcat(vecs...) == reduce(vcat, collect(vecs))\ntrue\n\njulia> stack(zip(1:4, 10:99)) # accepts any iterators of iterators\n2×4 Matrix{Int64}:\n 1 2 3 4\n 10 11 12 13\n\njulia> vec(ans) == collect(Iterators.flatten(zip(1:4, 10:99)))\ntrue\n\njulia> stack(vecs; dims=1) # unlike any cat function, 1st axis of vecs[1] is 2nd axis of result\n3×2 Matrix{Float32}:\n 1.0 2.0\n 30.0 40.0\n 500.0 600.0\n\njulia> x = rand(3,4);\n\njulia> x == stack(eachcol(x)) == stack(eachrow(x), dims=1) # inverse of eachslice\ntrue\n\nHigher-dimensional examples:\n\njulia> A = rand(5, 7, 11);\n\njulia> E = eachslice(A, dims=2); # a vector of matrices\n\njulia> (element = size(first(E)), container = size(E))\n(element = (5, 11), container = (7,))\n\njulia> stack(E) |> size\n(5, 11, 7)\n\njulia> stack(E) == stack(E; dims=3) == cat(E...; dims=3)\ntrue\n\njulia> A == stack(E; dims=2)\ntrue\n\njulia> M = (fill(10i+j, 2, 3) for i in 1:5, j in 1:7);\n\njulia> (element = size(first(M)), container = size(M))\n(element = (2, 3), container = (5, 7))\n\njulia> stack(M) |> size # keeps all dimensions\n(2, 3, 5, 7)\n\njulia> stack(M; dims=1) |> size # vec(container) along dims=1\n(35, 2, 3)\n\njulia> hvcat(5, M...) |> size # hvcat puts matrices next to each other\n(14, 15)\n\n\n\n\n\nstack(f, args...; [dims])\n\nApply a function to each element of a collection, and stack the result. Or to several collections, zipped together.\n\nThe function should return arrays (or tuples, or other iterators) all of the same size. These become slices of the result, each separated along dims (if given) or by default along the last dimensions.\n\nSee also mapslices, eachcol.\n\nExamples\n\njulia> stack(c -> (c, c-32), \"julia\")\n2×5 Matrix{Char}:\n 'j' 'u' 'l' 'i' 'a'\n 'J' 'U' 'L' 'I' 'A'\n\njulia> stack(eachrow([1 2 3; 4 5 6]), (10, 100); dims=1) do row, n\n vcat(row, row .* n, row ./ n)\n end\n2×9 Matrix{Float64}:\n 1.0 2.0 3.0 10.0 20.0 30.0 0.1 0.2 0.3\n 4.0 5.0 6.0 400.0 500.0 600.0 0.04 0.05 0.06\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.vect","page":"Arrays","title":"Base.vect","text":"vect(X...)\n\nCreate a Vector with element type computed from the promote_typeof of the argument, containing the argument list.\n\nExamples\n\njulia> a = Base.vect(UInt8(1), 2.5, 1//2)\n3-element Vector{Float64}:\n 1.0\n 2.5\n 0.5\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.circshift","page":"Arrays","title":"Base.circshift","text":"circshift(A, shifts)\n\nCircularly shift, i.e. rotate, the data in A. The second argument is a tuple or vector giving the amount to shift in each dimension, or an integer to shift only in the first dimension.\n\nThe generated code is most efficient when the shift amounts are known at compile-time, i.e., compile-time constants.\n\nSee also: circshift!, circcopy!, bitrotate, <<.\n\nExamples\n\njulia> b = reshape(Vector(1:16), (4,4))\n4×4 Matrix{Int64}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> circshift(b, (0,2))\n4×4 Matrix{Int64}:\n 9 13 1 5\n 10 14 2 6\n 11 15 3 7\n 12 16 4 8\n\njulia> circshift(b, (-1,0))\n4×4 Matrix{Int64}:\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n 1 5 9 13\n\njulia> a = BitArray([true, true, false, false, true])\n5-element BitVector:\n 1\n 1\n 0\n 0\n 1\n\njulia> circshift(a, 1)\n5-element BitVector:\n 1\n 1\n 1\n 0\n 0\n\njulia> circshift(a, -1)\n5-element BitVector:\n 1\n 0\n 0\n 1\n 1\n\njulia> x = (1, 2, 3, 4, 5)\n(1, 2, 3, 4, 5)\n\njulia> circshift(x, 4)\n(2, 3, 4, 5, 1)\n\njulia> z = (1, 'a', -7.0, 3)\n(1, 'a', -7.0, 3)\n\njulia> circshift(z, -1)\n('a', -7.0, 3, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.circshift!","page":"Arrays","title":"Base.circshift!","text":"circshift!(dest, src, shifts)\n\nCircularly shift, i.e. rotate, the data in src, storing the result in dest. shifts specifies the amount to shift in each dimension.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also circshift.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.circcopy!","page":"Arrays","title":"Base.circcopy!","text":"circcopy!(dest, src)\n\nCopy src to dest, indexing each dimension modulo its length. src and dest must have the same size, but can be offset in their indices; any offset results in a (circular) wraparound. If the arrays have overlapping indices, then on the domain of the overlap dest agrees with src.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also: circshift.\n\nExamples\n\njulia> src = reshape(Vector(1:16), (4,4))\n4×4 Array{Int64,2}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> dest = OffsetArray{Int}(undef, (0:3,2:5))\n\njulia> circcopy!(dest, src)\nOffsetArrays.OffsetArray{Int64,2,Array{Int64,2}} with indices 0:3×2:5:\n 8 12 16 4\n 5 9 13 1\n 6 10 14 2\n 7 11 15 3\n\njulia> dest[1:3,2:4] == src[1:3,2:4]\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.findall-Tuple{Any}","page":"Arrays","title":"Base.findall","text":"findall(A)\n\nReturn a vector I of the true indices or keys of A. If there are no such elements of A, return an empty array. To search for other kinds of values, pass a predicate as the first argument.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nSee also: findfirst, searchsorted.\n\nExamples\n\njulia> A = [true, false, false, true]\n4-element Vector{Bool}:\n 1\n 0\n 0\n 1\n\njulia> findall(A)\n2-element Vector{Int64}:\n 1\n 4\n\njulia> A = [true false; false true]\n2×2 Matrix{Bool}:\n 1 0\n 0 1\n\njulia> findall(A)\n2-element Vector{CartesianIndex{2}}:\n CartesianIndex(1, 1)\n CartesianIndex(2, 2)\n\njulia> findall(falses(3))\nInt64[]\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findall-Tuple{Function, Any}","page":"Arrays","title":"Base.findall","text":"findall(f::Function, A)\n\nReturn a vector I of the indices or keys of A where f(A[I]) returns true. If there are no such elements of A, return an empty array.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> x = [1, 3, 4]\n3-element Vector{Int64}:\n 1\n 3\n 4\n\njulia> findall(isodd, x)\n2-element Vector{Int64}:\n 1\n 2\n\njulia> A = [1 2 0; 3 4 0]\n2×3 Matrix{Int64}:\n 1 2 0\n 3 4 0\njulia> findall(isodd, A)\n2-element Vector{CartesianIndex{2}}:\n CartesianIndex(1, 1)\n CartesianIndex(2, 1)\n\njulia> findall(!iszero, A)\n4-element Vector{CartesianIndex{2}}:\n CartesianIndex(1, 1)\n CartesianIndex(2, 1)\n CartesianIndex(1, 2)\n CartesianIndex(2, 2)\n\njulia> d = Dict(:A => 10, :B => -1, :C => 0)\nDict{Symbol, Int64} with 3 entries:\n :A => 10\n :B => -1\n :C => 0\n\njulia> findall(≥(0), d)\n2-element Vector{Symbol}:\n :A\n :C\n\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findfirst-Tuple{Any}","page":"Arrays","title":"Base.findfirst","text":"findfirst(A)\n\nReturn the index or key of the first true value in A. Return nothing if no such value is found. To search for other kinds of values, pass a predicate as the first argument.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nSee also: findall, findnext, findlast, searchsortedfirst.\n\nExamples\n\njulia> A = [false, false, true, false]\n4-element Vector{Bool}:\n 0\n 0\n 1\n 0\n\njulia> findfirst(A)\n3\n\njulia> findfirst(falses(3)) # returns nothing, but not printed in the REPL\n\njulia> A = [false false; true false]\n2×2 Matrix{Bool}:\n 0 0\n 1 0\n\njulia> findfirst(A)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findfirst-Tuple{Function, Any}","page":"Arrays","title":"Base.findfirst","text":"findfirst(predicate::Function, A)\n\nReturn the index or key of the first element of A for which predicate returns true. Return nothing if there is no such element.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [1, 4, 2, 2]\n4-element Vector{Int64}:\n 1\n 4\n 2\n 2\n\njulia> findfirst(iseven, A)\n2\n\njulia> findfirst(x -> x>10, A) # returns nothing, but not printed in the REPL\n\njulia> findfirst(isequal(4), A)\n2\n\njulia> A = [1 4; 2 2]\n2×2 Matrix{Int64}:\n 1 4\n 2 2\n\njulia> findfirst(iseven, A)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findlast-Tuple{Any}","page":"Arrays","title":"Base.findlast","text":"findlast(A)\n\nReturn the index or key of the last true value in A. Return nothing if there is no true value in A.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nSee also: findfirst, findprev, findall.\n\nExamples\n\njulia> A = [true, false, true, false]\n4-element Vector{Bool}:\n 1\n 0\n 1\n 0\n\njulia> findlast(A)\n3\n\njulia> A = falses(2,2);\n\njulia> findlast(A) # returns nothing, but not printed in the REPL\n\njulia> A = [true false; true false]\n2×2 Matrix{Bool}:\n 1 0\n 1 0\n\njulia> findlast(A)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findlast-Tuple{Function, Any}","page":"Arrays","title":"Base.findlast","text":"findlast(predicate::Function, A)\n\nReturn the index or key of the last element of A for which predicate returns true. Return nothing if there is no such element.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> findlast(isodd, A)\n3\n\njulia> findlast(x -> x > 5, A) # returns nothing, but not printed in the REPL\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> findlast(isodd, A)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findnext-Tuple{Any, Integer}","page":"Arrays","title":"Base.findnext","text":"findnext(A, i)\n\nFind the next index after or including i of a true element of A, or nothing if not found.\n\nIndices are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [false, false, true, false]\n4-element Vector{Bool}:\n 0\n 0\n 1\n 0\n\njulia> findnext(A, 1)\n3\n\njulia> findnext(A, 4) # returns nothing, but not printed in the REPL\n\njulia> A = [false false; true false]\n2×2 Matrix{Bool}:\n 0 0\n 1 0\n\njulia> findnext(A, CartesianIndex(1, 1))\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findnext-Tuple{Function, Any, Integer}","page":"Arrays","title":"Base.findnext","text":"findnext(predicate::Function, A, i)\n\nFind the next index after or including i of an element of A for which predicate returns true, or nothing if not found. This works for Arrays, Strings, and most other collections that support getindex, keys(A), and nextind.\n\nIndices are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [1, 4, 2, 2];\n\njulia> findnext(isodd, A, 1)\n1\n\njulia> findnext(isodd, A, 2) # returns nothing, but not printed in the REPL\n\njulia> A = [1 4; 2 2];\n\njulia> findnext(isodd, A, CartesianIndex(1, 1))\nCartesianIndex(1, 1)\n\njulia> findnext(isspace, \"a b c\", 3)\n4\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findprev-Tuple{Any, Integer}","page":"Arrays","title":"Base.findprev","text":"findprev(A, i)\n\nFind the previous index before or including i of a true element of A, or nothing if not found.\n\nIndices are of the same type as those returned by keys(A) and pairs(A).\n\nSee also: findnext, findfirst, findall.\n\nExamples\n\njulia> A = [false, false, true, true]\n4-element Vector{Bool}:\n 0\n 0\n 1\n 1\n\njulia> findprev(A, 3)\n3\n\njulia> findprev(A, 1) # returns nothing, but not printed in the REPL\n\njulia> A = [false false; true true]\n2×2 Matrix{Bool}:\n 0 0\n 1 1\n\njulia> findprev(A, CartesianIndex(2, 1))\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findprev-Tuple{Function, Any, Integer}","page":"Arrays","title":"Base.findprev","text":"findprev(predicate::Function, A, i)\n\nFind the previous index before or including i of an element of A for which predicate returns true, or nothing if not found. This works for Arrays, Strings, and most other collections that support getindex, keys(A), and nextind.\n\nIndices are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [4, 6, 1, 2]\n4-element Vector{Int64}:\n 4\n 6\n 1\n 2\n\njulia> findprev(isodd, A, 1) # returns nothing, but not printed in the REPL\n\njulia> findprev(isodd, A, 3)\n3\n\njulia> A = [4 6; 1 2]\n2×2 Matrix{Int64}:\n 4 6\n 1 2\n\njulia> findprev(isodd, A, CartesianIndex(1, 2))\nCartesianIndex(2, 1)\n\njulia> findprev(isspace, \"a b c\", 3)\n2\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.permutedims","page":"Arrays","title":"Base.permutedims","text":"permutedims(A::AbstractArray, perm)\npermutedims(A::AbstractMatrix)\n\nPermute the dimensions (axes) of array A. perm is a tuple or vector of ndims(A) integers specifying the permutation.\n\nIf A is a 2d array (AbstractMatrix), then perm defaults to (2,1), swapping the two axes of A (the rows and columns of the matrix). This differs from transpose in that the operation is not recursive, which is especially useful for arrays of non-numeric values (where the recursive transpose would throw an error) and/or 2d arrays that do not represent linear operators.\n\nFor 1d arrays, see permutedims(v::AbstractVector), which returns a 1-row “matrix”.\n\nSee also permutedims!, PermutedDimsArray, transpose, invperm.\n\nExamples\n\n2d arrays:\n\nUnlike transpose, permutedims can be used to swap rows and columns of 2d arrays of arbitrary non-numeric elements, such as strings:\n\njulia> A = [\"a\" \"b\" \"c\"\n \"d\" \"e\" \"f\"]\n2×3 Matrix{String}:\n \"a\" \"b\" \"c\"\n \"d\" \"e\" \"f\"\n\njulia> permutedims(A)\n3×2 Matrix{String}:\n \"a\" \"d\"\n \"b\" \"e\"\n \"c\" \"f\"\n\nAnd permutedims produces results that differ from transpose for matrices whose elements are themselves numeric matrices:\n\njulia> a = [1 2; 3 4];\n\njulia> b = [5 6; 7 8];\n\njulia> c = [9 10; 11 12];\n\njulia> d = [13 14; 15 16];\n\njulia> X = [[a] [b]; [c] [d]]\n2×2 Matrix{Matrix{Int64}}:\n [1 2; 3 4] [5 6; 7 8]\n [9 10; 11 12] [13 14; 15 16]\n\njulia> permutedims(X)\n2×2 Matrix{Matrix{Int64}}:\n [1 2; 3 4] [9 10; 11 12]\n [5 6; 7 8] [13 14; 15 16]\n\njulia> transpose(X)\n2×2 transpose(::Matrix{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:\n [1 3; 2 4] [9 11; 10 12]\n [5 7; 6 8] [13 15; 14 16]\n\nMulti-dimensional arrays\n\njulia> A = reshape(Vector(1:8), (2,2,2))\n2×2×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 3\n 2 4\n\n[:, :, 2] =\n 5 7\n 6 8\n\njulia> perm = (3, 1, 2); # put the last dimension first\n\njulia> B = permutedims(A, perm)\n2×2×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 2\n 5 6\n\n[:, :, 2] =\n 3 4\n 7 8\n\njulia> A == permutedims(B, invperm(perm)) # the inverse permutation\ntrue\n\nFor each dimension i of B = permutedims(A, perm), its corresponding dimension of A will be perm[i]. This means the equality size(B, i) == size(A, perm[i]) holds.\n\njulia> A = randn(5, 7, 11, 13);\n\njulia> perm = [4, 1, 3, 2];\n\njulia> B = permutedims(A, perm);\n\njulia> size(B)\n(13, 5, 11, 7)\n\njulia> size(A)[perm] == ans\ntrue\n\n\n\n\n\npermutedims(v::AbstractVector)\n\nReshape vector v into a 1 × length(v) row matrix. Differs from transpose in that the operation is not recursive, which is especially useful for arrays of non-numeric values (where the recursive transpose might throw an error).\n\nExamples\n\nUnlike transpose, permutedims can be used on vectors of arbitrary non-numeric elements, such as strings:\n\njulia> permutedims([\"a\", \"b\", \"c\"])\n1×3 Matrix{String}:\n \"a\" \"b\" \"c\"\n\nFor vectors of numbers, permutedims(v) works much like transpose(v) except that the return type differs (it uses reshape rather than a LinearAlgebra.Transpose view, though both share memory with the original array v):\n\njulia> v = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> p = permutedims(v)\n1×4 Matrix{Int64}:\n 1 2 3 4\n\njulia> r = transpose(v)\n1×4 transpose(::Vector{Int64}) with eltype Int64:\n 1 2 3 4\n\njulia> p == r\ntrue\n\njulia> typeof(r)\nTranspose{Int64, Vector{Int64}}\n\njulia> p[1] = 5; r[2] = 6; # mutating p or r also changes v\n\njulia> v # shares memory with both p and r\n4-element Vector{Int64}:\n 5\n 6\n 3\n 4\n\nHowever, permutedims produces results that differ from transpose for vectors whose elements are themselves numeric matrices:\n\njulia> V = [[[1 2; 3 4]]; [[5 6; 7 8]]]\n2-element Vector{Matrix{Int64}}:\n [1 2; 3 4]\n [5 6; 7 8]\n\njulia> permutedims(V)\n1×2 Matrix{Matrix{Int64}}:\n [1 2; 3 4] [5 6; 7 8]\n\njulia> transpose(V)\n1×2 transpose(::Vector{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:\n [1 3; 2 4] [5 7; 6 8]\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.permutedims!","page":"Arrays","title":"Base.permutedims!","text":"permutedims!(dest, src, perm)\n\nPermute the dimensions of array src and store the result in the array dest. perm is a vector specifying a permutation of length ndims(src). The preallocated array dest should have size(dest) == size(src)[perm] and is completely overwritten. No in-place permutation is supported and unexpected results will happen if src and dest have overlapping memory regions.\n\nSee also permutedims.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.PermutedDimsArrays.PermutedDimsArray","page":"Arrays","title":"Base.PermutedDimsArrays.PermutedDimsArray","text":"PermutedDimsArray(A, perm) -> B\n\nGiven an AbstractArray A, create a view B such that the dimensions appear to be permuted. Similar to permutedims, except that no copying occurs (B shares storage with A).\n\nSee also permutedims, invperm.\n\nExamples\n\njulia> A = rand(3,5,4);\n\njulia> B = PermutedDimsArray(A, (3,1,2));\n\njulia> size(B)\n(4, 3, 5)\n\njulia> B[3,1,2] == A[1,2,3]\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.promote_shape","page":"Arrays","title":"Base.promote_shape","text":"promote_shape(s1, s2)\n\nCheck two array shapes for compatibility, allowing trailing singleton dimensions, and return whichever shape has more dimensions.\n\nExamples\n\njulia> a = fill(1, (3,4,1,1,1));\n\njulia> b = fill(1, (3,4));\n\njulia> promote_shape(a,b)\n(Base.OneTo(3), Base.OneTo(4), Base.OneTo(1), Base.OneTo(1), Base.OneTo(1))\n\njulia> promote_shape((2,3,1,4), (2, 3, 1, 4, 1))\n(2, 3, 1, 4, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Array-functions","page":"Arrays","title":"Array functions","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.accumulate\nBase.accumulate!\nBase.cumprod\nBase.cumprod!\nBase.cumsum\nBase.cumsum!\nBase.diff\nBase.repeat\nBase.rot180\nBase.rotl90\nBase.rotr90\nBase.mapslices\nBase.eachrow\nBase.eachcol\nBase.eachslice","category":"page"},{"location":"base/arrays/#Base.accumulate","page":"Arrays","title":"Base.accumulate","text":"accumulate(op, A; dims::Integer, [init])\n\nCumulative operation op along the dimension dims of A (providing dims is optional for vectors). An initial value init may optionally be provided by a keyword argument. See also accumulate! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).\n\nFor common operations there are specialized variants of accumulate, see cumsum, cumprod. For a lazy version, see Iterators.accumulate.\n\ncompat: Julia 1.5\naccumulate on a non-array iterator requires at least Julia 1.5.\n\nExamples\n\njulia> accumulate(+, [1,2,3])\n3-element Vector{Int64}:\n 1\n 3\n 6\n\njulia> accumulate(min, (1, -2, 3, -4, 5), init=0)\n(0, -2, -2, -4, -4)\n\njulia> accumulate(/, (2, 4, Inf), init=100)\n(50.0, 12.5, 0.0)\n\njulia> accumulate(=>, i^2 for i in 1:3)\n3-element Vector{Any}:\n 1\n 1 => 4\n (1 => 4) => 9\n\njulia> accumulate(+, fill(1, 3, 4))\n3×4 Matrix{Int64}:\n 1 4 7 10\n 2 5 8 11\n 3 6 9 12\n\njulia> accumulate(+, fill(1, 2, 5), dims=2, init=100.0)\n2×5 Matrix{Float64}:\n 101.0 102.0 103.0 104.0 105.0\n 101.0 102.0 103.0 104.0 105.0\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.accumulate!","page":"Arrays","title":"Base.accumulate!","text":"accumulate!(op, B, A; [dims], [init])\n\nCumulative operation op on A along the dimension dims, storing the result in B. Providing dims is optional for vectors. If the keyword argument init is given, its value is used to instantiate the accumulation.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also accumulate, cumsum!, cumprod!.\n\nExamples\n\njulia> x = [1, 0, 2, 0, 3];\n\njulia> y = rand(5);\n\njulia> accumulate!(+, y, x);\n\njulia> y\n5-element Vector{Float64}:\n 1.0\n 1.0\n 3.0\n 3.0\n 6.0\n\njulia> A = [1 2 3; 4 5 6];\n\njulia> B = similar(A);\n\njulia> accumulate!(-, B, A, dims=1)\n2×3 Matrix{Int64}:\n 1 2 3\n -3 -3 -3\n\njulia> accumulate!(*, B, A, dims=2, init=10)\n2×3 Matrix{Int64}:\n 10 20 60\n 40 200 1200\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.cumprod","page":"Arrays","title":"Base.cumprod","text":"cumprod(A; dims::Integer)\n\nCumulative product along the dimension dim. See also cumprod! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).\n\nExamples\n\njulia> a = Int8[1 2 3; 4 5 6];\n\njulia> cumprod(a, dims=1)\n2×3 Matrix{Int64}:\n 1 2 3\n 4 10 18\n\njulia> cumprod(a, dims=2)\n2×3 Matrix{Int64}:\n 1 2 6\n 4 20 120\n\n\n\n\n\ncumprod(itr)\n\nCumulative product of an iterator.\n\nSee also cumprod!, accumulate, cumsum.\n\ncompat: Julia 1.5\ncumprod on a non-array iterator requires at least Julia 1.5.\n\nExamples\n\njulia> cumprod(fill(1//2, 3))\n3-element Vector{Rational{Int64}}:\n 1//2\n 1//4\n 1//8\n\njulia> cumprod((1, 2, 1, 3, 1))\n(1, 2, 2, 6, 6)\n\njulia> cumprod(\"julia\")\n5-element Vector{String}:\n \"j\"\n \"ju\"\n \"jul\"\n \"juli\"\n \"julia\"\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.cumprod!","page":"Arrays","title":"Base.cumprod!","text":"cumprod!(B, A; dims::Integer)\n\nCumulative product of A along the dimension dims, storing the result in B. See also cumprod.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\ncumprod!(y::AbstractVector, x::AbstractVector)\n\nCumulative product of a vector x, storing the result in y. See also cumprod.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.cumsum","page":"Arrays","title":"Base.cumsum","text":"cumsum(A; dims::Integer)\n\nCumulative sum along the dimension dims. See also cumsum! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).\n\nExamples\n\njulia> a = [1 2 3; 4 5 6]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> cumsum(a, dims=1)\n2×3 Matrix{Int64}:\n 1 2 3\n 5 7 9\n\njulia> cumsum(a, dims=2)\n2×3 Matrix{Int64}:\n 1 3 6\n 4 9 15\n\nnote: Note\nThe return array's eltype is Int for signed integers of less than system word size and UInt for unsigned integers of less than system word size. To preserve eltype of arrays with small signed or unsigned integer accumulate(+, A) should be used.julia> cumsum(Int8[100, 28])\n2-element Vector{Int64}:\n 100\n 128\n\njulia> accumulate(+,Int8[100, 28])\n2-element Vector{Int8}:\n 100\n -128In the former case, the integers are widened to system word size and therefore the result is Int64[100, 128]. In the latter case, no such widening happens and integer overflow results in Int8[100, -128].\n\n\n\n\n\ncumsum(itr)\n\nCumulative sum of an iterator.\n\nSee also accumulate to apply functions other than +.\n\ncompat: Julia 1.5\ncumsum on a non-array iterator requires at least Julia 1.5.\n\nExamples\n\njulia> cumsum(1:3)\n3-element Vector{Int64}:\n 1\n 3\n 6\n\njulia> cumsum((true, false, true, false, true))\n(1, 1, 2, 2, 3)\n\njulia> cumsum(fill(1, 2) for i in 1:3)\n3-element Vector{Vector{Int64}}:\n [1, 1]\n [2, 2]\n [3, 3]\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.cumsum!","page":"Arrays","title":"Base.cumsum!","text":"cumsum!(B, A; dims::Integer)\n\nCumulative sum of A along the dimension dims, storing the result in B. See also cumsum.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.diff","page":"Arrays","title":"Base.diff","text":"diff(A::AbstractVector)\ndiff(A::AbstractArray; dims::Integer)\n\nFinite difference operator on a vector or a multidimensional array A. In the latter case the dimension to operate on needs to be specified with the dims keyword argument.\n\ncompat: Julia 1.1\ndiff for arrays with dimension higher than 2 requires at least Julia 1.1.\n\nExamples\n\njulia> a = [2 4; 6 16]\n2×2 Matrix{Int64}:\n 2 4\n 6 16\n\njulia> diff(a, dims=2)\n2×1 Matrix{Int64}:\n 2\n 10\n\njulia> diff(vec(a))\n3-element Vector{Int64}:\n 4\n -2\n 12\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.repeat","page":"Arrays","title":"Base.repeat","text":"repeat(A::AbstractArray, counts::Integer...)\n\nConstruct an array by repeating array A a given number of times in each dimension, specified by counts.\n\nSee also: fill, Iterators.repeated, Iterators.cycle.\n\nExamples\n\njulia> repeat([1, 2, 3], 2)\n6-element Vector{Int64}:\n 1\n 2\n 3\n 1\n 2\n 3\n\njulia> repeat([1, 2, 3], 2, 3)\n6×3 Matrix{Int64}:\n 1 1 1\n 2 2 2\n 3 3 3\n 1 1 1\n 2 2 2\n 3 3 3\n\n\n\n\n\nrepeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A)))\n\nConstruct an array by repeating the entries of A. The i-th element of inner specifies the number of times that the individual entries of the i-th dimension of A should be repeated. The i-th element of outer specifies the number of times that a slice along the i-th dimension of A should be repeated. If inner or outer are omitted, no repetition is performed.\n\nExamples\n\njulia> repeat(1:2, inner=2)\n4-element Vector{Int64}:\n 1\n 1\n 2\n 2\n\njulia> repeat(1:2, outer=2)\n4-element Vector{Int64}:\n 1\n 2\n 1\n 2\n\njulia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))\n4×6 Matrix{Int64}:\n 1 2 1 2 1 2\n 1 2 1 2 1 2\n 3 4 3 4 3 4\n 3 4 3 4 3 4\n\n\n\n\n\nrepeat(s::AbstractString, r::Integer)\n\nRepeat a string r times. This can be written as s^r.\n\nSee also ^.\n\nExamples\n\njulia> repeat(\"ha\", 3)\n\"hahaha\"\n\n\n\n\n\nrepeat(c::AbstractChar, r::Integer) -> String\n\nRepeat a character r times. This can equivalently be accomplished by calling c^r.\n\nExamples\n\njulia> repeat('A', 3)\n\"AAA\"\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.rot180","page":"Arrays","title":"Base.rot180","text":"rot180(A)\n\nRotate matrix A 180 degrees.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rot180(a)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\n\n\n\n\nrot180(A, k)\n\nRotate matrix A 180 degrees an integer k number of times. If k is even, this is equivalent to a copy.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rot180(a,1)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\njulia> rot180(a,2)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.rotl90","page":"Arrays","title":"Base.rotl90","text":"rotl90(A)\n\nRotate matrix A left 90 degrees.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rotl90(a)\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\n\n\n\n\nrotl90(A, k)\n\nLeft-rotate matrix A 90 degrees counterclockwise an integer k number of times. If k is a multiple of four (including zero), this is equivalent to a copy.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rotl90(a,1)\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\njulia> rotl90(a,2)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\njulia> rotl90(a,3)\n2×2 Matrix{Int64}:\n 3 1\n 4 2\n\njulia> rotl90(a,4)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.rotr90","page":"Arrays","title":"Base.rotr90","text":"rotr90(A)\n\nRotate matrix A right 90 degrees.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rotr90(a)\n2×2 Matrix{Int64}:\n 3 1\n 4 2\n\n\n\n\n\nrotr90(A, k)\n\nRight-rotate matrix A 90 degrees clockwise an integer k number of times. If k is a multiple of four (including zero), this is equivalent to a copy.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rotr90(a,1)\n2×2 Matrix{Int64}:\n 3 1\n 4 2\n\njulia> rotr90(a,2)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\njulia> rotr90(a,3)\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\njulia> rotr90(a,4)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.mapslices","page":"Arrays","title":"Base.mapslices","text":"mapslices(f, A; dims)\n\nTransform the given dimensions of array A by applying a function f on each slice of the form A[..., :, ..., :, ...], with a colon at each d in dims. The results are concatenated along the remaining dimensions.\n\nFor example, if dims = [1,2] and A is 4-dimensional, then f is called on x = A[:,:,i,j] for all i and j, and f(x) becomes R[:,:,i,j] in the result R.\n\nSee also eachcol or eachslice, used with map or stack.\n\nExamples\n\njulia> A = reshape(1:30,(2,5,3))\n2×5×3 reshape(::UnitRange{Int64}, 2, 5, 3) with eltype Int64:\n[:, :, 1] =\n 1 3 5 7 9\n 2 4 6 8 10\n\n[:, :, 2] =\n 11 13 15 17 19\n 12 14 16 18 20\n\n[:, :, 3] =\n 21 23 25 27 29\n 22 24 26 28 30\n\njulia> f(x::Matrix) = fill(x[1,1], 1,4); # returns a 1×4 matrix\n\njulia> B = mapslices(f, A, dims=(1,2))\n1×4×3 Array{Int64, 3}:\n[:, :, 1] =\n 1 1 1 1\n\n[:, :, 2] =\n 11 11 11 11\n\n[:, :, 3] =\n 21 21 21 21\n\njulia> f2(x::AbstractMatrix) = fill(x[1,1], 1,4);\n\njulia> B == stack(f2, eachslice(A, dims=3))\ntrue\n\njulia> g(x) = x[begin] // x[end-1]; # returns a number\n\njulia> mapslices(g, A, dims=[1,3])\n1×5×1 Array{Rational{Int64}, 3}:\n[:, :, 1] =\n 1//21 3//23 1//5 7//27 9//29\n\njulia> map(g, eachslice(A, dims=2))\n5-element Vector{Rational{Int64}}:\n 1//21\n 3//23\n 1//5\n 7//27\n 9//29\n\njulia> mapslices(sum, A; dims=(1,3)) == sum(A; dims=(1,3))\ntrue\n\nNotice that in eachslice(A; dims=2), the specified dimension is the one without a colon in the slice. This is view(A,:,i,:), whereas mapslices(f, A; dims=(1,3)) uses A[:,i,:]. The function f may mutate values in the slice without affecting A.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.eachrow","page":"Arrays","title":"Base.eachrow","text":"eachrow(A::AbstractVecOrMat) <: AbstractVector\n\nCreate a RowSlices object that is a vector of rows of matrix or vector A. Row slices are returned as AbstractVector views of A.\n\nFor the inverse, see stack(rows; dims=1).\n\nSee also eachcol, eachslice and mapslices.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this returned an iterator.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> s = eachrow(a)\n2-element RowSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:\n [1, 2]\n [3, 4]\n\njulia> s[1]\n2-element view(::Matrix{Int64}, 1, :) with eltype Int64:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.eachcol","page":"Arrays","title":"Base.eachcol","text":"eachcol(A::AbstractVecOrMat) <: AbstractVector\n\nCreate a ColumnSlices object that is a vector of columns of matrix or vector A. Column slices are returned as AbstractVector views of A.\n\nFor the inverse, see stack(cols) or reduce(hcat, cols).\n\nSee also eachrow, eachslice and mapslices.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this returned an iterator.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> s = eachcol(a)\n2-element ColumnSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}:\n [1, 3]\n [2, 4]\n\njulia> s[1]\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 1\n 3\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.eachslice","page":"Arrays","title":"Base.eachslice","text":"eachslice(A::AbstractArray; dims, drop=true)\n\nCreate a Slices object that is an array of slices over dimensions dims of A, returning views that select all the data from the other dimensions in A. dims can either be an integer or a tuple of integers.\n\nIf drop = true (the default), the outer Slices will drop the inner dimensions, and the ordering of the dimensions will match those in dims. If drop = false, then the Slices will have the same dimensionality as the underlying array, with inner dimensions having size 1.\n\nSee stack(slices; dims) for the inverse of eachslice(A; dims::Integer).\n\nSee also eachrow, eachcol, mapslices and selectdim.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this returned an iterator, and only a single dimension dims was supported.\n\nExamples\n\njulia> m = [1 2 3; 4 5 6; 7 8 9]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n 7 8 9\n\njulia> s = eachslice(m, dims=1)\n3-element RowSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:\n [1, 2, 3]\n [4, 5, 6]\n [7, 8, 9]\n\njulia> s[1]\n3-element view(::Matrix{Int64}, 1, :) with eltype Int64:\n 1\n 2\n 3\n\njulia> eachslice(m, dims=1, drop=false)\n3×1 Slices{Matrix{Int64}, Tuple{Int64, Colon}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}, 2}:\n [1, 2, 3]\n [4, 5, 6]\n [7, 8, 9]\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Combinatorics","page":"Arrays","title":"Combinatorics","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.invperm\nBase.isperm\nBase.permute!(::Any, ::AbstractVector)\nBase.invpermute!\nBase.reverse(::AbstractVector; kwargs...)\nBase.reverseind\nBase.reverse!","category":"page"},{"location":"base/arrays/#Base.invperm","page":"Arrays","title":"Base.invperm","text":"invperm(v)\n\nReturn the inverse permutation of v. If B = A[v], then A == B[invperm(v)].\n\nSee also sortperm, invpermute!, isperm, permutedims.\n\nExamples\n\njulia> p = (2, 3, 1);\n\njulia> invperm(p)\n(3, 1, 2)\n\njulia> v = [2; 4; 3; 1];\n\njulia> invperm(v)\n4-element Vector{Int64}:\n 4\n 1\n 3\n 2\n\njulia> A = ['a','b','c','d'];\n\njulia> B = A[v]\n4-element Vector{Char}:\n 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)\n 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)\n 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)\n 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> B[invperm(v)]\n4-element Vector{Char}:\n 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)\n 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)\n 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.isperm","page":"Arrays","title":"Base.isperm","text":"isperm(v) -> Bool\n\nReturn true if v is a valid permutation.\n\nExamples\n\njulia> isperm([1; 2])\ntrue\n\njulia> isperm([1; 3])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.permute!-Tuple{Any, AbstractVector}","page":"Arrays","title":"Base.permute!","text":"permute!(v, p)\n\nPermute vector v in-place, according to permutation p. No checking is done to verify that p is a permutation.\n\nTo return a new permutation, use v[p]. This is generally faster than permute!(v, p); it is even faster to write into a pre-allocated output array with u .= @view v[p]. (Even though permute! overwrites v in-place, it internally requires some allocation to keep track of which elements have been moved.)\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also invpermute!.\n\nExamples\n\njulia> A = [1, 1, 3, 4];\n\njulia> perm = [2, 4, 3, 1];\n\njulia> permute!(A, perm);\n\njulia> A\n4-element Vector{Int64}:\n 1\n 4\n 3\n 1\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.invpermute!","page":"Arrays","title":"Base.invpermute!","text":"invpermute!(v, p)\n\nLike permute!, but the inverse of the given permutation is applied.\n\nNote that if you have a pre-allocated output array (e.g. u = similar(v)), it is quicker to instead employ u[p] = v. (invpermute! internally allocates a copy of the data.)\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1, 1, 3, 4];\n\njulia> perm = [2, 4, 3, 1];\n\njulia> invpermute!(A, perm);\n\njulia> A\n4-element Vector{Int64}:\n 4\n 1\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.reverse-Tuple{AbstractVector}","page":"Arrays","title":"Base.reverse","text":"reverse(A; dims=:)\n\nReverse A along dimension dims, which can be an integer (a single dimension), a tuple of integers (a tuple of dimensions) or : (reverse along all the dimensions, the default). See also reverse! for in-place reversal.\n\nExamples\n\njulia> b = Int64[1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> reverse(b, dims=2)\n2×2 Matrix{Int64}:\n 2 1\n 4 3\n\njulia> reverse(b)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\ncompat: Julia 1.6\nPrior to Julia 1.6, only single-integer dims are supported in reverse.\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.reverseind","page":"Arrays","title":"Base.reverseind","text":"reverseind(v, i)\n\nGiven an index i in reverse(v), return the corresponding index in v so that v[reverseind(v,i)] == reverse(v)[i]. (This can be nontrivial in cases where v contains non-ASCII characters.)\n\nExamples\n\njulia> s = \"Julia🚀\"\n\"Julia🚀\"\n\njulia> r = reverse(s)\n\"🚀ailuJ\"\n\njulia> for i in eachindex(s)\n print(r[reverseind(r, i)])\n end\nJulia🚀\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.reverse!","page":"Arrays","title":"Base.reverse!","text":"reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v\n\nIn-place version of reverse.\n\nExamples\n\njulia> A = Vector(1:5)\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n\njulia> reverse!(A);\n\njulia> A\n5-element Vector{Int64}:\n 5\n 4\n 3\n 2\n 1\n\n\n\n\n\nreverse!(A; dims=:)\n\nLike reverse, but operates in-place in A.\n\ncompat: Julia 1.6\nMultidimensional reverse! requires Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"manual/handling-operating-system-variation/#Handling-Operating-System-Variation","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"","category":"section"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"When writing cross-platform applications or libraries, it is often necessary to allow for differences between operating systems. The variable Sys.KERNEL can be used to handle such cases. There are several functions in the Sys module intended to make this easier, such as isunix, islinux, isapple, isbsd, isfreebsd, and iswindows. These may be used as follows:","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"if Sys.iswindows()\n windows_specific_thing(a)\nend","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"Note that islinux, isapple, and isfreebsd are mutually exclusive subsets of isunix. Additionally, there is a macro @static which makes it possible to use these functions to conditionally hide invalid code, as demonstrated in the following examples.","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"Simple blocks:","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"ccall((@static Sys.iswindows() ? :_fopen : :fopen), ...)","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"Complex blocks:","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"@static if Sys.islinux()\n linux_specific_thing(a)\nelseif Sys.isapple()\n apple_specific_thing(a)\nelse\n generic_thing(a)\nend","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"When nesting conditionals, the @static must be repeated for each level (parentheses optional, but recommended for readability):","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"@static Sys.iswindows() ? :a : (@static Sys.isapple() ? :b : :c)","category":"page"},{"location":"manual/performance-tips/#man-performance-tips","page":"Performance Tips","title":"Performance Tips","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In the following sections, we briefly go through a few techniques that can help make your Julia code run as fast as possible.","category":"page"},{"location":"manual/performance-tips/#Performance-critical-code-should-be-inside-a-function","page":"Performance Tips","title":"Performance critical code should be inside a function","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Any code that is performance critical should be inside a function. Code inside functions tends to run much faster than top level code, due to how Julia's compiler works.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The use of functions is not only important for performance: functions are more reusable and testable, and clarify what steps are being done and what their inputs and outputs are, Write functions, not just scripts is also a recommendation of Julia's Styleguide.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The functions should take arguments, instead of operating directly on global variables, see the next point.","category":"page"},{"location":"manual/performance-tips/#Avoid-untyped-global-variables","page":"Performance Tips","title":"Avoid untyped global variables","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The value of an untyped global variable might change at any point, possibly leading to a change of its type. This makes it difficult for the compiler to optimize code using global variables. This also applies to type-valued variables, i.e. type aliases on the global level. Variables should be local, or passed as arguments to functions, whenever possible.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"We find that global names are frequently constants, and declaring them as such greatly improves performance:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"const DEFAULT_VAL = 0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If a global is known to always be of the same type, the type should be annotated.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Uses of untyped globals can be optimized by annotating their types at the point of use:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"global x = rand(1000)\n\nfunction loop_over_global()\n s = 0.0\n for i in x::Vector{Float64}\n s += i\n end\n return s\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Passing arguments to functions is better style. It leads to more reusable code and clarifies what the inputs and outputs are.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"note: Note\nAll code in the REPL is evaluated in global scope, so a variable defined and assigned at top level will be a global variable. Variables defined at top level scope inside modules are also global.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In the following REPL session:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = 1.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"is equivalent to:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> global x = 1.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"so all the performance issues discussed previously apply.","category":"page"},{"location":"manual/performance-tips/#Measure-performance-with-[@time](@ref)-and-pay-attention-to-memory-allocation","page":"Performance Tips","title":"Measure performance with @time and pay attention to memory allocation","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"A useful tool for measuring performance is the @time macro. We here repeat the example with the global variable above, but this time with the type annotation removed:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = rand(1000);\n\njulia> function sum_global()\n s = 0.0\n for i in x\n s += i\n end\n return s\n end;\n\njulia> @time sum_global()\n 0.011539 seconds (9.08 k allocations: 373.386 KiB, 98.69% compilation time)\n523.0007221951678\n\njulia> @time sum_global()\n 0.000091 seconds (3.49 k allocations: 70.156 KiB)\n523.0007221951678","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"On the first call (@time sum_global()) the function gets compiled. (If you've not yet used @time in this session, it will also compile functions needed for timing.) You should not take the results of this run seriously. For the second run, note that in addition to reporting the time, it also indicated that a significant amount of memory was allocated. We are here just computing a sum over all elements in a vector of 64-bit floats so there should be no need to allocate (heap) memory.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"We should clarify that what @time reports is specifically heap allocations, which are typically needed for either mutable objects or for creating/growing variable-sized containers (such as Array or Dict, strings, or \"type-unstable\" objects whose type is only known at runtime). Allocating (or deallocating) such blocks of memory may require an expensive function call to libc (e.g. via malloc in C), and they must be tracked for garbage collection. In contrast, immutable values like numbers (except bignums), tuples, and immutable structs can be stored much more cheaply, e.g. in stack or CPU-register memory, so one doesn’t typically worry about the performance cost of \"allocating\" them.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Unexpected memory allocation is almost always a sign of some problem with your code, usually a problem with type-stability or creating many small temporary arrays. Consequently, in addition to the allocation itself, it's very likely that the code generated for your function is far from optimal. Take such indications seriously and follow the advice below.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In this particular case, the memory allocation is due to the usage of a type-unstable global variable x, so if we instead pass x as an argument to the function it no longer allocates memory (the remaining allocation reported below is due to running the @time macro in global scope) and is significantly faster after the first call:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = rand(1000);\n\njulia> function sum_arg(x)\n s = 0.0\n for i in x\n s += i\n end\n return s\n end;\n\njulia> @time sum_arg(x)\n 0.007551 seconds (3.98 k allocations: 200.548 KiB, 99.77% compilation time)\n523.0007221951678\n\njulia> @time sum_arg(x)\n 0.000006 seconds (1 allocation: 16 bytes)\n523.0007221951678","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The 1 allocation seen is from running the @time macro itself in global scope. If we instead run the timing in a function, we can see that indeed no allocations are performed:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> time_sum(x) = @time sum_arg(x);\n\njulia> time_sum(x)\n 0.000002 seconds\n523.0007221951678","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In some situations, your function may need to allocate memory as part of its operation, and this can complicate the simple picture above. In such cases, consider using one of the tools below to diagnose problems, or write a version of your function that separates allocation from its algorithmic aspects (see Pre-allocating outputs).","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"note: Note\nFor more serious benchmarking, consider the BenchmarkTools.jl package which among other things evaluates the function multiple times in order to reduce noise.","category":"page"},{"location":"manual/performance-tips/#tools","page":"Performance Tips","title":"Tools","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia and its package ecosystem includes tools that may help you diagnose problems and improve the performance of your code:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Profiling allows you to measure the performance of your running code and identify lines that serve as bottlenecks. For complex projects, the ProfileView package can help you visualize your profiling results.\nThe JET package can help you find common performance problems in your code.\nUnexpectedly-large memory allocations–as reported by @time, @allocated, or the profiler (through calls to the garbage-collection routines)–hint that there might be issues with your code. If you don't see another reason for the allocations, suspect a type problem. You can also start Julia with the --track-allocation=user option and examine the resulting *.mem files to see information about where those allocations occur. See Memory allocation analysis.\n@code_warntype generates a representation of your code that can be helpful in finding expressions that result in type uncertainty. See @code_warntype below.","category":"page"},{"location":"manual/performance-tips/#man-performance-abstract-container","page":"Performance Tips","title":"Avoid containers with abstract type parameters","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When working with parameterized types, including arrays, it is best to avoid parameterizing with abstract types where possible.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Consider the following:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> a = Real[]\nReal[]\n\njulia> push!(a, 1); push!(a, 2.0); push!(a, π)\n3-element Vector{Real}:\n 1\n 2.0\n π = 3.1415926535897...","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Because a is an array of abstract type Real, it must be able to hold any Real value. Since Real objects can be of arbitrary size and structure, a must be represented as an array of pointers to individually allocated Real objects. However, if we instead only allow numbers of the same type, e.g. Float64, to be stored in a these can be stored more efficiently:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> a = Float64[]\nFloat64[]\n\njulia> push!(a, 1); push!(a, 2.0); push!(a, π)\n3-element Vector{Float64}:\n 1.0\n 2.0\n 3.141592653589793","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Assigning numbers into a will now convert them to Float64 and a will be stored as a contiguous block of 64-bit floating-point values that can be manipulated efficiently.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If you cannot avoid containers with abstract value types, it is sometimes better to parametrize with Any to avoid runtime type checking. E.g. IdDict{Any, Any} performs better than IdDict{Type, Vector}","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"See also the discussion under Parametric Types.","category":"page"},{"location":"manual/performance-tips/#Type-declarations","page":"Performance Tips","title":"Type declarations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In many languages with optional type declarations, adding declarations is the principal way to make code run faster. This is not the case in Julia. In Julia, the compiler generally knows the types of all function arguments, local variables, and expressions. However, there are a few specific instances where declarations are helpful.","category":"page"},{"location":"manual/performance-tips/#Avoid-fields-with-abstract-type","page":"Performance Tips","title":"Avoid fields with abstract type","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Types can be declared without specifying the types of their fields:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> struct MyAmbiguousType\n a\n end","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This allows a to be of any type. This can often be useful, but it does have a downside: for objects of type MyAmbiguousType, the compiler will not be able to generate high-performance code. The reason is that the compiler uses the types of objects, not their values, to determine how to build code. Unfortunately, very little can be inferred about an object of type MyAmbiguousType:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> b = MyAmbiguousType(\"Hello\")\nMyAmbiguousType(\"Hello\")\n\njulia> c = MyAmbiguousType(17)\nMyAmbiguousType(17)\n\njulia> typeof(b)\nMyAmbiguousType\n\njulia> typeof(c)\nMyAmbiguousType","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The values of b and c have the same type, yet their underlying representation of data in memory is very different. Even if you stored just numeric values in field a, the fact that the memory representation of a UInt8 differs from a Float64 also means that the CPU needs to handle them using two different kinds of instructions. Since the required information is not available in the type, such decisions have to be made at run-time. This slows performance.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"You can do better by declaring the type of a. Here, we are focused on the case where a might be any one of several types, in which case the natural solution is to use parameters. For example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> mutable struct MyType{T<:AbstractFloat}\n a::T\n end","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This is a better choice than","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> mutable struct MyStillAmbiguousType\n a::AbstractFloat\n end","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"because the first version specifies the type of a from the type of the wrapper object. For example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> m = MyType(3.2)\nMyType{Float64}(3.2)\n\njulia> t = MyStillAmbiguousType(3.2)\nMyStillAmbiguousType(3.2)\n\njulia> typeof(m)\nMyType{Float64}\n\njulia> typeof(t)\nMyStillAmbiguousType","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The type of field a can be readily determined from the type of m, but not from the type of t. Indeed, in t it's possible to change the type of the field a:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> typeof(t.a)\nFloat64\n\njulia> t.a = 4.5f0\n4.5f0\n\njulia> typeof(t.a)\nFloat32","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In contrast, once m is constructed, the type of m.a cannot change:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> m.a = 4.5f0\n4.5f0\n\njulia> typeof(m.a)\nFloat64","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The fact that the type of m.a is known from m's type—coupled with the fact that its type cannot change mid-function—allows the compiler to generate highly-optimized code for objects like m but not for objects like t.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Of course, all of this is true only if we construct m with a concrete type. We can break this by explicitly constructing it with an abstract type:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> m = MyType{AbstractFloat}(3.2)\nMyType{AbstractFloat}(3.2)\n\njulia> typeof(m.a)\nFloat64\n\njulia> m.a = 4.5f0\n4.5f0\n\njulia> typeof(m.a)\nFloat32","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For all practical purposes, such objects behave identically to those of MyStillAmbiguousType.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"It's quite instructive to compare the sheer amount of code generated for a simple function","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"func(m::MyType) = m.a+1","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"using","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"code_llvm(func, Tuple{MyType{Float64}})\ncode_llvm(func, Tuple{MyType{AbstractFloat}})","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For reasons of length the results are not shown here, but you may wish to try this yourself. Because the type is fully-specified in the first case, the compiler doesn't need to generate any code to resolve the type at run-time. This results in shorter and faster code.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"One should also keep in mind that not-fully-parameterized types behave like abstract types. For example, even though a fully specified Array{T,n} is concrete, Array itself with no parameters given is not concrete:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> !isconcretetype(Array), !isabstracttype(Array), isstructtype(Array), !isconcretetype(Array{Int}), isconcretetype(Array{Int,1})\n(true, true, true, true, true)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In this case, it would be better to avoid declaring MyType with a field a::Array and instead declare the field as a::Array{T,N} or as a::A, where {T,N} or A are parameters of MyType.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The previous advice is especially useful when the fields of a struct are meant to be functions, or more generally callable objects. It is very tempting to define a struct as follows:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"struct MyCallableWrapper\n f::Function\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"But since Function is an abstract type, every call to wrapper.f will require dynamic dispatch, due to the type instability of accessing the field f. Instead, you should write something like:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"struct MyCallableWrapper{F}\n f::F\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"which has nearly identical behavior but will be much faster (because the type instability is eliminated). Note that we do not impose F<:Function: this means callable objects which do not subtype Function are also allowed for the field f.","category":"page"},{"location":"manual/performance-tips/#Avoid-fields-with-abstract-containers","page":"Performance Tips","title":"Avoid fields with abstract containers","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The same best practices also work for container types:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> struct MySimpleContainer{A<:AbstractVector}\n a::A\n end\n\njulia> struct MyAmbiguousContainer{T}\n a::AbstractVector{T}\n end\n\njulia> struct MyAlsoAmbiguousContainer\n a::Array\n end","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> c = MySimpleContainer(1:3);\n\njulia> typeof(c)\nMySimpleContainer{UnitRange{Int64}}\n\njulia> c = MySimpleContainer([1:3;]);\n\njulia> typeof(c)\nMySimpleContainer{Vector{Int64}}\n\njulia> b = MyAmbiguousContainer(1:3);\n\njulia> typeof(b)\nMyAmbiguousContainer{Int64}\n\njulia> b = MyAmbiguousContainer([1:3;]);\n\njulia> typeof(b)\nMyAmbiguousContainer{Int64}\n\njulia> d = MyAlsoAmbiguousContainer(1:3);\n\njulia> typeof(d), typeof(d.a)\n(MyAlsoAmbiguousContainer, Vector{Int64})\n\njulia> d = MyAlsoAmbiguousContainer(1:1.0:3);\n\njulia> typeof(d), typeof(d.a)\n(MyAlsoAmbiguousContainer, Vector{Float64})\n","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For MySimpleContainer, the object is fully-specified by its type and parameters, so the compiler can generate optimized functions. In most instances, this will probably suffice.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"While the compiler can now do its job perfectly well, there are cases where you might wish that your code could do different things depending on the element type of a. Usually the best way to achieve this is to wrap your specific operation (here, foo) in a separate function:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function sumfoo(c::MySimpleContainer)\n s = 0\n for x in c.a\n s += foo(x)\n end\n s\n end\nsumfoo (generic function with 1 method)\n\njulia> foo(x::Integer) = x\nfoo (generic function with 1 method)\n\njulia> foo(x::AbstractFloat) = round(x)\nfoo (generic function with 2 methods)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This keeps things simple, while allowing the compiler to generate optimized code in all cases.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"However, there are cases where you may need to declare different versions of the outer function for different element types or types of the AbstractVector of the field a in MySimpleContainer. You could do it like this:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function myfunc(c::MySimpleContainer{<:AbstractArray{<:Integer}})\n return c.a[1]+1\n end\nmyfunc (generic function with 1 method)\n\njulia> function myfunc(c::MySimpleContainer{<:AbstractArray{<:AbstractFloat}})\n return c.a[1]+2\n end\nmyfunc (generic function with 2 methods)\n\njulia> function myfunc(c::MySimpleContainer{Vector{T}}) where T <: Integer\n return c.a[1]+3\n end\nmyfunc (generic function with 3 methods)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> myfunc(MySimpleContainer(1:3))\n2\n\njulia> myfunc(MySimpleContainer(1.0:3))\n3.0\n\njulia> myfunc(MySimpleContainer([1:3;]))\n4","category":"page"},{"location":"manual/performance-tips/#Annotate-values-taken-from-untyped-locations","page":"Performance Tips","title":"Annotate values taken from untyped locations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"It is often convenient to work with data structures that may contain values of any type (arrays of type Array{Any}). But, if you're using one of these structures and happen to know the type of an element, it helps to share this knowledge with the compiler:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function foo(a::Array{Any,1})\n x = a[1]::Int32\n b = x+1\n ...\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here, we happened to know that the first element of a would be an Int32. Making an annotation like this has the added benefit that it will raise a run-time error if the value is not of the expected type, potentially catching certain bugs earlier.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In the case that the type of a[1] is not known precisely, x can be declared via x = convert(Int32, a[1])::Int32. The use of the convert function allows a[1] to be any object convertible to an Int32 (such as UInt8), thus increasing the genericity of the code by loosening the type requirement. Notice that convert itself needs a type annotation in this context in order to achieve type stability. This is because the compiler cannot deduce the type of the return value of a function, even convert, unless the types of all the function's arguments are known.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Type annotation will not enhance (and can actually hinder) performance if the type is abstract, or constructed at run-time. This is because the compiler cannot use the annotation to specialize the subsequent code, and the type-check itself takes time. For example, in the code:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function nr(a, prec)\n ctype = prec == 32 ? Float32 : Float64\n b = Complex{ctype}(a)\n c = (b + 1.0f0)::Complex{ctype}\n abs(c)\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"the annotation of c harms performance. To write performant code involving types constructed at run-time, use the function-barrier technique discussed below, and ensure that the constructed type appears among the argument types of the kernel function so that the kernel operations are properly specialized by the compiler. For example, in the above snippet, as soon as b is constructed, it can be passed to another function k, the kernel. If, for example, function k declares b as an argument of type Complex{T}, where T is a type parameter, then a type annotation appearing in an assignment statement within k of the form:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"c = (b + 1.0f0)::Complex{T}","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"does not hinder performance (but does not help either) since the compiler can determine the type of c at the time k is compiled.","category":"page"},{"location":"manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing","page":"Performance Tips","title":"Be aware of when Julia avoids specializing","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"As a heuristic, Julia avoids automatically specializing on argument type parameters in three specific cases: Type, Function, and Vararg. Julia will always specialize when the argument is used within the method, but not if the argument is just passed through to another function. This usually has no performance impact at runtime and improves compiler performance. If you find it does have a performance impact at runtime in your case, you can trigger specialization by adding a type parameter to the method declaration. Here are some examples:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This will not specialize:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function f_type(t) # or t::Type\n x = ones(t, 10)\n return sum(map(sin, x))\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"but this will:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function g_type(t::Type{T}) where T\n x = ones(T, 10)\n return sum(map(sin, x))\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"These will not specialize:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"f_func(f, num) = ntuple(f, div(num, 2))\ng_func(g::Function, num) = ntuple(g, div(num, 2))","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"but this will:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"h_func(h::H, num) where {H} = ntuple(h, div(num, 2))","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This will not specialize:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"f_vararg(x::Int...) = tuple(x...)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"but this will:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"g_vararg(x::Vararg{Int, N}) where {N} = tuple(x...)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"One only needs to introduce a single type parameter to force specialization, even if the other types are unconstrained. For example, this will also specialize, and is useful when the arguments are not all of the same type:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"h_vararg(x::Vararg{Any, N}) where {N} = tuple(x...)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Note that @code_typed and friends will always show you specialized code, even if Julia would not normally specialize that method call. You need to check the method internals if you want to see whether specializations are generated when argument types are changed, i.e., if Base.specializations(@which f(...)) contains specializations for the argument in question.","category":"page"},{"location":"manual/performance-tips/#Break-functions-into-multiple-definitions","page":"Performance Tips","title":"Break functions into multiple definitions","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Writing a function as many small definitions allows the compiler to directly call the most applicable code, or even inline it.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here is an example of a \"compound function\" that should really be written as multiple definitions:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"using LinearAlgebra\n\nfunction mynorm(A)\n if isa(A, Vector)\n return sqrt(real(dot(A,A)))\n elseif isa(A, Matrix)\n return maximum(svdvals(A))\n else\n error(\"mynorm: invalid argument\")\n end\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This can be written more concisely and efficiently as:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"mynorm(x::Vector) = sqrt(real(dot(x, x)))\nmynorm(A::Matrix) = maximum(svdvals(A))","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"It should however be noted that the compiler is quite efficient at optimizing away the dead branches in code written as the mynorm example.","category":"page"},{"location":"manual/performance-tips/#Write-\"type-stable\"-functions","page":"Performance Tips","title":"Write \"type-stable\" functions","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When possible, it helps to ensure that a function always returns a value of the same type. Consider the following definition:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"pos(x) = x < 0 ? 0 : x","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Although this seems innocent enough, the problem is that 0 is an integer (of type Int) and x might be of any type. Thus, depending on the value of x, this function might return a value of either of two types. This behavior is allowed, and may be desirable in some cases. But it can easily be fixed as follows:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"pos(x) = x < 0 ? zero(x) : x","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"There is also a oneunit function, and a more general oftype(x, y) function, which returns y converted to the type of x.","category":"page"},{"location":"manual/performance-tips/#Avoid-changing-the-type-of-a-variable","page":"Performance Tips","title":"Avoid changing the type of a variable","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"An analogous \"type-stability\" problem exists for variables used repeatedly within a function:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function foo()\n x = 1\n for i = 1:10\n x /= rand()\n end\n return x\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Local variable x starts as an integer, and after one loop iteration becomes a floating-point number (the result of / operator). This makes it more difficult for the compiler to optimize the body of the loop. There are several possible fixes:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Initialize x with x = 1.0\nDeclare the type of x explicitly as x::Float64 = 1\nUse an explicit conversion by x = oneunit(Float64)\nInitialize with the first loop iteration, to x = 1 / rand(), then loop for i = 2:10","category":"page"},{"location":"manual/performance-tips/#kernel-functions","page":"Performance Tips","title":"Separate kernel functions (aka, function barriers)","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Many functions follow a pattern of performing some set-up work, and then running many iterations to perform a core computation. Where possible, it is a good idea to put these core computations in separate functions. For example, the following contrived function returns an array of a randomly-chosen type:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function strange_twos(n)\n a = Vector{rand(Bool) ? Int64 : Float64}(undef, n)\n for i = 1:n\n a[i] = 2\n end\n return a\n end;\n\njulia> strange_twos(3)\n3-element Vector{Int64}:\n 2\n 2\n 2","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This should be written as:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function fill_twos!(a)\n for i = eachindex(a)\n a[i] = 2\n end\n end;\n\njulia> function strange_twos(n)\n a = Vector{rand(Bool) ? Int64 : Float64}(undef, n)\n fill_twos!(a)\n return a\n end;\n\njulia> strange_twos(3)\n3-element Vector{Int64}:\n 2\n 2\n 2","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia's compiler specializes code for argument types at function boundaries, so in the original implementation it does not know the type of a during the loop (since it is chosen randomly). Therefore the second version is generally faster since the inner loop can be recompiled as part of fill_twos! for different types of a.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The second form is also often better style and can lead to more code reuse.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This pattern is used in several places in Julia Base. For example, see vcat and hcat in abstractarray.jl, or the fill! function, which we could have used instead of writing our own fill_twos!.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Functions like strange_twos occur when dealing with data of uncertain type, for example data loaded from an input file that might contain either integers, floats, strings, or something else.","category":"page"},{"location":"manual/performance-tips/#man-performance-value-type","page":"Performance Tips","title":"Types with values-as-parameters","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Let's say you want to create an N-dimensional array that has size 3 along each axis. Such arrays can be created like this:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> A = fill(5.0, (3, 3))\n3×3 Matrix{Float64}:\n 5.0 5.0 5.0\n 5.0 5.0 5.0\n 5.0 5.0 5.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This approach works very well: the compiler can figure out that A is an Array{Float64,2} because it knows the type of the fill value (5.0::Float64) and the dimensionality ((3, 3)::NTuple{2,Int}). This implies that the compiler can generate very efficient code for any future usage of A in the same function.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"But now let's say you want to write a function that creates a 3×3×... array in arbitrary dimensions; you might be tempted to write a function","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function array3(fillval, N)\n fill(fillval, ntuple(d->3, N))\n end\narray3 (generic function with 1 method)\n\njulia> array3(5.0, 2)\n3×3 Matrix{Float64}:\n 5.0 5.0 5.0\n 5.0 5.0 5.0\n 5.0 5.0 5.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This works, but (as you can verify for yourself using @code_warntype array3(5.0, 2)) the problem is that the output type cannot be inferred: the argument N is a value of type Int, and type-inference does not (and cannot) predict its value in advance. This means that code using the output of this function has to be conservative, checking the type on each access of A; such code will be very slow.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Now, one very good way to solve such problems is by using the function-barrier technique. However, in some cases you might want to eliminate the type-instability altogether. In such cases, one approach is to pass the dimensionality as a parameter, for example through Val{T}() (see \"Value types\"):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function array3(fillval, ::Val{N}) where N\n fill(fillval, ntuple(d->3, Val(N)))\n end\narray3 (generic function with 1 method)\n\njulia> array3(5.0, Val(2))\n3×3 Matrix{Float64}:\n 5.0 5.0 5.0\n 5.0 5.0 5.0\n 5.0 5.0 5.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia has a specialized version of ntuple that accepts a Val{::Int} instance as the second parameter; by passing N as a type-parameter, you make its \"value\" known to the compiler. Consequently, this version of array3 allows the compiler to predict the return type.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"However, making use of such techniques can be surprisingly subtle. For example, it would be of no help if you called array3 from a function like this:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function call_array3(fillval, n)\n A = array3(fillval, Val(n))\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here, you've created the same problem all over again: the compiler can't guess what n is, so it doesn't know the type of Val(n). Attempting to use Val, but doing so incorrectly, can easily make performance worse in many situations. (Only in situations where you're effectively combining Val with the function-barrier trick, to make the kernel function more efficient, should code like the above be used.)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"An example of correct usage of Val would be:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function filter3(A::AbstractArray{T,N}) where {T,N}\n kernel = array3(1, Val(N))\n filter(A, kernel)\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In this example, N is passed as a parameter, so its \"value\" is known to the compiler. Essentially, Val(T) works only when T is either hard-coded/literal (Val(3)) or already specified in the type-domain.","category":"page"},{"location":"manual/performance-tips/#The-dangers-of-abusing-multiple-dispatch-(aka,-more-on-types-with-values-as-parameters)","page":"Performance Tips","title":"The dangers of abusing multiple dispatch (aka, more on types with values-as-parameters)","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Once one learns to appreciate multiple dispatch, there's an understandable tendency to go overboard and try to use it for everything. For example, you might imagine using it to store information, e.g.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"struct Car{Make, Model}\n year::Int\n ...more fields...\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"and then dispatch on objects like Car{:Honda,:Accord}(year, args...).","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This might be worthwhile when either of the following are true:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"You require CPU-intensive processing on each Car, and it becomes vastly more efficient if you know the Make and Model at compile time and the total number of different Make or Model that will be used is not too large.\nYou have homogeneous lists of the same type of Car to process, so that you can store them all in an Array{Car{:Honda,:Accord},N}.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When the latter holds, a function processing such a homogeneous array can be productively specialized: Julia knows the type of each element in advance (all objects in the container have the same concrete type), so Julia can \"look up\" the correct method calls when the function is being compiled (obviating the need to check at run-time) and thereby emit efficient code for processing the whole list.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When these do not hold, then it's likely that you'll get no benefit; worse, the resulting \"combinatorial explosion of types\" will be counterproductive. If items[i+1] has a different type than item[i], Julia has to look up the type at run-time, search for the appropriate method in method tables, decide (via type intersection) which one matches, determine whether it has been JIT-compiled yet (and do so if not), and then make the call. In essence, you're asking the full type- system and JIT-compilation machinery to basically execute the equivalent of a switch statement or dictionary lookup in your own code.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Some run-time benchmarks comparing (1) type dispatch, (2) dictionary lookup, and (3) a \"switch\" statement can be found on the mailing list.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Perhaps even worse than the run-time impact is the compile-time impact: Julia will compile specialized functions for each different Car{Make, Model}; if you have hundreds or thousands of such types, then every function that accepts such an object as a parameter (from a custom get_year function you might write yourself, to the generic push! function in Julia Base) will have hundreds or thousands of variants compiled for it. Each of these increases the size of the cache of compiled code, the length of internal lists of methods, etc. Excess enthusiasm for values-as-parameters can easily waste enormous resources.","category":"page"},{"location":"manual/performance-tips/#man-performance-column-major","page":"Performance Tips","title":"Access arrays in memory order, along columns","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Multidimensional arrays in Julia are stored in column-major order. This means that arrays are stacked one column at a time. This can be verified using the vec function or the syntax [:] as shown below (notice that the array is ordered [1 3 2 4], not [1 2 3 4]):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> x[:]\n4-element Vector{Int64}:\n 1\n 3\n 2\n 4","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This convention for ordering arrays is common in many languages like Fortran, Matlab, and R (to name a few). The alternative to column-major ordering is row-major ordering, which is the convention adopted by C and Python (numpy) among other languages. Remembering the ordering of arrays can have significant performance effects when looping over arrays. A rule of thumb to keep in mind is that with column-major arrays, the first index changes most rapidly. Essentially this means that looping will be faster if the inner-most loop index is the first to appear in a slice expression. Keep in mind that indexing an array with : is an implicit loop that iteratively accesses all elements within a particular dimension; it can be faster to extract columns than rows, for example.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Consider the following contrived example. Imagine we wanted to write a function that accepts a Vector and returns a square Matrix with either the rows or the columns filled with copies of the input vector. Assume that it is not important whether rows or columns are filled with these copies (perhaps the rest of the code can be easily adapted accordingly). We could conceivably do this in at least four ways (in addition to the recommended call to the built-in repeat):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function copy_cols(x::Vector{T}) where T\n inds = axes(x, 1)\n out = similar(Array{T}, inds, inds)\n for i = inds\n out[:, i] = x\n end\n return out\nend\n\nfunction copy_rows(x::Vector{T}) where T\n inds = axes(x, 1)\n out = similar(Array{T}, inds, inds)\n for i = inds\n out[i, :] = x\n end\n return out\nend\n\nfunction copy_col_row(x::Vector{T}) where T\n inds = axes(x, 1)\n out = similar(Array{T}, inds, inds)\n for col = inds, row = inds\n out[row, col] = x[row]\n end\n return out\nend\n\nfunction copy_row_col(x::Vector{T}) where T\n inds = axes(x, 1)\n out = similar(Array{T}, inds, inds)\n for row = inds, col = inds\n out[row, col] = x[col]\n end\n return out\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Now we will time each of these functions using the same random 10000 by 1 input vector:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = randn(10000);\n\njulia> fmt(f) = println(rpad(string(f)*\": \", 14, ' '), @elapsed f(x))\n\njulia> map(fmt, [copy_cols, copy_rows, copy_col_row, copy_row_col]);\ncopy_cols: 0.331706323\ncopy_rows: 1.799009911\ncopy_col_row: 0.415630047\ncopy_row_col: 1.721531501","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Notice that copy_cols is much faster than copy_rows. This is expected because copy_cols respects the column-based memory layout of the Matrix and fills it one column at a time. Additionally, copy_col_row is much faster than copy_row_col because it follows our rule of thumb that the first element to appear in a slice expression should be coupled with the inner-most loop.","category":"page"},{"location":"manual/performance-tips/#Pre-allocating-outputs","page":"Performance Tips","title":"Pre-allocating outputs","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If your function returns an Array or some other complex type, it may have to allocate memory. Unfortunately, oftentimes allocation and its converse, garbage collection, are substantial bottlenecks.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Sometimes you can circumvent the need to allocate memory on each function call by preallocating the output. As a trivial example, compare","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function xinc(x)\n return [x, x+1, x+2]\n end;\n\njulia> function loopinc()\n y = 0\n for i = 1:10^7\n ret = xinc(i)\n y += ret[2]\n end\n return y\n end;","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"with","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function xinc!(ret::AbstractVector{T}, x::T) where T\n ret[1] = x\n ret[2] = x+1\n ret[3] = x+2\n nothing\n end;\n\njulia> function loopinc_prealloc()\n ret = Vector{Int}(undef, 3)\n y = 0\n for i = 1:10^7\n xinc!(ret, i)\n y += ret[2]\n end\n return y\n end;","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Timing results:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> @time loopinc()\n 0.529894 seconds (40.00 M allocations: 1.490 GiB, 12.14% gc time)\n50000015000000\n\njulia> @time loopinc_prealloc()\n 0.030850 seconds (6 allocations: 288 bytes)\n50000015000000","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Preallocation has other advantages, for example by allowing the caller to control the \"output\" type from an algorithm. In the example above, we could have passed a SubArray rather than an Array, had we so desired.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Taken to its extreme, pre-allocation can make your code uglier, so performance measurements and some judgment may be required. However, for \"vectorized\" (element-wise) functions, the convenient syntax x .= f.(y) can be used for in-place operations with fused loops and no temporary arrays (see the dot syntax for vectorizing functions).","category":"page"},{"location":"manual/performance-tips/#man-perftips-mutablearithmetics","page":"Performance Tips","title":"Use MutableArithmetics for more control over allocation for mutable arithmetic types","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Some Number subtypes, such as BigInt or BigFloat, may be implemented as mutable struct types, or they may have mutable components. The arithmetic interfaces in Julia Base usually opt for convenience over efficiency in such cases, so using them in a naive manner may result in suboptimal performance. The abstractions of the MutableArithmetics package, on the other hand, make it possible to exploit the mutability of such types for writing fast code that allocates only as much as necessary. MutableArithmetics also makes it possible to copy values of mutable arithmetic types explicitly when necessary. MutableArithmetics is a user package and is not affiliated with the Julia project.","category":"page"},{"location":"manual/performance-tips/#More-dots:-Fuse-vectorized-operations","page":"Performance Tips","title":"More dots: Fuse vectorized operations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia has a special dot syntax that converts any scalar function into a \"vectorized\" function call, and any operator into a \"vectorized\" operator, with the special property that nested \"dot calls\" are fusing: they are combined at the syntax level into a single loop, without allocating temporary arrays. If you use .= and similar assignment operators, the result can also be stored in-place in a pre-allocated array (see above).","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In a linear-algebra context, this means that even though operations like vector + vector and vector * scalar are defined, it can be advantageous to instead use vector .+ vector and vector .* scalar because the resulting loops can be fused with surrounding computations. For example, consider the two functions:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> f(x) = 3x.^2 + 4x + 7x.^3;\n\njulia> fdot(x) = @. 3x^2 + 4x + 7x^3; # equivalent to 3 .* x.^2 .+ 4 .* x .+ 7 .* x.^3","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Both f and fdot compute the same thing. However, fdot (defined with the help of the @. macro) is significantly faster when applied to an array:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = rand(10^6);\n\njulia> @time f(x);\n 0.019049 seconds (16 allocations: 45.777 MiB, 18.59% gc time)\n\njulia> @time fdot(x);\n 0.002790 seconds (6 allocations: 7.630 MiB)\n\njulia> @time f.(x);\n 0.002626 seconds (8 allocations: 7.630 MiB)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"That is, fdot(x) is ten times faster and allocates 1/6 the memory of f(x), because each * and + operation in f(x) allocates a new temporary array and executes in a separate loop. In this example f.(x) is as fast as fdot(x) but in many contexts it is more convenient to sprinkle some dots in your expressions than to define a separate function for each vectorized operation.","category":"page"},{"location":"manual/performance-tips/#man-performance-unfuse","page":"Performance Tips","title":"Fewer dots: Unfuse certain intermediate broadcasts","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The dot loop fusion mentioned above enables concise and idiomatic code to express highly performant operations. However, it is important to remember that the fused operation will be computed at every iteration of the broadcast. This means that in some situations, particularly in the presence of composed or multidimensional broadcasts, an expression with dot calls may be computing a function more times than intended. As an example, say we want to build a random matrix whose rows have Euclidean norm one. We might write something like the following:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = rand(1000, 1000);\n\njulia> d = sum(abs2, x; dims=2);\n\njulia> @time x ./= sqrt.(d);\n 0.002049 seconds (4 allocations: 96 bytes)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This will work. However, this expression will actually recompute sqrt(d[i]) for every element in the row x[i, :], meaning that many more square roots are computed than necessary. To see precisely over which indices the broadcast will iterate, we can call Broadcast.combine_axes on the arguments of the fused expression. This will return a tuple of ranges whose entries correspond to the axes of iteration; the product of lengths of these ranges will be the total number of calls to the fused operation.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"It follows that when some components of the broadcast expression are constant along an axis—like the sqrt along the second dimension in the preceding example—there is potential for a performance improvement by forcibly \"unfusing\" those components, i.e. allocating the result of the broadcasted operation in advance and reusing the cached value along its constant axis. Some such potential approaches are to use temporary variables, wrap components of a dot expression in identity, or use an equivalent intrinsically vectorized (but non-fused) function.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> @time let s = sqrt.(d); x ./= s end;\n 0.000809 seconds (5 allocations: 8.031 KiB)\n\njulia> @time x ./= identity(sqrt.(d));\n 0.000608 seconds (5 allocations: 8.031 KiB)\n\njulia> @time x ./= map(sqrt, d);\n 0.000611 seconds (4 allocations: 8.016 KiB)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Any of these options yields approximately a three-fold speedup at the cost of an allocation; for large broadcastables this speedup can be asymptotically very large.","category":"page"},{"location":"manual/performance-tips/#man-performance-views","page":"Performance Tips","title":"Consider using views for slices","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In Julia, an array \"slice\" expression like array[1:5, :] creates a copy of that data (except on the left-hand side of an assignment, where array[1:5, :] = ... assigns in-place to that portion of array). If you are doing many operations on the slice, this can be good for performance because it is more efficient to work with a smaller contiguous copy than it would be to index into the original array. On the other hand, if you are just doing a few simple operations on the slice, the cost of the allocation and copy operations can be substantial.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"An alternative is to create a \"view\" of the array, which is an array object (a SubArray) that actually references the data of the original array in-place, without making a copy. (If you write to a view, it modifies the original array's data as well.) This can be done for individual slices by calling view, or more simply for a whole expression or block of code by putting @views in front of that expression. For example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> fcopy(x) = sum(x[2:end-1]);\n\njulia> @views fview(x) = sum(x[2:end-1]);\n\njulia> x = rand(10^6);\n\njulia> @time fcopy(x);\n 0.003051 seconds (3 allocations: 7.629 MB)\n\njulia> @time fview(x);\n 0.001020 seconds (1 allocation: 16 bytes)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Notice both the 3× speedup and the decreased memory allocation of the fview version of the function.","category":"page"},{"location":"manual/performance-tips/#Copying-data-is-not-always-bad","page":"Performance Tips","title":"Copying data is not always bad","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Arrays are stored contiguously in memory, lending themselves to CPU vectorization and fewer memory accesses due to caching. These are the same reasons that it is recommended to access arrays in column-major order (see above). Irregular access patterns and non-contiguous views can drastically slow down computations on arrays because of non-sequential memory access.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Copying irregularly-accessed data into a contiguous array before repeatedly accessing it can result in a large speedup, such as in the example below. Here, a matrix is being accessed at randomly-shuffled indices before being multiplied. Copying into plain arrays speeds up the multiplication even with the added cost of copying and allocation.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using Random\n\njulia> A = randn(3000, 3000);\n\njulia> x = randn(2000);\n\njulia> inds = shuffle(1:3000)[1:2000];\n\njulia> function iterated_neural_network(A, x, depth)\n for _ in 1:depth\n x .= max.(0, A * x)\n end\n argmax(x)\n end\n\njulia> @time iterated_neural_network(view(A, inds, inds), x, 10)\n 0.324903 seconds (12 allocations: 157.562 KiB)\n1569\n\njulia> @time iterated_neural_network(A[inds, inds], x, 10)\n 0.054576 seconds (13 allocations: 30.671 MiB, 13.33% gc time)\n1569","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Provided there is enough memory, the cost of copying the view to an array is outweighed by the speed boost from doing the repeated matrix multiplications on a contiguous array.","category":"page"},{"location":"manual/performance-tips/#Consider-StaticArrays.jl-for-small-fixed-size-vector/matrix-operations","page":"Performance Tips","title":"Consider StaticArrays.jl for small fixed-size vector/matrix operations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If your application involves many small (< 100 element) arrays of fixed sizes (i.e. the size is known prior to execution), then you might want to consider using the StaticArrays.jl package. This package allows you to represent such arrays in a way that avoids unnecessary heap allocations and allows the compiler to specialize code for the size of the array, e.g. by completely unrolling vector operations (eliminating the loops) and storing elements in CPU registers.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For example, if you are doing computations with 2d geometries, you might have many computations with 2-component vectors. By using the SVector type from StaticArrays.jl, you can use convenient vector notation and operations like norm(3v - w) on vectors v and w, while allowing the compiler to unroll the code to a minimal computation equivalent to @inbounds hypot(3v[1]-w[1], 3v[2]-w[2]).","category":"page"},{"location":"manual/performance-tips/#Avoid-string-interpolation-for-I/O","page":"Performance Tips","title":"Avoid string interpolation for I/O","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When writing data to a file (or other I/O device), forming extra intermediate strings is a source of overhead. Instead of:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"println(file, \"$a $b\")","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"use:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"println(file, a, \" \", b)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The first version of the code forms a string, then writes it to the file, while the second version writes values directly to the file. Also notice that in some cases string interpolation can be harder to read. Consider:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"println(file, \"$(f(a))$(f(b))\")","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"versus:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"println(file, f(a), f(b))","category":"page"},{"location":"manual/performance-tips/#Avoid-eager-string-materialization","page":"Performance Tips","title":"Avoid eager string materialization","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In settings where a string representation of an object is only needed conditionally (e.g. in error paths of functions or conditional warnings such as deprecations), it is advisable to avoid the overhead of eagerly materializing the string. Since Julia 1.8, this can be achieved via LazyString and the corresponding string macro @lazy_str.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For example, instead of:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Base.depwarn(\"`foo` is deprecated for type $(typeof(x))\", :bar)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"use:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Base.depwarn(lazy\"`foo` is deprecated for type $(typeof(x))\", :bar)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"or the equivalent macro-free version:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Base.depwarn(LazyString(\"`foo` is deprecated for type \", typeof(x)), :bar)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Through this approach, the interpolated string will only be constructed when it is actually displayed.","category":"page"},{"location":"manual/performance-tips/#Optimize-network-I/O-during-parallel-execution","page":"Performance Tips","title":"Optimize network I/O during parallel execution","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When executing a remote function in parallel:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"using Distributed\n\nresponses = Vector{Any}(undef, nworkers())\n@sync begin\n for (idx, pid) in enumerate(workers())\n @async responses[idx] = remotecall_fetch(foo, pid, args...)\n end\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"is faster than:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"using Distributed\n\nrefs = Vector{Any}(undef, nworkers())\nfor (idx, pid) in enumerate(workers())\n refs[idx] = @spawnat pid foo(args...)\nend\nresponses = [fetch(r) for r in refs]","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The former results in a single network round-trip to every worker, while the latter results in two network calls - first by the @spawnat and the second due to the fetch (or even a wait). The fetch/wait is also being executed serially resulting in an overall poorer performance.","category":"page"},{"location":"manual/performance-tips/#Fix-deprecation-warnings","page":"Performance Tips","title":"Fix deprecation warnings","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"A deprecated function internally performs a lookup in order to print a relevant warning only once. This extra lookup can cause a significant slowdown, so all uses of deprecated functions should be modified as suggested by the warnings.","category":"page"},{"location":"manual/performance-tips/#Tweaks","page":"Performance Tips","title":"Tweaks","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"These are some minor points that might help in tight inner loops.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Avoid unnecessary arrays. For example, instead of sum([x,y,z]) use x+y+z.\nUse abs2(z) instead of abs(z)^2 for complex z. In general, try to rewrite code to use abs2 instead of abs for complex arguments.\nUse div(x,y) for truncating division of integers instead of trunc(x/y), fld(x,y) instead of floor(x/y), and cld(x,y) instead of ceil(x/y).","category":"page"},{"location":"manual/performance-tips/#man-performance-annotations","page":"Performance Tips","title":"Performance Annotations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Sometimes you can enable better optimization by promising certain program properties.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Use @inbounds to eliminate array bounds checking within expressions. Be certain before doing this. If the subscripts are ever out of bounds, you may suffer crashes or silent corruption.\nUse @fastmath to allow floating point optimizations that are correct for real numbers, but lead to differences for IEEE numbers. Be careful when doing this, as this may change numerical results. This corresponds to the -ffast-math option of clang.\nWrite @simd in front of for loops to promise that the iterations are independent and may be reordered. Note that in many cases, Julia can automatically vectorize code without the @simd macro; it is only beneficial in cases where such a transformation would otherwise be illegal, including cases like allowing floating-point re-associativity and ignoring dependent memory accesses (@simd ivdep). Again, be very careful when asserting @simd as erroneously annotating a loop with dependent iterations may result in unexpected results. In particular, note that setindex! on some AbstractArray subtypes is inherently dependent upon iteration order. This feature is experimental and could change or disappear in future versions of Julia.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The common idiom of using 1:n to index into an AbstractArray is not safe if the Array uses unconventional indexing, and may cause a segmentation fault if bounds checking is turned off. Use LinearIndices(x) or eachindex(x) instead (see also Arrays with custom indices).","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"note: Note\nWhile @simd needs to be placed directly in front of an innermost for loop, both @inbounds and @fastmath can be applied to either single expressions or all the expressions that appear within nested blocks of code, e.g., using @inbounds begin or @inbounds for ....","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here is an example with both @inbounds and @simd markup (we here use @noinline to prevent the optimizer from trying to be too clever and defeat our benchmark):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"@noinline function inner(x, y)\n s = zero(eltype(x))\n for i=eachindex(x)\n @inbounds s += x[i]*y[i]\n end\n return s\nend\n\n@noinline function innersimd(x, y)\n s = zero(eltype(x))\n @simd for i = eachindex(x)\n @inbounds s += x[i] * y[i]\n end\n return s\nend\n\nfunction timeit(n, reps)\n x = rand(Float32, n)\n y = rand(Float32, n)\n s = zero(Float64)\n time = @elapsed for j in 1:reps\n s += inner(x, y)\n end\n println(\"GFlop/sec = \", 2n*reps / time*1E-9)\n time = @elapsed for j in 1:reps\n s += innersimd(x, y)\n end\n println(\"GFlop/sec (SIMD) = \", 2n*reps / time*1E-9)\nend\n\ntimeit(1000, 1000)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"On a computer with a 2.4GHz Intel Core i5 processor, this produces:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"GFlop/sec = 1.9467069505224963\nGFlop/sec (SIMD) = 17.578554163920018","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"(GFlop/sec measures the performance, and larger numbers are better.)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here is an example with all three kinds of markup. This program first calculates the finite difference of a one-dimensional array, and then evaluates the L2-norm of the result:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function init!(u::Vector)\n n = length(u)\n dx = 1.0 / (n-1)\n @fastmath @inbounds @simd for i in 1:n #by asserting that `u` is a `Vector` we can assume it has 1-based indexing\n u[i] = sin(2pi*dx*i)\n end\nend\n\nfunction deriv!(u::Vector, du)\n n = length(u)\n dx = 1.0 / (n-1)\n @fastmath @inbounds du[1] = (u[2] - u[1]) / dx\n @fastmath @inbounds @simd for i in 2:n-1\n du[i] = (u[i+1] - u[i-1]) / (2*dx)\n end\n @fastmath @inbounds du[n] = (u[n] - u[n-1]) / dx\nend\n\nfunction mynorm(u::Vector)\n n = length(u)\n T = eltype(u)\n s = zero(T)\n @fastmath @inbounds @simd for i in 1:n\n s += u[i]^2\n end\n @fastmath @inbounds return sqrt(s)\nend\n\nfunction main()\n n = 2000\n u = Vector{Float64}(undef, n)\n init!(u)\n du = similar(u)\n\n deriv!(u, du)\n nu = mynorm(du)\n\n @time for i in 1:10^6\n deriv!(u, du)\n nu = mynorm(du)\n end\n\n println(nu)\nend\n\nmain()","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"On a computer with a 2.7 GHz Intel Core i7 processor, this produces:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"$ julia wave.jl;\n 1.207814709 seconds\n4.443986180758249\n\n$ julia --math-mode=ieee wave.jl;\n 4.487083643 seconds\n4.443986180758249","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here, the option --math-mode=ieee disables the @fastmath macro, so that we can compare results.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In this case, the speedup due to @fastmath is a factor of about 3.7. This is unusually large – in general, the speedup will be smaller. (In this particular example, the working set of the benchmark is small enough to fit into the L1 cache of the processor, so that memory access latency does not play a role, and computing time is dominated by CPU usage. In many real world programs this is not the case.) Also, in this case this optimization does not change the result – in general, the result will be slightly different. In some cases, especially for numerically unstable algorithms, the result can be very different.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The annotation @fastmath re-arranges floating point expressions, e.g. changing the order of evaluation, or assuming that certain special cases (inf, nan) cannot occur. In this case (and on this particular computer), the main difference is that the expression 1 / (2*dx) in the function deriv is hoisted out of the loop (i.e. calculated outside the loop), as if one had written idx = 1 / (2*dx). In the loop, the expression ... / (2*dx) then becomes ... * idx, which is much faster to evaluate. Of course, both the actual optimization that is applied by the compiler as well as the resulting speedup depend very much on the hardware. You can examine the change in generated code by using Julia's code_native function.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Note that @fastmath also assumes that NaNs will not occur during the computation, which can lead to surprising behavior:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> f(x) = isnan(x);\n\njulia> f(NaN)\ntrue\n\njulia> f_fast(x) = @fastmath isnan(x);\n\njulia> f_fast(NaN)\nfalse","category":"page"},{"location":"manual/performance-tips/#Treat-Subnormal-Numbers-as-Zeros","page":"Performance Tips","title":"Treat Subnormal Numbers as Zeros","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Subnormal numbers, formerly called denormal numbers, are useful in many contexts, but incur a performance penalty on some hardware. A call set_zero_subnormals(true) grants permission for floating-point operations to treat subnormal inputs or outputs as zeros, which may improve performance on some hardware. A call set_zero_subnormals(false) enforces strict IEEE behavior for subnormal numbers.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Below is an example where subnormals noticeably impact performance on some hardware:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function timestep(b::Vector{T}, a::Vector{T}, Δt::T) where T\n @assert length(a)==length(b)\n n = length(b)\n b[1] = 1 # Boundary condition\n for i=2:n-1\n b[i] = a[i] + (a[i-1] - T(2)*a[i] + a[i+1]) * Δt\n end\n b[n] = 0 # Boundary condition\nend\n\nfunction heatflow(a::Vector{T}, nstep::Integer) where T\n b = similar(a)\n for t=1:div(nstep,2) # Assume nstep is even\n timestep(b,a,T(0.1))\n timestep(a,b,T(0.1))\n end\nend\n\nheatflow(zeros(Float32,10),2) # Force compilation\nfor trial=1:6\n a = zeros(Float32,1000)\n set_zero_subnormals(iseven(trial)) # Odd trials use strict IEEE arithmetic\n @time heatflow(a,1000)\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This gives an output similar to","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":" 0.002202 seconds (1 allocation: 4.063 KiB)\n 0.001502 seconds (1 allocation: 4.063 KiB)\n 0.002139 seconds (1 allocation: 4.063 KiB)\n 0.001454 seconds (1 allocation: 4.063 KiB)\n 0.002115 seconds (1 allocation: 4.063 KiB)\n 0.001455 seconds (1 allocation: 4.063 KiB)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Note how each even iteration is significantly faster.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This example generates many subnormal numbers because the values in a become an exponentially decreasing curve, which slowly flattens out over time.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Treating subnormals as zeros should be used with caution, because doing so breaks some identities, such as x-y == 0 implies x == y:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = 3f-38; y = 2f-38;\n\njulia> set_zero_subnormals(true); (x - y, x == y)\n(0.0f0, false)\n\njulia> set_zero_subnormals(false); (x - y, x == y)\n(1.0000001f-38, false)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In some applications, an alternative to zeroing subnormal numbers is to inject a tiny bit of noise. For example, instead of initializing a with zeros, initialize it with:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"a = rand(Float32,1000) * 1.f-9","category":"page"},{"location":"manual/performance-tips/#man-code-warntype","page":"Performance Tips","title":"@code_warntype","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The macro @code_warntype (or its function variant code_warntype) can sometimes be helpful in diagnosing type-related problems. Here's an example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> @noinline pos(x) = x < 0 ? 0 : x;\n\njulia> function f(x)\n y = pos(x)\n return sin(y*x + 1)\n end;\n\njulia> @code_warntype f(3.2)\nMethodInstance for f(::Float64)\n from f(x) @ Main REPL[9]:1\nArguments\n #self#::Core.Const(f)\n x::Float64\nLocals\n y::Union{Float64, Int64}\nBody::Float64\n1 ─ (y = Main.pos(x))\n│ %2 = (y * x)::Float64\n│ %3 = (%2 + 1)::Float64\n│ %4 = Main.sin(%3)::Float64\n└── return %4","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Interpreting the output of @code_warntype, like that of its cousins @code_lowered, @code_typed, @code_llvm, and @code_native, takes a little practice. Your code is being presented in form that has been heavily digested on its way to generating compiled machine code. Most of the expressions are annotated by a type, indicated by the ::T (where T might be Float64, for example). The most important characteristic of @code_warntype is that non-concrete types are displayed in red; since this document is written in Markdown, which has no color, in this document, red text is denoted by uppercase.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"At the top, the inferred return type of the function is shown as Body::Float64. The next lines represent the body of f in Julia's SSA IR form. The numbered boxes are labels and represent targets for jumps (via goto) in your code. Looking at the body, you can see that the first thing that happens is that pos is called and the return value has been inferred as the Union type Union{Float64, Int64} shown in uppercase since it is a non-concrete type. This means that we cannot know the exact return type of pos based on the input types. However, the result of y*xis a Float64 no matter if y is a Float64 or Int64 The net result is that f(x::Float64) will not be type-unstable in its output, even if some of the intermediate computations are type-unstable.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"How you use this information is up to you. Obviously, it would be far and away best to fix pos to be type-stable: if you did so, all of the variables in f would be concrete, and its performance would be optimal. However, there are circumstances where this kind of ephemeral type instability might not matter too much: for example, if pos is never used in isolation, the fact that f's output is type-stable (for Float64 inputs) will shield later code from the propagating effects of type instability. This is particularly relevant in cases where fixing the type instability is difficult or impossible. In such cases, the tips above (e.g., adding type annotations and/or breaking up functions) are your best tools to contain the \"damage\" from type instability. Also, note that even Julia Base has functions that are type unstable. For example, the function findfirst returns the index into an array where a key is found, or nothing if it is not found, a clear type instability. In order to make it easier to find the type instabilities that are likely to be important, Unions containing either missing or nothing are color highlighted in yellow, instead of red.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The following examples may help you interpret expressions marked as containing non-leaf types:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Function body starting with Body::Union{T1,T2})\nInterpretation: function with unstable return type\nSuggestion: make the return value type-stable, even if you have to annotate it\ninvoke Main.g(%%x::Int64)::Union{Float64, Int64}\nInterpretation: call to a type-unstable function g.\nSuggestion: fix the function, or if necessary annotate the return value\ninvoke Base.getindex(%%x::Array{Any,1}, 1::Int64)::Any\nInterpretation: accessing elements of poorly-typed arrays\nSuggestion: use arrays with better-defined types, or if necessary annotate the type of individual element accesses\nBase.getfield(%%x, :(:data))::Array{Float64,N} where N\nInterpretation: getting a field that is of non-leaf type. In this case, the type of x, say ArrayContainer, had a field data::Array{T}. But Array needs the dimension N, too, to be a concrete type.\nSuggestion: use concrete types like Array{T,3} or Array{T,N}, where N is now a parameter of ArrayContainer","category":"page"},{"location":"manual/performance-tips/#man-performance-captured","page":"Performance Tips","title":"Performance of captured variable","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Consider the following example that defines an inner function:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function abmult(r::Int)\n if r < 0\n r = -r\n end\n f = x -> x * r\n return f\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Function abmult returns a function f that multiplies its argument by the absolute value of r. The inner function assigned to f is called a \"closure\". Inner functions are also used by the language for do-blocks and for generator expressions.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This style of code presents performance challenges for the language. The parser, when translating it into lower-level instructions, substantially reorganizes the above code by extracting the inner function to a separate code block. \"Captured\" variables such as r that are shared by inner functions and their enclosing scope are also extracted into a heap-allocated \"box\" accessible to both inner and outer functions because the language specifies that r in the inner scope must be identical to r in the outer scope even after the outer scope (or another inner function) modifies r.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The discussion in the preceding paragraph referred to the \"parser\", that is, the phase of compilation that takes place when the module containing abmult is first loaded, as opposed to the later phase when it is first invoked. The parser does not \"know\" that Int is a fixed type, or that the statement r = -r transforms an Int to another Int. The magic of type inference takes place in the later phase of compilation.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Thus, the parser does not know that r has a fixed type (Int). nor that r does not change value once the inner function is created (so that the box is unneeded). Therefore, the parser emits code for box that holds an object with an abstract type such as Any, which requires run-time type dispatch for each occurrence of r. This can be verified by applying @code_warntype to the above function. Both the boxing and the run-time type dispatch can cause loss of performance.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If captured variables are used in a performance-critical section of the code, then the following tips help ensure that their use is performant. First, if it is known that a captured variable does not change its type, then this can be declared explicitly with a type annotation (on the variable, not the right-hand side):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function abmult2(r0::Int)\n r::Int = r0\n if r < 0\n r = -r\n end\n f = x -> x * r\n return f\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The type annotation partially recovers lost performance due to capturing because the parser can associate a concrete type to the object in the box. Going further, if the captured variable does not need to be boxed at all (because it will not be reassigned after the closure is created), this can be indicated with let blocks as follows.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function abmult3(r::Int)\n if r < 0\n r = -r\n end\n f = let r = r\n x -> x * r\n end\n return f\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The let block creates a new variable r whose scope is only the inner function. The second technique recovers full language performance in the presence of captured variables. Note that this is a rapidly evolving aspect of the compiler, and it is likely that future releases will not require this degree of programmer annotation to attain performance. In the mean time, some user-contributed packages like FastClosures automate the insertion of let statements as in abmult3.","category":"page"},{"location":"manual/performance-tips/#man-multithreading-linear-algebra","page":"Performance Tips","title":"Multithreading and linear algebra","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This section applies to multithreaded Julia code which, in each thread, performs linear algebra operations. Indeed, these linear algebra operations involve BLAS / LAPACK calls, which are themselves multithreaded. In this case, one must ensure that cores aren't oversubscribed due to the two different types of multithreading.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia compiles and uses its own copy of OpenBLAS for linear algebra, whose number of threads is controlled by the environment variable OPENBLAS_NUM_THREADS. It can either be set as a command line option when launching Julia, or modified during the Julia session with BLAS.set_num_threads(N) (the submodule BLAS is exported by using LinearAlgebra). Its current value can be accessed with BLAS.get_num_threads().","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When the user does not specify anything, Julia tries to choose a reasonable value for the number of OpenBLAS threads (e.g. based on the platform, the Julia version, etc.). However, it is generally recommended to check and set the value manually. The OpenBLAS behavior is as follows:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If OPENBLAS_NUM_THREADS=1, OpenBLAS uses the calling Julia thread(s), i.e. it \"lives in\" the Julia thread that runs the computation.\nIf OPENBLAS_NUM_THREADS=N>1, OpenBLAS creates and manages its own pool of threads (N in total). There is just one OpenBLAS thread pool shared among all Julia threads.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When you start Julia in multithreaded mode with JULIA_NUM_THREADS=X, it is generally recommended to set OPENBLAS_NUM_THREADS=1. Given the behavior described above, increasing the number of BLAS threads to N>1 can very easily lead to worse performance, in particular when N< c = 'x'\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\njulia> typeof(c)\nChar","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can easily convert a Char to its integer value, i.e. code point:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> c = Int('x')\n120\n\njulia> typeof(c)\nInt64","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"On 32-bit architectures, typeof(c) will be Int32. You can convert an integer value back to a Char just as easily:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> Char(120)\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Not all integer values are valid Unicode code points, but for performance, the Char conversion does not check that every character value is valid. If you want to check that each converted value is a valid code point, use the isvalid function:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> Char(0x110000)\n'\\U110000': Unicode U+110000 (category In: Invalid, too high)\n\njulia> isvalid(Char, 0x110000)\nfalse","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"As of this writing, the valid Unicode code points are U+0000 through U+D7FF and U+E000 through U+10FFFF. These have not all been assigned intelligible meanings yet, nor are they necessarily interpretable by applications, but all of these values are considered to be valid Unicode characters.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can input any Unicode character in single quotes using \\u followed by up to four hexadecimal digits or \\U followed by up to eight hexadecimal digits (the longest valid value only requires six):","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> '\\u0'\n'\\0': ASCII/Unicode U+0000 (category Cc: Other, control)\n\njulia> '\\u78'\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\njulia> '\\u2200'\n'∀': Unicode U+2200 (category Sm: Symbol, math)\n\njulia> '\\U10ffff'\n'\\U10ffff': Unicode U+10FFFF (category Cn: Other, not assigned)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia uses your system's locale and language settings to determine which characters can be printed as-is and which must be output using the generic, escaped \\u or \\U input forms. In addition to these Unicode escape forms, all of C's traditional escaped input forms can also be used:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> Int('\\0')\n0\n\njulia> Int('\\t')\n9\n\njulia> Int('\\n')\n10\n\njulia> Int('\\e')\n27\n\njulia> Int('\\x7f')\n127\n\njulia> Int('\\177')\n127","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can do comparisons and a limited amount of arithmetic with Char values:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> 'A' < 'a'\ntrue\n\njulia> 'A' <= 'a' <= 'Z'\nfalse\n\njulia> 'A' <= 'X' <= 'Z'\ntrue\n\njulia> 'x' - 'a'\n23\n\njulia> 'A' + 1\n'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)","category":"page"},{"location":"manual/strings/#String-Basics","page":"Strings","title":"String Basics","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"String literals are delimited by double quotes or triple double quotes (not single quotes):","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str = \"Hello, world.\\n\"\n\"Hello, world.\\n\"\n\njulia> \"\"\"Contains \"quote\" characters\"\"\"\n\"Contains \\\"quote\\\" characters\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Long lines in strings can be broken up by preceding the newline with a backslash (\\):","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"This is a long \\\n line\"\n\"This is a long line\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If you want to extract a character from a string, you index into it:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[begin]\n'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)\n\njulia> str[1]\n'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)\n\njulia> str[6]\n',': ASCII/Unicode U+002C (category Po: Punctuation, other)\n\njulia> str[end]\n'\\n': ASCII/Unicode U+000A (category Cc: Other, control)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Many Julia objects, including strings, can be indexed with integers. The index of the first element (the first character of a string) is returned by firstindex(str), and the index of the last element (character) with lastindex(str). The keywords begin and end can be used inside an indexing operation as shorthand for the first and last indices, respectively, along the given dimension. String indexing, like most indexing in Julia, is 1-based: firstindex always returns 1 for any AbstractString. As we will see below, however, lastindex(str) is not in general the same as length(str) for a string, because some Unicode characters can occupy multiple \"code units\".","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can perform arithmetic and other operations with end, just like a normal value:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[end-1]\n'.': ASCII/Unicode U+002E (category Po: Punctuation, other)\n\njulia> str[end÷2]\n' ': ASCII/Unicode U+0020 (category Zs: Separator, space)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Using an index less than begin (1) or greater than end raises an error:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[begin-1]\nERROR: BoundsError: attempt to access 14-codeunit String at index [0]\n[...]\n\njulia> str[end+1]\nERROR: BoundsError: attempt to access 14-codeunit String at index [15]\n[...]","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can also extract a substring using range indexing:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[4:9]\n\"lo, wo\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Notice that the expressions str[k] and str[k:k] do not give the same result:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[6]\n',': ASCII/Unicode U+002C (category Po: Punctuation, other)\n\njulia> str[6:6]\n\",\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The former is a single character value of type Char, while the latter is a string value that happens to contain only a single character. In Julia these are very different things.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Range indexing makes a copy of the selected part of the original string. Alternatively, it is possible to create a view into a string using the type SubString. More simply, using the @views macro on a block of code converts all string slices into substrings. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str = \"long string\"\n\"long string\"\n\njulia> substr = SubString(str, 1, 4)\n\"long\"\n\njulia> typeof(substr)\nSubString{String}\n\njulia> @views typeof(str[1:4]) # @views converts slices to SubStrings\nSubString{String}","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Several standard functions like chop, chomp or strip return a SubString.","category":"page"},{"location":"manual/strings/#Unicode-and-UTF-8","page":"Strings","title":"Unicode and UTF-8","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia fully supports Unicode characters and strings. As discussed above, in character literals, Unicode code points can be represented using Unicode \\u and \\U escape sequences, as well as all the standard C escape sequences. These can likewise be used to write string literals:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s = \"\\u2200 x \\u2203 y\"\n\"∀ x ∃ y\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Whether these Unicode characters are displayed as escapes or shown as special characters depends on your terminal's locale settings and its support for Unicode. String literals are encoded using the UTF-8 encoding. UTF-8 is a variable-width encoding, meaning that not all characters are encoded in the same number of bytes (\"code units\"). In UTF-8, ASCII characters — i.e. those with code points less than 0x80 (128) – are encoded as they are in ASCII, using a single byte, while code points 0x80 and above are encoded using multiple bytes — up to four per character.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"String indices in Julia refer to code units (= bytes for UTF-8), the fixed-width building blocks that are used to encode arbitrary characters (code points). This means that not every index into a String is necessarily a valid index for a character. If you index into a string at such an invalid byte index, an error is thrown:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s[1]\n'∀': Unicode U+2200 (category Sm: Symbol, math)\n\njulia> s[2]\nERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'∀', [4]=>' '\nStacktrace:\n[...]\n\njulia> s[3]\nERROR: StringIndexError: invalid index [3], valid nearby indices [1]=>'∀', [4]=>' '\nStacktrace:\n[...]\n\njulia> s[4]\n' ': ASCII/Unicode U+0020 (category Zs: Separator, space)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"In this case, the character ∀ is a three-byte character, so the indices 2 and 3 are invalid and the next character's index is 4; this next valid index can be computed by nextind(s,1), and the next index after that by nextind(s,4) and so on.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Since end is always the last valid index into a collection, end-1 references an invalid byte index if the second-to-last character is multibyte.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s[end-1]\n' ': ASCII/Unicode U+0020 (category Zs: Separator, space)\n\njulia> s[end-2]\nERROR: StringIndexError: invalid index [9], valid nearby indices [7]=>'∃', [10]=>' '\nStacktrace:\n[...]\n\njulia> s[prevind(s, end, 2)]\n'∃': Unicode U+2203 (category Sm: Symbol, math)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The first case works, because the last character y and the space are one-byte characters, whereas end-2 indexes into the middle of the ∃ multibyte representation. The correct way for this case is using prevind(s, lastindex(s), 2) or, if you're using that value to index into s you can write s[prevind(s, end, 2)] and end expands to lastindex(s).","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Extraction of a substring using range indexing also expects valid byte indices or an error is thrown:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s[1:1]\n\"∀\"\n\njulia> s[1:2]\nERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'∀', [4]=>' '\nStacktrace:\n[...]\n\njulia> s[1:4]\n\"∀ \"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Because of variable-length encodings, the number of characters in a string (given by length(s)) is not always the same as the last index. If you iterate through the indices 1 through lastindex(s) and index into s, the sequence of characters returned when errors aren't thrown is the sequence of characters comprising the string s. Thus length(s) <= lastindex(s), since each character in a string must have its own index. The following is an inefficient and verbose way to iterate through the characters of s:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> for i = firstindex(s):lastindex(s)\n try\n println(s[i])\n catch\n # ignore the index error\n end\n end\n∀\n\nx\n\n∃\n\ny","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The blank lines actually have spaces on them. Fortunately, the above awkward idiom is unnecessary for iterating through the characters in a string, since you can just use the string as an iterable object, no exception handling required:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> for c in s\n println(c)\n end\n∀\n\nx\n\n∃\n\ny","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If you need to obtain valid indices for a string, you can use the nextind and prevind functions to increment/decrement to the next/previous valid index, as mentioned above. You can also use the eachindex function to iterate over the valid character indices:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> collect(eachindex(s))\n7-element Vector{Int64}:\n 1\n 4\n 5\n 6\n 7\n 10\n 11","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"To access the raw code units (bytes for UTF-8) of the encoding, you can use the codeunit(s,i) function, where the index i runs consecutively from 1 to ncodeunits(s). The codeunits(s) function returns an AbstractVector{UInt8} wrapper that lets you access these raw codeunits (bytes) as an array.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Strings in Julia can contain invalid UTF-8 code unit sequences. This convention allows to treat any byte sequence as a String. In such situations a rule is that when parsing a sequence of code units from left to right characters are formed by the longest sequence of 8-bit code units that matches the start of one of the following bit patterns (each x can be 0 or 1):","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"0xxxxxxx;\n110xxxxx 10xxxxxx;\n1110xxxx 10xxxxxx 10xxxxxx;\n11110xxx 10xxxxxx 10xxxxxx 10xxxxxx;\n10xxxxxx;\n11111xxx.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"In particular this means that overlong and too-high code unit sequences and prefixes thereof are treated as a single invalid character rather than multiple invalid characters. This rule may be best explained with an example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s = \"\\xc0\\xa0\\xe2\\x88\\xe2|\"\n\"\\xc0\\xa0\\xe2\\x88\\xe2|\"\n\njulia> foreach(display, s)\n'\\xc0\\xa0': [overlong] ASCII/Unicode U+0020 (category Zs: Separator, space)\n'\\xe2\\x88': Malformed UTF-8 (category Ma: Malformed, bad data)\n'\\xe2': Malformed UTF-8 (category Ma: Malformed, bad data)\n'|': ASCII/Unicode U+007C (category Sm: Symbol, math)\n\njulia> isvalid.(collect(s))\n4-element BitArray{1}:\n 0\n 0\n 0\n 1\n\njulia> s2 = \"\\xf7\\xbf\\xbf\\xbf\"\n\"\\U1fffff\"\n\njulia> foreach(display, s2)\n'\\U1fffff': Unicode U+1FFFFF (category In: Invalid, too high)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"We can see that the first two code units in the string s form an overlong encoding of space character. It is invalid, but is accepted in a string as a single character. The next two code units form a valid start of a three-byte UTF-8 sequence. However, the fifth code unit \\xe2 is not its valid continuation. Therefore code units 3 and 4 are also interpreted as malformed characters in this string. Similarly code unit 5 forms a malformed character because | is not a valid continuation to it. Finally the string s2 contains one too high code point.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia uses the UTF-8 encoding by default, and support for new encodings can be added by packages. For example, the LegacyStrings.jl package implements UTF16String and UTF32String types. Additional discussion of other encodings and how to implement support for them is beyond the scope of this document for the time being. For further discussion of UTF-8 encoding issues, see the section below on byte array literals. The transcode function is provided to convert data between the various UTF-xx encodings, primarily for working with external data and libraries.","category":"page"},{"location":"manual/strings/#man-concatenation","page":"Strings","title":"Concatenation","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"One of the most common and useful string operations is concatenation:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> greet = \"Hello\"\n\"Hello\"\n\njulia> whom = \"world\"\n\"world\"\n\njulia> string(greet, \", \", whom, \".\\n\")\n\"Hello, world.\\n\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"It's important to be aware of potentially dangerous situations such as concatenation of invalid UTF-8 strings. The resulting string may contain different characters than the input strings, and its number of characters may be lower than sum of numbers of characters of the concatenated strings, e.g.:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> a, b = \"\\xe2\\x88\", \"\\x80\"\n(\"\\xe2\\x88\", \"\\x80\")\n\njulia> c = string(a, b)\n\"∀\"\n\njulia> collect.([a, b, c])\n3-element Vector{Vector{Char}}:\n ['\\xe2\\x88']\n ['\\x80']\n ['∀']\n\njulia> length.([a, b, c])\n3-element Vector{Int64}:\n 1\n 1\n 1","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"This situation can happen only for invalid UTF-8 strings. For valid UTF-8 strings concatenation preserves all characters in strings and additivity of string lengths.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia also provides * for string concatenation:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> greet * \", \" * whom * \".\\n\"\n\"Hello, world.\\n\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"While * may seem like a surprising choice to users of languages that provide + for string concatenation, this use of * has precedent in mathematics, particularly in abstract algebra.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"In mathematics, + usually denotes a commutative operation, where the order of the operands does not matter. An example of this is matrix addition, where A + B == B + A for any matrices A and B that have the same shape. In contrast, * typically denotes a noncommutative operation, where the order of the operands does matter. An example of this is matrix multiplication, where in general A * B != B * A. As with matrix multiplication, string concatenation is noncommutative: greet * whom != whom * greet. As such, * is a more natural choice for an infix string concatenation operator, consistent with common mathematical use.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"More precisely, the set of all finite-length strings S together with the string concatenation operator * forms a free monoid (S, *). The identity element of this set is the empty string, \"\". Whenever a free monoid is not commutative, the operation is typically represented as \\cdot, *, or a similar symbol, rather than +, which as stated usually implies commutativity.","category":"page"},{"location":"manual/strings/#string-interpolation","page":"Strings","title":"Interpolation","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Constructing strings using concatenation can become a bit cumbersome, however. To reduce the need for these verbose calls to string or repeated multiplications, Julia allows interpolation into string literals using $, as in Perl:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> greet = \"Hello\"; whom = \"world\";\n\njulia> \"$greet, $whom.\\n\"\n\"Hello, world.\\n\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"This is more readable and convenient and equivalent to the above string concatenation – the system rewrites this apparent single string literal into the call string(greet, \", \", whom, \".\\n\").","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The shortest complete expression after the $ is taken as the expression whose value is to be interpolated into the string. Thus, you can interpolate any expression into a string using parentheses:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"1 + 2 = $(1 + 2)\"\n\"1 + 2 = 3\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Both concatenation and string interpolation call string to convert objects into string form. However, string actually just returns the output of print, so new types should add methods to print or show instead of string.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Most non-AbstractString objects are converted to strings closely corresponding to how they are entered as literal expressions:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> v = [1,2,3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> \"v: $v\"\n\"v: [1, 2, 3]\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"string is the identity for AbstractString and AbstractChar values, so these are interpolated into strings as themselves, unquoted and unescaped:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> c = 'x'\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\njulia> \"hi, $c\"\n\"hi, x\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"To include a literal $ in a string literal, escape it with a backslash:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> print(\"I have \\$100 in my account.\\n\")\nI have $100 in my account.","category":"page"},{"location":"manual/strings/#Triple-Quoted-String-Literals","page":"Strings","title":"Triple-Quoted String Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"When strings are created using triple-quotes (\"\"\"...\"\"\") they have some special behavior that can be useful for creating longer blocks of text.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"First, triple-quoted strings are also dedented to the level of the least-indented line. This is useful for defining strings within code that is indented. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str = \"\"\"\n Hello,\n world.\n \"\"\"\n\" Hello,\\n world.\\n\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"In this case the final (empty) line before the closing \"\"\" sets the indentation level.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The dedentation level is determined as the longest common starting sequence of spaces or tabs in all lines, excluding the line following the opening \"\"\" and lines containing only spaces or tabs (the line containing the closing \"\"\" is always included). Then for all lines, excluding the text following the opening \"\"\", the common starting sequence is removed (including lines containing only spaces and tabs if they start with this sequence), e.g.:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"\"\" This\n is\n a test\"\"\"\n\" This\\nis\\n a test\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Next, if the opening \"\"\" is followed by a newline, the newline is stripped from the resulting string.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"\"\"\"hello\"\"\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"is equivalent to","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"\"\"\"\nhello\"\"\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"but","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"\"\"\"\n\nhello\"\"\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"will contain a literal newline at the beginning.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Stripping of the newline is performed after the dedentation. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"\"\"\n Hello,\n world.\"\"\"\n\"Hello,\\nworld.\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If the newline is removed using a backslash, dedentation will be respected as well:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"\"\"\n Averylong\\\n word\"\"\"\n\"Averylongword\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Trailing whitespace is left unaltered.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Triple-quoted string literals can contain \" characters without escaping.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Note that line breaks in literal strings, whether single- or triple-quoted, result in a newline (LF) character \\n in the string, even if your editor uses a carriage return \\r (CR) or CRLF combination to end lines. To include a CR in a string, use an explicit escape \\r; for example, you can enter the literal string \"a CRLF line ending\\r\\n\".","category":"page"},{"location":"manual/strings/#Common-Operations","page":"Strings","title":"Common Operations","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can lexicographically compare strings using the standard comparison operators:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"abracadabra\" < \"xylophone\"\ntrue\n\njulia> \"abracadabra\" == \"xylophone\"\nfalse\n\njulia> \"Hello, world.\" != \"Goodbye, world.\"\ntrue\n\njulia> \"1 + 2 = 3\" == \"1 + 2 = $(1 + 2)\"\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can search for the index of a particular character using the findfirst and findlast functions:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> findfirst('o', \"xylophone\")\n4\n\njulia> findlast('o', \"xylophone\")\n7\n\njulia> findfirst('z', \"xylophone\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can start the search for a character at a given offset by using the functions findnext and findprev:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> findnext('o', \"xylophone\", 1)\n4\n\njulia> findnext('o', \"xylophone\", 5)\n7\n\njulia> findprev('o', \"xylophone\", 5)\n4\n\njulia> findnext('o', \"xylophone\", 8)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can use the occursin function to check if a substring is found within a string:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> occursin(\"world\", \"Hello, world.\")\ntrue\n\njulia> occursin(\"o\", \"Xylophon\")\ntrue\n\njulia> occursin(\"a\", \"Xylophon\")\nfalse\n\njulia> occursin('o', \"Xylophon\")\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The last example shows that occursin can also look for a character literal.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Two other handy string functions are repeat and join:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> repeat(\".:Z:.\", 10)\n\".:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:.\"\n\njulia> join([\"apples\", \"bananas\", \"pineapples\"], \", \", \" and \")\n\"apples, bananas and pineapples\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Some other useful functions include:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"firstindex(str) gives the minimal (byte) index that can be used to index into str (always 1 for strings, not necessarily true for other containers).\nlastindex(str) gives the maximal (byte) index that can be used to index into str.\nlength(str) the number of characters in str.\nlength(str, i, j) the number of valid character indices in str from i to j.\nncodeunits(str) number of code units in a string.\ncodeunit(str, i) gives the code unit value in the string str at index i.\nthisind(str, i) given an arbitrary index into a string find the first index of the character into which the index points.\nnextind(str, i, n=1) find the start of the nth character starting after index i.\nprevind(str, i, n=1) find the start of the nth character starting before index i.","category":"page"},{"location":"manual/strings/#non-standard-string-literals","page":"Strings","title":"Non-Standard String Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"There are situations when you want to construct a string or use string semantics, but the behavior of the standard string construct is not quite what is needed. For these kinds of situations, Julia provides non-standard string literals. A non-standard string literal looks like a regular double-quoted string literal, but is immediately prefixed by an identifier, and may behave differently from a normal string literal.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Regular expressions, byte array literals, and version number literals, as described below, are some examples of non-standard string literals. Users and packages may also define new non-standard string literals. Further documentation is given in the Metaprogramming section.","category":"page"},{"location":"manual/strings/#man-regex-literals","page":"Strings","title":"Regular Expressions","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Sometimes you are not looking for an exact string, but a particular pattern. For example, suppose you are trying to extract a single date from a large text file. You don’t know what that date is (that’s why you are searching for it), but you do know it will look something like YYYY-MM-DD. Regular expressions allow you to specify these patterns and search for them.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia uses version 2 of Perl-compatible regular expressions (regexes), as provided by the PCRE library (see the PCRE2 syntax description for more details). Regular expressions are related to strings in two ways: the obvious connection is that regular expressions are used to find regular patterns in strings; the other connection is that regular expressions are themselves input as strings, which are parsed into a state machine that can be used to efficiently search for patterns in strings. In Julia, regular expressions are input using non-standard string literals prefixed with various identifiers beginning with r. The most basic regular expression literal without any options turned on just uses r\"...\":","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> re = r\"^\\s*(?:#|$)\"\nr\"^\\s*(?:#|$)\"\n\njulia> typeof(re)\nRegex","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"To check if a regex matches a string, use occursin:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> occursin(r\"^\\s*(?:#|$)\", \"not a comment\")\nfalse\n\njulia> occursin(r\"^\\s*(?:#|$)\", \"# a comment\")\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"As one can see here, occursin simply returns true or false, indicating whether a match for the given regex occurs in the string. Commonly, however, one wants to know not just whether a string matched, but also how it matched. To capture this information about a match, use the match function instead:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> match(r\"^\\s*(?:#|$)\", \"not a comment\")\n\njulia> match(r\"^\\s*(?:#|$)\", \"# a comment\")\nRegexMatch(\"#\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If the regular expression does not match the given string, match returns nothing – a special value that does not print anything at the interactive prompt. Other than not printing, it is a completely normal value and you can test for it programmatically:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"m = match(r\"^\\s*(?:#|$)\", line)\nif m === nothing\n println(\"not a comment\")\nelse\n println(\"blank or comment\")\nend","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If a regular expression does match, the value returned by match is a RegexMatch object. These objects record how the expression matches, including the substring that the pattern matches and any captured substrings, if there are any. This example only captures the portion of the substring that matches, but perhaps we want to capture any non-blank text after the comment character. We could do the following:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> m = match(r\"^\\s*(?:#\\s*(.*?)\\s*$)\", \"# a comment \")\nRegexMatch(\"# a comment \", 1=\"a comment\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"When calling match, you have the option to specify an index at which to start the search. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> m = match(r\"[0-9]\",\"aaaa1aaaa2aaaa3\",1)\nRegexMatch(\"1\")\n\njulia> m = match(r\"[0-9]\",\"aaaa1aaaa2aaaa3\",6)\nRegexMatch(\"2\")\n\njulia> m = match(r\"[0-9]\",\"aaaa1aaaa2aaaa3\",11)\nRegexMatch(\"3\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can extract the following info from a RegexMatch object:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"the entire substring matched: m.match\nthe captured substrings as an array of strings: m.captures\nthe offset at which the whole match begins: m.offset\nthe offsets of the captured substrings as a vector: m.offsets","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"For when a capture doesn't match, instead of a substring, m.captures contains nothing in that position, and m.offsets has a zero offset (recall that indices in Julia are 1-based, so a zero offset into a string is invalid). Here is a pair of somewhat contrived examples:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> m = match(r\"(a|b)(c)?(d)\", \"acd\")\nRegexMatch(\"acd\", 1=\"a\", 2=\"c\", 3=\"d\")\n\njulia> m.match\n\"acd\"\n\njulia> m.captures\n3-element Vector{Union{Nothing, SubString{String}}}:\n \"a\"\n \"c\"\n \"d\"\n\njulia> m.offset\n1\n\njulia> m.offsets\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> m = match(r\"(a|b)(c)?(d)\", \"ad\")\nRegexMatch(\"ad\", 1=\"a\", 2=nothing, 3=\"d\")\n\njulia> m.match\n\"ad\"\n\njulia> m.captures\n3-element Vector{Union{Nothing, SubString{String}}}:\n \"a\"\n nothing\n \"d\"\n\njulia> m.offset\n1\n\njulia> m.offsets\n3-element Vector{Int64}:\n 1\n 0\n 2","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"It is convenient to have captures returned as an array so that one can use destructuring syntax to bind them to local variables. As a convenience, the RegexMatch object implements iterator methods that pass through to the captures field, so you can destructure the match object directly:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> first, second, third = m; first\n\"a\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Captures can also be accessed by indexing the RegexMatch object with the number or name of the capture group:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> m=match(r\"(?\\d+):(?\\d+)\",\"12:45\")\nRegexMatch(\"12:45\", hour=\"12\", minute=\"45\")\n\njulia> m[:minute]\n\"45\"\n\njulia> m[2]\n\"45\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Captures can be referenced in a substitution string when using replace by using \\n to refer to the nth capture group and prefixing the substitution string with s. Capture group 0 refers to the entire match object. Named capture groups can be referenced in the substitution with \\g. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> replace(\"first second\", r\"(\\w+) (?\\w+)\" => s\"\\g \\1\")\n\"second first\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Numbered capture groups can also be referenced as \\g for disambiguation, as in:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> replace(\"a\", r\".\" => s\"\\g<0>1\")\n\"a1\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can modify the behavior of regular expressions by some combination of the flags i, m, s, and x after the closing double quote mark. These flags have the same meaning as they do in Perl, as explained in this excerpt from the perlre manpage:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"i Do case-insensitive pattern matching.\n\n If locale matching rules are in effect, the case map is taken\n from the current locale for code points less than 255, and\n from Unicode rules for larger code points. However, matches\n that would cross the Unicode rules/non-Unicode rules boundary\n (ords 255/256) will not succeed.\n\nm Treat string as multiple lines. That is, change \"^\" and \"$\"\n from matching the start or end of the string to matching the\n start or end of any line anywhere within the string.\n\ns Treat string as single line. That is, change \".\" to match any\n character whatsoever, even a newline, which normally it would\n not match.\n\n Used together, as r\"\"ms, they let the \".\" match any character\n whatsoever, while still allowing \"^\" and \"$\" to match,\n respectively, just after and just before newlines within the\n string.\n\nx Tells the regular expression parser to ignore most whitespace\n that is neither backslashed nor within a character class. You\n can use this to break up your regular expression into\n (slightly) more readable parts. The '#' character is also\n treated as a metacharacter introducing a comment, just as in\n ordinary code.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"For example, the following regex has all three flags turned on:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> r\"a+.*b+.*d$\"ism\nr\"a+.*b+.*d$\"ims\n\njulia> match(r\"a+.*b+.*d$\"ism, \"Goodbye,\\nOh, angry,\\nBad world\\n\")\nRegexMatch(\"angry,\\nBad world\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The r\"...\" literal is constructed without interpolation and unescaping (except for quotation mark \" which still has to be escaped). Here is an example showing the difference from standard string literals:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> x = 10\n10\n\njulia> r\"$x\"\nr\"$x\"\n\njulia> \"$x\"\n\"10\"\n\njulia> r\"\\x\"\nr\"\\x\"\n\njulia> \"\\x\"\nERROR: syntax: invalid escape sequence","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Triple-quoted regex strings, of the form r\"\"\"...\"\"\", are also supported (and may be convenient for regular expressions containing quotation marks or newlines).","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The Regex() constructor may be used to create a valid regex string programmatically. This permits using the contents of string variables and other string operations when constructing the regex string. Any of the regex codes above can be used within the single string argument to Regex(). Here are some examples:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> using Dates\n\njulia> d = Date(1962,7,10)\n1962-07-10\n\njulia> regex_d = Regex(\"Day \" * string(day(d)))\nr\"Day 10\"\n\njulia> match(regex_d, \"It happened on Day 10\")\nRegexMatch(\"Day 10\")\n\njulia> name = \"Jon\"\n\"Jon\"\n\njulia> regex_name = Regex(\"[\\\"( ]\\\\Q$name\\\\E[\\\") ]\") # interpolate value of name\nr\"[\\\"( ]\\QJon\\E[\\\") ]\"\n\njulia> match(regex_name, \" Jon \")\nRegexMatch(\" Jon \")\n\njulia> match(regex_name, \"[Jon]\") === nothing\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Note the use of the \\Q...\\E escape sequence. All characters between the \\Q and the \\E are interpreted as literal characters. This is convenient for matching characters that would otherwise be regex metacharacters. However, caution is needed when using this feature together with string interpolation, since the interpolated string might itself contain the \\E sequence, unexpectedly terminating literal matching. User inputs need to be sanitized before inclusion in a regex.","category":"page"},{"location":"manual/strings/#man-byte-array-literals","page":"Strings","title":"Byte Array Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Another useful non-standard string literal is the byte-array string literal: b\"...\". This form lets you use string notation to express read only literal byte arrays – i.e. arrays of UInt8 values. The type of those objects is CodeUnits{UInt8, String}. The rules for byte array literals are the following:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"ASCII characters and ASCII escapes produce a single byte.\n\\x and octal escape sequences produce the byte corresponding to the escape value.\nUnicode escape sequences produce a sequence of bytes encoding that code point in UTF-8.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"There is some overlap between these rules since the behavior of \\x and octal escapes less than 0x80 (128) are covered by both of the first two rules, but here these rules agree. Together, these rules allow one to easily use ASCII characters, arbitrary byte values, and UTF-8 sequences to produce arrays of bytes. Here is an example using all three:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> b\"DATA\\xff\\u2200\"\n8-element Base.CodeUnits{UInt8, String}:\n 0x44\n 0x41\n 0x54\n 0x41\n 0xff\n 0xe2\n 0x88\n 0x80","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The ASCII string \"DATA\" corresponds to the bytes 68, 65, 84, 65. \\xff produces the single byte 255. The Unicode escape \\u2200 is encoded in UTF-8 as the three bytes 226, 136, 128. Note that the resulting byte array does not correspond to a valid UTF-8 string:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> isvalid(\"DATA\\xff\\u2200\")\nfalse","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"As it was mentioned CodeUnits{UInt8, String} type behaves like read only array of UInt8 and if you need a standard vector you can convert it using Vector{UInt8}:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> x = b\"123\"\n3-element Base.CodeUnits{UInt8, String}:\n 0x31\n 0x32\n 0x33\n\njulia> x[1]\n0x31\n\njulia> x[1] = 0x32\nERROR: CanonicalIndexError: setindex! not defined for Base.CodeUnits{UInt8, String}\n[...]\n\njulia> Vector{UInt8}(x)\n3-element Vector{UInt8}:\n 0x31\n 0x32\n 0x33","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Also observe the significant distinction between \\xff and \\uff: the former escape sequence encodes the byte 255, whereas the latter escape sequence represents the code point 255, which is encoded as two bytes in UTF-8:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> b\"\\xff\"\n1-element Base.CodeUnits{UInt8, String}:\n 0xff\n\njulia> b\"\\uff\"\n2-element Base.CodeUnits{UInt8, String}:\n 0xc3\n 0xbf","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Character literals use the same behavior.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"For code points less than \\u80, it happens that the UTF-8 encoding of each code point is just the single byte produced by the corresponding \\x escape, so the distinction can safely be ignored. For the escapes \\x80 through \\xff as compared to \\u80 through \\uff, however, there is a major difference: the former escapes all encode single bytes, which – unless followed by very specific continuation bytes – do not form valid UTF-8 data, whereas the latter escapes all represent Unicode code points with two-byte encodings.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If this is all extremely confusing, try reading \"The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets\". It's an excellent introduction to Unicode and UTF-8, and may help alleviate some confusion regarding the matter.","category":"page"},{"location":"manual/strings/#man-version-number-literals","page":"Strings","title":"Version Number Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Version numbers can easily be expressed with non-standard string literals of the form v\"...\". Version number literals create VersionNumber objects which follow the specifications of semantic versioning 2.0.0-rc2, and therefore are composed of major, minor and patch numeric values, followed by pre-release and build alphanumeric annotations. For example, v\"0.2.1-rc1+win64\" is broken into major version 0, minor version 2, patch version 1, pre-release rc1 and build win64. When entering a version literal, everything except the major version number is optional, therefore e.g. v\"0.2\" is equivalent to v\"0.2.0\" (with empty pre-release/build annotations), v\"2\" is equivalent to v\"2.0.0\", and so on.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"VersionNumber objects are mostly useful to easily and correctly compare two (or more) versions. For example, the constant VERSION holds Julia version number as a VersionNumber object, and therefore one can define some version-specific behavior using simple statements as:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"if v\"0.2\" <= VERSION < v\"0.3-\"\n # do something specific to 0.2 release series\nend","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Note that in the above example the non-standard version number v\"0.3-\" is used, with a trailing -: this notation is a Julia extension of the standard, and it's used to indicate a version which is lower than any 0.3 release, including all of its pre-releases. So in the above example the code would only run with stable 0.2 versions, and exclude such versions as v\"0.3.0-rc1\". In order to also allow for unstable (i.e. pre-release) 0.2 versions, the lower bound check should be modified like this: v\"0.2-\" <= VERSION.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Another non-standard version specification extension allows one to use a trailing + to express an upper limit on build versions, e.g. VERSION > v\"0.2-rc1+\" can be used to mean any version above 0.2-rc1 and any of its builds: it will return false for version v\"0.2-rc1+win64\" and true for v\"0.2-rc2\".","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"It is good practice to use such special versions in comparisons (particularly, the trailing - should always be used on upper bounds unless there's a good reason not to), but they must not be used as the actual version number of anything, as they are invalid in the semantic versioning scheme.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Besides being used for the VERSION constant, VersionNumber objects are widely used in the Pkg module, to specify packages versions and their dependencies.","category":"page"},{"location":"manual/strings/#man-raw-string-literals","page":"Strings","title":"Raw String Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Raw strings without interpolation or unescaping can be expressed with non-standard string literals of the form raw\"...\". Raw string literals create ordinary String objects which contain the enclosed contents exactly as entered with no interpolation or unescaping. This is useful for strings which contain code or markup in other languages which use $ or \\ as special characters.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The exception is that quotation marks still must be escaped, e.g. raw\"\\\"\" is equivalent to \"\\\"\". To make it possible to express all strings, backslashes then also must be escaped, but only when appearing right before a quote character:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> println(raw\"\\\\ \\\\\\\"\")\n\\\\ \\\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Notice that the first two backslashes appear verbatim in the output, since they do not precede a quote character. However, the next backslash character escapes the backslash that follows it, and the last backslash escapes a quote, since these backslashes appear before a quote.","category":"page"},{"location":"manual/strings/#man-annotated-strings","page":"Strings","title":"Annotated Strings","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"It is sometimes useful to be able to hold metadata relating to regions of a string. A AnnotatedString wraps another string and allows for regions of it to be annotated with labelled values (:label => value). All generic string operations are applied to the underlying string. However, when possible, styling information is preserved. This means you can manipulate a AnnotatedString —taking substrings, padding them, concatenating them with other strings— and the metadata annotations will \"come along for the ride\".","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"This string type is fundamental to the StyledStrings stdlib, which uses :face-labelled annotations to hold styling information.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"When concatenating a AnnotatedString, take care to use annotatedstring instead of string if you want to keep the string annotations.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str = Base.AnnotatedString(\"hello there\",\n [(1:5, :word => :greeting), (7:11, :label => 1)])\n\"hello there\"\n\njulia> length(str)\n11\n\njulia> lpad(str, 14)\n\" hello there\"\n\njulia> typeof(lpad(str, 7))\nBase.AnnotatedString{String}\n\njulia> str2 = Base.AnnotatedString(\" julia\", [(2:6, :face => :magenta)])\n\" julia\"\n\njulia> Base.annotatedstring(str, str2)\n\"hello there julia\"\n\njulia> str * str2 == Base.annotatedstring(str, str2) # *-concatenation still works\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The annotations of a AnnotatedString can be accessed and modified via the annotations and annotate! functions.","category":"page"},{"location":"base/base/#Essentials","page":"Essentials","title":"Essentials","text":"","category":"section"},{"location":"base/base/#Introduction","page":"Essentials","title":"Introduction","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Julia Base contains a range of functions and macros appropriate for performing scientific and numerical computing, but is also as broad as those of many general purpose programming languages. Additional functionality is available from a growing collection of available packages. Functions are grouped by topic below.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Some general notes:","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"To use module functions, use import Module to import the module, and Module.fn(x) to use the functions.\nAlternatively, using Module will import all exported Module functions into the current namespace.\nBy convention, function names ending with an exclamation point (!) modify their arguments. Some functions have both modifying (e.g., sort!) and non-modifying (sort) versions.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"The behaviors of Base and standard libraries are stable as defined in SemVer only if they are documented; i.e., included in the Julia documentation and not marked as unstable. See API FAQ for more information.","category":"page"},{"location":"base/base/#Getting-Around","page":"Essentials","title":"Getting Around","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.exit\nBase.atexit\nBase.isinteractive\nBase.summarysize\nBase.__precompile__\nBase.include\nMain.include\nBase.include_string\nBase.include_dependency\n__init__\nBase.which(::Any, ::Any)\nBase.methods\nBase.@show\nans\nerr\nBase.active_project\nBase.set_active_project","category":"page"},{"location":"base/base/#Base.exit","page":"Essentials","title":"Base.exit","text":"exit(code=0)\n\nStop the program with an exit code. The default exit code is zero, indicating that the program completed successfully. In an interactive session, exit() can be called with the keyboard shortcut ^D.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.atexit","page":"Essentials","title":"Base.atexit","text":"atexit(f)\n\nRegister a zero- or one-argument function f() to be called at process exit. atexit() hooks are called in last in first out (LIFO) order and run before object finalizers.\n\nIf f has a method defined for one integer argument, it will be called as f(n::Int32), where n is the current exit code, otherwise it will be called as f().\n\ncompat: Julia 1.9\nThe one-argument form requires Julia 1.9\n\nExit hooks are allowed to call exit(n), in which case Julia will exit with exit code n (instead of the original exit code). If more than one exit hook calls exit(n), then Julia will exit with the exit code corresponding to the last called exit hook that calls exit(n). (Because exit hooks are called in LIFO order, \"last called\" is equivalent to \"first registered\".)\n\nNote: Once all exit hooks have been called, no more exit hooks can be registered, and any call to atexit(f) after all hooks have completed will throw an exception. This situation may occur if you are registering exit hooks from background Tasks that may still be executing concurrently during shutdown.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isinteractive","page":"Essentials","title":"Base.isinteractive","text":"isinteractive() -> Bool\n\nDetermine whether Julia is running an interactive session.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.summarysize","page":"Essentials","title":"Base.summarysize","text":"Base.summarysize(obj; exclude=Union{...}, chargeall=Union{...}) -> Int\n\nCompute the amount of memory, in bytes, used by all unique objects reachable from the argument.\n\nKeyword Arguments\n\nexclude: specifies the types of objects to exclude from the traversal.\nchargeall: specifies the types of objects to always charge the size of all of their fields, even if those fields would normally be excluded.\n\nSee also sizeof.\n\nExamples\n\njulia> Base.summarysize(1.0)\n8\n\njulia> Base.summarysize(Ref(rand(100)))\n864\n\njulia> sizeof(Ref(rand(100)))\n8\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.__precompile__","page":"Essentials","title":"Base.__precompile__","text":"__precompile__(isprecompilable::Bool)\n\nSpecify whether the file calling this function is precompilable, defaulting to true. If a module or file is not safely precompilable, it should call __precompile__(false) in order to throw an error if Julia attempts to precompile it.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.include","page":"Essentials","title":"Base.include","text":"Base.include([mapexpr::Function,] m::Module, path::AbstractString)\n\nEvaluate the contents of the input source file in the global scope of module m. Every module (except those defined with baremodule) has its own definition of include omitting the m argument, which evaluates the file in that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to include will search relative to that path. This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files.\n\nThe optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in path, the include function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.\n\ncompat: Julia 1.5\nJulia 1.5 is required for passing the mapexpr argument.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#include","page":"Essentials","title":"include","text":"include([mapexpr::Function,] path::AbstractString)\n\nEvaluate the contents of the input source file in the global scope of the containing module. Every module (except those defined with baremodule) has its own definition of include, which evaluates the file in that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to include will search relative to that path. This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files. The argument path is normalized using normpath which will resolve relative path tokens such as .. and convert / to the appropriate path separator.\n\nThe optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in path, the include function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.\n\nUse Base.include to evaluate a file into another module.\n\ncompat: Julia 1.5\nJulia 1.5 is required for passing the mapexpr argument.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.include_string","page":"Essentials","title":"Base.include_string","text":"include_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString=\"string\")\n\nLike include, except reads code from the given string rather than from a file.\n\nThe optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in code, the include_string function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.\n\ncompat: Julia 1.5\nJulia 1.5 is required for passing the mapexpr argument.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.include_dependency","page":"Essentials","title":"Base.include_dependency","text":"include_dependency(path::AbstractString; track_content::Bool=false)\n\nIn a module, declare that the file, directory, or symbolic link specified by path (relative or absolute) is a dependency for precompilation; that is, the module will need to be recompiled if the modification time mtime of path changes. If track_content=true recompilation is triggered when the content of path changes (if path is a directory the content equals join(readdir(path))).\n\nThis is only needed if your module depends on a path that is not used via include. It has no effect outside of compilation.\n\ncompat: Julia 1.11\nKeyword argument track_content requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#__init__","page":"Essentials","title":"__init__","text":"__init__\n\nThe __init__() function in a module executes immediately after the module is loaded at runtime for the first time. It is called once, after all other statements in the module have been executed. Because it is called after fully importing the module, __init__ functions of submodules will be executed first. Two typical uses of __init__ are calling runtime initialization functions of external C libraries and initializing global constants that involve pointers returned by external libraries. See the manual section about modules for more details.\n\nExamples\n\nconst foo_data_ptr = Ref{Ptr{Cvoid}}(0)\nfunction __init__()\n ccall((:foo_init, :libfoo), Cvoid, ())\n foo_data_ptr[] = ccall((:foo_data, :libfoo), Ptr{Cvoid}, ())\n nothing\nend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.which-Tuple{Any, Any}","page":"Essentials","title":"Base.which","text":"which(f, types)\n\nReturns the method of f (a Method object) that would be called for arguments of the given types.\n\nIf types is an abstract type, then the method that would be called by invoke is returned.\n\nSee also: parentmodule, @which, and @edit.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.methods","page":"Essentials","title":"Base.methods","text":"methods(f, [types], [module])\n\nReturn the method table for f.\n\nIf types is specified, return an array of methods whose types match. If module is specified, return an array of methods defined in that module. A list of modules can also be specified as an array.\n\ncompat: Julia 1.4\nAt least Julia 1.4 is required for specifying a module.\n\nSee also: which, @which and methodswith.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@show","page":"Essentials","title":"Base.@show","text":"@show exs...\n\nPrints one or more expressions, and their results, to stdout, and returns the last result.\n\nSee also: show, @info, println.\n\nExamples\n\njulia> x = @show 1+2\n1 + 2 = 3\n3\n\njulia> @show x^2 x/2;\nx ^ 2 = 9\nx / 2 = 1.5\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.MainInclude.ans","page":"Essentials","title":"Base.MainInclude.ans","text":"ans\n\nA variable referring to the last computed value, automatically imported to the interactive prompt.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.MainInclude.err","page":"Essentials","title":"Base.MainInclude.err","text":"err\n\nA variable referring to the last thrown errors, automatically imported to the interactive prompt. The thrown errors are collected in a stack of exceptions.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.active_project","page":"Essentials","title":"Base.active_project","text":"active_project()\n\nReturn the path of the active Project.toml file. See also Base.set_active_project.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.set_active_project","page":"Essentials","title":"Base.set_active_project","text":"set_active_project(projfile::Union{AbstractString,Nothing})\n\nSet the active Project.toml file to projfile. See also Base.active_project.\n\ncompat: Julia 1.8\nThis function requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Keywords","page":"Essentials","title":"Keywords","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"This is the list of reserved keywords in Julia: baremodule, begin, break, catch, const, continue, do, else, elseif, end, export, false, finally, for, function, global, if, import, let, local, macro, module, quote, return, struct, true, try, using, while. Those keywords are not allowed to be used as variable names.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"The following two-word sequences are reserved: abstract type, mutable struct, primitive type. However, you can create variables with names: abstract, mutable, primitive and type.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Finally: where is parsed as an infix operator for writing parametric method and type definitions; in and isa are parsed as infix operators; public is parsed as a keyword when beginning a toplevel statement; outer is parsed as a keyword when used to modify the scope of a variable in an iteration specification of a for loop; and as is used as a keyword to rename an identifier brought into scope by import or using. Creation of variables named where, in, isa, outer and as is allowed, though.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"module\nexport\npublic\nimport\nusing\nas\nbaremodule\nfunction\nmacro\nreturn\ndo\nbegin\nend\nlet\nif\nfor\nwhile\nbreak\ncontinue\ntry\nfinally\nquote\nlocal\nglobal\nouter\nconst\nstruct\nmutable struct\n@kwdef\nabstract type\nprimitive type\nwhere\n...\n;\n=\n?:","category":"page"},{"location":"base/base/#module","page":"Essentials","title":"module","text":"module\n\nmodule declares a Module, which is a separate global variable workspace. Within a module, you can control which names from other modules are visible (via importing), and specify which of your names are intended to be public (via export and public). Modules allow you to create top-level definitions without worrying about name conflicts when your code is used together with somebody else’s. See the manual section about modules for more details.\n\nExamples\n\nmodule Foo\nimport Base.show\nexport MyType, foo\n\nstruct MyType\n x\nend\n\nbar(x) = 2x\nfoo(a::MyType) = bar(a.x) + 1\nshow(io::IO, a::MyType) = print(io, \"MyType $(a.x)\")\nend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#export","page":"Essentials","title":"export","text":"export\n\nexport is used within modules to tell Julia which names should be made available to the user. For example: export foo makes the name foo available when using the module. See the manual section about modules for details.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#public","page":"Essentials","title":"public","text":"public\n\npublic is used within modules to tell Julia which names are part of the public API of the module. For example: public foo indicates that the name foo is public, without making it available when using the module.\n\nAs export already indicates that a name is public, it is unnecessary and an error to declare a name both as public and as exported. See the manual section about modules for details.\n\ncompat: Julia 1.11\nThe public keyword was added in Julia 1.11. Prior to this the notion of publicness was less explicit.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#import","page":"Essentials","title":"import","text":"import\n\nimport Foo will load the module or package Foo. Names from the imported Foo module can be accessed with dot syntax (e.g. Foo.foo to access the name foo). See the manual section about modules for details.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#using","page":"Essentials","title":"using","text":"using\n\nusing Foo will load the module or package Foo and make its exported names available for direct use. Names can also be used via dot syntax (e.g. Foo.foo to access the name foo), whether they are exported or not. See the manual section about modules for details.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#as","page":"Essentials","title":"as","text":"as\n\nas is used as a keyword to rename an identifier brought into scope by import or using, for the purpose of working around name conflicts as well as for shortening names. (Outside of import or using statements, as is not a keyword and can be used as an ordinary identifier.)\n\nimport LinearAlgebra as LA brings the imported LinearAlgebra standard library into scope as LA.\n\nimport LinearAlgebra: eigen as eig, cholesky as chol brings the eigen and cholesky methods from LinearAlgebra into scope as eig and chol respectively.\n\nas works with using only when individual identifiers are brought into scope. For example, using LinearAlgebra: eigen as eig or using LinearAlgebra: eigen as eig, cholesky as chol works, but using LinearAlgebra as LA is invalid syntax, since it is nonsensical to rename all exported names from LinearAlgebra to LA.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#baremodule","page":"Essentials","title":"baremodule","text":"baremodule\n\nbaremodule declares a module that does not contain using Base or local definitions of eval and include. It does still import Core. In other words,\n\nmodule Mod\n\n...\n\nend\n\nis equivalent to\n\nbaremodule Mod\n\nusing Base\n\neval(x) = Core.eval(Mod, x)\ninclude(p) = Base.include(Mod, p)\n\n...\n\nend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#function","page":"Essentials","title":"function","text":"function\n\nFunctions are defined with the function keyword:\n\nfunction add(a, b)\n return a + b\nend\n\nOr the short form notation:\n\nadd(a, b) = a + b\n\nThe use of the return keyword is exactly the same as in other languages, but is often optional. A function without an explicit return statement will return the last expression in the function body.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#macro","page":"Essentials","title":"macro","text":"macro\n\nmacro defines a method for inserting generated code into a program. A macro maps a sequence of argument expressions to a returned expression, and the resulting expression is substituted directly into the program at the point where the macro is invoked. Macros are a way to run generated code without calling eval, since the generated code instead simply becomes part of the surrounding program. Macro arguments may include expressions, literal values, and symbols. Macros can be defined for variable number of arguments (varargs), but do not accept keyword arguments. Every macro also implicitly gets passed the arguments __source__, which contains the line number and file name the macro is called from, and __module__, which is the module the macro is expanded in.\n\nSee the manual section on Metaprogramming for more information about how to write a macro.\n\nExamples\n\njulia> macro sayhello(name)\n return :( println(\"Hello, \", $name, \"!\") )\n end\n@sayhello (macro with 1 method)\n\njulia> @sayhello \"Charlie\"\nHello, Charlie!\n\njulia> macro saylots(x...)\n return :( println(\"Say: \", $(x...)) )\n end\n@saylots (macro with 1 method)\n\njulia> @saylots \"hey \" \"there \" \"friend\"\nSay: hey there friend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#return","page":"Essentials","title":"return","text":"return\n\nreturn x causes the enclosing function to exit early, passing the given value x back to its caller. return by itself with no value is equivalent to return nothing (see nothing).\n\nfunction compare(a, b)\n a == b && return \"equal to\"\n a < b ? \"less than\" : \"greater than\"\nend\n\nIn general you can place a return statement anywhere within a function body, including within deeply nested loops or conditionals, but be careful with do blocks. For example:\n\nfunction test1(xs)\n for x in xs\n iseven(x) && return 2x\n end\nend\n\nfunction test2(xs)\n map(xs) do x\n iseven(x) && return 2x\n x\n end\nend\n\nIn the first example, the return breaks out of test1 as soon as it hits an even number, so test1([5,6,7]) returns 12.\n\nYou might expect the second example to behave the same way, but in fact the return there only breaks out of the inner function (inside the do block) and gives a value back to map. test2([5,6,7]) then returns [5,12,7].\n\nWhen used in a top-level expression (i.e. outside any function), return causes the entire current top-level expression to terminate early.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#do","page":"Essentials","title":"do","text":"do\n\nCreate an anonymous function and pass it as the first argument to a function call. For example:\n\nmap(1:10) do x\n 2x\nend\n\nis equivalent to map(x->2x, 1:10).\n\nUse multiple arguments like so:\n\nmap(1:10, 11:20) do x, y\n x + y\nend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#begin","page":"Essentials","title":"begin","text":"begin\n\nbegin...end denotes a block of code.\n\nbegin\n println(\"Hello, \")\n println(\"World!\")\nend\n\nUsually begin will not be necessary, since keywords such as function and let implicitly begin blocks of code. See also ;.\n\nbegin may also be used when indexing to represent the first index of a collection or the first index of a dimension of an array.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Array{Int64,2}:\n 1 2\n 3 4\n\njulia> A[begin, :]\n2-element Array{Int64,1}:\n 1\n 2\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#end","page":"Essentials","title":"end","text":"end\n\nend marks the conclusion of a block of expressions, for example module, struct, mutable struct, begin, let, for etc.\n\nend may also be used when indexing to represent the last index of a collection or the last index of a dimension of an array.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Array{Int64, 2}:\n 1 2\n 3 4\n\njulia> A[end, :]\n2-element Array{Int64, 1}:\n 3\n 4\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#let","page":"Essentials","title":"let","text":"let\n\nlet blocks create a new hard scope and optionally introduce new local bindings.\n\nJust like the other scope constructs, let blocks define the block of code where newly introduced local variables are accessible. Additionally, the syntax has a special meaning for comma-separated assignments and variable names that may optionally appear on the same line as the let:\n\nlet var1 = value1, var2, var3 = value3\n code\nend\n\nThe variables introduced on this line are local to the let block and the assignments are evaluated in order, with each right-hand side evaluated in the scope without considering the name on the left-hand side. Therefore it makes sense to write something like let x = x, since the two x variables are distinct with the left-hand side locally shadowing the x from the outer scope. This can even be a useful idiom as new local variables are freshly created each time local scopes are entered, but this is only observable in the case of variables that outlive their scope via closures. A let variable without an assignment, such as var2 in the example above, declares a new local variable that is not yet bound to a value.\n\nBy contrast, begin blocks also group multiple expressions together but do not introduce scope or have the special assignment syntax.\n\nExamples\n\nIn the function below, there is a single x that is iteratively updated three times by the map. The closures returned all reference that one x at its final value:\n\njulia> function test_outer_x()\n x = 0\n map(1:3) do _\n x += 1\n return ()->x\n end\n end\ntest_outer_x (generic function with 1 method)\n\njulia> [f() for f in test_outer_x()]\n3-element Vector{Int64}:\n 3\n 3\n 3\n\nIf, however, we add a let block that introduces a new local variable we will end up with three distinct variables being captured (one at each iteration) even though we chose to use (shadow) the same name.\n\njulia> function test_let_x()\n x = 0\n map(1:3) do _\n x += 1\n let x = x\n return ()->x\n end\n end\n end\ntest_let_x (generic function with 1 method)\n\njulia> [f() for f in test_let_x()]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\nAll scope constructs that introduce new local variables behave this way when repeatedly run; the distinctive feature of let is its ability to succinctly declare new locals that may shadow outer variables of the same name. For example, directly using the argument of the do function similarly captures three distinct variables:\n\njulia> function test_do_x()\n map(1:3) do x\n return ()->x\n end\n end\ntest_do_x (generic function with 1 method)\n\njulia> [f() for f in test_do_x()]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#if","page":"Essentials","title":"if","text":"if/elseif/else\n\nif/elseif/else performs conditional evaluation, which allows portions of code to be evaluated or not evaluated depending on the value of a boolean expression. Here is the anatomy of the if/elseif/else conditional syntax:\n\nif x < y\n println(\"x is less than y\")\nelseif x > y\n println(\"x is greater than y\")\nelse\n println(\"x is equal to y\")\nend\n\nIf the condition expression x < y is true, then the corresponding block is evaluated; otherwise the condition expression x > y is evaluated, and if it is true, the corresponding block is evaluated; if neither expression is true, the else block is evaluated. The elseif and else blocks are optional, and as many elseif blocks as desired can be used.\n\nIn contrast to some other languages conditions must be of type Bool. It does not suffice for conditions to be convertible to Bool.\n\njulia> if 1 end\nERROR: TypeError: non-boolean (Int64) used in boolean context\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#for","page":"Essentials","title":"for","text":"for\n\nfor loops repeatedly evaluate a block of statements while iterating over a sequence of values.\n\nThe iteration variable is always a new variable, even if a variable of the same name exists in the enclosing scope. Use outer to reuse an existing local variable for iteration.\n\nExamples\n\njulia> for i in [1, 4, 0]\n println(i)\n end\n1\n4\n0\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#while","page":"Essentials","title":"while","text":"while\n\nwhile loops repeatedly evaluate a conditional expression, and continue evaluating the body of the while loop as long as the expression remains true. If the condition expression is false when the while loop is first reached, the body is never evaluated.\n\nExamples\n\njulia> i = 1\n1\n\njulia> while i < 5\n println(i)\n global i += 1\n end\n1\n2\n3\n4\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#break","page":"Essentials","title":"break","text":"break\n\nBreak out of a loop immediately.\n\nExamples\n\njulia> i = 0\n0\n\njulia> while true\n global i += 1\n i > 5 && break\n println(i)\n end\n1\n2\n3\n4\n5\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#continue","page":"Essentials","title":"continue","text":"continue\n\nSkip the rest of the current loop iteration.\n\nExamples\n\njulia> for i = 1:6\n iseven(i) && continue\n println(i)\n end\n1\n3\n5\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#try","page":"Essentials","title":"try","text":"try/catch\n\nA try/catch statement allows intercepting errors (exceptions) thrown by throw so that program execution can continue. For example, the following code attempts to write a file, but warns the user and proceeds instead of terminating execution if the file cannot be written:\n\ntry\n open(\"/danger\", \"w\") do f\n println(f, \"Hello\")\n end\ncatch\n @warn \"Could not write file.\"\nend\n\nor, when the file cannot be read into a variable:\n\nlines = try\n open(\"/danger\", \"r\") do f\n readlines(f)\n end\ncatch\n @warn \"File not found.\"\nend\n\nThe syntax catch e (where e is any variable) assigns the thrown exception object to the given variable within the catch block.\n\nThe power of the try/catch construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#finally","page":"Essentials","title":"finally","text":"finally\n\nRun some code when a given block of code exits, regardless of how it exits. For example, here is how we can guarantee that an opened file is closed:\n\nf = open(\"file\")\ntry\n operate_on_file(f)\nfinally\n close(f)\nend\n\nWhen control leaves the try block (for example, due to a return, or just finishing normally), close(f) will be executed. If the try block exits due to an exception, the exception will continue propagating. A catch block may be combined with try and finally as well. In this case the finally block will run after catch has handled the error.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#quote","page":"Essentials","title":"quote","text":"quote\n\nquote creates multiple expression objects in a block without using the explicit Expr constructor. For example:\n\nex = quote\n x = 1\n y = 2\n x + y\nend\n\nUnlike the other means of quoting, :( ... ), this form introduces QuoteNode elements to the expression tree, which must be considered when directly manipulating the tree. For other purposes, :( ... ) and quote .. end blocks are treated identically.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#local","page":"Essentials","title":"local","text":"local\n\nlocal introduces a new local variable. See the manual section on variable scoping for more information.\n\nExamples\n\njulia> function foo(n)\n x = 0\n for i = 1:n\n local x # introduce a loop-local x\n x = i\n end\n x\n end\nfoo (generic function with 1 method)\n\njulia> foo(10)\n0\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#global","page":"Essentials","title":"global","text":"global\n\nglobal x makes x in the current scope and its inner scopes refer to the global variable of that name. See the manual section on variable scoping for more information.\n\nExamples\n\njulia> z = 3\n3\n\njulia> function foo()\n global z = 6 # use the z variable defined outside foo\n end\nfoo (generic function with 1 method)\n\njulia> foo()\n6\n\njulia> z\n6\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#outer","page":"Essentials","title":"outer","text":"for outer\n\nReuse an existing local variable for iteration in a for loop.\n\nSee the manual section on variable scoping for more information.\n\nSee also for.\n\nExamples\n\njulia> function f()\n i = 0\n for i = 1:3\n # empty\n end\n return i\n end;\n\njulia> f()\n0\n\njulia> function f()\n i = 0\n for outer i = 1:3\n # empty\n end\n return i\n end;\n\njulia> f()\n3\n\njulia> i = 0 # global variable\n for outer i = 1:3\n end\nERROR: syntax: no outer local variable declaration exists for \"for outer\"\n[...]\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#const","page":"Essentials","title":"const","text":"const\n\nconst is used to declare global variables whose values will not change. In almost all code (and particularly performance sensitive code) global variables should be declared constant in this way.\n\nconst x = 5\n\nMultiple variables can be declared within a single const:\n\nconst y, z = 7, 11\n\nNote that const only applies to one = operation, therefore const x = y = 1 declares x to be constant but not y. On the other hand, const x = const y = 1 declares both x and y constant.\n\nNote that \"constant-ness\" does not extend into mutable containers; only the association between a variable and its value is constant. If x is an array or dictionary (for example) you can still modify, add, or remove elements.\n\nIn some cases changing the value of a const variable gives a warning instead of an error. However, this can produce unpredictable behavior or corrupt the state of your program, and so should be avoided. This feature is intended only for convenience during interactive use.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#struct","page":"Essentials","title":"struct","text":"struct\n\nThe most commonly used kind of type in Julia is a struct, specified as a name and a set of fields.\n\nstruct Point\n x\n y\nend\n\nFields can have type restrictions, which may be parameterized:\n\nstruct Point{X}\n x::X\n y::Float64\nend\n\nA struct can also declare an abstract super type via <: syntax:\n\nstruct Point <: AbstractPoint\n x\n y\nend\n\nstructs are immutable by default; an instance of one of these types cannot be modified after construction. Use mutable struct instead to declare a type whose instances can be modified.\n\nSee the manual section on Composite Types for more details, such as how to define constructors.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#mutable struct","page":"Essentials","title":"mutable struct","text":"mutable struct\n\nmutable struct is similar to struct, but additionally allows the fields of the type to be set after construction. See the manual section on Composite Types for more information.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.@kwdef","page":"Essentials","title":"Base.@kwdef","text":"@kwdef typedef\n\nThis is a helper macro that automatically defines a keyword-based constructor for the type declared in the expression typedef, which must be a struct or mutable struct expression. The default argument is supplied by declaring fields of the form field::T = default or field = default. If no default is provided then the keyword argument becomes a required keyword argument in the resulting type constructor.\n\nInner constructors can still be defined, but at least one should accept arguments in the same form as the default inner constructor (i.e. one positional argument per field) in order to function correctly with the keyword outer constructor.\n\ncompat: Julia 1.1\nBase.@kwdef for parametric structs, and structs with supertypes requires at least Julia 1.1.\n\ncompat: Julia 1.9\nThis macro is exported as of Julia 1.9.\n\nExamples\n\njulia> @kwdef struct Foo\n a::Int = 1 # specified default\n b::String # required keyword\n end\nFoo\n\njulia> Foo(b=\"hi\")\nFoo(1, \"hi\")\n\njulia> Foo()\nERROR: UndefKeywordError: keyword argument `b` not assigned\nStacktrace:\n[...]\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#abstract type","page":"Essentials","title":"abstract type","text":"abstract type\n\nabstract type declares a type that cannot be instantiated, and serves only as a node in the type graph, thereby describing sets of related concrete types: those concrete types which are their descendants. Abstract types form the conceptual hierarchy which makes Julia’s type system more than just a collection of object implementations. For example:\n\nabstract type Number end\nabstract type Real <: Number end\n\nNumber has no supertype, whereas Real is an abstract subtype of Number.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#primitive type","page":"Essentials","title":"primitive type","text":"primitive type\n\nprimitive type declares a concrete type whose data consists only of a series of bits. Classic examples of primitive types are integers and floating-point values. Some example built-in primitive type declarations:\n\nprimitive type Char 32 end\nprimitive type Bool <: Integer 8 end\n\nThe number after the name indicates how many bits of storage the type requires. Currently, only sizes that are multiples of 8 bits are supported. The Bool declaration shows how a primitive type can be optionally declared to be a subtype of some supertype.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#where","page":"Essentials","title":"where","text":"where\n\nThe where keyword creates a type that is an iterated union of other types, over all values of some variable. For example Vector{T} where T<:Real includes all Vectors where the element type is some kind of Real number.\n\nThe variable bound defaults to Any if it is omitted:\n\nVector{T} where T # short for `where T<:Any`\n\nVariables can also have lower bounds:\n\nVector{T} where T>:Int\nVector{T} where Int<:T<:Real\n\nThere is also a concise syntax for nested where expressions. For example, this:\n\nPair{T, S} where S<:Array{T} where T<:Number\n\ncan be shortened to:\n\nPair{T, S} where {T<:Number, S<:Array{T}}\n\nThis form is often found on method signatures.\n\nNote that in this form, the variables are listed outermost-first. This matches the order in which variables are substituted when a type is \"applied\" to parameter values using the syntax T{p1, p2, ...}.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#...","page":"Essentials","title":"...","text":"...\n\nThe \"splat\" operator, ..., represents a sequence of arguments. ... can be used in function definitions, to indicate that the function accepts an arbitrary number of arguments. ... can also be used to apply a function to a sequence of arguments.\n\nExamples\n\njulia> add(xs...) = reduce(+, xs)\nadd (generic function with 1 method)\n\njulia> add(1, 2, 3, 4, 5)\n15\n\njulia> add([1, 2, 3]...)\n6\n\njulia> add(7, 1:100..., 1000:1100...)\n111107\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#;","page":"Essentials","title":";","text":";\n\n; has a similar role in Julia as in many C-like languages, and is used to delimit the end of the previous statement.\n\n; is not necessary at the end of a line, but can be used to separate statements on a single line or to join statements into a single expression.\n\nAdding ; at the end of a line in the REPL will suppress printing the result of that expression.\n\nIn function declarations, and optionally in calls, ; separates regular arguments from keywords.\n\nIn array literals, arguments separated by semicolons have their contents concatenated together. A separator made of a single ; concatenates vertically (i.e. along the first dimension), ;; concatenates horizontally (second dimension), ;;; concatenates along the third dimension, etc. Such a separator can also be used in last position in the square brackets to add trailing dimensions of length 1.\n\nA ; in first position inside of parentheses can be used to construct a named tuple. The same (; ...) syntax on the left side of an assignment allows for property destructuring.\n\nIn the standard REPL, typing ; on an empty line will switch to shell mode.\n\nExamples\n\njulia> function foo()\n x = \"Hello, \"; x *= \"World!\"\n return x\n end\nfoo (generic function with 1 method)\n\njulia> bar() = (x = \"Hello, Mars!\"; return x)\nbar (generic function with 1 method)\n\njulia> foo();\n\njulia> bar()\n\"Hello, Mars!\"\n\njulia> function plot(x, y; style=\"solid\", width=1, color=\"black\")\n ###\n end\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> [1; 3;; 2; 4;;; 10*A]\n2×2×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 2\n 3 4\n\n[:, :, 2] =\n 10 20\n 30 40\n\njulia> [2; 3;;;]\n2×1×1 Array{Int64, 3}:\n[:, :, 1] =\n 2\n 3\n\njulia> nt = (; x=1) # without the ; or a trailing comma this would assign to x\n(x = 1,)\n\njulia> key = :a; c = 3;\n\njulia> nt2 = (; key => 1, b=2, c, nt.x)\n(a = 1, b = 2, c = 3, x = 1)\n\njulia> (; b, x) = nt2; # set variables b and x using property destructuring\n\njulia> b, x\n(2, 1)\n\njulia> ; # upon typing ;, the prompt changes (in place) to: shell>\nshell> echo hello\nhello\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#=","page":"Essentials","title":"=","text":"=\n\n= is the assignment operator.\n\nFor variable a and expression b, a = b makes a refer to the value of b.\nFor functions f(x), f(x) = x defines a new function constant f, or adds a new method to f if f is already defined; this usage is equivalent to function f(x); x; end.\na[i] = v calls setindex!(a,v,i).\na.b = c calls setproperty!(a,:b,c).\nInside a function call, f(a=b) passes b as the value of keyword argument a.\nInside parentheses with commas, (a=1,) constructs a NamedTuple.\n\nExamples\n\nAssigning a to b does not create a copy of b; instead use copy or deepcopy.\n\njulia> b = [1]; a = b; b[1] = 2; a\n1-element Array{Int64, 1}:\n 2\n\njulia> b = [1]; a = copy(b); b[1] = 2; a\n1-element Array{Int64, 1}:\n 1\n\n\nCollections passed to functions are also not copied. Functions can modify (mutate) the contents of the objects their arguments refer to. (The names of functions which do this are conventionally suffixed with '!'.)\n\njulia> function f!(x); x[:] .+= 1; end\nf! (generic function with 1 method)\n\njulia> a = [1]; f!(a); a\n1-element Array{Int64, 1}:\n 2\n\n\nAssignment can operate on multiple variables in parallel, taking values from an iterable:\n\njulia> a, b = 4, 5\n(4, 5)\n\njulia> a, b = 1:3\n1:3\n\njulia> a, b\n(1, 2)\n\n\nAssignment can operate on multiple variables in series, and will return the value of the right-hand-most expression:\n\njulia> a = [1]; b = [2]; c = [3]; a = b = c\n1-element Array{Int64, 1}:\n 3\n\njulia> b[1] = 2; a, b, c\n([2], [2], [2])\n\n\nAssignment at out-of-bounds indices does not grow a collection. If the collection is a Vector it can instead be grown with push! or append!.\n\njulia> a = [1, 1]; a[3] = 2\nERROR: BoundsError: attempt to access 2-element Array{Int64, 1} at index [3]\n[...]\n\njulia> push!(a, 2, 3)\n4-element Array{Int64, 1}:\n 1\n 1\n 2\n 3\n\n\nAssigning [] does not eliminate elements from a collection; instead use filter!.\n\njulia> a = collect(1:3); a[a .<= 1] = []\nERROR: DimensionMismatch: tried to assign 0 elements to 1 destinations\n[...]\n\njulia> filter!(x -> x > 1, a) # in-place & thus more efficient than a = a[a .> 1]\n2-element Array{Int64, 1}:\n 2\n 3\n\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#?:","page":"Essentials","title":"?:","text":"a ? b : c\n\nShort form for conditionals; read \"if a, evaluate b otherwise evaluate c\". Also known as the ternary operator.\n\nThis syntax is equivalent to if a; b else c end, but is often used to emphasize the value b-or-c which is being used as part of a larger expression, rather than the side effects that evaluating b or c may have.\n\nSee the manual section on control flow for more details.\n\nExamples\n\njulia> x = 1; y = 2;\n\njulia> x > y ? println(\"x is larger\") : println(\"y is larger\")\ny is larger\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Standard-Modules","page":"Essentials","title":"Standard Modules","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Main\nCore\nBase","category":"page"},{"location":"base/base/#Main","page":"Essentials","title":"Main","text":"Main\n\nMain is the top-level module, and Julia starts with Main set as the current module. Variables defined at the prompt go in Main, and varinfo lists variables in Main.\n\njulia> @__MODULE__\nMain\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Core","page":"Essentials","title":"Core","text":"Core\n\nCore is the module that contains all identifiers considered \"built in\" to the language, i.e. part of the core language and not libraries. Every module implicitly specifies using Core, since you can't do anything without those definitions.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base","page":"Essentials","title":"Base","text":"Base\n\nThe base library of Julia. Base is a module that contains basic functionality (the contents of base/). All modules implicitly contain using Base, since this is needed in the vast majority of cases.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base-Submodules","page":"Essentials","title":"Base Submodules","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.Broadcast\nBase.Docs\nBase.Iterators\nBase.Libc\nBase.Meta\nBase.StackTraces\nBase.Sys\nBase.Threads\nBase.GC","category":"page"},{"location":"base/base/#Base.Broadcast","page":"Essentials","title":"Base.Broadcast","text":"Base.Broadcast\n\nModule containing the broadcasting implementation.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Docs","page":"Essentials","title":"Base.Docs","text":"Docs\n\nThe Docs module provides the @doc macro which can be used to set and retrieve documentation metadata for Julia objects.\n\nPlease see the manual section on documentation for more information.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Iterators","page":"Essentials","title":"Base.Iterators","text":"Methods for working with Iterators.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Libc","page":"Essentials","title":"Base.Libc","text":"Interface to libc, the C standard library.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Meta","page":"Essentials","title":"Base.Meta","text":"Convenience functions for metaprogramming.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.StackTraces","page":"Essentials","title":"Base.StackTraces","text":"Tools for collecting and manipulating stack traces. Mainly used for building errors.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Sys","page":"Essentials","title":"Base.Sys","text":"Provide methods for retrieving information about hardware and the operating system.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Threads","page":"Essentials","title":"Base.Threads","text":"Multithreading support.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.GC","page":"Essentials","title":"Base.GC","text":"Base.GC\n\nModule with garbage collection utilities.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#All-Objects","page":"Essentials","title":"All Objects","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Core.:(===)\nCore.isa\nBase.isequal\nBase.isless\nBase.isunordered\nBase.ifelse\nCore.typeassert\nCore.typeof\nCore.tuple\nBase.ntuple\nBase.objectid\nBase.hash\nBase.finalizer\nBase.finalize\nBase.copy\nBase.deepcopy\nBase.getproperty\nBase.setproperty!\nBase.replaceproperty!\nBase.swapproperty!\nBase.modifyproperty!\nBase.setpropertyonce!\nBase.propertynames\nBase.hasproperty\nCore.getfield\nCore.setfield!\nCore.modifyfield!\nCore.replacefield!\nCore.swapfield!\nCore.setfieldonce!\nCore.isdefined\nBase.@isdefined\nBase.convert\nBase.promote\nBase.oftype\nBase.widen\nBase.identity\nBase.WeakRef","category":"page"},{"location":"base/base/#Core.:===","page":"Essentials","title":"Core.:===","text":"===(x,y) -> Bool\n≡(x,y) -> Bool\n\nDetermine whether x and y are identical, in the sense that no program could distinguish them. First the types of x and y are compared. If those are identical, mutable objects are compared by address in memory and immutable objects (such as numbers) are compared by contents at the bit level. This function is sometimes called \"egal\". It always returns a Bool value.\n\nExamples\n\njulia> a = [1, 2]; b = [1, 2];\n\njulia> a == b\ntrue\n\njulia> a === b\nfalse\n\njulia> a === a\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.isa","page":"Essentials","title":"Core.isa","text":"isa(x, type) -> Bool\n\nDetermine whether x is of the given type. Can also be used as an infix operator, e.g. x isa type.\n\nExamples\n\njulia> isa(1, Int)\ntrue\n\njulia> isa(1, Matrix)\nfalse\n\njulia> isa(1, Char)\nfalse\n\njulia> isa(1, Number)\ntrue\n\njulia> 1 isa Number\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isequal","page":"Essentials","title":"Base.isequal","text":"isequal(x, y) -> Bool\n\nSimilar to ==, except for the treatment of floating point numbers and of missing values. isequal treats all floating-point NaN values as equal to each other, treats -0.0 as unequal to 0.0, and missing as equal to missing. Always returns a Bool value.\n\nisequal is an equivalence relation - it is reflexive (=== implies isequal), symmetric (isequal(a, b) implies isequal(b, a)) and transitive (isequal(a, b) and isequal(b, c) implies isequal(a, c)).\n\nImplementation\n\nThe default implementation of isequal calls ==, so a type that does not involve floating-point values generally only needs to define ==.\n\nisequal is the comparison function used by hash tables (Dict). isequal(x,y) must imply that hash(x) == hash(y).\n\nThis typically means that types for which a custom == or isequal method exists must implement a corresponding hash method (and vice versa). Collections typically implement isequal by calling isequal recursively on all contents.\n\nFurthermore, isequal is linked with isless, and they work together to define a fixed total ordering, where exactly one of isequal(x, y), isless(x, y), or isless(y, x) must be true (and the other two false).\n\nScalar types generally do not need to implement isequal separate from ==, unless they represent floating-point numbers amenable to a more efficient implementation than that provided as a generic fallback (based on isnan, signbit, and ==).\n\nExamples\n\njulia> isequal([1., NaN], [1., NaN])\ntrue\n\njulia> [1., NaN] == [1., NaN]\nfalse\n\njulia> 0.0 == -0.0\ntrue\n\njulia> isequal(0.0, -0.0)\nfalse\n\njulia> missing == missing\nmissing\n\njulia> isequal(missing, missing)\ntrue\n\n\n\n\n\nisequal(x)\n\nCreate a function that compares its argument to x using isequal, i.e. a function equivalent to y -> isequal(y, x).\n\nThe returned function is of type Base.Fix2{typeof(isequal)}, which can be used to implement specialized methods.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isless","page":"Essentials","title":"Base.isless","text":"isless(x, y)\n\nTest whether x is less than y, according to a fixed total order (defined together with isequal). isless is not defined for pairs (x, y) of all types. However, if it is defined, it is expected to satisfy the following:\n\nIf isless(x, y) is defined, then so is isless(y, x) and isequal(x, y), and exactly one of those three yields true.\nThe relation defined by isless is transitive, i.e., isless(x, y) && isless(y, z) implies isless(x, z).\n\nValues that are normally unordered, such as NaN, are ordered after regular values. missing values are ordered last.\n\nThis is the default comparison used by sort!.\n\nImplementation\n\nNon-numeric types with a total order should implement this function. Numeric types only need to implement it if they have special values such as NaN. Types with a partial order should implement <. See the documentation on Alternate Orderings for how to define alternate ordering methods that can be used in sorting and related functions.\n\nExamples\n\njulia> isless(1, 3)\ntrue\n\njulia> isless(\"Red\", \"Blue\")\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isunordered","page":"Essentials","title":"Base.isunordered","text":"isunordered(x)\n\nReturn true if x is a value that is not orderable according to <, such as NaN or missing.\n\nThe values that evaluate to true with this predicate may be orderable with respect to other orderings such as isless.\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ifelse","page":"Essentials","title":"Base.ifelse","text":"ifelse(condition::Bool, x, y)\n\nReturn x if condition is true, otherwise return y. This differs from ? or if in that it is an ordinary function, so all the arguments are evaluated first. In some cases, using ifelse instead of an if statement can eliminate the branch in generated code and provide higher performance in tight loops.\n\nExamples\n\njulia> ifelse(1 > 2, 1, 2)\n2\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.typeassert","page":"Essentials","title":"Core.typeassert","text":"typeassert(x, type)\n\nThrow a TypeError unless x isa type. The syntax x::type calls this function.\n\nExamples\n\njulia> typeassert(2.5, Int)\nERROR: TypeError: in typeassert, expected Int64, got a value of type Float64\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.typeof","page":"Essentials","title":"Core.typeof","text":"typeof(x)\n\nGet the concrete type of x.\n\nSee also eltype.\n\nExamples\n\njulia> a = 1//2;\n\njulia> typeof(a)\nRational{Int64}\n\njulia> M = [1 2; 3.5 4];\n\njulia> typeof(M)\nMatrix{Float64} (alias for Array{Float64, 2})\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.tuple","page":"Essentials","title":"Core.tuple","text":"tuple(xs...)\n\nConstruct a tuple of the given objects.\n\nSee also Tuple, ntuple, NamedTuple.\n\nExamples\n\njulia> tuple(1, 'b', pi)\n(1, 'b', π)\n\njulia> ans === (1, 'b', π)\ntrue\n\njulia> Tuple(Real[1, 2, pi]) # takes a collection\n(1, 2, π)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ntuple","page":"Essentials","title":"Base.ntuple","text":"ntuple(f, n::Integer)\n\nCreate a tuple of length n, computing each element as f(i), where i is the index of the element.\n\nExamples\n\njulia> ntuple(i -> 2*i, 4)\n(2, 4, 6, 8)\n\n\n\n\n\nntuple(f, ::Val{N})\n\nCreate a tuple of length N, computing each element as f(i), where i is the index of the element. By taking a Val(N) argument, it is possible that this version of ntuple may generate more efficient code than the version taking the length as an integer. But ntuple(f, N) is preferable to ntuple(f, Val(N)) in cases where N cannot be determined at compile time.\n\nExamples\n\njulia> ntuple(i -> 2*i, Val(4))\n(2, 4, 6, 8)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.objectid","page":"Essentials","title":"Base.objectid","text":"objectid(x) -> UInt\n\nGet a hash value for x based on object identity.\n\nIf x === y then objectid(x) == objectid(y), and usually when x !== y, objectid(x) != objectid(y).\n\nSee also hash, IdDict.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.hash","page":"Essentials","title":"Base.hash","text":"hash(x[, h::UInt]) -> UInt\n\nCompute an integer hash code such that isequal(x,y) implies hash(x)==hash(y). The optional second argument h is another hash code to be mixed with the result.\n\nNew types should implement the 2-argument form, typically by calling the 2-argument hash method recursively in order to mix hashes of the contents with each other (and with h). Typically, any type that implements hash should also implement its own == (hence isequal) to guarantee the property mentioned above. Types supporting subtraction (operator -) should also implement widen, which is required to hash values inside heterogeneous arrays.\n\nThe hash value may change when a new Julia process is started.\n\njulia> a = hash(10)\n0x95ea2955abd45275\n\njulia> hash(10, a) # only use the output of another hash function as the second argument\n0xd42bad54a8575b16\n\nSee also: objectid, Dict, Set.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.finalizer","page":"Essentials","title":"Base.finalizer","text":"finalizer(f, x)\n\nRegister a function f(x) to be called when there are no program-accessible references to x, and return x. The type of x must be a mutable struct, otherwise the function will throw.\n\nf must not cause a task switch, which excludes most I/O operations such as println. Using the @async macro (to defer context switching to outside of the finalizer) or ccall to directly invoke IO functions in C may be helpful for debugging purposes.\n\nNote that there is no guaranteed world age for the execution of f. It may be called in the world age in which the finalizer was registered or any later world age.\n\nExamples\n\nfinalizer(my_mutable_struct) do x\n @async println(\"Finalizing $x.\")\nend\n\nfinalizer(my_mutable_struct) do x\n ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), \"Finalizing %s.\", repr(x))\nend\n\nA finalizer may be registered at object construction. In the following example note that we implicitly rely on the finalizer returning the newly created mutable struct x.\n\nmutable struct MyMutableStruct\n bar\n function MyMutableStruct(bar)\n x = new(bar)\n f(t) = @async println(\"Finalizing $t.\")\n finalizer(f, x)\n end\nend\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.finalize","page":"Essentials","title":"Base.finalize","text":"finalize(x)\n\nImmediately run finalizers registered for object x.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.copy","page":"Essentials","title":"Base.copy","text":"copy(x)\n\nCreate a shallow copy of x: the outer structure is copied, but not all internal values. For example, copying an array produces a new array with identically-same elements as the original.\n\nSee also copy!, copyto!, deepcopy.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.deepcopy","page":"Essentials","title":"Base.deepcopy","text":"deepcopy(x)\n\nCreate a deep copy of x: everything is copied recursively, resulting in a fully independent object. For example, deep-copying an array creates deep copies of all the objects it contains and produces a new array with the consistent relationship structure (e.g., if the first two elements are the same object in the original array, the first two elements of the new array will also be the same deepcopyed object). Calling deepcopy on an object should generally have the same effect as serializing and then deserializing it.\n\nWhile it isn't normally necessary, user-defined types can override the default deepcopy behavior by defining a specialized version of the function deepcopy_internal(x::T, dict::IdDict) (which shouldn't otherwise be used), where T is the type to be specialized for, and dict keeps track of objects copied so far within the recursion. Within the definition, deepcopy_internal should be used in place of deepcopy, and the dict variable should be updated as appropriate before returning.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.getproperty","page":"Essentials","title":"Base.getproperty","text":"getproperty(value, name::Symbol)\ngetproperty(value, name::Symbol, order::Symbol)\n\nThe syntax a.b calls getproperty(a, :b). The syntax @atomic order a.b calls getproperty(a, :b, :order) and the syntax @atomic a.b calls getproperty(a, :b, :sequentially_consistent).\n\nExamples\n\njulia> struct MyType{T <: Number}\n x::T\n end\n\njulia> function Base.getproperty(obj::MyType, sym::Symbol)\n if sym === :special\n return obj.x + 1\n else # fallback to getfield\n return getfield(obj, sym)\n end\n end\n\njulia> obj = MyType(1);\n\njulia> obj.special\n2\n\njulia> obj.x\n1\n\nOne should overload getproperty only when necessary, as it can be confusing if the behavior of the syntax obj.f is unusual. Also note that using methods is often preferable. See also this style guide documentation for more information: Prefer exported methods over direct field access.\n\nSee also getfield, propertynames and setproperty!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.setproperty!","page":"Essentials","title":"Base.setproperty!","text":"setproperty!(value, name::Symbol, x)\nsetproperty!(value, name::Symbol, x, order::Symbol)\n\nThe syntax a.b = c calls setproperty!(a, :b, c). The syntax @atomic order a.b = c calls setproperty!(a, :b, c, :order) and the syntax @atomic a.b = c calls setproperty!(a, :b, c, :sequentially_consistent).\n\ncompat: Julia 1.8\nsetproperty! on modules requires at least Julia 1.8.\n\nSee also setfield!, propertynames and getproperty.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.replaceproperty!","page":"Essentials","title":"Base.replaceproperty!","text":"replaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)\n\nPerform a compare-and-swap operation on x.f from expected to desired, per egal. The syntax @atomicreplace x.f expected => desired can be used instead of the function call form.\n\nSee also replacefield! setproperty!, setpropertyonce!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.swapproperty!","page":"Essentials","title":"Base.swapproperty!","text":"swapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)\n\nThe syntax @atomic a.b, _ = c, a.b returns (c, swapproperty!(a, :b, c, :sequentially_consistent)), where there must be one getproperty expression common to both sides.\n\nSee also swapfield! and setproperty!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.modifyproperty!","page":"Essentials","title":"Base.modifyproperty!","text":"modifyproperty!(x, f::Symbol, op, v, order::Symbol=:not_atomic)\n\nThe syntax @atomic op(x.f, v) (and its equivalent @atomic x.f op v) returns modifyproperty!(x, :f, op, v, :sequentially_consistent), where the first argument must be a getproperty expression and is modified atomically.\n\nInvocation of op(getproperty(x, f), v) must return a value that can be stored in the field f of the object x by default. In particular, unlike the default behavior of setproperty!, the convert function is not called automatically.\n\nSee also modifyfield! and setproperty!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.setpropertyonce!","page":"Essentials","title":"Base.setpropertyonce!","text":"setpropertyonce!(x, f::Symbol, value, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)\n\nPerform a compare-and-swap operation on x.f to set it to value if previously unset. The syntax @atomiconce x.f = value can be used instead of the function call form.\n\nSee also setfieldonce!, setproperty!, replaceproperty!.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.propertynames","page":"Essentials","title":"Base.propertynames","text":"propertynames(x, private=false)\n\nGet a tuple or a vector of the properties (x.property) of an object x. This is typically the same as fieldnames(typeof(x)), but types that overload getproperty should generally overload propertynames as well to get the properties of an instance of the type.\n\npropertynames(x) may return only \"public\" property names that are part of the documented interface of x. If you want it to also return \"private\" property names intended for internal use, pass true for the optional second argument. REPL tab completion on x. shows only the private=false properties.\n\nSee also: hasproperty, hasfield.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.hasproperty","page":"Essentials","title":"Base.hasproperty","text":"hasproperty(x, s::Symbol)\n\nReturn a boolean indicating whether the object x has s as one of its own properties.\n\ncompat: Julia 1.2\nThis function requires at least Julia 1.2.\n\nSee also: propertynames, hasfield.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.getfield","page":"Essentials","title":"Core.getfield","text":"getfield(value, name::Symbol, [order::Symbol])\ngetfield(value, i::Int, [order::Symbol])\n\nExtract a field from a composite value by name or position. Optionally, an ordering can be defined for the operation. If the field was declared @atomic, the specification is strongly recommended to be compatible with the stores to that location. Otherwise, if not declared as @atomic, this parameter must be :not_atomic if specified. See also getproperty and fieldnames.\n\nExamples\n\njulia> a = 1//2\n1//2\n\njulia> getfield(a, :num)\n1\n\njulia> a.num\n1\n\njulia> getfield(a, 1)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.setfield!","page":"Essentials","title":"Core.setfield!","text":"setfield!(value, name::Symbol, x, [order::Symbol])\nsetfield!(value, i::Int, x, [order::Symbol])\n\nAssign x to a named field in value of composite type. The value must be mutable and x must be a subtype of fieldtype(typeof(value), name). Additionally, an ordering can be specified for this operation. If the field was declared @atomic, this specification is mandatory. Otherwise, if not declared as @atomic, it must be :not_atomic if specified. See also setproperty!.\n\nExamples\n\njulia> mutable struct MyMutableStruct\n field::Int\n end\n\njulia> a = MyMutableStruct(1);\n\njulia> setfield!(a, :field, 2);\n\njulia> getfield(a, :field)\n2\n\njulia> a = 1//2\n1//2\n\njulia> setfield!(a, :num, 3);\nERROR: setfield!: immutable struct of type Rational cannot be changed\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.modifyfield!","page":"Essentials","title":"Core.modifyfield!","text":"modifyfield!(value, name::Symbol, op, x, [order::Symbol]) -> Pair\nmodifyfield!(value, i::Int, op, x, [order::Symbol]) -> Pair\n\nAtomically perform the operations to get and set a field after applying the function op.\n\ny = getfield(value, name)\nz = op(y, x)\nsetfield!(value, name, z)\nreturn y => z\n\nIf supported by the hardware (for example, atomic increment), this may be optimized to the appropriate hardware instruction, otherwise it'll use a loop.\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.replacefield!","page":"Essentials","title":"Core.replacefield!","text":"replacefield!(value, name::Symbol, expected, desired,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)\nreplacefield!(value, i::Int, expected, desired,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)\n\nAtomically perform the operations to get and conditionally set a field to a given value.\n\ny = getfield(value, name, fail_order)\nok = y === expected\nif ok\n setfield!(value, name, desired, success_order)\nend\nreturn (; old = y, success = ok)\n\nIf supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise it'll use a loop.\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.swapfield!","page":"Essentials","title":"Core.swapfield!","text":"swapfield!(value, name::Symbol, x, [order::Symbol])\nswapfield!(value, i::Int, x, [order::Symbol])\n\nAtomically perform the operations to simultaneously get and set a field:\n\ny = getfield(value, name)\nsetfield!(value, name, x)\nreturn y\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.setfieldonce!","page":"Essentials","title":"Core.setfieldonce!","text":"setfieldonce!(value, name::Union{Int,Symbol}, desired,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool\n\nAtomically perform the operations to set a field to a given value, only if it was previously not set.\n\nok = !isdefined(value, name, fail_order)\nif ok\n setfield!(value, name, desired, success_order)\nend\nreturn ok\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.isdefined","page":"Essentials","title":"Core.isdefined","text":"isdefined(m::Module, s::Symbol, [order::Symbol])\nisdefined(object, s::Symbol, [order::Symbol])\nisdefined(object, index::Int, [order::Symbol])\n\nTests whether a global variable or object field is defined. The arguments can be a module and a symbol or a composite object and field name (as a symbol) or index. Optionally, an ordering can be defined for the operation. If the field was declared @atomic, the specification is strongly recommended to be compatible with the stores to that location. Otherwise, if not declared as @atomic, this parameter must be :not_atomic if specified.\n\nTo test whether an array element is defined, use isassigned instead.\n\nSee also @isdefined.\n\nExamples\n\njulia> isdefined(Base, :sum)\ntrue\n\njulia> isdefined(Base, :NonExistentMethod)\nfalse\n\njulia> a = 1//2;\n\njulia> isdefined(a, 2)\ntrue\n\njulia> isdefined(a, 3)\nfalse\n\njulia> isdefined(a, :num)\ntrue\n\njulia> isdefined(a, :numerator)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@isdefined","page":"Essentials","title":"Base.@isdefined","text":"@isdefined s -> Bool\n\nTests whether variable s is defined in the current scope.\n\nSee also isdefined for field properties and isassigned for array indexes or haskey for other mappings.\n\nExamples\n\njulia> @isdefined newvar\nfalse\n\njulia> newvar = 1\n1\n\njulia> @isdefined newvar\ntrue\n\njulia> function f()\n println(@isdefined x)\n x = 3\n println(@isdefined x)\n end\nf (generic function with 1 method)\n\njulia> f()\nfalse\ntrue\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.convert","page":"Essentials","title":"Base.convert","text":"convert(T, x)\n\nConvert x to a value of type T.\n\nIf T is an Integer type, an InexactError will be raised if x is not representable by T, for example if x is not integer-valued, or is outside the range supported by T.\n\nExamples\n\njulia> convert(Int, 3.0)\n3\n\njulia> convert(Int, 3.5)\nERROR: InexactError: Int64(3.5)\nStacktrace:\n[...]\n\nIf T is a AbstractFloat type, then it will return the closest value to x representable by T.\n\njulia> x = 1/3\n0.3333333333333333\n\njulia> convert(Float32, x)\n0.33333334f0\n\njulia> convert(BigFloat, x)\n0.333333333333333314829616256247390992939472198486328125\n\nIf T is a collection type and x a collection, the result of convert(T, x) may alias all or part of x.\n\njulia> x = Int[1, 2, 3];\n\njulia> y = convert(Vector{Int}, x);\n\njulia> y === x\ntrue\n\nSee also: round, trunc, oftype, reinterpret.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.promote","page":"Essentials","title":"Base.promote","text":"promote(xs...)\n\nConvert all arguments to a common type, and return them all (as a tuple). If no arguments can be converted, an error is raised.\n\nSee also: promote_type, promote_rule.\n\nExamples\n\njulia> promote(Int8(1), Float16(4.5), Float32(4.1))\n(1.0f0, 4.5f0, 4.1f0)\n\njulia> promote_type(Int8, Float16, Float32)\nFloat32\n\njulia> reduce(Base.promote_typejoin, (Int8, Float16, Float32))\nReal\n\njulia> promote(1, \"x\")\nERROR: promotion of types Int64 and String failed to change any arguments\n[...]\n\njulia> promote_type(Int, String)\nAny\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.oftype","page":"Essentials","title":"Base.oftype","text":"oftype(x, y)\n\nConvert y to the type of x i.e. convert(typeof(x), y).\n\nExamples\n\njulia> x = 4;\n\njulia> y = 3.;\n\njulia> oftype(x, y)\n3\n\njulia> oftype(y, x)\n4.0\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.widen","page":"Essentials","title":"Base.widen","text":"widen(x)\n\nIf x is a type, return a \"larger\" type, defined so that arithmetic operations + and - are guaranteed not to overflow nor lose precision for any combination of values that type x can hold.\n\nFor fixed-size integer types less than 128 bits, widen will return a type with twice the number of bits.\n\nIf x is a value, it is converted to widen(typeof(x)).\n\nExamples\n\njulia> widen(Int32)\nInt64\n\njulia> widen(1.5f0)\n1.5\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.identity","page":"Essentials","title":"Base.identity","text":"identity(x)\n\nThe identity function. Returns its argument.\n\nSee also: one, oneunit, and LinearAlgebra's I.\n\nExamples\n\njulia> identity(\"Well, what did you expect?\")\n\"Well, what did you expect?\"\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.WeakRef","page":"Essentials","title":"Core.WeakRef","text":"WeakRef(x)\n\nw = WeakRef(x) constructs a weak reference to the Julia value x: although w contains a reference to x, it does not prevent x from being garbage collected. w.value is either x (if x has not been garbage-collected yet) or nothing (if x has been garbage-collected).\n\njulia> x = \"a string\"\n\"a string\"\n\njulia> w = WeakRef(x)\nWeakRef(\"a string\")\n\njulia> GC.gc()\n\njulia> w # a reference is maintained via `x`\nWeakRef(\"a string\")\n\njulia> x = nothing # clear reference\n\njulia> GC.gc()\n\njulia> w\nWeakRef(nothing)\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Properties-of-Types","page":"Essentials","title":"Properties of Types","text":"","category":"section"},{"location":"base/base/#Type-relations","page":"Essentials","title":"Type relations","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.supertype\nCore.Type\nCore.DataType\nCore.:(<:)\nBase.:(>:)\nBase.typejoin\nBase.typeintersect\nBase.promote_type\nBase.promote_rule\nBase.promote_typejoin\nBase.isdispatchtuple","category":"page"},{"location":"base/base/#Base.supertype","page":"Essentials","title":"Base.supertype","text":"supertype(T::DataType)\n\nReturn the supertype of DataType T.\n\nExamples\n\njulia> supertype(Int32)\nSigned\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.Type","page":"Essentials","title":"Core.Type","text":"Core.Type{T}\n\nCore.Type is an abstract type which has all type objects as its instances. The only instance of the singleton type Core.Type{T} is the object T.\n\nExamples\n\njulia> isa(Type{Float64}, Type)\ntrue\n\njulia> isa(Float64, Type)\ntrue\n\njulia> isa(Real, Type{Float64})\nfalse\n\njulia> isa(Real, Type{Real})\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.DataType","page":"Essentials","title":"Core.DataType","text":"DataType <: Type{T}\n\nDataType represents explicitly declared types that have names, explicitly declared supertypes, and, optionally, parameters. Every concrete value in the system is an instance of some DataType.\n\nExamples\n\njulia> typeof(Real)\nDataType\n\njulia> typeof(Int)\nDataType\n\njulia> struct Point\n x::Int\n y\n end\n\njulia> typeof(Point)\nDataType\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.:<:","page":"Essentials","title":"Core.:<:","text":"<:(T1, T2)::Bool\n\nSubtyping relation, defined between two types. In Julia, a type S is said to be a subtype of a type T if and only if we have S <: T.\n\nFor any type L and any type R, L <: R implies that any value v of type L is also of type R. I.e., (L <: R) && (v isa L) implies v isa R.\n\nThe subtyping relation is a partial order. I.e., <: is:\n\nreflexive: for any type T, T <: T holds\nantisymmetric: for any type A and any type B, (A <: B) && (B <: A) implies A == B\ntransitive: for any type A, any type B and any type C; (A <: B) && (B <: C) implies A <: C\n\nSee also info on Types, Union{}, Any, isa.\n\nExamples\n\njulia> Float64 <: AbstractFloat\ntrue\n\njulia> Vector{Int} <: AbstractArray\ntrue\n\njulia> Matrix{Float64} <: Matrix{AbstractFloat} # `Matrix` is invariant\nfalse\n\njulia> Tuple{Float64} <: Tuple{AbstractFloat} # `Tuple` is covariant\ntrue\n\njulia> Union{} <: Int # The bottom type, `Union{}`, subtypes each type.\ntrue\n\njulia> Union{} <: Float32 <: AbstractFloat <: Real <: Number <: Any # Operator chaining\ntrue\n\nThe <: keyword also has several syntactic uses which represent the same subtyping relation, but which do not execute the operator or return a Bool:\n\nTo specify the lower bound and the upper bound on a parameter of a UnionAll type in a where statement.\nTo specify the lower bound and the upper bound on a (static) parameter of a method, see Parametric Methods.\nTo define a subtyping relation while declaring a new type, see struct and abstract type.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.:>:","page":"Essentials","title":"Base.:>:","text":">:(T1, T2)\n\nSupertype operator, equivalent to T2 <: T1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.typejoin","page":"Essentials","title":"Base.typejoin","text":"typejoin(T, S, ...)\n\nReturn the closest common ancestor of types T and S, i.e. the narrowest type from which they both inherit. Recurses on additional varargs.\n\nExamples\n\njulia> typejoin(Int, Float64)\nReal\n\njulia> typejoin(Int, Float64, ComplexF32)\nNumber\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.typeintersect","page":"Essentials","title":"Base.typeintersect","text":"typeintersect(T::Type, S::Type)\n\nCompute a type that contains the intersection of T and S. Usually this will be the smallest such type or one close to it.\n\nA special case where exact behavior is guaranteed: when T <: S, typeintersect(S, T) == T == typeintersect(T, S).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.promote_type","page":"Essentials","title":"Base.promote_type","text":"promote_type(type1, type2, ...)\n\nPromotion refers to converting values of mixed types to a single common type. promote_type represents the default promotion behavior in Julia when operators (usually mathematical) are given arguments of differing types. promote_type generally tries to return a type which can at least approximate most values of either input type without excessively widening. Some loss is tolerated; for example, promote_type(Int64, Float64) returns Float64 even though strictly, not all Int64 values can be represented exactly as Float64 values.\n\nSee also: promote, promote_typejoin, promote_rule.\n\nExamples\n\njulia> promote_type(Int64, Float64)\nFloat64\n\njulia> promote_type(Int32, Int64)\nInt64\n\njulia> promote_type(Float32, BigInt)\nBigFloat\n\njulia> promote_type(Int16, Float16)\nFloat16\n\njulia> promote_type(Int64, Float16)\nFloat16\n\njulia> promote_type(Int8, UInt16)\nUInt16\n\nwarning: Don't overload this directly\nTo overload promotion for your own types you should overload promote_rule. promote_type calls promote_rule internally to determine the type. Overloading promote_type directly can cause ambiguity errors.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.promote_rule","page":"Essentials","title":"Base.promote_rule","text":"promote_rule(type1, type2)\n\nSpecifies what type should be used by promote when given values of types type1 and type2. This function should not be called directly, but should have definitions added to it for new types as appropriate.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.promote_typejoin","page":"Essentials","title":"Base.promote_typejoin","text":"promote_typejoin(T, S)\n\nCompute a type that contains both T and S, which could be either a parent of both types, or a Union if appropriate. Falls back to typejoin.\n\nSee instead promote, promote_type.\n\nExamples\n\njulia> Base.promote_typejoin(Int, Float64)\nReal\n\njulia> Base.promote_type(Int, Float64)\nFloat64\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isdispatchtuple","page":"Essentials","title":"Base.isdispatchtuple","text":"isdispatchtuple(T)\n\nDetermine whether type T is a tuple \"leaf type\", meaning it could appear as a type signature in dispatch and has no subtypes (or supertypes) which could appear in a call. If T is not a type, then return false.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Declared-structure","page":"Essentials","title":"Declared structure","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.ismutable\nBase.isimmutable\nBase.ismutabletype\nBase.isabstracttype\nBase.isprimitivetype\nBase.issingletontype\nBase.isstructtype\nBase.nameof(::DataType)\nBase.fieldnames\nBase.fieldname\nCore.fieldtype\nBase.fieldtypes\nBase.fieldcount\nBase.hasfield\nCore.nfields\nBase.isconst\nBase.isfieldatomic","category":"page"},{"location":"base/base/#Base.ismutable","page":"Essentials","title":"Base.ismutable","text":"ismutable(v) -> Bool\n\nReturn true if and only if value v is mutable. See Mutable Composite Types for a discussion of immutability. Note that this function works on values, so if you give it a DataType, it will tell you that a value of the type is mutable.\n\nnote: Note\nFor technical reasons, ismutable returns true for values of certain special types (for example String and Symbol) even though they cannot be mutated in a permissible way.\n\nSee also isbits, isstructtype.\n\nExamples\n\njulia> ismutable(1)\nfalse\n\njulia> ismutable([1,2])\ntrue\n\ncompat: Julia 1.5\nThis function requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isimmutable","page":"Essentials","title":"Base.isimmutable","text":"isimmutable(v) -> Bool\n\nwarning: Warning\nConsider using !ismutable(v) instead, as isimmutable(v) will be replaced by !ismutable(v) in a future release. (Since Julia 1.5)\n\nReturn true iff value v is immutable. See Mutable Composite Types for a discussion of immutability. Note that this function works on values, so if you give it a type, it will tell you that a value of DataType is mutable.\n\nExamples\n\njulia> isimmutable(1)\ntrue\n\njulia> isimmutable([1,2])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ismutabletype","page":"Essentials","title":"Base.ismutabletype","text":"ismutabletype(T) -> Bool\n\nDetermine whether type T was declared as a mutable type (i.e. using mutable struct keyword). If T is not a type, then return false.\n\ncompat: Julia 1.7\nThis function requires at least Julia 1.7.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isabstracttype","page":"Essentials","title":"Base.isabstracttype","text":"isabstracttype(T)\n\nDetermine whether type T was declared as an abstract type (i.e. using the abstract type syntax). Note that this is not the negation of isconcretetype(T). If T is not a type, then return false.\n\nExamples\n\njulia> isabstracttype(AbstractArray)\ntrue\n\njulia> isabstracttype(Vector)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isprimitivetype","page":"Essentials","title":"Base.isprimitivetype","text":"isprimitivetype(T) -> Bool\n\nDetermine whether type T was declared as a primitive type (i.e. using the primitive type syntax). If T is not a type, then return false.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.issingletontype","page":"Essentials","title":"Base.issingletontype","text":"Base.issingletontype(T)\n\nDetermine whether type T has exactly one possible instance; for example, a struct type with no fields except other singleton values. If T is not a concrete type, then return false.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isstructtype","page":"Essentials","title":"Base.isstructtype","text":"isstructtype(T) -> Bool\n\nDetermine whether type T was declared as a struct type (i.e. using the struct or mutable struct keyword). If T is not a type, then return false.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.nameof-Tuple{DataType}","page":"Essentials","title":"Base.nameof","text":"nameof(t::DataType) -> Symbol\n\nGet the name of a (potentially UnionAll-wrapped) DataType (without its parent module) as a symbol.\n\nExamples\n\njulia> module Foo\n struct S{T}\n end\n end\nFoo\n\njulia> nameof(Foo.S{T} where T)\n:S\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.fieldnames","page":"Essentials","title":"Base.fieldnames","text":"fieldnames(x::DataType)\n\nGet a tuple with the names of the fields of a DataType.\n\nSee also propertynames, hasfield.\n\nExamples\n\njulia> fieldnames(Rational)\n(:num, :den)\n\njulia> fieldnames(typeof(1+im))\n(:re, :im)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.fieldname","page":"Essentials","title":"Base.fieldname","text":"fieldname(x::DataType, i::Integer)\n\nGet the name of field i of a DataType.\n\nExamples\n\njulia> fieldname(Rational, 1)\n:num\n\njulia> fieldname(Rational, 2)\n:den\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.fieldtype","page":"Essentials","title":"Core.fieldtype","text":"fieldtype(T, name::Symbol | index::Int)\n\nDetermine the declared type of a field (specified by name or index) in a composite DataType T.\n\nExamples\n\njulia> struct Foo\n x::Int64\n y::String\n end\n\njulia> fieldtype(Foo, :x)\nInt64\n\njulia> fieldtype(Foo, 2)\nString\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.fieldtypes","page":"Essentials","title":"Base.fieldtypes","text":"fieldtypes(T::Type)\n\nThe declared types of all fields in a composite DataType T as a tuple.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nExamples\n\njulia> struct Foo\n x::Int64\n y::String\n end\n\njulia> fieldtypes(Foo)\n(Int64, String)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.fieldcount","page":"Essentials","title":"Base.fieldcount","text":"fieldcount(t::Type)\n\nGet the number of fields that an instance of the given type would have. An error is thrown if the type is too abstract to determine this.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.hasfield","page":"Essentials","title":"Base.hasfield","text":"hasfield(T::Type, name::Symbol)\n\nReturn a boolean indicating whether T has name as one of its own fields.\n\nSee also fieldnames, fieldcount, hasproperty.\n\ncompat: Julia 1.2\nThis function requires at least Julia 1.2.\n\nExamples\n\njulia> struct Foo\n bar::Int\n end\n\njulia> hasfield(Foo, :bar)\ntrue\n\njulia> hasfield(Foo, :x)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.nfields","page":"Essentials","title":"Core.nfields","text":"nfields(x) -> Int\n\nGet the number of fields in the given object.\n\nExamples\n\njulia> a = 1//2;\n\njulia> nfields(a)\n2\n\njulia> b = 1\n1\n\njulia> nfields(b)\n0\n\njulia> ex = ErrorException(\"I've done a bad thing\");\n\njulia> nfields(ex)\n1\n\nIn these examples, a is a Rational, which has two fields. b is an Int, which is a primitive bitstype with no fields at all. ex is an ErrorException, which has one field.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isconst","page":"Essentials","title":"Base.isconst","text":"isconst(m::Module, s::Symbol) -> Bool\n\nDetermine whether a global is declared const in a given module m.\n\n\n\n\n\nisconst(t::DataType, s::Union{Int,Symbol}) -> Bool\n\nDetermine whether a field s is declared const in a given type t.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isfieldatomic","page":"Essentials","title":"Base.isfieldatomic","text":"isfieldatomic(t::DataType, s::Union{Int,Symbol}) -> Bool\n\nDetermine whether a field s is declared @atomic in a given type t.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Memory-layout","page":"Essentials","title":"Memory layout","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.sizeof(::Type)\nBase.isconcretetype\nBase.isbits\nBase.isbitstype\nBase.fieldoffset\nBase.datatype_alignment\nBase.datatype_haspadding\nBase.datatype_pointerfree","category":"page"},{"location":"base/base/#Base.sizeof-Tuple{Type}","page":"Essentials","title":"Base.sizeof","text":"sizeof(T::DataType)\nsizeof(obj)\n\nSize, in bytes, of the canonical binary representation of the given DataType T, if any. Or the size, in bytes, of object obj if it is not a DataType.\n\nSee also Base.summarysize.\n\nExamples\n\njulia> sizeof(Float32)\n4\n\njulia> sizeof(ComplexF64)\n16\n\njulia> sizeof(1.0)\n8\n\njulia> sizeof(collect(1.0:10.0))\n80\n\njulia> struct StructWithPadding\n x::Int64\n flag::Bool\n end\n\njulia> sizeof(StructWithPadding) # not the sum of `sizeof` of fields due to padding\n16\n\njulia> sizeof(Int64) + sizeof(Bool) # different from above\n9\n\nIf DataType T does not have a specific size, an error is thrown.\n\njulia> sizeof(AbstractArray)\nERROR: Abstract type AbstractArray does not have a definite size.\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.isconcretetype","page":"Essentials","title":"Base.isconcretetype","text":"isconcretetype(T)\n\nDetermine whether type T is a concrete type, meaning it could have direct instances (values x such that typeof(x) === T). Note that this is not the negation of isabstracttype(T). If T is not a type, then return false.\n\nSee also: isbits, isabstracttype, issingletontype.\n\nExamples\n\njulia> isconcretetype(Complex)\nfalse\n\njulia> isconcretetype(Complex{Float32})\ntrue\n\njulia> isconcretetype(Vector{Complex})\ntrue\n\njulia> isconcretetype(Vector{Complex{Float32}})\ntrue\n\njulia> isconcretetype(Union{})\nfalse\n\njulia> isconcretetype(Union{Int,String})\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isbits","page":"Essentials","title":"Base.isbits","text":"isbits(x)\n\nReturn true if x is an instance of an isbitstype type.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isbitstype","page":"Essentials","title":"Base.isbitstype","text":"isbitstype(T)\n\nReturn true if type T is a \"plain data\" type, meaning it is immutable and contains no references to other values, only primitive types and other isbitstype types. Typical examples are numeric types such as UInt8, Float64, and Complex{Float64}. This category of types is significant since they are valid as type parameters, may not track isdefined / isassigned status, and have a defined layout that is compatible with C. If T is not a type, then return false.\n\nSee also isbits, isprimitivetype, ismutable.\n\nExamples\n\njulia> isbitstype(Complex{Float64})\ntrue\n\njulia> isbitstype(Complex)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.fieldoffset","page":"Essentials","title":"Base.fieldoffset","text":"fieldoffset(type, i)\n\nThe byte offset of field i of a type relative to the data start. For example, we could use it in the following manner to summarize information about a struct:\n\njulia> structinfo(T) = [(fieldoffset(T,i), fieldname(T,i), fieldtype(T,i)) for i = 1:fieldcount(T)];\n\njulia> structinfo(Base.Filesystem.StatStruct)\n13-element Vector{Tuple{UInt64, Symbol, Type}}:\n (0x0000000000000000, :desc, Union{RawFD, String})\n (0x0000000000000008, :device, UInt64)\n (0x0000000000000010, :inode, UInt64)\n (0x0000000000000018, :mode, UInt64)\n (0x0000000000000020, :nlink, Int64)\n (0x0000000000000028, :uid, UInt64)\n (0x0000000000000030, :gid, UInt64)\n (0x0000000000000038, :rdev, UInt64)\n (0x0000000000000040, :size, Int64)\n (0x0000000000000048, :blksize, Int64)\n (0x0000000000000050, :blocks, Int64)\n (0x0000000000000058, :mtime, Float64)\n (0x0000000000000060, :ctime, Float64)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.datatype_alignment","page":"Essentials","title":"Base.datatype_alignment","text":"Base.datatype_alignment(dt::DataType) -> Int\n\nMemory allocation minimum alignment for instances of this type. Can be called on any isconcretetype, although for Memory it will give the alignment of the elements, not the whole object.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.datatype_haspadding","page":"Essentials","title":"Base.datatype_haspadding","text":"Base.datatype_haspadding(dt::DataType) -> Bool\n\nReturn whether the fields of instances of this type are packed in memory, with no intervening padding bits (defined as bits whose value does not uniquely impact the egal test when applied to the struct fields). Can be called on any isconcretetype.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.datatype_pointerfree","page":"Essentials","title":"Base.datatype_pointerfree","text":"Base.datatype_pointerfree(dt::DataType) -> Bool\n\nReturn whether instances of this type can contain references to gc-managed memory. Can be called on any isconcretetype.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Special-values","page":"Essentials","title":"Special values","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.typemin\nBase.typemax\nBase.floatmin\nBase.floatmax\nBase.maxintfloat\nBase.eps(::Type{<:AbstractFloat})\nBase.eps(::AbstractFloat)\nBase.instances","category":"page"},{"location":"base/base/#Base.typemin","page":"Essentials","title":"Base.typemin","text":"typemin(T)\n\nThe lowest value representable by the given (real) numeric DataType T.\n\nSee also: floatmin, typemax, eps.\n\nExamples\n\njulia> typemin(Int8)\n-128\n\njulia> typemin(UInt32)\n0x00000000\n\njulia> typemin(Float16)\n-Inf16\n\njulia> typemin(Float32)\n-Inf32\n\njulia> nextfloat(-Inf32) # smallest finite Float32 floating point number\n-3.4028235f38\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.typemax","page":"Essentials","title":"Base.typemax","text":"typemax(T)\n\nThe highest value representable by the given (real) numeric DataType.\n\nSee also: floatmax, typemin, eps.\n\nExamples\n\njulia> typemax(Int8)\n127\n\njulia> typemax(UInt32)\n0xffffffff\n\njulia> typemax(Float64)\nInf\n\njulia> typemax(Float32)\nInf32\n\njulia> floatmax(Float32) # largest finite Float32 floating point number\n3.4028235f38\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.floatmin","page":"Essentials","title":"Base.floatmin","text":"floatmin(T = Float64)\n\nReturn the smallest positive normal number representable by the floating-point type T.\n\nExamples\n\njulia> floatmin(Float16)\nFloat16(6.104e-5)\n\njulia> floatmin(Float32)\n1.1754944f-38\n\njulia> floatmin()\n2.2250738585072014e-308\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.floatmax","page":"Essentials","title":"Base.floatmax","text":"floatmax(T = Float64)\n\nReturn the largest finite number representable by the floating-point type T.\n\nSee also: typemax, floatmin, eps.\n\nExamples\n\njulia> floatmax(Float16)\nFloat16(6.55e4)\n\njulia> floatmax(Float32)\n3.4028235f38\n\njulia> floatmax()\n1.7976931348623157e308\n\njulia> typemax(Float64)\nInf\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.maxintfloat","page":"Essentials","title":"Base.maxintfloat","text":"maxintfloat(T=Float64)\n\nThe largest consecutive integer-valued floating-point number that is exactly represented in the given floating-point type T (which defaults to Float64).\n\nThat is, maxintfloat returns the smallest positive integer-valued floating-point number n such that n+1 is not exactly representable in the type T.\n\nWhen an Integer-type value is needed, use Integer(maxintfloat(T)).\n\n\n\n\n\nmaxintfloat(T, S)\n\nThe largest consecutive integer representable in the given floating-point type T that also does not exceed the maximum integer representable by the integer type S. Equivalently, it is the minimum of maxintfloat(T) and typemax(S).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.eps-Tuple{Type{<:AbstractFloat}}","page":"Essentials","title":"Base.eps","text":"eps(::Type{T}) where T<:AbstractFloat\neps()\n\nReturn the machine epsilon of the floating point type T (T = Float64 by default). This is defined as the gap between 1 and the next largest value representable by typeof(one(T)), and is equivalent to eps(one(T)). (Since eps(T) is a bound on the relative error of T, it is a \"dimensionless\" quantity like one.)\n\nExamples\n\njulia> eps()\n2.220446049250313e-16\n\njulia> eps(Float32)\n1.1920929f-7\n\njulia> 1.0 + eps()\n1.0000000000000002\n\njulia> 1.0 + eps()/2\n1.0\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.eps-Tuple{AbstractFloat}","page":"Essentials","title":"Base.eps","text":"eps(x::AbstractFloat)\n\nReturn the unit in last place (ulp) of x. This is the distance between consecutive representable floating point values at x. In most cases, if the distance on either side of x is different, then the larger of the two is taken, that is\n\neps(x) == max(x-prevfloat(x), nextfloat(x)-x)\n\nThe exceptions to this rule are the smallest and largest finite values (e.g. nextfloat(-Inf) and prevfloat(Inf) for Float64), which round to the smaller of the values.\n\nThe rationale for this behavior is that eps bounds the floating point rounding error. Under the default RoundNearest rounding mode, if y is a real number and x is the nearest floating point number to y, then\n\ny-x leq operatornameeps(x)2\n\nSee also: nextfloat, issubnormal, floatmax.\n\nExamples\n\njulia> eps(1.0)\n2.220446049250313e-16\n\njulia> eps(prevfloat(2.0))\n2.220446049250313e-16\n\njulia> eps(2.0)\n4.440892098500626e-16\n\njulia> x = prevfloat(Inf) # largest finite Float64\n1.7976931348623157e308\n\njulia> x + eps(x)/2 # rounds up\nInf\n\njulia> x + prevfloat(eps(x)/2) # rounds down\n1.7976931348623157e308\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.instances","page":"Essentials","title":"Base.instances","text":"instances(T::Type)\n\nReturn a collection of all instances of the given type, if applicable. Mostly used for enumerated types (see @enum).\n\nExamples\n\njulia> @enum Color red blue green\n\njulia> instances(Color)\n(red, blue, green)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Special-Types","page":"Essentials","title":"Special Types","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Core.Any\nCore.Union\nUnion{}\nCore.UnionAll\nCore.Tuple\nCore.NTuple\nCore.NamedTuple\nBase.@NamedTuple\nBase.@Kwargs\nBase.Val\nCore.Vararg\nCore.Nothing\nBase.isnothing\nBase.notnothing\nBase.Some\nBase.something\nBase.@something\nBase.Enums.Enum\nBase.Enums.@enum\nCore.Expr\nCore.Symbol\nCore.Symbol(x...)\nCore.Module","category":"page"},{"location":"base/base/#Core.Any","page":"Essentials","title":"Core.Any","text":"Any::DataType\n\nAny is the union of all types. It has the defining property isa(x, Any) == true for any x. Any therefore describes the entire universe of possible values. For example Integer is a subset of Any that includes Int, Int8, and other integer types.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Union","page":"Essentials","title":"Core.Union","text":"Union{Types...}\n\nA Union type is an abstract type which includes all instances of any of its argument types. This means that T <: Union{T,S} and S <: Union{T,S}.\n\nLike other abstract types, it cannot be instantiated, even if all of its arguments are non abstract.\n\nExamples\n\njulia> IntOrString = Union{Int,AbstractString}\nUnion{Int64, AbstractString}\n\njulia> 1 isa IntOrString # instance of Int is included in the union\ntrue\n\njulia> \"Hello!\" isa IntOrString # String is also included\ntrue\n\njulia> 1.0 isa IntOrString # Float64 is not included because it is neither Int nor AbstractString\nfalse\n\nExtended Help\n\nUnlike most other parametric types, unions are covariant in their parameters. For example, Union{Real, String} is a subtype of Union{Number, AbstractString}.\n\nThe empty union Union{} is the bottom type of Julia.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Union{}","page":"Essentials","title":"Union{}","text":"Union{}\n\nUnion{}, the empty Union of types, is the type that has no values. That is, it has the defining property isa(x, Union{}) == false for any x. Base.Bottom is defined as its alias and the type of Union{} is Core.TypeofBottom.\n\nExamples\n\njulia> isa(nothing, Union{})\nfalse\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Core.UnionAll","page":"Essentials","title":"Core.UnionAll","text":"UnionAll\n\nA union of types over all values of a type parameter. UnionAll is used to describe parametric types where the values of some parameters are not known. See the manual section on UnionAll Types.\n\nExamples\n\njulia> typeof(Vector)\nUnionAll\n\njulia> typeof(Vector{Int})\nDataType\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Tuple","page":"Essentials","title":"Core.Tuple","text":"Tuple{Types...}\n\nA tuple is a fixed-length container that can hold any values of different types, but cannot be modified (it is immutable). The values can be accessed via indexing. Tuple literals are written with commas and parentheses:\n\njulia> (1, 1+1)\n(1, 2)\n\njulia> (1,)\n(1,)\n\njulia> x = (0.0, \"hello\", 6*7)\n(0.0, \"hello\", 42)\n\njulia> x[2]\n\"hello\"\n\njulia> typeof(x)\nTuple{Float64, String, Int64}\n\nA length-1 tuple must be written with a comma, (1,), since (1) would just be a parenthesized value. () represents the empty (length-0) tuple.\n\nA tuple can be constructed from an iterator by using a Tuple type as constructor:\n\njulia> Tuple([\"a\", 1])\n(\"a\", 1)\n\njulia> Tuple{String, Float64}([\"a\", 1])\n(\"a\", 1.0)\n\nTuple types are covariant in their parameters: Tuple{Int} is a subtype of Tuple{Any}. Therefore Tuple{Any} is considered an abstract type, and tuple types are only concrete if their parameters are. Tuples do not have field names; fields are only accessed by index. Tuple types may have any number of parameters.\n\nSee the manual section on Tuple Types.\n\nSee also Vararg, NTuple, ntuple, tuple, NamedTuple.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.NTuple","page":"Essentials","title":"Core.NTuple","text":"NTuple{N, T}\n\nA compact way of representing the type for a tuple of length N where all elements are of type T.\n\nExamples\n\njulia> isa((1, 2, 3, 4, 5, 6), NTuple{6, Int})\ntrue\n\nSee also ntuple.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.NamedTuple","page":"Essentials","title":"Core.NamedTuple","text":"NamedTuple\n\nNamedTuples are, as their name suggests, named Tuples. That is, they're a tuple-like collection of values, where each entry has a unique name, represented as a Symbol. Like Tuples, NamedTuples are immutable; neither the names nor the values can be modified in place after construction.\n\nA named tuple can be created as a tuple literal with keys, e.g. (a=1, b=2), or as a tuple literal with semicolon after the opening parenthesis, e.g. (; a=1, b=2) (this form also accepts programmatically generated names as described below), or using a NamedTuple type as constructor, e.g. NamedTuple{(:a, :b)}((1,2)).\n\nAccessing the value associated with a name in a named tuple can be done using field access syntax, e.g. x.a, or using getindex, e.g. x[:a] or x[(:a, :b)]. A tuple of the names can be obtained using keys, and a tuple of the values can be obtained using values.\n\nnote: Note\nIteration over NamedTuples produces the values without the names. (See example below.) To iterate over the name-value pairs, use the pairs function.\n\nThe @NamedTuple macro can be used for conveniently declaring NamedTuple types.\n\nExamples\n\njulia> x = (a=1, b=2)\n(a = 1, b = 2)\n\njulia> x.a\n1\n\njulia> x[:a]\n1\n\njulia> x[(:a,)]\n(a = 1,)\n\njulia> keys(x)\n(:a, :b)\n\njulia> values(x)\n(1, 2)\n\njulia> collect(x)\n2-element Vector{Int64}:\n 1\n 2\n\njulia> collect(pairs(x))\n2-element Vector{Pair{Symbol, Int64}}:\n :a => 1\n :b => 2\n\nIn a similar fashion as to how one can define keyword arguments programmatically, a named tuple can be created by giving pairs name::Symbol => value after a semicolon inside a tuple literal. This and the name=value syntax can be mixed:\n\njulia> (; :a => 1, :b => 2, c=3)\n(a = 1, b = 2, c = 3)\n\nThe name-value pairs can also be provided by splatting a named tuple or any iterator that yields two-value collections holding each a symbol as first value:\n\njulia> keys = (:a, :b, :c); values = (1, 2, 3);\n\njulia> NamedTuple{keys}(values)\n(a = 1, b = 2, c = 3)\n\njulia> (; (keys .=> values)...)\n(a = 1, b = 2, c = 3)\n\njulia> nt1 = (a=1, b=2);\n\njulia> nt2 = (c=3, d=4);\n\njulia> (; nt1..., nt2..., b=20) # the final b overwrites the value from nt1\n(a = 1, b = 20, c = 3, d = 4)\n\njulia> (; zip(keys, values)...) # zip yields tuples such as (:a, 1)\n(a = 1, b = 2, c = 3)\n\nAs in keyword arguments, identifiers and dot expressions imply names:\n\njulia> x = 0\n0\n\njulia> t = (; x)\n(x = 0,)\n\njulia> (; t.x)\n(x = 0,)\n\ncompat: Julia 1.5\nImplicit names from identifiers and dot expressions are available as of Julia 1.5.\n\ncompat: Julia 1.7\nUse of getindex methods with multiple Symbols is available as of Julia 1.7.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.@NamedTuple","page":"Essentials","title":"Base.@NamedTuple","text":"@NamedTuple{key1::Type1, key2::Type2, ...}\n@NamedTuple begin key1::Type1; key2::Type2; ...; end\n\nThis macro gives a more convenient syntax for declaring NamedTuple types. It returns a NamedTuple type with the given keys and types, equivalent to NamedTuple{(:key1, :key2, ...), Tuple{Type1,Type2,...}}. If the ::Type declaration is omitted, it is taken to be Any. The begin ... end form allows the declarations to be split across multiple lines (similar to a struct declaration), but is otherwise equivalent. The NamedTuple macro is used when printing NamedTuple types to e.g. the REPL.\n\nFor example, the tuple (a=3.1, b=\"hello\") has a type NamedTuple{(:a, :b), Tuple{Float64, String}}, which can also be declared via @NamedTuple as:\n\njulia> @NamedTuple{a::Float64, b::String}\n@NamedTuple{a::Float64, b::String}\n\njulia> @NamedTuple begin\n a::Float64\n b::String\n end\n@NamedTuple{a::Float64, b::String}\n\ncompat: Julia 1.5\nThis macro is available as of Julia 1.5.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@Kwargs","page":"Essentials","title":"Base.@Kwargs","text":"@Kwargs{key1::Type1, key2::Type2, ...}\n\nThis macro gives a convenient way to construct the type representation of keyword arguments from the same syntax as @NamedTuple. For example, when we have a function call like func([positional arguments]; kw1=1.0, kw2=\"2\"), we can use this macro to construct the internal type representation of the keyword arguments as @Kwargs{kw1::Float64, kw2::String}. The macro syntax is specifically designed to simplify the signature type of a keyword method when it is printed in the stack trace view.\n\njulia> @Kwargs{init::Int} # the internal representation of keyword arguments\nBase.Pairs{Symbol, Int64, Tuple{Symbol}, @NamedTuple{init::Int64}}\n\njulia> sum(\"julia\"; init=1)\nERROR: MethodError: no method matching +(::Char, ::Char)\nThe function `+` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n +(::Any, ::Any, ::Any, ::Any...)\n @ Base operators.jl:585\n +(::Integer, ::AbstractChar)\n @ Base char.jl:247\n +(::T, ::Integer) where T<:AbstractChar\n @ Base char.jl:237\n\nStacktrace:\n [1] add_sum(x::Char, y::Char)\n @ Base ./reduce.jl:24\n [2] BottomRF\n @ Base ./reduce.jl:86 [inlined]\n [3] _foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, init::Int64, itr::String)\n @ Base ./reduce.jl:62\n [4] foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, nt::Int64, itr::String)\n @ Base ./reduce.jl:48 [inlined]\n [5] mapfoldl_impl(f::typeof(identity), op::typeof(Base.add_sum), nt::Int64, itr::String)\n @ Base ./reduce.jl:44 [inlined]\n [6] mapfoldl(f::typeof(identity), op::typeof(Base.add_sum), itr::String; init::Int64)\n @ Base ./reduce.jl:175 [inlined]\n [7] mapreduce(f::typeof(identity), op::typeof(Base.add_sum), itr::String; kw::@Kwargs{init::Int64})\n @ Base ./reduce.jl:307 [inlined]\n [8] sum(f::typeof(identity), a::String; kw::@Kwargs{init::Int64})\n @ Base ./reduce.jl:535 [inlined]\n [9] sum(a::String; kw::@Kwargs{init::Int64})\n @ Base ./reduce.jl:564 [inlined]\n [10] top-level scope\n @ REPL[12]:1\n\ncompat: Julia 1.10\nThis macro is available as of Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Val","page":"Essentials","title":"Base.Val","text":"Val(c)\n\nReturn Val{c}(), which contains no run-time data. Types like this can be used to pass the information between functions through the value c, which must be an isbits value or a Symbol. The intent of this construct is to be able to dispatch on constants directly (at compile time) without having to test the value of the constant at run time.\n\nExamples\n\njulia> f(::Val{true}) = \"Good\"\nf (generic function with 1 method)\n\njulia> f(::Val{false}) = \"Bad\"\nf (generic function with 2 methods)\n\njulia> f(Val(true))\n\"Good\"\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Vararg","page":"Essentials","title":"Core.Vararg","text":"Vararg{T,N}\n\nThe last parameter of a tuple type Tuple can be the special value Vararg, which denotes any number of trailing elements. Vararg{T,N} corresponds to exactly N elements of type T. Finally Vararg{T} corresponds to zero or more elements of type T. Vararg tuple types are used to represent the arguments accepted by varargs methods (see the section on Varargs Functions in the manual.)\n\nSee also NTuple.\n\nExamples\n\njulia> mytupletype = Tuple{AbstractString, Vararg{Int}}\nTuple{AbstractString, Vararg{Int64}}\n\njulia> isa((\"1\",), mytupletype)\ntrue\n\njulia> isa((\"1\",1), mytupletype)\ntrue\n\njulia> isa((\"1\",1,2), mytupletype)\ntrue\n\njulia> isa((\"1\",1,2,3.0), mytupletype)\nfalse\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Core.Nothing","page":"Essentials","title":"Core.Nothing","text":"Nothing\n\nA type with no fields that is the type of nothing.\n\nSee also: isnothing, Some, Missing.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.isnothing","page":"Essentials","title":"Base.isnothing","text":"isnothing(x)\n\nReturn true if x === nothing, and return false if not.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nSee also something, Base.notnothing, ismissing.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.notnothing","page":"Essentials","title":"Base.notnothing","text":"notnothing(x)\n\nThrow an error if x === nothing, and return x if not.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Some","page":"Essentials","title":"Base.Some","text":"Some{T}\n\nA wrapper type used in Union{Some{T}, Nothing} to distinguish between the absence of a value (nothing) and the presence of a nothing value (i.e. Some(nothing)).\n\nUse something to access the value wrapped by a Some object.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.something","page":"Essentials","title":"Base.something","text":"something(x...)\n\nReturn the first value in the arguments which is not equal to nothing, if any. Otherwise throw an error. Arguments of type Some are unwrapped.\n\nSee also coalesce, skipmissing, @something.\n\nExamples\n\njulia> something(nothing, 1)\n1\n\njulia> something(Some(1), nothing)\n1\n\njulia> something(Some(nothing), 2) === nothing\ntrue\n\njulia> something(missing, nothing)\nmissing\n\njulia> something(nothing, nothing)\nERROR: ArgumentError: No value arguments present\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@something","page":"Essentials","title":"Base.@something","text":"@something(x...)\n\nShort-circuiting version of something.\n\nExamples\n\njulia> f(x) = (println(\"f($x)\"); nothing);\n\njulia> a = 1;\n\njulia> a = @something a f(2) f(3) error(\"Unable to find default for `a`\")\n1\n\njulia> b = nothing;\n\njulia> b = @something b f(2) f(3) error(\"Unable to find default for `b`\")\nf(2)\nf(3)\nERROR: Unable to find default for `b`\n[...]\n\njulia> b = @something b f(2) f(3) Some(nothing)\nf(2)\nf(3)\n\njulia> b === nothing\ntrue\n\ncompat: Julia 1.7\nThis macro is available as of Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Enums.Enum","page":"Essentials","title":"Base.Enums.Enum","text":"Enum{T<:Integer}\n\nThe abstract supertype of all enumerated types defined with @enum.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.Enums.@enum","page":"Essentials","title":"Base.Enums.@enum","text":"@enum EnumName[::BaseType] value1[=x] value2[=y]\n\nCreate an Enum{BaseType} subtype with name EnumName and enum member values of value1 and value2 with optional assigned values of x and y, respectively. EnumName can be used just like other types and enum member values as regular values, such as\n\nExamples\n\njulia> @enum Fruit apple=1 orange=2 kiwi=3\n\njulia> f(x::Fruit) = \"I'm a Fruit with value: $(Int(x))\"\nf (generic function with 1 method)\n\njulia> f(apple)\n\"I'm a Fruit with value: 1\"\n\njulia> Fruit(1)\napple::Fruit = 1\n\nValues can also be specified inside a begin block, e.g.\n\n@enum EnumName begin\n value1\n value2\nend\n\nBaseType, which defaults to Int32, must be a primitive subtype of Integer. Member values can be converted between the enum type and BaseType. read and write perform these conversions automatically. In case the enum is created with a non-default BaseType, Integer(value1) will return the integer value1 with the type BaseType.\n\nTo list all the instances of an enum use instances, e.g.\n\njulia> instances(Fruit)\n(apple, orange, kiwi)\n\nIt is possible to construct a symbol from an enum instance:\n\njulia> Symbol(apple)\n:apple\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Core.Expr","page":"Essentials","title":"Core.Expr","text":"Expr(head::Symbol, args...)\n\nA type representing compound expressions in parsed julia code (ASTs). Each expression consists of a head Symbol identifying which kind of expression it is (e.g. a call, for loop, conditional statement, etc.), and subexpressions (e.g. the arguments of a call). The subexpressions are stored in a Vector{Any} field called args.\n\nSee the manual chapter on Metaprogramming and the developer documentation Julia ASTs.\n\nExamples\n\njulia> Expr(:call, :+, 1, 2)\n:(1 + 2)\n\njulia> dump(:(a ? b : c))\nExpr\n head: Symbol if\n args: Array{Any}((3,))\n 1: Symbol a\n 2: Symbol b\n 3: Symbol c\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Symbol","page":"Essentials","title":"Core.Symbol","text":"Symbol\n\nThe type of object used to represent identifiers in parsed julia code (ASTs). Also often used as a name or label to identify an entity (e.g. as a dictionary key). Symbols can be entered using the : quote operator:\n\njulia> :name\n:name\n\njulia> typeof(:name)\nSymbol\n\njulia> x = 42\n42\n\njulia> eval(:x)\n42\n\nSymbols can also be constructed from strings or other values by calling the constructor Symbol(x...).\n\nSymbols are immutable and their implementation re-uses the same object for all Symbols with the same name.\n\nUnlike strings, Symbols are \"atomic\" or \"scalar\" entities that do not support iteration over characters.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Symbol-Tuple","page":"Essentials","title":"Core.Symbol","text":"Symbol(x...) -> Symbol\n\nCreate a Symbol by concatenating the string representations of the arguments together.\n\nExamples\n\njulia> Symbol(\"my\", \"name\")\n:myname\n\njulia> Symbol(\"day\", 4)\n:day4\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Core.Module","page":"Essentials","title":"Core.Module","text":"Module\n\nA Module is a separate global variable workspace. See module and the manual section about modules for details.\n\nModule(name::Symbol=:anonymous, std_imports=true, default_names=true)\n\nReturn a module with the specified name. A baremodule corresponds to Module(:ModuleName, false)\n\nAn empty module containing no names at all can be created with Module(:ModuleName, false, false). This module will not import Base or Core and does not contain a reference to itself.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Generic-Functions","page":"Essentials","title":"Generic Functions","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Core.Function\nBase.hasmethod\nCore.applicable\nBase.isambiguous\nCore.invoke\nBase.@invoke\nBase.invokelatest\nBase.@invokelatest\nnew\nBase.:(|>)\nBase.:(∘)\nBase.ComposedFunction\nBase.splat\nBase.Fix1\nBase.Fix2","category":"page"},{"location":"base/base/#Core.Function","page":"Essentials","title":"Core.Function","text":"Function\n\nAbstract type of all functions.\n\nExamples\n\njulia> isa(+, Function)\ntrue\n\njulia> typeof(sin)\ntypeof(sin) (singleton type of function sin, subtype of Function)\n\njulia> ans <: Function\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.hasmethod","page":"Essentials","title":"Base.hasmethod","text":"hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool\n\nDetermine whether the given generic function has a method matching the given Tuple of argument types with the upper bound of world age given by world.\n\nIf a tuple of keyword argument names kwnames is provided, this also checks whether the method of f matching t has the given keyword argument names. If the matching method accepts a variable number of keyword arguments, e.g. with kwargs..., any names given in kwnames are considered valid. Otherwise the provided names must be a subset of the method's keyword arguments.\n\nSee also applicable.\n\ncompat: Julia 1.2\nProviding keyword argument names requires Julia 1.2 or later.\n\nExamples\n\njulia> hasmethod(length, Tuple{Array})\ntrue\n\njulia> f(; oranges=0) = oranges;\n\njulia> hasmethod(f, Tuple{}, (:oranges,))\ntrue\n\njulia> hasmethod(f, Tuple{}, (:apples, :bananas))\nfalse\n\njulia> g(; xs...) = 4;\n\njulia> hasmethod(g, Tuple{}, (:a, :b, :c, :d)) # g accepts arbitrary kwargs\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.applicable","page":"Essentials","title":"Core.applicable","text":"applicable(f, args...) -> Bool\n\nDetermine whether the given generic function has a method applicable to the given arguments.\n\nSee also hasmethod.\n\nExamples\n\njulia> function f(x, y)\n x + y\n end;\n\njulia> applicable(f, 1)\nfalse\n\njulia> applicable(f, 1, 2)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isambiguous","page":"Essentials","title":"Base.isambiguous","text":"Base.isambiguous(m1, m2; ambiguous_bottom=false) -> Bool\n\nDetermine whether two methods m1 and m2 may be ambiguous for some call signature. This test is performed in the context of other methods of the same function; in isolation, m1 and m2 might be ambiguous, but if a third method resolving the ambiguity has been defined, this returns false. Alternatively, in isolation m1 and m2 might be ordered, but if a third method cannot be sorted with them, they may cause an ambiguity together.\n\nFor parametric types, the ambiguous_bottom keyword argument controls whether Union{} counts as an ambiguous intersection of type parameters – when true, it is considered ambiguous, when false it is not.\n\nExamples\n\njulia> foo(x::Complex{<:Integer}) = 1\nfoo (generic function with 1 method)\n\njulia> foo(x::Complex{<:Rational}) = 2\nfoo (generic function with 2 methods)\n\njulia> m1, m2 = collect(methods(foo));\n\njulia> typeintersect(m1.sig, m2.sig)\nTuple{typeof(foo), Complex{Union{}}}\n\njulia> Base.isambiguous(m1, m2, ambiguous_bottom=true)\ntrue\n\njulia> Base.isambiguous(m1, m2, ambiguous_bottom=false)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.invoke","page":"Essentials","title":"Core.invoke","text":"invoke(f, argtypes::Type, args...; kwargs...)\n\nInvoke a method for the given generic function f matching the specified types argtypes on the specified arguments args and passing the keyword arguments kwargs. The arguments args must conform with the specified types in argtypes, i.e. conversion is not automatically performed. This method allows invoking a method other than the most specific matching method, which is useful when the behavior of a more general definition is explicitly needed (often as part of the implementation of a more specific method of the same function).\n\nBe careful when using invoke for functions that you don't write. What definition is used for given argtypes is an implementation detail unless the function is explicitly states that calling with certain argtypes is a part of public API. For example, the change between f1 and f2 in the example below is usually considered compatible because the change is invisible by the caller with a normal (non-invoke) call. However, the change is visible if you use invoke.\n\nExamples\n\njulia> f(x::Real) = x^2;\n\njulia> f(x::Integer) = 1 + invoke(f, Tuple{Real}, x);\n\njulia> f(2)\n5\n\njulia> f1(::Integer) = Integer\n f1(::Real) = Real;\n\njulia> f2(x::Real) = _f2(x)\n _f2(::Integer) = Integer\n _f2(_) = Real;\n\njulia> f1(1)\nInteger\n\njulia> f2(1)\nInteger\n\njulia> invoke(f1, Tuple{Real}, 1)\nReal\n\njulia> invoke(f2, Tuple{Real}, 1)\nInteger\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@invoke","page":"Essentials","title":"Base.@invoke","text":"@invoke f(arg::T, ...; kwargs...)\n\nProvides a convenient way to call invoke by expanding @invoke f(arg1::T1, arg2::T2; kwargs...) to invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...). When an argument's type annotation is omitted, it's replaced with Core.Typeof that argument. To invoke a method where an argument is untyped or explicitly typed as Any, annotate the argument with ::Any.\n\nIt also supports the following syntax:\n\n@invoke (x::X).f expands to invoke(getproperty, Tuple{X,Symbol}, x, :f)\n@invoke (x::X).f = v::V expands to invoke(setproperty!, Tuple{X,Symbol,V}, x, :f, v)\n@invoke (xs::Xs)[i::I] expands to invoke(getindex, Tuple{Xs,I}, xs, i)\n@invoke (xs::Xs)[i::I] = v::V expands to invoke(setindex!, Tuple{Xs,V,I}, xs, v, i)\n\nExamples\n\njulia> @macroexpand @invoke f(x::T, y)\n:(Core.invoke(f, Tuple{T, Core.Typeof(y)}, x, y))\n\njulia> @invoke 420::Integer % Unsigned\n0x00000000000001a4\n\njulia> @macroexpand @invoke (x::X).f\n:(Core.invoke(Base.getproperty, Tuple{X, Core.Typeof(:f)}, x, :f))\n\njulia> @macroexpand @invoke (x::X).f = v::V\n:(Core.invoke(Base.setproperty!, Tuple{X, Core.Typeof(:f), V}, x, :f, v))\n\njulia> @macroexpand @invoke (xs::Xs)[i::I]\n:(Core.invoke(Base.getindex, Tuple{Xs, I}, xs, i))\n\njulia> @macroexpand @invoke (xs::Xs)[i::I] = v::V\n:(Core.invoke(Base.setindex!, Tuple{Xs, V, I}, xs, v, i))\n\ncompat: Julia 1.7\nThis macro requires Julia 1.7 or later.\n\ncompat: Julia 1.9\nThis macro is exported as of Julia 1.9.\n\ncompat: Julia 1.10\nThe additional syntax is supported as of Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.invokelatest","page":"Essentials","title":"Base.invokelatest","text":"invokelatest(f, args...; kwargs...)\n\nCalls f(args...; kwargs...), but guarantees that the most recent method of f will be executed. This is useful in specialized circumstances, e.g. long-running event loops or callback functions that may call obsolete versions of a function f. (The drawback is that invokelatest is somewhat slower than calling f directly, and the type of the result cannot be inferred by the compiler.)\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this function was not exported, and was called as Base.invokelatest.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@invokelatest","page":"Essentials","title":"Base.@invokelatest","text":"@invokelatest f(args...; kwargs...)\n\nProvides a convenient way to call invokelatest. @invokelatest f(args...; kwargs...) will simply be expanded into Base.invokelatest(f, args...; kwargs...).\n\nIt also supports the following syntax:\n\n@invokelatest x.f expands to Base.invokelatest(getproperty, x, :f)\n@invokelatest x.f = v expands to Base.invokelatest(setproperty!, x, :f, v)\n@invokelatest xs[i] expands to Base.invokelatest(getindex, xs, i)\n@invokelatest xs[i] = v expands to Base.invokelatest(setindex!, xs, v, i)\n\njulia> @macroexpand @invokelatest f(x; kw=kwv)\n:(Base.invokelatest(f, x; kw = kwv))\n\njulia> @macroexpand @invokelatest x.f\n:(Base.invokelatest(Base.getproperty, x, :f))\n\njulia> @macroexpand @invokelatest x.f = v\n:(Base.invokelatest(Base.setproperty!, x, :f, v))\n\njulia> @macroexpand @invokelatest xs[i]\n:(Base.invokelatest(Base.getindex, xs, i))\n\njulia> @macroexpand @invokelatest xs[i] = v\n:(Base.invokelatest(Base.setindex!, xs, v, i))\n\ncompat: Julia 1.7\nThis macro requires Julia 1.7 or later.\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this macro was not exported, and was called as Base.@invokelatest.\n\ncompat: Julia 1.10\nThe additional x.f and xs[i] syntax requires Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#new","page":"Essentials","title":"new","text":"new, or new{A,B,...}\n\nSpecial function available to inner constructors which creates a new object of the type. The form new{A,B,...} explicitly specifies values of parameters for parametric types. See the manual section on Inner Constructor Methods for more information.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.:|>","page":"Essentials","title":"Base.:|>","text":"|>(x, f)\n\nInfix operator which applies function f to the argument x. This allows f(g(x)) to be written x |> g |> f. When used with anonymous functions, parentheses are typically required around the definition to get the intended chain.\n\nExamples\n\njulia> 4 |> inv\n0.25\n\njulia> [2, 3, 5] |> sum |> inv\n0.1\n\njulia> [0 1; 2 3] .|> (x -> x^2) |> sum\n14\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.:∘","page":"Essentials","title":"Base.:∘","text":"f ∘ g\n\nCompose functions: i.e. (f ∘ g)(args...; kwargs...) means f(g(args...; kwargs...)). The ∘ symbol can be entered in the Julia REPL (and most editors, appropriately configured) by typing \\circ.\n\nFunction composition also works in prefix form: ∘(f, g) is the same as f ∘ g. The prefix form supports composition of multiple functions: ∘(f, g, h) = f ∘ g ∘ h and splatting ∘(fs...) for composing an iterable collection of functions. The last argument to ∘ execute first.\n\ncompat: Julia 1.4\nMultiple function composition requires at least Julia 1.4.\n\ncompat: Julia 1.5\nComposition of one function ∘(f) requires at least Julia 1.5.\n\ncompat: Julia 1.7\nUsing keyword arguments requires at least Julia 1.7.\n\nExamples\n\njulia> map(uppercase∘first, [\"apple\", \"banana\", \"carrot\"])\n3-element Vector{Char}:\n 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)\n 'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)\n 'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)\n\njulia> (==(6)∘length).([\"apple\", \"banana\", \"carrot\"])\n3-element BitVector:\n 0\n 1\n 1\n\njulia> fs = [\n x -> 2x\n x -> x-1\n x -> x/2\n x -> x+1\n ];\n\njulia> ∘(fs...)(3)\n2.0\n\nSee also ComposedFunction, !f::Function.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ComposedFunction","page":"Essentials","title":"Base.ComposedFunction","text":"ComposedFunction{Outer,Inner} <: Function\n\nRepresents the composition of two callable objects outer::Outer and inner::Inner. That is\n\nComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))\n\nThe preferred way to construct an instance of ComposedFunction is to use the composition operator ∘:\n\njulia> sin ∘ cos === ComposedFunction(sin, cos)\ntrue\n\njulia> typeof(sin∘cos)\nComposedFunction{typeof(sin), typeof(cos)}\n\nThe composed pieces are stored in the fields of ComposedFunction and can be retrieved as follows:\n\njulia> composition = sin ∘ cos\nsin ∘ cos\n\njulia> composition.outer === sin\ntrue\n\njulia> composition.inner === cos\ntrue\n\ncompat: Julia 1.6\nComposedFunction requires at least Julia 1.6. In earlier versions ∘ returns an anonymous function instead.\n\nSee also ∘.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.splat","page":"Essentials","title":"Base.splat","text":"splat(f)\n\nEquivalent to\n\n my_splat(f) = args->f(args...)\n\ni.e. given a function returns a new function that takes one argument and splats it into the original function. This is useful as an adaptor to pass a multi-argument function in a context that expects a single argument, but passes a tuple as that single argument.\n\nExamples\n\njulia> map(splat(+), zip(1:3,4:6))\n3-element Vector{Int64}:\n 5\n 7\n 9\n\njulia> my_add = splat(+)\nsplat(+)\n\njulia> my_add((1,2,3))\n6\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Fix1","page":"Essentials","title":"Base.Fix1","text":"Fix1(f, x)\n\nA type representing a partially-applied version of the two-argument function f, with the first argument fixed to the value \"x\". In other words, Fix1(f, x) behaves similarly to y->f(x, y).\n\nSee also Fix2.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.Fix2","page":"Essentials","title":"Base.Fix2","text":"Fix2(f, x)\n\nA type representing a partially-applied version of the two-argument function f, with the second argument fixed to the value \"x\". In other words, Fix2(f, x) behaves similarly to y->f(y, x).\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Syntax","page":"Essentials","title":"Syntax","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Core.eval\nMain.eval\nBase.@eval\nBase.evalfile\nBase.esc\nBase.@inbounds\nBase.@boundscheck\nBase.@propagate_inbounds\nBase.@inline\nBase.@noinline\nBase.@nospecialize\nBase.@specialize\nBase.@nospecializeinfer\nBase.@constprop\nBase.gensym\nBase.@gensym\nvar\"name\"\nBase.@goto\nBase.@label\nBase.@simd\nBase.@polly\nBase.@generated\nBase.@assume_effects\nBase.@deprecate","category":"page"},{"location":"base/base/#Core.eval","page":"Essentials","title":"Core.eval","text":"Core.eval(m::Module, expr)\n\nEvaluate an expression in the given module and return the result.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#eval","page":"Essentials","title":"eval","text":"eval(expr)\n\nEvaluate an expression in the global scope of the containing module. Every Module (except those defined with baremodule) has its own 1-argument definition of eval, which evaluates expressions in that module.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@eval","page":"Essentials","title":"Base.@eval","text":"@eval [mod,] ex\n\nEvaluate an expression with values interpolated into it using eval. If two arguments are provided, the first is the module to evaluate in.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.evalfile","page":"Essentials","title":"Base.evalfile","text":"evalfile(path::AbstractString, args::Vector{String}=String[])\n\nLoad the file into an anonymous module using include, evaluate all expressions, and return the value of the last expression. The optional args argument can be used to set the input arguments of the script (i.e. the global ARGS variable). Note that definitions (e.g. methods, globals) are evaluated in the anonymous module and do not affect the current module.\n\nExamples\n\njulia> write(\"testfile.jl\", \"\"\"\n @show ARGS\n 1 + 1\n \"\"\");\n\njulia> x = evalfile(\"testfile.jl\", [\"ARG1\", \"ARG2\"]);\nARGS = [\"ARG1\", \"ARG2\"]\n\njulia> x\n2\n\njulia> rm(\"testfile.jl\")\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.esc","page":"Essentials","title":"Base.esc","text":"esc(e)\n\nOnly valid in the context of an Expr returned from a macro. Prevents the macro hygiene pass from turning embedded variables into gensym variables. See the Macros section of the Metaprogramming chapter of the manual for more details and examples.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@inbounds","page":"Essentials","title":"Base.@inbounds","text":"@inbounds(blk)\n\nEliminates array bounds checking within expressions.\n\nIn the example below the in-range check for referencing element i of array A is skipped to improve performance.\n\nfunction sum(A::AbstractArray)\n r = zero(eltype(A))\n for i in eachindex(A)\n @inbounds r += A[i]\n end\n return r\nend\n\nwarning: Warning\nUsing @inbounds may return incorrect results/crashes/corruption for out-of-bounds indices. The user is responsible for checking it manually. Only use @inbounds when it is certain from the information locally available that all accesses are in bounds. In particular, using 1:length(A) instead of eachindex(A) in a function like the one above is not safely inbounds because the first index of A may not be 1 for all user defined types that subtype AbstractArray.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@boundscheck","page":"Essentials","title":"Base.@boundscheck","text":"@boundscheck(blk)\n\nAnnotates the expression blk as a bounds checking block, allowing it to be elided by @inbounds.\n\nnote: Note\nThe function in which @boundscheck is written must be inlined into its caller in order for @inbounds to have effect.\n\nExamples\n\njulia> @inline function g(A, i)\n @boundscheck checkbounds(A, i)\n return \"accessing ($A)[$i]\"\n end;\n\njulia> f1() = return g(1:2, -1);\n\njulia> f2() = @inbounds return g(1:2, -1);\n\njulia> f1()\nERROR: BoundsError: attempt to access 2-element UnitRange{Int64} at index [-1]\nStacktrace:\n [1] throw_boundserror(::UnitRange{Int64}, ::Tuple{Int64}) at ./abstractarray.jl:455\n [2] checkbounds at ./abstractarray.jl:420 [inlined]\n [3] g at ./none:2 [inlined]\n [4] f1() at ./none:1\n [5] top-level scope\n\njulia> f2()\n\"accessing (1:2)[-1]\"\n\nwarning: Warning\nThe @boundscheck annotation allows you, as a library writer, to opt-in to allowing other code to remove your bounds checks with @inbounds. As noted there, the caller must verify—using information they can access—that their accesses are valid before using @inbounds. For indexing into your AbstractArray subclasses, for example, this involves checking the indices against its axes. Therefore, @boundscheck annotations should only be added to a getindex or setindex! implementation after you are certain its behavior is correct.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@propagate_inbounds","page":"Essentials","title":"Base.@propagate_inbounds","text":"@propagate_inbounds\n\nTells the compiler to inline a function while retaining the caller's inbounds context.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@inline","page":"Essentials","title":"Base.@inline","text":"@inline\n\nGive a hint to the compiler that this function is worth inlining.\n\nSmall functions typically do not need the @inline annotation, as the compiler does it automatically. By using @inline on bigger functions, an extra nudge can be given to the compiler to inline it.\n\n@inline can be applied immediately before a function definition or within a function body.\n\n# annotate long-form definition\n@inline function longdef(x)\n ...\nend\n\n# annotate short-form definition\n@inline shortdef(x) = ...\n\n# annotate anonymous function that a `do` block creates\nf() do\n @inline\n ...\nend\n\ncompat: Julia 1.8\nThe usage within a function body requires at least Julia 1.8.\n\n\n\n@inline block\n\nGive a hint to the compiler that calls within block are worth inlining.\n\n# The compiler will try to inline `f`\n@inline f(...)\n\n# The compiler will try to inline `f`, `g` and `+`\n@inline f(...) + g(...)\n\nnote: Note\nA callsite annotation always has the precedence over the annotation applied to the definition of the called function:@noinline function explicit_noinline(args...)\n # body\nend\n\nlet\n @inline explicit_noinline(args...) # will be inlined\nend\n\nnote: Note\nWhen there are nested callsite annotations, the innermost annotation has the precedence:@noinline let a0, b0 = ...\n a = @inline f(a0) # the compiler will try to inline this call\n b = f(b0) # the compiler will NOT try to inline this call\n return a, b\nend\n\nwarning: Warning\nAlthough a callsite annotation will try to force inlining in regardless of the cost model, there are still chances it can't succeed in it. Especially, recursive calls can not be inlined even if they are annotated as @inlined.\n\ncompat: Julia 1.8\nThe callsite annotation requires at least Julia 1.8.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@noinline","page":"Essentials","title":"Base.@noinline","text":"@noinline\n\nGive a hint to the compiler that it should not inline a function.\n\nSmall functions are typically inlined automatically. By using @noinline on small functions, auto-inlining can be prevented.\n\n@noinline can be applied immediately before a function definition or within a function body.\n\n# annotate long-form definition\n@noinline function longdef(x)\n ...\nend\n\n# annotate short-form definition\n@noinline shortdef(x) = ...\n\n# annotate anonymous function that a `do` block creates\nf() do\n @noinline\n ...\nend\n\ncompat: Julia 1.8\nThe usage within a function body requires at least Julia 1.8.\n\n\n\n@noinline block\n\nGive a hint to the compiler that it should not inline the calls within block.\n\n# The compiler will try to not inline `f`\n@noinline f(...)\n\n# The compiler will try to not inline `f`, `g` and `+`\n@noinline f(...) + g(...)\n\nnote: Note\nA callsite annotation always has the precedence over the annotation applied to the definition of the called function:@inline function explicit_inline(args...)\n # body\nend\n\nlet\n @noinline explicit_inline(args...) # will not be inlined\nend\n\nnote: Note\nWhen there are nested callsite annotations, the innermost annotation has the precedence:@inline let a0, b0 = ...\n a = @noinline f(a0) # the compiler will NOT try to inline this call\n b = f(b0) # the compiler will try to inline this call\n return a, b\nend\n\ncompat: Julia 1.8\nThe callsite annotation requires at least Julia 1.8.\n\n\n\nnote: Note\nIf the function is trivial (for example returning a constant) it might get inlined anyway.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@nospecialize","page":"Essentials","title":"Base.@nospecialize","text":"@nospecialize\n\nApplied to a function argument name, hints to the compiler that the method implementation should not be specialized for different types of that argument, but instead use the declared type for that argument. It can be applied to an argument within a formal argument list, or in the function body. When applied to an argument, the macro must wrap the entire argument expression, e.g., @nospecialize(x::Real) or @nospecialize(i::Integer...) rather than wrapping just the argument name. When used in a function body, the macro must occur in statement position and before any code.\n\nWhen used without arguments, it applies to all arguments of the parent scope. In local scope, this means all arguments of the containing function. In global (top-level) scope, this means all methods subsequently defined in the current module.\n\nSpecialization can reset back to the default by using @specialize.\n\nfunction example_function(@nospecialize x)\n ...\nend\n\nfunction example_function(x, @nospecialize(y = 1))\n ...\nend\n\nfunction example_function(x, y, z)\n @nospecialize x y\n ...\nend\n\n@nospecialize\nf(y) = [x for x in y]\n@specialize\n\nnote: Note\n@nospecialize affects code generation but not inference: it limits the diversity of the resulting native code, but it does not impose any limitations (beyond the standard ones) on type-inference. Use Base.@nospecializeinfer together with @nospecialize to additionally suppress inference.\n\nExamples\n\njulia> f(A::AbstractArray) = g(A)\nf (generic function with 1 method)\n\njulia> @noinline g(@nospecialize(A::AbstractArray)) = A[1]\ng (generic function with 1 method)\n\njulia> @code_typed f([1.0])\nCodeInfo(\n1 ─ %1 = invoke Main.g(_2::AbstractArray)::Float64\n└── return %1\n) => Float64\n\nHere, the @nospecialize annotation results in the equivalent of\n\nf(A::AbstractArray) = invoke(g, Tuple{AbstractArray}, A)\n\nensuring that only one version of native code will be generated for g, one that is generic for any AbstractArray. However, the specific return type is still inferred for both g and f, and this is still used in optimizing the callers of f and g.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@specialize","page":"Essentials","title":"Base.@specialize","text":"@specialize\n\nReset the specialization hint for an argument back to the default. For details, see @nospecialize.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@nospecializeinfer","page":"Essentials","title":"Base.@nospecializeinfer","text":"Base.@nospecializeinfer function f(args...)\n @nospecialize ...\n ...\nend\nBase.@nospecializeinfer f(@nospecialize args...) = ...\n\nTells the compiler to infer f using the declared types of @nospecialized arguments. This can be used to limit the number of compiler-generated specializations during inference.\n\nExamples\n\njulia> f(A::AbstractArray) = g(A)\nf (generic function with 1 method)\n\njulia> @noinline Base.@nospecializeinfer g(@nospecialize(A::AbstractArray)) = A[1]\ng (generic function with 1 method)\n\njulia> @code_typed f([1.0])\nCodeInfo(\n1 ─ %1 = invoke Main.g(_2::AbstractArray)::Any\n└── return %1\n) => Any\n\nIn this example, f will be inferred for each specific type of A, but g will only be inferred once with the declared argument type A::AbstractArray, meaning that the compiler will not likely see the excessive inference time on it while it can not infer the concrete return type of it. Without the @nospecializeinfer, f([1.0]) would infer the return type of g as Float64, indicating that inference ran for g(::Vector{Float64}) despite the prohibition on specialized code generation.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@constprop","page":"Essentials","title":"Base.@constprop","text":"Base.@constprop setting [ex]\n\nControl the mode of interprocedural constant propagation for the annotated function.\n\nTwo settings are supported:\n\nBase.@constprop :aggressive [ex]: apply constant propagation aggressively. For a method where the return type depends on the value of the arguments, this can yield improved inference results at the cost of additional compile time.\nBase.@constprop :none [ex]: disable constant propagation. This can reduce compile times for functions that Julia might otherwise deem worthy of constant-propagation. Common cases are for functions with Bool- or Symbol-valued arguments or keyword arguments.\n\nBase.@constprop can be applied immediately before a function definition or within a function body.\n\n# annotate long-form definition\nBase.@constprop :aggressive function longdef(x)\n ...\nend\n\n# annotate short-form definition\nBase.@constprop :aggressive shortdef(x) = ...\n\n# annotate anonymous function that a `do` block creates\nf() do\n Base.@constprop :aggressive\n ...\nend\n\ncompat: Julia 1.10\nThe usage within a function body requires at least Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.gensym","page":"Essentials","title":"Base.gensym","text":"gensym([tag])\n\nGenerates a symbol which will not conflict with other variable names (in the same module).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@gensym","page":"Essentials","title":"Base.@gensym","text":"@gensym\n\nGenerates a gensym symbol for a variable. For example, @gensym x y is transformed into x = gensym(\"x\"); y = gensym(\"y\").\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#var\"name\"","page":"Essentials","title":"var\"name\"","text":"var\n\nThe syntax var\"#example#\" refers to a variable named Symbol(\"#example#\"), even though #example# is not a valid Julia identifier name.\n\nThis can be useful for interoperability with programming languages which have different rules for the construction of valid identifiers. For example, to refer to the R variable draw.segments, you can use var\"draw.segments\" in your Julia code.\n\nIt is also used to show julia source code which has gone through macro hygiene or otherwise contains variable names which can't be parsed normally.\n\nNote that this syntax requires parser support so it is expanded directly by the parser rather than being implemented as a normal string macro @var_str.\n\ncompat: Julia 1.3\nThis syntax requires at least Julia 1.3.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.@goto","page":"Essentials","title":"Base.@goto","text":"@goto name\n\n@goto name unconditionally jumps to the statement at the location @label name.\n\n@label and @goto cannot create jumps to different top-level statements. Attempts cause an error. To still use @goto, enclose the @label and @goto in a block.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@label","page":"Essentials","title":"Base.@label","text":"@label name\n\nLabels a statement with the symbolic label name. The label marks the end-point of an unconditional jump with @goto name.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.SimdLoop.@simd","page":"Essentials","title":"Base.SimdLoop.@simd","text":"@simd\n\nAnnotate a for loop to allow the compiler to take extra liberties to allow loop re-ordering\n\nwarning: Warning\nThis feature is experimental and could change or disappear in future versions of Julia. Incorrect use of the @simd macro may cause unexpected results.\n\nThe object iterated over in a @simd for loop should be a one-dimensional range. By using @simd, you are asserting several properties of the loop:\n\nIt is safe to execute iterations in arbitrary or overlapping order, with special consideration for reduction variables.\nFloating-point operations on reduction variables can be reordered or contracted, possibly causing different results than without @simd.\n\nIn many cases, Julia is able to automatically vectorize inner for loops without the use of @simd. Using @simd gives the compiler a little extra leeway to make it possible in more situations. In either case, your inner loop should have the following properties to allow vectorization:\n\nThe loop must be an innermost loop\nThe loop body must be straight-line code. Therefore, @inbounds is currently needed for all array accesses. The compiler can sometimes turn short &&, ||, and ?: expressions into straight-line code if it is safe to evaluate all operands unconditionally. Consider using the ifelse function instead of ?: in the loop if it is safe to do so.\nAccesses must have a stride pattern and cannot be \"gathers\" (random-index reads) or \"scatters\" (random-index writes).\nThe stride should be unit stride.\n\nnote: Note\nThe @simd does not assert by default that the loop is completely free of loop-carried memory dependencies, which is an assumption that can easily be violated in generic code. If you are writing non-generic code, you can use @simd ivdep for ... end to also assert that:\n\nThere exists no loop-carried memory dependencies\nNo iteration ever waits on a previous iteration to make forward progress.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@polly","page":"Essentials","title":"Base.@polly","text":"@polly\n\nTells the compiler to apply the polyhedral optimizer Polly to a function.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@generated","page":"Essentials","title":"Base.@generated","text":"@generated f\n\n@generated is used to annotate a function which will be generated. In the body of the generated function, only types of arguments can be read (not the values). The function returns a quoted expression evaluated when the function is called. The @generated macro should not be used on functions mutating the global scope or depending on mutable elements.\n\nSee Metaprogramming for further details.\n\nExamples\n\njulia> @generated function bar(x)\n if x <: Integer\n return :(x ^ 2)\n else\n return :(x)\n end\n end\nbar (generic function with 1 method)\n\njulia> bar(4)\n16\n\njulia> bar(\"baz\")\n\"baz\"\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@assume_effects","page":"Essentials","title":"Base.@assume_effects","text":"Base.@assume_effects setting... [ex]\n\nOverride the compiler's effect modeling. This macro can be used in several contexts:\n\nImmediately before a method definition, to override the entire effect modeling of the applied method.\nWithin a function body without any arguments, to override the entire effect modeling of the enclosing method.\nApplied to a code block, to override the local effect modeling of the applied code block.\n\nExamples\n\njulia> Base.@assume_effects :terminates_locally function fact(x)\n # usage 1:\n # this :terminates_locally allows `fact` to be constant-folded\n res = 1\n 0 ≤ x < 20 || error(\"bad fact\")\n while x > 1\n res *= x\n x -= 1\n end\n return res\n end\nfact (generic function with 1 method)\n\njulia> code_typed() do\n fact(12)\n end |> only\nCodeInfo(\n1 ─ return 479001600\n) => Int64\n\njulia> code_typed() do\n map((2,3,4)) do x\n # usage 2:\n # this :terminates_locally allows this anonymous function to be constant-folded\n Base.@assume_effects :terminates_locally\n res = 1\n 0 ≤ x < 20 || error(\"bad fact\")\n while x > 1\n res *= x\n x -= 1\n end\n return res\n end\n end |> only\nCodeInfo(\n1 ─ return (2, 6, 24)\n) => Tuple{Int64, Int64, Int64}\n\njulia> code_typed() do\n map((2,3,4)) do x\n res = 1\n 0 ≤ x < 20 || error(\"bad fact\")\n # usage 3:\n # with this :terminates_locally annotation the compiler skips tainting\n # `:terminates` effect within this `while` block, allowing the parent\n # anonymous function to be constant-folded\n Base.@assume_effects :terminates_locally while x > 1\n res *= x\n x -= 1\n end\n return res\n end\n end |> only\nCodeInfo(\n1 ─ return (2, 6, 24)\n) => Tuple{Int64, Int64, Int64}\n\ncompat: Julia 1.8\nUsing Base.@assume_effects requires Julia version 1.8.\n\ncompat: Julia 1.10\nThe usage within a function body requires at least Julia 1.10.\n\ncompact: Julia 1.11\nThe code block annotation requires at least Julia 1.11.\n\nwarning: Warning\nImproper use of this macro causes undefined behavior (including crashes, incorrect answers, or other hard to track bugs). Use with care and only as a last resort if absolutely required. Even in such a case, you SHOULD take all possible steps to minimize the strength of the effect assertion (e.g., do not use :total if :nothrow would have been sufficient).\n\nIn general, each setting value makes an assertion about the behavior of the function, without requiring the compiler to prove that this behavior is indeed true. These assertions are made for all world ages. It is thus advisable to limit the use of generic functions that may later be extended to invalidate the assumption (which would cause undefined behavior).\n\nThe following settings are supported.\n\n:consistent\n:effect_free\n:nothrow\n:terminates_globally\n:terminates_locally\n:notaskstate\n:inaccessiblememonly\n:noub\n:noub_if_noinbounds\n:foldable\n:removable\n:total\n\nExtended help\n\n\n\n:consistent\n\nThe :consistent setting asserts that for egal (===) inputs:\n\nThe manner of termination (return value, exception, non-termination) will always be the same.\nIf the method returns, the results will always be egal.\n\nnote: Note\nThis in particular implies that the method must not return a freshly allocated mutable object. Multiple allocations of mutable objects (even with identical contents) are not egal.\n\nnote: Note\nThe :consistent-cy assertion is made world-age wise. More formally, write fᵢ for the evaluation of f in world-age i, then we require: i x y x y fᵢ(x) fᵢ(y)However, for two world ages i, j s.t. i j, we may have fᵢ(x) fⱼ(y).A further implication is that :consistent functions may not make their return value dependent on the state of the heap or any other global state that is not constant for a given world age.\n\nnote: Note\nThe :consistent-cy includes all legal rewrites performed by the optimizer. For example, floating-point fastmath operations are not considered :consistent, because the optimizer may rewrite them causing the output to not be :consistent, even for the same world age (e.g. because one ran in the interpreter, while the other was optimized).\n\nnote: Note\nIf :consistent functions terminate by throwing an exception, that exception itself is not required to meet the egality requirement specified above.\n\n\n\n:effect_free\n\nThe :effect_free setting asserts that the method is free of externally semantically visible side effects. The following is an incomplete list of externally semantically visible side effects:\n\nChanging the value of a global variable.\nMutating the heap (e.g. an array or mutable value), except as noted below\nChanging the method table (e.g. through calls to eval)\nFile/Network/etc. I/O\nTask switching\n\nHowever, the following are explicitly not semantically visible, even if they may be observable:\n\nMemory allocations (both mutable and immutable)\nElapsed time\nGarbage collection\nHeap mutations of objects whose lifetime does not exceed the method (i.e. were allocated in the method and do not escape).\nThe returned value (which is externally visible, but not a side effect)\n\nThe rule of thumb here is that an externally visible side effect is anything that would affect the execution of the remainder of the program if the function were not executed.\n\nnote: Note\nThe :effect_free assertion is made both for the method itself and any code that is executed by the method. Keep in mind that the assertion must be valid for all world ages and limit use of this assertion accordingly.\n\n\n\n:nothrow\n\nThe :nothrow settings asserts that this method does not throw an exception (i.e. will either always return a value or never return).\n\nnote: Note\nIt is permissible for :nothrow annotated methods to make use of exception handling internally as long as the exception is not rethrown out of the method itself.\n\nnote: Note\nIf the execution of a method may raise MethodErrors and similar exceptions, then the method is not considered as :nothrow. However, note that environment-dependent errors like StackOverflowError or InterruptException are not modeled by this effect and thus a method that may result in StackOverflowError does not necessarily need to be !:nothrow (although it should usually be !:terminates too).\n\n\n\n:terminates_globally\n\nThe :terminates_globally settings asserts that this method will eventually terminate (either normally or abnormally), i.e. does not loop indefinitely.\n\nnote: Note\nThis :terminates_globally assertion covers any other methods called by the annotated method.\n\nnote: Note\nThe compiler will consider this a strong indication that the method will terminate relatively quickly and may (if otherwise legal) call this method at compile time. I.e. it is a bad idea to annotate this setting on a method that technically, but not practically, terminates.\n\n\n\n:terminates_locally\n\nThe :terminates_locally setting is like :terminates_globally, except that it only applies to syntactic control flow within the annotated method. It is thus a much weaker (and thus safer) assertion that allows for the possibility of non-termination if the method calls some other method that does not terminate.\n\nnote: Note\n:terminates_globally implies :terminates_locally.\n\n\n\n:notaskstate\n\nThe :notaskstate setting asserts that the method does not use or modify the local task state (task local storage, RNG state, etc.) and may thus be safely moved between tasks without observable results.\n\nnote: Note\nThe implementation of exception handling makes use of state stored in the task object. However, this state is currently not considered to be within the scope of :notaskstate and is tracked separately using the :nothrow effect.\n\nnote: Note\nThe :notaskstate assertion concerns the state of the currently running task. If a reference to a Task object is obtained by some other means that does not consider which task is currently running, the :notaskstate effect need not be tainted. This is true, even if said task object happens to be === to the currently running task.\n\nnote: Note\nAccess to task state usually also results in the tainting of other effects, such as :effect_free (if task state is modified) or :consistent (if task state is used in the computation of the result). In particular, code that is not :notaskstate, but is :effect_free and :consistent may still be dead-code-eliminated and thus promoted to :total.\n\n\n\n:inaccessiblememonly\n\nThe :inaccessiblememonly setting asserts that the method does not access or modify externally accessible mutable memory. This means the method can access or modify mutable memory for newly allocated objects that is not accessible by other methods or top-level execution before return from the method, but it can not access or modify any mutable global state or mutable memory pointed to by its arguments.\n\nnote: Note\nBelow is an incomplete list of examples that invalidate this assumption:a global reference or getglobal call to access a mutable global variable\na global assignment or setglobal! call to perform assignment to a non-constant global variable\nsetfield! call that changes a field of a global mutable variable\n\nnote: Note\nThis :inaccessiblememonly assertion covers any other methods called by the annotated method.\n\n\n\n:noub\n\nThe :noub setting asserts that the method will not execute any undefined behavior (for any input). Note that undefined behavior may technically cause the method to violate any other effect assertions (such as :consistent or :effect_free) as well, but we do not model this, and they assume the absence of undefined behavior.\n\n\n\n:foldable\n\nThis setting is a convenient shortcut for the set of effects that the compiler requires to be guaranteed to constant fold a call at compile time. It is currently equivalent to the following settings:\n\n:consistent\n:effect_free\n:terminates_globally\n:noub\n\nnote: Note\nThis list in particular does not include :nothrow. The compiler will still attempt constant propagation and note any thrown error at compile time. Note however, that by the :consistent-cy requirements, any such annotated call must consistently throw given the same argument values.\n\nnote: Note\nAn explicit @inbounds annotation inside the function will also disable constant folding and not be overridden by :foldable.\n\n\n\n:removable\n\nThis setting is a convenient shortcut for the set of effects that the compiler requires to be guaranteed to delete a call whose result is unused at compile time. It is currently equivalent to the following settings:\n\n:effect_free\n:nothrow\n:terminates_globally\n\n\n\n:total\n\nThis setting is the maximum possible set of effects. It currently implies the following other settings:\n\n:consistent\n:effect_free\n:nothrow\n:terminates_globally\n:notaskstate\n:inaccessiblememonly\n:noub\n\nwarning: Warning\n:total is a very strong assertion and will likely gain additional semantics in future versions of Julia (e.g. if additional effects are added and included in the definition of :total). As a result, it should be used with care. Whenever possible, prefer to use the minimum possible set of specific effect assertions required for a particular application. In cases where a large number of effect overrides apply to a set of functions, a custom macro is recommended over the use of :total.\n\n\n\nNegated effects\n\nEffect names may be prefixed by ! to indicate that the effect should be removed from an earlier meta effect. For example, :total !:nothrow indicates that while the call is generally total, it may however throw.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@deprecate","page":"Essentials","title":"Base.@deprecate","text":"@deprecate old new [export_old=true]\n\nDeprecate method old and specify the replacement call new, defining a new method old with the specified signature in the process.\n\nTo prevent old from being exported, set export_old to false.\n\ncompat: Julia 1.5\nAs of Julia 1.5, functions defined by @deprecate do not print warning when julia is run without the --depwarn=yes flag set, as the default value of --depwarn option is no. The warnings are printed from tests run by Pkg.test().\n\nExamples\n\njulia> @deprecate old_export(x) new(x)\nold_export (generic function with 1 method)\n\njulia> @deprecate old_public(x) new(x) false\nold_public (generic function with 1 method)\n\nCalls to @deprecate without explicit type-annotations will define deprecated methods accepting any number of positional and keyword arguments of type Any.\n\ncompat: Julia 1.9\nKeyword arguments are forwarded when there is no explicit type annotation as of Julia 1.9. For older versions, you can manually forward positional and keyword arguments by doing @deprecate old(args...; kwargs...) new(args...; kwargs...).\n\nTo restrict deprecation to a specific signature, annotate the arguments of old. For example,\n\njulia> new(x::Int) = x;\n\njulia> new(x::Float64) = 2x;\n\njulia> @deprecate old(x::Int) new(x);\n\njulia> methods(old)\n# 1 method for generic function \"old\" from Main:\n [1] old(x::Int64)\n @ deprecated.jl:94\n\nwill define and deprecate a method old(x::Int) that mirrors new(x::Int) but will not define nor deprecate the method old(x::Float64).\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Missing-Values","page":"Essentials","title":"Missing Values","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.Missing\nBase.missing\nBase.coalesce\nBase.@coalesce\nBase.ismissing\nBase.skipmissing\nBase.nonmissingtype","category":"page"},{"location":"base/base/#Base.Missing","page":"Essentials","title":"Base.Missing","text":"Missing\n\nA type with no fields whose singleton instance missing is used to represent missing values.\n\nSee also: skipmissing, nonmissingtype, Nothing.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.missing","page":"Essentials","title":"Base.missing","text":"missing\n\nThe singleton instance of type Missing representing a missing value.\n\nSee also: NaN, skipmissing, nonmissingtype.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.coalesce","page":"Essentials","title":"Base.coalesce","text":"coalesce(x...)\n\nReturn the first value in the arguments which is not equal to missing, if any. Otherwise return missing.\n\nSee also skipmissing, something, @coalesce.\n\nExamples\n\njulia> coalesce(missing, 1)\n1\n\njulia> coalesce(1, missing)\n1\n\njulia> coalesce(nothing, 1) # returns `nothing`\n\njulia> coalesce(missing, missing)\nmissing\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@coalesce","page":"Essentials","title":"Base.@coalesce","text":"@coalesce(x...)\n\nShort-circuiting version of coalesce.\n\nExamples\n\njulia> f(x) = (println(\"f($x)\"); missing);\n\njulia> a = 1;\n\njulia> a = @coalesce a f(2) f(3) error(\"`a` is still missing\")\n1\n\njulia> b = missing;\n\njulia> b = @coalesce b f(2) f(3) error(\"`b` is still missing\")\nf(2)\nf(3)\nERROR: `b` is still missing\n[...]\n\ncompat: Julia 1.7\nThis macro is available as of Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.ismissing","page":"Essentials","title":"Base.ismissing","text":"ismissing(x)\n\nIndicate whether x is missing.\n\nSee also: skipmissing, isnothing, isnan.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.skipmissing","page":"Essentials","title":"Base.skipmissing","text":"skipmissing(itr)\n\nReturn an iterator over the elements in itr skipping missing values. The returned object can be indexed using indices of itr if the latter is indexable. Indices corresponding to missing values are not valid: they are skipped by keys and eachindex, and a MissingException is thrown when trying to use them.\n\nUse collect to obtain an Array containing the non-missing values in itr. Note that even if itr is a multidimensional array, the result will always be a Vector since it is not possible to remove missings while preserving dimensions of the input.\n\nSee also coalesce, ismissing, something.\n\nExamples\n\njulia> x = skipmissing([1, missing, 2])\nskipmissing(Union{Missing, Int64}[1, missing, 2])\n\njulia> sum(x)\n3\n\njulia> x[1]\n1\n\njulia> x[2]\nERROR: MissingException: the value at index (2,) is missing\n[...]\n\njulia> argmax(x)\n3\n\njulia> collect(keys(x))\n2-element Vector{Int64}:\n 1\n 3\n\njulia> collect(skipmissing([1, missing, 2]))\n2-element Vector{Int64}:\n 1\n 2\n\njulia> collect(skipmissing([1 missing; 2 missing]))\n2-element Vector{Int64}:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.nonmissingtype","page":"Essentials","title":"Base.nonmissingtype","text":"nonmissingtype(T::Type)\n\nIf T is a union of types containing Missing, return a new type with Missing removed.\n\nExamples\n\njulia> nonmissingtype(Union{Int64,Missing})\nInt64\n\njulia> nonmissingtype(Any)\nAny\n\ncompat: Julia 1.3\nThis function is exported as of Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#System","page":"Essentials","title":"System","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.run\nBase.devnull\nBase.success\nBase.process_running\nBase.process_exited\nBase.kill(::Base.Process, ::Integer)\nBase.Sys.set_process_title\nBase.Sys.get_process_title\nBase.ignorestatus\nBase.detach\nBase.Cmd\nBase.setenv\nBase.addenv\nBase.withenv\nBase.setcpuaffinity\nBase.pipeline(::Any, ::Any, ::Any, ::Any...)\nBase.pipeline(::Base.AbstractCmd)\nBase.Libc.gethostname\nBase.Libc.getpid\nBase.Libc.time()\nBase.time_ns\nBase.@time\nBase.@showtime\nBase.@timev\nBase.@timed\nBase.@elapsed\nBase.@allocated\nBase.@allocations\nBase.@lock_conflicts\nBase.EnvDict\nBase.ENV\nBase.Sys.STDLIB\nBase.Sys.isunix\nBase.Sys.isapple\nBase.Sys.islinux\nBase.Sys.isbsd\nBase.Sys.isfreebsd\nBase.Sys.isopenbsd\nBase.Sys.isnetbsd\nBase.Sys.isdragonfly\nBase.Sys.iswindows\nBase.Sys.windows_version\nBase.Sys.free_memory\nBase.Sys.total_memory\nBase.Sys.free_physical_memory\nBase.Sys.total_physical_memory\nBase.Sys.uptime\nBase.Sys.isjsvm\nBase.Sys.loadavg\nBase.Sys.isexecutable\nBase.Sys.isreadable\nBase.Sys.iswritable\nBase.Sys.username\nBase.@static","category":"page"},{"location":"base/base/#Base.run","page":"Essentials","title":"Base.run","text":"run(command, args...; wait::Bool = true)\n\nRun a command object, constructed with backticks (see the Running External Programs section in the manual). Throws an error if anything goes wrong, including the process exiting with a non-zero status (when wait is true).\n\nThe args... allow you to pass through file descriptors to the command, and are ordered like regular unix file descriptors (eg stdin, stdout, stderr, FD(3), FD(4)...).\n\nIf wait is false, the process runs asynchronously. You can later wait for it and check its exit status by calling success on the returned process object.\n\nWhen wait is false, the process' I/O streams are directed to devnull. When wait is true, I/O streams are shared with the parent process. Use pipeline to control I/O redirection.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.devnull","page":"Essentials","title":"Base.devnull","text":"devnull\n\nUsed in a stream redirect to discard all data written to it. Essentially equivalent to /dev/null on Unix or NUL on Windows. Usage:\n\nrun(pipeline(`cat test.txt`, devnull))\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.success","page":"Essentials","title":"Base.success","text":"success(command)\n\nRun a command object, constructed with backticks (see the Running External Programs section in the manual), and tell whether it was successful (exited with a code of 0). An exception is raised if the process cannot be started.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.process_running","page":"Essentials","title":"Base.process_running","text":"process_running(p::Process)\n\nDetermine whether a process is currently running.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.process_exited","page":"Essentials","title":"Base.process_exited","text":"process_exited(p::Process)\n\nDetermine whether a process has exited.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.kill-Tuple{Base.Process, Integer}","page":"Essentials","title":"Base.kill","text":"kill(p::Process, signum=Base.SIGTERM)\n\nSend a signal to a process. The default is to terminate the process. Returns successfully if the process has already exited, but throws an error if killing the process failed for other reasons (e.g. insufficient permissions).\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Sys.set_process_title","page":"Essentials","title":"Base.Sys.set_process_title","text":"Sys.set_process_title(title::AbstractString)\n\nSet the process title. No-op on some operating systems.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.get_process_title","page":"Essentials","title":"Base.Sys.get_process_title","text":"Sys.get_process_title()\n\nGet the process title. On some systems, will always return an empty string.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ignorestatus","page":"Essentials","title":"Base.ignorestatus","text":"ignorestatus(command)\n\nMark a command object so that running it will not throw an error if the result code is non-zero.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.detach","page":"Essentials","title":"Base.detach","text":"detach(command)\n\nMark a command object so that it will be run in a new process group, allowing it to outlive the julia process, and not have Ctrl-C interrupts passed to it.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Cmd","page":"Essentials","title":"Base.Cmd","text":"Cmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)\nCmd(exec::Vector{String})\n\nConstruct a new Cmd object, representing an external program and arguments, from cmd, while changing the settings of the optional keyword arguments:\n\nignorestatus::Bool: If true (defaults to false), then the Cmd will not throw an error if the return code is nonzero.\ndetach::Bool: If true (defaults to false), then the Cmd will be run in a new process group, allowing it to outlive the julia process and not have Ctrl-C passed to it.\nwindows_verbatim::Bool: If true (defaults to false), then on Windows the Cmd will send a command-line string to the process with no quoting or escaping of arguments, even arguments containing spaces. (On Windows, arguments are sent to a program as a single \"command-line\" string, and programs are responsible for parsing it into arguments. By default, empty arguments and arguments with spaces or tabs are quoted with double quotes \" in the command line, and \\ or \" are preceded by backslashes. windows_verbatim=true is useful for launching programs that parse their command line in nonstandard ways.) Has no effect on non-Windows systems.\nwindows_hide::Bool: If true (defaults to false), then on Windows no new console window is displayed when the Cmd is executed. This has no effect if a console is already open or on non-Windows systems.\nenv: Set environment variables to use when running the Cmd. env is either a dictionary mapping strings to strings, an array of strings of the form \"var=val\", an array or tuple of \"var\"=>val pairs. In order to modify (rather than replace) the existing environment, initialize env with copy(ENV) and then set env[\"var\"]=val as desired. To add to an environment block within a Cmd object without replacing all elements, use addenv() which will return a Cmd object with the updated environment.\ndir::AbstractString: Specify a working directory for the command (instead of the current directory).\n\nFor any keywords that are not specified, the current settings from cmd are used.\n\nNote that the Cmd(exec) constructor does not create a copy of exec. Any subsequent changes to exec will be reflected in the Cmd object.\n\nThe most common way to construct a Cmd object is with command literals (backticks), e.g.\n\n`ls -l`\n\nThis can then be passed to the Cmd constructor to modify its settings, e.g.\n\nCmd(`echo \"Hello world\"`, ignorestatus=true, detach=false)\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.setenv","page":"Essentials","title":"Base.setenv","text":"setenv(command::Cmd, env; dir)\n\nSet environment variables to use when running the given command. env is either a dictionary mapping strings to strings, an array of strings of the form \"var=val\", or zero or more \"var\"=>val pair arguments. In order to modify (rather than replace) the existing environment, create env through copy(ENV) and then setting env[\"var\"]=val as desired, or use addenv.\n\nThe dir keyword argument can be used to specify a working directory for the command. dir defaults to the currently set dir for command (which is the current working directory if not specified already).\n\nSee also Cmd, addenv, ENV, pwd.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.addenv","page":"Essentials","title":"Base.addenv","text":"addenv(command::Cmd, env...; inherit::Bool = true)\n\nMerge new environment mappings into the given Cmd object, returning a new Cmd object. Duplicate keys are replaced. If command does not contain any environment values set already, it inherits the current environment at time of addenv() call if inherit is true. Keys with value nothing are deleted from the env.\n\nSee also Cmd, setenv, ENV.\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.withenv","page":"Essentials","title":"Base.withenv","text":"withenv(f, kv::Pair...)\n\nExecute f in an environment that is temporarily modified (not replaced as in setenv) by zero or more \"var\"=>val arguments kv. withenv is generally used via the withenv(kv...) do ... end syntax. A value of nothing can be used to temporarily unset an environment variable (if it is set). When withenv returns, the original environment has been restored.\n\nwarning: Warning\nChanging the environment is not thread-safe. For running external commands with a different environment from the parent process, prefer using addenv over withenv.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.setcpuaffinity","page":"Essentials","title":"Base.setcpuaffinity","text":"setcpuaffinity(original_command::Cmd, cpus) -> command::Cmd\n\nSet the CPU affinity of the command by a list of CPU IDs (1-based) cpus. Passing cpus = nothing means to unset the CPU affinity if the original_command has any.\n\nThis function is supported only in Linux and Windows. It is not supported in macOS because libuv does not support affinity setting.\n\ncompat: Julia 1.8\nThis function requires at least Julia 1.8.\n\nExamples\n\nIn Linux, the taskset command line program can be used to see how setcpuaffinity works.\n\njulia> run(setcpuaffinity(`sh -c 'taskset -p $$'`, [1, 2, 5]));\npid 2273's current affinity mask: 13\n\nNote that the mask value 13 reflects that the first, second, and the fifth bits (counting from the least significant position) are turned on:\n\njulia> 0b010011\n0x13\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.pipeline-Tuple{Any, Any, Any, Vararg{Any}}","page":"Essentials","title":"Base.pipeline","text":"pipeline(from, to, ...)\n\nCreate a pipeline from a data source to a destination. The source and destination can be commands, I/O streams, strings, or results of other pipeline calls. At least one argument must be a command. Strings refer to filenames. When called with more than two arguments, they are chained together from left to right. For example, pipeline(a,b,c) is equivalent to pipeline(pipeline(a,b),c). This provides a more concise way to specify multi-stage pipelines.\n\nExamples:\n\nrun(pipeline(`ls`, `grep xyz`))\nrun(pipeline(`ls`, \"out.txt\"))\nrun(pipeline(\"out.txt\", `grep xyz`))\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.pipeline-Tuple{Base.AbstractCmd}","page":"Essentials","title":"Base.pipeline","text":"pipeline(command; stdin, stdout, stderr, append=false)\n\nRedirect I/O to or from the given command. Keyword arguments specify which of the command's streams should be redirected. append controls whether file output appends to the file. This is a more general version of the 2-argument pipeline function. pipeline(from, to) is equivalent to pipeline(from, stdout=to) when from is a command, and to pipeline(to, stdin=from) when from is another kind of data source.\n\nExamples:\n\nrun(pipeline(`dothings`, stdout=\"out.txt\", stderr=\"errs.txt\"))\nrun(pipeline(`update`, stdout=\"log.txt\", append=true))\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Libc.gethostname","page":"Essentials","title":"Base.Libc.gethostname","text":"gethostname() -> String\n\nGet the local machine's host name.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Libc.getpid","page":"Essentials","title":"Base.Libc.getpid","text":"getpid() -> Int32\n\nGet Julia's process ID.\n\n\n\n\n\ngetpid(process) -> Int32\n\nGet the child process ID, if it still exists.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Libc.time-Tuple{}","page":"Essentials","title":"Base.Libc.time","text":"time() -> Float64\n\nGet the system time in seconds since the epoch, with fairly high (typically, microsecond) resolution.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.time_ns","page":"Essentials","title":"Base.time_ns","text":"time_ns() -> UInt64\n\nGet the time in nanoseconds. The time corresponding to 0 is undefined, and wraps every 5.8 years.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@time","page":"Essentials","title":"Base.@time","text":"@time expr\n@time \"description\" expr\n\nA macro to execute an expression, printing the time it took to execute, the number of allocations, and the total number of bytes its execution caused to be allocated, before returning the value of the expression. Any time spent garbage collecting (gc), compiling new code, or recompiling invalidated code is shown as a percentage. Any lock conflicts where a ReentrantLock had to wait are shown as a count.\n\nOptionally provide a description string to print before the time report.\n\nIn some cases the system will look inside the @time expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @time @eval ....\n\nSee also @showtime, @timev, @timed, @elapsed, @allocated, and @allocations.\n\nnote: Note\nFor more serious benchmarking, consider the @btime macro from the BenchmarkTools.jl package which among other things evaluates the function multiple times in order to reduce noise.\n\ncompat: Julia 1.8\nThe option to add a description was introduced in Julia 1.8.Recompilation time being shown separately from compilation time was introduced in Julia 1.8\n\ncompat: Julia 1.11\nThe reporting of any lock conflicts was added in Julia 1.11.\n\njulia> x = rand(10,10);\n\njulia> @time x * x;\n 0.606588 seconds (2.19 M allocations: 116.555 MiB, 3.75% gc time, 99.94% compilation time)\n\njulia> @time x * x;\n 0.000009 seconds (1 allocation: 896 bytes)\n\njulia> @time begin\n sleep(0.3)\n 1+1\n end\n 0.301395 seconds (8 allocations: 336 bytes)\n2\n\njulia> @time \"A one second sleep\" sleep(1)\nA one second sleep: 1.005750 seconds (5 allocations: 144 bytes)\n\njulia> for loop in 1:3\n @time loop sleep(1)\n end\n1: 1.006760 seconds (5 allocations: 144 bytes)\n2: 1.001263 seconds (5 allocations: 144 bytes)\n3: 1.003676 seconds (5 allocations: 144 bytes)\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@showtime","page":"Essentials","title":"Base.@showtime","text":"@showtime expr\n\nLike @time but also prints the expression being evaluated for reference.\n\ncompat: Julia 1.8\nThis macro was added in Julia 1.8.\n\nSee also @time.\n\njulia> @showtime sleep(1)\nsleep(1): 1.002164 seconds (4 allocations: 128 bytes)\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@timev","page":"Essentials","title":"Base.@timev","text":"@timev expr\n@timev \"description\" expr\n\nThis is a verbose version of the @time macro. It first prints the same information as @time, then any non-zero memory allocation counters, and then returns the value of the expression.\n\nOptionally provide a description string to print before the time report.\n\ncompat: Julia 1.8\nThe option to add a description was introduced in Julia 1.8.\n\nSee also @time, @timed, @elapsed, @allocated, and @allocations.\n\njulia> x = rand(10,10);\n\njulia> @timev x * x;\n 0.546770 seconds (2.20 M allocations: 116.632 MiB, 4.23% gc time, 99.94% compilation time)\nelapsed time (ns): 546769547\ngc time (ns): 23115606\nbytes allocated: 122297811\npool allocs: 2197930\nnon-pool GC allocs:1327\nmalloc() calls: 36\nrealloc() calls: 5\nGC pauses: 3\n\njulia> @timev x * x;\n 0.000010 seconds (1 allocation: 896 bytes)\nelapsed time (ns): 9848\nbytes allocated: 896\npool allocs: 1\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@timed","page":"Essentials","title":"Base.@timed","text":"@timed\n\nA macro to execute an expression, and return the value of the expression, elapsed time in seconds, total bytes allocated, garbage collection time, an object with various memory allocation counters, compilation time in seconds, and recompilation time in seconds. Any lock conflicts where a ReentrantLock had to wait are shown as a count.\n\nIn some cases the system will look inside the @timed expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @timed @eval ....\n\nSee also @time, @timev, @elapsed, @allocated, @allocations, and @lock_conflicts.\n\njulia> stats = @timed rand(10^6);\n\njulia> stats.time\n0.006634834\n\njulia> stats.bytes\n8000256\n\njulia> stats.gctime\n0.0055765\n\njulia> propertynames(stats.gcstats)\n(:allocd, :malloc, :realloc, :poolalloc, :bigalloc, :freecall, :total_time, :pause, :full_sweep)\n\njulia> stats.gcstats.total_time\n5576500\n\njulia> stats.compile_time\n0.0\n\njulia> stats.recompile_time\n0.0\n\n\ncompat: Julia 1.5\nThe return type of this macro was changed from Tuple to NamedTuple in Julia 1.5.\n\ncompat: Julia 1.11\nThe lock_conflicts, compile_time, and recompile_time fields were added in Julia 1.11.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@elapsed","page":"Essentials","title":"Base.@elapsed","text":"@elapsed\n\nA macro to evaluate an expression, discarding the resulting value, instead returning the number of seconds it took to execute as a floating-point number.\n\nIn some cases the system will look inside the @elapsed expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @elapsed @eval ....\n\nSee also @time, @timev, @timed, @allocated, and @allocations.\n\njulia> @elapsed sleep(0.3)\n0.301391426\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@allocated","page":"Essentials","title":"Base.@allocated","text":"@allocated\n\nA macro to evaluate an expression, discarding the resulting value, instead returning the total number of bytes allocated during evaluation of the expression.\n\nSee also @allocations, @time, @timev, @timed, and @elapsed.\n\njulia> @allocated rand(10^6)\n8000080\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@allocations","page":"Essentials","title":"Base.@allocations","text":"@allocations\n\nA macro to evaluate an expression, discard the resulting value, and instead return the total number of allocations during evaluation of the expression.\n\nSee also @allocated, @time, @timev, @timed, and @elapsed.\n\njulia> @allocations rand(10^6)\n2\n\ncompat: Julia 1.9\nThis macro was added in Julia 1.9.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@lock_conflicts","page":"Essentials","title":"Base.@lock_conflicts","text":"@lock_conflicts\n\nA macro to evaluate an expression, discard the resulting value, and instead return the total number of lock conflicts during evaluation, where a lock attempt on a ReentrantLock resulted in a wait because the lock was already held.\n\nSee also @time, @timev and @timed.\n\njulia> @lock_conflicts begin\n l = ReentrantLock()\n Threads.@threads for i in 1:Threads.nthreads()\n lock(l) do\n sleep(1)\n end\n end\nend\n5\n\ncompat: Julia 1.11\nThis macro was added in Julia 1.11.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.EnvDict","page":"Essentials","title":"Base.EnvDict","text":"EnvDict() -> EnvDict\n\nA singleton of this type provides a hash table interface to environment variables.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.ENV","page":"Essentials","title":"Base.ENV","text":"ENV\n\nReference to the singleton EnvDict, providing a dictionary interface to system environment variables.\n\n(On Windows, system environment variables are case-insensitive, and ENV correspondingly converts all keys to uppercase for display, iteration, and copying. Portable code should not rely on the ability to distinguish variables by case, and should beware that setting an ostensibly lowercase variable may result in an uppercase ENV key.)\n\nwarning: Warning\nMutating the environment is not thread-safe.\n\nExamples\n\njulia> ENV\nBase.EnvDict with \"50\" entries:\n \"SECURITYSESSIONID\" => \"123\"\n \"USER\" => \"username\"\n \"MallocNanoZone\" => \"0\"\n ⋮ => ⋮\n\njulia> ENV[\"JULIA_EDITOR\"] = \"vim\"\n\"vim\"\n\njulia> ENV[\"JULIA_EDITOR\"]\n\"vim\"\n\nSee also: withenv, addenv.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.Sys.STDLIB","page":"Essentials","title":"Base.Sys.STDLIB","text":"Sys.STDLIB::String\n\nA string containing the full path to the directory containing the stdlib packages.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.Sys.isunix","page":"Essentials","title":"Base.Sys.isunix","text":"Sys.isunix([os])\n\nPredicate for testing if the OS provides a Unix-like interface. See documentation in Handling Operating System Variation.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isapple","page":"Essentials","title":"Base.Sys.isapple","text":"Sys.isapple([os])\n\nPredicate for testing if the OS is a derivative of Apple Macintosh OS X or Darwin. See documentation in Handling Operating System Variation.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.islinux","page":"Essentials","title":"Base.Sys.islinux","text":"Sys.islinux([os])\n\nPredicate for testing if the OS is a derivative of Linux. See documentation in Handling Operating System Variation.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isbsd","page":"Essentials","title":"Base.Sys.isbsd","text":"Sys.isbsd([os])\n\nPredicate for testing if the OS is a derivative of BSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nThe Darwin kernel descends from BSD, which means that Sys.isbsd() is true on macOS systems. To exclude macOS from a predicate, use Sys.isbsd() && !Sys.isapple().\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isfreebsd","page":"Essentials","title":"Base.Sys.isfreebsd","text":"Sys.isfreebsd([os])\n\nPredicate for testing if the OS is a derivative of FreeBSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nNot to be confused with Sys.isbsd(), which is true on FreeBSD but also on other BSD-based systems. Sys.isfreebsd() refers only to FreeBSD.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isopenbsd","page":"Essentials","title":"Base.Sys.isopenbsd","text":"Sys.isopenbsd([os])\n\nPredicate for testing if the OS is a derivative of OpenBSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nNot to be confused with Sys.isbsd(), which is true on OpenBSD but also on other BSD-based systems. Sys.isopenbsd() refers only to OpenBSD.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isnetbsd","page":"Essentials","title":"Base.Sys.isnetbsd","text":"Sys.isnetbsd([os])\n\nPredicate for testing if the OS is a derivative of NetBSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nNot to be confused with Sys.isbsd(), which is true on NetBSD but also on other BSD-based systems. Sys.isnetbsd() refers only to NetBSD.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isdragonfly","page":"Essentials","title":"Base.Sys.isdragonfly","text":"Sys.isdragonfly([os])\n\nPredicate for testing if the OS is a derivative of DragonFly BSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nNot to be confused with Sys.isbsd(), which is true on DragonFly but also on other BSD-based systems. Sys.isdragonfly() refers only to DragonFly.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.iswindows","page":"Essentials","title":"Base.Sys.iswindows","text":"Sys.iswindows([os])\n\nPredicate for testing if the OS is a derivative of Microsoft Windows NT. See documentation in Handling Operating System Variation.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.windows_version","page":"Essentials","title":"Base.Sys.windows_version","text":"Sys.windows_version()\n\nReturn the version number for the Windows NT Kernel as a VersionNumber, i.e. v\"major.minor.build\", or v\"0.0.0\" if this is not running on Windows.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.free_memory","page":"Essentials","title":"Base.Sys.free_memory","text":"Sys.free_memory()\n\nGet the total free memory in RAM in bytes.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.total_memory","page":"Essentials","title":"Base.Sys.total_memory","text":"Sys.total_memory()\n\nGet the total memory in RAM (including that which is currently used) in bytes. This amount may be constrained, e.g., by Linux control groups. For the unconstrained amount, see Sys.total_physical_memory().\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.free_physical_memory","page":"Essentials","title":"Base.Sys.free_physical_memory","text":"Sys.free_physical_memory()\n\nGet the free memory of the system in bytes. The entire amount may not be available to the current process; use Sys.free_memory() for the actually available amount.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.total_physical_memory","page":"Essentials","title":"Base.Sys.total_physical_memory","text":"Sys.total_physical_memory()\n\nGet the total memory in RAM (including that which is currently used) in bytes. The entire amount may not be available to the current process; see Sys.total_memory().\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.uptime","page":"Essentials","title":"Base.Sys.uptime","text":"Sys.uptime()\n\nGets the current system uptime in seconds.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isjsvm","page":"Essentials","title":"Base.Sys.isjsvm","text":"Sys.isjsvm([os])\n\nPredicate for testing if Julia is running in a JavaScript VM (JSVM), including e.g. a WebAssembly JavaScript embedding in a web browser.\n\ncompat: Julia 1.2\nThis function requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.loadavg","page":"Essentials","title":"Base.Sys.loadavg","text":"Sys.loadavg()\n\nGet the load average. See: https://en.wikipedia.org/wiki/Load_(computing).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isexecutable","page":"Essentials","title":"Base.Sys.isexecutable","text":"isexecutable(path::String)\n\nReturn true if the given path has executable permissions.\n\nnote: Note\nThis permission may change before the user executes path, so it is recommended to execute the file and handle the error if that fails, rather than calling isexecutable first.\n\nnote: Note\nPrior to Julia 1.6, this did not correctly interrogate filesystem ACLs on Windows, therefore it would return true for any file. From Julia 1.6 on, it correctly determines whether the file is marked as executable or not.\n\nSee also ispath, isreadable, iswritable.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isreadable","page":"Essentials","title":"Base.Sys.isreadable","text":"isreadable(path::String)\n\nReturn true if the access permissions for the given path permitted reading by the current user.\n\nnote: Note\nThis permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling isreadable first.\n\nnote: Note\nCurrently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also ispath, isexecutable, iswritable.\n\n\n\n\n\nisreadable(io) -> Bool\n\nReturn false if the specified IO object is not readable.\n\nExamples\n\njulia> open(\"myfile.txt\", \"w\") do io\n print(io, \"Hello world!\");\n isreadable(io)\n end\nfalse\n\njulia> open(\"myfile.txt\", \"r\") do io\n isreadable(io)\n end\ntrue\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.iswritable","page":"Essentials","title":"Base.Sys.iswritable","text":"iswritable(path::String)\n\nReturn true if the access permissions for the given path permitted writing by the current user.\n\nnote: Note\nThis permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling iswritable first.\n\nnote: Note\nCurrently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also ispath, isexecutable, isreadable.\n\n\n\n\n\niswritable(io) -> Bool\n\nReturn false if the specified IO object is not writable.\n\nExamples\n\njulia> open(\"myfile.txt\", \"w\") do io\n print(io, \"Hello world!\");\n iswritable(io)\n end\ntrue\n\njulia> open(\"myfile.txt\", \"r\") do io\n iswritable(io)\n end\nfalse\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.username","page":"Essentials","title":"Base.Sys.username","text":"Sys.username() -> String\n\nReturn the username for the current user. If the username cannot be determined or is empty, this function throws an error.\n\nTo retrieve a username that is overridable via an environment variable, e.g., USER, consider using\n\nuser = get(Sys.username, ENV, \"USER\")\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also homedir.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@static","page":"Essentials","title":"Base.@static","text":"@static\n\nPartially evaluate an expression at parse time.\n\nFor example, @static Sys.iswindows() ? foo : bar will evaluate Sys.iswindows() and insert either foo or bar into the expression. This is useful in cases where a construct would be invalid on other platforms, such as a ccall to a non-existent function. @static if Sys.isapple() foo end and @static foo <&&,||> bar are also valid syntax.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Versioning","page":"Essentials","title":"Versioning","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.VersionNumber\nBase.@v_str","category":"page"},{"location":"base/base/#Base.VersionNumber","page":"Essentials","title":"Base.VersionNumber","text":"VersionNumber\n\nVersion number type which follows the specifications of semantic versioning (semver), composed of major, minor and patch numeric values, followed by pre-release and build alphanumeric annotations.\n\nVersionNumber objects can be compared with all of the standard comparison operators (==, <, <=, etc.), with the result following semver v2.0.0-rc.2 rules.\n\nVersionNumber has the following public fields:\n\nv.major::Integer\nv.minor::Integer\nv.patch::Integer\nv.prerelease::Tuple{Vararg{Union{Integer, AbstractString}}}\nv.build::Tuple{Vararg{Union{Integer, AbstractString}}}\n\nSee also @v_str to efficiently construct VersionNumber objects from semver-format literal strings, VERSION for the VersionNumber of Julia itself, and Version Number Literals in the manual.\n\nExamples\n\njulia> a = VersionNumber(1, 2, 3)\nv\"1.2.3\"\n\njulia> a >= v\"1.2\"\ntrue\n\njulia> b = VersionNumber(\"2.0.1-rc1\")\nv\"2.0.1-rc1\"\n\njulia> b >= v\"2.0.1\"\nfalse\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.@v_str","page":"Essentials","title":"Base.@v_str","text":"@v_str\n\nString macro used to parse a string to a VersionNumber.\n\nExamples\n\njulia> v\"1.2.3\"\nv\"1.2.3\"\n\njulia> v\"2.0.1-rc1\"\nv\"2.0.1-rc1\"\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Errors","page":"Essentials","title":"Errors","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.error\nCore.throw\nBase.rethrow\nBase.backtrace\nBase.catch_backtrace\nBase.current_exceptions\nBase.@assert\nBase.Experimental.register_error_hint\nBase.Experimental.show_error_hints\nBase.ArgumentError\nBase.AssertionError\nCore.BoundsError\nBase.CompositeException\nBase.DimensionMismatch\nCore.DivideError\nCore.DomainError\nBase.EOFError\nCore.ErrorException\nCore.InexactError\nCore.InterruptException\nBase.KeyError\nBase.LoadError\nBase.MethodError\nBase.MissingException\nCore.OutOfMemoryError\nCore.ReadOnlyMemoryError\nCore.OverflowError\nBase.ProcessFailedException\nBase.TaskFailedException\nCore.StackOverflowError\nBase.SystemError\nCore.TypeError\nCore.UndefKeywordError\nCore.UndefRefError\nCore.UndefVarError\nBase.StringIndexError\nBase.InitError\nBase.retry\nBase.ExponentialBackOff","category":"page"},{"location":"base/base/#Base.error","page":"Essentials","title":"Base.error","text":"error(message::AbstractString)\n\nRaise an ErrorException with the given message.\n\n\n\n\n\nerror(msg...)\n\nRaise an ErrorException with a message constructed by string(msg...).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.throw","page":"Essentials","title":"Core.throw","text":"throw(e)\n\nThrow an object as an exception.\n\nSee also: rethrow, error.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.rethrow","page":"Essentials","title":"Base.rethrow","text":"rethrow()\n\nRethrow the current exception from within a catch block. The rethrown exception will continue propagation as if it had not been caught.\n\nnote: Note\nThe alternative form rethrow(e) allows you to associate an alternative exception object e with the current backtrace. However this misrepresents the program state at the time of the error so you're encouraged to instead throw a new exception using throw(e). In Julia 1.1 and above, using throw(e) will preserve the root cause exception on the stack, as described in current_exceptions.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.backtrace","page":"Essentials","title":"Base.backtrace","text":"backtrace()\n\nGet a backtrace object for the current program point.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.catch_backtrace","page":"Essentials","title":"Base.catch_backtrace","text":"catch_backtrace()\n\nGet the backtrace of the current exception, for use within catch blocks.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.current_exceptions","page":"Essentials","title":"Base.current_exceptions","text":"current_exceptions(task::Task=current_task(); [backtrace::Bool=true])\n\nGet the stack of exceptions currently being handled. For nested catch blocks there may be more than one current exception in which case the most recently thrown exception is last in the stack. The stack is returned as an ExceptionStack which is an AbstractVector of named tuples (exception,backtrace). If backtrace is false, the backtrace in each pair will be set to nothing.\n\nExplicitly passing task will return the current exception stack on an arbitrary task. This is useful for inspecting tasks which have failed due to uncaught exceptions.\n\ncompat: Julia 1.7\nThis function went by the experimental name catch_stack() in Julia 1.1–1.6, and had a plain Vector-of-tuples as a return type.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@assert","page":"Essentials","title":"Base.@assert","text":"@assert cond [text]\n\nThrow an AssertionError if cond is false. This is the preferred syntax for writing assertions, which are conditions that are assumed to be true, but that the user might decide to check anyways, as an aid to debugging if they fail. The optional message text is displayed upon assertion failure.\n\nwarning: Warning\nAn assert might be disabled at some optimization levels. Assert should therefore only be used as a debugging tool and not used for authentication verification (e.g., verifying passwords or checking array bounds). The code must not rely on the side effects of running cond for the correct behavior of a function.\n\nExamples\n\njulia> @assert iseven(3) \"3 is an odd number!\"\nERROR: AssertionError: 3 is an odd number!\n\njulia> @assert isodd(3) \"What even are numbers?\"\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Experimental.register_error_hint","page":"Essentials","title":"Base.Experimental.register_error_hint","text":"Experimental.register_error_hint(handler, exceptiontype)\n\nRegister a \"hinting\" function handler(io, exception) that can suggest potential ways for users to circumvent errors. handler should examine exception to see whether the conditions appropriate for a hint are met, and if so generate output to io. Packages should call register_error_hint from within their __init__ function.\n\nFor specific exception types, handler is required to accept additional arguments:\n\nMethodError: provide handler(io, exc::MethodError, argtypes, kwargs), which splits the combined arguments into positional and keyword arguments.\n\nWhen issuing a hint, the output should typically start with \\n.\n\nIf you define custom exception types, your showerror method can support hints by calling Experimental.show_error_hints.\n\nExamples\n\njulia> module Hinter\n\n only_int(x::Int) = 1\n any_number(x::Number) = 2\n\n function __init__()\n Base.Experimental.register_error_hint(MethodError) do io, exc, argtypes, kwargs\n if exc.f == only_int\n # Color is not necessary, this is just to show it's possible.\n print(io, \"\\nDid you mean to call \")\n printstyled(io, \"`any_number`?\", color=:cyan)\n end\n end\n end\n\n end\n\nThen if you call Hinter.only_int on something that isn't an Int (thereby triggering a MethodError), it issues the hint:\n\njulia> Hinter.only_int(1.0)\nERROR: MethodError: no method matching only_int(::Float64)\nThe function `only_int` exists, but no method is defined for this combination of argument types.\nDid you mean to call `any_number`?\nClosest candidates are:\n ...\n\ncompat: Julia 1.5\nCustom error hints are available as of Julia 1.5.\n\nwarning: Warning\nThis interface is experimental and subject to change or removal without notice. To insulate yourself against changes, consider putting any registrations inside an if isdefined(Base.Experimental, :register_error_hint) ... end block.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Experimental.show_error_hints","page":"Essentials","title":"Base.Experimental.show_error_hints","text":"Experimental.show_error_hints(io, ex, args...)\n\nInvoke all handlers from Experimental.register_error_hint for the particular exception type typeof(ex). args must contain any other arguments expected by the handler for that type.\n\ncompat: Julia 1.5\nCustom error hints are available as of Julia 1.5.\n\nwarning: Warning\nThis interface is experimental and subject to change or removal without notice.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.ArgumentError","page":"Essentials","title":"Core.ArgumentError","text":"ArgumentError(msg)\n\nThe arguments passed to a function are invalid. msg is a descriptive error message.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.AssertionError","page":"Essentials","title":"Core.AssertionError","text":"AssertionError([msg])\n\nThe asserted condition did not evaluate to true. Optional argument msg is a descriptive error string.\n\nExamples\n\njulia> @assert false \"this is not true\"\nERROR: AssertionError: this is not true\n\nAssertionError is usually thrown from @assert.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.BoundsError","page":"Essentials","title":"Core.BoundsError","text":"BoundsError([a],[i])\n\nAn indexing operation into an array, a, tried to access an out-of-bounds element at index i.\n\nExamples\n\njulia> A = fill(1.0, 7);\n\njulia> A[8]\nERROR: BoundsError: attempt to access 7-element Vector{Float64} at index [8]\n\n\njulia> B = fill(1.0, (2,3));\n\njulia> B[2, 4]\nERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [2, 4]\n\n\njulia> B[9]\nERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [9]\n\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.CompositeException","page":"Essentials","title":"Base.CompositeException","text":"CompositeException\n\nWrap a Vector of exceptions thrown by a Task (e.g. generated from a remote worker over a channel or an asynchronously executing local I/O write or a remote worker under pmap) with information about the series of exceptions. For example, if a group of workers are executing several tasks, and multiple workers fail, the resulting CompositeException will contain a \"bundle\" of information from each worker indicating where and why the exception(s) occurred.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.DimensionMismatch","page":"Essentials","title":"Base.DimensionMismatch","text":"DimensionMismatch([msg])\n\nThe objects called do not have matching dimensionality. Optional argument msg is a descriptive error string.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.DivideError","page":"Essentials","title":"Core.DivideError","text":"DivideError()\n\nInteger division was attempted with a denominator value of 0.\n\nExamples\n\njulia> 2/0\nInf\n\njulia> div(2, 0)\nERROR: DivideError: integer division error\nStacktrace:\n[...]\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.DomainError","page":"Essentials","title":"Core.DomainError","text":"DomainError(val)\nDomainError(val, msg)\n\nThe argument val to a function or constructor is outside the valid domain.\n\nExamples\n\njulia> sqrt(-1)\nERROR: DomainError with -1.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.EOFError","page":"Essentials","title":"Base.EOFError","text":"EOFError()\n\nNo more data was available to read from a file or stream.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.ErrorException","page":"Essentials","title":"Core.ErrorException","text":"ErrorException(msg)\n\nGeneric error type. The error message, in the .msg field, may provide more specific details.\n\nExamples\n\njulia> ex = ErrorException(\"I've done a bad thing\");\n\njulia> ex.msg\n\"I've done a bad thing\"\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.InexactError","page":"Essentials","title":"Core.InexactError","text":"InexactError(name::Symbol, T, val)\n\nCannot exactly convert val to type T in a method of function name.\n\nExamples\n\njulia> convert(Float64, 1+2im)\nERROR: InexactError: Float64(1 + 2im)\nStacktrace:\n[...]\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.InterruptException","page":"Essentials","title":"Core.InterruptException","text":"InterruptException()\n\nThe process was stopped by a terminal interrupt (CTRL+C).\n\nNote that, in Julia script started without -i (interactive) option, InterruptException is not thrown by default. Calling Base.exit_on_sigint(false) in the script can recover the behavior of the REPL. Alternatively, a Julia script can be started with\n\njulia -e \"include(popfirst!(ARGS))\" script.jl\n\nto let InterruptException be thrown by CTRL+C during the execution.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.KeyError","page":"Essentials","title":"Base.KeyError","text":"KeyError(key)\n\nAn indexing operation into an AbstractDict (Dict) or Set like object tried to access or delete a non-existent element.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.LoadError","page":"Essentials","title":"Core.LoadError","text":"LoadError(file::AbstractString, line::Int, error)\n\nAn error occurred while includeing, requireing, or using a file. The error specifics should be available in the .error field.\n\ncompat: Julia 1.7\nLoadErrors are no longer emitted by @macroexpand, @macroexpand1, and macroexpand as of Julia 1.7.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.MethodError","page":"Essentials","title":"Core.MethodError","text":"MethodError(f, args)\n\nA method with the required type signature does not exist in the given generic function. Alternatively, there is no unique most-specific method.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.MissingException","page":"Essentials","title":"Base.MissingException","text":"MissingException(msg)\n\nException thrown when a missing value is encountered in a situation where it is not supported. The error message, in the msg field may provide more specific details.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.OutOfMemoryError","page":"Essentials","title":"Core.OutOfMemoryError","text":"OutOfMemoryError()\n\nAn operation allocated too much memory for either the system or the garbage collector to handle properly.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.ReadOnlyMemoryError","page":"Essentials","title":"Core.ReadOnlyMemoryError","text":"ReadOnlyMemoryError()\n\nAn operation tried to write to memory that is read-only.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.OverflowError","page":"Essentials","title":"Core.OverflowError","text":"OverflowError(msg)\n\nThe result of an expression is too large for the specified type and will cause a wraparound.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.ProcessFailedException","page":"Essentials","title":"Base.ProcessFailedException","text":"ProcessFailedException\n\nIndicates problematic exit status of a process. When running commands or pipelines, this is thrown to indicate a nonzero exit code was returned (i.e. that the invoked process failed).\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.TaskFailedException","page":"Essentials","title":"Base.TaskFailedException","text":"TaskFailedException\n\nThis exception is thrown by a wait(t) call when task t fails. TaskFailedException wraps the failed task t.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.StackOverflowError","page":"Essentials","title":"Core.StackOverflowError","text":"StackOverflowError()\n\nThe function call grew beyond the size of the call stack. This usually happens when a call recurses infinitely.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.SystemError","page":"Essentials","title":"Base.SystemError","text":"SystemError(prefix::AbstractString, [errno::Int32])\n\nA system call failed with an error code (in the errno global variable).\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.TypeError","page":"Essentials","title":"Core.TypeError","text":"TypeError(func::Symbol, context::AbstractString, expected::Type, got)\n\nA type assertion failure, or calling an intrinsic function with an incorrect argument type.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.UndefKeywordError","page":"Essentials","title":"Core.UndefKeywordError","text":"UndefKeywordError(var::Symbol)\n\nThe required keyword argument var was not assigned in a function call.\n\nExamples\n\njulia> function my_func(;my_arg)\n return my_arg + 1\n end\nmy_func (generic function with 1 method)\n\njulia> my_func()\nERROR: UndefKeywordError: keyword argument `my_arg` not assigned\nStacktrace:\n [1] my_func() at ./REPL[1]:2\n [2] top-level scope at REPL[2]:1\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.UndefRefError","page":"Essentials","title":"Core.UndefRefError","text":"UndefRefError()\n\nThe item or field is not defined for the given object.\n\nExamples\n\njulia> struct MyType\n a::Vector{Int}\n MyType() = new()\n end\n\njulia> A = MyType()\nMyType(#undef)\n\njulia> A.a\nERROR: UndefRefError: access to undefined reference\nStacktrace:\n[...]\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.UndefVarError","page":"Essentials","title":"Core.UndefVarError","text":"UndefVarError(var::Symbol, [scope])\n\nA symbol in the current scope is not defined.\n\nExamples\n\njulia> a\nERROR: UndefVarError: `a` not defined in `Main`\n\njulia> a = 1;\n\njulia> a\n1\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.StringIndexError","page":"Essentials","title":"Base.StringIndexError","text":"StringIndexError(str, i)\n\nAn error occurred when trying to access str at index i that is not valid.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.InitError","page":"Essentials","title":"Core.InitError","text":"InitError(mod::Symbol, error)\n\nAn error occurred when running a module's __init__ function. The actual error thrown is available in the .error field.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.retry","page":"Essentials","title":"Base.retry","text":"retry(f; delays=ExponentialBackOff(), check=nothing) -> Function\n\nReturn an anonymous function that calls function f. If an exception arises, f is repeatedly called again, each time check returns true, after waiting the number of seconds specified in delays. check should input delays's current state and the Exception.\n\ncompat: Julia 1.2\nBefore Julia 1.2 this signature was restricted to f::Function.\n\nExamples\n\nretry(f, delays=fill(5.0, 3))\nretry(f, delays=rand(5:10, 2))\nretry(f, delays=Base.ExponentialBackOff(n=3, first_delay=5, max_delay=1000))\nretry(http_get, check=(s,e)->e.status == \"503\")(url)\nretry(read, check=(s,e)->isa(e, IOError))(io, 128; all=false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ExponentialBackOff","page":"Essentials","title":"Base.ExponentialBackOff","text":"ExponentialBackOff(; n=1, first_delay=0.05, max_delay=10.0, factor=5.0, jitter=0.1)\n\nA Float64 iterator of length n whose elements exponentially increase at a rate in the interval factor * (1 ± jitter). The first element is first_delay and all elements are clamped to max_delay.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Events","page":"Essentials","title":"Events","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.Timer(::Function, ::Real)\nBase.Timer\nBase.AsyncCondition\nBase.AsyncCondition(::Function)","category":"page"},{"location":"base/base/#Base.Timer-Tuple{Function, Real}","page":"Essentials","title":"Base.Timer","text":"Timer(callback::Function, delay; interval = 0)\n\nCreate a timer that runs the function callback at each timer expiration.\n\nWaiting tasks are woken and the function callback is called after an initial delay of delay seconds, and then repeating with the given interval in seconds. If interval is equal to 0, the callback is only run once. The function callback is called with a single argument, the timer itself. Stop a timer by calling close. The callback may still be run one final time, if the timer has already expired.\n\nExamples\n\nHere the first number is printed after a delay of two seconds, then the following numbers are printed quickly.\n\njulia> begin\n i = 0\n cb(timer) = (global i += 1; println(i))\n t = Timer(cb, 2, interval=0.2)\n wait(t)\n sleep(0.5)\n close(t)\n end\n1\n2\n3\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Timer","page":"Essentials","title":"Base.Timer","text":"Timer(delay; interval = 0)\n\nCreate a timer that wakes up tasks waiting for it (by calling wait on the timer object).\n\nWaiting tasks are woken after an initial delay of at least delay seconds, and then repeating after at least interval seconds again elapse. If interval is equal to 0, the timer is only triggered once. When the timer is closed (by close) waiting tasks are woken with an error. Use isopen to check whether a timer is still active.\n\nnote: Note\ninterval is subject to accumulating time skew. If you need precise events at a particular absolute time, create a new timer at each expiration with the difference to the next time computed.\n\nnote: Note\nA Timer requires yield points to update its state. For instance, isopen(t::Timer) cannot be used to timeout a non-yielding while loop.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.AsyncCondition","page":"Essentials","title":"Base.AsyncCondition","text":"AsyncCondition()\n\nCreate a async condition that wakes up tasks waiting for it (by calling wait on the object) when notified from C by a call to uv_async_send. Waiting tasks are woken with an error when the object is closed (by close). Use isopen to check whether it is still active.\n\nThis provides an implicit acquire & release memory ordering between the sending and waiting threads.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.AsyncCondition-Tuple{Function}","page":"Essentials","title":"Base.AsyncCondition","text":"AsyncCondition(callback::Function)\n\nCreate a async condition that calls the given callback function. The callback is passed one argument, the async condition object itself.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Reflection","page":"Essentials","title":"Reflection","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.nameof(::Module)\nBase.parentmodule\nBase.pathof(::Module)\nBase.pkgdir(::Module)\nBase.pkgversion(::Module)\nBase.moduleroot\n__module__\n__source__\nBase.@__MODULE__\nBase.@__FILE__\nBase.@__DIR__\nBase.@__LINE__\nBase.fullname\nBase.names\nBase.isexported\nBase.ispublic\nBase.nameof(::Function)\nBase.functionloc(::Any, ::Any)\nBase.functionloc(::Method)\nBase.@locals\nCore.getglobal\nCore.setglobal!\nCore.modifyglobal!\nCore.swapglobal!\nCore.setglobalonce!\nCore.replaceglobal!","category":"page"},{"location":"base/base/#Base.nameof-Tuple{Module}","page":"Essentials","title":"Base.nameof","text":"nameof(m::Module) -> Symbol\n\nGet the name of a Module as a Symbol.\n\nExamples\n\njulia> nameof(Base.Broadcast)\n:Broadcast\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.parentmodule","page":"Essentials","title":"Base.parentmodule","text":"parentmodule(m::Module) -> Module\n\nGet a module's enclosing Module. Main is its own parent.\n\nSee also: names, nameof, fullname, @__MODULE__.\n\nExamples\n\njulia> parentmodule(Main)\nMain\n\njulia> parentmodule(Base.Broadcast)\nBase\n\n\n\n\n\nparentmodule(t::DataType) -> Module\n\nDetermine the module containing the definition of a (potentially UnionAll-wrapped) DataType.\n\nExamples\n\njulia> module Foo\n struct Int end\n end\nFoo\n\njulia> parentmodule(Int)\nCore\n\njulia> parentmodule(Foo.Int)\nFoo\n\n\n\n\n\nparentmodule(f::Function) -> Module\n\nDetermine the module containing the (first) definition of a generic function.\n\n\n\n\n\nparentmodule(f::Function, types) -> Module\n\nDetermine the module containing the first method of a generic function f matching the specified types.\n\n\n\n\n\nparentmodule(m::Method) -> Module\n\nReturn the module in which the given method m is defined.\n\ncompat: Julia 1.9\nPassing a Method as an argument requires Julia 1.9 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.pathof-Tuple{Module}","page":"Essentials","title":"Base.pathof","text":"pathof(m::Module)\n\nReturn the path of the m.jl file that was used to import module m, or nothing if m was not imported from a package.\n\nUse dirname to get the directory part and basename to get the file name part of the path.\n\nSee also pkgdir.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.pkgdir-Tuple{Module}","page":"Essentials","title":"Base.pkgdir","text":"pkgdir(m::Module[, paths::String...])\n\nReturn the root directory of the package that declared module m, or nothing if m was not declared in a package. Optionally further path component strings can be provided to construct a path within the package root.\n\nTo get the root directory of the package that implements the current module the form pkgdir(@__MODULE__) can be used.\n\njulia> pkgdir(Foo)\n\"/path/to/Foo.jl\"\n\njulia> pkgdir(Foo, \"src\", \"file.jl\")\n\"/path/to/Foo.jl/src/file.jl\"\n\nSee also pathof.\n\ncompat: Julia 1.7\nThe optional argument paths requires at least Julia 1.7.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.pkgversion-Tuple{Module}","page":"Essentials","title":"Base.pkgversion","text":"pkgversion(m::Module)\n\nReturn the version of the package that imported module m, or nothing if m was not imported from a package, or imported from a package without a version field set.\n\nThe version is read from the package's Project.toml during package load.\n\nTo get the version of the package that imported the current module the form pkgversion(@__MODULE__) can be used.\n\ncompat: Julia 1.9\nThis function was introduced in Julia 1.9.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.moduleroot","page":"Essentials","title":"Base.moduleroot","text":"moduleroot(m::Module) -> Module\n\nFind the root module of a given module. This is the first module in the chain of parent modules of m which is either a registered root module or which is its own parent module.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#__module__","page":"Essentials","title":"__module__","text":"__module__\n\nThe argument __module__ is only visible inside the macro, and it provides information (in the form of a Module object) about the expansion context of the macro invocation. See the manual section on Macro invocation for more information.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#__source__","page":"Essentials","title":"__source__","text":"__source__\n\nThe argument __source__ is only visible inside the macro, and it provides information (in the form of a LineNumberNode object) about the parser location of the @ sign from the macro invocation. See the manual section on Macro invocation for more information.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.@__MODULE__","page":"Essentials","title":"Base.@__MODULE__","text":"@__MODULE__ -> Module\n\nGet the Module of the toplevel eval, which is the Module code is currently being read from.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@__FILE__","page":"Essentials","title":"Base.@__FILE__","text":"@__FILE__ -> String\n\nExpand to a string with the path to the file containing the macrocall, or an empty string if evaluated by julia -e . Return nothing if the macro was missing parser source information. Alternatively see PROGRAM_FILE.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@__DIR__","page":"Essentials","title":"Base.@__DIR__","text":"@__DIR__ -> String\n\nMacro to obtain the absolute path of the current directory as a string.\n\nIf in a script, returns the directory of the script containing the @__DIR__ macrocall. If run from a REPL or if evaluated by julia -e , returns the current working directory.\n\nExamples\n\nThe example illustrates the difference in the behaviors of @__DIR__ and pwd(), by creating a simple script in a different directory than the current working one and executing both commands:\n\njulia> cd(\"/home/JuliaUser\") # working directory\n\njulia> # create script at /home/JuliaUser/Projects\n open(\"/home/JuliaUser/Projects/test.jl\",\"w\") do io\n print(io, \"\"\"\n println(\"@__DIR__ = \", @__DIR__)\n println(\"pwd() = \", pwd())\n \"\"\")\n end\n\njulia> # outputs script directory and current working directory\n include(\"/home/JuliaUser/Projects/test.jl\")\n@__DIR__ = /home/JuliaUser/Projects\npwd() = /home/JuliaUser\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@__LINE__","page":"Essentials","title":"Base.@__LINE__","text":"@__LINE__ -> Int\n\nExpand to the line number of the location of the macrocall. Return 0 if the line number could not be determined.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.fullname","page":"Essentials","title":"Base.fullname","text":"fullname(m::Module)\n\nGet the fully-qualified name of a module as a tuple of symbols. For example,\n\nExamples\n\njulia> fullname(Base.Iterators)\n(:Base, :Iterators)\n\njulia> fullname(Main)\n(:Main,)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.names","page":"Essentials","title":"Base.names","text":"names(x::Module; all::Bool = false, imported::Bool = false)\n\nGet a vector of the public names of a Module, excluding deprecated names. If all is true, then the list also includes non-public names defined in the module, deprecated names, and compiler-generated names. If imported is true, then names explicitly imported from other modules are also included. Names are returned in sorted order.\n\nAs a special case, all names defined in Main are considered \"public\", since it is not idiomatic to explicitly mark names from Main as public.\n\nnote: Note\nsym ∈ names(SomeModule) does not imply isdefined(SomeModule, sym). names will return symbols marked with public or export, even if they are not defined in the module.\n\nSee also: Base.isexported, Base.ispublic, Base.@locals, @__MODULE__.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isexported","page":"Essentials","title":"Base.isexported","text":"isexported(m::Module, s::Symbol) -> Bool\n\nReturns whether a symbol is exported from a module.\n\nSee also: ispublic, names\n\njulia> module Mod\n export foo\n public bar\n end\nMod\n\njulia> Base.isexported(Mod, :foo)\ntrue\n\njulia> Base.isexported(Mod, :bar)\nfalse\n\njulia> Base.isexported(Mod, :baz)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ispublic","page":"Essentials","title":"Base.ispublic","text":"ispublic(m::Module, s::Symbol) -> Bool\n\nReturns whether a symbol is marked as public in a module.\n\nExported symbols are considered public.\n\ncompat: Julia 1.11\nThis function and the notion of publicity were added in Julia 1.11.\n\nSee also: isexported, names\n\njulia> module Mod\n export foo\n public bar\n end\nMod\n\njulia> Base.ispublic(Mod, :foo)\ntrue\n\njulia> Base.ispublic(Mod, :bar)\ntrue\n\njulia> Base.ispublic(Mod, :baz)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.nameof-Tuple{Function}","page":"Essentials","title":"Base.nameof","text":"nameof(f::Function) -> Symbol\n\nGet the name of a generic Function as a symbol. For anonymous functions, this is a compiler-generated name. For explicitly-declared subtypes of Function, it is the name of the function's type.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.functionloc-Tuple{Any, Any}","page":"Essentials","title":"Base.functionloc","text":"functionloc(f::Function, types)\n\nReturn a tuple (filename,line) giving the location of a generic Function definition.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.functionloc-Tuple{Method}","page":"Essentials","title":"Base.functionloc","text":"functionloc(m::Method)\n\nReturn a tuple (filename,line) giving the location of a Method definition.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.@locals","page":"Essentials","title":"Base.@locals","text":"@locals()\n\nConstruct a dictionary of the names (as symbols) and values of all local variables defined as of the call site.\n\ncompat: Julia 1.1\nThis macro requires at least Julia 1.1.\n\nExamples\n\njulia> let x = 1, y = 2\n Base.@locals\n end\nDict{Symbol, Any} with 2 entries:\n :y => 2\n :x => 1\n\njulia> function f(x)\n local y\n show(Base.@locals); println()\n for i = 1:1\n show(Base.@locals); println()\n end\n y = 2\n show(Base.@locals); println()\n nothing\n end;\n\njulia> f(42)\nDict{Symbol, Any}(:x => 42)\nDict{Symbol, Any}(:i => 1, :x => 42)\nDict{Symbol, Any}(:y => 2, :x => 42)\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Core.getglobal","page":"Essentials","title":"Core.getglobal","text":"getglobal(module::Module, name::Symbol, [order::Symbol=:monotonic])\n\nRetrieve the value of the binding name from the module module. Optionally, an atomic ordering can be defined for the operation, otherwise it defaults to monotonic.\n\nWhile accessing module bindings using getfield is still supported to maintain compatibility, using getglobal should always be preferred since getglobal allows for control over atomic ordering (getfield is always monotonic) and better signifies the code's intent both to the user as well as the compiler.\n\nMost users should not have to call this function directly – The getproperty function or corresponding syntax (i.e. module.name) should be preferred in all but few very specific use cases.\n\ncompat: Julia 1.9\nThis function requires Julia 1.9 or later.\n\nSee also getproperty and setglobal!.\n\nExamples\n\njulia> a = 1\n1\n\njulia> module M\n a = 2\n end;\n\njulia> getglobal(@__MODULE__, :a)\n1\n\njulia> getglobal(M, :a)\n2\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.setglobal!","page":"Essentials","title":"Core.setglobal!","text":"setglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])\n\nSet or change the value of the binding name in the module module to x. No type conversion is performed, so if a type has already been declared for the binding, x must be of appropriate type or an error is thrown.\n\nAdditionally, an atomic ordering can be specified for this operation, otherwise it defaults to monotonic.\n\nUsers will typically access this functionality through the setproperty! function or corresponding syntax (i.e. module.name = x) instead, so this is intended only for very specific use cases.\n\ncompat: Julia 1.9\nThis function requires Julia 1.9 or later.\n\nSee also setproperty! and getglobal\n\nExamples\n\njulia> module M end;\n\njulia> M.a # same as `getglobal(M, :a)`\nERROR: UndefVarError: `a` not defined in `M`\nSuggestion: check for spelling errors or missing imports.\n\njulia> setglobal!(M, :a, 1)\n1\n\njulia> M.a\n1\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.modifyglobal!","page":"Essentials","title":"Core.modifyglobal!","text":"modifyglobal!(module::Module, name::Symbol, op, x, [order::Symbol=:monotonic]) -> Pair\n\nAtomically perform the operations to get and set a global after applying the function op.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also modifyproperty! and setglobal!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.swapglobal!","page":"Essentials","title":"Core.swapglobal!","text":"swapglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])\n\nAtomically perform the operations to simultaneously get and set a global.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also swapproperty! and setglobal!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.setglobalonce!","page":"Essentials","title":"Core.setglobalonce!","text":"setglobalonce!(module::Module, name::Symbol, value,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool\n\nAtomically perform the operations to set a global to a given value, only if it was previously not set.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also setpropertyonce! and setglobal!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.replaceglobal!","page":"Essentials","title":"Core.replaceglobal!","text":"replaceglobal!(module::Module, name::Symbol, expected, desired,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)\n\nAtomically perform the operations to get and conditionally set a global to a given value.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also replaceproperty! and setglobal!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Documentation","page":"Essentials","title":"Documentation","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"(See also the documentation chapter.)","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.@doc\nDocs.HTML\nDocs.Text\nDocs.hasdoc\nDocs.undocumented_names","category":"page"},{"location":"base/base/#Core.@doc","page":"Essentials","title":"Core.@doc","text":"Documentation\n\nFunctions, methods and types can be documented by placing a string before the definition:\n\n\"\"\"\n# The Foo Function\n`foo(x)`: Foo the living hell out of `x`.\n\"\"\"\nfoo(x) = ...\n\nThe @doc macro can be used directly to both set and retrieve documentation / metadata. The macro has special parsing so that the documented object may occur on the next line:\n\n@doc \"blah\"\nfunction foo() ...\n\nBy default, documentation is written as Markdown, but any object can be used as the first argument.\n\nDocumenting objects separately from their definitions\n\nYou can document an object before or after its definition with\n\n@doc \"foo\" function_to_doc\n@doc \"bar\" TypeToDoc\n\nFor macros, the syntax is @doc \"macro doc\" :(Module.@macro) or @doc \"macro doc\" :(string_macro\"\") for string macros. Without the quote :() the expansion of the macro will be documented.\n\nRetrieving Documentation\n\nYou can retrieve docs for functions, macros and other objects as follows:\n\n@doc foo\n@doc @time\n@doc md\"\"\n\nFunctions & Methods\n\nPlacing documentation before a method definition (e.g. function foo() ... or foo() = ...) will cause that specific method to be documented, as opposed to the whole function. Method docs are concatenated together in the order they were defined to provide docs for the function.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Docs.HTML","page":"Essentials","title":"Base.Docs.HTML","text":"HTML(s): Create an object that renders s as html.\n\nHTML(\"
    foo
    \")\n\nYou can also use a stream for large amounts of data:\n\nHTML() do io\n println(io, \"
    foo
    \")\nend\n\nwarning: Warning\nHTML is currently exported to maintain backwards compatibility, but this export is deprecated. It is recommended to use this type as Docs.HTML or to explicitly import it from Docs.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.Docs.Text","page":"Essentials","title":"Base.Docs.Text","text":"Text(s): Create an object that renders s as plain text.\n\nText(\"foo\")\n\nYou can also use a stream for large amounts of data:\n\nText() do io\n println(io, \"foo\")\nend\n\nwarning: Warning\nText is currently exported to maintain backwards compatibility, but this export is deprecated. It is recommended to use this type as Docs.Text or to explicitly import it from Docs.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.Docs.hasdoc","page":"Essentials","title":"Base.Docs.hasdoc","text":"Docs.hasdoc(mod::Module, sym::Symbol)::Bool\n\nReturn true if sym in mod has a docstring and false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Docs.undocumented_names","page":"Essentials","title":"Base.Docs.undocumented_names","text":"undocumented_names(mod::Module; private=false)\n\nReturn a sorted vector of undocumented symbols in module (that is, lacking docstrings). private=false (the default) returns only identifiers declared with public and/or export, whereas private=true returns all symbols in the module (excluding compiler-generated hidden symbols starting with #).\n\nSee also: names, Docs.hasdoc, Base.ispublic.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Code-loading","page":"Essentials","title":"Code loading","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.identify_package\nBase.locate_package\nBase.require\nBase.compilecache\nBase.isprecompiled\nBase.get_extension","category":"page"},{"location":"base/base/#Base.identify_package","page":"Essentials","title":"Base.identify_package","text":"Base.identify_package(name::String)::Union{PkgId, Nothing}\nBase.identify_package(where::Union{Module,PkgId}, name::String)::Union{PkgId, Nothing}\n\nIdentify the package by its name from the current environment stack, returning its PkgId, or nothing if it cannot be found.\n\nIf only the name argument is provided, it searches each environment in the stack and its named direct dependencies.\n\nThe where argument provides the context from where to search for the package: in this case it first checks if the name matches the context itself, otherwise it searches all recursive dependencies (from the resolved manifest of each environment) until it locates the context where, and from there identifies the dependency with the corresponding name.\n\njulia> Base.identify_package(\"Pkg\") # Pkg is a dependency of the default environment\nPkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]\n\njulia> using LinearAlgebra\n\njulia> Base.identify_package(LinearAlgebra, \"Pkg\") # Pkg is not a dependency of LinearAlgebra\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.locate_package","page":"Essentials","title":"Base.locate_package","text":"Base.locate_package(pkg::PkgId)::Union{String, Nothing}\n\nThe path to the entry-point file for the package corresponding to the identifier pkg, or nothing if not found. See also identify_package.\n\njulia> pkg = Base.identify_package(\"Pkg\")\nPkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]\n\njulia> Base.locate_package(pkg)\n\"/path/to/julia/stdlib/v1.12/Pkg/src/Pkg.jl\"\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.require","page":"Essentials","title":"Base.require","text":"require(into::Module, module::Symbol)\n\nThis function is part of the implementation of using / import, if a module is not already defined in Main. It can also be called directly to force reloading a module, regardless of whether it has been loaded before (for example, when interactively developing libraries).\n\nLoads a source file, in the context of the Main module, on every active node, searching standard locations for files. require is considered a top-level operation, so it sets the current include path but does not use it to search for files (see help for include). This function is typically used to load library code, and is implicitly called by using to load packages.\n\nWhen searching for files, require first looks for package code in the global array LOAD_PATH. require is case-sensitive on all platforms, including those with case-insensitive filesystems like macOS and Windows.\n\nFor more details regarding code loading, see the manual sections on modules and parallel computing.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.compilecache","page":"Essentials","title":"Base.compilecache","text":"Base.compilecache(module::PkgId)\n\nCreates a precompiled cache file for a module and all of its dependencies. This can be used to reduce package load times. Cache files are stored in DEPOT_PATH[1]/compiled. See Module initialization and precompilation for important notes.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isprecompiled","page":"Essentials","title":"Base.isprecompiled","text":"Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)\n\nReturns whether a given PkgId within the active project is precompiled.\n\nBy default this check observes the same approach that code loading takes with respect to when different versions of dependencies are currently loaded to that which is expected. To ignore loaded modules and answer as if in a fresh julia session specify ignore_loaded=true.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.get_extension","page":"Essentials","title":"Base.get_extension","text":"get_extension(parent::Module, extension::Symbol)\n\nReturn the module for extension of parent or return nothing if the extension is not loaded.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Internals","page":"Essentials","title":"Internals","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.GC.gc\nBase.GC.enable\nBase.GC.@preserve\nBase.GC.safepoint\nBase.GC.enable_logging\nBase.GC.logging_enabled\nMeta.lower\nMeta.@lower\nMeta.parse(::AbstractString, ::Int)\nMeta.parse(::AbstractString)\nMeta.ParseError\nCore.QuoteNode\nBase.macroexpand\nBase.@macroexpand\nBase.@macroexpand1\nBase.code_lowered\nBase.code_typed\nBase.precompile\nBase.jit_total_bytes","category":"page"},{"location":"base/base/#Base.GC.gc","page":"Essentials","title":"Base.GC.gc","text":"GC.gc([full=true])\n\nPerform garbage collection. The argument full determines the kind of collection: a full collection (default) traverses all live objects (i.e. full mark) and should reclaim memory from all unreachable objects. An incremental collection only reclaims memory from young objects which are not reachable.\n\nThe GC may decide to perform a full collection even if an incremental collection was requested.\n\nwarning: Warning\nExcessive use will likely lead to poor performance.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.GC.enable","page":"Essentials","title":"Base.GC.enable","text":"GC.enable(on::Bool)\n\nControl whether garbage collection is enabled using a boolean argument (true for enabled, false for disabled). Return previous GC state.\n\nwarning: Warning\nDisabling garbage collection should be used only with caution, as it can cause memory use to grow without bound.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.GC.@preserve","page":"Essentials","title":"Base.GC.@preserve","text":"GC.@preserve x1 x2 ... xn expr\n\nMark the objects x1, x2, ... as being in use during the evaluation of the expression expr. This is only required in unsafe code where expr implicitly uses memory or other resources owned by one of the xs.\n\nImplicit use of x covers any indirect use of resources logically owned by x which the compiler cannot see. Some examples:\n\nAccessing memory of an object directly via a Ptr\nPassing a pointer to x to ccall\nUsing resources of x which would be cleaned up in the finalizer.\n\n@preserve should generally not have any performance impact in typical use cases where it briefly extends object lifetime. In implementation, @preserve has effects such as protecting dynamically allocated objects from garbage collection.\n\nExamples\n\nWhen loading from a pointer with unsafe_load, the underlying object is implicitly used, for example x is implicitly used by unsafe_load(p) in the following:\n\njulia> let\n x = Ref{Int}(101)\n p = Base.unsafe_convert(Ptr{Int}, x)\n GC.@preserve x unsafe_load(p)\n end\n101\n\nWhen passing pointers to ccall, the pointed-to object is implicitly used and should be preserved. (Note however that you should normally just pass x directly to ccall which counts as an explicit use.)\n\njulia> let\n x = \"Hello\"\n p = pointer(x)\n Int(GC.@preserve x @ccall strlen(p::Cstring)::Csize_t)\n # Preferred alternative\n Int(@ccall strlen(x::Cstring)::Csize_t)\n end\n5\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.GC.safepoint","page":"Essentials","title":"Base.GC.safepoint","text":"GC.safepoint()\n\nInserts a point in the program where garbage collection may run. This can be useful in rare cases in multi-threaded programs where some threads are allocating memory (and hence may need to run GC) but other threads are doing only simple operations (no allocation, task switches, or I/O). Calling this function periodically in non-allocating threads allows garbage collection to run.\n\ncompat: Julia 1.4\nThis function is available as of Julia 1.4.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.GC.enable_logging","page":"Essentials","title":"Base.GC.enable_logging","text":"GC.enable_logging(on::Bool)\n\nWhen turned on, print statistics about each GC to stderr.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.GC.logging_enabled","page":"Essentials","title":"Base.GC.logging_enabled","text":"GC.logging_enabled()\n\nReturn whether GC logging has been enabled via GC.enable_logging.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Meta.lower","page":"Essentials","title":"Base.Meta.lower","text":"lower(m, x)\n\nTakes the expression x and returns an equivalent expression in lowered form for executing in module m. See also code_lowered.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Meta.@lower","page":"Essentials","title":"Base.Meta.@lower","text":"@lower [m] x\n\nReturn lowered form of the expression x in module m. By default m is the module in which the macro is called. See also lower.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Meta.parse-Tuple{AbstractString, Int64}","page":"Essentials","title":"Base.Meta.parse","text":"parse(str, start; greedy=true, raise=true, depwarn=true, filename=\"none\")\n\nParse the expression string and return an expression (which could later be passed to eval for execution). start is the code unit index into str of the first character to start parsing at (as with all string indexing, these are not character indices). If greedy is true (default), parse will try to consume as much input as it can; otherwise, it will stop as soon as it has parsed a valid expression. Incomplete but otherwise syntactically valid expressions will return Expr(:incomplete, \"(error message)\"). If raise is true (default), syntax errors other than incomplete expressions will raise an error. If raise is false, parse will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be suppressed. The filename argument is used to display diagnostics when an error is raised.\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 1) # start of string\n(:((α, β) = (3, 5)), 16)\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 1, greedy=false)\n(:((α, β)), 9)\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 16) # end of string\n(nothing, 16)\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 11) # index of 3\n(:((3, 5)), 16)\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 11, greedy=false)\n(3, 13)\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Meta.parse-Tuple{AbstractString}","page":"Essentials","title":"Base.Meta.parse","text":"parse(str; raise=true, depwarn=true, filename=\"none\")\n\nParse the expression string greedily, returning a single expression. An error is thrown if there are additional characters after the first expression. If raise is true (default), syntax errors will raise an error; otherwise, parse will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be suppressed. The filename argument is used to display diagnostics when an error is raised.\n\njulia> Meta.parse(\"x = 3\")\n:(x = 3)\n\njulia> Meta.parse(\"1.0.2\")\nERROR: ParseError:\n# Error @ none:1:1\n1.0.2\n└──┘ ── invalid numeric constant\n[...]\n\njulia> Meta.parse(\"1.0.2\"; raise = false)\n:($(Expr(:error, \"invalid numeric constant \"1.0.\"\")))\n\njulia> Meta.parse(\"x = \")\n:($(Expr(:incomplete, \"incomplete: premature end of input\")))\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Meta.ParseError","page":"Essentials","title":"Base.Meta.ParseError","text":"ParseError(msg)\n\nThe expression passed to the parse function could not be interpreted as a valid Julia expression.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.QuoteNode","page":"Essentials","title":"Core.QuoteNode","text":"QuoteNode\n\nA quoted piece of code, that does not support interpolation. See the manual section about QuoteNodes for details.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.macroexpand","page":"Essentials","title":"Base.macroexpand","text":"macroexpand(m::Module, x; recursive=true)\n\nTake the expression x and return an equivalent expression with all macros removed (expanded) for executing in module m. The recursive keyword controls whether deeper levels of nested macros are also expanded. This is demonstrated in the example below:\n\njulia> module M\n macro m1()\n 42\n end\n macro m2()\n :(@m1())\n end\n end\nM\n\njulia> macroexpand(M, :(@m2()), recursive=true)\n42\n\njulia> macroexpand(M, :(@m2()), recursive=false)\n:(#= REPL[16]:6 =# M.@m1)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@macroexpand","page":"Essentials","title":"Base.@macroexpand","text":"@macroexpand [mod,] ex\n\nReturn equivalent expression with all macros removed (expanded). If two arguments are provided, the first is the module to evaluate in.\n\nThere are differences between @macroexpand and macroexpand.\n\nWhile macroexpand takes a keyword argument recursive, @macroexpand is always recursive. For a non recursive macro version, see @macroexpand1.\nWhile macroexpand has an explicit module argument, @macroexpand always expands with respect to the module in which it is called.\n\nThis is best seen in the following example:\n\njulia> module M\n macro m()\n 1\n end\n function f()\n (@macroexpand(@m),\n macroexpand(M, :(@m)),\n macroexpand(Main, :(@m))\n )\n end\n end\nM\n\njulia> macro m()\n 2\n end\n@m (macro with 1 method)\n\njulia> M.f()\n(1, 1, 2)\n\nWith @macroexpand the expression expands where @macroexpand appears in the code (module M in the example). With macroexpand the expression expands in the module given as the first argument.\n\ncompat: Julia 1.11\nThe two-argument form requires at least Julia 1.11.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@macroexpand1","page":"Essentials","title":"Base.@macroexpand1","text":"@macroexpand1 [mod,] ex\n\nNon recursive version of @macroexpand.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.code_lowered","page":"Essentials","title":"Base.code_lowered","text":"code_lowered(f, types; generated=true, debuginfo=:default)\n\nReturn an array of the lowered forms (IR) for the methods matching the given generic function and type signature.\n\nIf generated is false, the returned CodeInfo instances will correspond to fallback implementations. An error is thrown if no fallback implementation exists. If generated is true, these CodeInfo instances will correspond to the method bodies yielded by expanding the generators.\n\nThe keyword debuginfo controls the amount of code metadata present in the output.\n\nNote that an error will be thrown if types are not leaf types when generated is true and any of the corresponding methods are an @generated method.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.code_typed","page":"Essentials","title":"Base.code_typed","text":"code_typed(f, types; kw...)\n\nReturns an array of type-inferred lowered form (IR) for the methods matching the given generic function and type signature.\n\nKeyword Arguments\n\noptimize::Bool = true: optional, controls whether additional optimizations, such as inlining, are also applied.\ndebuginfo::Symbol = :default: optional, controls the amount of code metadata present in the output, possible options are :source or :none.\n\nInternal Keyword Arguments\n\nThis section should be considered internal, and is only for who understands Julia compiler internals.\n\nworld::UInt = Base.get_world_counter(): optional, controls the world age to use when looking up methods, use current world age if not specified.\ninterp::Core.Compiler.AbstractInterpreter = Core.Compiler.NativeInterpreter(world): optional, controls the abstract interpreter to use, use the native interpreter if not specified.\n\nExamples\n\nOne can put the argument types in a tuple to get the corresponding code_typed.\n\njulia> code_typed(+, (Float64, Float64))\n1-element Vector{Any}:\n CodeInfo(\n1 ─ %1 = Base.add_float(x, y)::Float64\n└── return %1\n) => Float64\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.precompile","page":"Essentials","title":"Base.precompile","text":"precompile(f, argtypes::Tuple{Vararg{Any}})\n\nCompile the given function f for the argument tuple (of types) argtypes, but do not execute it.\n\n\n\n\n\nprecompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)\n\nPrecompile a specific method for the given argument types. This may be used to precompile a different method than the one that would ordinarily be chosen by dispatch, thus mimicking invoke.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.jit_total_bytes","page":"Essentials","title":"Base.jit_total_bytes","text":"Base.jit_total_bytes()\n\nReturn the total amount (in bytes) allocated by the just-in-time compiler for e.g. native code and data.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Meta","page":"Essentials","title":"Meta","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Meta.quot\nMeta.isexpr\nMeta.isidentifier\nMeta.isoperator\nMeta.isunaryoperator\nMeta.isbinaryoperator\nMeta.show_sexpr","category":"page"},{"location":"base/base/#Base.Meta.quot","page":"Essentials","title":"Base.Meta.quot","text":"Meta.quot(ex)::Expr\n\nQuote expression ex to produce an expression with head quote. This can for instance be used to represent objects of type Expr in the AST. See also the manual section about QuoteNode.\n\nExamples\n\njulia> eval(Meta.quot(:x))\n:x\n\njulia> dump(Meta.quot(:x))\nExpr\n head: Symbol quote\n args: Array{Any}((1,))\n 1: Symbol x\n\njulia> eval(Meta.quot(:(1+2)))\n:(1 + 2)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isexpr","page":"Essentials","title":"Base.isexpr","text":"Meta.isexpr(ex, head[, n])::Bool\n\nReturn true if ex is an Expr with the given type head and optionally that the argument list is of length n. head may be a Symbol or collection of Symbols. For example, to check that a macro was passed a function call expression, you might use isexpr(ex, :call).\n\nExamples\n\njulia> ex = :(f(x))\n:(f(x))\n\njulia> Meta.isexpr(ex, :block)\nfalse\n\njulia> Meta.isexpr(ex, :call)\ntrue\n\njulia> Meta.isexpr(ex, [:block, :call]) # multiple possible heads\ntrue\n\njulia> Meta.isexpr(ex, :call, 1)\nfalse\n\njulia> Meta.isexpr(ex, :call, 2)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isidentifier","page":"Essentials","title":"Base.isidentifier","text":" isidentifier(s) -> Bool\n\nReturn whether the symbol or string s contains characters that are parsed as a valid ordinary identifier (not a binary/unary operator) in Julia code; see also Base.isoperator.\n\nInternally Julia allows any sequence of characters in a Symbol (except \\0s), and macros automatically use variable names containing # in order to avoid naming collision with the surrounding code. In order for the parser to recognize a variable, it uses a limited set of characters (greatly extended by Unicode). isidentifier() makes it possible to query the parser directly whether a symbol contains valid characters.\n\nExamples\n\njulia> Meta.isidentifier(:x), Meta.isidentifier(\"1x\")\n(true, false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isoperator","page":"Essentials","title":"Base.isoperator","text":"isoperator(s::Symbol)\n\nReturn true if the symbol can be used as an operator, false otherwise.\n\nExamples\n\njulia> Meta.isoperator(:+), Meta.isoperator(:f)\n(true, false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isunaryoperator","page":"Essentials","title":"Base.isunaryoperator","text":"isunaryoperator(s::Symbol)\n\nReturn true if the symbol can be used as a unary (prefix) operator, false otherwise.\n\nExamples\n\njulia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)\n(true, true, false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isbinaryoperator","page":"Essentials","title":"Base.isbinaryoperator","text":"isbinaryoperator(s::Symbol)\n\nReturn true if the symbol can be used as a binary (infix) operator, false otherwise.\n\nExamples\n\njulia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)\n(true, false, false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Meta.show_sexpr","page":"Essentials","title":"Base.Meta.show_sexpr","text":"Meta.show_sexpr([io::IO,], ex)\n\nShow expression ex as a lisp style S-expression.\n\nExamples\n\njulia> Meta.show_sexpr(:(f(x, g(y,z))))\n(:call, :f, :x, (:call, :g, :y, :z))\n\n\n\n\n\n","category":"function"},{"location":"manual/unicode-input/#Unicode-Input","page":"Unicode Input","title":"Unicode Input","text":"","category":"section"},{"location":"manual/unicode-input/","page":"Unicode Input","title":"Unicode Input","text":"The following table lists Unicode characters that can be entered via tab completion of LaTeX-like abbreviations in the Julia REPL (and in various other editing environments). You can also get information on how to type a symbol by entering it in the REPL help, i.e. by typing ? and then entering the symbol in the REPL (e.g., by copy-paste from somewhere you saw the symbol).","category":"page"},{"location":"manual/unicode-input/","page":"Unicode Input","title":"Unicode Input","text":"warning: Warning\nThis table may appear to contain missing characters in the second column, or even show characters that are inconsistent with the characters as they are rendered in the Julia REPL. In these cases, users are strongly advised to check their choice of fonts in their browser and REPL environment, as there are known issues with glyphs in many fonts.","category":"page"},{"location":"manual/unicode-input/","page":"Unicode Input","title":"Unicode Input","text":"#\n# Generate a table containing all LaTeX and Emoji tab completions available in the REPL.\n#\nimport REPL, Markdown\nconst NBSP = '\\u00A0'\n\nfunction tab_completions(symbols...)\n completions = Dict{String, Vector{String}}()\n for each in symbols, (k, v) in each\n completions[v] = push!(get!(completions, v, String[]), k)\n end\n return completions\nend\n\nfunction unicode_data()\n file = normpath(@__DIR__, \"..\", \"..\", \"..\", \"..\", \"..\", \"doc\", \"UnicodeData.txt\")\n names = Dict{UInt32, String}()\n open(file) do unidata\n for line in readlines(unidata)\n id, name, desc = split(line, \";\")[[1, 2, 11]]\n codepoint = parse(UInt32, \"0x$id\")\n names[codepoint] = titlecase(lowercase(\n name == \"\" ? desc : desc == \"\" ? name : \"$name / $desc\"))\n end\n end\n return names\nend\n\n# Surround combining characters with no-break spaces (i.e '\\u00A0'). Follows the same format\n# for how unicode is displayed on the unicode.org website:\n# https://util.unicode.org/UnicodeJsps/character.jsp?a=0300\nfunction fix_combining_chars(char)\n cat = Base.Unicode.category_code(char)\n return cat == 6 || cat == 8 ? \"$NBSP$char$NBSP\" : \"$char\"\nend\n\nfunction table_entries(completions, unicode_dict)\n entries = Any[Any[\n [\"Code point(s)\"],\n [\"Character(s)\"],\n [\"Tab completion sequence(s)\"],\n [\"Unicode name(s)\"],\n ]]\n for (chars, inputs) in sort!(collect(completions), by = first)\n code_points, unicode_names, characters = String[], String[], String[]\n for char in chars\n push!(code_points, \"U+$(uppercase(string(UInt32(char), base = 16, pad = 5)))\")\n push!(unicode_names, get(unicode_dict, UInt32(char), \"(No Unicode name)\"))\n push!(characters, isempty(characters) ? fix_combining_chars(char) : \"$char\")\n end\n inputs_md = []\n for (i, input) in enumerate(inputs)\n i > 1 && push!(inputs_md, \", \")\n push!(inputs_md, Markdown.Code(\"\", input))\n end\n push!(entries, [\n [join(code_points, \" + \")],\n [join(characters)],\n inputs_md,\n [join(unicode_names, \" + \")],\n ])\n end\n table = Markdown.Table(entries, [:l, :c, :l, :l])\n # We also need to wrap the Table in a Markdown.MD \"document\"\n return Markdown.MD([table])\nend\n\ntable_entries(\n tab_completions(\n REPL.REPLCompletions.latex_symbols,\n REPL.REPLCompletions.emoji_symbols\n ),\n unicode_data()\n)","category":"page"},{"location":"base/scopedvalues/#scoped-values","page":"Scoped Values","title":"Scoped Values","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Scoped values provide an implementation of dynamic scoping in Julia.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"note: Lexical scoping vs dynamic scoping\nLexical scoping is the default behavior in Julia. Under lexical scoping the scope of a variable is determined by the lexical (textual) structure of a program. Under dynamic scoping a variable is bound to the most recent assigned value during the program's execution.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"The state of a scoped value is dependent on the execution path of the program. This means that for a scoped value you may observe multiple different values concurrently.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"compat: Julia 1.11\nScoped values were introduced in Julia 1.11. In Julia 1.8+ a compatible implementation is available from the package ScopedValues.jl.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In its simplest form you can create a ScopedValue with a default value and then use with or @with to enter a new dynamic scope. The new scope will inherit all values from the parent scope (and recursively from all outer scopes) with the provided scoped value taking priority over previous definitions.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Let's first look at an example of lexical scope. A let statement begins a new lexical scope within which the outer definition of x is shadowed by it's inner definition.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"x = 1\nlet x = 5\n @show x # 5\nend\n@show x # 1","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In the following example, since Julia uses lexical scope, the variable x in the body of f refers to the x defined in the global scope, and entering a let scope does not change the value f observes.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"x = 1\nf() = @show x\nlet x = 5\n f() # 1\nend\nf() # 1","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Now using a ScopedValue we can use dynamic scoping.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\n\nx = ScopedValue(1)\nf() = @show x[]\nwith(x=>5) do\n f() # 5\nend\nf() # 1","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Note that the observed value of the ScopedValue is dependent on the execution path of the program.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"It often makes sense to use a const variable to point to a scoped value, and you can set the value of multiple ScopedValues with one call to with.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\n\nf() = @show a[]\ng() = @show b[]\n\nconst a = ScopedValue(1)\nconst b = ScopedValue(2)\n\nf() # a[] = 1\ng() # b[] = 2\n\n# Enter a new dynamic scope and set value.\nwith(a => 3) do\n f() # a[] = 3\n g() # b[] = 2\n with(a => 4, b => 5) do\n f() # a[] = 4\n g() # b[] = 5\n end\n f() # a[] = 3\n g() # b[] = 2\nend\n\nf() # a[] = 1\ng() # b[] = 2","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"ScopedValues provides a macro version of with. The expression @with var=>val expr evaluates expr in a new dynamic scope with var set to val. @with var=>val expr is equivalent to with(var=>val) do expr end. However, with requires a zero-argument closure or function, which results in an extra call-frame. As an example, consider the following function f:","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nconst a = ScopedValue(1)\nf(x) = a[] + x","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"If you wish to run f in a dynamic scope with a set to 2, then you can use with:","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"with(() -> f(10), a=>2)","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"However, this requires wrapping f in a zero-argument function. If you wish to avoid the extra call-frame, then you can use the @with macro:","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"@with a=>2 f(10)","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"note: Note\nDynamic scopes are inherited by Tasks, at the moment of task creation. Dynamic scopes are not propagated through Distributed.jl operations.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In the example below we open a new dynamic scope before launching a task. The parent task and the two child tasks observe independent values of the same scoped value at the same time.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nimport Base.Threads: @spawn\n\nconst scoped_val = ScopedValue(1)\n@sync begin\n with(scoped_val => 2)\n @spawn @show scoped_val[] # 2\n end\n with(scoped_val => 3)\n @spawn @show scoped_val[] # 3\n end\n @show scoped_val[] # 1\nend","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Scoped values are constant throughout a scope, but you can store mutable state in a scoped value. Just keep in mind that the usual caveats for global variables apply in the context of concurrent programming.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Care is also required when storing references to mutable state in scoped values. You might want to explicitly unshare mutable state when entering a new dynamic scope.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nimport Base.Threads: @spawn\n\nconst sval_dict = ScopedValue(Dict())\n\n# Example of using a mutable value wrongly\n@sync begin\n # `Dict` is not thread-safe the usage below is invalid\n @spawn (sval_dict[][:a] = 3)\n @spawn (sval_dict[][:b] = 3)\nend\n\n@sync begin\n # If we instead pass a unique dictionary to each\n # task we can access the dictionaries race free.\n with(sval_dict => Dict()) do\n @spawn (sval_dict[][:a] = 3)\n end\n with(sval_dict => Dict()) do\n @spawn (sval_dict[][:b] = 3)\n end\nend","category":"page"},{"location":"base/scopedvalues/#Example","page":"Scoped Values","title":"Example","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In the example below we use a scoped value to implement a permission check in a web-application. After determining the permissions of the request, a new dynamic scope is entered and the scoped value LEVEL is set. Other parts of the application can query the scoped value and will receive the appropriate value. Other alternatives like task-local storage and global variables are not well suited for this kind of propagation; our only alternative would have been to thread a value through the entire call-chain.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\n\nconst LEVEL = ScopedValue(:GUEST)\n\nfunction serve(request, response)\n level = isAdmin(request) ? :ADMIN : :GUEST\n with(LEVEL => level) do\n Threads.@spawn handle(request, response)\n end\nend\n\nfunction open(connection::Database)\n level = LEVEL[]\n if level !== :ADMIN\n error(\"Access disallowed\")\n end\n # ... open connection\nend\n\nfunction handle(request, response)\n # ...\n open(Database(#=...=#))\n # ...\nend","category":"page"},{"location":"base/scopedvalues/#Idioms","page":"Scoped Values","title":"Idioms","text":"","category":"section"},{"location":"base/scopedvalues/#unshare_mutable_state","page":"Scoped Values","title":"Unshare mutable state","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nimport Base.Threads: @spawn\n\nconst sval_dict = ScopedValue(Dict())\n\n# If you want to add new values to the dict, instead of replacing\n# it, unshare the values explicitly. In this example we use `merge`\n# to unshare the state of the dictionary in parent scope.\n@sync begin\n with(sval_dict => merge(sval_dict[], Dict(:a => 10))) do\n @spawn @show sval_dict[][:a]\n end\n @spawn sval_dict[][:a] = 3 # Not a race since they are unshared.\nend","category":"page"},{"location":"base/scopedvalues/#Scoped-values-as-globals","page":"Scoped Values","title":"Scoped values as globals","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In order to access the value of a scoped value, the scoped value itself has to be in (lexical) scope. This means most often you likely want to use scoped values as constant globals.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nconst sval = ScopedValue(1)","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Indeed one can think of scoped values as hidden function arguments.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"This does not preclude their use as non-globals.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nimport Base.Threads: @spawn\n\nfunction main()\n role = ScopedValue(:client)\n\n function launch()\n #...\n role[]\n end\n\n @with role => :server @spawn launch()\n launch()\nend","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"But it might have been simpler to just directly pass the function argument in these cases.","category":"page"},{"location":"base/scopedvalues/#Very-many-ScopedValues","page":"Scoped Values","title":"Very many ScopedValues","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"If you find yourself creating many ScopedValue's for one given module, it may be better to use a dedicated struct to hold them.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\n\nBase.@kwdef struct Configuration\n color::Bool = false\n verbose::Bool = false\nend\n\nconst CONFIG = ScopedValue(Configuration(color=true))\n\n@with CONFIG => Configuration(color=CONFIG[].color, verbose=true) begin\n @show CONFIG[].color # true\n @show CONFIG[].verbose # true\nend","category":"page"},{"location":"base/scopedvalues/#API-docs","page":"Scoped Values","title":"API docs","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Base.ScopedValues.ScopedValue\nBase.ScopedValues.with\nBase.ScopedValues.@with\nBase.isassigned(::Base.ScopedValues.ScopedValue)\nBase.ScopedValues.get","category":"page"},{"location":"base/scopedvalues/#Base.ScopedValues.ScopedValue","page":"Scoped Values","title":"Base.ScopedValues.ScopedValue","text":"ScopedValue(x)\n\nCreate a container that propagates values across dynamic scopes. Use with to create and enter a new dynamic scope.\n\nValues can only be set when entering a new dynamic scope, and the value referred to will be constant during the execution of a dynamic scope.\n\nDynamic scopes are propagated across tasks.\n\nExamples\n\njulia> using Base.ScopedValues;\n\njulia> const sval = ScopedValue(1);\n\njulia> sval[]\n1\n\njulia> with(sval => 2) do\n sval[]\n end\n2\n\njulia> sval[]\n1\n\ncompat: Julia 1.11\nScoped values were introduced in Julia 1.11. In Julia 1.8+ a compatible implementation is available from the package ScopedValues.jl.\n\n\n\n\n\n","category":"type"},{"location":"base/scopedvalues/#Base.ScopedValues.with","page":"Scoped Values","title":"Base.ScopedValues.with","text":"with(f, (var::ScopedValue{T} => val)...)\n\nExecute f in a new dynamic scope with var set to val. val will be converted to type T.\n\nSee also: ScopedValues.@with, ScopedValues.ScopedValue, ScopedValues.get.\n\nExamples\n\njulia> using Base.ScopedValues\n\njulia> a = ScopedValue(1);\n\njulia> f(x) = a[] + x;\n\njulia> f(10)\n11\n\njulia> with(a=>2) do\n f(10)\n end\n12\n\njulia> f(10)\n11\n\njulia> b = ScopedValue(2);\n\njulia> g(x) = a[] + b[] + x;\n\njulia> with(a=>10, b=>20) do\n g(30)\n end\n60\n\njulia> with(() -> a[] * b[], a=>3, b=>4)\n12\n\n\n\n\n\n","category":"function"},{"location":"base/scopedvalues/#Base.ScopedValues.@with","page":"Scoped Values","title":"Base.ScopedValues.@with","text":"@with (var::ScopedValue{T} => val)... expr\n\nMacro version of with. The expression @with var=>val expr evaluates expr in a new dynamic scope with var set to val. val will be converted to type T. @with var=>val expr is equivalent to with(var=>val) do expr end, but @with avoids creating a closure.\n\nSee also: ScopedValues.with, ScopedValues.ScopedValue, ScopedValues.get.\n\nExamples\n\njulia> using Base.ScopedValues\n\njulia> const a = ScopedValue(1);\n\njulia> f(x) = a[] + x;\n\njulia> @with a=>2 f(10)\n12\n\njulia> @with a=>3 begin\n x = 100\n f(x)\n end\n103\n\n\n\n\n\n","category":"macro"},{"location":"base/scopedvalues/#Base.isassigned-Tuple{Base.ScopedValues.ScopedValue}","page":"Scoped Values","title":"Base.isassigned","text":"isassigned(val::ScopedValue)\n\nTest whether a ScopedValue has an assigned value.\n\nSee also: ScopedValues.with, ScopedValues.@with, ScopedValues.get.\n\nExamples\n\njulia> using Base.ScopedValues\n\njulia> a = ScopedValue(1); b = ScopedValue{Int}();\n\njulia> isassigned(a)\ntrue\n\njulia> isassigned(b)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"base/scopedvalues/#Base.ScopedValues.get","page":"Scoped Values","title":"Base.ScopedValues.get","text":"get(val::ScopedValue{T})::Union{Nothing, Some{T}}\n\nIf the scoped value isn't set and doesn't have a default value, return nothing. Otherwise returns Some{T} with the current value.\n\nSee also: ScopedValues.with, ScopedValues.@with, ScopedValues.ScopedValue.\n\nExamples\n\njulia> using Base.ScopedValues\n\njulia> a = ScopedValue(42); b = ScopedValue{Int}();\n\njulia> ScopedValues.get(a)\nSome(42)\n\njulia> isnothing(ScopedValues.get(b))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/scopedvalues/#Implementation-notes-and-performance","page":"Scoped Values","title":"Implementation notes and performance","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Scopes use a persistent dictionary. Lookup and insertion is O(log(32, n)), upon dynamic scope entry a small amount of data is copied and the unchanged data is shared among other scopes.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"The Scope object itself is not user-facing and may be changed in a future version of Julia.","category":"page"},{"location":"base/scopedvalues/#Design-inspiration","page":"Scoped Values","title":"Design inspiration","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"This design was heavily inspired by JEPS-429, which in turn was inspired by dynamically scoped free variables in many Lisp dialects. In particular Interlisp-D and its deep binding strategy.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"A prior design discussed was context variables ala PEPS-567 and implemented in Julia as ContextVariablesX.jl.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Integers-and-Floating-Point-Numbers","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Integers and floating-point values are the basic building blocks of arithmetic and computation. Built-in representations of such values are called numeric primitives, while representations of integers and floating-point numbers as immediate values in code are known as numeric literals. For example, 1 is an integer literal, while 1.0 is a floating-point literal; their binary in-memory representations as objects are numeric primitives.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia provides a broad range of primitive numeric types, and a full complement of arithmetic and bitwise operators as well as standard mathematical functions are defined over them. These map directly onto numeric types and operations that are natively supported on modern computers, thus allowing Julia to take full advantage of computational resources. Additionally, Julia provides software support for Arbitrary Precision Arithmetic, which can handle operations on numeric values that cannot be represented effectively in native hardware representations, but at the cost of relatively slower performance.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The following are Julia's primitive numeric types:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Integer types:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Type Signed? Number of bits Smallest value Largest value\nInt8 ✓ 8 -2^7 2^7 - 1\nUInt8 8 0 2^8 - 1\nInt16 ✓ 16 -2^15 2^15 - 1\nUInt16 16 0 2^16 - 1\nInt32 ✓ 32 -2^31 2^31 - 1\nUInt32 32 0 2^32 - 1\nInt64 ✓ 64 -2^63 2^63 - 1\nUInt64 64 0 2^64 - 1\nInt128 ✓ 128 -2^127 2^127 - 1\nUInt128 128 0 2^128 - 1\nBool N/A 8 false (0) true (1)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Floating-point types:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Type Precision Number of bits\nFloat16 half 16\nFloat32 single 32\nFloat64 double 64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Additionally, full support for Complex and Rational Numbers is built on top of these primitive numeric types. All numeric types interoperate naturally without explicit casting, thanks to a flexible, user-extensible type promotion system.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Integers","page":"Integers and Floating-Point Numbers","title":"Integers","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Literal integers are represented in the standard manner:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 1\n1\n\njulia> 1234\n1234","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The default type for an integer literal depends on whether the target system has a 32-bit architecture or a 64-bit architecture:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"# 32-bit system:\njulia> typeof(1)\nInt32\n\n# 64-bit system:\njulia> typeof(1)\nInt64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The Julia internal variable Sys.WORD_SIZE indicates whether the target system is 32-bit or 64-bit:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"# 32-bit system:\njulia> Sys.WORD_SIZE\n32\n\n# 64-bit system:\njulia> Sys.WORD_SIZE\n64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia also defines the types Int and UInt, which are aliases for the system's signed and unsigned native integer types respectively:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"# 32-bit system:\njulia> Int\nInt32\njulia> UInt\nUInt32\n\n# 64-bit system:\njulia> Int\nInt64\njulia> UInt\nUInt64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Larger integer literals that cannot be represented using only 32 bits but can be represented in 64 bits always create 64-bit integers, regardless of the system type:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"# 32-bit or 64-bit system:\njulia> typeof(3000000000)\nInt64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Unsigned integers are input and output using the 0x prefix and hexadecimal (base 16) digits 0-9a-f (the capitalized digits A-F also work for input). The size of the unsigned value is determined by the number of hex digits used:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 0x1\n0x01\n\njulia> typeof(x)\nUInt8\n\njulia> x = 0x123\n0x0123\n\njulia> typeof(x)\nUInt16\n\njulia> x = 0x1234567\n0x01234567\n\njulia> typeof(x)\nUInt32\n\njulia> x = 0x123456789abcdef\n0x0123456789abcdef\n\njulia> typeof(x)\nUInt64\n\njulia> x = 0x11112222333344445555666677778888\n0x11112222333344445555666677778888\n\njulia> typeof(x)\nUInt128","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"This behavior is based on the observation that when one uses unsigned hex literals for integer values, one typically is using them to represent a fixed numeric byte sequence, rather than just an integer value.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Binary and octal literals are also supported:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 0b10\n0x02\n\njulia> typeof(x)\nUInt8\n\njulia> x = 0o010\n0x08\n\njulia> typeof(x)\nUInt8\n\njulia> x = 0x00000000000000001111222233334444\n0x00000000000000001111222233334444\n\njulia> typeof(x)\nUInt128","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"As for hexadecimal literals, binary and octal literals produce unsigned integer types. The size of the binary data item is the minimal needed size, if the leading digit of the literal is not 0. In the case of leading zeros, the size is determined by the minimal needed size for a literal, which has the same length but leading digit 1. It means that:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"0x1 and 0x12 are UInt8 literals,\n0x123 and 0x1234 are UInt16 literals,\n0x12345 and 0x12345678 are UInt32 literals,\n0x123456789 and 0x1234567890adcdef are UInt64 literals, etc.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Even if there are leading zero digits which don’t contribute to the value, they count for determining storage size of a literal. So 0x01 is a UInt8 while 0x0001 is a UInt16.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"That allows the user to control the size.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Unsigned literals (starting with 0x) that encode integers too large to be represented as UInt128 values will construct BigInt values instead. This is not an unsigned type but it is the only built-in type big enough to represent such large integer values.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Binary, octal, and hexadecimal literals may be signed by a - immediately preceding the unsigned literal. They produce an unsigned integer of the same size as the unsigned literal would do, with the two's complement of the value:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> -0x2\n0xfe\n\njulia> -0x0002\n0xfffe","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The minimum and maximum representable values of primitive numeric types such as integers are given by the typemin and typemax functions:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> (typemin(Int32), typemax(Int32))\n(-2147483648, 2147483647)\n\njulia> for T in [Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128]\n println(\"$(lpad(T,7)): [$(typemin(T)),$(typemax(T))]\")\n end\n Int8: [-128,127]\n Int16: [-32768,32767]\n Int32: [-2147483648,2147483647]\n Int64: [-9223372036854775808,9223372036854775807]\n Int128: [-170141183460469231731687303715884105728,170141183460469231731687303715884105727]\n UInt8: [0,255]\n UInt16: [0,65535]\n UInt32: [0,4294967295]\n UInt64: [0,18446744073709551615]\nUInt128: [0,340282366920938463463374607431768211455]","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The values returned by typemin and typemax are always of the given argument type. (The above expression uses several features that have yet to be introduced, including for loops, Strings, and Interpolation, but should be easy enough to understand for users with some existing programming experience.)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Overflow-behavior","page":"Integers and Floating-Point Numbers","title":"Overflow behavior","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"In Julia, exceeding the maximum representable value of a given type results in a wraparound behavior:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = typemax(Int64)\n9223372036854775807\n\njulia> x + 1\n-9223372036854775808\n\njulia> x + 1 == typemin(Int64)\ntrue","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Arithmetic operations with Julia's integer types inherently perform modular arithmetic, mirroring the characteristics of integer arithmetic on modern computer hardware. In scenarios where overflow is a possibility, it is crucial to explicitly check for wraparound effects that can result from such overflows. The Base.Checked module provides a suite of arithmetic operations equipped with overflow checks, which trigger errors if an overflow occurs. For use cases where overflow cannot be tolerated under any circumstances, utilizing the BigInt type, as detailed in Arbitrary Precision Arithmetic, is advisable.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"An example of overflow behavior and how to potentially resolve it is as follows:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 10^19\n-8446744073709551616\n\njulia> big(10)^19\n10000000000000000000","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Division-errors","page":"Integers and Floating-Point Numbers","title":"Division errors","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Integer division (the div function) has two exceptional cases: dividing by zero, and dividing the lowest negative number (typemin) by -1. Both of these cases throw a DivideError. The remainder and modulus functions (rem and mod) throw a DivideError when their second argument is zero.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Floating-Point-Numbers","page":"Integers and Floating-Point Numbers","title":"Floating-Point Numbers","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Literal floating-point numbers are represented in the standard formats, using E-notation when necessary:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 1.0\n1.0\n\njulia> 1.\n1.0\n\njulia> 0.5\n0.5\n\njulia> .5\n0.5\n\njulia> -1.23\n-1.23\n\njulia> 1e10\n1.0e10\n\njulia> 2.5e-4\n0.00025","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The above results are all Float64 values. Literal Float32 values can be entered by writing an f in place of e:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 0.5f0\n0.5f0\n\njulia> typeof(x)\nFloat32\n\njulia> 2.5f-4\n0.00025f0","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Values can be converted to Float32 easily:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = Float32(-1.5)\n-1.5f0\n\njulia> typeof(x)\nFloat32","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Hexadecimal floating-point literals are also valid, but only as Float64 values, with p preceding the base-2 exponent:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 0x1p0\n1.0\n\njulia> 0x1.8p3\n12.0\n\njulia> x = 0x.4p-1\n0.125\n\njulia> typeof(x)\nFloat64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Half-precision floating-point numbers are also supported (Float16), but they are implemented in software and use Float32 for calculations.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> sizeof(Float16(4.))\n2\n\njulia> 2*Float16(4.)\nFloat16(8.0)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The underscore _ can be used as digit separator:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010\n(10000, 5.0e-9, 0xdeadbeef, 0xb2)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Floating-point-zero","page":"Integers and Floating-Point Numbers","title":"Floating-point zero","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Floating-point numbers have two zeros, positive zero and negative zero. They are equal to each other but have different binary representations, as can be seen using the bitstring function:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 0.0 == -0.0\ntrue\n\njulia> bitstring(0.0)\n\"0000000000000000000000000000000000000000000000000000000000000000\"\n\njulia> bitstring(-0.0)\n\"1000000000000000000000000000000000000000000000000000000000000000\"","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Special-floating-point-values","page":"Integers and Floating-Point Numbers","title":"Special floating-point values","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"There are three specified standard floating-point values that do not correspond to any point on the real number line:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Float16 Float32 Float64 Name Description\nInf16 Inf32 Inf positive infinity a value greater than all finite floating-point values\n-Inf16 -Inf32 -Inf negative infinity a value less than all finite floating-point values\nNaN16 NaN32 NaN not a number a value not == to any floating-point value (including itself)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"For further discussion of how these non-finite floating-point values are ordered with respect to each other and other floats, see Numeric Comparisons. By the IEEE 754 standard, these floating-point values are the results of certain arithmetic operations:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 1/Inf\n0.0\n\njulia> 1/0\nInf\n\njulia> -5/0\n-Inf\n\njulia> 0.000001/0\nInf\n\njulia> 0/0\nNaN\n\njulia> 500 + Inf\nInf\n\njulia> 500 - Inf\n-Inf\n\njulia> Inf + Inf\nInf\n\njulia> Inf - Inf\nNaN\n\njulia> Inf * Inf\nInf\n\njulia> Inf / Inf\nNaN\n\njulia> 0 * Inf\nNaN\n\njulia> NaN == NaN\nfalse\n\njulia> NaN != NaN\ntrue\n\njulia> NaN < NaN\nfalse\n\njulia> NaN > NaN\nfalse","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The typemin and typemax functions also apply to floating-point types:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> (typemin(Float16),typemax(Float16))\n(-Inf16, Inf16)\n\njulia> (typemin(Float32),typemax(Float32))\n(-Inf32, Inf32)\n\njulia> (typemin(Float64),typemax(Float64))\n(-Inf, Inf)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Machine-epsilon","page":"Integers and Floating-Point Numbers","title":"Machine epsilon","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Most real numbers cannot be represented exactly with floating-point numbers, and so for many purposes it is important to know the distance between two adjacent representable floating-point numbers, which is often known as machine epsilon.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia provides eps, which gives the distance between 1.0 and the next larger representable floating-point value:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> eps(Float32)\n1.1920929f-7\n\njulia> eps(Float64)\n2.220446049250313e-16\n\njulia> eps() # same as eps(Float64)\n2.220446049250313e-16","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"These values are 2.0^-23 and 2.0^-52 as Float32 and Float64 values, respectively. The eps function can also take a floating-point value as an argument, and gives the absolute difference between that value and the next representable floating point value. That is, eps(x) yields a value of the same type as x such that x + eps(x) is the next representable floating-point value larger than x:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> eps(1.0)\n2.220446049250313e-16\n\njulia> eps(1000.)\n1.1368683772161603e-13\n\njulia> eps(1e-27)\n1.793662034335766e-43\n\njulia> eps(0.0)\n5.0e-324","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The distance between two adjacent representable floating-point numbers is not constant, but is smaller for smaller values and larger for larger values. In other words, the representable floating-point numbers are densest in the real number line near zero, and grow sparser exponentially as one moves farther away from zero. By definition, eps(1.0) is the same as eps(Float64) since 1.0 is a 64-bit floating-point value.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia also provides the nextfloat and prevfloat functions which return the next largest or smallest representable floating-point number to the argument respectively:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 1.25f0\n1.25f0\n\njulia> nextfloat(x)\n1.2500001f0\n\njulia> prevfloat(x)\n1.2499999f0\n\njulia> bitstring(prevfloat(x))\n\"00111111100111111111111111111111\"\n\njulia> bitstring(x)\n\"00111111101000000000000000000000\"\n\njulia> bitstring(nextfloat(x))\n\"00111111101000000000000000000001\"","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"This example highlights the general principle that the adjacent representable floating-point numbers also have adjacent binary integer representations.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Rounding-modes","page":"Integers and Floating-Point Numbers","title":"Rounding modes","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"If a number doesn't have an exact floating-point representation, it must be rounded to an appropriate representable value. However, the manner in which this rounding is done can be changed if required according to the rounding modes presented in the IEEE 754 standard.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The default mode used is always RoundNearest, which rounds to the nearest representable value, with ties rounded towards the nearest value with an even least significant bit.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Background-and-References","page":"Integers and Floating-Point Numbers","title":"Background and References","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Floating-point arithmetic entails many subtleties which can be surprising to users who are unfamiliar with the low-level implementation details. However, these subtleties are described in detail in most books on scientific computation, and also in the following references:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The definitive guide to floating point arithmetic is the IEEE 754-2008 Standard; however, it is not available for free online.\nFor a brief but lucid presentation of how floating-point numbers are represented, see John D. Cook's article on the subject as well as his introduction to some of the issues arising from how this representation differs in behavior from the idealized abstraction of real numbers.\nAlso recommended is Bruce Dawson's series of blog posts on floating-point numbers.\nFor an excellent, in-depth discussion of floating-point numbers and issues of numerical accuracy encountered when computing with them, see David Goldberg's paper What Every Computer Scientist Should Know About Floating-Point Arithmetic.\nFor even more extensive documentation of the history of, rationale for, and issues with floating-point numbers, as well as discussion of many other topics in numerical computing, see the collected writings of William Kahan, commonly known as the \"Father of Floating-Point\". Of particular interest may be An Interview with the Old Man of Floating-Point.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Arbitrary-Precision-Arithmetic","page":"Integers and Floating-Point Numbers","title":"Arbitrary Precision Arithmetic","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"To allow computations with arbitrary-precision integers and floating point numbers, Julia wraps the GNU Multiple Precision Arithmetic Library (GMP) and the GNU MPFR Library, respectively. The BigInt and BigFloat types are available in Julia for arbitrary precision integer and floating point numbers respectively.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Constructors exist to create these types from primitive numerical types, and the string literal @big_str or parse can be used to construct them from AbstractStrings. BigInts can also be input as integer literals when they are too big for other built-in integer types. Note that as there is no unsigned arbitrary-precision integer type in Base (BigInt is sufficient in most cases), hexadecimal, octal and binary literals can be used (in addition to decimal literals).","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Once created, they participate in arithmetic with all other numeric types thanks to Julia's type promotion and conversion mechanism:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> BigInt(typemax(Int64)) + 1\n9223372036854775808\n\njulia> big\"123456789012345678901234567890\" + 1\n123456789012345678901234567891\n\njulia> parse(BigInt, \"123456789012345678901234567890\") + 1\n123456789012345678901234567891\n\njulia> string(big\"2\"^200, base=16)\n\"100000000000000000000000000000000000000000000000000\"\n\njulia> 0x100000000000000000000000000000000-1 == typemax(UInt128)\ntrue\n\njulia> 0x000000000000000000000000000000000\n0\n\njulia> typeof(ans)\nBigInt\n\njulia> big\"1.23456789012345678901\"\n1.234567890123456789010000000000000000000000000000000000000000000000000000000004\n\njulia> parse(BigFloat, \"1.23456789012345678901\")\n1.234567890123456789010000000000000000000000000000000000000000000000000000000004\n\njulia> BigFloat(2.0^66) / 3\n2.459565876494606882133333333333333333333333333333333333333333333333333333333344e+19\n\njulia> factorial(BigInt(40))\n815915283247897734345611269596115894272000000000","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"However, type promotion between the primitive types above and BigInt/BigFloat is not automatic and must be explicitly stated.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = typemin(Int64)\n-9223372036854775808\n\njulia> x = x - 1\n9223372036854775807\n\njulia> typeof(x)\nInt64\n\njulia> y = BigInt(typemin(Int64))\n-9223372036854775808\n\njulia> y = y - 1\n-9223372036854775809\n\njulia> typeof(y)\nBigInt","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The default precision (in number of bits of the significand) and rounding mode of BigFloat operations can be changed globally by calling setprecision and setrounding, and all further calculations will take these changes in account. Alternatively, the precision or the rounding can be changed only within the execution of a particular block of code by using the same functions with a do block:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> setrounding(BigFloat, RoundUp) do\n BigFloat(1) + parse(BigFloat, \"0.1\")\n end\n1.100000000000000000000000000000000000000000000000000000000000000000000000000003\n\njulia> setrounding(BigFloat, RoundDown) do\n BigFloat(1) + parse(BigFloat, \"0.1\")\n end\n1.099999999999999999999999999999999999999999999999999999999999999999999999999986\n\njulia> setprecision(40) do\n BigFloat(1) + parse(BigFloat, \"0.1\")\n end\n1.1000000000004","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"warning: Warning\nThe relation between setprecision or setrounding and @big_str, the macro used for big string literals (such as big\"0.3\"), might not be intuitive, as a consequence of the fact that @big_str is a macro. See the @big_str documentation for details.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#man-numeric-literal-coefficients","page":"Integers and Floating-Point Numbers","title":"Numeric Literal Coefficients","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"To make common numeric formulae and expressions clearer, Julia allows variables to be immediately preceded by a numeric literal, implying multiplication. This makes writing polynomial expressions much cleaner:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 3\n3\n\njulia> 2x^2 - 3x + 1\n10\n\njulia> 1.5x^2 - .5x + 1\n13.0","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"It also makes writing exponential functions more elegant:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 2^2x\n64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The precedence of numeric literal coefficients is slightly lower than that of unary operators such as negation. So -2x is parsed as (-2) * x and √2x is parsed as (√2) * x. However, numeric literal coefficients parse similarly to unary operators when combined with exponentiation. For example 2^3x is parsed as 2^(3x), and 2x^3 is parsed as 2*(x^3).","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Numeric literals also work as coefficients to parenthesized expressions:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 2(x-1)^2 - 3(x-1) + 1\n3","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"note: Note\nThe precedence of numeric literal coefficients used for implicit multiplication is higher than other binary operators such as multiplication (*), and division (/, \\, and //). This means, for example, that 1 / 2im equals -0.5im and 6 // 2(2 + 1) equals 1 // 1.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Additionally, parenthesized expressions can be used as coefficients to variables, implying multiplication of the expression by the variable:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> (x-1)x\n6","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Neither juxtaposition of two parenthesized expressions, nor placing a variable before a parenthesized expression, however, can be used to imply multiplication:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> (x-1)(x+1)\nERROR: MethodError: objects of type Int64 are not callable\n\njulia> x(x+1)\nERROR: MethodError: objects of type Int64 are not callable","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Both expressions are interpreted as function application: any expression that is not a numeric literal, when immediately followed by a parenthetical, is interpreted as a function applied to the values in parentheses (see Functions for more about functions). Thus, in both of these cases, an error occurs since the left-hand value is not a function.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The above syntactic enhancements significantly reduce the visual noise incurred when writing common mathematical formulae. Note that no whitespace may come between a numeric literal coefficient and the identifier or parenthesized expression which it multiplies.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Syntax-Conflicts","page":"Integers and Floating-Point Numbers","title":"Syntax Conflicts","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Juxtaposed literal coefficient syntax may conflict with some numeric literal syntaxes: hexadecimal, octal and binary integer literals and engineering notation for floating-point literals. Here are some situations where syntactic conflicts arise:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The hexadecimal integer literal expression 0xff could be interpreted as the numeric literal 0 multiplied by the variable xff. Similar ambiguities arise with octal and binary literals like 0o777 or 0b01001010.\nThe floating-point literal expression 1e10 could be interpreted as the numeric literal 1 multiplied by the variable e10, and similarly with the equivalent E form.\nThe 32-bit floating-point literal expression 1.5f22 could be interpreted as the numeric literal 1.5 multiplied by the variable f22.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"In all cases the ambiguity is resolved in favor of interpretation as numeric literals:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Expressions starting with 0x/0o/0b are always hexadecimal/octal/binary literals.\nExpressions starting with a numeric literal followed by e or E are always floating-point literals.\nExpressions starting with a numeric literal followed by f are always 32-bit floating-point literals.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Unlike E, which is equivalent to e in numeric literals for historical reasons, F is just another letter and does not behave like f in numeric literals. Hence, expressions starting with a numeric literal followed by F are interpreted as the numerical literal multiplied by a variable, which means that, for example, 1.5F22 is equal to 1.5 * F22.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Literal-zero-and-one","page":"Integers and Floating-Point Numbers","title":"Literal zero and one","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia provides functions which return literal 0 and 1 corresponding to a specified type or the type of a given variable.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Function Description\nzero(x) Literal zero of type x or type of variable x\none(x) Literal one of type x or type of variable x","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"These functions are useful in Numeric Comparisons to avoid overhead from unnecessary type conversion.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Examples:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> zero(Float32)\n0.0f0\n\njulia> zero(1.0)\n0.0\n\njulia> one(Int32)\n1\n\njulia> one(BigFloat)\n1.0","category":"page"},{"location":"stdlib/Statistics/#Statistics","page":"Statistics","title":"Statistics","text":"","category":"section"},{"location":"stdlib/Statistics/","page":"Statistics","title":"Statistics","text":"The Statistics standard library module contains basic statistics functionality.","category":"page"},{"location":"stdlib/Statistics/","page":"Statistics","title":"Statistics","text":"std\nstdm\nvar\nvarm\ncor\ncov\nmean!\nmean\nmedian!\nmedian\nmiddle\nquantile!\nquantile","category":"page"},{"location":"stdlib/Statistics/#Statistics.std","page":"Statistics","title":"Statistics.std","text":"std(itr; corrected::Bool=true, mean=nothing[, dims])\n\nCompute the sample standard deviation of collection itr.\n\nThe algorithm returns an estimator of the generative distribution's standard deviation under the assumption that each entry of itr is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating sqrt(sum((itr .- mean(itr)).^2) / (length(itr) - 1)). If corrected is true, then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false with n the number of elements in itr.\n\nIf itr is an AbstractArray, dims can be provided to compute the standard deviation over dimensions.\n\nA pre-computed mean may be provided. When dims is specified, mean must be an array with the same shape as mean(itr, dims=dims) (additional trailing singleton dimensions are allowed).\n\nnote: Note\nIf array contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the standard deviation of non-missing values.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.stdm","page":"Statistics","title":"Statistics.stdm","text":"stdm(itr, mean; corrected::Bool=true[, dims])\n\nCompute the sample standard deviation of collection itr, with known mean(s) mean.\n\nThe algorithm returns an estimator of the generative distribution's standard deviation under the assumption that each entry of itr is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating sqrt(sum((itr .- mean(itr)).^2) / (length(itr) - 1)). If corrected is true, then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false with n the number of elements in itr.\n\nIf itr is an AbstractArray, dims can be provided to compute the standard deviation over dimensions. In that case, mean must be an array with the same shape as mean(itr, dims=dims) (additional trailing singleton dimensions are allowed).\n\nnote: Note\nIf array contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the standard deviation of non-missing values.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.var","page":"Statistics","title":"Statistics.var","text":"var(itr; corrected::Bool=true, mean=nothing[, dims])\n\nCompute the sample variance of collection itr.\n\nThe algorithm returns an estimator of the generative distribution's variance under the assumption that each entry of itr is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating sum((itr .- mean(itr)).^2) / (length(itr) - 1). If corrected is true, then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false where n is the number of elements in itr.\n\nIf itr is an AbstractArray, dims can be provided to compute the variance over dimensions.\n\nA pre-computed mean may be provided. When dims is specified, mean must be an array with the same shape as mean(itr, dims=dims) (additional trailing singleton dimensions are allowed).\n\nnote: Note\nIf array contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the variance of non-missing values.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.varm","page":"Statistics","title":"Statistics.varm","text":"varm(itr, mean; dims, corrected::Bool=true)\n\nCompute the sample variance of collection itr, with known mean(s) mean.\n\nThe algorithm returns an estimator of the generative distribution's variance under the assumption that each entry of itr is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating sum((itr .- mean(itr)).^2) / (length(itr) - 1). If corrected is true, then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false with n the number of elements in itr.\n\nIf itr is an AbstractArray, dims can be provided to compute the variance over dimensions. In that case, mean must be an array with the same shape as mean(itr, dims=dims) (additional trailing singleton dimensions are allowed).\n\nnote: Note\nIf array contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the variance of non-missing values.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.cor","page":"Statistics","title":"Statistics.cor","text":"cor(x::AbstractVector)\n\nReturn the number one.\n\n\n\n\n\ncor(X::AbstractMatrix; dims::Int=1)\n\nCompute the Pearson correlation matrix of the matrix X along the dimension dims.\n\n\n\n\n\ncor(x::AbstractVector, y::AbstractVector)\n\nCompute the Pearson correlation between the vectors x and y.\n\n\n\n\n\ncor(X::AbstractVecOrMat, Y::AbstractVecOrMat; dims=1)\n\nCompute the Pearson correlation between the vectors or matrices X and Y along the dimension dims.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.cov","page":"Statistics","title":"Statistics.cov","text":"cov(x::AbstractVector; corrected::Bool=true)\n\nCompute the variance of the vector x. If corrected is true (the default) then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false where n = length(x).\n\n\n\n\n\ncov(X::AbstractMatrix; dims::Int=1, corrected::Bool=true)\n\nCompute the covariance matrix of the matrix X along the dimension dims. If corrected is true (the default) then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false where n = size(X, dims).\n\n\n\n\n\ncov(x::AbstractVector, y::AbstractVector; corrected::Bool=true)\n\nCompute the covariance between the vectors x and y. If corrected is true (the default), computes frac1n-1sum_i=1^n (x_i-bar x) (y_i-bar y)^* where * denotes the complex conjugate and n = length(x) = length(y). If corrected is false, computes frac1nsum_i=1^n (x_i-bar x) (y_i-bar y)^*.\n\n\n\n\n\ncov(X::AbstractVecOrMat, Y::AbstractVecOrMat; dims::Int=1, corrected::Bool=true)\n\nCompute the covariance between the vectors or matrices X and Y along the dimension dims. If corrected is true (the default) then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false where n = size(X, dims) = size(Y, dims).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.mean!","page":"Statistics","title":"Statistics.mean!","text":"mean!(r, v)\n\nCompute the mean of v over the singleton dimensions of r, and write results to r.\n\nExamples\n\njulia> using Statistics\n\njulia> v = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> mean!([1., 1.], v)\n2-element Vector{Float64}:\n 1.5\n 3.5\n\njulia> mean!([1. 1.], v)\n1×2 Matrix{Float64}:\n 2.0 3.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.mean","page":"Statistics","title":"Statistics.mean","text":"mean(itr)\n\nCompute the mean of all elements in a collection.\n\nnote: Note\nIf itr contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the mean of non-missing values.\n\nExamples\n\njulia> using Statistics\n\njulia> mean(1:20)\n10.5\n\njulia> mean([1, missing, 3])\nmissing\n\njulia> mean(skipmissing([1, missing, 3]))\n2.0\n\n\n\n\n\nmean(f, itr)\n\nApply the function f to each element of collection itr and take the mean.\n\njulia> using Statistics\n\njulia> mean(√, [1, 2, 3])\n1.3820881233139908\n\njulia> mean([√1, √2, √3])\n1.3820881233139908\n\n\n\n\n\nmean(f, A::AbstractArray; dims)\n\nApply the function f to each element of array A and take the mean over dimensions dims.\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\njulia> using Statistics\n\njulia> mean(√, [1, 2, 3])\n1.3820881233139908\n\njulia> mean([√1, √2, √3])\n1.3820881233139908\n\njulia> mean(√, [1 2 3; 4 5 6], dims=2)\n2×1 Matrix{Float64}:\n 1.3820881233139908\n 2.2285192400943226\n\n\n\n\n\nmean(A::AbstractArray; dims)\n\nCompute the mean of an array over the given dimensions.\n\ncompat: Julia 1.1\nmean for empty arrays requires at least Julia 1.1.\n\nExamples\n\njulia> using Statistics\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> mean(A, dims=1)\n1×2 Matrix{Float64}:\n 2.0 3.0\n\njulia> mean(A, dims=2)\n2×1 Matrix{Float64}:\n 1.5\n 3.5\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.median!","page":"Statistics","title":"Statistics.median!","text":"median!(v)\n\nLike median, but may overwrite the input vector.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.median","page":"Statistics","title":"Statistics.median","text":"median(itr)\n\nCompute the median of all elements in a collection. For an even number of elements no exact median element exists, so the result is equivalent to calculating mean of two median elements.\n\nnote: Note\nIf itr contains NaN or missing values, the result is also NaN or missing (missing takes precedence if itr contains both). Use the skipmissing function to omit missing entries and compute the median of non-missing values.\n\nExamples\n\njulia> using Statistics\n\njulia> median([1, 2, 3])\n2.0\n\njulia> median([1, 2, 3, 4])\n2.5\n\njulia> median([1, 2, missing, 4])\nmissing\n\njulia> median(skipmissing([1, 2, missing, 4]))\n2.0\n\n\n\n\n\nmedian(A::AbstractArray; dims)\n\nCompute the median of an array along the given dimensions.\n\nExamples\n\njulia> using Statistics\n\njulia> median([1 2; 3 4], dims=1)\n1×2 Matrix{Float64}:\n 2.0 3.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.middle","page":"Statistics","title":"Statistics.middle","text":"middle(x)\n\nCompute the middle of a scalar value, which is equivalent to x itself, but of the type of middle(x, x) for consistency.\n\n\n\n\n\nmiddle(x, y)\n\nCompute the middle of two numbers x and y, which is equivalent in both value and type to computing their mean ((x + y) / 2).\n\n\n\n\n\nmiddle(a::AbstractArray)\n\nCompute the middle of an array a, which consists of finding its extrema and then computing their mean.\n\njulia> using Statistics\n\njulia> middle(1:10)\n5.5\n\njulia> a = [1,2,3.6,10.9]\n4-element Vector{Float64}:\n 1.0\n 2.0\n 3.6\n 10.9\n\njulia> middle(a)\n5.95\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.quantile!","page":"Statistics","title":"Statistics.quantile!","text":"quantile!([q::AbstractArray, ] v::AbstractVector, p; sorted=false, alpha::Real=1.0, beta::Real=alpha)\n\nCompute the quantile(s) of a vector v at a specified probability or vector or tuple of probabilities p on the interval [0,1]. If p is a vector, an optional output array q may also be specified. (If not provided, a new output array is created.) The keyword argument sorted indicates whether v can be assumed to be sorted; if false (the default), then the elements of v will be partially sorted in-place.\n\nSamples quantile are defined by Q(p) = (1-γ)*x[j] + γ*x[j+1], where x[j] is the j-th order statistic of v, j = floor(n*p + m), m = alpha + p*(1 - alpha - beta) and γ = n*p + m - j.\n\nBy default (alpha = beta = 1), quantiles are computed via linear interpolation between the points ((k-1)/(n-1), x[k]), for k = 1:n where n = length(v). This corresponds to Definition 7 of Hyndman and Fan (1996), and is the same as the R and NumPy default.\n\nThe keyword arguments alpha and beta correspond to the same parameters in Hyndman and Fan, setting them to different values allows to calculate quantiles with any of the methods 4-9 defined in this paper:\n\nDef. 4: alpha=0, beta=1\nDef. 5: alpha=0.5, beta=0.5 (MATLAB default)\nDef. 6: alpha=0, beta=0 (Excel PERCENTILE.EXC, Python default, Stata altdef)\nDef. 7: alpha=1, beta=1 (Julia, R and NumPy default, Excel PERCENTILE and PERCENTILE.INC, Python 'inclusive')\nDef. 8: alpha=1/3, beta=1/3\nDef. 9: alpha=3/8, beta=3/8\n\nnote: Note\nAn ArgumentError is thrown if v contains NaN or missing values.\n\nReferences\n\nHyndman, R.J and Fan, Y. (1996) \"Sample Quantiles in Statistical Packages\", The American Statistician, Vol. 50, No. 4, pp. 361-365\nQuantile on Wikipedia details the different quantile definitions\n\nExamples\n\njulia> using Statistics\n\njulia> x = [3, 2, 1];\n\njulia> quantile!(x, 0.5)\n2.0\n\njulia> x\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> y = zeros(3);\n\njulia> quantile!(y, x, [0.1, 0.5, 0.9]) === y\ntrue\n\njulia> y\n3-element Vector{Float64}:\n 1.2000000000000002\n 2.0\n 2.8000000000000003\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.quantile","page":"Statistics","title":"Statistics.quantile","text":"quantile(itr, p; sorted=false, alpha::Real=1.0, beta::Real=alpha)\n\nCompute the quantile(s) of a collection itr at a specified probability or vector or tuple of probabilities p on the interval [0,1]. The keyword argument sorted indicates whether itr can be assumed to be sorted.\n\nSamples quantile are defined by Q(p) = (1-γ)*x[j] + γ*x[j+1], where x[j] is the j-th order statistic of itr, j = floor(n*p + m), m = alpha + p*(1 - alpha - beta) and γ = n*p + m - j.\n\nBy default (alpha = beta = 1), quantiles are computed via linear interpolation between the points ((k-1)/(n-1), x[k]), for k = 1:n where n = length(itr). This corresponds to Definition 7 of Hyndman and Fan (1996), and is the same as the R and NumPy default.\n\nThe keyword arguments alpha and beta correspond to the same parameters in Hyndman and Fan, setting them to different values allows to calculate quantiles with any of the methods 4-9 defined in this paper:\n\nDef. 4: alpha=0, beta=1\nDef. 5: alpha=0.5, beta=0.5 (MATLAB default)\nDef. 6: alpha=0, beta=0 (Excel PERCENTILE.EXC, Python default, Stata altdef)\nDef. 7: alpha=1, beta=1 (Julia, R and NumPy default, Excel PERCENTILE and PERCENTILE.INC, Python 'inclusive')\nDef. 8: alpha=1/3, beta=1/3\nDef. 9: alpha=3/8, beta=3/8\n\nnote: Note\nAn ArgumentError is thrown if v contains NaN or missing values. Use the skipmissing function to omit missing entries and compute the quantiles of non-missing values.\n\nReferences\n\nHyndman, R.J and Fan, Y. (1996) \"Sample Quantiles in Statistical Packages\", The American Statistician, Vol. 50, No. 4, pp. 361-365\nQuantile on Wikipedia details the different quantile definitions\n\nExamples\n\njulia> using Statistics\n\njulia> quantile(0:20, 0.5)\n10.0\n\njulia> quantile(0:20, [0.1, 0.5, 0.9])\n3-element Vector{Float64}:\n 2.0\n 10.0\n 18.000000000000004\n\njulia> quantile(skipmissing([1, 10, missing]), 0.5)\n5.5\n\n\n\n\n\n","category":"function"},{"location":"devdocs/require/#Module-loading","page":"Module loading","title":"Module loading","text":"","category":"section"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"Base.require is responsible for loading modules and it also manages the precompilation cache. It is the implementation of the import statement.","category":"page"},{"location":"devdocs/require/#Experimental-features","page":"Module loading","title":"Experimental features","text":"","category":"section"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"The features below are experimental and not part of the stable Julia API. Before building upon them inform yourself about the current thinking and whether they might change soon.","category":"page"},{"location":"devdocs/require/#Package-loading-callbacks","page":"Module loading","title":"Package loading callbacks","text":"","category":"section"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"It is possible to listen to the packages loaded by Base.require, by registering a callback.","category":"page"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"loaded_packages = Base.PkgId[]\ncallback = (pkg::Base.PkgId) -> push!(loaded_packages, pkg)\npush!(Base.package_callbacks, callback)","category":"page"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"Using this would look something like:","category":"page"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"julia> using Example\n\njulia> loaded_packages\n1-element Vector{Base.PkgId}:\n Example [7876af07-990d-54b4-ab0e-23690620f79a]","category":"page"},{"location":"manual/embedding/#Embedding-Julia","page":"Embedding Julia","title":"Embedding Julia","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As we have seen in Calling C and Fortran Code, Julia has a simple and efficient way to call functions written in C. But there are situations where the opposite is needed: calling Julia functions from C code. This can be used to integrate Julia code into a larger C/C++ project, without the need to rewrite everything in C/C++. Julia has a C API to make this possible. As almost all programming languages have some way to call C functions, the Julia C API can also be used to build further language bridges (e.g. calling Julia from Python, Rust or C#). Even though Rust and C++ can use the C embedding API directly, both have packages helping with it, for C++ Jluna is useful.","category":"page"},{"location":"manual/embedding/#High-Level-Embedding","page":"Embedding Julia","title":"High-Level Embedding","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Note: This section covers embedding Julia code in C on Unix-like operating systems. For doing this on Windows, please see the section following this, High-Level Embedding on Windows with Visual Studio.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"We start with a simple C program that initializes Julia and calls some Julia code:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"#include \nJULIA_DEFINE_FAST_TLS // only define this once, in an executable (not in a shared library) if you want fast code.\n\nint main(int argc, char *argv[])\n{\n /* required: setup the Julia context */\n jl_init();\n\n /* run Julia commands */\n jl_eval_string(\"print(sqrt(2.0))\");\n\n /* strongly recommended: notify Julia that the\n program is about to terminate. this allows\n Julia time to cleanup pending write requests\n and run all finalizers\n */\n jl_atexit_hook(0);\n return 0;\n}","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In order to build this program you must add the path to the Julia header to the include path and link against libjulia. For instance, when Julia is installed to $JULIA_DIR, one can compile the above test program test.c with gcc using:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"gcc -o test -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib -Wl,-rpath,$JULIA_DIR/lib test.c -ljulia","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Alternatively, look at the embedding.c program in the Julia source tree in the test/embedding/ folder. The file cli/loader_exe.c program is another simple example of how to set jl_options options while linking against libjulia.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The first thing that must be done before calling any other Julia C function is to initialize Julia. This is done by calling jl_init, which tries to automatically determine Julia's install location. If you need to specify a custom location, or specify which system image to load, use jl_init_with_image instead.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The second statement in the test program evaluates a Julia statement using a call to jl_eval_string.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Before the program terminates, it is strongly recommended that jl_atexit_hook is called. The above example program calls this just before returning from main.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"note: Note\nCurrently, dynamically linking with the libjulia shared library requires passing the RTLD_GLOBAL option. In Python, this looks like:>>> julia=CDLL('./libjulia.dylib',RTLD_GLOBAL)\n>>> julia.jl_init.argtypes = []\n>>> julia.jl_init()\n250593296","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"note: Note\nIf the julia program needs to access symbols from the main executable, it may be necessary to add the -Wl,--export-dynamic linker flag at compile time on Linux in addition to the ones generated by julia-config.jl described below. This is not necessary when compiling a shared library.","category":"page"},{"location":"manual/embedding/#Using-julia-config-to-automatically-determine-build-parameters","page":"Embedding Julia","title":"Using julia-config to automatically determine build parameters","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The script julia-config.jl was created to aid in determining what build parameters are required by a program that uses embedded Julia. This script uses the build parameters and system configuration of the particular Julia distribution it is invoked by to export the necessary compiler flags for an embedding program to interact with that distribution. This script is located in the Julia shared data directory.","category":"page"},{"location":"manual/embedding/#Example","page":"Embedding Julia","title":"Example","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"#include \n\nint main(int argc, char *argv[])\n{\n jl_init();\n (void)jl_eval_string(\"println(sqrt(2.0))\");\n jl_atexit_hook(0);\n return 0;\n}","category":"page"},{"location":"manual/embedding/#On-the-command-line","page":"Embedding Julia","title":"On the command line","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"A simple use of this script is from the command line. Assuming that julia-config.jl is located in /usr/local/julia/share/julia, it can be invoked on the command line directly and takes any combination of three flags:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"/usr/local/julia/share/julia/julia-config.jl\nUsage: julia-config [--cflags|--ldflags|--ldlibs]","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If the above example source is saved in the file embed_example.c, then the following command will compile it into an executable program on Linux and Windows (MSYS2 environment). On macOS, substitute clang for gcc.:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"/usr/local/julia/share/julia/julia-config.jl --cflags --ldflags --ldlibs | xargs gcc embed_example.c","category":"page"},{"location":"manual/embedding/#Use-in-Makefiles","page":"Embedding Julia","title":"Use in Makefiles","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In general, embedding projects will be more complicated than the above example, and so the following allows general makefile support as well – assuming GNU make because of the use of the shell macro expansions. Furthermore, although julia-config.jl is usually in the /usr/local directory, if it isn't, then Julia itself can be used to find julia-config.jl, and the makefile can take advantage of this. The above example is extended to use a makefile:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"JL_SHARE = $(shell julia -e 'print(joinpath(Sys.BINDIR, Base.DATAROOTDIR, \"julia\"))')\nCFLAGS += $(shell $(JL_SHARE)/julia-config.jl --cflags)\nCXXFLAGS += $(shell $(JL_SHARE)/julia-config.jl --cflags)\nLDFLAGS += $(shell $(JL_SHARE)/julia-config.jl --ldflags)\nLDLIBS += $(shell $(JL_SHARE)/julia-config.jl --ldlibs)\n\nall: embed_example","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Now the build command is simply make.","category":"page"},{"location":"manual/embedding/#High-Level-Embedding-on-Windows-with-Visual-Studio","page":"Embedding Julia","title":"High-Level Embedding on Windows with Visual Studio","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If the JULIA_DIR environment variable hasn't been setup, add it using the System panel before starting Visual Studio. The bin folder under JULIA_DIR should be on the system PATH.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"We start by opening Visual Studio and creating a new Console Application project. Open the 'stdafx.h' header file, and add the following lines at the end:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"#include ","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Then, replace the main() function in the project with this code:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"int main(int argc, char *argv[])\n{\n /* required: setup the Julia context */\n jl_init();\n\n /* run Julia commands */\n jl_eval_string(\"print(sqrt(2.0))\");\n\n /* strongly recommended: notify Julia that the\n program is about to terminate. this allows\n Julia time to cleanup pending write requests\n and run all finalizers\n */\n jl_atexit_hook(0);\n return 0;\n}","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The next step is to set up the project to find the Julia include files and the libraries. It's important to know whether the Julia installation is 32- or 64-bit. Remove any platform configuration that doesn't correspond to the Julia installation before proceeding.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Using the project Properties dialog, go to C/C++ | General and add $(JULIA_DIR)\\include\\julia\\ to the Additional Include Directories property. Then, go to the Linker | General section and add $(JULIA_DIR)\\lib to the Additional Library Directories property. Finally, under Linker | Input, add libjulia.dll.a;libopenlibm.dll.a; to the list of libraries.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"At this point, the project should build and run.","category":"page"},{"location":"manual/embedding/#Converting-Types","page":"Embedding Julia","title":"Converting Types","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Real applications will not only need to execute expressions, but also return their values to the host program. jl_eval_string returns a jl_value_t*, which is a pointer to a heap-allocated Julia object. Storing simple data types like Float64 in this way is called boxing, and extracting the stored primitive data is called unboxing. Our improved sample program that calculates the square root of 2 in Julia and reads back the result in C has a body that now contains this code:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *ret = jl_eval_string(\"sqrt(2.0)\");\n\nif (jl_typeis(ret, jl_float64_type)) {\n double ret_unboxed = jl_unbox_float64(ret);\n printf(\"sqrt(2.0) in C: %e \\n\", ret_unboxed);\n}\nelse {\n printf(\"ERROR: unexpected return type from sqrt(::Float64)\\n\");\n}","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In order to check whether ret is of a specific Julia type, we can use the jl_isa, jl_typeis, or jl_is_... functions. By typing typeof(sqrt(2.0)) into the Julia shell we can see that the return type is Float64 (double in C). To convert the boxed Julia value into a C double the jl_unbox_float64 function is used in the above code snippet.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Corresponding jl_box_... functions are used to convert the other way:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *a = jl_box_float64(3.0);\njl_value_t *b = jl_box_float32(3.0f);\njl_value_t *c = jl_box_int32(3);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As we will see next, boxing is required to call Julia functions with specific arguments.","category":"page"},{"location":"manual/embedding/#Calling-Julia-Functions","page":"Embedding Julia","title":"Calling Julia Functions","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"While jl_eval_string allows C to obtain the result of a Julia expression, it does not allow passing arguments computed in C to Julia. For this you will need to invoke Julia functions directly, using jl_call:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_function_t *func = jl_get_function(jl_base_module, \"sqrt\");\njl_value_t *argument = jl_box_float64(2.0);\njl_value_t *ret = jl_call1(func, argument);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In the first step, a handle to the Julia function sqrt is retrieved by calling jl_get_function. The first argument passed to jl_get_function is a pointer to the Base module in which sqrt is defined. Then, the double value is boxed using jl_box_float64. Finally, in the last step, the function is called using jl_call1. jl_call0, jl_call2, and jl_call3 functions also exist, to conveniently handle different numbers of arguments. To pass more arguments, use jl_call:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs)","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Its second argument args is an array of jl_value_t* arguments and nargs is the number of arguments.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"There is also an alternative, possibly simpler, way of calling Julia functions and that is via @cfunction. Using @cfunction allows you to do the type conversions on the Julia side, which is typically easier than doing it on the C side. The sqrt example above would with @cfunction be written as:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"double (*sqrt_jl)(double) = jl_unbox_voidpointer(jl_eval_string(\"@cfunction(sqrt, Float64, (Float64,))\"));\ndouble ret = sqrt_jl(2.0);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"where we first define a C callable function in Julia, extract the function pointer from it, and finally call it. In addition to simplifying type conversions by doing them in the higher-level language, calling Julia functions via @cfunction pointers eliminates the dynamic-dispatch overhead required by jl_call (for which all of the arguments are \"boxed\"), and should have performance equivalent to native C function pointers.","category":"page"},{"location":"manual/embedding/#Memory-Management","page":"Embedding Julia","title":"Memory Management","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As we have seen, Julia objects are represented in C as pointers of type jl_value_t*. This raises the question of who is responsible for freeing these objects.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Typically, Julia objects are freed by the garbage collector (GC), but the GC does not automatically know that we are holding a reference to a Julia value from C. This means the GC can free objects out from under you, rendering pointers invalid.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The GC will only run when new Julia objects are being allocated. Calls like jl_box_float64 perform allocation, but allocation might also happen at any point in running Julia code.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"When writing code that embeds Julia, it is generally safe to use jl_value_t* values in between jl_... calls (as GC will only get triggered by those calls). But in order to make sure that values can survive jl_... calls, we have to tell Julia that we still hold a reference to Julia root values, a process called \"GC rooting\". Rooting a value will ensure that the garbage collector does not accidentally identify this value as unused and free the memory backing that value. This can be done using the JL_GC_PUSH macros:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *ret = jl_eval_string(\"sqrt(2.0)\");\nJL_GC_PUSH1(&ret);\n// Do something with ret\nJL_GC_POP();","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The JL_GC_POP call releases the references established by the previous JL_GC_PUSH. Note that JL_GC_PUSH stores references on the C stack, so it must be exactly paired with a JL_GC_POP before the scope is exited. That is, before the function returns, or control flow otherwise leaves the block in which the JL_GC_PUSH was invoked.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Several Julia values can be pushed at once using the JL_GC_PUSH2 to JL_GC_PUSH6 macros:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"JL_GC_PUSH2(&ret1, &ret2);\n// ...\nJL_GC_PUSH6(&ret1, &ret2, &ret3, &ret4, &ret5, &ret6);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"To push an array of Julia values one can use the JL_GC_PUSHARGS macro, which can be used as follows:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t **args;\nJL_GC_PUSHARGS(args, 2); // args can now hold 2 `jl_value_t*` objects\nargs[0] = some_value;\nargs[1] = some_other_value;\n// Do something with args (e.g. call jl_... functions)\nJL_GC_POP();","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Each scope must have only one call to JL_GC_PUSH*, and should be paired with only a single JL_GC_POP call. If all necessary variables you want to root cannot be pushed by a one single call to JL_GC_PUSH*, or if there are more than 6 variables to be pushed and using an array of arguments is not an option, then one can use inner blocks:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *ret1 = jl_eval_string(\"sqrt(2.0)\");\nJL_GC_PUSH1(&ret1);\njl_value_t *ret2 = 0;\n{\n jl_function_t *func = jl_get_function(jl_base_module, \"exp\");\n ret2 = jl_call1(func, ret1);\n JL_GC_PUSH1(&ret2);\n // Do something with ret2.\n JL_GC_POP(); // This pops ret2.\n}\nJL_GC_POP(); // This pops ret1.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Note that it is not necessary to have valid jl_value_t* values before calling JL_GC_PUSH*. It is fine to have a number of them initialized to NULL, pass those to JL_GC_PUSH* and then create the actual Julia values. For example:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *ret1 = NULL, *ret2 = NULL;\nJL_GC_PUSH2(&ret1, &ret2);\nret1 = jl_eval_string(\"sqrt(2.0)\");\nret2 = jl_eval_string(\"sqrt(3.0)\");\n// Use ret1 and ret2\nJL_GC_POP();","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If it is required to hold the pointer to a variable between functions (or block scopes), then it is not possible to use JL_GC_PUSH*. In this case, it is necessary to create and keep a reference to the variable in the Julia global scope. One simple way to accomplish this is to use a global IdDict that will hold the references, avoiding deallocation by the GC. However, this method will only work properly with mutable types.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"// This functions shall be executed only once, during the initialization.\njl_value_t* refs = jl_eval_string(\"refs = IdDict()\");\njl_function_t* setindex = jl_get_function(jl_base_module, \"setindex!\");\n\n...\n\n// `var` is the variable we want to protect between function calls.\njl_value_t* var = 0;\n\n...\n\n// `var` is a `Vector{Float64}`, which is mutable.\nvar = jl_eval_string(\"[sqrt(2.0); sqrt(4.0); sqrt(6.0)]\");\n\n// To protect `var`, add its reference to `refs`.\njl_call3(setindex, refs, var, var);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If the variable is immutable, then it needs to be wrapped in an equivalent mutable container or, preferably, in a RefValue{Any} before it is pushed to IdDict. In this approach, the container has to be created or filled in via C code using, for example, the function jl_new_struct. If the container is created by jl_call*, then you will need to reload the pointer to be used in C code.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"// This functions shall be executed only once, during the initialization.\njl_value_t* refs = jl_eval_string(\"refs = IdDict()\");\njl_function_t* setindex = jl_get_function(jl_base_module, \"setindex!\");\njl_datatype_t* reft = (jl_datatype_t*)jl_eval_string(\"Base.RefValue{Any}\");\n\n...\n\n// `var` is the variable we want to protect between function calls.\njl_value_t* var = 0;\n\n...\n\n// `var` is a `Float64`, which is immutable.\nvar = jl_eval_string(\"sqrt(2.0)\");\n\n// Protect `var` until we add its reference to `refs`.\nJL_GC_PUSH1(&var);\n\n// Wrap `var` in `RefValue{Any}` and push to `refs` to protect it.\njl_value_t* rvar = jl_new_struct(reft, var);\nJL_GC_POP();\n\njl_call3(setindex, refs, rvar, rvar);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The GC can be allowed to deallocate a variable by removing the reference to it from refs using the function delete!, provided that no other reference to the variable is kept anywhere:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_function_t* delete = jl_get_function(jl_base_module, \"delete!\");\njl_call2(delete, refs, rvar);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As an alternative for very simple cases, it is possible to just create a global container of type Vector{Any} and fetch the elements from that when necessary, or even to create one global variable per pointer using","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_module_t *mod = jl_main_module;\njl_sym_t *var = jl_symbol(\"var\");\njl_binding_t *bp = jl_get_binding_wr(mod, var);\njl_checked_assignment(bp, mod, var, val);","category":"page"},{"location":"manual/embedding/#Updating-fields-of-GC-managed-objects","page":"Embedding Julia","title":"Updating fields of GC-managed objects","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The garbage collector also operates under the assumption that it is aware of every older-generation object pointing to a younger-generation one. Any time a pointer is updated breaking that assumption, it must be signaled to the collector with the jl_gc_wb (write barrier) function like so:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *parent = some_old_value, *child = some_young_value;\n((some_specific_type*)parent)->field = child;\njl_gc_wb(parent, child);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"It is in general impossible to predict which values will be old at runtime, so the write barrier must be inserted after all explicit stores. One notable exception is if the parent object has just been allocated and no garbage collection has run since then. Note that most jl_... functions can sometimes invoke garbage collection.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The write barrier is also necessary for arrays of pointers when updating their data directly. Calling jl_array_ptr_set is usually much preferred. But direct updates can be done. For example:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_array_t *some_array = ...; // e.g. a Vector{Any}\nvoid **data = jl_array_data(some_array, void*);\njl_value_t *some_value = ...;\ndata[0] = some_value;\njl_gc_wb(jl_array_owner(some_array), some_value);","category":"page"},{"location":"manual/embedding/#Controlling-the-Garbage-Collector","page":"Embedding Julia","title":"Controlling the Garbage Collector","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"There are some functions to control the GC. In normal use cases, these should not be necessary.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Function Description\njl_gc_collect() Force a GC run\njl_gc_enable(0) Disable the GC, return previous state as int\njl_gc_enable(1) Enable the GC, return previous state as int\njl_gc_is_enabled() Return current state as int","category":"page"},{"location":"manual/embedding/#Working-with-Arrays","page":"Embedding Julia","title":"Working with Arrays","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Julia and C can share array data without copying. The next example will show how this works.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Julia arrays are represented in C by the datatype jl_array_t*. Basically, jl_array_t is a struct that contains:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Information about the datatype\nA pointer to the data block\nInformation about the sizes of the array","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"To keep things simple, we start with a 1D array. Creating an array containing Float64 elements of length 10 can be done like this:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1);\njl_array_t* x = jl_alloc_array_1d(array_type, 10);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Alternatively, if you have already allocated the array you can generate a thin wrapper around its data:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"double *existingArray = (double*)malloc(sizeof(double)*10);\njl_array_t *x = jl_ptr_to_array_1d(array_type, existingArray, 10, 0);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The last argument is a boolean indicating whether Julia should take ownership of the data. If this argument is non-zero, the GC will call free on the data pointer when the array is no longer referenced.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In order to access the data of x, we can use jl_array_data:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"double *xData = jl_array_data(x, double);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Now we can fill the array:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"for (size_t i = 0; i < jl_array_nrows(x); i++)\n xData[i] = i;","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Now let us call a Julia function that performs an in-place operation on x:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_function_t *func = jl_get_function(jl_base_module, \"reverse!\");\njl_call1(func, (jl_value_t*)x);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"By printing the array, one can verify that the elements of x are now reversed.","category":"page"},{"location":"manual/embedding/#Accessing-Returned-Arrays","page":"Embedding Julia","title":"Accessing Returned Arrays","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If a Julia function returns an array, the return value of jl_eval_string and jl_call can be cast to a jl_array_t*:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_function_t *func = jl_get_function(jl_base_module, \"reverse\");\njl_array_t *y = (jl_array_t*)jl_call1(func, (jl_value_t*)x);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Now the content of y can be accessed as before using jl_array_data. As always, be sure to keep a reference to the array while it is in use.","category":"page"},{"location":"manual/embedding/#Multidimensional-Arrays","page":"Embedding Julia","title":"Multidimensional Arrays","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Julia's multidimensional arrays are stored in memory in column-major order. Here is some code that creates a 2D array and accesses its properties:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"// Create 2D array of float64 type\njl_value_t *array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 2);\nint dims[] = {10,5};\njl_array_t *x = jl_alloc_array_nd(array_type, dims, 2);\n\n// Get array pointer\ndouble *p = jl_array_data(x, double);\n// Get number of dimensions\nint ndims = jl_array_ndims(x);\n// Get the size of the i-th dim\nsize_t size0 = jl_array_dim(x,0);\nsize_t size1 = jl_array_dim(x,1);\n\n// Fill array with data\nfor(size_t i=0; i\nJULIA_DEFINE_FAST_TLS\n\ndouble c_func(int i)\n{\n printf(\"[C %08x] i = %d\\n\", pthread_self(), i);\n\n // Call the Julia sqrt() function to compute the square root of i, and return it\n jl_function_t *sqrt = jl_get_function(jl_base_module, \"sqrt\");\n jl_value_t* arg = jl_box_int32(i);\n double ret = jl_unbox_float64(jl_call1(sqrt, arg));\n\n return ret;\n}\n\nint main()\n{\n jl_init();\n\n // Define a Julia function func() that calls our c_func() defined in C above\n jl_eval_string(\"func(i) = ccall(:c_func, Float64, (Int32,), i)\");\n\n // Call func() multiple times, using multiple threads to do so\n jl_eval_string(\"println(Threads.threadpoolsize())\");\n jl_eval_string(\"use(i) = println(\\\"[J $(Threads.threadid())] i = $(i) -> $(func(i))\\\")\");\n jl_eval_string(\"Threads.@threads for i in 1:5 use(i) end\");\n\n jl_atexit_hook(0);\n}","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If we run this code with 2 Julia threads we get the following output (note: the output will vary per run and system):","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"$ JULIA_NUM_THREADS=2 ./thread_example\n2\n[C 3bfd9c00] i = 1\n[C 23938640] i = 4\n[J 1] i = 1 -> 1.0\n[C 3bfd9c00] i = 2\n[J 1] i = 2 -> 1.4142135623730951\n[C 3bfd9c00] i = 3\n[J 2] i = 4 -> 2.0\n[C 23938640] i = 5\n[J 1] i = 3 -> 1.7320508075688772\n[J 2] i = 5 -> 2.23606797749979","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As can be seen, Julia thread 1 corresponds to pthread ID 3bfd9c00, and Julia thread 2 corresponds to ID 23938640, showing that indeed multiple threads are used at the C level, and that we can safely call Julia C API routines from those threads.","category":"page"},{"location":"devdocs/backtraces/#Reporting-and-analyzing-crashes-(segfaults)","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"So you managed to break Julia. Congratulations! Collected here are some general procedures you can undergo for common symptoms encountered when something goes awry. Including the information from these debugging steps can greatly help the maintainers when tracking down a segfault or trying to figure out why your script is running slower than expected.","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"If you've been directed to this page, find the symptom that best matches what you're experiencing and follow the instructions to generate the debugging information requested. Table of symptoms:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Segfaults during bootstrap (sysimg.jl)\nSegfaults when running a script\nErrors during Julia startup\nOther generic segfaults or unreachables reached","category":"page"},{"location":"devdocs/backtraces/#dev-version-info","page":"Reporting and analyzing crashes (segfaults)","title":"Version/Environment info","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"No matter the error, we will always need to know what version of Julia you are running. When Julia first starts up, a header is printed out with a version number and date. Please also include the output of versioninfo() (exported from the InteractiveUtils standard library) in any report you create:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"using InteractiveUtils\nversioninfo()","category":"page"},{"location":"devdocs/backtraces/#Segfaults-during-bootstrap-(sysimg.jl)","page":"Reporting and analyzing crashes (segfaults)","title":"Segfaults during bootstrap (sysimg.jl)","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Segfaults toward the end of the make process of building Julia are a common symptom of something going wrong while Julia is preparsing the corpus of code in the base/ folder. Many factors can contribute toward this process dying unexpectedly, however it is as often as not due to an error in the C-code portion of Julia, and as such must typically be debugged with a debug build inside of gdb. Explicitly:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Create a debug build of Julia:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"$ cd \n$ make debug","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Note that this process will likely fail with the same error as a normal make incantation, however this will create a debug executable that will offer gdb the debugging symbols needed to get accurate backtraces. Next, manually run the bootstrap process inside of gdb:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"$ cd base/\n$ gdb -x ../contrib/debug_bootstrap.gdb","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"This will start gdb, attempt to run the bootstrap process using the debug build of Julia, and print out a backtrace if (when) it segfaults. You may need to hit a few times to get the full backtrace. Create a gist with the backtrace, the version info, and any other pertinent information you can think of and open a new issue on Github with a link to the gist.","category":"page"},{"location":"devdocs/backtraces/#Segfaults-when-running-a-script","page":"Reporting and analyzing crashes (segfaults)","title":"Segfaults when running a script","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"The procedure is very similar to Segfaults during bootstrap (sysimg.jl). Create a debug build of Julia, and run your script inside of a debugged Julia process:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"$ cd \n$ make debug\n$ gdb --args usr/bin/julia-debug ","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Note that gdb will sit there, waiting for instructions. Type r to run the process, and bt to generate a backtrace once it segfaults:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"(gdb) r\nStarting program: /home/sabae/src/julia/usr/bin/julia-debug ./test.jl\n...\n(gdb) bt","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Create a gist with the backtrace, the version info, and any other pertinent information you can think of and open a new issue on Github with a link to the gist.","category":"page"},{"location":"devdocs/backtraces/#Errors-during-Julia-startup","page":"Reporting and analyzing crashes (segfaults)","title":"Errors during Julia startup","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Occasionally errors occur during Julia's startup process (especially when using binary distributions, as opposed to compiling from source) such as the following:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"$ julia\nexec: error -5","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"These errors typically indicate something is not getting loaded properly very early on in the bootup phase, and our best bet in determining what's going wrong is to use external tools to audit the disk activity of the julia process:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"On Linux, use strace:\n$ strace julia\nOn OSX, use dtruss:\n$ dtruss -f julia","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Create a gist with the strace/ dtruss output, the version info, and any other pertinent information and open a new issue on Github with a link to the gist.","category":"page"},{"location":"devdocs/backtraces/#Other-generic-segfaults-or-unreachables-reached","page":"Reporting and analyzing crashes (segfaults)","title":"Other generic segfaults or unreachables reached","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"As mentioned elsewhere, julia has good integration with rr for generating traces; this includes, on Linux, the ability to automatically run julia under rr and share the trace after a crash. This can be immensely helpful when debugging such crashes and is strongly encouraged when reporting crash issues to the JuliaLang/julia repo. To run julia under rr automatically, do:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"julia --bug-report=rr","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"To generate the rr trace locally, but not share, you can do:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"julia --bug-report=rr-local","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Note that this is only works on Linux. The blog post on Time Travelling Bug Reporting has many more details.","category":"page"},{"location":"devdocs/backtraces/#Glossary","page":"Reporting and analyzing crashes (segfaults)","title":"Glossary","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"A few terms have been used as shorthand in this guide:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":" refers to the root directory of the Julia source tree; e.g. it should contain folders such as base, deps, src, test, etc.....","category":"page"},{"location":"devdocs/init/#Initialization-of-the-Julia-runtime","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"How does the Julia runtime execute julia -e 'println(\"Hello World!\")' ?","category":"page"},{"location":"devdocs/init/#main()","page":"Initialization of the Julia runtime","title":"main()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Execution starts at main() in cli/loader_exe.c, which calls jl_load_repl() in cli/loader_lib.c which loads a few libraries, eventually calling jl_repl_entrypoint() in src/jlapi.c.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_repl_entrypoint() calls libsupport_init() to set the C library locale and to initialize the \"ios\" library (see ios_init_stdstreams() and Legacy ios.c library).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Next jl_parse_opts() is called to process command line options. Note that jl_parse_opts() only deals with options that affect code generation or early initialization. Other options are handled later by exec_options() in base/client.jl.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_parse_opts() stores command line options in the global jl_options struct.","category":"page"},{"location":"devdocs/init/#julia_init()","page":"Initialization of the Julia runtime","title":"julia_init()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"julia_init() in init.c is called by main() and calls _julia_init() in init.c.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"_julia_init() begins by calling libsupport_init() again (it does nothing the second time).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"restore_signals() is called to zero the signal handler mask.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_resolve_sysimg_location() searches configured paths for the base system image. See Building the Julia system image.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_gc_init() sets up allocation pools and lists for weak refs, preserved values and finalization.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_frontend() loads and initializes a pre-compiled femtolisp image containing the scanner/parser.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_types() creates jl_datatype_t type description objects for the built-in types defined in julia.h. e.g.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_any_type = jl_new_abstracttype(jl_symbol(\"Any\"), core, NULL, jl_emptysvec);\njl_any_type->super = jl_any_type;\n\njl_type_type = jl_new_abstracttype(jl_symbol(\"Type\"), core, jl_any_type, jl_emptysvec);\n\njl_int32_type = jl_new_primitivetype(jl_symbol(\"Int32\"), core,\n jl_any_type, jl_emptysvec, 32);","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_tasks() creates the jl_datatype_t* jl_task_type object; initializes the global jl_root_task struct; and sets jl_current_task to the root task.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_codegen() initializes the LLVM library.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_serializer() initializes 8-bit serialization tags for builtin jl_value_t values.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"If there is no sysimg file (!jl_options.image_file) then the Core and Main modules are created and boot.jl is evaluated:","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_core_module = jl_new_module(jl_symbol(\"Core\")) creates the Julia Core module.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_intrinsic_functions() creates a new Julia module Intrinsics containing constant jl_intrinsic_type symbols. These define an integer code for each intrinsic function. emit_intrinsic() translates these symbols into LLVM instructions during code generation.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_primitives() hooks C functions up to Julia function symbols. e.g. the symbol Core.:(===)() is bound to C function pointer jl_f_is() by calling add_builtin_func(\"===\", jl_f_is).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_new_main_module() creates the global \"Main\" module and sets jl_current_task->current_module = jl_main_module.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Note: _julia_init() then sets jl_root_task->current_module = jl_core_module. jl_root_task is an alias of jl_current_task at this point, so the current_module set by jl_new_main_module() above is overwritten.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_load(\"boot.jl\", sizeof(\"boot.jl\")) calls jl_parse_eval_all which repeatedly calls jl_toplevel_eval_flex() to execute boot.jl. ","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_get_builtin_hooks() initializes global C pointers to Julia globals defined in boot.jl.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_box_caches() pre-allocates global boxed integer value objects for values up to 1024. This speeds up allocation of boxed ints later on. e.g.:","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_value_t *jl_box_uint8(uint32_t x)\n{\n return boxed_uint8_cache[(uint8_t)x];\n}","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"_julia_init() iterates over the jl_core_module->bindings.table looking for jl_datatype_t values and sets the type name's module prefix to jl_core_module.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_add_standard_imports(jl_main_module) does \"using Base\" in the \"Main\" module.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Note: _julia_init() now reverts to jl_root_task->current_module = jl_main_module as it was before being set to jl_core_module above.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Platform specific signal handlers are initialized for SIGSEGV (OSX, Linux), and SIGFPE (Windows).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Other signals (SIGINFO, SIGBUS, SIGILL, SIGTERM, SIGABRT, SIGQUIT, SIGSYS and SIGPIPE) are hooked up to sigdie_handler() which prints a backtrace.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_restored_module() calls jl_module_run_initializer() for each deserialized module to run the __init__() function.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Finally sigint_handler() is hooked up to SIGINT and calls jl_throw(jl_interrupt_exception).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"_julia_init() then returns back to main() in cli/loader_exe.c and main() calls repl_entrypoint(argc, (char**)argv).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"sidebar: sysimg\nIf there is a sysimg file, it contains a pre-cooked image of the Core and Main modules (and whatever else is created by boot.jl). See Building the Julia system image.jl_restore_system_image() deserializes the saved sysimg into the current Julia runtime environment and initialization continues after jl_init_box_caches() below...Note: jl_restore_system_image() (and staticdata.c in general) uses the Legacy ios.c library.","category":"page"},{"location":"devdocs/init/#repl_entrypoint()","page":"Initialization of the Julia runtime","title":"repl_entrypoint()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"repl_entrypoint() loads the contents of argv[] into Base.ARGS.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"If a .jl \"program\" file was supplied on the command line, then exec_program() calls jl_load(program,len) which calls jl_parse_eval_all which repeatedly calls jl_toplevel_eval_flex() to execute the program.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"However, in our example (julia -e 'println(\"Hello World!\")'), jl_get_global(jl_base_module, jl_symbol(\"_start\")) looks up Base._start and jl_apply() executes it.","category":"page"},{"location":"devdocs/init/#Base._start","page":"Initialization of the Julia runtime","title":"Base._start","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Base._start calls Base.exec_options which calls jl_parse_input_line(\"println(\"Hello World!\")\") to create an expression object and Core.eval(Main, ex) to execute the parsed expression ex in the module context of Main.","category":"page"},{"location":"devdocs/init/#Core.eval","page":"Initialization of the Julia runtime","title":"Core.eval","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Core.eval(Main, ex) calls jl_toplevel_eval_in(m, ex), which calls jl_toplevel_eval_flex. jl_toplevel_eval_flex implements a simple heuristic to decide whether to compile a given code thunk or run it by interpreter. When given println(\"Hello World!\"), it would usually decide to run the code by interpreter, in which case it calls jl_interpret_toplevel_thunk, which then calls eval_body.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"The stack dump below shows how the interpreter works its way through various methods of Base.println() and Base.print() before arriving at write(s::IO, a::Array{T}) where T which does ccall(jl_uv_write()).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_uv_write() calls uv_write() to write \"Hello World!\" to JL_STDOUT. See Libuv wrappers for stdio.:","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Hello World!","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Stack frame Source code Notes\njl_uv_write() jl_uv.c called though ccall\njulia_write_282942 stream.jl function write!(s::IO, a::Array{T}) where T\njulia_print_284639 ascii.jl print(io::IO, s::String) = (write(io, s); nothing)\njlcall_print_284639 \njl_apply() julia.h \njl_trampoline() builtins.c \njl_apply() julia.h \njl_apply_generic() gf.c Base.print(Base.TTY, String)\njl_apply() julia.h \njl_trampoline() builtins.c \njl_apply() julia.h \njl_apply_generic() gf.c Base.print(Base.TTY, String, Char, Char...)\njl_apply() julia.h \njl_f_apply() builtins.c \njl_apply() julia.h \njl_trampoline() builtins.c \njl_apply() julia.h \njl_apply_generic() gf.c Base.println(Base.TTY, String, String...)\njl_apply() julia.h \njl_trampoline() builtins.c \njl_apply() julia.h \njl_apply_generic() gf.c Base.println(String,)\njl_apply() julia.h \ndo_call() interpreter.c \neval_body() interpreter.c \njl_interpret_toplevel_thunk interpreter.c \njl_toplevel_eval_flex toplevel.c \njl_toplevel_eval_in toplevel.c \nCore.eval boot.jl ","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Since our example has just one function call, which has done its job of printing \"Hello World!\", the stack now rapidly unwinds back to main().","category":"page"},{"location":"devdocs/init/#jl_atexit_hook()","page":"Initialization of the Julia runtime","title":"jl_atexit_hook()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"main() calls jl_atexit_hook(). This calls Base._atexit, then calls jl_gc_run_all_finalizers() and cleans up libuv handles.","category":"page"},{"location":"devdocs/init/#julia_save()","page":"Initialization of the Julia runtime","title":"julia_save()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Finally, main() calls julia_save(), which if requested on the command line, saves the runtime state to a new system image. See jl_compile_all() and jl_save_system_image().","category":"page"},{"location":"devdocs/build/distributing/#Binary-distributions","page":"Binary distributions","title":"Binary distributions","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"These notes are for those wishing to compile a binary distribution of Julia for distribution on various platforms. We love users spreading Julia as far and wide as they can, trying it out on as wide an array of operating systems and hardware configurations as possible. As each platform has specific gotchas and processes that must be followed in order to create a portable, working Julia distribution, we have separated most of the notes by OS.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Note that while the code for Julia is MIT-licensed, with a few exceptions, the distribution created by the techniques described herein will be GPL licensed, as various dependent libraries such as SuiteSparse are GPL licensed. We do hope to have a non-GPL distribution of Julia in the future.","category":"page"},{"location":"devdocs/build/distributing/#Versioning-and-Git","page":"Binary distributions","title":"Versioning and Git","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"The Makefile uses both the VERSION file and commit hashes and tags from the git repository to generate the base/version_git.jl with information we use to fill the splash screen and the versioninfo() output. If you for some reason don't want to have the git repository available when building you should pregenerate the base/version_git.jl file with:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"make -C base version_git.jl.phony","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia has lots of build dependencies where we use patched versions that has not yet been included by the popular package managers. These dependencies will usually be automatically downloaded when you build, but if you want to be able to build Julia on a computer without internet access you should create a full-source-dist archive with the special make target","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"make full-source-dist","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"that creates a julia-version-commit.tar.gz archive with all required dependencies.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"When compiling a tagged release in the git repository, we don't display the branch/commit hash info in the splash screen. You can use this line to show a release description of up to 45 characters. To set this line you have to create a Make.user file containing:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"override TAGGED_RELEASE_BANNER = \"my-package-repository build\"","category":"page"},{"location":"devdocs/build/distributing/#Target-Architectures","page":"Binary distributions","title":"Target Architectures","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"By default, Julia optimizes its system image to the native architecture of the build machine. This is usually not what you want when building packages, as it will make Julia fail at startup on any machine with incompatible CPUs (in particular older ones with more restricted instruction sets).","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"We therefore recommend that you pass the MARCH variable when calling make, setting it to the baseline target you intend to support. This will determine the target CPU for both the Julia executable and libraries, and the system image (the latter can also be set using JULIA_CPU_TARGET). Typically useful values for x86 CPUs are x86-64 and core2 (for 64-bit builds) and pentium4 (for 32-bit builds). Unfortunately, CPUs older than Pentium 4 are currently not supported (see this issue).","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"The full list of CPU targets supported by LLVM can be obtained by running llc -mattr=help.","category":"page"},{"location":"devdocs/build/distributing/#Linux","page":"Binary distributions","title":"Linux","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"On Linux, make binary-dist creates a tarball that contains a fully functional Julia installation. If you wish to create a distribution package such as a .deb, or .rpm, some extra effort is needed. See the julia-debian repository for an example of what metadata is needed for creating .deb packages for Debian and Ubuntu-based systems. See the Fedora package for RPM-based distributions. Although we have not yet experimented with it, Alien could be used to generate Julia packages for various Linux distributions.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia supports overriding standard installation directories via prefix and other environment variables you can pass when calling make and make install. See Make.inc for their list. DESTDIR can also be used to force the installation into a temporary directory.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"By default, Julia loads $prefix/etc/julia/startup.jl as an installation-wide initialization file. This file can be used by distribution managers to set up custom paths or initialization code. For Linux distribution packages, if $prefix is set to /usr, there is no /usr/etc to look into. This requires the path to Julia's private etc directory to be changed. This can be done via the sysconfdir make variable when building. Simply pass sysconfdir=/etc to make when building and Julia will first check /etc/julia/startup.jl before trying $prefix/etc/julia/startup.jl.","category":"page"},{"location":"devdocs/build/distributing/#OS-X","page":"Binary distributions","title":"OS X","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"To create a binary distribution on OSX, build Julia first, then cd to contrib/mac/app, and run make with the same makevars that were used with make when building Julia proper. This will then create a .dmg file in the contrib/mac/app directory holding a completely self-contained Julia.app.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Alternatively, Julia may be built as a framework by invoking make with the darwinframework target and DARWIN_FRAMEWORK=1 set. For example, make DARWIN_FRAMEWORK=1 darwinframework.","category":"page"},{"location":"devdocs/build/distributing/#Windows","page":"Binary distributions","title":"Windows","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Instructions for reating a Julia distribution on Windows are described in the build devdocs for Windows.","category":"page"},{"location":"devdocs/build/distributing/#Notes-on-BLAS-and-LAPACK","page":"Binary distributions","title":"Notes on BLAS and LAPACK","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia builds OpenBLAS by default, which includes the BLAS and LAPACK libraries. On 32-bit architectures, Julia builds OpenBLAS to use 32-bit integers, while on 64-bit architectures, Julia builds OpenBLAS to use 64-bit integers (ILP64). It is essential that all Julia functions that call BLAS and LAPACK API routines use integers of the correct width.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Most BLAS and LAPACK distributions provided on linux distributions, and even commercial implementations ship libraries that use 32-bit APIs. In many cases, a 64-bit API is provided as a separate library.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"When using vendor provided or OS provided libraries, a make option called USE_BLAS64 is available as part of the Julia build. When doing make USE_BLAS64=0, Julia will call BLAS and LAPACK assuming a 32-bit API, where all integers are 32-bit wide, even on a 64-bit architecture.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Other libraries that Julia uses, such as SuiteSparse also use BLAS and LAPACK internally. The APIs need to be consistent across all libraries that depend on BLAS and LAPACK. The Julia build process will build all these libraries correctly, but when overriding defaults and using system provided libraries, this consistency must be ensured.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Also note that Linux distributions sometimes ship several versions of OpenBLAS, some of which enable multithreading, and others only working in a serial fashion. For example, in Fedora, libopenblasp.so is threaded, but libopenblas.so is not. We recommend using the former for optimal performance. To choose an OpenBLAS library whose name is different from the default libopenblas.so, pass LIBBLAS=-l$(YOURBLAS) and LIBBLASNAME=lib$(YOURBLAS) to make, replacing $(YOURBLAS) with the name of your library. You can also add .so.0 to the name of the library if you want your package to work without requiring the unversioned .so symlink.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Finally, OpenBLAS includes its own optimized version of LAPACK. If you set USE_SYSTEM_BLAS=1 and USE_SYSTEM_LAPACK=1, you should also set LIBLAPACK=-l$(YOURBLAS) and LIBLAPACKNAME=lib$(YOURBLAS). Else, the reference LAPACK will be used and performance will typically be much lower.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Starting with Julia 1.7, Julia uses libblastrampoline to pick a different BLAS at runtime.","category":"page"},{"location":"devdocs/build/distributing/#Point-releasing-101","page":"Binary distributions","title":"Point releasing 101","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Creating a point/patch release consists of several distinct steps.","category":"page"},{"location":"devdocs/build/distributing/#Backporting-commits","page":"Binary distributions","title":"Backporting commits","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Some pull requests are labeled \"backport pending x.y\", e.g. \"backport pending 0.6\". This designates that the next subsequent release tagged from the release-x.y branch should include the commit(s) in that pull request. Once the pull request is merged into master, each of the commits should be cherry picked to a dedicated branch that will ultimately be merged into release-x.y.","category":"page"},{"location":"devdocs/build/distributing/#Creating-a-backports-branch","page":"Binary distributions","title":"Creating a backports branch","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"First, create a new branch based on release-x.y. The typical convention for Julia branches is to prefix the branch name with your initials if it's intended to be a personal branch. For the sake of example, we'll say that the author of the branch is Jane Smith.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git fetch origin\ngit checkout release-x.y\ngit rebase origin/release-x.y\ngit checkout -b js/backport-x.y","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This ensures that your local copy of release-x.y is up to date with origin before you create a new branch from it.","category":"page"},{"location":"devdocs/build/distributing/#Cherry-picking-commits","page":"Binary distributions","title":"Cherry picking commits","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Now we do the actual backporting. Find all merged pull requests labeled \"backport pending x.y\" in the GitHub web UI. For each of these, scroll to the bottom where it says \"someperson merged commit 123abc into master XX minutes ago\". Note that the commit name is a link; if you click it, you'll be shown the contents of the commit. If this page shows that 123abc is a merge commit, go back to the PR page–-we don't want merge commits, we want the actual commits. However, if this does not show a merge commit, it means that the PR was squash-merged. In that case, use the git SHA of the commit, listed next to commit on this page.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Once you have the SHA of the commit, cherry-pick it onto the backporting branch:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git cherry-pick -x -e ","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"There may be conflicts which need to be resolved manually. Once conflicts are resolved (if applicable), add a reference to the GitHub pull request that introduced the commit in the body of the commit message.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"After all of the relevant commits are on the backports branch, push the branch to GitHub.","category":"page"},{"location":"devdocs/build/distributing/#Checking-for-performance-regressions","page":"Binary distributions","title":"Checking for performance regressions","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Point releases should never introduce performance regressions. Luckily the Julia benchmarking bot, Nanosoldier, can run benchmarks against any branch, not just master. In this case we want to check the benchmark results of js/backport-x.y against release-x.y. To do this, awaken the Nanosoldier from his robotic slumber using a comment on your backporting pull request:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"@nanosoldier `runbenchmarks(ALL, vs=\":release-x.y\")`","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This will run all registered benchmarks on release-x.y and js/backport-x.y and produce a summary of results, marking all improvements and regressions.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"If Nanosoldier finds any regressions, try verifying locally and rerun Nanosoldier if necessary. If the regressions are deemed to be real rather than just noise, you'll have to find a commit on master to backport that fixes it if one exists, otherwise you should determine what caused the regression and submit a patch (or get someone who knows the code to submit a patch) to master, then backport the commit once that's merged. (Or submit a patch directly to the backport branch if appropriate.)","category":"page"},{"location":"devdocs/build/distributing/#Building-test-binaries","page":"Binary distributions","title":"Building test binaries","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"After the backport PR has been merged into the release-x.y branch, update your local clone of Julia, then get the SHA of the branch using","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git rev-parse origin/release-x.y","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Keep that handy, as it's what you'll enter in the \"Revision\" field in the buildbot UI.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"For now, all you need are binaries for Linux x86-64, since this is what's used for running PackageEvaluator. Go to https://buildog.julialang.org, submit a job for nuke_linux64, then queue up a job for package_linux64, providing the SHA as the revision. When the packaging job completes, it will upload the binary to the julialang2 bucket on AWS. Retrieve the URL, as it will be used for PackageEvaluator.","category":"page"},{"location":"devdocs/build/distributing/#Checking-for-package-breakages","page":"Binary distributions","title":"Checking for package breakages","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Point releases should never break packages, with the possible exception of packages that are doing some seriously questionable hacks using Base internals that are not intended to be user-facing. (In those cases, maybe have a word with the package author.)","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Checking whether changes made in the forthcoming new version will break packages can be accomplished using PackageEvaluator, often called \"PkgEval\" for short. PkgEval is what populates the status badges on GitHub repos and on pkg.julialang.org. It typically runs on one of the non-benchmarking nodes of Nanosoldier and uses Vagrant to perform its duties in separate, parallel VirtualBox virtual machines.","category":"page"},{"location":"devdocs/build/distributing/#Setting-up-PackageEvaluator","page":"Binary distributions","title":"Setting up PackageEvaluator","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Clone PackageEvaluator and create a branch called backport-x.y.z, and check it out. Note that the required changes are a little hacky and confusing, and hopefully that will be addressed in a future version of PackageEvaluator. The changes to make will be modeled off of this commit.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"The setup script takes its first argument as the version of Julia to run and the second as the range of package names (AK for packages named A-K, LZ for L-Z). The basic idea is that we're going to tweak that a bit to run only two versions of Julia, the current x.y release and our backport version, each with three ranges of packages.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"In the linked diff, we're saying that if the second argument is LZ, use the binaries built from our backport branch, otherwise (AK) use the release binaries. Then we're using the first argument to run a section of the package list: A-F for input 0.4, G-N for 0.5, and O-Z for 0.6.","category":"page"},{"location":"devdocs/build/distributing/#Running-PackageEvaluator","page":"Binary distributions","title":"Running PackageEvaluator","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"To run PkgEval, find a hefty enough machine (such as Nanosoldier node 1), then run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git clone https://github.com/JuliaCI/PackageEvaluator.jl.git\ncd PackageEvaluator.jl/scripts\ngit checkout backport-x.y.z\n./runvagrant.sh","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This produces some folders in the scripts/ directory. The folder names and their contents are decoded below:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Folder name Julia version Package range\n0.4AK Release A-F\n0.4LZ Backport A-F\n0.5AK Release G-N\n0.5LZ Backport G-N\n0.6AK Release O-Z\n0.6LZ Backport O-Z","category":"page"},{"location":"devdocs/build/distributing/#Investigating-results","page":"Binary distributions","title":"Investigating results","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Once that's done, you can use ./summary.sh from that same directory to produce a summary report of the findings. We'll do so for each of the folders to aggregate overall results by version.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"./summary.sh 0.4AK/*.json > summary_release.txt\n./summary.sh 0.5AK/*.json >> summary_release.txt\n./summary.sh 0.6AK/*.json >> summary_release.txt\n./summary.sh 0.4LZ/*.json > summary_backport.txt\n./summary.sh 0.5LZ/*.json >> summary_backport.txt\n./summary.sh 0.6LZ/*.json >> summary_backport.txt","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Now we have two files, summary_release.txt and summary_backport.txt, containing the PackageEvaluator test results (pass/fail) for each package for the two versions.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"To make these easier to ingest into a Julia, we'll convert them into CSV files then use the DataFrames package to process the results. To convert to CSV, copy each .txt file to a corresponding .csv file, then enter Vim and execute ggVGI\" then :%s/\\.json /\",/g. (You don't have to use Vim; this just is one way to do it.) Now process the results with Julia code similar to the following.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"using DataFrames\n\nrelease = readtable(\"summary_release.csv\", header=false, names=[:package, :release])\nbackport = readtable(\"summary_backport.csv\", header=false, names=[:package, :backport])\n\nresults = join(release, backport, on=:package, kind=:outer)\n\nfor result in eachrow(results)\n a = result[:release]\n b = result[:backport]\n if (isna(a) && !isna(b)) || (isna(b) && !isna(a))\n color = :yellow\n elseif a != b && occursin(\"pass\", b)\n color = :green\n elseif a != b\n color = :red\n else\n continue\n end\n printstyled(result[:package], \": Release \", a, \" -> Backport \", b, \"\\n\", color=color)\nend","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This will write color-coded lines to stdout. All lines in red must be investigated as they signify potential breakages caused by the backport version. Lines in yellow should be looked into since it means a package ran on one version but not on the other for some reason. If you find that your backported branch is causing breakages, use git bisect to identify the problematic commits, git revert those commits, and repeat the process.","category":"page"},{"location":"devdocs/build/distributing/#Merging-backports-into-the-release-branch","page":"Binary distributions","title":"Merging backports into the release branch","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"After you have ensured that","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"the backported commits pass all of Julia's unit tests,\nthere are no performance regressions introduced by the backported commits as compared to the release branch, and\nthe backported commits do not break any registered packages,","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"then the backport branch is ready to be merged into release-x.y. Once it's merged, go through and remove the \"backport pending x.y\" label from all pull requests containing the commits that have been backported. Do not remove the label from PRs that have not been backported.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"The release-x.y branch should now contain all of the new commits. The last thing we want to do to the branch is to adjust the version number. To do this, submit a PR against release-x.y that edits the VERSION file to remove -pre from the version number. Once that's merged, we're ready to tag.","category":"page"},{"location":"devdocs/build/distributing/#Tagging-the-release","page":"Binary distributions","title":"Tagging the release","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"It's time! Check out the release-x.y branch and make sure that your local copy of the branch is up to date with the remote branch. At the command line, run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git tag v$(cat VERSION)\ngit push --tags","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This creates the tag locally and pushes it to GitHub.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"After tagging the release, submit another PR to release-x.y to bump the patch number and add -pre back to the end. This denotes that the branch state reflects a prerelease version of the next point release in the x.y series.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Follow the remaining directions in the Makefile.","category":"page"},{"location":"devdocs/build/distributing/#Signing-binaries","page":"Binary distributions","title":"Signing binaries","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Some of these steps will require secure passwords. To obtain the appropriate passwords, contact Elliot Saba (staticfloat) or Alex Arslan (ararslan). Note that code signing for each platform must be performed on that platform (e.g. Windows signing must be done on Windows, etc.).","category":"page"},{"location":"devdocs/build/distributing/#Linux-2","page":"Binary distributions","title":"Linux","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Code signing must be done manually on Linux, but it's quite simple. First obtain the file julia.key from the CodeSigning folder in the juliasecure AWS bucket. Add this to your GnuPG keyring using","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"gpg --import julia.key","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This will require entering a password that you must obtain from Elliot or Alex. Next, set the trust level for the key to maximum. Start by entering a gpg session:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"gpg --edit-key julia","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"At the prompt, type trust, then when asked for a trust level, provide the maximum available (likely 5). Exit GnuPG.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Now, for each of the Linux tarballs that were built on the buildbots, enter","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"gpg -u julia --armor --detach-sig julia-x.y.z-linux-.tar.gz","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This will produce a corresponding .asc file for each tarball. And that's it!","category":"page"},{"location":"devdocs/build/distributing/#macOS","page":"Binary distributions","title":"macOS","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Code signing should happen automatically on the macOS buildbots. However, it's important to verify that it was successful. On a system or virtual machine running macOS, download the .dmg file that was built on the buildbots. For the sake of example, say that the .dmg file is called julia-x.y.z-osx.dmg. Run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"mkdir ./jlmnt\nhdiutil mount -readonly -mountpoint ./jlmnt julia-x.y.z-osx.dmg\ncodesign -v jlmnt/Julia-x.y.app","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Be sure to note the name of the mounted disk listed when mounting! For the sake of example, we'll assume this is disk3. If the code signing verification exited successfully, there will be no output from the codesign step. If it was indeed successful, you can detach the .dmg now:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"hdiutil eject /dev/disk3\nrm -rf ./jlmnt","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"If you get a message like","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia-x.y.app: code object is not signed at all","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"then you'll need to sign manually.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"To sign manually, first retrieve the OS X certificates from the CodeSigning folder in the juliasecure bucket on AWS. Add the .p12 file to your keychain using Keychain.app. Ask Elliot Saba (staticfloat) or Alex Arslan (ararslan) for the password for the key. Now run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"hdiutil convert julia-x.y.z-osx.dmg -format UDRW -o julia-x.y.z-osx_writable.dmg\nmkdir ./jlmnt\nhdiutil mount -mountpoint julia-x.y.z-osx_writable.dmg\ncodesign -s \"AFB379C0B4CBD9DB9A762797FC2AB5460A2B0DBE\" --deep jlmnt/Julia-x.y.app","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This may fail with a message like","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia-x.y.app: resource fork, Finder information, or similar detritus not allowed","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"If that's the case, you'll need to remove extraneous attributes:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"xattr -cr jlmnt/Julia-x.y.app","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Then retry code signing. If that produces no errors, retry verification. If all is now well, unmount the writable .dmg and convert it back to read-only:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"hdiutil eject /dev/disk3\nrm -rf ./jlmnt\nhdiutil convert julia-x.y.z-osx_writable.dmg -format UDZO -o julia-x.y.z-osx_fixed.dmg","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Verify that the resulting .dmg is in fact fixed by double clicking it. If everything looks good, eject it then drop the _fixed suffix from the name. And that's it!","category":"page"},{"location":"devdocs/build/distributing/#Windows-2","page":"Binary distributions","title":"Windows","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Signing must be performed manually on Windows. First obtain the Windows 10 SDK, which contains the necessary signing utilities, from the Microsoft website. We need the SignTool utility which should have been installed somewhere like C:\\Program Files (x86)\\Windows Kits\\10\\App Certification Kit. Grab the Windows certificate files from CodeSigning on juliasecure and put them in the same directory as the executables. Open a Windows CMD window, cd to where all the files are, and run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"set PATH=%PATH%;C:\\Program Files (x86)\\Windows Kits\\10\\App Certification Kit;\nsigntool sign /f julia-windows-code-sign_2017.p12 /p \"PASSWORD\" ^\n /t http://timestamp.verisign.com/scripts/timstamp.dll ^\n /v julia-x.y.z-win32.exe","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Note that ^ is a line continuation character in Windows CMD and PASSWORD is a placeholder for the password for this certificate. As usual, contact Elliot or Alex for passwords. If there are no errors, we're all good!","category":"page"},{"location":"devdocs/build/distributing/#Uploading-binaries","page":"Binary distributions","title":"Uploading binaries","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Now that everything is signed, we need to upload the binaries to AWS. You can use a program like Cyberduck or the aws command line utility. The binaries should go in the julialang2 bucket in the appropriate folders. For example, Linux x86-64 goes in julialang2/bin/linux/x.y. Be sure to delete the current julia-x.y-latest-linux-.tar.gz file and replace it with a duplicate of julia-x.y.z-linux-.tar.gz.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"We also need to upload the checksums for everything we've built, including the source tarballs and all release binaries. This is simple:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"shasum -a 256 julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.sha256\nmd5sum julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.md5","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Note that if you're running those commands on macOS, you'll get very slightly different output, which can be reformatted by looking at an existing file. Mac users will also need to use md5 -r instead of md5sum. Upload the .md5 and .sha256 files to julialang2/bin/checksums on AWS.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Ensure that the permissions on AWS for all uploaded files are set to \"Everyone: READ.\"","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"For each file we've uploaded, we need to purge the Fastly cache so that the links on the website point to the updated files. As an example:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"curl -X PURGE https://julialang-s3.julialang.org/bin/checksums/julia-x.y.z.sha256","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Sometimes this isn't necessary but it's good to do anyway.","category":"page"},{"location":"manual/workflow-tips/#man-workflow-tips","page":"Workflow Tips","title":"Workflow Tips","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Here are some tips for working with Julia efficiently.","category":"page"},{"location":"manual/workflow-tips/#REPL-based-workflow","page":"Workflow Tips","title":"REPL-based workflow","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"As already elaborated in The Julia REPL, Julia's REPL provides rich functionality that facilitates an efficient interactive workflow. Here are some tips that might further enhance your experience at the command line.","category":"page"},{"location":"manual/workflow-tips/#A-basic-editor/REPL-workflow","page":"Workflow Tips","title":"A basic editor/REPL workflow","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"The most basic Julia workflows involve using a text editor in conjunction with the julia command line.","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Create a file, say Tmp.jl, and include within it","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"module Tmp\n\nsay_hello() = println(\"Hello!\")\n\n# Your other definitions here\n\nend # module\n\nusing .Tmp","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Then, in the same directory, start the Julia REPL (using the julia command). Run the new file as follows:","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"julia> include(\"Tmp.jl\")\n\njulia> Tmp.say_hello()\nHello!","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Explore ideas in the REPL. Save good ideas in Tmp.jl. To reload the file after it has been changed, just include it again.","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"The key in the above is that your code is encapsulated in a module. That allows you to edit struct definitions and remove methods, without restarting Julia.","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"(Explanation: structs cannot be edited after definition, nor can methods be deleted. But you can overwrite the definition of a module, which is what we do when we re-include(\"Tmp.jl\")).","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"In addition, the encapsulation of code in a module protects it from being influenced by previous state in the REPL, protecting you from hard-to-detect errors.","category":"page"},{"location":"manual/workflow-tips/#Browser-based-workflow","page":"Workflow Tips","title":"Browser-based workflow","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"There are a few ways to interact with Julia in a browser:","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Using Pluto notebooks through Pluto.jl\nUsing Jupyter notebooks through IJulia.jl","category":"page"},{"location":"manual/workflow-tips/#Revise-based-workflows","page":"Workflow Tips","title":"Revise-based workflows","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Whether you're at the REPL or in IJulia, you can typically improve your development experience with Revise. It is common to configure Revise to start whenever julia is started, as per the instructions in the Revise documentation. Once configured, Revise will track changes to files in any loaded modules, and to any files loaded in to the REPL with includet (but not with plain include); you can then edit the files and the changes take effect without restarting your julia session. A standard workflow is similar to the REPL-based workflow above, with the following modifications:","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Put your code in a module somewhere on your load path. There are several options for achieving this, of which two recommended choices are:\nFor long-term projects, use PkgTemplates:\nusing PkgTemplates\nt = Template()\nt(\"MyPkg\")\nThis will create a blank package, \"MyPkg\", in your .julia/dev directory. Note that PkgTemplates allows you to control many different options through its Template constructor.\nIn step 2 below, edit MyPkg/src/MyPkg.jl to change the source code, and MyPkg/test/runtests.jl for the tests.\nFor \"throw-away\" projects, you can avoid any need for cleanup by doing your work in your temporary directory (e.g., /tmp).\nNavigate to your temporary directory and launch Julia, then do the following:\npkg> generate MyPkg # type ] to enter pkg mode\njulia> push!(LOAD_PATH, pwd()) # hit backspace to exit pkg mode\nIf you restart your Julia session you'll have to re-issue that command modifying LOAD_PATH.\nIn step 2 below, edit MyPkg/src/MyPkg.jl to change the source code, and create any test file of your choosing.\nDevelop your package\nBefore loading any code, make sure you're running Revise: say using Revise or follow its documentation on configuring it to run automatically.\nThen navigate to the directory containing your test file (here assumed to be \"runtests.jl\") and do the following:\njulia> using MyPkg\n\njulia> include(\"runtests.jl\")\nYou can iteratively modify the code in MyPkg in your editor and re-run the tests with include(\"runtests.jl\"). You generally should not need to restart your Julia session to see the changes take effect (subject to a few limitations).","category":"page"},{"location":"stdlib/LazyArtifacts/#Lazy-Artifacts","page":"Lazy Artifacts","title":"Lazy Artifacts","text":"","category":"section"},{"location":"stdlib/LazyArtifacts/","page":"Lazy Artifacts","title":"Lazy Artifacts","text":"DocTestSetup = :(using LazyArtifacts)","category":"page"},{"location":"stdlib/LazyArtifacts/","page":"Lazy Artifacts","title":"Lazy Artifacts","text":"In order for a package to download artifacts lazily, LazyArtifacts must be explicitly listed as a dependency of that package.","category":"page"},{"location":"stdlib/LazyArtifacts/","page":"Lazy Artifacts","title":"Lazy Artifacts","text":"For further information on artifacts, see Artifacts.","category":"page"},{"location":"base/numbers/#lib-numbers","page":"Numbers","title":"Numbers","text":"","category":"section"},{"location":"base/numbers/#Standard-Numeric-Types","page":"Numbers","title":"Standard Numeric Types","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"A type tree for all subtypes of Number in Base is shown below. Abstract types have been marked, the rest are concrete types.","category":"page"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Number (Abstract Type)\n├─ Complex\n└─ Real (Abstract Type)\n ├─ AbstractFloat (Abstract Type)\n │ ├─ Float16\n │ ├─ Float32\n │ ├─ Float64\n │ └─ BigFloat\n ├─ Integer (Abstract Type)\n │ ├─ Bool\n │ ├─ Signed (Abstract Type)\n │ │ ├─ Int8\n │ │ ├─ Int16\n │ │ ├─ Int32\n │ │ ├─ Int64\n │ │ ├─ Int128\n │ │ └─ BigInt\n │ └─ Unsigned (Abstract Type)\n │ ├─ UInt8\n │ ├─ UInt16\n │ ├─ UInt32\n │ ├─ UInt64\n │ └─ UInt128\n ├─ Rational\n └─ AbstractIrrational (Abstract Type)\n └─ Irrational","category":"page"},{"location":"base/numbers/#Abstract-number-types","page":"Numbers","title":"Abstract number types","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Core.Number\nCore.Real\nCore.AbstractFloat\nCore.Integer\nCore.Signed\nCore.Unsigned\nBase.AbstractIrrational","category":"page"},{"location":"base/numbers/#Core.Number","page":"Numbers","title":"Core.Number","text":"Number\n\nAbstract supertype for all number types.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Real","page":"Numbers","title":"Core.Real","text":"Real <: Number\n\nAbstract supertype for all real numbers.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.AbstractFloat","page":"Numbers","title":"Core.AbstractFloat","text":"AbstractFloat <: Real\n\nAbstract supertype for all floating point numbers.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Integer","page":"Numbers","title":"Core.Integer","text":"Integer <: Real\n\nAbstract supertype for all integers (e.g. Signed, Unsigned, and Bool).\n\nSee also isinteger, trunc, div.\n\nExamples\n\njulia> 42 isa Integer\ntrue\n\njulia> 1.0 isa Integer\nfalse\n\njulia> isinteger(1.0)\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Signed","page":"Numbers","title":"Core.Signed","text":"Signed <: Integer\n\nAbstract supertype for all signed integers.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Unsigned","page":"Numbers","title":"Core.Unsigned","text":"Unsigned <: Integer\n\nAbstract supertype for all unsigned integers.\n\nBuilt-in unsigned integers are printed in hexadecimal, with prefix 0x, and can be entered in the same way.\n\nExamples\n\njulia> typemax(UInt8)\n0xff\n\njulia> Int(0x00d)\n13\n\njulia> unsigned(true)\n0x0000000000000001\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.AbstractIrrational","page":"Numbers","title":"Base.AbstractIrrational","text":"AbstractIrrational <: Real\n\nNumber type representing an exact irrational value, which is automatically rounded to the correct precision in arithmetic operations with other numeric quantities.\n\nSubtypes MyIrrational <: AbstractIrrational should implement at least ==(::MyIrrational, ::MyIrrational), hash(x::MyIrrational, h::UInt), and convert(::Type{F}, x::MyIrrational) where {F <: Union{BigFloat,Float32,Float64}}.\n\nIf a subtype is used to represent values that may occasionally be rational (e.g. a square-root type that represents √n for integers n will give a rational result when n is a perfect square), then it should also implement isinteger, iszero, isone, and == with Real values (since all of these default to false for AbstractIrrational types), as well as defining hash to equal that of the corresponding Rational.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Concrete-number-types","page":"Numbers","title":"Concrete number types","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Core.Float16\nCore.Float32\nCore.Float64\nBase.BigFloat\nCore.Bool\nCore.Int8\nCore.UInt8\nCore.Int16\nCore.UInt16\nCore.Int32\nCore.UInt32\nCore.Int64\nCore.UInt64\nCore.Int128\nCore.UInt128\nBase.Int\nBase.UInt\nBase.BigInt\nBase.Complex\nBase.Rational\nBase.Irrational","category":"page"},{"location":"base/numbers/#Core.Float16","page":"Numbers","title":"Core.Float16","text":"Float16 <: AbstractFloat <: Real\n\n16-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 5 exponent, 10 fraction bits.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Float32","page":"Numbers","title":"Core.Float32","text":"Float32 <: AbstractFloat <: Real\n\n32-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 8 exponent, 23 fraction bits.\n\nThe exponent for scientific notation should be entered as lower-case f, thus 2f3 === 2.0f0 * 10^3 === Float32(2_000). For array literals and comprehensions, the element type can be specified before the square brackets: Float32[1,4,9] == Float32[i^2 for i in 1:3].\n\nSee also Inf32, NaN32, Float16, exponent, frexp.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Float64","page":"Numbers","title":"Core.Float64","text":"Float64 <: AbstractFloat <: Real\n\n64-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 11 exponent, 52 fraction bits. See bitstring, signbit, exponent, frexp, and significand to access various bits.\n\nThis is the default for floating point literals, 1.0 isa Float64, and for many operations such as 1/2, 2pi, log(2), range(0,90,length=4). Unlike integers, this default does not change with Sys.WORD_SIZE.\n\nThe exponent for scientific notation can be entered as e or E, thus 2e3 === 2.0E3 === 2.0 * 10^3. Doing so is strongly preferred over 10^n because integers overflow, thus 2.0 * 10^19 < 0 but 2e19 > 0.\n\nSee also Inf, NaN, floatmax, Float32, Complex.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.MPFR.BigFloat","page":"Numbers","title":"Base.MPFR.BigFloat","text":"BigFloat <: AbstractFloat\n\nArbitrary precision floating point number type.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Bool","page":"Numbers","title":"Core.Bool","text":"Bool <: Integer\n\nBoolean type, containing the values true and false.\n\nBool is a kind of number: false is numerically equal to 0 and true is numerically equal to 1. Moreover, false acts as a multiplicative \"strong zero\" against NaN and Inf:\n\njulia> [true, false] == [1, 0]\ntrue\n\njulia> 42.0 + true\n43.0\n\njulia> 0 .* (NaN, Inf, -Inf)\n(NaN, NaN, NaN)\n\njulia> false .* (NaN, Inf, -Inf)\n(0.0, 0.0, -0.0)\n\nBranches via if and other conditionals only accept Bool. There are no \"truthy\" values in Julia.\n\nComparisons typically return Bool, and broadcasted comparisons may return BitArray instead of an Array{Bool}.\n\njulia> [1 2 3 4 5] .< pi\n1×5 BitMatrix:\n 1 1 1 0 0\n\njulia> map(>(pi), [1 2 3 4 5])\n1×5 Matrix{Bool}:\n 0 0 0 1 1\n\nSee also trues, falses, ifelse.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int8","page":"Numbers","title":"Core.Int8","text":"Int8 <: Signed <: Integer\n\n8-bit signed integer type.\n\nRepresents numbers n ∈ -128:127. Note that such integers overflow without warning, thus typemax(Int8) + Int8(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt8","page":"Numbers","title":"Core.UInt8","text":"UInt8 <: Unsigned <: Integer\n\n8-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x07 == 7.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int16","page":"Numbers","title":"Core.Int16","text":"Int16 <: Signed <: Integer\n\n16-bit signed integer type.\n\nRepresents numbers n ∈ -32768:32767. Note that such integers overflow without warning, thus typemax(Int16) + Int16(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt16","page":"Numbers","title":"Core.UInt16","text":"UInt16 <: Unsigned <: Integer\n\n16-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x000f == 15.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int32","page":"Numbers","title":"Core.Int32","text":"Int32 <: Signed <: Integer\n\n32-bit signed integer type.\n\nNote that such integers overflow without warning, thus typemax(Int32) + Int32(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt32","page":"Numbers","title":"Core.UInt32","text":"UInt32 <: Unsigned <: Integer\n\n32-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x0000001f == 31.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int64","page":"Numbers","title":"Core.Int64","text":"Int64 <: Signed <: Integer\n\n64-bit signed integer type.\n\nNote that such integers overflow without warning, thus typemax(Int64) + Int64(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt64","page":"Numbers","title":"Core.UInt64","text":"UInt64 <: Unsigned <: Integer\n\n64-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x000000000000003f == 63.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int128","page":"Numbers","title":"Core.Int128","text":"Int128 <: Signed <: Integer\n\n128-bit signed integer type.\n\nNote that such integers overflow without warning, thus typemax(Int128) + Int128(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt128","page":"Numbers","title":"Core.UInt128","text":"UInt128 <: Unsigned <: Integer\n\n128-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x0000000000000000000000000000007f == 127.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int","page":"Numbers","title":"Core.Int","text":"Int\n\nSys.WORD_SIZE-bit signed integer type, Int <: Signed <: Integer <: Real.\n\nThis is the default type of most integer literals and is an alias for either Int32 or Int64, depending on Sys.WORD_SIZE. It is the type returned by functions such as length, and the standard type for indexing arrays.\n\nNote that integers overflow without warning, thus typemax(Int) + 1 < 0 and 10^19 < 0. Overflow can be avoided by using BigInt. Very large integer literals will use a wider type, for instance 10_000_000_000_000_000_000 isa Int128.\n\nInteger division is div alias ÷, whereas / acting on integers returns Float64.\n\nSee also Int64, widen, typemax, bitstring.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt","page":"Numbers","title":"Core.UInt","text":"UInt\n\nSys.WORD_SIZE-bit unsigned integer type, UInt <: Unsigned <: Integer.\n\nLike Int, the alias UInt may point to either UInt32 or UInt64, according to the value of Sys.WORD_SIZE on a given computer.\n\nPrinted and parsed in hexadecimal: UInt(15) === 0x000000000000000f.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.GMP.BigInt","page":"Numbers","title":"Base.GMP.BigInt","text":"BigInt <: Signed\n\nArbitrary precision integer type.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.Complex","page":"Numbers","title":"Base.Complex","text":"Complex{T<:Real} <: Number\n\nComplex number type with real and imaginary part of type T.\n\nComplexF16, ComplexF32 and ComplexF64 are aliases for Complex{Float16}, Complex{Float32} and Complex{Float64} respectively.\n\nSee also: Real, complex, real.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.Rational","page":"Numbers","title":"Base.Rational","text":"Rational{T<:Integer} <: Real\n\nRational number type, with numerator and denominator of type T. Rationals are checked for overflow.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.Irrational","page":"Numbers","title":"Base.Irrational","text":"Irrational{sym} <: AbstractIrrational\n\nNumber type representing an exact irrational value denoted by the symbol sym, such as π, ℯ and γ.\n\nSee also AbstractIrrational.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Data-Formats","page":"Numbers","title":"Data Formats","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Base.digits\nBase.digits!\nBase.bitstring\nBase.parse\nBase.tryparse\nBase.big\nBase.signed\nBase.unsigned\nBase.float(::Any)\nBase.Math.significand\nBase.Math.exponent\nBase.complex(::Complex)\nBase.bswap\nBase.hex2bytes\nBase.hex2bytes!\nBase.bytes2hex","category":"page"},{"location":"base/numbers/#Base.digits","page":"Numbers","title":"Base.digits","text":"digits([T<:Integer], n::Integer; base::T = 10, pad::Integer = 1)\n\nReturn an array with element type T (default Int) of the digits of n in the given base, optionally padded with zeros to a specified size. More significant digits are at higher indices, such that n == sum(digits[k]*base^(k-1) for k=1:length(digits)).\n\nSee also ndigits, digits!, and for base 2 also bitstring, count_ones.\n\nExamples\n\njulia> digits(10)\n2-element Vector{Int64}:\n 0\n 1\n\njulia> digits(10, base = 2)\n4-element Vector{Int64}:\n 0\n 1\n 0\n 1\n\njulia> digits(-256, base = 10, pad = 5)\n5-element Vector{Int64}:\n -6\n -5\n -2\n 0\n 0\n\njulia> n = rand(-999:999);\n\njulia> n == evalpoly(13, digits(n, base = 13))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.digits!","page":"Numbers","title":"Base.digits!","text":"digits!(array, n::Integer; base::Integer = 10)\n\nFills an array of the digits of n in the given base. More significant digits are at higher indices. If the array length is insufficient, the least significant digits are filled up to the array length. If the array length is excessive, the excess portion is filled with zeros.\n\nExamples\n\njulia> digits!([2, 2, 2, 2], 10, base = 2)\n4-element Vector{Int64}:\n 0\n 1\n 0\n 1\n\njulia> digits!([2, 2, 2, 2, 2, 2], 10, base = 2)\n6-element Vector{Int64}:\n 0\n 1\n 0\n 1\n 0\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.bitstring","page":"Numbers","title":"Base.bitstring","text":"bitstring(n)\n\nA string giving the literal bit representation of a primitive type.\n\nSee also count_ones, count_zeros, digits.\n\nExamples\n\njulia> bitstring(Int32(4))\n\"00000000000000000000000000000100\"\n\njulia> bitstring(2.2)\n\"0100000000000001100110011001100110011001100110011001100110011010\"\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.parse","page":"Numbers","title":"Base.parse","text":"parse(::Type{SimpleColor}, rgb::String)\n\nAn analogue of tryparse(SimpleColor, rgb::String) (which see), that raises an error instead of returning nothing.\n\n\n\n\n\nparse(::Type{Platform}, triplet::AbstractString)\n\nParses a string platform triplet back into a Platform object.\n\n\n\n\n\nparse(type, str; base)\n\nParse a string as a number. For Integer types, a base can be specified (the default is 10). For floating-point types, the string is parsed as a decimal floating-point number. Complex types are parsed from decimal strings of the form \"R±Iim\" as a Complex(R,I) of the requested type; \"i\" or \"j\" can also be used instead of \"im\", and \"R\" or \"Iim\" are also permitted. If the string does not contain a valid number, an error is raised.\n\ncompat: Julia 1.1\nparse(Bool, str) requires at least Julia 1.1.\n\nExamples\n\njulia> parse(Int, \"1234\")\n1234\n\njulia> parse(Int, \"1234\", base = 5)\n194\n\njulia> parse(Int, \"afc\", base = 16)\n2812\n\njulia> parse(Float64, \"1.2e-3\")\n0.0012\n\njulia> parse(Complex{Float64}, \"3.2e-1 + 4.5im\")\n0.32 + 4.5im\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.tryparse","page":"Numbers","title":"Base.tryparse","text":"tryparse(::Type{SimpleColor}, rgb::String)\n\nAttempt to parse rgb as a SimpleColor. If rgb starts with # and has a length of 7, it is converted into a RGBTuple-backed SimpleColor. If rgb starts with a-z, rgb is interpreted as a color name and converted to a Symbol-backed SimpleColor.\n\nOtherwise, nothing is returned.\n\nExamples\n\njulia> tryparse(SimpleColor, \"blue\")\nSimpleColor(blue)\n\njulia> tryparse(SimpleColor, \"#9558b2\")\nSimpleColor(#9558b2)\n\njulia> tryparse(SimpleColor, \"#nocolor\")\n\n\n\n\n\ntryparse(type, str; base)\n\nLike parse, but returns either a value of the requested type, or nothing if the string does not contain a valid number.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.big","page":"Numbers","title":"Base.big","text":"big(x)\n\nConvert a number to a maximum precision representation (typically BigInt or BigFloat). See BigFloat for information about some pitfalls with floating-point numbers.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.signed","page":"Numbers","title":"Base.signed","text":"signed(T::Integer)\n\nConvert an integer bitstype to the signed type of the same size.\n\nExamples\n\njulia> signed(UInt16)\nInt16\njulia> signed(UInt64)\nInt64\n\n\n\n\n\nsigned(x)\n\nConvert a number to a signed integer. If the argument is unsigned, it is reinterpreted as signed without checking for overflow.\n\nSee also: unsigned, sign, signbit.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.unsigned","page":"Numbers","title":"Base.unsigned","text":"unsigned(T::Integer)\n\nConvert an integer bitstype to the unsigned type of the same size.\n\nExamples\n\njulia> unsigned(Int16)\nUInt16\njulia> unsigned(UInt64)\nUInt64\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.float-Tuple{Any}","page":"Numbers","title":"Base.float","text":"float(x)\n\nConvert a number or array to a floating point data type.\n\nSee also: complex, oftype, convert.\n\nExamples\n\njulia> float(1:1000)\n1.0:1.0:1000.0\n\njulia> float(typemax(Int32))\n2.147483647e9\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.Math.significand","page":"Numbers","title":"Base.Math.significand","text":"significand(x)\n\nExtract the significand (a.k.a. mantissa) of a floating-point number. If x is a non-zero finite number, then the result will be a number of the same type and sign as x, and whose absolute value is on the interval 12). Otherwise x is returned.\n\nSee also frexp, exponent.\n\nExamples\n\njulia> significand(15.2)\n1.9\n\njulia> significand(-15.2)\n-1.9\n\njulia> significand(-15.2) * 2^3\n-15.2\n\njulia> significand(-Inf), significand(Inf), significand(NaN)\n(-Inf, Inf, NaN)\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.Math.exponent","page":"Numbers","title":"Base.Math.exponent","text":"exponent(x::Real) -> Int\n\nReturn the largest integer y such that 2^y ≤ abs(x). For a normalized floating-point number x, this corresponds to the exponent of x.\n\nThrows a DomainError when x is zero, infinite, or NaN. For any other non-subnormal floating-point number x, this corresponds to the exponent bits of x.\n\nSee also signbit, significand, frexp, issubnormal, log2, ldexp.\n\nExamples\n\njulia> exponent(8)\n3\n\njulia> exponent(6.5)\n2\n\njulia> exponent(-1//4)\n-2\n\njulia> exponent(3.142e-4)\n-12\n\njulia> exponent(floatmin(Float32)), exponent(nextfloat(0.0f0))\n(-126, -149)\n\njulia> exponent(0.0)\nERROR: DomainError with 0.0:\nCannot be ±0.0.\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.complex-Tuple{Complex}","page":"Numbers","title":"Base.complex","text":"complex(r, [i])\n\nConvert real numbers or arrays to complex. i defaults to zero.\n\nExamples\n\njulia> complex(7)\n7 + 0im\n\njulia> complex([1, 2, 3])\n3-element Vector{Complex{Int64}}:\n 1 + 0im\n 2 + 0im\n 3 + 0im\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.bswap","page":"Numbers","title":"Base.bswap","text":"bswap(n)\n\nReverse the byte order of n.\n\n(See also ntoh and hton to convert between the current native byte order and big-endian order.)\n\nExamples\n\njulia> a = bswap(0x10203040)\n0x40302010\n\njulia> bswap(a)\n0x10203040\n\njulia> string(1, base = 2)\n\"1\"\n\njulia> string(bswap(1), base = 2)\n\"100000000000000000000000000000000000000000000000000000000\"\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.hex2bytes","page":"Numbers","title":"Base.hex2bytes","text":"hex2bytes(itr)\n\nGiven an iterable itr of ASCII codes for a sequence of hexadecimal digits, returns a Vector{UInt8} of bytes corresponding to the binary representation: each successive pair of hexadecimal digits in itr gives the value of one byte in the return vector.\n\nThe length of itr must be even, and the returned array has half of the length of itr. See also hex2bytes! for an in-place version, and bytes2hex for the inverse.\n\ncompat: Julia 1.7\nCalling hex2bytes with iterators producing UInt8 values requires Julia 1.7 or later. In earlier versions, you can collect the iterator before calling hex2bytes.\n\nExamples\n\njulia> s = string(12345, base = 16)\n\"3039\"\n\njulia> hex2bytes(s)\n2-element Vector{UInt8}:\n 0x30\n 0x39\n\njulia> a = b\"01abEF\"\n6-element Base.CodeUnits{UInt8, String}:\n 0x30\n 0x31\n 0x61\n 0x62\n 0x45\n 0x46\n\njulia> hex2bytes(a)\n3-element Vector{UInt8}:\n 0x01\n 0xab\n 0xef\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.hex2bytes!","page":"Numbers","title":"Base.hex2bytes!","text":"hex2bytes!(dest::AbstractVector{UInt8}, itr)\n\nConvert an iterable itr of bytes representing a hexadecimal string to its binary representation, similar to hex2bytes except that the output is written in-place to dest. The length of dest must be half the length of itr.\n\ncompat: Julia 1.7\nCalling hex2bytes! with iterators producing UInt8 requires version 1.7. In earlier versions, you can collect the iterable before calling instead.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.bytes2hex","page":"Numbers","title":"Base.bytes2hex","text":"bytes2hex(itr) -> String\nbytes2hex(io::IO, itr)\n\nConvert an iterator itr of bytes to its hexadecimal string representation, either returning a String via bytes2hex(itr) or writing the string to an io stream via bytes2hex(io, itr). The hexadecimal characters are all lowercase.\n\ncompat: Julia 1.7\nCalling bytes2hex with arbitrary iterators producing UInt8 values requires Julia 1.7 or later. In earlier versions, you can collect the iterator before calling bytes2hex.\n\nExamples\n\njulia> a = string(12345, base = 16)\n\"3039\"\n\njulia> b = hex2bytes(a)\n2-element Vector{UInt8}:\n 0x30\n 0x39\n\njulia> bytes2hex(b)\n\"3039\"\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#General-Number-Functions-and-Constants","page":"Numbers","title":"General Number Functions and Constants","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Base.one\nBase.oneunit\nBase.zero\nBase.im\nBase.MathConstants.pi\nBase.MathConstants.ℯ\nBase.MathConstants.catalan\nBase.MathConstants.eulergamma\nBase.MathConstants.golden\nBase.Inf\nBase.Inf64\nBase.Inf32\nBase.Inf16\nBase.NaN\nBase.NaN64\nBase.NaN32\nBase.NaN16\nBase.issubnormal\nBase.isfinite\nBase.isinf\nBase.isnan\nBase.iszero\nBase.isone\nBase.nextfloat\nBase.prevfloat\nBase.isinteger\nBase.isreal\nCore.Float32(::Any)\nCore.Float64(::Any)\nBase.Rounding.rounding\nBase.Rounding.setrounding(::Type, ::Any)\nBase.Rounding.setrounding(::Function, ::Type, ::RoundingMode)\nBase.Rounding.get_zero_subnormals\nBase.Rounding.set_zero_subnormals","category":"page"},{"location":"base/numbers/#Base.one","page":"Numbers","title":"Base.one","text":"one(x)\none(T::type)\n\nReturn a multiplicative identity for x: a value such that one(x)*x == x*one(x) == x. If the multiplicative identity can be deduced from the type alone, then a type may be given as an argument to one (e.g. one(Int) will work because the multiplicative identity is the same for all instances of Int, but one(Matrix{Int}) is not defined because matrices of different shapes have different multiplicative identities.)\n\nIf possible, one(x) returns a value of the same type as x, and one(T) returns a value of type T. However, this may not be the case for types representing dimensionful quantities (e.g. time in days), since the multiplicative identity must be dimensionless. In that case, one(x) should return an identity value of the same precision (and shape, for matrices) as x.\n\nIf you want a quantity that is of the same type as x, or of type T, even if x is dimensionful, use oneunit instead.\n\nSee also the identity function, and I in LinearAlgebra for the identity matrix.\n\nExamples\n\njulia> one(3.7)\n1.0\n\njulia> one(Int)\n1\n\njulia> import Dates; one(Dates.Day(1))\n1\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.oneunit","page":"Numbers","title":"Base.oneunit","text":"oneunit(x::T)\noneunit(T::Type)\n\nReturn T(one(x)), where T is either the type of the argument, or the argument itself in cases where the oneunit can be deduced from the type alone. This differs from one for dimensionful quantities: one is dimensionless (a multiplicative identity) while oneunit is dimensionful (of the same type as x, or of type T).\n\nExamples\n\njulia> oneunit(3.7)\n1.0\n\njulia> import Dates; oneunit(Dates.Day)\n1 day\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.zero","page":"Numbers","title":"Base.zero","text":"zero(x)\nzero(::Type)\n\nGet the additive identity element for x. If the additive identity can be deduced from the type alone, then a type may be given as an argument to zero.\n\nFor example, zero(Int) will work because the additive identity is the same for all instances of Int, but zero(Vector{Int}) is not defined because vectors of different lengths have different additive identities.\n\nSee also iszero, one, oneunit, oftype.\n\nExamples\n\njulia> zero(1)\n0\n\njulia> zero(big\"2.0\")\n0.0\n\njulia> zero(rand(2,2))\n2×2 Matrix{Float64}:\n 0.0 0.0\n 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.im","page":"Numbers","title":"Base.im","text":"im\n\nThe imaginary unit.\n\nSee also: imag, angle, complex.\n\nExamples\n\njulia> im * im\n-1 + 0im\n\njulia> (2.0 + 3im)^2\n-5.0 + 12.0im\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.pi","page":"Numbers","title":"Base.MathConstants.pi","text":"π\npi\n\nThe constant pi.\n\nUnicode π can be typed by writing \\pi then pressing tab in the Julia REPL, and in many editors.\n\nSee also: sinpi, sincospi, deg2rad.\n\nExamples\n\njulia> pi\nπ = 3.1415926535897...\n\njulia> 1/2pi\n0.15915494309189535\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.ℯ","page":"Numbers","title":"Base.MathConstants.ℯ","text":"ℯ\ne\n\nThe constant ℯ.\n\nUnicode ℯ can be typed by writing \\euler and pressing tab in the Julia REPL, and in many editors.\n\nSee also: exp, cis, cispi.\n\nExamples\n\njulia> ℯ\nℯ = 2.7182818284590...\n\njulia> log(ℯ)\n1\n\njulia> ℯ^(im)π ≈ -1\ntrue\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.catalan","page":"Numbers","title":"Base.MathConstants.catalan","text":"catalan\n\nCatalan's constant.\n\nExamples\n\njulia> Base.MathConstants.catalan\ncatalan = 0.9159655941772...\n\njulia> sum(log(x)/(1+x^2) for x in 1:0.01:10^6) * 0.01\n0.9159466120554123\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.eulergamma","page":"Numbers","title":"Base.MathConstants.eulergamma","text":"γ\neulergamma\n\nEuler's constant.\n\nExamples\n\njulia> Base.MathConstants.eulergamma\nγ = 0.5772156649015...\n\njulia> dx = 10^-6;\n\njulia> sum(-exp(-x) * log(x) for x in dx:dx:100) * dx\n0.5772078382499133\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.golden","page":"Numbers","title":"Base.MathConstants.golden","text":"φ\ngolden\n\nThe golden ratio.\n\nExamples\n\njulia> Base.MathConstants.golden\nφ = 1.6180339887498...\n\njulia> (2ans - 1)^2 ≈ 5\ntrue\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.Inf","page":"Numbers","title":"Base.Inf","text":"Inf, Inf64\n\nPositive infinity of type Float64.\n\nSee also: isfinite, typemax, NaN, Inf32.\n\nExamples\n\njulia> π/0\nInf\n\njulia> +1.0 / -0.0\n-Inf\n\njulia> ℯ^-Inf\n0.0\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.Inf64","page":"Numbers","title":"Base.Inf64","text":"Inf, Inf64\n\nPositive infinity of type Float64.\n\nSee also: isfinite, typemax, NaN, Inf32.\n\nExamples\n\njulia> π/0\nInf\n\njulia> +1.0 / -0.0\n-Inf\n\njulia> ℯ^-Inf\n0.0\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.Inf32","page":"Numbers","title":"Base.Inf32","text":"Inf32\n\nPositive infinity of type Float32.\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.Inf16","page":"Numbers","title":"Base.Inf16","text":"Inf16\n\nPositive infinity of type Float16.\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.NaN","page":"Numbers","title":"Base.NaN","text":"NaN, NaN64\n\nA not-a-number value of type Float64.\n\nSee also: isnan, missing, NaN32, Inf.\n\nExamples\n\njulia> 0/0\nNaN\n\njulia> Inf - Inf\nNaN\n\njulia> NaN == NaN, isequal(NaN, NaN), isnan(NaN)\n(false, true, true)\n\nnote: Note\nAlways use isnan or isequal for checking for NaN. Using x === NaN may give unexpected results:julia> reinterpret(UInt32, NaN32)\n0x7fc00000\n\njulia> NaN32p1 = reinterpret(Float32, 0x7fc00001)\nNaN32\n\njulia> NaN32p1 === NaN32, isequal(NaN32p1, NaN32), isnan(NaN32p1)\n(false, true, true)\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.NaN64","page":"Numbers","title":"Base.NaN64","text":"NaN, NaN64\n\nA not-a-number value of type Float64.\n\nSee also: isnan, missing, NaN32, Inf.\n\nExamples\n\njulia> 0/0\nNaN\n\njulia> Inf - Inf\nNaN\n\njulia> NaN == NaN, isequal(NaN, NaN), isnan(NaN)\n(false, true, true)\n\nnote: Note\nAlways use isnan or isequal for checking for NaN. Using x === NaN may give unexpected results:julia> reinterpret(UInt32, NaN32)\n0x7fc00000\n\njulia> NaN32p1 = reinterpret(Float32, 0x7fc00001)\nNaN32\n\njulia> NaN32p1 === NaN32, isequal(NaN32p1, NaN32), isnan(NaN32p1)\n(false, true, true)\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.NaN32","page":"Numbers","title":"Base.NaN32","text":"NaN32\n\nA not-a-number value of type Float32.\n\nSee also: NaN.\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.NaN16","page":"Numbers","title":"Base.NaN16","text":"NaN16\n\nA not-a-number value of type Float16.\n\nSee also: NaN.\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.issubnormal","page":"Numbers","title":"Base.issubnormal","text":"issubnormal(f) -> Bool\n\nTest whether a floating point number is subnormal.\n\nAn IEEE floating point number is subnormal when its exponent bits are zero and its significand is not zero.\n\nExamples\n\njulia> floatmin(Float32)\n1.1754944f-38\n\njulia> issubnormal(1.0f-37)\nfalse\n\njulia> issubnormal(1.0f-38)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isfinite","page":"Numbers","title":"Base.isfinite","text":"isfinite(f) -> Bool\n\nTest whether a number is finite.\n\nExamples\n\njulia> isfinite(5)\ntrue\n\njulia> isfinite(NaN32)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isinf","page":"Numbers","title":"Base.isinf","text":"isinf(f) -> Bool\n\nTest whether a number is infinite.\n\nSee also: Inf, iszero, isfinite, isnan.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isnan","page":"Numbers","title":"Base.isnan","text":"isnan(f) -> Bool\n\nTest whether a number value is a NaN, an indeterminate value which is neither an infinity nor a finite number (\"not a number\").\n\nSee also: iszero, isone, isinf, ismissing.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.iszero","page":"Numbers","title":"Base.iszero","text":"iszero(x)\n\nReturn true if x == zero(x); if x is an array, this checks whether all of the elements of x are zero.\n\nSee also: isone, isinteger, isfinite, isnan.\n\nExamples\n\njulia> iszero(0.0)\ntrue\n\njulia> iszero([1, 9, 0])\nfalse\n\njulia> iszero([false, 0, 0])\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isone","page":"Numbers","title":"Base.isone","text":"isone(x)\n\nReturn true if x == one(x); if x is an array, this checks whether x is an identity matrix.\n\nExamples\n\njulia> isone(1.0)\ntrue\n\njulia> isone([1 0; 0 2])\nfalse\n\njulia> isone([1 0; 0 true])\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.nextfloat","page":"Numbers","title":"Base.nextfloat","text":"nextfloat(x::AbstractFloat, n::Integer)\n\nThe result of n iterative applications of nextfloat to x if n >= 0, or -n applications of prevfloat if n < 0.\n\n\n\n\n\nnextfloat(x::AbstractFloat)\n\nReturn the smallest floating point number y of the same type as x such x < y. If no such y exists (e.g. if x is Inf or NaN), then return x.\n\nSee also: prevfloat, eps, issubnormal.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.prevfloat","page":"Numbers","title":"Base.prevfloat","text":"prevfloat(x::AbstractFloat, n::Integer)\n\nThe result of n iterative applications of prevfloat to x if n >= 0, or -n applications of nextfloat if n < 0.\n\n\n\n\n\nprevfloat(x::AbstractFloat)\n\nReturn the largest floating point number y of the same type as x such y < x. If no such y exists (e.g. if x is -Inf or NaN), then return x.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isinteger","page":"Numbers","title":"Base.isinteger","text":"isinteger(x) -> Bool\n\nTest whether x is numerically equal to some integer.\n\nExamples\n\njulia> isinteger(4.0)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isreal","page":"Numbers","title":"Base.isreal","text":"isreal(x) -> Bool\n\nTest whether x or all its elements are numerically equal to some real number including infinities and NaNs. isreal(x) is true if isequal(x, real(x)) is true.\n\nExamples\n\njulia> isreal(5.)\ntrue\n\njulia> isreal(1 - 3im)\nfalse\n\njulia> isreal(Inf + 0im)\ntrue\n\njulia> isreal([4.; complex(0,1)])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Core.Float32-Tuple{Any}","page":"Numbers","title":"Core.Float32","text":"Float32(x [, mode::RoundingMode])\n\nCreate a Float32 from x. If x is not exactly representable then mode determines how x is rounded.\n\nExamples\n\njulia> Float32(1/3, RoundDown)\n0.3333333f0\n\njulia> Float32(1/3, RoundUp)\n0.33333334f0\n\nSee RoundingMode for available rounding modes.\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Core.Float64-Tuple{Any}","page":"Numbers","title":"Core.Float64","text":"Float64(x [, mode::RoundingMode])\n\nCreate a Float64 from x. If x is not exactly representable then mode determines how x is rounded.\n\nExamples\n\njulia> Float64(pi, RoundDown)\n3.141592653589793\n\njulia> Float64(pi, RoundUp)\n3.1415926535897936\n\nSee RoundingMode for available rounding modes.\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.Rounding.rounding","page":"Numbers","title":"Base.Rounding.rounding","text":"rounding(T)\n\nGet the current floating point rounding mode for type T, controlling the rounding of basic arithmetic functions (+, -, *, / and sqrt) and type conversion.\n\nSee RoundingMode for available modes.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.Rounding.setrounding-Tuple{Type, Any}","page":"Numbers","title":"Base.Rounding.setrounding","text":"setrounding(T, mode)\n\nSet the rounding mode of floating point type T, controlling the rounding of basic arithmetic functions (+, -, *, / and sqrt) and type conversion. Other numerical functions may give incorrect or invalid values when using rounding modes other than the default RoundNearest.\n\nNote that this is currently only supported for T == BigFloat.\n\nwarning: Warning\nThis function is not thread-safe. It will affect code running on all threads, but its behavior is undefined if called concurrently with computations that use the setting.\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.Rounding.setrounding-Tuple{Function, Type, RoundingMode}","page":"Numbers","title":"Base.Rounding.setrounding","text":"setrounding(f::Function, T, mode)\n\nChange the rounding mode of floating point type T for the duration of f. It is logically equivalent to:\n\nold = rounding(T)\nsetrounding(T, mode)\nf()\nsetrounding(T, old)\n\nSee RoundingMode for available rounding modes.\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.Rounding.get_zero_subnormals","page":"Numbers","title":"Base.Rounding.get_zero_subnormals","text":"get_zero_subnormals() -> Bool\n\nReturn false if operations on subnormal floating-point values (\"denormals\") obey rules for IEEE arithmetic, and true if they might be converted to zeros.\n\nwarning: Warning\nThis function only affects the current thread.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.Rounding.set_zero_subnormals","page":"Numbers","title":"Base.Rounding.set_zero_subnormals","text":"set_zero_subnormals(yes::Bool) -> Bool\n\nIf yes is false, subsequent floating-point operations follow rules for IEEE arithmetic on subnormal values (\"denormals\"). Otherwise, floating-point operations are permitted (but not required) to convert subnormal inputs or outputs to zero. Returns true unless yes==true but the hardware does not support zeroing of subnormal numbers.\n\nset_zero_subnormals(true) can speed up some computations on some hardware. However, it can break identities such as (x-y==0) == (x==y).\n\nwarning: Warning\nThis function only affects the current thread.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Integers","page":"Numbers","title":"Integers","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Base.count_ones\nBase.count_zeros\nBase.leading_zeros\nBase.leading_ones\nBase.trailing_zeros\nBase.trailing_ones\nBase.isodd\nBase.iseven\nBase.@int128_str\nBase.@uint128_str","category":"page"},{"location":"base/numbers/#Base.count_ones","page":"Numbers","title":"Base.count_ones","text":"count_ones(x::Integer) -> Integer\n\nNumber of ones in the binary representation of x.\n\nExamples\n\njulia> count_ones(7)\n3\n\njulia> count_ones(Int32(-1))\n32\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.count_zeros","page":"Numbers","title":"Base.count_zeros","text":"count_zeros(x::Integer) -> Integer\n\nNumber of zeros in the binary representation of x.\n\nExamples\n\njulia> count_zeros(Int32(2 ^ 16 - 1))\n16\n\njulia> count_zeros(-1)\n0\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.leading_zeros","page":"Numbers","title":"Base.leading_zeros","text":"leading_zeros(x::Integer) -> Integer\n\nNumber of zeros leading the binary representation of x.\n\nExamples\n\njulia> leading_zeros(Int32(1))\n31\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.leading_ones","page":"Numbers","title":"Base.leading_ones","text":"leading_ones(x::Integer) -> Integer\n\nNumber of ones leading the binary representation of x.\n\nExamples\n\njulia> leading_ones(UInt32(2 ^ 32 - 2))\n31\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.trailing_zeros","page":"Numbers","title":"Base.trailing_zeros","text":"trailing_zeros(x::Integer) -> Integer\n\nNumber of zeros trailing the binary representation of x.\n\nExamples\n\njulia> trailing_zeros(2)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.trailing_ones","page":"Numbers","title":"Base.trailing_ones","text":"trailing_ones(x::Integer) -> Integer\n\nNumber of ones trailing the binary representation of x.\n\nExamples\n\njulia> trailing_ones(3)\n2\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isodd","page":"Numbers","title":"Base.isodd","text":"isodd(x::Number) -> Bool\n\nReturn true if x is an odd integer (that is, an integer not divisible by 2), and false otherwise.\n\ncompat: Julia 1.7\nNon-Integer arguments require Julia 1.7 or later.\n\nExamples\n\njulia> isodd(9)\ntrue\n\njulia> isodd(10)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.iseven","page":"Numbers","title":"Base.iseven","text":"iseven(x::Number) -> Bool\n\nReturn true if x is an even integer (that is, an integer divisible by 2), and false otherwise.\n\ncompat: Julia 1.7\nNon-Integer arguments require Julia 1.7 or later.\n\nExamples\n\njulia> iseven(9)\nfalse\n\njulia> iseven(10)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Core.@int128_str","page":"Numbers","title":"Core.@int128_str","text":"@int128_str str\n\nParse str as an Int128. Throw an ArgumentError if the string is not a valid integer.\n\nExamples\n\njulia> int128\"123456789123\"\n123456789123\n\njulia> int128\"123456789123.4\"\nERROR: LoadError: ArgumentError: invalid base 10 digit '.' in \"123456789123.4\"\n[...]\n\n\n\n\n\n","category":"macro"},{"location":"base/numbers/#Core.@uint128_str","page":"Numbers","title":"Core.@uint128_str","text":"@uint128_str str\n\nParse str as an UInt128. Throw an ArgumentError if the string is not a valid integer.\n\nExamples\n\njulia> uint128\"123456789123\"\n0x00000000000000000000001cbe991a83\n\njulia> uint128\"-123456789123\"\nERROR: LoadError: ArgumentError: invalid base 10 digit '-' in \"-123456789123\"\n[...]\n\n\n\n\n\n","category":"macro"},{"location":"base/numbers/#BigFloats-and-BigInts","page":"Numbers","title":"BigFloats and BigInts","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"The BigFloat and BigInt types implements arbitrary-precision floating point and integer arithmetic, respectively. For BigFloat the GNU MPFR library is used, and for BigInt the GNU Multiple Precision Arithmetic Library (GMP) is used.","category":"page"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Base.MPFR.BigFloat(::Any, rounding::RoundingMode)\nBase.precision\nBase.MPFR.setprecision\nBase.GMP.BigInt(::Any)\nBase.@big_str","category":"page"},{"location":"base/numbers/#Base.MPFR.BigFloat-Tuple{Any, RoundingMode}","page":"Numbers","title":"Base.MPFR.BigFloat","text":"BigFloat(x::Union{Real, AbstractString} [, rounding::RoundingMode=rounding(BigFloat)]; [precision::Integer=precision(BigFloat)])\n\nCreate an arbitrary precision floating point number from x, with precision precision. The rounding argument specifies the direction in which the result should be rounded if the conversion cannot be done exactly. If not provided, these are set by the current global values.\n\nBigFloat(x::Real) is the same as convert(BigFloat,x), except if x itself is already BigFloat, in which case it will return a value with the precision set to the current global precision; convert will always return x.\n\nBigFloat(x::AbstractString) is identical to parse. This is provided for convenience since decimal literals are converted to Float64 when parsed, so BigFloat(2.1) may not yield what you expect.\n\nSee also:\n\n@big_str\nrounding and setrounding\nprecision and setprecision\n\ncompat: Julia 1.1\nprecision as a keyword argument requires at least Julia 1.1. In Julia 1.0 precision is the second positional argument (BigFloat(x, precision)).\n\nExamples\n\njulia> BigFloat(2.1) # 2.1 here is a Float64\n2.100000000000000088817841970012523233890533447265625\n\njulia> BigFloat(\"2.1\") # the closest BigFloat to 2.1\n2.099999999999999999999999999999999999999999999999999999999999999999999999999986\n\njulia> BigFloat(\"2.1\", RoundUp)\n2.100000000000000000000000000000000000000000000000000000000000000000000000000021\n\njulia> BigFloat(\"2.1\", RoundUp, precision=128)\n2.100000000000000000000000000000000000007\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.precision","page":"Numbers","title":"Base.precision","text":"precision(num::AbstractFloat; base::Integer=2)\nprecision(T::Type; base::Integer=2)\n\nGet the precision of a floating point number, as defined by the effective number of bits in the significand, or the precision of a floating-point type T (its current default, if T is a variable-precision type like BigFloat).\n\nIf base is specified, then it returns the maximum corresponding number of significand digits in that base.\n\ncompat: Julia 1.8\nThe base keyword requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.MPFR.setprecision","page":"Numbers","title":"Base.MPFR.setprecision","text":"setprecision([T=BigFloat,] precision::Int; base=2)\n\nSet the precision (in bits, by default) to be used for T arithmetic. If base is specified, then the precision is the minimum required to give at least precision digits in the given base.\n\nwarning: Warning\nThis function is not thread-safe. It will affect code running on all threads, but its behavior is undefined if called concurrently with computations that use the setting.\n\ncompat: Julia 1.8\nThe base keyword requires at least Julia 1.8.\n\n\n\n\n\nsetprecision(f::Function, [T=BigFloat,] precision::Integer; base=2)\n\nChange the T arithmetic precision (in the given base) for the duration of f. It is logically equivalent to:\n\nold = precision(BigFloat)\nsetprecision(BigFloat, precision)\nf()\nsetprecision(BigFloat, old)\n\nOften used as setprecision(T, precision) do ... end\n\nNote: nextfloat(), prevfloat() do not use the precision mentioned by setprecision.\n\ncompat: Julia 1.8\nThe base keyword requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.GMP.BigInt-Tuple{Any}","page":"Numbers","title":"Base.GMP.BigInt","text":"BigInt(x)\n\nCreate an arbitrary precision integer. x may be an Int (or anything that can be converted to an Int). The usual mathematical operators are defined for this type, and results are promoted to a BigInt.\n\nInstances can be constructed from strings via parse, or using the big string literal.\n\nExamples\n\njulia> parse(BigInt, \"42\")\n42\n\njulia> big\"313\"\n313\n\njulia> BigInt(10)^19\n10000000000000000000\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Core.@big_str","page":"Numbers","title":"Core.@big_str","text":"@big_str str\n\nParse a string into a BigInt or BigFloat, and throw an ArgumentError if the string is not a valid number. For integers _ is allowed in the string as a separator.\n\nExamples\n\njulia> big\"123_456\"\n123456\n\njulia> big\"7891.5\"\n7891.5\n\njulia> big\"_\"\nERROR: ArgumentError: invalid number format _ for BigInt or BigFloat\n[...]\n\nwarning: Warning\nUsing @big_str for constructing BigFloat values may not result in the behavior that might be naively expected: as a macro, @big_str obeys the global precision (setprecision) and rounding mode (setrounding) settings as they are at load time. Thus, a function like () -> precision(big\"0.3\") returns a constant whose value depends on the value of the precision at the point when the function is defined, not at the precision at the time when the function is called.\n\n\n\n\n\n","category":"macro"},{"location":"manual/missing/#missing","page":"Missing Values","title":"Missing Values","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Julia provides support for representing missing values in the statistical sense. This is for situations where no value is available for a variable in an observation, but a valid value theoretically exists. Missing values are represented via the missing object, which is the singleton instance of the type Missing. missing is equivalent to NULL in SQL and NA in R, and behaves like them in most situations.","category":"page"},{"location":"manual/missing/#Propagation-of-Missing-Values","page":"Missing Values","title":"Propagation of Missing Values","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"missing values propagate automatically when passed to standard mathematical operators and functions. For these functions, uncertainty about the value of one of the operands induces uncertainty about the result. In practice, this means a math operation involving a missing value generally returns missing:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> missing + 1\nmissing\n\njulia> \"a\" * missing\nmissing\n\njulia> abs(missing)\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Since missing is a normal Julia object, this propagation rule only works for functions which have opted in to implement this behavior. This can be achieved by:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"adding a specific method defined for arguments of type Missing,\naccepting arguments of this type, and passing them to functions which propagate them (like standard math operators).","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Packages should consider whether it makes sense to propagate missing values when defining new functions, and define methods appropriately if this is the case. Passing a missing value to a function which does not have a method accepting arguments of type Missing throws a MethodError, just like for any other type.","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Functions that do not propagate missing values can be made to do so by wrapping them in the passmissing function provided by the Missings.jl package. For example, f(x) becomes passmissing(f)(x).","category":"page"},{"location":"manual/missing/#Equality-and-Comparison-Operators","page":"Missing Values","title":"Equality and Comparison Operators","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Standard equality and comparison operators follow the propagation rule presented above: if any of the operands is missing, the result is missing. Here are a few examples:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> missing == 1\nmissing\n\njulia> missing == missing\nmissing\n\njulia> missing < 1\nmissing\n\njulia> 2 >= missing\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"In particular, note that missing == missing returns missing, so == cannot be used to test whether a value is missing. To test whether x is missing, use ismissing(x).","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Special comparison operators isequal and === are exceptions to the propagation rule. They will always return a Bool value, even in the presence of missing values, considering missing as equal to missing and as different from any other value. They can therefore be used to test whether a value is missing:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> missing === 1\nfalse\n\njulia> isequal(missing, 1)\nfalse\n\njulia> missing === missing\ntrue\n\njulia> isequal(missing, missing)\ntrue","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"The isless operator is another exception: missing is considered as greater than any other value. This operator is used by sort!, which therefore places missing values after all other values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> isless(1, missing)\ntrue\n\njulia> isless(missing, Inf)\nfalse\n\njulia> isless(missing, missing)\nfalse","category":"page"},{"location":"manual/missing/#Logical-operators","page":"Missing Values","title":"Logical operators","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Logical (or boolean) operators |, & and xor are another special case since they only propagate missing values when it is logically required. For these operators, whether or not the result is uncertain, depends on the particular operation. This follows the well-established rules of three-valued logic which are implemented by e.g. NULL in SQL and NA in R. This abstract definition corresponds to a relatively natural behavior which is best explained via concrete examples.","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Let us illustrate this principle with the logical \"or\" operator |. Following the rules of boolean logic, if one of the operands is true, the value of the other operand does not have an influence on the result, which will always be true:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> true | true\ntrue\n\njulia> true | false\ntrue\n\njulia> false | true\ntrue","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Based on this observation, we can conclude if one of the operands is true and the other missing, we know that the result is true in spite of the uncertainty about the actual value of one of the operands. If we had been able to observe the actual value of the second operand, it could only be true or false, and in both cases the result would be true. Therefore, in this particular case, missingness does not propagate:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> true | missing\ntrue\n\njulia> missing | true\ntrue","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"On the contrary, if one of the operands is false, the result could be either true or false depending on the value of the other operand. Therefore, if that operand is missing, the result has to be missing too:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> false | true\ntrue\n\njulia> true | false\ntrue\n\njulia> false | false\nfalse\n\njulia> false | missing\nmissing\n\njulia> missing | false\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"The behavior of the logical \"and\" operator & is similar to that of the | operator, with the difference that missingness does not propagate when one of the operands is false. For example, when that is the case of the first operand:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> false & false\nfalse\n\njulia> false & true\nfalse\n\njulia> false & missing\nfalse","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"On the other hand, missingness propagates when one of the operands is true, for example the first one:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> true & true\ntrue\n\njulia> true & false\nfalse\n\njulia> true & missing\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Finally, the \"exclusive or\" logical operator xor always propagates missing values, since both operands always have an effect on the result. Also note that the negation operator ! returns missing when the operand is missing, just like other unary operators.","category":"page"},{"location":"manual/missing/#Control-Flow-and-Short-Circuiting-Operators","page":"Missing Values","title":"Control Flow and Short-Circuiting Operators","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Control flow operators including if, while and the ternary operator x ? y : z do not allow for missing values. This is because of the uncertainty about whether the actual value would be true or false if we could observe it. This implies we do not know how the program should behave. In this case, a TypeError is thrown as soon as a missing value is encountered in this context:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> if missing\n println(\"here\")\n end\nERROR: TypeError: non-boolean (Missing) used in boolean context","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"For the same reason, contrary to logical operators presented above, the short-circuiting boolean operators && and || do not allow for missing values in situations where the value of the operand determines whether the next operand is evaluated or not. For example:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> missing || false\nERROR: TypeError: non-boolean (Missing) used in boolean context\n\njulia> missing && false\nERROR: TypeError: non-boolean (Missing) used in boolean context\n\njulia> true && missing && false\nERROR: TypeError: non-boolean (Missing) used in boolean context","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"In contrast, there is no error thrown when the result can be determined without the missing values. This is the case when the code short-circuits before evaluating the missing operand, and when the missing operand is the last one:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> true && missing\nmissing\n\njulia> false && missing\nfalse","category":"page"},{"location":"manual/missing/#Arrays-With-Missing-Values","page":"Missing Values","title":"Arrays With Missing Values","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Arrays containing missing values can be created like other arrays:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> [1, missing]\n2-element Vector{Union{Missing, Int64}}:\n 1\n missing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"As this example shows, the element type of such arrays is Union{Missing, T}, with T the type of the non-missing values. This reflects the fact that array entries can be either of type T (here, Int64) or of type Missing. This kind of array uses an efficient memory storage equivalent to an Array{T} holding the actual values combined with an Array{UInt8} indicating the type of the entry (i.e. whether it is Missing or T).","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Arrays allowing for missing values can be constructed with the standard syntax. Use Array{Union{Missing, T}}(missing, dims) to create arrays filled with missing values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> Array{Union{Missing, String}}(missing, 2, 3)\n2×3 Matrix{Union{Missing, String}}:\n missing missing missing\n missing missing missing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"note: Note\nUsing undef or similar may currently give an array filled with missing, but this is not the correct way to obtain such an array. Use a missing constructor as shown above instead.","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"An array with element type allowing missing entries (e.g. Vector{Union{Missing, T}}) which does not contain any missing entries can be converted to an array type that does not allow for missing entries (e.g. Vector{T}) using convert. If the array contains missing values, a MethodError is thrown during conversion:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> x = Union{Missing, String}[\"a\", \"b\"]\n2-element Vector{Union{Missing, String}}:\n \"a\"\n \"b\"\n\njulia> convert(Array{String}, x)\n2-element Vector{String}:\n \"a\"\n \"b\"\n\njulia> y = Union{Missing, String}[missing, \"b\"]\n2-element Vector{Union{Missing, String}}:\n missing\n \"b\"\n\njulia> convert(Array{String}, y)\nERROR: MethodError: Cannot `convert` an object of type Missing to an object of type String","category":"page"},{"location":"manual/missing/#Skipping-Missing-Values","page":"Missing Values","title":"Skipping Missing Values","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Since missing values propagate with standard mathematical operators, reduction functions return missing when called on arrays which contain missing values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> sum([1, missing])\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"In this situation, use the skipmissing function to skip missing values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> sum(skipmissing([1, missing]))\n1","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"This convenience function returns an iterator which filters out missing values efficiently. It can therefore be used with any function which supports iterators:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> x = skipmissing([3, missing, 2, 1])\nskipmissing(Union{Missing, Int64}[3, missing, 2, 1])\n\njulia> maximum(x)\n3\n\njulia> sum(x)\n6\n\njulia> mapreduce(sqrt, +, x)\n4.146264369941973","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Objects created by calling skipmissing on an array can be indexed using indices from the parent array. Indices corresponding to missing values are not valid for these objects, and an error is thrown when trying to use them (they are also skipped by keys and eachindex):","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> x[1]\n3\n\njulia> x[2]\nERROR: MissingException: the value at index (2,) is missing\n[...]","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"This allows functions which operate on indices to work in combination with skipmissing. This is notably the case for search and find functions. These functions return indices valid for the object returned by skipmissing, and are also the indices of the matching entries in the parent array:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> findall(==(1), x)\n1-element Vector{Int64}:\n 4\n\njulia> findfirst(!iszero, x)\n1\n\njulia> argmax(x)\n1","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Use collect to extract non-missing values and store them in an array:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> collect(x)\n3-element Vector{Int64}:\n 3\n 2\n 1","category":"page"},{"location":"manual/missing/#Logical-Operations-on-Arrays","page":"Missing Values","title":"Logical Operations on Arrays","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"The three-valued logic described above for logical operators is also used by logical functions applied to arrays. Thus, array equality tests using the == operator return missing whenever the result cannot be determined without knowing the actual value of the missing entry. In practice, this means missing is returned if all non-missing values of the compared arrays are equal, but one or both arrays contain missing values (possibly at different positions):","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> [1, missing] == [2, missing]\nfalse\n\njulia> [1, missing] == [1, missing]\nmissing\n\njulia> [1, 2, missing] == [1, missing, 2]\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"As for single values, use isequal to treat missing values as equal to other missing values, but different from non-missing values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> isequal([1, missing], [1, missing])\ntrue\n\njulia> isequal([1, 2, missing], [1, missing, 2])\nfalse","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Functions any and all also follow the rules of three-valued logic. Thus, returning missing when the result cannot be determined:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> all([true, missing])\nmissing\n\njulia> all([false, missing])\nfalse\n\njulia> any([true, missing])\ntrue\n\njulia> any([false, missing])\nmissing","category":"page"},{"location":"base/multi-threading/#lib-multithreading","page":"Multi-Threading","title":"Multi-Threading","text":"","category":"section"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.Threads.@threads\nBase.Threads.foreach\nBase.Threads.@spawn\nBase.Threads.threadid\nBase.Threads.maxthreadid\nBase.Threads.nthreads\nBase.Threads.threadpool\nBase.Threads.nthreadpools\nBase.Threads.threadpoolsize\nBase.Threads.ngcthreads","category":"page"},{"location":"base/multi-threading/#Base.Threads.@threads","page":"Multi-Threading","title":"Base.Threads.@threads","text":"Threads.@threads [schedule] for ... end\n\nA macro to execute a for loop in parallel. The iteration space is distributed to coarse-grained tasks. This policy can be specified by the schedule argument. The execution of the loop waits for the evaluation of all iterations.\n\nSee also: @spawn and pmap in Distributed.\n\nExtended help\n\nSemantics\n\nUnless stronger guarantees are specified by the scheduling option, the loop executed by @threads macro have the following semantics.\n\nThe @threads macro executes the loop body in an unspecified order and potentially concurrently. It does not specify the exact assignments of the tasks and the worker threads. The assignments can be different for each execution. The loop body code (including any code transitively called from it) must not make any assumptions about the distribution of iterations to tasks or the worker thread in which they are executed. The loop body for each iteration must be able to make forward progress independent of other iterations and be free from data races. As such, invalid synchronizations across iterations may deadlock while unsynchronized memory accesses may result in undefined behavior.\n\nFor example, the above conditions imply that:\n\nA lock taken in an iteration must be released within the same iteration.\nCommunicating between iterations using blocking primitives like Channels is incorrect.\nWrite only to locations not shared across iterations (unless a lock or atomic operation is used).\nUnless the :static schedule is used, the value of threadid() may change even within a single iteration. See Task Migration.\n\nSchedulers\n\nWithout the scheduler argument, the exact scheduling is unspecified and varies across Julia releases. Currently, :dynamic is used when the scheduler is not specified.\n\ncompat: Julia 1.5\nThe schedule argument is available as of Julia 1.5.\n\n:dynamic (default)\n\n:dynamic scheduler executes iterations dynamically to available worker threads. Current implementation assumes that the workload for each iteration is uniform. However, this assumption may be removed in the future.\n\nThis scheduling option is merely a hint to the underlying execution mechanism. However, a few properties can be expected. The number of Tasks used by :dynamic scheduler is bounded by a small constant multiple of the number of available worker threads (Threads.threadpoolsize()). Each task processes contiguous regions of the iteration space. Thus, @threads :dynamic for x in xs; f(x); end is typically more efficient than @sync for x in xs; @spawn f(x); end if length(xs) is significantly larger than the number of the worker threads and the run-time of f(x) is relatively smaller than the cost of spawning and synchronizing a task (typically less than 10 microseconds).\n\ncompat: Julia 1.8\nThe :dynamic option for the schedule argument is available and the default as of Julia 1.8.\n\n:greedy\n\n:greedy scheduler spawns up to Threads.threadpoolsize() tasks, each greedily working on the given iterated values as they are produced. As soon as one task finishes its work, it takes the next value from the iterator. Work done by any individual task is not necessarily on contiguous values from the iterator. The given iterator may produce values forever, only the iterator interface is required (no indexing).\n\nThis scheduling option is generally a good choice if the workload of individual iterations is not uniform/has a large spread.\n\ncompat: Julia 1.11\nThe :greedy option for the schedule argument is available as of Julia 1.11.\n\n:static\n\n:static scheduler creates one task per thread and divides the iterations equally among them, assigning each task specifically to each thread. In particular, the value of threadid() is guaranteed to be constant within one iteration. Specifying :static is an error if used from inside another @threads loop or from a thread other than 1.\n\nnote: Note\n:static scheduling exists for supporting transition of code written before Julia 1.3. In newly written library functions, :static scheduling is discouraged because the functions using this option cannot be called from arbitrary worker threads.\n\nExamples\n\nTo illustrate of the different scheduling strategies, consider the following function busywait containing a non-yielding timed loop that runs for a given number of seconds.\n\njulia> function busywait(seconds)\n tstart = time_ns()\n while (time_ns() - tstart) / 1e9 < seconds\n end\n end\n\njulia> @time begin\n Threads.@spawn busywait(5)\n Threads.@threads :static for i in 1:Threads.threadpoolsize()\n busywait(1)\n end\n end\n6.003001 seconds (16.33 k allocations: 899.255 KiB, 0.25% compilation time)\n\njulia> @time begin\n Threads.@spawn busywait(5)\n Threads.@threads :dynamic for i in 1:Threads.threadpoolsize()\n busywait(1)\n end\n end\n2.012056 seconds (16.05 k allocations: 883.919 KiB, 0.66% compilation time)\n\nThe :dynamic example takes 2 seconds since one of the non-occupied threads is able to run two of the 1-second iterations to complete the for loop.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.Threads.foreach","page":"Multi-Threading","title":"Base.Threads.foreach","text":"Threads.foreach(f, channel::Channel;\n schedule::Threads.AbstractSchedule=Threads.FairSchedule(),\n ntasks=Threads.threadpoolsize())\n\nSimilar to foreach(f, channel), but iteration over channel and calls to f are split across ntasks tasks spawned by Threads.@spawn. This function will wait for all internally spawned tasks to complete before returning.\n\nIf schedule isa FairSchedule, Threads.foreach will attempt to spawn tasks in a manner that enables Julia's scheduler to more freely load-balance work items across threads. This approach generally has higher per-item overhead, but may perform better than StaticSchedule in concurrence with other multithreaded workloads.\n\nIf schedule isa StaticSchedule, Threads.foreach will spawn tasks in a manner that incurs lower per-item overhead than FairSchedule, but is less amenable to load-balancing. This approach thus may be more suitable for fine-grained, uniform workloads, but may perform worse than FairSchedule in concurrence with other multithreaded workloads.\n\nExamples\n\njulia> n = 20\n\njulia> c = Channel{Int}(ch -> foreach(i -> put!(ch, i), 1:n), 1)\n\njulia> d = Channel{Int}(n) do ch\n f = i -> put!(ch, i^2)\n Threads.foreach(f, c)\n end\n\njulia> collect(d)\ncollect(d) = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400]\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.@spawn","page":"Multi-Threading","title":"Base.Threads.@spawn","text":"Threads.@spawn [:default|:interactive] expr\n\nCreate a Task and schedule it to run on any available thread in the specified threadpool (:default if unspecified). The task is allocated to a thread once one becomes available. To wait for the task to finish, call wait on the result of this macro, or call fetch to wait and then obtain its return value.\n\nValues can be interpolated into @spawn via $, which copies the value directly into the constructed underlying closure. This allows you to insert the value of a variable, isolating the asynchronous code from changes to the variable's value in the current task.\n\nnote: Note\nThe thread that the task runs on may change if the task yields, therefore threadid() should not be treated as constant for a task. See Task Migration, and the broader multi-threading manual for further important caveats. See also the chapter on threadpools.\n\ncompat: Julia 1.3\nThis macro is available as of Julia 1.3.\n\ncompat: Julia 1.4\nInterpolating values via $ is available as of Julia 1.4.\n\ncompat: Julia 1.9\nA threadpool may be specified as of Julia 1.9.\n\nExamples\n\njulia> t() = println(\"Hello from \", Threads.threadid());\n\njulia> tasks = fetch.([Threads.@spawn t() for i in 1:4]);\nHello from 1\nHello from 1\nHello from 3\nHello from 4\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.Threads.threadid","page":"Multi-Threading","title":"Base.Threads.threadid","text":"Threads.threadid() -> Int\n\nGet the ID number of the current thread of execution. The master thread has ID 1.\n\nExamples\n\njulia> Threads.threadid()\n1\n\njulia> Threads.@threads for i in 1:4\n println(Threads.threadid())\n end\n4\n2\n5\n4\n\nnote: Note\nThe thread that a task runs on may change if the task yields, which is known as Task Migration. For this reason in most cases it is not safe to use threadid() to index into, say, a vector of buffer or stateful objects.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.maxthreadid","page":"Multi-Threading","title":"Base.Threads.maxthreadid","text":"Threads.maxthreadid() -> Int\n\nGet a lower bound on the number of threads (across all thread pools) available to the Julia process, with atomic-acquire semantics. The result will always be greater than or equal to threadid() as well as threadid(task) for any task you were able to observe before calling maxthreadid.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.nthreads","page":"Multi-Threading","title":"Base.Threads.nthreads","text":"Threads.nthreads(:default | :interactive) -> Int\n\nGet the current number of threads within the specified thread pool. The threads in :interactive have id numbers 1:nthreads(:interactive), and the threads in :default have id numbers in nthreads(:interactive) .+ (1:nthreads(:default)).\n\nSee also BLAS.get_num_threads and BLAS.set_num_threads in the LinearAlgebra standard library, and nprocs() in the Distributed standard library and Threads.maxthreadid().\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.threadpool","page":"Multi-Threading","title":"Base.Threads.threadpool","text":"Threads.threadpool(tid = threadid()) -> Symbol\n\nReturns the specified thread's threadpool; either :default, :interactive, or :foreign.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.nthreadpools","page":"Multi-Threading","title":"Base.Threads.nthreadpools","text":"Threads.nthreadpools() -> Int\n\nReturns the number of threadpools currently configured.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.threadpoolsize","page":"Multi-Threading","title":"Base.Threads.threadpoolsize","text":"Threads.threadpoolsize(pool::Symbol = :default) -> Int\n\nGet the number of threads available to the default thread pool (or to the specified thread pool).\n\nSee also: BLAS.get_num_threads and BLAS.set_num_threads in the LinearAlgebra standard library, and nprocs() in the Distributed standard library.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.ngcthreads","page":"Multi-Threading","title":"Base.Threads.ngcthreads","text":"Threads.ngcthreads() -> Int\n\nReturns the number of GC threads currently configured. This includes both mark threads and concurrent sweep threads.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"See also Multi-Threading.","category":"page"},{"location":"base/multi-threading/#Atomic-operations","page":"Multi-Threading","title":"Atomic operations","text":"","category":"section"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"atomic","category":"page"},{"location":"base/multi-threading/#atomic","page":"Multi-Threading","title":"atomic","text":"Unsafe pointer operations are compatible with loading and storing pointers declared with _Atomic and std::atomic type in C11 and C++23 respectively. An error may be thrown if there is not support for atomically loading the Julia type T.\n\nSee also: unsafe_load, unsafe_modify!, unsafe_replace!, unsafe_store!, unsafe_swap!\n\n\n\n\n\n","category":"keyword"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.@atomic\nBase.@atomicswap\nBase.@atomicreplace\nBase.@atomiconce\nBase.AtomicMemory","category":"page"},{"location":"base/multi-threading/#Base.@atomic","page":"Multi-Threading","title":"Base.@atomic","text":"@atomic var\n@atomic order ex\n\nMark var or ex as being performed atomically, if ex is a supported expression. If no order is specified it defaults to :sequentially_consistent.\n\n@atomic a.b.x = new\n@atomic a.b.x += addend\n@atomic :release a.b.x = new\n@atomic :acquire_release a.b.x += addend\n\nPerform the store operation expressed on the right atomically and return the new value.\n\nWith =, this operation translates to a setproperty!(a.b, :x, new) call. With any operator also, this operation translates to a modifyproperty!(a.b, :x, +, addend)[2] call.\n\n@atomic a.b.x max arg2\n@atomic a.b.x + arg2\n@atomic max(a.b.x, arg2)\n@atomic :acquire_release max(a.b.x, arg2)\n@atomic :acquire_release a.b.x + arg2\n@atomic :acquire_release a.b.x max arg2\n\nPerform the binary operation expressed on the right atomically. Store the result into the field in the first argument and return the values (old, new).\n\nThis operation translates to a modifyproperty!(a.b, :x, func, arg2) call.\n\nSee Per-field atomics section in the manual for more details.\n\nExamples\n\njulia> mutable struct Atomic{T}; @atomic x::T; end\n\njulia> a = Atomic(1)\nAtomic{Int64}(1)\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n1\n\njulia> @atomic :sequentially_consistent a.x = 2 # set field x of a, with sequential consistency\n2\n\njulia> @atomic a.x += 1 # increment field x of a, with sequential consistency\n3\n\njulia> @atomic a.x + 1 # increment field x of a, with sequential consistency\n3 => 4\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n4\n\njulia> @atomic max(a.x, 10) # change field x of a to the max value, with sequential consistency\n4 => 10\n\njulia> @atomic a.x max 5 # again change field x of a to the max value, with sequential consistency\n10 => 10\n\ncompat: Julia 1.7\nThis functionality requires at least Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.@atomicswap","page":"Multi-Threading","title":"Base.@atomicswap","text":"@atomicswap a.b.x = new\n@atomicswap :sequentially_consistent a.b.x = new\n\nStores new into a.b.x and returns the old value of a.b.x.\n\nThis operation translates to a swapproperty!(a.b, :x, new) call.\n\nSee Per-field atomics section in the manual for more details.\n\nExamples\n\njulia> mutable struct Atomic{T}; @atomic x::T; end\n\njulia> a = Atomic(1)\nAtomic{Int64}(1)\n\njulia> @atomicswap a.x = 2+2 # replace field x of a with 4, with sequential consistency\n1\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n4\n\ncompat: Julia 1.7\nThis functionality requires at least Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.@atomicreplace","page":"Multi-Threading","title":"Base.@atomicreplace","text":"@atomicreplace a.b.x expected => desired\n@atomicreplace :sequentially_consistent a.b.x expected => desired\n@atomicreplace :sequentially_consistent :monotonic a.b.x expected => desired\n\nPerform the conditional replacement expressed by the pair atomically, returning the values (old, success::Bool). Where success indicates whether the replacement was completed.\n\nThis operation translates to a replaceproperty!(a.b, :x, expected, desired) call.\n\nSee Per-field atomics section in the manual for more details.\n\nExamples\n\njulia> mutable struct Atomic{T}; @atomic x::T; end\n\njulia> a = Atomic(1)\nAtomic{Int64}(1)\n\njulia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency\n(old = 1, success = true)\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n2\n\njulia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency\n(old = 2, success = false)\n\njulia> xchg = 2 => 0; # replace field x of a with 0 if it was 2, with sequential consistency\n\njulia> @atomicreplace a.x xchg\n(old = 2, success = true)\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n0\n\ncompat: Julia 1.7\nThis functionality requires at least Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.@atomiconce","page":"Multi-Threading","title":"Base.@atomiconce","text":"@atomiconce a.b.x = value\n@atomiconce :sequentially_consistent a.b.x = value\n@atomiconce :sequentially_consistent :monotonic a.b.x = value\n\nPerform the conditional assignment of value atomically if it was previously unset, returning the value success::Bool. Where success indicates whether the assignment was completed.\n\nThis operation translates to a setpropertyonce!(a.b, :x, value) call.\n\nSee Per-field atomics section in the manual for more details.\n\nExamples\n\njulia> mutable struct AtomicOnce\n @atomic x\n AtomicOnce() = new()\n end\n\njulia> a = AtomicOnce()\nAtomicOnce(#undef)\n\njulia> @atomiconce a.x = 1 # set field x of a to 1, if unset, with sequential consistency\ntrue\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n1\n\njulia> @atomiconce a.x = 1 # set field x of a to 1, if unset, with sequential consistency\nfalse\n\ncompat: Julia 1.11\nThis functionality requires at least Julia 1.11.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Core.AtomicMemory","page":"Multi-Threading","title":"Core.AtomicMemory","text":"AtomicMemory{T} == GenericMemory{:atomic, T, Core.CPU}\n\nOne-dimensional dense array with elements of type T, where each element is independently atomic when accessed, and cannot be set non-atomically.\n\ncompat: Julia 1.11\nThis type requires Julia 1.11 or later.\n\n\n\n\n\n","category":"type"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"There are also optional memory ordering parameters for the unsafe set of functions, that select the C/C++-compatible versions of these atomic operations, if that parameter is specified to unsafe_load, unsafe_store!, unsafe_swap!, unsafe_replace!, and unsafe_modify!.","category":"page"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"warning: Warning\nThe following APIs are deprecated, though support for them is likely to remain for several releases.","category":"page"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.Threads.Atomic\nBase.Threads.atomic_cas!\nBase.Threads.atomic_xchg!\nBase.Threads.atomic_add!\nBase.Threads.atomic_sub!\nBase.Threads.atomic_and!\nBase.Threads.atomic_nand!\nBase.Threads.atomic_or!\nBase.Threads.atomic_xor!\nBase.Threads.atomic_max!\nBase.Threads.atomic_min!\nBase.Threads.atomic_fence","category":"page"},{"location":"base/multi-threading/#Base.Threads.Atomic","page":"Multi-Threading","title":"Base.Threads.Atomic","text":"Threads.Atomic{T}\n\nHolds a reference to an object of type T, ensuring that it is only accessed atomically, i.e. in a thread-safe manner.\n\nOnly certain \"simple\" types can be used atomically, namely the primitive boolean, integer, and float-point types. These are Bool, Int8...Int128, UInt8...UInt128, and Float16...Float64.\n\nNew atomic objects can be created from a non-atomic values; if none is specified, the atomic object is initialized with zero.\n\nAtomic objects can be accessed using the [] notation:\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> x[] = 1\n1\n\njulia> x[]\n1\n\nAtomic operations use an atomic_ prefix, such as atomic_add!, atomic_xchg!, etc.\n\n\n\n\n\n","category":"type"},{"location":"base/multi-threading/#Base.Threads.atomic_cas!","page":"Multi-Threading","title":"Base.Threads.atomic_cas!","text":"Threads.atomic_cas!(x::Atomic{T}, cmp::T, newval::T) where T\n\nAtomically compare-and-set x\n\nAtomically compares the value in x with cmp. If equal, write newval to x. Otherwise, leaves x unmodified. Returns the old value in x. By comparing the returned value to cmp (via ===) one knows whether x was modified and now holds the new value newval.\n\nFor further details, see LLVM's cmpxchg instruction.\n\nThis function can be used to implement transactional semantics. Before the transaction, one records the value in x. After the transaction, the new value is stored only if x has not been modified in the mean time.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_cas!(x, 4, 2);\n\njulia> x\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_cas!(x, 3, 2);\n\njulia> x\nBase.Threads.Atomic{Int64}(2)\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_xchg!","page":"Multi-Threading","title":"Base.Threads.atomic_xchg!","text":"Threads.atomic_xchg!(x::Atomic{T}, newval::T) where T\n\nAtomically exchange the value in x\n\nAtomically exchanges the value in x with newval. Returns the old value.\n\nFor further details, see LLVM's atomicrmw xchg instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_xchg!(x, 2)\n3\n\njulia> x[]\n2\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_add!","page":"Multi-Threading","title":"Base.Threads.atomic_add!","text":"Threads.atomic_add!(x::Atomic{T}, val::T) where T <: ArithmeticTypes\n\nAtomically add val to x\n\nPerforms x[] += val atomically. Returns the old value. Not defined for Atomic{Bool}.\n\nFor further details, see LLVM's atomicrmw add instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_add!(x, 2)\n3\n\njulia> x[]\n5\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_sub!","page":"Multi-Threading","title":"Base.Threads.atomic_sub!","text":"Threads.atomic_sub!(x::Atomic{T}, val::T) where T <: ArithmeticTypes\n\nAtomically subtract val from x\n\nPerforms x[] -= val atomically. Returns the old value. Not defined for Atomic{Bool}.\n\nFor further details, see LLVM's atomicrmw sub instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_sub!(x, 2)\n3\n\njulia> x[]\n1\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_and!","page":"Multi-Threading","title":"Base.Threads.atomic_and!","text":"Threads.atomic_and!(x::Atomic{T}, val::T) where T\n\nAtomically bitwise-and x with val\n\nPerforms x[] &= val atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw and instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_and!(x, 2)\n3\n\njulia> x[]\n2\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_nand!","page":"Multi-Threading","title":"Base.Threads.atomic_nand!","text":"Threads.atomic_nand!(x::Atomic{T}, val::T) where T\n\nAtomically bitwise-nand (not-and) x with val\n\nPerforms x[] = ~(x[] & val) atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw nand instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_nand!(x, 2)\n3\n\njulia> x[]\n-3\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_or!","page":"Multi-Threading","title":"Base.Threads.atomic_or!","text":"Threads.atomic_or!(x::Atomic{T}, val::T) where T\n\nAtomically bitwise-or x with val\n\nPerforms x[] |= val atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw or instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(5)\nBase.Threads.Atomic{Int64}(5)\n\njulia> Threads.atomic_or!(x, 7)\n5\n\njulia> x[]\n7\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_xor!","page":"Multi-Threading","title":"Base.Threads.atomic_xor!","text":"Threads.atomic_xor!(x::Atomic{T}, val::T) where T\n\nAtomically bitwise-xor (exclusive-or) x with val\n\nPerforms x[] $= val atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw xor instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(5)\nBase.Threads.Atomic{Int64}(5)\n\njulia> Threads.atomic_xor!(x, 7)\n5\n\njulia> x[]\n2\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_max!","page":"Multi-Threading","title":"Base.Threads.atomic_max!","text":"Threads.atomic_max!(x::Atomic{T}, val::T) where T\n\nAtomically store the maximum of x and val in x\n\nPerforms x[] = max(x[], val) atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw max instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(5)\nBase.Threads.Atomic{Int64}(5)\n\njulia> Threads.atomic_max!(x, 7)\n5\n\njulia> x[]\n7\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_min!","page":"Multi-Threading","title":"Base.Threads.atomic_min!","text":"Threads.atomic_min!(x::Atomic{T}, val::T) where T\n\nAtomically store the minimum of x and val in x\n\nPerforms x[] = min(x[], val) atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw min instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(7)\nBase.Threads.Atomic{Int64}(7)\n\njulia> Threads.atomic_min!(x, 5)\n7\n\njulia> x[]\n5\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_fence","page":"Multi-Threading","title":"Base.Threads.atomic_fence","text":"Threads.atomic_fence()\n\nInsert a sequential-consistency memory fence\n\nInserts a memory fence with sequentially-consistent ordering semantics. There are algorithms where this is needed, i.e. where an acquire/release ordering is insufficient.\n\nThis is likely a very expensive operation. Given that all other atomic operations in Julia already have acquire/release semantics, explicit fences should not be necessary in most cases.\n\nFor further details, see LLVM's fence instruction.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#ccall-using-a-libuv-threadpool-(Experimental)","page":"Multi-Threading","title":"ccall using a libuv threadpool (Experimental)","text":"","category":"section"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.@threadcall","category":"page"},{"location":"base/multi-threading/#Base.@threadcall","page":"Multi-Threading","title":"Base.@threadcall","text":"@threadcall((cfunc, clib), rettype, (argtypes...), argvals...)\n\nThe @threadcall macro is called in the same way as ccall but does the work in a different thread. This is useful when you want to call a blocking C function without causing the current julia thread to become blocked. Concurrency is limited by size of the libuv thread pool, which defaults to 4 threads but can be increased by setting the UV_THREADPOOL_SIZE environment variable and restarting the julia process.\n\nNote that the called function should never call back into Julia.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Low-level-synchronization-primitives","page":"Multi-Threading","title":"Low-level synchronization primitives","text":"","category":"section"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"These building blocks are used to create the regular synchronization objects.","category":"page"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.Threads.SpinLock","category":"page"},{"location":"base/multi-threading/#Base.Threads.SpinLock","page":"Multi-Threading","title":"Base.Threads.SpinLock","text":"SpinLock()\n\nCreate a non-reentrant, test-and-test-and-set spin lock. Recursive use will result in a deadlock. This kind of lock should only be used around code that takes little time to execute and does not block (e.g. perform I/O). In general, ReentrantLock should be used instead.\n\nEach lock must be matched with an unlock. If !islocked(lck::SpinLock) holds, trylock(lck) succeeds unless there are other tasks attempting to hold the lock \"at the same time.\"\n\nTest-and-test-and-set spin locks are quickest up to about 30ish contending threads. If you have more contention than that, different synchronization approaches should be considered.\n\n\n\n\n\n","category":"type"},{"location":"devdocs/llvm-passes/#Custom-LLVM-Passes","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Julia has a number of custom LLVM passes. Broadly, they can be classified into passes that are required to be run to maintain Julia semantics, and passes that take advantage of Julia semantics to optimize LLVM IR.","category":"page"},{"location":"devdocs/llvm-passes/#Semantic-Passes","page":"Custom LLVM Passes","title":"Semantic Passes","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"These passes are used to transform LLVM IR into code that is legal to be run on a CPU. Their main purpose is to enable simpler IR to be emitted by codegen, which then enables other LLVM passes to optimize common patterns.","category":"page"},{"location":"devdocs/llvm-passes/#CPUFeatures","page":"Custom LLVM Passes","title":"CPUFeatures","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-cpufeatures.cpp\nClass Name: CPUFeaturesPass\nOpt Name: module(CPUFeatures)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass lowers the julia.cpu.have_fma.(f32|f64) intrinsic to either true or false, depending on the target architecture and target features present on the function. This intrinsic is often used to determine if using algorithms dependent on fast fused multiply-add operations is better than using standard algorithms not dependent on such instructions.","category":"page"},{"location":"devdocs/llvm-passes/#DemoteFloat16","page":"Custom LLVM Passes","title":"DemoteFloat16","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-demote-float16.cpp\nClassName: DemoteFloat16Pass\nOpt Name function(DemoteFloat16)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass replaces float16 operations with float32 operations on architectures that do not natively support float16 operations. This is done by inserting fpext and fptrunc instructions around any float16 operation. On architectures that do support native float16 operations, this pass is a no-op.","category":"page"},{"location":"devdocs/llvm-passes/#LateGCLowering","page":"Custom LLVM Passes","title":"LateGCLowering","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-late-gc-lowering.cpp\nClass Name: LateLowerGCPass\nOpt Name: function(LateLowerGCFrame)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass performs most of the GC rooting work required to track pointers between GC safepoints. It also lowers several intrinsics to their corresponding instruction translation, and is permitted to violate the non-integral invariants previously established (pointer_from_objref is lowered to a ptrtoint instruction here). This pass typically occupies the most time out of all the custom Julia passes, due to its dataflow algorithm to minimize the number of objects live at any safepoint.","category":"page"},{"location":"devdocs/llvm-passes/#FinalGCLowering","page":"Custom LLVM Passes","title":"FinalGCLowering","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-final-gc-lowering.cpp\nClass Name: FinalLowerGCPass\nOpt Name: module(FinalLowerGC)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass lowers a few last intrinsics to their final form targeting functions in the libjulia library. Separating this from LateGCLowering enables other backends (GPU compilation) to supply their own custom lowerings for these intrinsics, enabling the Julia pipeline to be used on those backends as well.","category":"page"},{"location":"devdocs/llvm-passes/#LowerHandlers","page":"Custom LLVM Passes","title":"LowerHandlers","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-lower-handlers.cpp\nClass Name: LowerExcHandlersPass\nOpt Name: function(LowerExcHandlers)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass lowers exception handling intrinsics into calls to runtime functions that are actually called when handling exceptions.","category":"page"},{"location":"devdocs/llvm-passes/#RemoveNI","page":"Custom LLVM Passes","title":"RemoveNI","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-remove-ni.cpp\nClass Name: RemoveNIPass\nOpt Name: module(RemoveNI)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass removes the non-integral address spaces from the module's datalayout string. This enables the backend to lower Julia's custom address spaces directly to machine code, without a costly rewrite of every pointer operation to address space 0.","category":"page"},{"location":"devdocs/llvm-passes/#SIMDLoop","page":"Custom LLVM Passes","title":"SIMDLoop","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-simdloop.cpp\nClass Name: LowerSIMDLoopPass\nOpt Name: loop(LowerSIMDLoop)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass acts as the main driver of the @simd annotation. Codegen inserts a !llvm.loopid marker at the back branch of a loop, which this pass uses to identify loops that were originally marked with @simd. Then, this pass looks for a chain of floating point operations that form a reduce and adds the contract and reassoc fast math flags to allow reassociation (and thus vectorization). This pass does not preserve either loop information nor inference correctness, so it may violate Julia semantics in surprising ways. If the loop was annotated with ivdep as well, then the pass marks the loop as having no loop-carried dependencies (the resulting behavior is undefined if the user annotation was incorrect or gets applied to the wrong loop).","category":"page"},{"location":"devdocs/llvm-passes/#LowerPTLS","page":"Custom LLVM Passes","title":"LowerPTLS","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-ptls.cpp\nClass Name: LowerPTLSPass\nOpt Name: module(LowerPTLSPass)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass lowers thread-local Julia intrinsics to assembly instructions. Julia relies on thread-local storage for garbage collection and multithreading task scheduling. When compiling code for system images and package images, this pass replaces calls to intrinsics with loads from global variables that are initialized at load time.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"If codegen produces a function with a swiftself argument and calling convention, this pass assumes the swiftself argument is the pgcstack and will replace the intrinsics with that argument. Doing so provides speedups on architectures that have slow thread local storage accesses.","category":"page"},{"location":"devdocs/llvm-passes/#RemoveAddrspaces","page":"Custom LLVM Passes","title":"RemoveAddrspaces","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-remove-addrspaces.cpp\nClass Name: RemoveAddrspacesPass\nOpt Name: module(RemoveAddrspaces)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass renames pointers in one address space to another address space. This is used to remove Julia-specific address spaces from LLVM IR.","category":"page"},{"location":"devdocs/llvm-passes/#RemoveJuliaAddrspaces","page":"Custom LLVM Passes","title":"RemoveJuliaAddrspaces","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-remove-addrspaces.cpp\nClass Name: RemoveJuliaAddrspacesPass\nOpt Name: module(RemoveJuliaAddrspaces)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass removes Julia-specific address spaces from LLVM IR. It is mostly used for displaying LLVM IR in a less cluttered format. Internally, it is implemented off the RemoveAddrspaces pass.","category":"page"},{"location":"devdocs/llvm-passes/#Multiversioning","page":"Custom LLVM Passes","title":"Multiversioning","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-multiversioning.cpp\nClass Name: MultiVersioningPass\nOpt Name: module(JuliaMultiVersioning)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass performs modifications to a module to create functions that are optimized for running on different architectures (see sysimg.md and pkgimg.md for more details). Implementation-wise, it clones functions and applies different target-specific attributes to them to allow the optimizer to use advanced features such as vectorization and instruction scheduling for that platform. It also creates some infrastructure to enable the Julia image loader to select the appropriate version of the function to call based on the architecture the loader is running on. The target-specific attributes are controlled by the julia.mv.specs module flag, which during compilation is derived from the JULIA_CPU_TARGET environment variable. The pass must also be enabled by providing a julia.mv.enable module flag with a value of 1.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"warning: Warning\n","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Use of llvmcall with multiversioning is dangerous. llvmcall enables access to features not typically exposed by the Julia APIs, and are therefore usually not available on all architectures. If multiversioning is enabled and code generation is requested for a target architecture that does not support the feature required by an llvmcall expression, LLVM will probably error out, likely with an abort and the message LLVM ERROR: Do not know how to split the result of this operator!.","category":"page"},{"location":"devdocs/llvm-passes/#GCInvariantVerifier","page":"Custom LLVM Passes","title":"GCInvariantVerifier","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-gc-invariant-verifier.cpp\nClass Name: GCInvariantVerifierPass\nOpt Name: module(GCInvariantVerifier)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass is used to verify Julia's invariants about LLVM IR. This includes things such as the nonexistence of ptrtoint in Julia's non-integral address spaces [nislides] and the existence of only blessed addrspacecast instructions (Tracked -> Derived, 0 -> Tracked, etc). It performs no transformations on IR.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"[nislides]: https://llvm.org/devmtg/2015-02/slides/chisnall-pointers-not-int.pdf","category":"page"},{"location":"devdocs/llvm-passes/#Optimization-Passes","page":"Custom LLVM Passes","title":"Optimization Passes","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"These passes are used to perform transformations on LLVM IR that LLVM will not perform itself, e.g. fast math flag propagation, escape analysis, and optimizations on Julia-specific internal functions. They use knowledge about Julia's semantics to perform these optimizations.","category":"page"},{"location":"devdocs/llvm-passes/#CombineMulAdd","page":"Custom LLVM Passes","title":"CombineMulAdd","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-muladd.cpp\nClass Name: CombineMulAddPass\nOpt Name: function(CombineMulAdd)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass serves to optimize the particular combination of a regular fmul with a fast fadd into a contract fmul with a fast fadd. This is later optimized by the backend to a fused multiply-add instruction, which can provide significantly faster operations at the cost of more unpredictable semantics.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"note: Note\nThis optimization only occurs when the fmul has a single use, which is the fast fadd.","category":"page"},{"location":"devdocs/llvm-passes/#AllocOpt","page":"Custom LLVM Passes","title":"AllocOpt","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-alloc-opt.cpp\nClass Name: AllocOptPass\nOpt Name: function(AllocOpt)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Julia does not have the concept of a program stack as a place to allocate mutable objects. However, allocating objects on the stack reduces GC pressure and is critical for GPU compilation. Thus, AllocOpt performs heap to stack conversion of objects that it can prove do not escape the current function. It also performs a number of other optimizations on allocations, such as removing allocations that are never used, optimizing typeof calls to freshly allocated objects, and removing stores to allocations that are immediately overwritten. The escape analysis implementation is located in llvm-alloc-helpers.cpp. Currently, this pass does not use information from EscapeAnalysis.jl, though that may change in the future.","category":"page"},{"location":"devdocs/llvm-passes/#PropagateJuliaAddrspaces","page":"Custom LLVM Passes","title":"PropagateJuliaAddrspaces","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-propagate-addrspaces.cpp\nClass Name: PropagateJuliaAddrspacesPass\nOpt Name: function(PropagateJuliaAddrspaces)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass is used to propagate Julia-specific address spaces through operations on pointers. LLVM is not allowed to introduce or remove addrspacecast instructions by optimizations, so this pass acts to eliminate redundant addrspace casts by replacing operations with their equivalent in a Julia address space. For more information on Julia's address spaces, see (TODO link to llvm.md).","category":"page"},{"location":"devdocs/llvm-passes/#JuliaLICM","page":"Custom LLVM Passes","title":"JuliaLICM","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-julia-licm.cpp\nClass Name: JuliaLICMPass\nOpt Name: loop(JuliaLICM)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass is used to hoist Julia-specific intrinsics out of loops. Specifically, it performs the following transformations:","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Hoist gc_preserve_begin and sink gc_preserve_end out of loops when the preserved objects are loop-invariant.\nSince objects preserved within a loop are likely preserved for the duration of the loop, this transformation can reduce the number of gc_preserve_begin/gc_preserve_end pairs in the IR. This makes it easier for the LateLowerGCPass to identify where particular objects are preserved.\nHoist write barriers with invariant objects\nHere we assume that there are only two generations that an object can be a part of. Given that, a write barrier needs to only execute once for any pair of the same object. Thus, we can hoist write barriers out of loops when the object being written to is loop-invariant.\nHoist allocations out of loops when they do not escape the loop\nWe use a very conservative definition of escape here, the same as the one used in AllocOptPass. This transformation can reduce the number of allocations in the IR, even when an allocation escapes the function altogether.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"!!!note","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass is required to preserve LLVM's [MemorySSA](https://llvm.org/docs/MemorySSA.html) ([Short Video](https://www.youtube.com/watch?v=bdxWmryoHak), [Longer Video](https://www.youtube.com/watch?v=1e5y6WDbXCQ)) and [ScalarEvolution](https://baziotis.cs.illinois.edu/compilers/introduction-to-scalar-evolution.html) ([Newer Slides](https://llvm.org/devmtg/2018-04/slides/Absar-ScalarEvolution.pdf) [Older Slides](https://llvm.org/devmtg/2009-10/ScalarEvolutionAndLoopOptimization.pdf)) analyses.","category":"page"},{"location":"devdocs/callconv/#Calling-Conventions","page":"Calling Conventions","title":"Calling Conventions","text":"","category":"section"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"Julia uses three calling conventions for four distinct purposes:","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"Name Prefix Purpose\nNative julia_ Speed via specialized signatures\nJL Call jlcall_ Wrapper for generic calls\nJL Call jl_ Builtins\nC ABI jlcapi_ Wrapper callable from C","category":"page"},{"location":"devdocs/callconv/#Julia-Native-Calling-Convention","page":"Calling Conventions","title":"Julia Native Calling Convention","text":"","category":"section"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"The native calling convention is designed for fast non-generic calls. It usually uses a specialized signature.","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"LLVM ghosts (zero-length types) are omitted.\nLLVM scalars and vectors are passed by value.\nLLVM aggregates (arrays and structs) are passed by reference.","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"A small return values is returned as LLVM return values. A large return values is returned via the \"structure return\" (sret) convention, where the caller provides a pointer to a return slot.","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"An argument or return values that is a homogeneous tuple is sometimes represented as an LLVM vector instead of an LLVM array.","category":"page"},{"location":"devdocs/callconv/#JL-Call-Convention","page":"Calling Conventions","title":"JL Call Convention","text":"","category":"section"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"The JL Call convention is for builtins and generic dispatch. Hand-written functions using this convention are declared via the macro JL_CALLABLE. The convention uses exactly 3 parameters:","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"F - Julia representation of function that is being applied\nargs - pointer to array of pointers to boxes\nnargs - length of the array","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"The return value is a pointer to a box.","category":"page"},{"location":"devdocs/callconv/#C-ABI","page":"Calling Conventions","title":"C ABI","text":"","category":"section"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"C ABI wrappers enable calling Julia from C. The wrapper calls a function using the native calling convention.","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"Tuples are always represented as C arrays.","category":"page"},{"location":"devdocs/compiler/#High-level-Overview-of-the-Native-Code-Generation-Process","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"","category":"section"},{"location":"devdocs/compiler/#Representation-of-Pointers","page":"High-level Overview of the Native-Code Generation Process","title":"Representation of Pointers","text":"","category":"section"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"When emitting code to an object file, pointers will be emitted as relocations. The deserialization code will ensure any object that pointed to one of these constants gets recreated and contains the right runtime pointer.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Otherwise, they will be emitted as literal constants.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"To emit one of these objects, call literal_pointer_val. It'll handle tracking the Julia value and the LLVM global, ensuring they are valid both for the current runtime and after deserialization.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"When emitted into the object file, these globals are stored as references in a large gvals table. This allows the deserializer to reference them by index, and implement a custom manual mechanism similar to a Global Offset Table (GOT) to restore them.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Function pointers are handled similarly. They are stored as values in a large fvals table. Like globals, this allows the deserializer to reference them by index.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Note that extern functions are handled separately, with names, via the usual symbol resolution mechanism in the linker.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Note too that ccall functions are also handled separately, via a manual GOT and Procedure Linkage Table (PLT).","category":"page"},{"location":"devdocs/compiler/#Representation-of-Intermediate-Values","page":"High-level Overview of the Native-Code Generation Process","title":"Representation of Intermediate Values","text":"","category":"section"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Values are passed around in a jl_cgval_t struct. This represents an R-value, and includes enough information to determine how to assign or pass it somewhere.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"They are created via one of the helper constructors, usually: mark_julia_type (for immediate values) and mark_julia_slot (for pointers to values).","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The function convert_julia_type can transform between any two types. It returns an R-value with cgval.typ set to typ. It'll cast the object to the requested representation, making heap boxes, allocating stack copies, and computing tagged unions as needed to change the representation.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"By contrast update_julia_type will change cgval.typ to typ, only if it can be done at zero-cost (i.e. without emitting any code).","category":"page"},{"location":"devdocs/compiler/#Union-representation","page":"High-level Overview of the Native-Code Generation Process","title":"Union representation","text":"","category":"section"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Inferred union types may be stack allocated via a tagged type representation.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The primitive routines that need to be able to handle tagged unions are:","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"mark-type\nload-local\nstore-local\nisa\nis\nemit_typeof\nemit_sizeof\nboxed\nunbox\nspecialized cc-ret","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Everything else should be possible to handle in inference by using these primitives to implement union-splitting.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The representation of the tagged-union is as a pair of < void* union, byte selector >. The selector is fixed-size as byte & 0x7f, and will union-tag the first 126 isbits. It records the one-based depth-first count into the type-union of the isbits objects inside. An index of zero indicates that the union* is actually a tagged heap-allocated jl_value_t*, and needs to be treated as normal for a boxed object rather than as a tagged union.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The high bit of the selector (byte & 0x80) can be tested to determine if the void* is actually a heap-allocated (jl_value_t*) box, thus avoiding the cost of re-allocating a box, while maintaining the ability to efficiently handle union-splitting based on the low bits.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"It is guaranteed that byte & 0x7f is an exact test for the type, if the value can be represented by a tag – it will never be marked byte = 0x80. It is not necessary to also test the type-tag when testing isa.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The union* memory region may be allocated at any size. The only constraint is that it is big enough to contain the data currently specified by selector. It might not be big enough to contain the union of all types that could be stored there according to the associated Union type field. Use appropriate care when copying.","category":"page"},{"location":"devdocs/compiler/#Specialized-Calling-Convention-Signature-Representation","page":"High-level Overview of the Native-Code Generation Process","title":"Specialized Calling Convention Signature Representation","text":"","category":"section"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"A jl_returninfo_t object describes the calling convention details of any callable.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"If any of the arguments or return type of a method can be represented unboxed, and the method is not varargs, it'll be given an optimized calling convention signature based on its specTypes and rettype fields.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The general principles are that:","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Primitive types get passed in int/float registers.\nTuples of VecElement types get passed in vector registers.\nStructs get passed on the stack.\nReturn values are handle similarly to arguments, with a size-cutoff at which they will instead be returned via a hidden sret argument.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The total logic for this is implemented by get_specsig_function and deserves_sret.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Additionally, if the return type is a union, it may be returned as a pair of values (a pointer and a tag). If the union values can be stack-allocated, then sufficient space to store them will also be passed as a hidden first argument. It is up to the callee whether the returned pointer will point to this space, a boxed object, or even other constant memory.","category":"page"},{"location":"base/parallel/#Tasks","page":"Tasks","title":"Tasks","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"Core.Task\nBase.@task\nBase.@async\nBase.asyncmap\nBase.asyncmap!\nBase.current_task\nBase.istaskdone\nBase.istaskstarted\nBase.istaskfailed\nBase.task_local_storage(::Any)\nBase.task_local_storage(::Any, ::Any)\nBase.task_local_storage(::Function, ::Any, ::Any)","category":"page"},{"location":"base/parallel/#Core.Task","page":"Tasks","title":"Core.Task","text":"Task(func)\n\nCreate a Task (i.e. coroutine) to execute the given function func (which must be callable with no arguments). The task exits when this function returns. The task will run in the \"world age\" from the parent at construction when scheduled.\n\nwarning: Warning\nBy default tasks will have the sticky bit set to true t.sticky. This models the historic default for @async. Sticky tasks can only be run on the worker thread they are first scheduled on. To obtain the behavior of Threads.@spawn set the sticky bit manually to false.\n\nExamples\n\njulia> a() = sum(i for i in 1:1000);\n\njulia> b = Task(a);\n\nIn this example, b is a runnable Task that hasn't started yet.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.@task","page":"Tasks","title":"Base.@task","text":"@task\n\nWrap an expression in a Task without executing it, and return the Task. This only creates a task, and does not run it.\n\nExamples\n\njulia> a1() = sum(i for i in 1:1000);\n\njulia> b = @task a1();\n\njulia> istaskstarted(b)\nfalse\n\njulia> schedule(b);\n\njulia> yield();\n\njulia> istaskdone(b)\ntrue\n\n\n\n\n\n","category":"macro"},{"location":"base/parallel/#Base.@async","page":"Tasks","title":"Base.@async","text":"@async\n\nWrap an expression in a Task and add it to the local machine's scheduler queue.\n\nValues can be interpolated into @async via $, which copies the value directly into the constructed underlying closure. This allows you to insert the value of a variable, isolating the asynchronous code from changes to the variable's value in the current task.\n\nwarning: Warning\nIt is strongly encouraged to favor Threads.@spawn over @async always even when no parallelism is required especially in publicly distributed libraries. This is because a use of @async disables the migration of the parent task across worker threads in the current implementation of Julia. Thus, seemingly innocent use of @async in a library function can have a large impact on the performance of very different parts of user applications.\n\ncompat: Julia 1.4\nInterpolating values via $ is available as of Julia 1.4.\n\n\n\n\n\n","category":"macro"},{"location":"base/parallel/#Base.asyncmap","page":"Tasks","title":"Base.asyncmap","text":"asyncmap(f, c...; ntasks=0, batch_size=nothing)\n\nUses multiple concurrent tasks to map f over a collection (or multiple equal length collections). For multiple collection arguments, f is applied elementwise.\n\nntasks specifies the number of tasks to run concurrently. Depending on the length of the collections, if ntasks is unspecified, up to 100 tasks will be used for concurrent mapping.\n\nntasks can also be specified as a zero-arg function. In this case, the number of tasks to run in parallel is checked before processing every element and a new task started if the value of ntasks_func is greater than the current number of tasks.\n\nIf batch_size is specified, the collection is processed in batch mode. f must then be a function that must accept a Vector of argument tuples and must return a vector of results. The input vector will have a length of batch_size or less.\n\nThe following examples highlight execution in different tasks by returning the objectid of the tasks in which the mapping function is executed.\n\nFirst, with ntasks undefined, each element is processed in a different task.\n\njulia> tskoid() = objectid(current_task());\n\njulia> asyncmap(x->tskoid(), 1:5)\n5-element Array{UInt64,1}:\n 0x6e15e66c75c75853\n 0x440f8819a1baa682\n 0x9fb3eeadd0c83985\n 0xebd3e35fe90d4050\n 0x29efc93edce2b961\n\njulia> length(unique(asyncmap(x->tskoid(), 1:5)))\n5\n\nWith ntasks=2 all elements are processed in 2 tasks.\n\njulia> asyncmap(x->tskoid(), 1:5; ntasks=2)\n5-element Array{UInt64,1}:\n 0x027ab1680df7ae94\n 0xa23d2f80cd7cf157\n 0x027ab1680df7ae94\n 0xa23d2f80cd7cf157\n 0x027ab1680df7ae94\n\njulia> length(unique(asyncmap(x->tskoid(), 1:5; ntasks=2)))\n2\n\nWith batch_size defined, the mapping function needs to be changed to accept an array of argument tuples and return an array of results. map is used in the modified mapping function to achieve this.\n\njulia> batch_func(input) = map(x->string(\"args_tuple: \", x, \", element_val: \", x[1], \", task: \", tskoid()), input)\nbatch_func (generic function with 1 method)\n\njulia> asyncmap(batch_func, 1:5; ntasks=2, batch_size=2)\n5-element Array{String,1}:\n \"args_tuple: (1,), element_val: 1, task: 9118321258196414413\"\n \"args_tuple: (2,), element_val: 2, task: 4904288162898683522\"\n \"args_tuple: (3,), element_val: 3, task: 9118321258196414413\"\n \"args_tuple: (4,), element_val: 4, task: 4904288162898683522\"\n \"args_tuple: (5,), element_val: 5, task: 9118321258196414413\"\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.asyncmap!","page":"Tasks","title":"Base.asyncmap!","text":"asyncmap!(f, results, c...; ntasks=0, batch_size=nothing)\n\nLike asyncmap, but stores output in results rather than returning a collection.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.current_task","page":"Tasks","title":"Base.current_task","text":"current_task()\n\nGet the currently running Task.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.istaskdone","page":"Tasks","title":"Base.istaskdone","text":"istaskdone(t::Task) -> Bool\n\nDetermine whether a task has exited.\n\nExamples\n\njulia> a2() = sum(i for i in 1:1000);\n\njulia> b = Task(a2);\n\njulia> istaskdone(b)\nfalse\n\njulia> schedule(b);\n\njulia> yield();\n\njulia> istaskdone(b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.istaskstarted","page":"Tasks","title":"Base.istaskstarted","text":"istaskstarted(t::Task) -> Bool\n\nDetermine whether a task has started executing.\n\nExamples\n\njulia> a3() = sum(i for i in 1:1000);\n\njulia> b = Task(a3);\n\njulia> istaskstarted(b)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.istaskfailed","page":"Tasks","title":"Base.istaskfailed","text":"istaskfailed(t::Task) -> Bool\n\nDetermine whether a task has exited because an exception was thrown.\n\nExamples\n\njulia> a4() = error(\"task failed\");\n\njulia> b = Task(a4);\n\njulia> istaskfailed(b)\nfalse\n\njulia> schedule(b);\n\njulia> yield();\n\njulia> istaskfailed(b)\ntrue\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.task_local_storage-Tuple{Any}","page":"Tasks","title":"Base.task_local_storage","text":"task_local_storage(key)\n\nLook up the value of a key in the current task's task-local storage.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.task_local_storage-Tuple{Any, Any}","page":"Tasks","title":"Base.task_local_storage","text":"task_local_storage(key, value)\n\nAssign a value to a key in the current task's task-local storage.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.task_local_storage-Tuple{Function, Any, Any}","page":"Tasks","title":"Base.task_local_storage","text":"task_local_storage(body, key, value)\n\nCall the function body with a modified task-local storage, in which value is assigned to key; the previous value of key, or lack thereof, is restored afterwards. Useful for emulating dynamic scoping.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Scheduling","page":"Tasks","title":"Scheduling","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"Base.yield\nBase.yieldto\nBase.sleep\nBase.schedule","category":"page"},{"location":"base/parallel/#Base.yield","page":"Tasks","title":"Base.yield","text":"yield()\n\nSwitch to the scheduler to allow another scheduled task to run. A task that calls this function is still runnable, and will be restarted immediately if there are no other runnable tasks.\n\n\n\n\n\nyield(t::Task, arg = nothing)\n\nA fast, unfair-scheduling version of schedule(t, arg); yield() which immediately yields to t before calling the scheduler.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.yieldto","page":"Tasks","title":"Base.yieldto","text":"yieldto(t::Task, arg = nothing)\n\nSwitch to the given task. The first time a task is switched to, the task's function is called with no arguments. On subsequent switches, arg is returned from the task's last call to yieldto. This is a low-level call that only switches tasks, not considering states or scheduling in any way. Its use is discouraged.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.sleep","page":"Tasks","title":"Base.sleep","text":"sleep(seconds)\n\nBlock the current task for a specified number of seconds. The minimum sleep time is 1 millisecond or input of 0.001.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.schedule","page":"Tasks","title":"Base.schedule","text":"schedule(t::Task, [val]; error=false)\n\nAdd a Task to the scheduler's queue. This causes the task to run constantly when the system is otherwise idle, unless the task performs a blocking operation such as wait.\n\nIf a second argument val is provided, it will be passed to the task (via the return value of yieldto) when it runs again. If error is true, the value is raised as an exception in the woken task.\n\nwarning: Warning\nIt is incorrect to use schedule on an arbitrary Task that has already been started. See the API reference for more information.\n\nExamples\n\njulia> a5() = sum(i for i in 1:1000);\n\njulia> b = Task(a5);\n\njulia> istaskstarted(b)\nfalse\n\njulia> schedule(b);\n\njulia> yield();\n\njulia> istaskstarted(b)\ntrue\n\njulia> istaskdone(b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#lib-task-sync","page":"Tasks","title":"Synchronization","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"Base.errormonitor\nBase.@sync\nBase.wait\nBase.waitany\nBase.waitall\nBase.fetch(t::Task)\nBase.fetch(x::Any)\nBase.timedwait\n\nBase.Condition\nBase.Threads.Condition\nBase.Threads.Event\nBase.notify\nBase.reset(::Base.Threads.Event)\n\nBase.Semaphore\nBase.acquire\nBase.release\n\nBase.AbstractLock\nBase.lock\nBase.unlock\nBase.trylock\nBase.islocked\nBase.ReentrantLock\nBase.@lock\nBase.Lockable","category":"page"},{"location":"base/parallel/#Base.errormonitor","page":"Tasks","title":"Base.errormonitor","text":"errormonitor(t::Task)\n\nPrint an error log to stderr if task t fails.\n\nExamples\n\njulia> Base._wait(errormonitor(Threads.@spawn error(\"task failed\")))\nUnhandled Task ERROR: task failed\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.@sync","page":"Tasks","title":"Base.@sync","text":"@sync\n\nWait until all lexically-enclosed uses of @async, @spawn, Distributed.@spawnat and Distributed.@distributed are complete. All exceptions thrown by enclosed async operations are collected and thrown as a CompositeException.\n\nExamples\n\njulia> Threads.nthreads()\n4\n\njulia> @sync begin\n Threads.@spawn println(\"Thread-id $(Threads.threadid()), task 1\")\n Threads.@spawn println(\"Thread-id $(Threads.threadid()), task 2\")\n end;\nThread-id 3, task 1\nThread-id 1, task 2\n\n\n\n\n\n","category":"macro"},{"location":"base/parallel/#Base.wait","page":"Tasks","title":"Base.wait","text":"Special note for Threads.Condition:\n\nThe caller must be holding the lock that owns a Threads.Condition before calling this method. The calling task will be blocked until some other task wakes it, usually by calling notify on the same Threads.Condition object. The lock will be atomically released when blocking (even if it was locked recursively), and will be reacquired before returning.\n\n\n\n\n\nwait(r::Future)\n\nWait for a value to become available for the specified Future.\n\n\n\n\n\nwait(r::RemoteChannel, args...)\n\nWait for a value to become available on the specified RemoteChannel.\n\n\n\n\n\nwait([x])\n\nBlock the current task until some event occurs, depending on the type of the argument:\n\nChannel: Wait for a value to be appended to the channel.\nCondition: Wait for notify on a condition and return the val parameter passed to notify. Waiting on a condition additionally allows passing first=true which results in the waiter being put first in line to wake up on notify instead of the usual first-in-first-out behavior.\nProcess: Wait for a process or process chain to exit. The exitcode field of a process can be used to determine success or failure.\nTask: Wait for a Task to finish. If the task fails with an exception, a TaskFailedException (which wraps the failed task) is thrown. Waiting on a task additionally allows passing throw=false which prevents throwing a TaskFailedException when the task fails.\nRawFD: Wait for changes on a file descriptor (see the FileWatching package).\n\nIf no argument is passed, the task blocks for an undefined period. A task can only be restarted by an explicit call to schedule or yieldto.\n\nOften wait is called within a while loop to ensure a waited-for condition is met before proceeding.\n\n\n\n\n\nwait(c::Channel)\n\nBlocks until the Channel isready.\n\njulia> c = Channel(1);\n\njulia> isready(c)\nfalse\n\njulia> task = Task(() -> wait(c));\n\njulia> schedule(task);\n\njulia> istaskdone(task) # task is blocked because channel is not ready\nfalse\n\njulia> put!(c, 1);\n\njulia> istaskdone(task) # task is now unblocked\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.waitany","page":"Tasks","title":"Base.waitany","text":"waitany(tasks; throw=true) -> (done_tasks, remaining_tasks)\n\nWait until at least one of the given tasks have been completed.\n\nIf throw is true, throw CompositeException when one of the completed tasks completes with an exception.\n\nThe return value consists of two task vectors. The first one consists of completed tasks, and the other consists of uncompleted tasks.\n\nwarning: Warning\nThis may scale poorly compared to writing code that uses multiple individual tasks that each runs serially, since this needs to scan the list of tasks each time and synchronize with each one every time this is called. Or consider using waitall(tasks; failfast=true) instead.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.waitall","page":"Tasks","title":"Base.waitall","text":"waitall(tasks; failfast=true, throw=true) -> (done_tasks, remaining_tasks)\n\nWait until all the given tasks have been completed.\n\nIf failfast is true, the function will return when at least one of the given tasks is finished by exception. If throw is true, throw CompositeException when one of the completed tasks has failed.\n\nfailfast and throw keyword arguments work independently; when only throw=true is specified, this function waits for all the tasks to complete.\n\nThe return value consists of two task vectors. The first one consists of completed tasks, and the other consists of uncompleted tasks.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.fetch-Tuple{Task}","page":"Tasks","title":"Base.fetch","text":"fetch(t::Task)\n\nWait for a Task to finish, then return its result value. If the task fails with an exception, a TaskFailedException (which wraps the failed task) is thrown.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.fetch-Tuple{Any}","page":"Tasks","title":"Base.fetch","text":"fetch(x::Any)\n\nReturn x.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.timedwait","page":"Tasks","title":"Base.timedwait","text":"timedwait(testcb, timeout::Real; pollint::Real=0.1)\n\nWait until testcb() returns true or timeout seconds have passed, whichever is earlier. The test function is polled every pollint seconds. The minimum value for pollint is 0.001 seconds, that is, 1 millisecond.\n\nReturn :ok or :timed_out.\n\nExamples\n\njulia> cb() = (sleep(5); return);\n\njulia> t = @async cb();\n\njulia> timedwait(()->istaskdone(t), 1)\n:timed_out\n\njulia> timedwait(()->istaskdone(t), 6.5)\n:ok\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.Condition","page":"Tasks","title":"Base.Condition","text":"Condition()\n\nCreate an edge-triggered event source that tasks can wait for. Tasks that call wait on a Condition are suspended and queued. Tasks are woken up when notify is later called on the Condition. Waiting on a condition can return a value or raise an error if the optional arguments of notify are used. Edge triggering means that only tasks waiting at the time notify is called can be woken up. For level-triggered notifications, you must keep extra state to keep track of whether a notification has happened. The Channel and Threads.Event types do this, and can be used for level-triggered events.\n\nThis object is NOT thread-safe. See Threads.Condition for a thread-safe version.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.Threads.Condition","page":"Tasks","title":"Base.Threads.Condition","text":"Threads.Condition([lock])\n\nA thread-safe version of Base.Condition.\n\nTo call wait or notify on a Threads.Condition, you must first call lock on it. When wait is called, the lock is atomically released during blocking, and will be reacquired before wait returns. Therefore idiomatic use of a Threads.Condition c looks like the following:\n\nlock(c)\ntry\n while !thing_we_are_waiting_for\n wait(c)\n end\nfinally\n unlock(c)\nend\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.Event","page":"Tasks","title":"Base.Event","text":"Event([autoreset=false])\n\nCreate a level-triggered event source. Tasks that call wait on an Event are suspended and queued until notify is called on the Event. After notify is called, the Event remains in a signaled state and tasks will no longer block when waiting for it, until reset is called.\n\nIf autoreset is true, at most one task will be released from wait for each call to notify.\n\nThis provides an acquire & release memory ordering on notify/wait.\n\ncompat: Julia 1.1\nThis functionality requires at least Julia 1.1.\n\ncompat: Julia 1.8\nThe autoreset functionality and memory ordering guarantee requires at least Julia 1.8.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.notify","page":"Tasks","title":"Base.notify","text":"notify(condition, val=nothing; all=true, error=false)\n\nWake up tasks waiting for a condition, passing them val. If all is true (the default), all waiting tasks are woken, otherwise only one is. If error is true, the passed value is raised as an exception in the woken tasks.\n\nReturn the count of tasks woken up. Return 0 if no tasks are waiting on condition.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.reset-Tuple{Base.Event}","page":"Tasks","title":"Base.reset","text":"reset(::Event)\n\nReset an Event back into an un-set state. Then any future calls to wait will block until notify is called again.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.Semaphore","page":"Tasks","title":"Base.Semaphore","text":"Semaphore(sem_size)\n\nCreate a counting semaphore that allows at most sem_size acquires to be in use at any time. Each acquire must be matched with a release.\n\nThis provides a acquire & release memory ordering on acquire/release calls.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.acquire","page":"Tasks","title":"Base.acquire","text":"acquire(s::Semaphore)\n\nWait for one of the sem_size permits to be available, blocking until one can be acquired.\n\n\n\n\n\nacquire(f, s::Semaphore)\n\nExecute f after acquiring from Semaphore s, and release on completion or error.\n\nFor example, a do-block form that ensures only 2 calls of foo will be active at the same time:\n\ns = Base.Semaphore(2)\n@sync for _ in 1:100\n Threads.@spawn begin\n Base.acquire(s) do\n foo()\n end\n end\nend\n\ncompat: Julia 1.8\nThis method requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.release","page":"Tasks","title":"Base.release","text":"release(s::Semaphore)\n\nReturn one permit to the pool, possibly allowing another task to acquire it and resume execution.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.AbstractLock","page":"Tasks","title":"Base.AbstractLock","text":"AbstractLock\n\nAbstract supertype describing types that implement the synchronization primitives: lock, trylock, unlock, and islocked.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.lock","page":"Tasks","title":"Base.lock","text":"lock(lock)\n\nAcquire the lock when it becomes available. If the lock is already locked by a different task/thread, wait for it to become available.\n\nEach lock must be matched by an unlock.\n\n\n\n\n\nlock(f::Function, lock)\n\nAcquire the lock, execute f with the lock held, and release the lock when f returns. If the lock is already locked by a different task/thread, wait for it to become available.\n\nWhen this function returns, the lock has been released, so the caller should not attempt to unlock it.\n\nSee also: @lock.\n\ncompat: Julia 1.7\nUsing a Channel as the second argument requires Julia 1.7 or later.\n\n\n\n\n\nlock(f::Function, l::Lockable)\n\nAcquire the lock associated with l, execute f with the lock held, and release the lock when f returns. f will receive one positional argument: the value wrapped by l. If the lock is already locked by a different task/thread, wait for it to become available. When this function returns, the lock has been released, so the caller should not attempt to unlock it.\n\ncompat: Julia 1.11\nRequires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.unlock","page":"Tasks","title":"Base.unlock","text":"unlock(lock)\n\nReleases ownership of the lock.\n\nIf this is a recursive lock which has been acquired before, decrement an internal counter and return immediately.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.trylock","page":"Tasks","title":"Base.trylock","text":"trylock(lock) -> Success (Boolean)\n\nAcquire the lock if it is available, and return true if successful. If the lock is already locked by a different task/thread, return false.\n\nEach successful trylock must be matched by an unlock.\n\nFunction trylock combined with islocked can be used for writing the test-and-test-and-set or exponential backoff algorithms if it is supported by the typeof(lock) (read its documentation).\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.islocked","page":"Tasks","title":"Base.islocked","text":"islocked(lock) -> Status (Boolean)\n\nCheck whether the lock is held by any task/thread. This function alone should not be used for synchronization. However, islocked combined with trylock can be used for writing the test-and-test-and-set or exponential backoff algorithms if it is supported by the typeof(lock) (read its documentation).\n\nExtended help\n\nFor example, an exponential backoff can be implemented as follows if the lock implementation satisfied the properties documented below.\n\nnspins = 0\nwhile true\n while islocked(lock)\n GC.safepoint()\n nspins += 1\n nspins > LIMIT && error(\"timeout\")\n end\n trylock(lock) && break\n backoff()\nend\n\nImplementation\n\nA lock implementation is advised to define islocked with the following properties and note it in its docstring.\n\nislocked(lock) is data-race-free.\nIf islocked(lock) returns false, an immediate invocation of trylock(lock) must succeed (returns true) if there is no interference from other tasks.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.ReentrantLock","page":"Tasks","title":"Base.ReentrantLock","text":"ReentrantLock()\n\nCreates a re-entrant lock for synchronizing Tasks. The same task can acquire the lock as many times as required (this is what the \"Reentrant\" part of the name means). Each lock must be matched with an unlock.\n\nCalling lock will also inhibit running of finalizers on that thread until the corresponding unlock. Use of the standard lock pattern illustrated below should naturally be supported, but beware of inverting the try/lock order or missing the try block entirely (e.g. attempting to return with the lock still held):\n\nThis provides a acquire/release memory ordering on lock/unlock calls.\n\nlock(l)\ntry\n \nfinally\n unlock(l)\nend\n\nIf !islocked(lck::ReentrantLock) holds, trylock(lck) succeeds unless there are other tasks attempting to hold the lock \"at the same time.\"\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.@lock","page":"Tasks","title":"Base.@lock","text":"@lock l expr\n\nMacro version of lock(f, l::AbstractLock) but with expr instead of f function. Expands to:\n\nlock(l)\ntry\n expr\nfinally\n unlock(l)\nend\n\nThis is similar to using lock with a do block, but avoids creating a closure and thus can improve the performance.\n\ncompat: Compat\n@lock was added in Julia 1.3, and exported in Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/parallel/#Base.Lockable","page":"Tasks","title":"Base.Lockable","text":"Lockable(value, lock = ReentrantLock())\n\nCreates a Lockable object that wraps value and associates it with the provided lock. This object supports @lock, lock, trylock, unlock. To access the value, index the lockable object while holding the lock.\n\ncompat: Julia 1.11\nRequires at least Julia 1.11.\n\nExample\n\njulia> locked_list = Base.Lockable(Int[]);\n\njulia> @lock(locked_list, push!(locked_list[], 1)) # must hold the lock to access the value\n1-element Vector{Int64}:\n 1\n\njulia> lock(summary, locked_list)\n\"1-element Vector{Int64}\"\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Channels","page":"Tasks","title":"Channels","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"Base.AbstractChannel\nBase.Channel\nBase.Channel(::Function)\nBase.put!(::Channel, ::Any)\nBase.take!(::Channel)\nBase.isfull(::Channel)\nBase.isready(::Channel)\nBase.fetch(::Channel)\nBase.close(::Channel)\nBase.bind(c::Channel, task::Task)","category":"page"},{"location":"base/parallel/#Base.AbstractChannel","page":"Tasks","title":"Base.AbstractChannel","text":"AbstractChannel{T}\n\nRepresentation of a channel passing objects of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.Channel","page":"Tasks","title":"Base.Channel","text":"Channel{T=Any}(size::Int=0)\n\nConstructs a Channel with an internal buffer that can hold a maximum of size objects of type T. put! calls on a full channel block until an object is removed with take!.\n\nChannel(0) constructs an unbuffered channel. put! blocks until a matching take! is called. And vice-versa.\n\nOther constructors:\n\nChannel(): default constructor, equivalent to Channel{Any}(0)\nChannel(Inf): equivalent to Channel{Any}(typemax(Int))\nChannel(sz): equivalent to Channel{Any}(sz)\n\ncompat: Julia 1.3\nThe default constructor Channel() and default size=0 were added in Julia 1.3.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.Channel-Tuple{Function}","page":"Tasks","title":"Base.Channel","text":"Channel{T=Any}(func::Function, size=0; taskref=nothing, spawn=false, threadpool=nothing)\n\nCreate a new task from func, bind it to a new channel of type T and size size, and schedule the task, all in a single call. The channel is automatically closed when the task terminates.\n\nfunc must accept the bound channel as its only argument.\n\nIf you need a reference to the created task, pass a Ref{Task} object via the keyword argument taskref.\n\nIf spawn=true, the Task created for func may be scheduled on another thread in parallel, equivalent to creating a task via Threads.@spawn.\n\nIf spawn=true and the threadpool argument is not set, it defaults to :default.\n\nIf the threadpool argument is set (to :default or :interactive), this implies that spawn=true and the new Task is spawned to the specified threadpool.\n\nReturn a Channel.\n\nExamples\n\njulia> chnl = Channel() do ch\n foreach(i -> put!(ch, i), 1:4)\n end;\n\njulia> typeof(chnl)\nChannel{Any}\n\njulia> for i in chnl\n @show i\n end;\ni = 1\ni = 2\ni = 3\ni = 4\n\nReferencing the created task:\n\njulia> taskref = Ref{Task}();\n\njulia> chnl = Channel(taskref=taskref) do ch\n println(take!(ch))\n end;\n\njulia> istaskdone(taskref[])\nfalse\n\njulia> put!(chnl, \"Hello\");\nHello\n\njulia> istaskdone(taskref[])\ntrue\n\ncompat: Julia 1.3\nThe spawn= parameter was added in Julia 1.3. This constructor was added in Julia 1.3. In earlier versions of Julia, Channel used keyword arguments to set size and T, but those constructors are deprecated.\n\ncompat: Julia 1.9\nThe threadpool= argument was added in Julia 1.9.\n\njulia> chnl = Channel{Char}(1, spawn=true) do ch\n for c in \"hello world\"\n put!(ch, c)\n end\n end\nChannel{Char}(1) (2 items available)\n\njulia> String(collect(chnl))\n\"hello world\"\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.put!-Tuple{Channel, Any}","page":"Tasks","title":"Base.put!","text":"put!(c::Channel, v)\n\nAppend an item v to the channel c. Blocks if the channel is full.\n\nFor unbuffered channels, blocks until a take! is performed by a different task.\n\ncompat: Julia 1.1\nv now gets converted to the channel's type with convert as put! is called.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.take!-Tuple{Channel}","page":"Tasks","title":"Base.take!","text":"take!(c::Channel)\n\nRemoves and returns a value from a Channel in order. Blocks until data is available. For unbuffered channels, blocks until a put! is performed by a different task.\n\nExamples\n\nBuffered channel:\n\njulia> c = Channel(1);\n\njulia> put!(c, 1);\n\njulia> take!(c)\n1\n\nUnbuffered channel:\n\njulia> c = Channel(0);\n\njulia> task = Task(() -> put!(c, 1));\n\njulia> schedule(task);\n\njulia> take!(c)\n1\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.isfull-Tuple{Channel}","page":"Tasks","title":"Base.isfull","text":"isfull(c::Channel)\n\nDetermines if a Channel is full, in the sense that calling put!(c, some_value) would have blocked. Returns immediately, does not block.\n\nNote that it may frequently be the case that put! will not block after this returns true. Users must take precautions not to accidentally create live-lock bugs in their code by calling this method, as these are generally harder to debug than deadlocks. It is also possible that put! will block after this call returns false, if there are multiple producer tasks calling put! in parallel.\n\nExamples\n\nBuffered channel:\n\njulia> c = Channel(1); # capacity = 1\n\njulia> isfull(c)\nfalse\n\njulia> put!(c, 1);\n\njulia> isfull(c)\ntrue\n\nUnbuffered channel:\n\njulia> c = Channel(); # capacity = 0\n\njulia> isfull(c) # unbuffered channel is always full\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.isready-Tuple{Channel}","page":"Tasks","title":"Base.isready","text":"isready(c::Channel)\n\nDetermines whether a Channel has a value stored in it. Returns immediately, does not block.\n\nFor unbuffered channels, return true if there are tasks waiting on a put!.\n\nExamples\n\nBuffered channel:\n\njulia> c = Channel(1);\n\njulia> isready(c)\nfalse\n\njulia> put!(c, 1);\n\njulia> isready(c)\ntrue\n\nUnbuffered channel:\n\njulia> c = Channel();\n\njulia> isready(c) # no tasks waiting to put!\nfalse\n\njulia> task = Task(() -> put!(c, 1));\n\njulia> schedule(task); # schedule a put! task\n\njulia> isready(c)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.fetch-Tuple{Channel}","page":"Tasks","title":"Base.fetch","text":"fetch(c::Channel)\n\nWaits for and returns (without removing) the first available item from the Channel. Note: fetch is unsupported on an unbuffered (0-size) Channel.\n\nExamples\n\nBuffered channel:\n\njulia> c = Channel(3) do ch\n foreach(i -> put!(ch, i), 1:3)\n end;\n\njulia> fetch(c)\n1\n\njulia> collect(c) # item is not removed\n3-element Vector{Any}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.close-Tuple{Channel}","page":"Tasks","title":"Base.close","text":"close(c::Channel[, excp::Exception])\n\nClose a channel. An exception (optionally given by excp), is thrown by:\n\nput! on a closed channel.\ntake! and fetch on an empty, closed channel.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.bind-Tuple{Channel, Task}","page":"Tasks","title":"Base.bind","text":"bind(chnl::Channel, task::Task)\n\nAssociate the lifetime of chnl with a task. Channel chnl is automatically closed when the task terminates. Any uncaught exception in the task is propagated to all waiters on chnl.\n\nThe chnl object can be explicitly closed independent of task termination. Terminating tasks have no effect on already closed Channel objects.\n\nWhen a channel is bound to multiple tasks, the first task to terminate will close the channel. When multiple channels are bound to the same task, termination of the task will close all of the bound channels.\n\nExamples\n\njulia> c = Channel(0);\n\njulia> task = @async foreach(i->put!(c, i), 1:4);\n\njulia> bind(c,task);\n\njulia> for i in c\n @show i\n end;\ni = 1\ni = 2\ni = 3\ni = 4\n\njulia> isopen(c)\nfalse\n\njulia> c = Channel(0);\n\njulia> task = @async (put!(c, 1); error(\"foo\"));\n\njulia> bind(c, task);\n\njulia> take!(c)\n1\n\njulia> put!(c, 1);\nERROR: TaskFailedException\nStacktrace:\n[...]\n nested task error: foo\n[...]\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#low-level-schedule-wait","page":"Tasks","title":"Low-level synchronization using schedule and wait","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"The easiest correct use of schedule is on a Task that is not started (scheduled) yet. However, it is possible to use schedule and wait as a very low-level building block for constructing synchronization interfaces. A crucial pre-condition of calling schedule(task) is that the caller must \"own\" the task; i.e., it must know that the call to wait in the given task is happening at the locations known to the code calling schedule(task). One strategy for ensuring such pre-condition is to use atomics, as demonstrated in the following example:","category":"page"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"@enum OWEState begin\n OWE_EMPTY\n OWE_WAITING\n OWE_NOTIFYING\nend\n\nmutable struct OneWayEvent\n @atomic state::OWEState\n task::Task\n OneWayEvent() = new(OWE_EMPTY)\nend\n\nfunction Base.notify(ev::OneWayEvent)\n state = @atomic ev.state\n while state !== OWE_NOTIFYING\n # Spin until we successfully update the state to OWE_NOTIFYING:\n state, ok = @atomicreplace(ev.state, state => OWE_NOTIFYING)\n if ok\n if state == OWE_WAITING\n # OWE_WAITING -> OWE_NOTIFYING transition means that the waiter task is\n # already waiting or about to call `wait`. The notifier task must wake up\n # the waiter task.\n schedule(ev.task)\n else\n @assert state == OWE_EMPTY\n # Since we are assuming that there is only one notifier task (for\n # simplicity), we know that the other possible case here is OWE_EMPTY.\n # We do not need to do anything because we know that the waiter task has\n # not called `wait(ev::OneWayEvent)` yet.\n end\n break\n end\n end\n return\nend\n\nfunction Base.wait(ev::OneWayEvent)\n ev.task = current_task()\n state, ok = @atomicreplace(ev.state, OWE_EMPTY => OWE_WAITING)\n if ok\n # OWE_EMPTY -> OWE_WAITING transition means that the notifier task is guaranteed to\n # invoke OWE_WAITING -> OWE_NOTIFYING transition. The waiter task must call\n # `wait()` immediately. In particular, it MUST NOT invoke any function that may\n # yield to the scheduler at this point in code.\n wait()\n else\n @assert state == OWE_NOTIFYING\n # Otherwise, the `state` must have already been moved to OWE_NOTIFYING by the\n # notifier task.\n end\n return\nend\n\nev = OneWayEvent()\n@sync begin\n @async begin\n wait(ev)\n println(\"done\")\n end\n println(\"notifying...\")\n notify(ev)\nend\n\n# output\nnotifying...\ndone","category":"page"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"OneWayEvent lets one task to wait for another task's notify. It is a limited communication interface since wait can only be used once from a single task (note the non-atomic assignment of ev.task)","category":"page"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"In this example, notify(ev::OneWayEvent) is allowed to call schedule(ev.task) if and only if it modifies the state from OWE_WAITING to OWE_NOTIFYING. This lets us know that the task executing wait(ev::OneWayEvent) is now in the ok branch and that there cannot be other tasks that tries to schedule(ev.task) since their @atomicreplace(ev.state, state => OWE_NOTIFYING) will fail.","category":"page"},{"location":"manual/arrays/#man-multi-dim-arrays","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Julia, like most technical computing languages, provides a first-class array implementation. Most technical computing languages pay a lot of attention to their array implementation at the expense of other containers. Julia does not treat arrays in any special way. The array library is implemented almost completely in Julia itself, and derives its performance from the compiler, just like any other code written in Julia. As such, it's also possible to define custom array types by inheriting from AbstractArray. See the manual section on the AbstractArray interface for more details on implementing a custom array type.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"An array is a collection of objects stored in a multi-dimensional grid. Zero-dimensional arrays are allowed, see this FAQ entry. In the most general case, an array may contain objects of type Any. For most computational purposes, arrays should contain objects of a more specific type, such as Float64 or Int32.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In general, unlike many other technical computing languages, Julia does not expect programs to be written in a vectorized style for performance. Julia's compiler uses type inference and generates optimized code for scalar array indexing, allowing programs to be written in a style that is convenient and readable, without sacrificing performance, and using less memory at times.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In Julia, all arguments to functions are passed by sharing (i.e. by pointers). Some technical computing languages pass arrays by value, and while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a ! indicates that it will mutate or destroy the value of one or more of its arguments (compare, for example, sort and sort!). Callees must make explicit copies to ensure that they don't modify inputs that they don't intend to change. Many non-mutating functions are implemented by calling a function of the same name with an added ! at the end on an explicit copy of the input, and returning that copy.","category":"page"},{"location":"manual/arrays/#Basic-Functions","page":"Single- and multi-dimensional Arrays","title":"Basic Functions","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Function Description\neltype(A) the type of the elements contained in A\nlength(A) the number of elements in A\nndims(A) the number of dimensions of A\nsize(A) a tuple containing the dimensions of A\nsize(A,n) the size of A along dimension n\naxes(A) a tuple containing the valid indices of A\naxes(A,n) a range expressing the valid indices along dimension n\neachindex(A) an efficient iterator for visiting each position in A\nstride(A,k) the stride (linear index distance between adjacent elements) along dimension k\nstrides(A) a tuple of the strides in each dimension","category":"page"},{"location":"manual/arrays/#Construction-and-Initialization","page":"Single- and multi-dimensional Arrays","title":"Construction and Initialization","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Many functions for constructing and initializing arrays are provided. In the following list of such functions, calls with a dims... argument can either take a single tuple of dimension sizes or a series of dimension sizes passed as a variable number of arguments. Most of these functions also accept a first input T, which is the element type of the array. If the type T is omitted it will default to Float64.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Function Description\nArray{T}(undef, dims...) an uninitialized dense Array\nzeros(T, dims...) an Array of all zeros\nones(T, dims...) an Array of all ones\ntrues(dims...) a BitArray with all values true\nfalses(dims...) a BitArray with all values false\nreshape(A, dims...) an array containing the same data as A, but with different dimensions\ncopy(A) copy A\ndeepcopy(A) copy A, recursively copying its elements\nsimilar(A, T, dims...) an uninitialized array of the same type as A (dense, sparse, etc.), but with the specified element type and dimensions. The second and third arguments are both optional, defaulting to the element type and dimensions of A if omitted.\nreinterpret(T, A) an array with the same binary data as A, but with element type T\nrand(T, dims...) an Array with random, iid [1] and uniformly distributed values. For floating point types T, the values lie in the half-open interval 0 1).\nrandn(T, dims...) an Array with random, iid and standard normally distributed values\nMatrix{T}(I, m, n) m-by-n identity matrix. Requires using LinearAlgebra for I.\nrange(start, stop, n) a range of n linearly spaced elements from start to stop\nfill!(A, x) fill the array A with the value x\nfill(x, dims...) an Array filled with the value x. In particular, fill(x) constructs a zero-dimensional Array containing x.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"[1]: iid, independently and identically distributed.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"To see the various ways we can pass dimensions to these functions, consider the following examples:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> zeros(Int8, 2, 3)\n2×3 Matrix{Int8}:\n 0 0 0\n 0 0 0\n\njulia> zeros(Int8, (2, 3))\n2×3 Matrix{Int8}:\n 0 0 0\n 0 0 0\n\njulia> zeros((2, 3))\n2×3 Matrix{Float64}:\n 0.0 0.0 0.0\n 0.0 0.0 0.0","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Here, (2, 3) is a Tuple and the first argument — the element type — is optional, defaulting to Float64.","category":"page"},{"location":"manual/arrays/#man-array-literals","page":"Single- and multi-dimensional Arrays","title":"Array literals","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Arrays can also be directly constructed with square braces; the syntax [A, B, C, ...] creates a one-dimensional array (i.e., a vector) containing the comma-separated arguments as its elements. The element type (eltype) of the resulting array is automatically determined by the types of the arguments inside the braces. If all the arguments are the same type, then that is its eltype. If they all have a common promotion type then they get converted to that type using convert and that type is the array's eltype. Otherwise, a heterogeneous array that can hold anything — a Vector{Any} — is constructed; this includes the literal [] where no arguments are given. Array literal can be typed with the syntax T[A, B, C, ...] where T is a type.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1, 2, 3] # An array of `Int`s\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> promote(1, 2.3, 4//5) # This combination of Int, Float64 and Rational promotes to Float64\n(1.0, 2.3, 0.8)\n\njulia> [1, 2.3, 4//5] # Thus that's the element type of this Array\n3-element Vector{Float64}:\n 1.0\n 2.3\n 0.8\n\njulia> Float32[1, 2.3, 4//5] # Specify element type manually\n3-element Vector{Float32}:\n 1.0\n 2.3\n 0.8\n\njulia> []\nAny[]","category":"page"},{"location":"manual/arrays/#man-array-concatenation","page":"Single- and multi-dimensional Arrays","title":"Concatenation","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If the arguments inside the square brackets are separated by single semicolons (;) or newlines instead of commas, then their contents are vertically concatenated together instead of the arguments being used as elements themselves.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1:2, 4:5] # Has a comma, so no concatenation occurs. The ranges are themselves the elements\n2-element Vector{UnitRange{Int64}}:\n 1:2\n 4:5\n\njulia> [1:2; 4:5]\n4-element Vector{Int64}:\n 1\n 2\n 4\n 5\n\njulia> [1:2\n 4:5\n 6]\n5-element Vector{Int64}:\n 1\n 2\n 4\n 5\n 6","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Similarly, if the arguments are separated by tabs or spaces or double semicolons, then their contents are horizontally concatenated together.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1:2 4:5 7:8]\n2×3 Matrix{Int64}:\n 1 4 7\n 2 5 8\n\njulia> [[1,2] [4,5] [7,8]]\n2×3 Matrix{Int64}:\n 1 4 7\n 2 5 8\n\njulia> [1 2 3] # Numbers can also be horizontally concatenated\n1×3 Matrix{Int64}:\n 1 2 3\n\njulia> [1;; 2;; 3;; 4]\n1×4 Matrix{Int64}:\n 1 2 3 4","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Single semicolons (or newlines) and spaces (or tabs) can be combined to concatenate both horizontally and vertically at the same time.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1 2\n 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> [zeros(Int, 2, 2) [1; 2]\n [3 4] 5]\n3×3 Matrix{Int64}:\n 0 0 1\n 0 0 2\n 3 4 5\n\njulia> [[1 1]; 2 3; [4 4]]\n3×2 Matrix{Int64}:\n 1 1\n 2 3\n 4 4","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Spaces (and tabs) have a higher precedence than semicolons, performing any horizontal concatenations first and then concatenating the result. Using double semicolons for the horizontal concatenation, on the other hand, performs any vertical concatenations before horizontally concatenating the result.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [zeros(Int, 2, 2) ; [3 4] ;; [1; 2] ; 5]\n3×3 Matrix{Int64}:\n 0 0 1\n 0 0 2\n 3 4 5\n\njulia> [1:2; 4;; 1; 3:4]\n3×2 Matrix{Int64}:\n 1 1\n 2 3\n 4 4","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Just as ; and ;; concatenate in the first and second dimension, using more semicolons extends this same general scheme. The number of semicolons in the separator specifies the particular dimension, so ;;; concatenates in the third dimension, ;;;; in the 4th, and so on. Fewer semicolons take precedence, so the lower dimensions are generally concatenated first.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1; 2;; 3; 4;; 5; 6;;;\n 7; 8;; 9; 10;; 11; 12]\n2×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 3 5\n 2 4 6\n\n[:, :, 2] =\n 7 9 11\n 8 10 12","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Like before, spaces (and tabs) for horizontal concatenation have a higher precedence than any number of semicolons. Thus, higher-dimensional arrays can also be written by specifying their rows first, with their elements textually arranged in a manner similar to their layout:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1 3 5\n 2 4 6;;;\n 7 9 11\n 8 10 12]\n2×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 3 5\n 2 4 6\n\n[:, :, 2] =\n 7 9 11\n 8 10 12\n\njulia> [1 2;;; 3 4;;;; 5 6;;; 7 8]\n1×2×2×2 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 2\n\n[:, :, 2, 1] =\n 3 4\n\n[:, :, 1, 2] =\n 5 6\n\n[:, :, 2, 2] =\n 7 8\n\njulia> [[1 2;;; 3 4];;;; [5 6];;; [7 8]]\n1×2×2×2 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 2\n\n[:, :, 2, 1] =\n 3 4\n\n[:, :, 1, 2] =\n 5 6\n\n[:, :, 2, 2] =\n 7 8","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Although they both mean concatenation in the second dimension, spaces (or tabs) and ;; cannot appear in the same array expression unless the double semicolon is simply serving as a \"line continuation\" character. This allows a single horizontal concatenation to span multiple lines (without the line break being interpreted as a vertical concatenation).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1 2 ;;\n 3 4]\n1×4 Matrix{Int64}:\n 1 2 3 4","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Terminating semicolons may also be used to add trailing length 1 dimensions.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1;;]\n1×1 Matrix{Int64}:\n 1\n\njulia> [2; 3;;;]\n2×1×1 Array{Int64, 3}:\n[:, :, 1] =\n 2\n 3","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"More generally, concatenation can be accomplished through the cat function. These syntaxes are shorthands for function calls that themselves are convenience functions:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Syntax Function Description\n cat concatenate input arrays along dimension(s) k\n[A; B; C; ...] vcat shorthand for cat(A...; dims=1)\n[A B C ...] hcat shorthand for cat(A...; dims=2)\n[A B; C D; ...] hvcat simultaneous vertical and horizontal concatenation\n[A; C;; B; D;;; ...] hvncat simultaneous n-dimensional concatenation, where number of semicolons indicate the dimension to concatenate","category":"page"},{"location":"manual/arrays/#man-array-typed-literal","page":"Single- and multi-dimensional Arrays","title":"Typed array literals","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"An array with a specific element type can be constructed using the syntax T[A, B, C, ...]. This will construct a 1-d array with element type T, initialized to contain elements A, B, C, etc. For example, Any[x, y, z] constructs a heterogeneous array that can contain any values.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Concatenation syntax can similarly be prefixed with a type to specify the element type of the result.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [[1 2] [3 4]]\n1×4 Matrix{Int64}:\n 1 2 3 4\n\njulia> Int8[[1 2] [3 4]]\n1×4 Matrix{Int8}:\n 1 2 3 4","category":"page"},{"location":"manual/arrays/#man-comprehensions","page":"Single- and multi-dimensional Arrays","title":"Comprehensions","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Comprehensions provide a general and powerful way to construct arrays. Comprehension syntax is similar to set construction notation in mathematics:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A = [ F(x, y, ...) for x=rx, y=ry, ... ]","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The meaning of this form is that F(x,y,...) is evaluated with the variables x, y, etc. taking on each value in their given list of values. Values can be specified as any iterable object, but will commonly be ranges like 1:n or 2:(n-1), or explicit arrays of values like [1.2, 3.4, 5.7]. The result is an N-d dense array with dimensions that are the concatenation of the dimensions of the variable ranges rx, ry, etc. and each F(x,y,...) evaluation returns a scalar.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The following example computes a weighted average of the current element and its left and right neighbor along a 1-d grid. :","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> x = rand(8)\n8-element Array{Float64,1}:\n 0.843025\n 0.869052\n 0.365105\n 0.699456\n 0.977653\n 0.994953\n 0.41084\n 0.809411\n\njulia> [ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ]\n6-element Array{Float64,1}:\n 0.736559\n 0.57468\n 0.685417\n 0.912429\n 0.8446\n 0.656511","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The resulting array type depends on the types of the computed elements just like array literals do. In order to control the type explicitly, a type can be prepended to the comprehension. For example, we could have requested the result in single precision by writing:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Float32[ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ]","category":"page"},{"location":"manual/arrays/#man-generators","page":"Single- and multi-dimensional Arrays","title":"Generator Expressions","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Comprehensions can also be written without the enclosing square brackets, producing an object known as a generator. This object can be iterated to produce values on demand, instead of allocating an array and storing them in advance (see Iteration). For example, the following expression sums a series without allocating memory:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> sum(1/n^2 for n=1:1000)\n1.6439345666815615","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"When writing a generator expression with multiple dimensions inside an argument list, parentheses are needed to separate the generator from subsequent arguments:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> map(tuple, 1/(i+j) for i=1:2, j=1:2, [1:4;])\nERROR: syntax: invalid iteration specification","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"All comma-separated expressions after for are interpreted as ranges. Adding parentheses lets us add a third argument to map:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4])\n2×2 Matrix{Tuple{Float64, Int64}}:\n (0.5, 1) (0.333333, 3)\n (0.333333, 2) (0.25, 4)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Generators are implemented via inner functions. Just like inner functions used elsewhere in the language, variables from the enclosing scope can be \"captured\" in the inner function. For example, sum(p[i] - q[i] for i=1:n) captures the three variables p, q and n from the enclosing scope. Captured variables can present performance challenges; see performance tips.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Ranges in generators and comprehensions can depend on previous ranges by writing multiple for keywords:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [(i, j) for i=1:3 for j=1:i]\n6-element Vector{Tuple{Int64, Int64}}:\n (1, 1)\n (2, 1)\n (2, 2)\n (3, 1)\n (3, 2)\n (3, 3)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In such cases, the result is always 1-d.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Generated values can be filtered using the if keyword:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [(i, j) for i=1:3 for j=1:i if i+j == 4]\n2-element Vector{Tuple{Int64, Int64}}:\n (2, 2)\n (3, 1)","category":"page"},{"location":"manual/arrays/#man-array-indexing","page":"Single- and multi-dimensional Arrays","title":"Indexing","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The general syntax for indexing into an n-dimensional array A is:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"X = A[I_1, I_2, ..., I_n]","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"where each I_k may be a scalar integer, an array of integers, or any other supported index. This includes Colon (:) to select all indices within the entire dimension, ranges of the form a:c or a:b:c to select contiguous or strided subsections, and arrays of booleans to select elements at their true indices.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If all the indices are scalars, then the result X is a single element from the array A. Otherwise, X is an array with the same number of dimensions as the sum of the dimensionalities of all the indices.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If all indices I_k are vectors, for example, then the shape of X would be (length(I_1), length(I_2), ..., length(I_n)), with location i_1, i_2, ..., i_n of X containing the value A[I_1[i_1], I_2[i_2], ..., I_n[i_n]].","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(collect(1:16), (2, 2, 2, 2))\n2×2×2×2 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 3\n 2 4\n\n[:, :, 2, 1] =\n 5 7\n 6 8\n\n[:, :, 1, 2] =\n 9 11\n 10 12\n\n[:, :, 2, 2] =\n 13 15\n 14 16\n\njulia> A[1, 2, 1, 1] # all scalar indices\n3\n\njulia> A[[1, 2], [1], [1, 2], [1]] # all vector indices\n2×1×2×1 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1\n 2\n\n[:, :, 2, 1] =\n 5\n 6\n\njulia> A[[1, 2], [1], [1, 2], 1] # a mix of index types\n2×1×2 Array{Int64, 3}:\n[:, :, 1] =\n 1\n 2\n\n[:, :, 2] =\n 5\n 6","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Note how the size of the resulting array is different in the last two cases.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If I_1 is changed to a two-dimensional matrix, then X becomes an n+1-dimensional array of shape (size(I_1, 1), size(I_1, 2), length(I_2), ..., length(I_n)). The matrix adds a dimension.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(collect(1:16), (2, 2, 2, 2));\n\njulia> A[[1 2; 1 2]]\n2×2 Matrix{Int64}:\n 1 2\n 1 2\n\njulia> A[[1 2; 1 2], 1, 2, 1]\n2×2 Matrix{Int64}:\n 5 6\n 5 6","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The location i_1, i_2, i_3, ..., i_{n+1} contains the value at A[I_1[i_1, i_2], I_2[i_3], ..., I_n[i_{n+1}]]. All dimensions indexed with scalars are dropped. For example, if J is an array of indices, then the result of A[2, J, 3] is an array with size size(J). Its jth element is populated by A[2, J[j], 3].","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"As a special part of this syntax, the end keyword may be used to represent the last index of each dimension within the indexing brackets, as determined by the size of the innermost array being indexed. Indexing syntax without the end keyword is equivalent to a call to getindex:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"X = getindex(A, I_1, I_2, ..., I_n)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> x = reshape(1:16, 4, 4)\n4×4 reshape(::UnitRange{Int64}, 4, 4) with eltype Int64:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> x[2:3, 2:end-1]\n2×2 Matrix{Int64}:\n 6 10\n 7 11\n\njulia> x[1, [2 3; 4 1]]\n2×2 Matrix{Int64}:\n 5 9\n 13 1","category":"page"},{"location":"manual/arrays/#man-indexed-assignment","page":"Single- and multi-dimensional Arrays","title":"Indexed Assignment","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The general syntax for assigning values in an n-dimensional array A is:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A[I_1, I_2, ..., I_n] = X","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"where each I_k may be a scalar integer, an array of integers, or any other supported index. This includes Colon (:) to select all indices within the entire dimension, ranges of the form a:c or a:b:c to select contiguous or strided subsections, and arrays of booleans to select elements at their true indices.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If all indices I_k are integers, then the value in location I_1, I_2, ..., I_n of A is overwritten with the value of X, converting to the eltype of A if necessary.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If any index I_k is itself an array, then the right hand side X must also be an array with the same shape as the result of indexing A[I_1, I_2, ..., I_n] or a vector with the same number of elements. The value in location I_1[i_1], I_2[i_2], ..., I_n[i_n] of A is overwritten with the value X[i_1, i_2, ..., i_n], converting if necessary. The element-wise assignment operator .= may be used to broadcast X across the selected locations:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A[I_1, I_2, ..., I_n] .= X","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Just as in Indexing, the end keyword may be used to represent the last index of each dimension within the indexing brackets, as determined by the size of the array being assigned into. Indexed assignment syntax without the end keyword is equivalent to a call to setindex!:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"setindex!(A, X, I_1, I_2, ..., I_n)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> x = collect(reshape(1:9, 3, 3))\n3×3 Matrix{Int64}:\n 1 4 7\n 2 5 8\n 3 6 9\n\njulia> x[3, 3] = -9;\n\njulia> x[1:2, 1:2] = [-1 -4; -2 -5];\n\njulia> x\n3×3 Matrix{Int64}:\n -1 -4 7\n -2 -5 8\n 3 6 -9","category":"page"},{"location":"manual/arrays/#man-supported-index-types","page":"Single- and multi-dimensional Arrays","title":"Supported index types","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In the expression A[I_1, I_2, ..., I_n], each I_k may be a scalar index, an array of scalar indices, or an object that represents an array of scalar indices and can be converted to such by to_indices:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A scalar index. By default this includes:\nNon-boolean integers\nCartesianIndex{N}s, which behave like an N-tuple of integers spanning multiple dimensions (see below for more details)\nAn array of scalar indices. This includes:\nVectors and multidimensional arrays of integers\nEmpty arrays like [], which select no elements e.g. A[[]] (not to be confused with A[])\nRanges like a:c or a:b:c, which select contiguous or strided subsections from a to c (inclusive)\nAny custom array of scalar indices that is a subtype of AbstractArray\nArrays of CartesianIndex{N} (see below for more details)\nAn object that represents an array of scalar indices and can be converted to such by to_indices. By default this includes:\nColon() (:), which represents all indices within an entire dimension or across the entire array\nArrays of booleans, which select elements at their true indices (see below for more details)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Some examples:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(collect(1:2:18), (3, 3))\n3×3 Matrix{Int64}:\n 1 7 13\n 3 9 15\n 5 11 17\n\njulia> A[4]\n7\n\njulia> A[[2, 5, 8]]\n3-element Vector{Int64}:\n 3\n 9\n 15\n\njulia> A[[1 4; 3 8]]\n2×2 Matrix{Int64}:\n 1 7\n 5 15\n\njulia> A[[]]\nInt64[]\n\njulia> A[1:2:5]\n3-element Vector{Int64}:\n 1\n 5\n 9\n\njulia> A[2, :]\n3-element Vector{Int64}:\n 3\n 9\n 15\n\njulia> A[:, 3]\n3-element Vector{Int64}:\n 13\n 15\n 17\n\njulia> A[:, 3:3]\n3×1 Matrix{Int64}:\n 13\n 15\n 17","category":"page"},{"location":"manual/arrays/#Cartesian-indices","page":"Single- and multi-dimensional Arrays","title":"Cartesian indices","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The special CartesianIndex{N} object represents a scalar index that behaves like an N-tuple of integers spanning multiple dimensions. For example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(1:32, 4, 4, 2);\n\njulia> A[3, 2, 1]\n7\n\njulia> A[CartesianIndex(3, 2, 1)] == A[3, 2, 1] == 7\ntrue","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Considered alone, this may seem relatively trivial; CartesianIndex simply gathers multiple integers together into one object that represents a single multidimensional index. When combined with other indexing forms and iterators that yield CartesianIndexes, however, this can produce very elegant and efficient code. See Iteration below, and for some more advanced examples, see this blog post on multidimensional algorithms and iteration.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Arrays of CartesianIndex{N} are also supported. They represent a collection of scalar indices that each span N dimensions, enabling a form of indexing that is sometimes referred to as pointwise indexing. For example, it enables accessing the diagonal elements from the first \"page\" of A from above:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> page = A[:, :, 1]\n4×4 Matrix{Int64}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> page[[CartesianIndex(1, 1),\n CartesianIndex(2, 2),\n CartesianIndex(3, 3),\n CartesianIndex(4, 4)]]\n4-element Vector{Int64}:\n 1\n 6\n 11\n 16","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This can be expressed much more simply with dot broadcasting and by combining it with a normal integer index (instead of extracting the first page from A as a separate step). It can even be combined with a : to extract both diagonals from the two pages at the same time:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), 1]\n4-element Vector{Int64}:\n 1\n 6\n 11\n 16\n\njulia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), :]\n4×2 Matrix{Int64}:\n 1 17\n 6 22\n 11 27\n 16 32","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"warning: Warning\nCartesianIndex and arrays of CartesianIndex are not compatible with the end keyword to represent the last index of a dimension. Do not use end in indexing expressions that may contain either CartesianIndex or arrays thereof.","category":"page"},{"location":"manual/arrays/#Logical-indexing","page":"Single- and multi-dimensional Arrays","title":"Logical indexing","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Often referred to as logical indexing or indexing with a logical mask, indexing by a boolean array selects elements at the indices where its values are true. Indexing by a boolean vector B is effectively the same as indexing by the vector of integers that is returned by findall(B). Similarly, indexing by a N-dimensional boolean array is effectively the same as indexing by the vector of CartesianIndex{N}s where its values are true. A logical index must be a array of the same shape as the dimension(s) it indexes into, or it must be the only index provided and match the shape of the one-dimensional reshaped view of the array it indexes into. It is generally more efficient to use boolean arrays as indices directly instead of first calling findall.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> x = reshape(1:12, 2, 3, 2)\n2×3×2 reshape(::UnitRange{Int64}, 2, 3, 2) with eltype Int64:\n[:, :, 1] =\n 1 3 5\n 2 4 6\n\n[:, :, 2] =\n 7 9 11\n 8 10 12\n\njulia> x[:, [true false; false true; true false]]\n2×3 Matrix{Int64}:\n 1 5 9\n 2 6 10\n\njulia> mask = map(ispow2, x)\n2×3×2 Array{Bool, 3}:\n[:, :, 1] =\n 1 0 0\n 1 1 0\n\n[:, :, 2] =\n 0 0 0\n 1 0 0\n\njulia> x[mask]\n4-element Vector{Int64}:\n 1\n 2\n 4\n 8\n\njulia> x[vec(mask)] == x[mask] # we can also index with a single Boolean vector\ntrue","category":"page"},{"location":"manual/arrays/#Number-of-indices","page":"Single- and multi-dimensional Arrays","title":"Number of indices","text":"","category":"section"},{"location":"manual/arrays/#Cartesian-indexing","page":"Single- and multi-dimensional Arrays","title":"Cartesian indexing","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The ordinary way to index into an N-dimensional array is to use exactly N indices; each index selects the position(s) in its particular dimension. For example, in the three-dimensional array A = rand(4, 3, 2), A[2, 3, 1] will select the number in the second row of the third column in the first \"page\" of the array. This is often referred to as cartesian indexing.","category":"page"},{"location":"manual/arrays/#Linear-indexing","page":"Single- and multi-dimensional Arrays","title":"Linear indexing","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"When exactly one index i is provided, that index no longer represents a location in a particular dimension of the array. Instead, it selects the ith element using the column-major iteration order that linearly spans the entire array. This is known as linear indexing. It essentially treats the array as though it had been reshaped into a one-dimensional vector with vec.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = [2 6; 4 7; 3 1]\n3×2 Matrix{Int64}:\n 2 6\n 4 7\n 3 1\n\njulia> A[5]\n7\n\njulia> vec(A)[5]\n7","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A linear index into the array A can be converted to a CartesianIndex for cartesian indexing with CartesianIndices(A)[i] (see CartesianIndices), and a set of N cartesian indices can be converted to a linear index with LinearIndices(A)[i_1, i_2, ..., i_N] (see LinearIndices).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> CartesianIndices(A)[5]\nCartesianIndex(2, 2)\n\njulia> LinearIndices(A)[2, 2]\n5","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"It's important to note that there's a very large asymmetry in the performance of these conversions. Converting a linear index to a set of cartesian indices requires dividing and taking the remainder, whereas going the other way is just multiplies and adds. In modern processors, integer division can be 10-50 times slower than multiplication. While some arrays — like Array itself — are implemented using a linear chunk of memory and directly use a linear index in their implementations, other arrays — like Diagonal — need the full set of cartesian indices to do their lookup (see IndexStyle to introspect which is which).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"warning: Warning\nWhen iterating over all the indices for an array, it is better to iterate over eachindex(A) instead of 1:length(A). Not only will this be faster in cases where A is IndexCartesian, but it will also support arrays with custom indexing, such as OffsetArrays. If only the values are needed, then is better to just iterate the array directly, i.e. for a in A.","category":"page"},{"location":"manual/arrays/#Omitted-and-extra-indices","page":"Single- and multi-dimensional Arrays","title":"Omitted and extra indices","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In addition to linear indexing, an N-dimensional array may be indexed with fewer or more than N indices in certain situations.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Indices may be omitted if the trailing dimensions that are not indexed into are all length one. In other words, trailing indices can be omitted only if there is only one possible value that those omitted indices could be for an in-bounds indexing expression. For example, a four-dimensional array with size (3, 4, 2, 1) may be indexed with only three indices as the dimension that gets skipped (the fourth dimension) has length one. Note that linear indexing takes precedence over this rule.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(1:24, 3, 4, 2, 1)\n3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64:\n[:, :, 1, 1] =\n 1 4 7 10\n 2 5 8 11\n 3 6 9 12\n\n[:, :, 2, 1] =\n 13 16 19 22\n 14 17 20 23\n 15 18 21 24\n\njulia> A[1, 3, 2] # Omits the fourth dimension (length 1)\n19\n\njulia> A[1, 3] # Attempts to omit dimensions 3 & 4 (lengths 2 and 1)\nERROR: BoundsError: attempt to access 3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64 at index [1, 3]\n\njulia> A[19] # Linear indexing\n19","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"When omitting all indices with A[], this semantic provides a simple idiom to retrieve the only element in an array and simultaneously ensure that there was only one element.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Similarly, more than N indices may be provided if all the indices beyond the dimensionality of the array are 1 (or more generally are the first and only element of axes(A, d) where d is that particular dimension number). This allows vectors to be indexed like one-column matrices, for example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = [8, 6, 7]\n3-element Vector{Int64}:\n 8\n 6\n 7\n\njulia> A[2, 1]\n6","category":"page"},{"location":"manual/arrays/#Iteration","page":"Single- and multi-dimensional Arrays","title":"Iteration","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The recommended ways to iterate over a whole array are","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"for a in A\n # Do something with the element a\nend\n\nfor i in eachindex(A)\n # Do something with i and/or A[i]\nend","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The first construct is used when you need the value, but not index, of each element. In the second construct, i will be an Int if A is an array type with fast linear indexing; otherwise, it will be a CartesianIndex:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = rand(4, 3);\n\njulia> B = view(A, 1:3, 2:3);\n\njulia> for i in eachindex(B)\n @show i\n end\ni = CartesianIndex(1, 1)\ni = CartesianIndex(2, 1)\ni = CartesianIndex(3, 1)\ni = CartesianIndex(1, 2)\ni = CartesianIndex(2, 2)\ni = CartesianIndex(3, 2)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"note: Note\nIn contrast with for i = 1:length(A), iterating with eachindex provides an efficient way to iterate over any array type. Besides, this also supports generic arrays with custom indexing such as OffsetArrays.","category":"page"},{"location":"manual/arrays/#Array-traits","page":"Single- and multi-dimensional Arrays","title":"Array traits","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If you write a custom AbstractArray type, you can specify that it has fast linear indexing using","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This setting will cause eachindex iteration over a MyArray to use integers. If you don't specify this trait, the default value IndexCartesian() is used.","category":"page"},{"location":"manual/arrays/#man-array-and-vectorized-operators-and-functions","page":"Single- and multi-dimensional Arrays","title":"Array and Vectorized Operators and Functions","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The following operators are supported for arrays:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Unary arithmetic – -, +\nBinary arithmetic – -, +, *, /, \\, ^\nComparison – ==, !=, ≈ (isapprox), ≉","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"To enable convenient vectorization of mathematical and other operations, Julia provides the dot syntax f.(args...), e.g. sin.(x) or min.(x, y), for elementwise operations over arrays or mixtures of arrays and scalars (a Broadcasting operation); these have the additional advantage of \"fusing\" into a single loop when combined with other dot calls, e.g. sin.(cos.(x)).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Also, every binary operator supports a dot version that can be applied to arrays (and combinations of arrays and scalars) in such fused broadcasting operations, e.g. z .== sin.(x .* y).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Note that comparisons such as == operate on whole arrays, giving a single boolean answer. Use dot operators like .== for elementwise comparisons. (For comparison operations like <, only the elementwise .< version is applicable to arrays.)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Also notice the difference between max.(a,b), which broadcasts max elementwise over a and b, and maximum(a), which finds the largest value within a. The same relationship holds for min.(a, b) and minimum(a).","category":"page"},{"location":"manual/arrays/#Broadcasting","page":"Single- and multi-dimensional Arrays","title":"Broadcasting","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"It is sometimes useful to perform element-by-element binary operations on arrays of different sizes, such as adding a vector to each column of a matrix. An inefficient way to do this would be to replicate the vector to the size of the matrix:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> a = rand(2, 1); A = rand(2, 3);\n\njulia> repeat(a, 1, 3) + A\n2×3 Array{Float64,2}:\n 1.20813 1.82068 1.25387\n 1.56851 1.86401 1.67846","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This is wasteful when dimensions get large, so Julia provides broadcast, which expands singleton dimensions in array arguments to match the corresponding dimension in the other array without using extra memory, and applies the given function elementwise:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> broadcast(+, a, A)\n2×3 Array{Float64,2}:\n 1.20813 1.82068 1.25387\n 1.56851 1.86401 1.67846\n\njulia> b = rand(1,2)\n1×2 Array{Float64,2}:\n 0.867535 0.00457906\n\njulia> broadcast(+, a, b)\n2×2 Array{Float64,2}:\n 1.71056 0.847604\n 1.73659 0.873631","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Dotted operators such as .+ and .* are equivalent to broadcast calls (except that they fuse, as described above). There is also a broadcast! function to specify an explicit destination (which can also be accessed in a fusing fashion by .= assignment). In fact, f.(args...) is equivalent to broadcast(f, args...), providing a convenient syntax to broadcast any function (dot syntax). Nested \"dot calls\" f.(...) (including calls to .+ etcetera) automatically fuse into a single broadcast call.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Additionally, broadcast is not limited to arrays (see the function documentation); it also handles scalars, tuples and other collections. By default, only some argument types are considered scalars, including (but not limited to) Numbers, Strings, Symbols, Types, Functions and some common singletons like missing and nothing. All other arguments are iterated over or indexed into elementwise.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> convert.(Float32, [1, 2])\n2-element Vector{Float32}:\n 1.0\n 2.0\n\njulia> ceil.(UInt8, [1.2 3.4; 5.6 6.7])\n2×2 Matrix{UInt8}:\n 0x02 0x04\n 0x06 0x07\n\njulia> string.(1:3, \". \", [\"First\", \"Second\", \"Third\"])\n3-element Vector{String}:\n \"1. First\"\n \"2. Second\"\n \"3. Third\"","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Sometimes, you want a container (like an array) that would normally participate in broadcast to be \"protected\" from broadcast's behavior of iterating over all of its elements. By placing it inside another container (like a single element Tuple) broadcast will treat it as a single value.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> ([1, 2, 3], [4, 5, 6]) .+ ([1, 2, 3],)\n([2, 4, 6], [5, 7, 9])\n\njulia> ([1, 2, 3], [4, 5, 6]) .+ tuple([1, 2, 3])\n([2, 4, 6], [5, 7, 9])","category":"page"},{"location":"manual/arrays/#Implementation","page":"Single- and multi-dimensional Arrays","title":"Implementation","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The base array type in Julia is the abstract type AbstractArray{T,N}. It is parameterized by the number of dimensions N and the element type T. AbstractVector and AbstractMatrix are aliases for the 1-d and 2-d cases. Operations on AbstractArray objects are defined using higher level operators and functions, in a way that is independent of the underlying storage. These operations generally work correctly as a fallback for any specific array implementation.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The AbstractArray type includes anything vaguely array-like, and implementations of it might be quite different from conventional arrays. For example, elements might be computed on request rather than stored. However, any concrete AbstractArray{T,N} type should generally implement at least size(A) (returning an Int tuple), getindex(A, i) and getindex(A, i1, ..., iN); mutable arrays should also implement setindex!. It is recommended that these operations have nearly constant time complexity, as otherwise some array functions may be unexpectedly slow. Concrete types should also typically provide a similar(A, T=eltype(A), dims=size(A)) method, which is used to allocate a similar array for copy and other out-of-place operations. No matter how an AbstractArray{T,N} is represented internally, T is the type of object returned by integer indexing (A[1, ..., 1], when A is not empty) and N should be the length of the tuple returned by size. For more details on defining custom AbstractArray implementations, see the array interface guide in the interfaces chapter.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"DenseArray is an abstract subtype of AbstractArray intended to include all arrays where elements are stored contiguously in column-major order (see additional notes in Performance Tips). The Array type is a specific instance of DenseArray; Vector and Matrix are aliases for the 1-d and 2-d cases. Very few operations are implemented specifically for Array beyond those that are required for all AbstractArrays; much of the array library is implemented in a generic manner that allows all custom arrays to behave similarly.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"SubArray is a specialization of AbstractArray that performs indexing by sharing memory with the original array rather than by copying it. A SubArray is created with the view function, which is called the same way as getindex (with an array and a series of index arguments). The result of view looks the same as the result of getindex, except the data is left in place. view stores the input index vectors in a SubArray object, which can later be used to index the original array indirectly. By putting the @views macro in front of an expression or block of code, any array[...] slice in that expression will be converted to create a SubArray view instead.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"BitArrays are space-efficient \"packed\" boolean arrays, which store one bit per boolean value. They can be used similarly to Array{Bool} arrays (which store one byte per boolean value), and can be converted to/from the latter via Array(bitarray) and BitArray(array), respectively.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"An array is \"strided\" if it is stored in memory with well-defined spacings (strides) between its elements. A strided array with a supported element type may be passed to an external (non-Julia) library like BLAS or LAPACK by simply passing its pointer and the stride for each dimension. The stride(A, d) is the distance between elements along dimension d. For example, the builtin Array returned by rand(5,7,2) has its elements arranged contiguously in column major order. This means that the stride of the first dimension — the spacing between elements in the same column — is 1:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = rand(5, 7, 2);\n\njulia> stride(A, 1)\n1","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The stride of the second dimension is the spacing between elements in the same row, skipping as many elements as there are in a single column (5). Similarly, jumping between the two \"pages\" (in the third dimension) requires skipping 5*7 == 35 elements. The strides of this array is the tuple of these three numbers together:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> strides(A)\n(1, 5, 35)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In this particular case, the number of elements skipped in memory matches the number of linear indices skipped. This is only the case for contiguous arrays like Array (and other DenseArray subtypes) and is not true in general. Views with range indices are a good example of non-contiguous strided arrays; consider V = @view A[1:3:4, 2:2:6, 2:-1:1]. This view V refers to the same memory as A but is skipping and re-arranging some of its elements. The stride of the first dimension of V is 3 because we're only selecting every third row from our original array:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> V = @view A[1:3:4, 2:2:6, 2:-1:1];\n\njulia> stride(V, 1)\n3","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This view is similarly selecting every other column from our original A — and thus it needs to skip the equivalent of two five-element columns when moving between indices in the second dimension:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> stride(V, 2)\n10","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The third dimension is interesting because its order is reversed! Thus to get from the first \"page\" to the second one it must go backwards in memory, and so its stride in this dimension is negative!","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> stride(V, 3)\n-35","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This means that the pointer for V is actually pointing into the middle of A's memory block, and it refers to elements both backwards and forwards in memory. See the interface guide for strided arrays for more details on defining your own strided arrays. StridedVector and StridedMatrix are convenient aliases for many of the builtin array types that are considered strided arrays, allowing them to dispatch to select specialized implementations that call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"It is worth emphasizing that strides are about offsets in memory rather than indexing. If you are looking to convert between linear (single-index) indexing and cartesian (multi-index) indexing, see LinearIndices and CartesianIndices.","category":"page"},{"location":"base/file/#Filesystem","page":"Filesystem","title":"Filesystem","text":"","category":"section"},{"location":"base/file/","page":"Filesystem","title":"Filesystem","text":"Base.read(::String)\nBase.write(::String, ::Any)\nBase.Filesystem.pwd\nBase.Filesystem.cd(::AbstractString)\nBase.Filesystem.cd(::Function)\nBase.Filesystem.readdir\nBase.Filesystem.walkdir\nBase.Filesystem.mkdir\nBase.Filesystem.mkpath\nBase.Filesystem.hardlink\nBase.Filesystem.symlink\nBase.Filesystem.readlink\nBase.Filesystem.chmod\nBase.Filesystem.chown\nBase.RawFD\nBase.stat\nBase.Filesystem.diskstat\nBase.Filesystem.lstat\nBase.Filesystem.ctime\nBase.Filesystem.mtime\nBase.Filesystem.filemode\nBase.Filesystem.filesize\nBase.Filesystem.uperm\nBase.Filesystem.gperm\nBase.Filesystem.operm\nBase.Filesystem.cp\nBase.download\nBase.Filesystem.mv\nBase.Filesystem.rm\nBase.Filesystem.touch\nBase.Filesystem.tempname\nBase.Filesystem.tempdir\nBase.Filesystem.mktemp(::AbstractString)\nBase.Filesystem.mktemp(::Function, ::AbstractString)\nBase.Filesystem.mktempdir(::AbstractString)\nBase.Filesystem.mktempdir(::Function, ::AbstractString)\nBase.Filesystem.isblockdev\nBase.Filesystem.ischardev\nBase.Filesystem.isdir\nBase.Filesystem.isfifo\nBase.Filesystem.isfile\nBase.Filesystem.islink\nBase.Filesystem.ismount\nBase.Filesystem.ispath\nBase.Filesystem.issetgid\nBase.Filesystem.issetuid\nBase.Filesystem.issocket\nBase.Filesystem.issticky\nBase.Filesystem.homedir\nBase.Filesystem.dirname\nBase.Filesystem.basename\nBase.Filesystem.isabspath\nBase.Filesystem.isdirpath\nBase.Filesystem.joinpath\nBase.Filesystem.abspath\nBase.Filesystem.normpath\nBase.Filesystem.realpath\nBase.Filesystem.relpath\nBase.Filesystem.expanduser\nBase.Filesystem.contractuser\nBase.Filesystem.samefile\nBase.Filesystem.splitdir\nBase.Filesystem.splitdrive\nBase.Filesystem.splitext\nBase.Filesystem.splitpath","category":"page"},{"location":"base/file/#Base.read-Tuple{String}","page":"Filesystem","title":"Base.read","text":"read(filename::AbstractString)\n\nRead the entire contents of a file as a Vector{UInt8}.\n\nread(filename::AbstractString, String)\n\nRead the entire contents of a file as a string.\n\nread(filename::AbstractString, args...)\n\nOpen a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.write-Tuple{String, Any}","page":"Filesystem","title":"Base.write","text":"write(filename::AbstractString, content)\n\nWrite the canonical binary representation of content to a file, which will be created if it does not exist yet or overwritten if it does exist.\n\nReturn the number of bytes written into the file.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.pwd","page":"Filesystem","title":"Base.Filesystem.pwd","text":"pwd() -> String\n\nGet the current working directory.\n\nSee also: cd, tempdir.\n\nExamples\n\njulia> pwd()\n\"/home/JuliaUser\"\n\njulia> cd(\"/home/JuliaUser/Projects/julia\")\n\njulia> pwd()\n\"/home/JuliaUser/Projects/julia\"\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.cd-Tuple{AbstractString}","page":"Filesystem","title":"Base.Filesystem.cd","text":"cd(dir::AbstractString=homedir())\n\nSet the current working directory.\n\nSee also: pwd, mkdir, mkpath, mktempdir.\n\nExamples\n\njulia> cd(\"/home/JuliaUser/Projects/julia\")\n\njulia> pwd()\n\"/home/JuliaUser/Projects/julia\"\n\njulia> cd()\n\njulia> pwd()\n\"/home/JuliaUser\"\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.cd-Tuple{Function}","page":"Filesystem","title":"Base.Filesystem.cd","text":"cd(f::Function, dir::AbstractString=homedir())\n\nTemporarily change the current working directory to dir, apply function f and finally return to the original directory.\n\nExamples\n\njulia> pwd()\n\"/home/JuliaUser\"\n\njulia> cd(readdir, \"/home/JuliaUser/Projects/julia\")\n34-element Array{String,1}:\n \".circleci\"\n \".freebsdci.sh\"\n \".git\"\n \".gitattributes\"\n \".github\"\n ⋮\n \"test\"\n \"ui\"\n \"usr\"\n \"usr-staging\"\n\njulia> pwd()\n\"/home/JuliaUser\"\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.readdir","page":"Filesystem","title":"Base.Filesystem.readdir","text":"readdir(dir::AbstractString=pwd();\n join::Bool = false,\n sort::Bool = true,\n) -> Vector{String}\n\nReturn the names in the directory dir or the current working directory if not given. When join is false, readdir returns just the names in the directory as is; when join is true, it returns joinpath(dir, name) for each name so that the returned strings are full paths. If you want to get absolute paths back, call readdir with an absolute directory path and join set to true.\n\nBy default, readdir sorts the list of names it returns. If you want to skip sorting the names and get them in the order that the file system lists them, you can use readdir(dir, sort=false) to opt out of sorting.\n\nSee also: walkdir.\n\ncompat: Julia 1.4\nThe join and sort keyword arguments require at least Julia 1.4.\n\nExamples\n\njulia> cd(\"/home/JuliaUser/dev/julia\")\n\njulia> readdir()\n30-element Array{String,1}:\n \".appveyor.yml\"\n \".git\"\n \".gitattributes\"\n ⋮\n \"ui\"\n \"usr\"\n \"usr-staging\"\n\njulia> readdir(join=true)\n30-element Array{String,1}:\n \"/home/JuliaUser/dev/julia/.appveyor.yml\"\n \"/home/JuliaUser/dev/julia/.git\"\n \"/home/JuliaUser/dev/julia/.gitattributes\"\n ⋮\n \"/home/JuliaUser/dev/julia/ui\"\n \"/home/JuliaUser/dev/julia/usr\"\n \"/home/JuliaUser/dev/julia/usr-staging\"\n\njulia> readdir(\"base\")\n145-element Array{String,1}:\n \".gitignore\"\n \"Base.jl\"\n \"Enums.jl\"\n ⋮\n \"version_git.sh\"\n \"views.jl\"\n \"weakkeydict.jl\"\n\njulia> readdir(\"base\", join=true)\n145-element Array{String,1}:\n \"base/.gitignore\"\n \"base/Base.jl\"\n \"base/Enums.jl\"\n ⋮\n \"base/version_git.sh\"\n \"base/views.jl\"\n \"base/weakkeydict.jl\"\n\njulia> readdir(abspath(\"base\"), join=true)\n145-element Array{String,1}:\n \"/home/JuliaUser/dev/julia/base/.gitignore\"\n \"/home/JuliaUser/dev/julia/base/Base.jl\"\n \"/home/JuliaUser/dev/julia/base/Enums.jl\"\n ⋮\n \"/home/JuliaUser/dev/julia/base/version_git.sh\"\n \"/home/JuliaUser/dev/julia/base/views.jl\"\n \"/home/JuliaUser/dev/julia/base/weakkeydict.jl\"\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.walkdir","page":"Filesystem","title":"Base.Filesystem.walkdir","text":"walkdir(dir; topdown=true, follow_symlinks=false, onerror=throw)\n\nReturn an iterator that walks the directory tree of a directory. The iterator returns a tuple containing (rootpath, dirs, files). The directory tree can be traversed top-down or bottom-up. If walkdir or stat encounters a IOError it will rethrow the error by default. A custom error handling function can be provided through onerror keyword argument. onerror is called with a IOError as argument.\n\nSee also: readdir.\n\nExamples\n\nfor (root, dirs, files) in walkdir(\".\")\n println(\"Directories in $root\")\n for dir in dirs\n println(joinpath(root, dir)) # path to directories\n end\n println(\"Files in $root\")\n for file in files\n println(joinpath(root, file)) # path to files\n end\nend\n\njulia> mkpath(\"my/test/dir\");\n\njulia> itr = walkdir(\"my\");\n\njulia> (root, dirs, files) = first(itr)\n(\"my\", [\"test\"], String[])\n\njulia> (root, dirs, files) = first(itr)\n(\"my/test\", [\"dir\"], String[])\n\njulia> (root, dirs, files) = first(itr)\n(\"my/test/dir\", String[], String[])\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mkdir","page":"Filesystem","title":"Base.Filesystem.mkdir","text":"mkdir(path::AbstractString; mode::Unsigned = 0o777)\n\nMake a new directory with name path and permissions mode. mode defaults to 0o777, modified by the current file creation mask. This function never creates more than one directory. If the directory already exists, or some intermediate directories do not exist, this function throws an error. See mkpath for a function which creates all required intermediate directories. Return path.\n\nExamples\n\njulia> mkdir(\"testingdir\")\n\"testingdir\"\n\njulia> cd(\"testingdir\")\n\njulia> pwd()\n\"/home/JuliaUser/testingdir\"\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mkpath","page":"Filesystem","title":"Base.Filesystem.mkpath","text":"mkpath(path::AbstractString; mode::Unsigned = 0o777)\n\nCreate all intermediate directories in the path as required. Directories are created with the permissions mode which defaults to 0o777 and is modified by the current file creation mask. Unlike mkdir, mkpath does not error if path (or parts of it) already exists. However, an error will be thrown if path (or parts of it) points to an existing file. Return path.\n\nIf path includes a filename you will probably want to use mkpath(dirname(path)) to avoid creating a directory using the filename.\n\nExamples\n\njulia> cd(mktempdir())\n\njulia> mkpath(\"my/test/dir\") # creates three directories\n\"my/test/dir\"\n\njulia> readdir()\n1-element Array{String,1}:\n \"my\"\n\njulia> cd(\"my\")\n\njulia> readdir()\n1-element Array{String,1}:\n \"test\"\n\njulia> readdir(\"test\")\n1-element Array{String,1}:\n \"dir\"\n\njulia> mkpath(\"intermediate_dir/actually_a_directory.txt\") # creates two directories\n\"intermediate_dir/actually_a_directory.txt\"\n\njulia> isdir(\"intermediate_dir/actually_a_directory.txt\")\ntrue\n\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.hardlink","page":"Filesystem","title":"Base.Filesystem.hardlink","text":"hardlink(src::AbstractString, dst::AbstractString)\n\nCreates a hard link to an existing source file src with the name dst. The destination, dst, must not exist.\n\nSee also: symlink.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.symlink","page":"Filesystem","title":"Base.Filesystem.symlink","text":"symlink(target::AbstractString, link::AbstractString; dir_target = false)\n\nCreates a symbolic link to target with the name link.\n\nOn Windows, symlinks must be explicitly declared as referring to a directory or not. If target already exists, by default the type of link will be auto- detected, however if target does not exist, this function defaults to creating a file symlink unless dir_target is set to true. Note that if the user sets dir_target but target exists and is a file, a directory symlink will still be created, but dereferencing the symlink will fail, just as if the user creates a file symlink (by calling symlink() with dir_target set to false before the directory is created) and tries to dereference it to a directory.\n\nAdditionally, there are two methods of making a link on Windows; symbolic links and junction points. Junction points are slightly more efficient, but do not support relative paths, so if a relative directory symlink is requested (as denoted by isabspath(target) returning false) a symlink will be used, else a junction point will be used. Best practice for creating symlinks on Windows is to create them only after the files/directories they reference are already created.\n\nSee also: hardlink.\n\nnote: Note\nThis function raises an error under operating systems that do not support soft symbolic links, such as Windows XP.\n\ncompat: Julia 1.6\nThe dir_target keyword argument was added in Julia 1.6. Prior to this, symlinks to nonexistent paths on windows would always be file symlinks, and relative symlinks to directories were not supported.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.readlink","page":"Filesystem","title":"Base.Filesystem.readlink","text":"readlink(path::AbstractString) -> String\n\nReturn the target location a symbolic link path points to.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.chmod","page":"Filesystem","title":"Base.Filesystem.chmod","text":"chmod(path::AbstractString, mode::Integer; recursive::Bool=false)\n\nChange the permissions mode of path to mode. Only integer modes (e.g. 0o777) are currently supported. If recursive=true and the path is a directory all permissions in that directory will be recursively changed. Return path.\n\nnote: Note\nPrior to Julia 1.6, this did not correctly manipulate filesystem ACLs on Windows, therefore it would only set read-only bits on files. It now is able to manipulate ACLs.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.chown","page":"Filesystem","title":"Base.Filesystem.chown","text":"chown(path::AbstractString, owner::Integer, group::Integer=-1)\n\nChange the owner and/or group of path to owner and/or group. If the value entered for owner or group is -1 the corresponding ID will not change. Only integer owners and groups are currently supported. Return path.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Libc.RawFD","page":"Filesystem","title":"Base.Libc.RawFD","text":"RawFD\n\nPrimitive type which wraps the native OS file descriptor. RawFDs can be passed to methods like stat to discover information about the underlying file, and can also be used to open streams, with the RawFD describing the OS file backing the stream.\n\n\n\n\n\n","category":"type"},{"location":"base/file/#Base.stat","page":"Filesystem","title":"Base.stat","text":"stat(file)\n\nReturn a structure whose fields contain information about the file. The fields of the structure are:\n\nName Type Description\ndesc Union{String, Base.OS_HANDLE} The path or OS file descriptor\nsize Int64 The size (in bytes) of the file\ndevice UInt ID of the device that contains the file\ninode UInt The inode number of the file\nmode UInt The protection mode of the file\nnlink Int The number of hard links to the file\nuid UInt The user id of the owner of the file\ngid UInt The group id of the file owner\nrdev UInt If this file refers to a device, the ID of the device it refers to\nblksize Int64 The file-system preferred block size for the file\nblocks Int64 The number of 512-byte blocks allocated\nmtime Float64 Unix timestamp of when the file was last modified\nctime Float64 Unix timestamp of when the file's metadata was changed\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.diskstat","page":"Filesystem","title":"Base.Filesystem.diskstat","text":"diskstat(path=pwd())\n\nReturns statistics in bytes about the disk that contains the file or directory pointed at by path. If no argument is passed, statistics about the disk that contains the current working directory are returned.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.lstat","page":"Filesystem","title":"Base.Filesystem.lstat","text":"lstat(file)\n\nLike stat, but for symbolic links gets the info for the link itself rather than the file it refers to. This function must be called on a file path rather than a file object or a file descriptor.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.ctime","page":"Filesystem","title":"Base.Filesystem.ctime","text":"ctime(file)\n\nEquivalent to stat(file).ctime.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mtime","page":"Filesystem","title":"Base.Filesystem.mtime","text":"mtime(file)\n\nEquivalent to stat(file).mtime.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.filemode","page":"Filesystem","title":"Base.Filesystem.filemode","text":"filemode(file)\n\nEquivalent to stat(file).mode.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.filesize","page":"Filesystem","title":"Base.filesize","text":"filesize(path...)\n\nEquivalent to stat(file).size.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.uperm","page":"Filesystem","title":"Base.Filesystem.uperm","text":"uperm(file)\n\nGet the permissions of the owner of the file as a bitfield of\n\nValue Description\n01 Execute Permission\n02 Write Permission\n04 Read Permission\n\nFor allowed arguments, see stat.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.gperm","page":"Filesystem","title":"Base.Filesystem.gperm","text":"gperm(file)\n\nLike uperm but gets the permissions of the group owning the file.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.operm","page":"Filesystem","title":"Base.Filesystem.operm","text":"operm(file)\n\nLike uperm but gets the permissions for people who neither own the file nor are a member of the group owning the file\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.cp","page":"Filesystem","title":"Base.Filesystem.cp","text":"cp(src::AbstractString, dst::AbstractString; force::Bool=false, follow_symlinks::Bool=false)\n\nCopy the file, link, or directory from src to dst. force=true will first remove an existing dst.\n\nIf follow_symlinks=false, and src is a symbolic link, dst will be created as a symbolic link. If follow_symlinks=true and src is a symbolic link, dst will be a copy of the file or directory src refers to. Return dst.\n\nnote: Note\nThe cp function is different from the cp command. The cp function always operates on the assumption that dst is a file, while the command does different things depending on whether dst is a directory or a file. Using force=true when dst is a directory will result in loss of all the contents present in the dst directory, and dst will become a file that has the contents of src instead.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.download","page":"Filesystem","title":"Base.download","text":"download(url::AbstractString, [path::AbstractString = tempname()]) -> path\n\nDownload a file from the given url, saving it to the location path, or if not specified, a temporary path. Returns the path of the downloaded file.\n\nnote: Note\nSince Julia 1.6, this function is deprecated and is just a thin wrapper around Downloads.download. In new code, you should use that function directly instead of calling this.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mv","page":"Filesystem","title":"Base.Filesystem.mv","text":"mv(src::AbstractString, dst::AbstractString; force::Bool=false)\n\nMove the file, link, or directory from src to dst. force=true will first remove an existing dst. Return dst.\n\nExamples\n\njulia> write(\"hello.txt\", \"world\");\n\njulia> mv(\"hello.txt\", \"goodbye.txt\")\n\"goodbye.txt\"\n\njulia> \"hello.txt\" in readdir()\nfalse\n\njulia> readline(\"goodbye.txt\")\n\"world\"\n\njulia> write(\"hello.txt\", \"world2\");\n\njulia> mv(\"hello.txt\", \"goodbye.txt\")\nERROR: ArgumentError: 'goodbye.txt' exists. `force=true` is required to remove 'goodbye.txt' before moving.\nStacktrace:\n [1] #checkfor_mv_cp_cptree#10(::Bool, ::Function, ::String, ::String, ::String) at ./file.jl:293\n[...]\n\njulia> mv(\"hello.txt\", \"goodbye.txt\", force=true)\n\"goodbye.txt\"\n\njulia> rm(\"goodbye.txt\");\n\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.rm","page":"Filesystem","title":"Base.Filesystem.rm","text":"rm(path::AbstractString; force::Bool=false, recursive::Bool=false)\n\nDelete the file, link, or empty directory at the given path. If force=true is passed, a non-existing path is not treated as error. If recursive=true is passed and the path is a directory, then all contents are removed recursively.\n\nExamples\n\njulia> mkpath(\"my/test/dir\");\n\njulia> rm(\"my\", recursive=true)\n\njulia> rm(\"this_file_does_not_exist\", force=true)\n\njulia> rm(\"this_file_does_not_exist\")\nERROR: IOError: unlink(\"this_file_does_not_exist\"): no such file or directory (ENOENT)\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.touch","page":"Filesystem","title":"Base.Filesystem.touch","text":"Base.touch(::Pidfile.LockMonitor)\n\nUpdate the mtime on the lock, to indicate it is still fresh.\n\nSee also the refresh keyword in the mkpidlock constructor.\n\n\n\n\n\ntouch(path::AbstractString)\ntouch(fd::File)\n\nUpdate the last-modified timestamp on a file to the current time.\n\nIf the file does not exist a new file is created.\n\nReturn path.\n\nExamples\n\njulia> write(\"my_little_file\", 2);\n\njulia> mtime(\"my_little_file\")\n1.5273815391135583e9\n\njulia> touch(\"my_little_file\");\n\njulia> mtime(\"my_little_file\")\n1.527381559163435e9\n\nWe can see the mtime has been modified by touch.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.tempname","page":"Filesystem","title":"Base.Filesystem.tempname","text":"tempname(parent=tempdir(); cleanup=true, suffix=\"\") -> String\n\nGenerate a temporary file path. This function only returns a path; no file is created. The path is likely to be unique, but this cannot be guaranteed due to the very remote possibility of two simultaneous calls to tempname generating the same file name. The name is guaranteed to differ from all files already existing at the time of the call to tempname.\n\nWhen called with no arguments, the temporary name will be an absolute path to a temporary name in the system temporary directory as given by tempdir(). If a parent directory argument is given, the temporary path will be in that directory instead. If a suffix is given the tempname will end with that suffix and be tested for uniqueness with that suffix.\n\nThe cleanup option controls whether the process attempts to delete the returned path automatically when the process exits. Note that the tempname function does not create any file or directory at the returned location, so there is nothing to cleanup unless you create a file or directory there. If you do and cleanup is true it will be deleted upon process termination.\n\ncompat: Julia 1.4\nThe parent and cleanup arguments were added in 1.4. Prior to Julia 1.4 the path tempname would never be cleaned up at process termination.\n\ncompat: Julia 1.12\nThe suffix keyword argument was added in Julia 1.12.\n\nwarning: Warning\nThis can lead to security holes if another process obtains the same file name and creates the file before you are able to. Open the file with JL_O_EXCL if this is a concern. Using mktemp() is also recommended instead.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.tempdir","page":"Filesystem","title":"Base.Filesystem.tempdir","text":"tempdir()\n\nGets the path of the temporary directory. On Windows, tempdir() uses the first environment variable found in the ordered list TMP, TEMP, USERPROFILE. On all other operating systems, tempdir() uses the first environment variable found in the ordered list TMPDIR, TMP, TEMP, and TEMPDIR. If none of these are found, the path \"/tmp\" is used.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mktemp-Tuple{AbstractString}","page":"Filesystem","title":"Base.Filesystem.mktemp","text":"mktemp(parent=tempdir(); cleanup=true) -> (path, io)\n\nReturn (path, io), where path is the path of a new temporary file in parent and io is an open file object for this path. The cleanup option controls whether the temporary file is automatically deleted when the process exits.\n\ncompat: Julia 1.3\nThe cleanup keyword argument was added in Julia 1.3. Relatedly, starting from 1.3, Julia will remove the temporary paths created by mktemp when the Julia process exits, unless cleanup is explicitly set to false.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.mktemp-Tuple{Function, AbstractString}","page":"Filesystem","title":"Base.Filesystem.mktemp","text":"mktemp(f::Function, parent=tempdir())\n\nApply the function f to the result of mktemp(parent) and remove the temporary file upon completion.\n\nSee also: mktempdir.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.mktempdir-Tuple{AbstractString}","page":"Filesystem","title":"Base.Filesystem.mktempdir","text":"mktempdir(parent=tempdir(); prefix=\"jl_\", cleanup=true) -> path\n\nCreate a temporary directory in the parent directory with a name constructed from the given prefix and a random suffix, and return its path. Additionally, on some platforms, any trailing 'X' characters in prefix may be replaced with random characters. If parent does not exist, throw an error. The cleanup option controls whether the temporary directory is automatically deleted when the process exits.\n\ncompat: Julia 1.2\nThe prefix keyword argument was added in Julia 1.2.\n\ncompat: Julia 1.3\nThe cleanup keyword argument was added in Julia 1.3. Relatedly, starting from 1.3, Julia will remove the temporary paths created by mktempdir when the Julia process exits, unless cleanup is explicitly set to false.\n\nSee also: mktemp, mkdir.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.mktempdir-Tuple{Function, AbstractString}","page":"Filesystem","title":"Base.Filesystem.mktempdir","text":"mktempdir(f::Function, parent=tempdir(); prefix=\"jl_\")\n\nApply the function f to the result of mktempdir(parent; prefix) and remove the temporary directory all of its contents upon completion.\n\nSee also: mktemp, mkdir.\n\ncompat: Julia 1.2\nThe prefix keyword argument was added in Julia 1.2.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.isblockdev","page":"Filesystem","title":"Base.Filesystem.isblockdev","text":"isblockdev(path) -> Bool\n\nReturn true if path is a block device, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.ischardev","page":"Filesystem","title":"Base.Filesystem.ischardev","text":"ischardev(path) -> Bool\n\nReturn true if path is a character device, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isdir","page":"Filesystem","title":"Base.Filesystem.isdir","text":"isdir(path) -> Bool\n\nReturn true if path is a directory, false otherwise.\n\nExamples\n\njulia> isdir(homedir())\ntrue\n\njulia> isdir(\"not/a/directory\")\nfalse\n\nSee also isfile and ispath.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isfifo","page":"Filesystem","title":"Base.Filesystem.isfifo","text":"isfifo(path) -> Bool\n\nReturn true if path is a FIFO, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isfile","page":"Filesystem","title":"Base.Filesystem.isfile","text":"isfile(path) -> Bool\n\nReturn true if path is a regular file, false otherwise.\n\nExamples\n\njulia> isfile(homedir())\nfalse\n\njulia> filename = \"test_file.txt\";\n\njulia> write(filename, \"Hello world!\");\n\njulia> isfile(filename)\ntrue\n\njulia> rm(filename);\n\njulia> isfile(filename)\nfalse\n\nSee also isdir and ispath.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.islink","page":"Filesystem","title":"Base.Filesystem.islink","text":"islink(path) -> Bool\n\nReturn true if path is a symbolic link, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.ismount","page":"Filesystem","title":"Base.Filesystem.ismount","text":"ismount(path) -> Bool\n\nReturn true if path is a mount point, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.ispath","page":"Filesystem","title":"Base.Filesystem.ispath","text":"ispath(path) -> Bool\n\nReturn true if a valid filesystem entity exists at path, otherwise returns false. This is the generalization of isfile, isdir etc.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.issetgid","page":"Filesystem","title":"Base.Filesystem.issetgid","text":"issetgid(path) -> Bool\n\nReturn true if path has the setgid flag set, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.issetuid","page":"Filesystem","title":"Base.Filesystem.issetuid","text":"issetuid(path) -> Bool\n\nReturn true if path has the setuid flag set, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.issocket","page":"Filesystem","title":"Base.Filesystem.issocket","text":"issocket(path) -> Bool\n\nReturn true if path is a socket, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.issticky","page":"Filesystem","title":"Base.Filesystem.issticky","text":"issticky(path) -> Bool\n\nReturn true if path has the sticky bit set, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.homedir","page":"Filesystem","title":"Base.Filesystem.homedir","text":"homedir() -> String\n\nReturn the current user's home directory.\n\nnote: Note\nhomedir determines the home directory via libuv's uv_os_homedir. For details (for example on how to specify the home directory via environment variables), see the uv_os_homedir documentation.\n\nSee also Sys.username.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.dirname","page":"Filesystem","title":"Base.Filesystem.dirname","text":"dirname(path::AbstractString) -> String\n\nGet the directory part of a path. Trailing characters ('/' or '\\') in the path are counted as part of the path.\n\nExamples\n\njulia> dirname(\"/home/myuser\")\n\"/home\"\n\njulia> dirname(\"/home/myuser/\")\n\"/home/myuser\"\n\nSee also basename.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.basename","page":"Filesystem","title":"Base.Filesystem.basename","text":"basename(path::AbstractString) -> String\n\nGet the file name part of a path.\n\nnote: Note\nThis function differs slightly from the Unix basename program, where trailing slashes are ignored, i.e. $ basename /foo/bar/ returns bar, whereas basename in Julia returns an empty string \"\".\n\nExamples\n\njulia> basename(\"/home/myuser/example.jl\")\n\"example.jl\"\n\njulia> basename(\"/home/myuser/\")\n\"\"\n\nSee also dirname.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isabspath","page":"Filesystem","title":"Base.Filesystem.isabspath","text":"isabspath(path::AbstractString) -> Bool\n\nDetermine whether a path is absolute (begins at the root directory).\n\nExamples\n\njulia> isabspath(\"/home\")\ntrue\n\njulia> isabspath(\"home\")\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isdirpath","page":"Filesystem","title":"Base.Filesystem.isdirpath","text":"isdirpath(path::AbstractString) -> Bool\n\nDetermine whether a path refers to a directory (for example, ends with a path separator).\n\nExamples\n\njulia> isdirpath(\"/home\")\nfalse\n\njulia> isdirpath(\"/home/\")\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.joinpath","page":"Filesystem","title":"Base.Filesystem.joinpath","text":"joinpath(parts::AbstractString...) -> String\njoinpath(parts::Vector{AbstractString}) -> String\njoinpath(parts::Tuple{AbstractString}) -> String\n\nJoin path components into a full path. If some argument is an absolute path or (on Windows) has a drive specification that doesn't match the drive computed for the join of the preceding paths, then prior components are dropped.\n\nNote on Windows since there is a current directory for each drive, joinpath(\"c:\", \"foo\") represents a path relative to the current directory on drive \"c:\" so this is equal to \"c:foo\", not \"c:\\foo\". Furthermore, joinpath treats this as a non-absolute path and ignores the drive letter casing, hence joinpath(\"C:\\A\",\"c:b\") = \"C:\\A\\b\".\n\nExamples\n\njulia> joinpath(\"/home/myuser\", \"example.jl\")\n\"/home/myuser/example.jl\"\n\njulia> joinpath([\"/home/myuser\", \"example.jl\"])\n\"/home/myuser/example.jl\"\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.abspath","page":"Filesystem","title":"Base.Filesystem.abspath","text":"abspath(path::AbstractString) -> String\n\nConvert a path to an absolute path by adding the current directory if necessary. Also normalizes the path as in normpath.\n\nExamples\n\nIf you are in a directory called JuliaExample and the data you are using is two levels up relative to the JuliaExample directory, you could write:\n\nabspath(\"../../data\")\n\nWhich gives a path like \"/home/JuliaUser/data/\".\n\nSee also joinpath, pwd, expanduser.\n\n\n\n\n\nabspath(path::AbstractString, paths::AbstractString...) -> String\n\nConvert a set of paths to an absolute path by joining them together and adding the current directory if necessary. Equivalent to abspath(joinpath(path, paths...)).\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.normpath","page":"Filesystem","title":"Base.Filesystem.normpath","text":"normpath(path::AbstractString) -> String\n\nNormalize a path, removing \".\" and \"..\" entries and changing \"/\" to the canonical path separator for the system.\n\nExamples\n\njulia> normpath(\"/home/myuser/../example.jl\")\n\"/home/example.jl\"\n\njulia> normpath(\"Documents/Julia\") == joinpath(\"Documents\", \"Julia\")\ntrue\n\n\n\n\n\nnormpath(path::AbstractString, paths::AbstractString...) -> String\n\nConvert a set of paths to a normalized path by joining them together and removing \".\" and \"..\" entries. Equivalent to normpath(joinpath(path, paths...)).\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.realpath","page":"Filesystem","title":"Base.Filesystem.realpath","text":"realpath(path::AbstractString) -> String\n\nCanonicalize a path by expanding symbolic links and removing \".\" and \"..\" entries. On case-insensitive case-preserving filesystems (typically Mac and Windows), the filesystem's stored case for the path is returned.\n\n(This function throws an exception if path does not exist in the filesystem.)\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.relpath","page":"Filesystem","title":"Base.Filesystem.relpath","text":"relpath(path::AbstractString, startpath::AbstractString = \".\") -> String\n\nReturn a relative filepath to path either from the current directory or from an optional start directory. This is a path computation: the filesystem is not accessed to confirm the existence or nature of path or startpath.\n\nOn Windows, case sensitivity is applied to every part of the path except drive letters. If path and startpath refer to different drives, the absolute path of path is returned.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.expanduser","page":"Filesystem","title":"Base.Filesystem.expanduser","text":"expanduser(path::AbstractString) -> AbstractString\n\nOn Unix systems, replace a tilde character at the start of a path with the current user's home directory.\n\nSee also: contractuser.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.contractuser","page":"Filesystem","title":"Base.Filesystem.contractuser","text":"contractuser(path::AbstractString) -> AbstractString\n\nOn Unix systems, if the path starts with homedir(), replace it with a tilde character.\n\nSee also: expanduser.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.samefile","page":"Filesystem","title":"Base.Filesystem.samefile","text":"samefile(path_a::AbstractString, path_b::AbstractString)\n\nCheck if the paths path_a and path_b refer to the same existing file or directory.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.splitdir","page":"Filesystem","title":"Base.Filesystem.splitdir","text":"splitdir(path::AbstractString) -> (AbstractString, AbstractString)\n\nSplit a path into a tuple of the directory name and file name.\n\nExamples\n\njulia> splitdir(\"/home/myuser\")\n(\"/home\", \"myuser\")\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.splitdrive","page":"Filesystem","title":"Base.Filesystem.splitdrive","text":"splitdrive(path::AbstractString) -> (AbstractString, AbstractString)\n\nOn Windows, split a path into the drive letter part and the path part. On Unix systems, the first component is always the empty string.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.splitext","page":"Filesystem","title":"Base.Filesystem.splitext","text":"splitext(path::AbstractString) -> (String, String)\n\nIf the last component of a path contains one or more dots, split the path into everything before the last dot and everything including and after the dot. Otherwise, return a tuple of the argument unmodified and the empty string. \"splitext\" is short for \"split extension\".\n\nExamples\n\njulia> splitext(\"/home/myuser/example.jl\")\n(\"/home/myuser/example\", \".jl\")\n\njulia> splitext(\"/home/myuser/example.tar.gz\")\n(\"/home/myuser/example.tar\", \".gz\")\n\njulia> splitext(\"/home/my.user/example\")\n(\"/home/my.user/example\", \"\")\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.splitpath","page":"Filesystem","title":"Base.Filesystem.splitpath","text":"splitpath(path::AbstractString) -> Vector{String}\n\nSplit a file path into all its path components. This is the opposite of joinpath. Returns an array of substrings, one for each directory or file in the path, including the root directory if present.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nExamples\n\njulia> splitpath(\"/home/myuser/example.jl\")\n4-element Vector{String}:\n \"/\"\n \"home\"\n \"myuser\"\n \"example.jl\"\n\n\n\n\n\n","category":"function"},{"location":"manual/functions/#man-functions","page":"Functions","title":"Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In Julia, a function is an object that maps a tuple of argument values to a return value. Julia functions are not pure mathematical functions, because they can alter and be affected by the global state of the program. The basic syntax for defining functions in Julia is:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> function f(x, y)\n x + y\n end\nf (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This function accepts two arguments x and y and returns the value of the last expression evaluated, which is x + y.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"There is a second, more terse syntax for defining a function in Julia. The traditional function declaration syntax demonstrated above is equivalent to the following compact \"assignment form\":","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(x, y) = x + y\nf (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In the assignment form, the body of the function must be a single expression, although it can be a compound expression (see Compound Expressions). Short, simple function definitions are common in Julia. The short function syntax is accordingly quite idiomatic, considerably reducing both typing and visual noise.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A function is called using the traditional parenthesis syntax:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(2, 3)\n5","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Without parentheses, the expression f refers to the function object, and can be passed around like any other value:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> g = f;\n\njulia> g(2, 3)\n5","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"As with variables, Unicode can also be used for function names:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> ∑(x, y) = x + y\n∑ (generic function with 1 method)\n\njulia> ∑(2, 3)\n5","category":"page"},{"location":"manual/functions/#man-argument-passing","page":"Functions","title":"Argument Passing Behavior","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Julia function arguments follow a convention sometimes called \"pass-by-sharing\", which means that values are not copied when they are passed to functions. Function arguments themselves act as new variable bindings (new \"names\" that can refer to values), much like assignments argument_name = argument_value, so that the objects they refer to are identical to the passed values. Modifications to mutable values (such as Arrays) made within a function will be visible to the caller. (This is the same behavior found in Scheme, most Lisps, Python, Ruby and Perl, among other dynamic languages.)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For example, in the function","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(x, y)\n x[1] = 42 # mutates x\n y = 7 + y # new binding for y, no mutation\n return y\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The statement x[1] = 42 mutates the object x, and hence this change will be visible in the array passed by the caller for this argument. On the other hand, the assignment y = 7 + y changes the binding (\"name\") y to refer to a new value 7 + y, rather than mutating the original object referred to by y, and hence does not change the corresponding argument passed by the caller. This can be seen if we call f(x, y):","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> a = [4, 5, 6]\n3-element Vector{Int64}:\n 4\n 5\n 6\n\njulia> b = 3\n3\n\njulia> f(a, b) # returns 7 + b == 10\n10\n\njulia> a # a[1] is changed to 42 by f\n3-element Vector{Int64}:\n 42\n 5\n 6\n\njulia> b # not changed\n3","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"As a common convention in Julia (not a syntactic requirement), such a function would typically be named f!(x, y) rather than f(x, y), as a visual reminder at the call site that at least one of the arguments (often the first one) is being mutated.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"warning: Shared memory between arguments\nThe behavior of a mutating function can be unexpected when a mutated argument shares memory with another argument, a situation known as aliasing (e.g. when one is a view of the other). Unless the function docstring explicitly indicates that aliasing produces the expected result, it is the responsibility of the caller to ensure proper behavior on such inputs.","category":"page"},{"location":"manual/functions/#Argument-type-declarations","page":"Functions","title":"Argument-type declarations","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"You can declare the types of function arguments by appending ::TypeName to the argument name, as usual for Type Declarations in Julia. For example, the following function computes Fibonacci numbers recursively:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"fib(n::Integer) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"and the ::Integer specification means that it will only be callable when n is a subtype of the abstract Integer type.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Argument-type declarations normally have no impact on performance: regardless of what argument types (if any) are declared, Julia compiles a specialized version of the function for the actual argument types passed by the caller. For example, calling fib(1) will trigger the compilation of specialized version of fib optimized specifically for Int arguments, which is then re-used if fib(7) or fib(15) are called. (There are rare exceptions when an argument-type declaration can trigger additional compiler specializations; see: Be aware of when Julia avoids specializing.) The most common reasons to declare argument types in Julia are, instead:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Dispatch: As explained in Methods, you can have different versions (\"methods\") of a function for different argument types, in which case the argument types are used to determine which implementation is called for which arguments. For example, you might implement a completely different algorithm fib(x::Number) = ... that works for any Number type by using Binet's formula to extend it to non-integer values.\nCorrectness: Type declarations can be useful if your function only returns correct results for certain argument types. For example, if we omitted argument types and wrote fib(n) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2), then fib(1.5) would silently give us the nonsensical answer 1.0.\nClarity: Type declarations can serve as a form of documentation about the expected arguments.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"However, it is a common mistake to overly restrict the argument types, which can unnecessarily limit the applicability of the function and prevent it from being re-used in circumstances you did not anticipate. For example, the fib(n::Integer) function above works equally well for Int arguments (machine integers) and BigInt arbitrary-precision integers (see BigFloats and BigInts), which is especially useful because Fibonacci numbers grow exponentially rapidly and will quickly overflow any fixed-precision type like Int (see Overflow behavior). If we had declared our function as fib(n::Int), however, the application to BigInt would have been prevented for no reason. In general, you should use the most general applicable abstract types for arguments, and when in doubt, omit the argument types. You can always add argument-type specifications later if they become necessary, and you don't sacrifice performance or functionality by omitting them.","category":"page"},{"location":"manual/functions/#The-return-Keyword","page":"Functions","title":"The return Keyword","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The value returned by a function is the value of the last expression evaluated, which, by default, is the last expression in the body of the function definition. In the example function, f, from the previous section this is the value of the expression x + y. As an alternative, as in many other languages, the return keyword causes a function to return immediately, providing an expression whose value is returned:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function g(x, y)\n return x * y\n x + y\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Since function definitions can be entered into interactive sessions, it is easy to compare these definitions:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(x, y) = x + y\nf (generic function with 1 method)\n\njulia> function g(x, y)\n return x * y\n x + y\n end\ng (generic function with 1 method)\n\njulia> f(2, 3)\n5\n\njulia> g(2, 3)\n6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Of course, in a purely linear function body like g, the usage of return is pointless since the expression x + y is never evaluated and we could simply make x * y the last expression in the function and omit the return. In conjunction with other control flow, however, return is of real use. Here, for example, is a function that computes the hypotenuse length of a right triangle with sides of length x and y, avoiding overflow:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> function hypot(x, y)\n x = abs(x)\n y = abs(y)\n if x > y\n r = y/x\n return x*sqrt(1 + r*r)\n end\n if y == 0\n return zero(x)\n end\n r = x/y\n return y*sqrt(1 + r*r)\n end\nhypot (generic function with 1 method)\n\njulia> hypot(3, 4)\n5.0","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"There are three possible points of return from this function, returning the values of three different expressions, depending on the values of x and y. The return on the last line could be omitted since it is the last expression.","category":"page"},{"location":"manual/functions/#man-functions-return-type","page":"Functions","title":"Return type","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A return type can be specified in the function declaration using the :: operator. This converts the return value to the specified type.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> function g(x, y)::Int8\n return x * y\n end;\n\njulia> typeof(g(1, 2))\nInt8","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This function will always return an Int8 regardless of the types of x and y. See Type Declarations for more on return types.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Return type declarations are rarely used in Julia: in general, you should instead write \"type-stable\" functions in which Julia's compiler can automatically infer the return type. For more information, see the Performance Tips chapter.","category":"page"},{"location":"manual/functions/#Returning-nothing","page":"Functions","title":"Returning nothing","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For functions that do not need to return a value (functions used only for some side effects), the Julia convention is to return the value nothing:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function printx(x)\n println(\"x = $x\")\n return nothing\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This is a convention in the sense that nothing is not a Julia keyword but only a singleton object of type Nothing. Also, you may notice that the printx function example above is contrived, because println already returns nothing, so that the return line is redundant.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"There are two possible shortened forms for the return nothing expression. On the one hand, the return keyword implicitly returns nothing, so it can be used alone. On the other hand, since functions implicitly return their last expression evaluated, nothing can be used alone when it's the last expression. The preference for the expression return nothing as opposed to return or nothing alone is a matter of coding style.","category":"page"},{"location":"manual/functions/#Operators-Are-Functions","page":"Functions","title":"Operators Are Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In Julia, most operators are just functions with support for special syntax. (The exceptions are operators with special evaluation semantics like && and ||. These operators cannot be functions since Short-Circuit Evaluation requires that their operands are not evaluated before evaluation of the operator.) Accordingly, you can also apply them using parenthesized argument lists, just as you would any other function:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> 1 + 2 + 3\n6\n\njulia> +(1, 2, 3)\n6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The infix form is exactly equivalent to the function application form – in fact the former is parsed to produce the function call internally. This also means that you can assign and pass around operators such as + and * just like you would with other function values:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f = +;\n\njulia> f(1, 2, 3)\n6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Under the name f, the function does not support infix notation, however.","category":"page"},{"location":"manual/functions/#Operators-With-Special-Names","page":"Functions","title":"Operators With Special Names","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A few special expressions correspond to calls to functions with non-obvious names. These are:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Expression Calls\n[A B C ...] hcat\n[A; B; C; ...] vcat\n[A B; C D; ...] hvcat\n[A; B;; C; D;; ...] hvncat\nA' adjoint\nA[i] getindex\nA[i] = x setindex!\nA.n getproperty\nA.n = x setproperty!","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Note that expressions similar to [A; B;; C; D;; ...] but with more than two consecutive ; also correspond to hvncat calls.","category":"page"},{"location":"manual/functions/#man-anonymous-functions","page":"Functions","title":"Anonymous Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Functions in Julia are first-class objects: they can be assigned to variables, and called using the standard function call syntax from the variable they have been assigned to. They can be used as arguments, and they can be returned as values. They can also be created anonymously, without being given a name, using either of these syntaxes:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x -> x^2 + 2x - 1\n#1 (generic function with 1 method)\n\njulia> function (x)\n x^2 + 2x - 1\n end\n#3 (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Each statement creates a function taking one argument x and returning the value of the polynomial x^2 + 2x - 1 at that value. Notice that the result is a generic function, but with a compiler-generated name based on consecutive numbering.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The primary use for anonymous functions is passing them to functions which take other functions as arguments. A classic example is map, which applies a function to each value of an array and returns a new array containing the resulting values:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> map(round, [1.2, 3.5, 1.7])\n3-element Vector{Float64}:\n 1.0\n 4.0\n 2.0","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This is fine if a named function effecting the transform already exists to pass as the first argument to map. Often, however, a ready-to-use, named function does not exist. In these situations, the anonymous function construct allows easy creation of a single-use function object without needing a name:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> map(x -> x^2 + 2x - 1, [1, 3, -1])\n3-element Vector{Int64}:\n 2\n 14\n -2","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"An anonymous function accepting multiple arguments can be written using the syntax (x,y,z)->2x+y-z.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Argument-type declarations for anonymous functions work as for named functions, for example x::Integer->2x. The return type of an anonymous function cannot be specified.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A zero-argument anonymous function can be written as ()->2+2. The idea of a function with no arguments may seem strange, but is useful in cases where a result cannot (or should not) be precomputed. For example, Julia has a zero-argument time function that returns the current time in seconds, and thus seconds = ()->round(Int, time()) is an anonymous function that returns this time rounded to the nearest integer assigned to the variable seconds. Each time this anonymous function is called as seconds() the current time will be calculated and returned.","category":"page"},{"location":"manual/functions/#Tuples","page":"Functions","title":"Tuples","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Julia has a built-in data structure called a tuple that is closely related to function arguments and return values. A tuple is a fixed-length container that can hold any values, but cannot be modified (it is immutable). Tuples are constructed with commas and parentheses, and can be accessed via indexing:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (1, 1+1)\n(1, 2)\n\njulia> (1,)\n(1,)\n\njulia> x = (0.0, \"hello\", 6*7)\n(0.0, \"hello\", 42)\n\njulia> x[2]\n\"hello\"","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Notice that a length-1 tuple must be written with a comma, (1,), since (1) would just be a parenthesized value. () represents the empty (length-0) tuple.","category":"page"},{"location":"manual/functions/#Named-Tuples","page":"Functions","title":"Named Tuples","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The components of tuples can optionally be named, in which case a named tuple is constructed:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x = (a=2, b=1+2)\n(a = 2, b = 3)\n\njulia> x[1]\n2\n\njulia> x.a\n2","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The fields of named tuples can be accessed by name using dot syntax (x.a) in addition to the regular indexing syntax (x[1] or x[:a]).","category":"page"},{"location":"manual/functions/#destructuring-assignment","page":"Functions","title":"Destructuring Assignment and Multiple Return Values","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A comma-separated list of variables (optionally wrapped in parentheses) can appear on the left side of an assignment: the value on the right side is destructured by iterating over and assigning to each variable in turn:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (a, b, c) = 1:3\n1:3\n\njulia> b\n2","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The value on the right should be an iterator (see Iteration interface) at least as long as the number of variables on the left (any excess elements of the iterator are ignored).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This can be used to return multiple values from functions by returning a tuple or other iterable value. For example, the following function returns two values:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> function foo(a, b)\n a+b, a*b\n end\nfoo (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"If you call it in an interactive session without assigning the return value anywhere, you will see the tuple returned:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> foo(2, 3)\n(5, 6)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Destructuring assignment extracts each value into a variable:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x, y = foo(2, 3)\n(5, 6)\n\njulia> x\n5\n\njulia> y\n6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Another common use is for swapping variables:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> y, x = x, y\n(5, 6)\n\njulia> x\n6\n\njulia> y\n5","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"If only a subset of the elements of the iterator are required, a common convention is to assign ignored elements to a variable consisting of only underscores _ (which is an otherwise invalid variable name, see Allowed Variable Names):","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> _, _, _, d = 1:10\n1:10\n\njulia> d\n4","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Other valid left-hand side expressions can be used as elements of the assignment list, which will call setindex! or setproperty!, or recursively destructure individual elements of the iterator:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> X = zeros(3);\n\njulia> X[1], (a, b) = (1, (2, 3))\n(1, (2, 3))\n\njulia> X\n3-element Vector{Float64}:\n 1.0\n 0.0\n 0.0\n\njulia> a\n2\n\njulia> b\n3","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"compat: Julia 1.6\n... with assignment requires Julia 1.6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"If the last symbol in the assignment list is suffixed by ... (known as slurping), then it will be assigned a collection or lazy iterator of the remaining elements of the right-hand side iterator:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> a, b... = \"hello\"\n\"hello\"\n\njulia> a\n'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)\n\njulia> b\n\"ello\"\n\njulia> a, b... = Iterators.map(abs2, 1:4)\nBase.Generator{UnitRange{Int64}, typeof(abs2)}(abs2, 1:4)\n\njulia> a\n1\n\njulia> b\nBase.Iterators.Rest{Base.Generator{UnitRange{Int64}, typeof(abs2)}, Int64}(Base.Generator{UnitRange{Int64}, typeof(abs2)}(abs2, 1:4), 1)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"See Base.rest for details on the precise handling and customization for specific iterators.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"compat: Julia 1.9\n... in non-final position of an assignment requires Julia 1.9","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Slurping in assignments can also occur in any other position. As opposed to slurping the end of a collection however, this will always be eager.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> a, b..., c = 1:5\n1:5\n\njulia> a\n1\n\njulia> b\n3-element Vector{Int64}:\n 2\n 3\n 4\n\njulia> c\n5\n\njulia> front..., tail = \"Hi!\"\n\"Hi!\"\n\njulia> front\n\"Hi\"\n\njulia> tail\n'!': ASCII/Unicode U+0021 (category Po: Punctuation, other)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This is implemented in terms of the function Base.split_rest.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Note that for variadic function definitions, slurping is still only allowed in final position. This does not apply to single argument destructuring though, as that does not affect method dispatch:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(x..., y) = x\nERROR: syntax: invalid \"...\" on non-final argument\nStacktrace:\n[...]\n\njulia> f((x..., y)) = x\nf (generic function with 1 method)\n\njulia> f((1, 2, 3))\n(1, 2)","category":"page"},{"location":"manual/functions/#Property-destructuring","page":"Functions","title":"Property destructuring","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Instead of destructuring based on iteration, the right side of assignments can also be destructured using property names. This follows the syntax for NamedTuples, and works by assigning to each variable on the left a property of the right side of the assignment with the same name using getproperty:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (; b, a) = (a=1, b=2, c=3)\n(a = 1, b = 2, c = 3)\n\njulia> a\n1\n\njulia> b\n2","category":"page"},{"location":"manual/functions/#man-argument-destructuring","page":"Functions","title":"Argument destructuring","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The destructuring feature can also be used within a function argument. If a function argument name is written as a tuple (e.g. (x, y)) instead of just a symbol, then an assignment (x, y) = argument will be inserted for you:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> minmax(x, y) = (y < x) ? (y, x) : (x, y)\n\njulia> gap((min, max)) = max - min\n\njulia> gap(minmax(10, 2))\n8","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Notice the extra set of parentheses in the definition of gap. Without those, gap would be a two-argument function, and this example would not work.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Similarly, property destructuring can also be used for function arguments:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> foo((; x, y)) = x + y\nfoo (generic function with 1 method)\n\njulia> foo((x=1, y=2))\n3\n\njulia> struct A\n x\n y\n end\n\njulia> foo(A(3, 4))\n7","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For anonymous functions, destructuring a single argument requires an extra comma:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> map(((x, y),) -> x + y, [(1, 2), (3, 4)])\n2-element Array{Int64,1}:\n 3\n 7","category":"page"},{"location":"manual/functions/#Varargs-Functions","page":"Functions","title":"Varargs Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"It is often convenient to be able to write functions taking an arbitrary number of arguments. Such functions are traditionally known as \"varargs\" functions, which is short for \"variable number of arguments\". You can define a varargs function by following the last positional argument with an ellipsis:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> bar(a, b, x...) = (a, b, x)\nbar (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The variables a and b are bound to the first two argument values as usual, and the variable x is bound to an iterable collection of the zero or more values passed to bar after its first two arguments:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> bar(1, 2)\n(1, 2, ())\n\njulia> bar(1, 2, 3)\n(1, 2, (3,))\n\njulia> bar(1, 2, 3, 4)\n(1, 2, (3, 4))\n\njulia> bar(1, 2, 3, 4, 5, 6)\n(1, 2, (3, 4, 5, 6))","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In all these cases, x is bound to a tuple of the trailing values passed to bar.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"It is possible to constrain the number of values passed as a variable argument; this will be discussed later in Parametrically-constrained Varargs methods.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"On the flip side, it is often handy to \"splat\" the values contained in an iterable collection into a function call as individual arguments. To do this, one also uses ... but in the function call instead:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x = (3, 4)\n(3, 4)\n\njulia> bar(1, 2, x...)\n(1, 2, (3, 4))","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In this case a tuple of values is spliced into a varargs call precisely where the variable number of arguments go. This need not be the case, however:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x = (2, 3, 4)\n(2, 3, 4)\n\njulia> bar(1, x...)\n(1, 2, (3, 4))\n\njulia> x = (1, 2, 3, 4)\n(1, 2, 3, 4)\n\njulia> bar(x...)\n(1, 2, (3, 4))","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Furthermore, the iterable object splatted into a function call need not be a tuple:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x = [3, 4]\n2-element Vector{Int64}:\n 3\n 4\n\njulia> bar(1, 2, x...)\n(1, 2, (3, 4))\n\njulia> x = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> bar(x...)\n(1, 2, (3, 4))","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Also, the function that arguments are splatted into need not be a varargs function (although it often is):","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> baz(a, b) = a + b;\n\njulia> args = [1, 2]\n2-element Vector{Int64}:\n 1\n 2\n\njulia> baz(args...)\n3\n\njulia> args = [1, 2, 3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> baz(args...)\nERROR: MethodError: no method matching baz(::Int64, ::Int64, ::Int64)\nThe function `baz` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n baz(::Any, ::Any)\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"As you can see, if the wrong number of elements are in the splatted container, then the function call will fail, just as it would if too many arguments were given explicitly.","category":"page"},{"location":"manual/functions/#Optional-Arguments","page":"Functions","title":"Optional Arguments","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"It is often possible to provide sensible default values for function arguments. This can save users from having to pass every argument on every call. For example, the function Date(y, [m, d]) from Dates module constructs a Date type for a given year y, month m and day d. However, m and d arguments are optional and their default value is 1. This behavior can be expressed concisely as:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> using Dates\n\njulia> function date(y::Int64, m::Int64=1, d::Int64=1)\n err = Dates.validargs(Date, y, m, d)\n err === nothing || throw(err)\n return Date(Dates.UTD(Dates.totaldays(y, m, d)))\n end\ndate (generic function with 3 methods)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Observe, that this definition calls another method of the Date function that takes one argument of type UTInstant{Day}.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"With this definition, the function can be called with either one, two or three arguments, and 1 is automatically passed when only one or two of the arguments are specified:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> date(2000, 12, 12)\n2000-12-12\n\njulia> date(2000, 12)\n2000-12-01\n\njulia> date(2000)\n2000-01-01","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Optional arguments are actually just a convenient syntax for writing multiple method definitions with different numbers of arguments (see Note on Optional and keyword Arguments). This can be checked for our date function example by calling the methods function:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> methods(date)\n# 3 methods for generic function \"date\":\n[1] date(y::Int64) in Main at REPL[1]:1\n[2] date(y::Int64, m::Int64) in Main at REPL[1]:1\n[3] date(y::Int64, m::Int64, d::Int64) in Main at REPL[1]:1","category":"page"},{"location":"manual/functions/#Keyword-Arguments","page":"Functions","title":"Keyword Arguments","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Some functions need a large number of arguments, or have a large number of behaviors. Remembering how to call such functions can be difficult. Keyword arguments can make these complex interfaces easier to use and extend by allowing arguments to be identified by name instead of only by position.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For example, consider a function plot that plots a line. This function might have many options, for controlling line style, width, color, and so on. If it accepts keyword arguments, a possible call might look like plot(x, y, width=2), where we have chosen to specify only line width. Notice that this serves two purposes. The call is easier to read, since we can label an argument with its meaning. It also becomes possible to pass any subset of a large number of arguments, in any order.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Functions with keyword arguments are defined using a semicolon in the signature:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function plot(x, y; style=\"solid\", width=1, color=\"black\")\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"When the function is called, the semicolon is optional: one can either call plot(x, y, width=2) or plot(x, y; width=2), but the former style is more common. An explicit semicolon is required only for passing varargs or computed keywords as described below.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Keyword argument default values are evaluated only when necessary (when a corresponding keyword argument is not passed), and in left-to-right order. Therefore default expressions may refer to prior keyword arguments.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The types of keyword arguments can be made explicit as follows:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(; x::Int=1)\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Keyword arguments can also be used in varargs functions:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function plot(x...; style=\"solid\")\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Extra keyword arguments can be collected using ..., as in varargs functions:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(x; y=0, kwargs...)\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Inside f, kwargs will be an immutable key-value iterator over a named tuple. Named tuples (as well as dictionaries with keys of Symbol, and other iterators yielding two-value collections with symbol as first values) can be passed as keyword arguments using a semicolon in a call, e.g. f(x, z=1; kwargs...).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"If a keyword argument is not assigned a default value in the method definition, then it is required: an UndefKeywordError exception will be thrown if the caller does not assign it a value:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(x; y)\n ###\nend\nf(3, y=5) # ok, y is assigned\nf(3) # throws UndefKeywordError(:y)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"One can also pass key => value expressions after a semicolon. For example, plot(x, y; :width => 2) is equivalent to plot(x, y, width=2). This is useful in situations where the keyword name is computed at runtime.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"When a bare identifier or dot expression occurs after a semicolon, the keyword argument name is implied by the identifier or field name. For example plot(x, y; width) is equivalent to plot(x, y; width=width) and plot(x, y; options.width) is equivalent to plot(x, y; width=options.width).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The nature of keyword arguments makes it possible to specify the same argument more than once. For example, in the call plot(x, y; options..., width=2) it is possible that the options structure also contains a value for width. In such a case the rightmost occurrence takes precedence; in this example, width is certain to have the value 2. However, explicitly specifying the same keyword argument multiple times, for example plot(x, y, width=2, width=3), is not allowed and results in a syntax error.","category":"page"},{"location":"manual/functions/#Evaluation-Scope-of-Default-Values","page":"Functions","title":"Evaluation Scope of Default Values","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"When optional and keyword argument default expressions are evaluated, only previous arguments are in scope. For example, given this definition:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(x, a=b, b=1)\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"the b in a=b refers to a b in an outer scope, not the subsequent argument b.","category":"page"},{"location":"manual/functions/#Do-Block-Syntax-for-Function-Arguments","page":"Functions","title":"Do-Block Syntax for Function Arguments","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Passing functions as arguments to other functions is a powerful technique, but the syntax for it is not always convenient. Such calls are especially awkward to write when the function argument requires multiple lines. As an example, consider calling map on a function with several cases:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"map(x->begin\n if x < 0 && iseven(x)\n return 0\n elseif x == 0\n return 1\n else\n return x\n end\n end,\n [A, B, C])","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Julia provides a reserved word do for rewriting this code more clearly:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"map([A, B, C]) do x\n if x < 0 && iseven(x)\n return 0\n elseif x == 0\n return 1\n else\n return x\n end\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The do x syntax creates an anonymous function with argument x and passes the anonymous function as the first argument to the \"outer\" function - map in this example. Similarly, do a,b would create a two-argument anonymous function. Note that do (a,b) would create a one-argument anonymous function, whose argument is a tuple to be deconstructed. A plain do would declare that what follows is an anonymous function of the form () -> ....","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"How these arguments are initialized depends on the \"outer\" function; here, map will sequentially set x to A, B, C, calling the anonymous function on each, just as would happen in the syntax map(func, [A, B, C]).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This syntax makes it easier to use functions to effectively extend the language, since calls look like normal code blocks. There are many possible uses quite different from map, such as managing system state. For example, there is a version of open that runs code ensuring that the opened file is eventually closed:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"open(\"outfile\", \"w\") do io\n write(io, data)\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This is accomplished by the following definition:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function open(f::Function, args...)\n io = open(args...)\n try\n f(io)\n finally\n close(io)\n end\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Here, open first opens the file for writing and then passes the resulting output stream to the anonymous function you defined in the do ... end block. After your function exits, open will make sure that the stream is properly closed, regardless of whether your function exited normally or threw an exception. (The try/finally construct will be described in Control Flow.)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"With the do block syntax, it helps to check the documentation or implementation to know how the arguments of the user function are initialized.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A do block, like any other inner function, can \"capture\" variables from its enclosing scope. For example, the variable data in the above example of open...do is captured from the outer scope. Captured variables can create performance challenges as discussed in performance tips.","category":"page"},{"location":"manual/functions/#Function-composition-and-piping","page":"Functions","title":"Function composition and piping","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Functions in Julia can be combined by composing or piping (chaining) them together.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Function composition is when you combine functions together and apply the resulting composition to arguments. You use the function composition operator (∘) to compose the functions, so (f ∘ g)(args...; kw...) is the same as f(g(args...; kw...)).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"You can type the composition operator at the REPL and suitably-configured editors using \\circ.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For example, the sqrt and + functions can be composed like this:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (sqrt ∘ +)(3, 6)\n3.0","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This adds the numbers first, then finds the square root of the result.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The next example composes three functions and maps the result over an array of strings:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> map(first ∘ reverse ∘ uppercase, split(\"you can compose functions like this\"))\n6-element Vector{Char}:\n 'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)\n 'N': ASCII/Unicode U+004E (category Lu: Letter, uppercase)\n 'E': ASCII/Unicode U+0045 (category Lu: Letter, uppercase)\n 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)\n 'E': ASCII/Unicode U+0045 (category Lu: Letter, uppercase)\n 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Function chaining (sometimes called \"piping\" or \"using a pipe\" to send data to a subsequent function) is when you apply a function to the previous function's output:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> 1:10 |> sum |> sqrt\n7.416198487095663","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Here, the total produced by sum is passed to the sqrt function. The equivalent composition would be:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (sqrt ∘ sum)(1:10)\n7.416198487095663","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The pipe operator can also be used with broadcasting, as .|>, to provide a useful combination of the chaining/piping and dot vectorization syntax (described below).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> [\"a\", \"list\", \"of\", \"strings\"] .|> [uppercase, reverse, titlecase, length]\n4-element Vector{Any}:\n \"A\"\n \"tsil\"\n \"Of\"\n 7","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"When combining pipes with anonymous functions, parentheses must be used if subsequent pipes are not to be parsed as part of the anonymous function's body. Compare:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> 1:3 .|> (x -> x^2) |> sum |> sqrt\n3.7416573867739413\n\njulia> 1:3 .|> x -> x^2 |> sum |> sqrt\n3-element Vector{Float64}:\n 1.0\n 2.0\n 3.0","category":"page"},{"location":"manual/functions/#man-vectorized","page":"Functions","title":"Dot Syntax for Vectorizing Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In technical-computing languages, it is common to have \"vectorized\" versions of functions, which simply apply a given function f(x) to each element of an array A to yield a new array via f(A). This kind of syntax is convenient for data processing, but in other languages vectorization is also often required for performance: if loops are slow, the \"vectorized\" version of a function can call fast library code written in a low-level language. In Julia, vectorized functions are not required for performance, and indeed it is often beneficial to write your own loops (see Performance Tips), but they can still be convenient. Therefore, any Julia function f can be applied elementwise to any array (or other collection) with the syntax f.(A). For example, sin can be applied to all elements in the vector A like so:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> A = [1.0, 2.0, 3.0]\n3-element Vector{Float64}:\n 1.0\n 2.0\n 3.0\n\njulia> sin.(A)\n3-element Vector{Float64}:\n 0.8414709848078965\n 0.9092974268256817\n 0.1411200080598672","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Of course, you can omit the dot if you write a specialized \"vector\" method of f, e.g. via f(A::AbstractArray) = map(f, A), and this is just as efficient as f.(A). The advantage of the f.(A) syntax is that which functions are vectorizable need not be decided upon in advance by the library writer.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"More generally, f.(args...) is actually equivalent to broadcast(f, args...), which allows you to operate on multiple arrays (even of different shapes), or a mix of arrays and scalars (see Broadcasting). For example, if you have f(x, y) = 3x + 4y, then f.(pi, A) will return a new array consisting of f(pi,a) for each a in A, and f.(vector1, vector2) will return a new vector consisting of f(vector1[i], vector2[i]) for each index i (throwing an exception if the vectors have different length).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(x, y) = 3x + 4y;\n\njulia> A = [1.0, 2.0, 3.0];\n\njulia> B = [4.0, 5.0, 6.0];\n\njulia> f.(pi, A)\n3-element Vector{Float64}:\n 13.42477796076938\n 17.42477796076938\n 21.42477796076938\n\njulia> f.(A, B)\n3-element Vector{Float64}:\n 19.0\n 26.0\n 33.0","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Keyword arguments are not broadcasted over, but are simply passed through to each call of the function. For example, round.(x, digits=3) is equivalent to broadcast(x -> round(x, digits=3), x).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Moreover, nested f.(args...) calls are fused into a single broadcast loop. For example, sin.(cos.(X)) is equivalent to broadcast(x -> sin(cos(x)), X), similar to [sin(cos(x)) for x in X]: there is only a single loop over X, and a single array is allocated for the result. [In contrast, sin(cos(X)) in a typical \"vectorized\" language would first allocate one temporary array for tmp=cos(X), and then compute sin(tmp) in a separate loop, allocating a second array.] This loop fusion is not a compiler optimization that may or may not occur, it is a syntactic guarantee whenever nested f.(args...) calls are encountered. Technically, the fusion stops as soon as a \"non-dot\" function call is encountered; for example, in sin.(sort(cos.(X))) the sin and cos loops cannot be merged because of the intervening sort function.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Finally, the maximum efficiency is typically achieved when the output array of a vectorized operation is pre-allocated, so that repeated calls do not allocate new arrays over and over again for the results (see Pre-allocating outputs). A convenient syntax for this is X .= ..., which is equivalent to broadcast!(identity, X, ...) except that, as above, the broadcast! loop is fused with any nested \"dot\" calls. For example, X .= sin.(Y) is equivalent to broadcast!(sin, X, Y), overwriting X with sin.(Y) in-place. If the left-hand side is an array-indexing expression, e.g. X[begin+1:end] .= sin.(Y), then it translates to broadcast! on a view, e.g. broadcast!(sin, view(X, firstindex(X)+1:lastindex(X)), Y), so that the left-hand side is updated in-place.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Since adding dots to many operations and function calls in an expression can be tedious and lead to code that is difficult to read, the macro @. is provided to convert every function call, operation, and assignment in an expression into the \"dotted\" version.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> Y = [1.0, 2.0, 3.0, 4.0];\n\njulia> X = similar(Y); # pre-allocate output array\n\njulia> @. X = sin(cos(Y)) # equivalent to X .= sin.(cos.(Y))\n4-element Vector{Float64}:\n 0.5143952585235492\n -0.4042391538522658\n -0.8360218615377305\n -0.6080830096407656","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Binary (or unary) operators like .+ are handled with the same mechanism: they are equivalent to broadcast calls and are fused with other nested \"dot\" calls. X .+= Y etcetera is equivalent to X .= X .+ Y and results in a fused in-place assignment; see also dot operators.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"You can also combine dot operations with function chaining using |>, as in this example:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> 1:5 .|> [x->x^2, inv, x->2*x, -, isodd]\n5-element Vector{Real}:\n 1\n 0.5\n 6\n -4\n true","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"All functions in the fused broadcast are always called for every element of the result. Thus X .+ σ .* randn.() will add a mask of independent and identically sampled random values to each element of the array X, but X .+ σ .* randn() will add the same random sample to each element. In cases where the fused computation is constant along one or more axes of the broadcast iteration, it may be possible to leverage a space-time tradeoff and allocate intermediate values to reduce the number of computations. See more at performance tips.","category":"page"},{"location":"manual/functions/#Further-Reading","page":"Functions","title":"Further Reading","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"We should mention here that this is far from a complete picture of defining functions. Julia has a sophisticated type system and allows multiple dispatch on argument types. None of the examples given here provide any type annotations on their arguments, meaning that they are applicable to all types of arguments. The type system is described in Types and defining a function in terms of methods chosen by multiple dispatch on run-time argument types is described in Methods.","category":"page"},{"location":"stdlib/Mmap/","page":"Memory-mapped I/O","title":"Memory-mapped I/O","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Mmap/docs/src/index.md\"","category":"page"},{"location":"stdlib/Mmap/#Memory-mapped-I/O","page":"Memory-mapped I/O","title":"Memory-mapped I/O","text":"","category":"section"},{"location":"stdlib/Mmap/","page":"Memory-mapped I/O","title":"Memory-mapped I/O","text":"Low level module for mmap (memory mapping of files).","category":"page"},{"location":"stdlib/Mmap/","page":"Memory-mapped I/O","title":"Memory-mapped I/O","text":"Mmap.Anonymous\nMmap.mmap\nMmap.sync!","category":"page"},{"location":"stdlib/Mmap/#Mmap.Anonymous","page":"Memory-mapped I/O","title":"Mmap.Anonymous","text":"Mmap.Anonymous(name::AbstractString=\"\", readonly::Bool=false, create::Bool=true)\n\nCreate an IO-like object for creating zeroed-out mmapped-memory that is not tied to a file for use in mmap. Used by SharedArray for creating shared memory arrays.\n\nExamples\n\njulia> using Mmap\n\njulia> anon = Mmap.Anonymous();\n\njulia> isreadable(anon)\ntrue\n\njulia> iswritable(anon)\ntrue\n\njulia> isopen(anon)\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Mmap/#Mmap.mmap","page":"Memory-mapped I/O","title":"Mmap.mmap","text":"mmap(io::Union{IOStream,AbstractString,Mmap.AnonymousMmap}[, type::Type{Array{T,N}}, dims, offset]; grow::Bool=true, shared::Bool=true)\nmmap(type::Type{Array{T,N}}, dims)\n\nCreate an Array whose values are linked to a file, using memory-mapping. This provides a convenient way of working with data too large to fit in the computer's memory.\n\nThe type is an Array{T,N} with a bits-type element of T and dimension N that determines how the bytes of the array are interpreted. Note that the file must be stored in binary format, and no format conversions are possible (this is a limitation of operating systems, not Julia).\n\ndims is a tuple or single Integer specifying the size or length of the array.\n\nThe file is passed via the stream argument, either as an open IOStream or filename string. When you initialize the stream, use \"r\" for a \"read-only\" array, and \"w+\" to create a new array used to write values to disk.\n\nIf no type argument is specified, the default is Vector{UInt8}.\n\nOptionally, you can specify an offset (in bytes) if, for example, you want to skip over a header in the file. The default value for the offset is the current stream position for an IOStream.\n\nThe grow keyword argument specifies whether the disk file should be grown to accommodate the requested size of array (if the total file size is < requested array size). Write privileges are required to grow the file.\n\nThe shared keyword argument specifies whether the resulting Array and changes made to it will be visible to other processes mapping the same file.\n\nFor example, the following code\n\n# Create a file for mmapping\n# (you could alternatively use mmap to do this step, too)\nusing Mmap\nA = rand(1:20, 5, 30)\ns = open(\"/tmp/mmap.bin\", \"w+\")\n# We'll write the dimensions of the array as the first two Ints in the file\nwrite(s, size(A,1))\nwrite(s, size(A,2))\n# Now write the data\nwrite(s, A)\nclose(s)\n\n# Test by reading it back in\ns = open(\"/tmp/mmap.bin\") # default is read-only\nm = read(s, Int)\nn = read(s, Int)\nA2 = mmap(s, Matrix{Int}, (m,n))\n\ncreates a m-by-n Matrix{Int}, linked to the file associated with stream s.\n\nA more portable file would need to encode the word size – 32 bit or 64 bit – and endianness information in the header. In practice, consider encoding binary data using standard formats like HDF5 (which can be used with memory-mapping).\n\n\n\n\n\nmmap(io, BitArray, [dims, offset])\n\nCreate a BitArray whose values are linked to a file, using memory-mapping; it has the same purpose, works in the same way, and has the same arguments, as mmap, but the byte representation is different.\n\nExamples\n\njulia> using Mmap\n\njulia> io = open(\"mmap.bin\", \"w+\");\n\njulia> B = mmap(io, BitArray, (25,30000));\n\njulia> B[3, 4000] = true;\n\njulia> Mmap.sync!(B);\n\njulia> close(io);\n\njulia> io = open(\"mmap.bin\", \"r+\");\n\njulia> C = mmap(io, BitArray, (25,30000));\n\njulia> C[3, 4000]\ntrue\n\njulia> C[2, 4000]\nfalse\n\njulia> close(io)\n\njulia> rm(\"mmap.bin\")\n\nThis creates a 25-by-30000 BitArray, linked to the file associated with stream io.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Mmap/#Mmap.sync!","page":"Memory-mapped I/O","title":"Mmap.sync!","text":"Mmap.sync!(array)\n\nForces synchronization between the in-memory version of a memory-mapped Array or BitArray and the on-disk version.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/sysimg/#System-Image-Building","page":"System Image Building","title":"System Image Building","text":"","category":"section"},{"location":"devdocs/sysimg/#Building-the-Julia-system-image","page":"System Image Building","title":"Building the Julia system image","text":"","category":"section"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"Julia ships with a preparsed system image containing the contents of the Base module, named sys.ji. This file is also precompiled into a shared library called sys.{so,dll,dylib} on as many platforms as possible, so as to give vastly improved startup times. On systems that do not ship with a precompiled system image file, one can be generated from the source files shipped in Julia's DATAROOTDIR/julia/base folder.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"Julia will by default generate its system image on half of the available system threads. This may be controlled by the JULIA_IMAGE_THREADS environment variable.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"This operation is useful for multiple reasons. A user may:","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"Build a precompiled shared library system image on a platform that did not ship with one, thereby improving startup times.\nModify Base, rebuild the system image and use the new Base next time Julia is started.\nInclude a userimg.jl file that includes packages into the system image, thereby creating a system image that has packages embedded into the startup environment.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"The PackageCompiler.jl package contains convenient wrapper functions to automate this process.","category":"page"},{"location":"devdocs/sysimg/#sysimg-multi-versioning","page":"System Image Building","title":"System image optimized for multiple microarchitectures","text":"","category":"section"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"The system image can be compiled simultaneously for multiple CPU microarchitectures under the same instruction set architecture (ISA). Multiple versions of the same function may be created with minimum dispatch point inserted into shared functions in order to take advantage of different ISA extensions or other microarchitecture features. The version that offers the best performance will be selected automatically at runtime based on available CPU features.","category":"page"},{"location":"devdocs/sysimg/#Specifying-multiple-system-image-targets","page":"System Image Building","title":"Specifying multiple system image targets","text":"","category":"section"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"A multi-microarchitecture system image can be enabled by passing multiple targets during system image compilation. This can be done either with the JULIA_CPU_TARGET make option or with the -C command line option when running the compilation command manually. Multiple targets are separated by ; in the option string. The syntax for each target is a CPU name followed by multiple features separated by ,. All features supported by LLVM are supported and a feature can be disabled with a - prefix. (+ prefix is also allowed and ignored to be consistent with LLVM syntax). Additionally, a few special features are supported to control the function cloning behavior.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"note: Note\nIt is good practice to specify either clone_all or base() for every target apart from the first one. This makes it explicit which targets have all functions cloned, and which targets are based on other targets. If this is not done, the default behavior is to not clone every function, and to use the first target's function definition as the fallback when not cloning a function.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"clone_all\nBy default, only functions that are the most likely to benefit from the microarchitecture features will be cloned. When clone_all is specified for a target, however, all functions in the system image will be cloned for the target. The negative form -clone_all can be used to prevent the built-in heuristic from cloning all functions.\nbase()\nWhere is a placeholder for a non-negative number (e.g. base(0), base(1)). By default, a partially cloned (i.e. not clone_all) target will use functions from the default target (first one specified) if a function is not cloned. This behavior can be changed by specifying a different base with the base() option. The nth target (0-based) will be used as the base target instead of the default (0th) one. The base target has to be either 0 or another clone_all target. Specifying a non-clone_all target as the base target will cause an error.\nopt_size\nThis causes the function for the target to be optimized for size when there isn't a significant runtime performance impact. This corresponds to -Os GCC and Clang option.\nmin_size\nThis causes the function for the target to be optimized for size that might have a significant runtime performance impact. This corresponds to -Oz Clang option.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"As an example, at the time of this writing, the following string is used in the creation of the official x86_64 Julia binaries downloadable from julialang.org:","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"This creates a system image with three separate targets; one for a generic x86_64 processor, one with a sandybridge ISA (explicitly excluding xsaveopt) that explicitly clones all functions, and one targeting the haswell ISA, based off of the sandybridge sysimg version, and also excluding rdrnd. When a Julia implementation loads the generated sysimg, it will check the host processor for matching CPU capability flags, enabling the highest ISA level possible. Note that the base level (generic) requires the cx16 instruction, which is disabled in some virtualization software and must be enabled for the generic target to be loaded. Alternatively, a sysimg could be generated with the target generic,-cx16 for greater compatibility, however note that this may cause performance and stability problems in some code.","category":"page"},{"location":"devdocs/sysimg/#Implementation-overview","page":"System Image Building","title":"Implementation overview","text":"","category":"section"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"This is a brief overview of different part involved in the implementation. See code comments for each components for more implementation details.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"System image compilation\nThe parsing and cloning decision are done in src/processor*. We currently support cloning of function based on the present of loops, simd instructions, or other math operations (e.g. fastmath, fma, muladd). This information is passed on to src/llvm-multiversioning.cpp which does the actual cloning. In addition to doing the cloning and insert dispatch slots (see comments in MultiVersioning::runOnModule for how this is done), the pass also generates metadata so that the runtime can load and initialize the system image correctly. A detailed description of the metadata is available in src/processor.h.\nSystem image loading\nThe loading and initialization of the system image is done in src/processor* by parsing the metadata saved during system image generation. Host feature detection and selection decision are done in src/processor_*.cpp depending on the ISA. The target selection will prefer exact CPU name match, larger vector register size, and larger number of features. An overview of this process is in src/processor.cpp.","category":"page"},{"location":"devdocs/functions/#Julia-Functions","page":"Julia Functions","title":"Julia Functions","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This document will explain how functions, method definitions, and method tables work.","category":"page"},{"location":"devdocs/functions/#Method-Tables","page":"Julia Functions","title":"Method Tables","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Every function in Julia is a generic function. A generic function is conceptually a single function, but consists of many definitions, or methods. The methods of a generic function are stored in a method table. Method tables (type MethodTable) are associated with TypeNames. A TypeName describes a family of parameterized types. For example Complex{Float32} and Complex{Float64} share the same Complex type name object.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"All objects in Julia are potentially callable, because every object has a type, which in turn has a TypeName.","category":"page"},{"location":"devdocs/functions/#Function-calls","page":"Julia Functions","title":"Function calls","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Given the call f(x, y), the following steps are performed: first, the method table to use is accessed as typeof(f).name.mt. Second, an argument tuple type is formed, Tuple{typeof(f), typeof(x), typeof(y)}. Note that the type of the function itself is the first element. This is because the type might have parameters, and so needs to take part in dispatch. This tuple type is looked up in the method table.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This dispatch process is performed by jl_apply_generic, which takes two arguments: a pointer to an array of the values f, x, and y, and the number of values (in this case 3).","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Throughout the system, there are two kinds of APIs that handle functions and argument lists: those that accept the function and arguments separately, and those that accept a single argument structure. In the first kind of API, the \"arguments\" part does not contain information about the function, since that is passed separately. In the second kind of API, the function is the first element of the argument structure.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"For example, the following function for performing a call accepts just an args pointer, so the first element of the args array will be the function to call:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"jl_value_t *jl_apply(jl_value_t **args, uint32_t nargs)","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This entry point for the same functionality accepts the function separately, so the args array does not contain the function:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs);","category":"page"},{"location":"devdocs/functions/#Adding-methods","page":"Julia Functions","title":"Adding methods","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Given the above dispatch process, conceptually all that is needed to add a new method is (1) a tuple type, and (2) code for the body of the method. jl_method_def implements this operation. jl_method_table_for is called to extract the relevant method table from what would be the type of the first argument. This is much more complicated than the corresponding procedure during dispatch, since the argument tuple type might be abstract. For example, we can define:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"(::Union{Foo{Int},Foo{Int8}})(x) = 0","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"which works since all possible matching methods would belong to the same method table.","category":"page"},{"location":"devdocs/functions/#Creating-generic-functions","page":"Julia Functions","title":"Creating generic functions","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Since every object is callable, nothing special is needed to create a generic function. Therefore jl_new_generic_function simply creates a new singleton (0 size) subtype of Function and returns its instance. A function can have a mnemonic \"display name\" which is used in debug info and when printing objects. For example the name of Base.sin is sin. By convention, the name of the created type is the same as the function name, with a # prepended. So typeof(sin) is Base.#sin.","category":"page"},{"location":"devdocs/functions/#Closures","page":"Julia Functions","title":"Closures","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"A closure is simply a callable object with field names corresponding to captured variables. For example, the following code:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function adder(x)\n return y->x+y\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"is lowered to (roughly):","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"struct ##1{T}\n x::T\nend\n\n(_::##1)(y) = _.x + y\n\nfunction adder(x)\n return ##1(x)\nend","category":"page"},{"location":"devdocs/functions/#Constructors","page":"Julia Functions","title":"Constructors","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"A constructor call is just a call to a type. The method table for Type contains all constructor definitions. All subtypes of Type (Type, UnionAll, Union, and DataType) currently share a method table via special arrangement.","category":"page"},{"location":"devdocs/functions/#Builtins","page":"Julia Functions","title":"Builtins","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The \"builtin\" functions, defined in the Core module, are:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function lines(words)\n io = IOBuffer()\n n = 0\n for w in words\n if n+length(w) > 80\n print(io, '\\n', w)\n n = length(w)\n elseif n == 0\n print(io, w);\n n += length(w)\n else\n print(io, ' ', w);\n n += length(w)+1\n end\n end\n String(take!(io))\nend\nimport Markdown\n[string(n) for n in names(Core;all=true)\n if getfield(Core,n) isa Core.Builtin && nameof(getfield(Core,n)) === n] |>\n lines |>\n s -> \"```\\n$s\\n```\" |>\n Markdown.parse","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"These are all singleton objects whose types are subtypes of Builtin, which is a subtype of Function. Their purpose is to expose entry points in the run time that use the \"jlcall\" calling convention:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"jl_value_t *(jl_value_t*, jl_value_t**, uint32_t)","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The method tables of builtins are empty. Instead, they have a single catch-all method cache entry (Tuple{Vararg{Any}}) whose jlcall fptr points to the correct function. This is kind of a hack but works reasonably well.","category":"page"},{"location":"devdocs/functions/#Keyword-arguments","page":"Julia Functions","title":"Keyword arguments","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Keyword arguments work by adding methods to the kwcall function. This function is usually the \"keyword argument sorter\" or \"keyword sorter\", which then calls the inner body of the function (defined anonymously). Every definition in the kwsorter function has the same arguments as some definition in the normal method table, except with a single NamedTuple argument prepended, which gives the names and values of passed keyword arguments. The kwsorter's job is to move keyword arguments into their canonical positions based on name, plus evaluate and substitute any needed default value expressions. The result is a normal positional argument list, which is then passed to yet another compiler-generated function.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The easiest way to understand the process is to look at how a keyword argument method definition is lowered. The code:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function circle(center, radius; color = black, fill::Bool = true, options...)\n # draw\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"actually produces three method definitions. The first is a function that accepts all arguments (including keyword arguments) as positional arguments, and includes the code for the method body. It has an auto-generated name:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function #circle#1(color, fill::Bool, options, circle, center, radius)\n # draw\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The second method is an ordinary definition for the original circle function, which handles the case where no keyword arguments are passed:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function circle(center, radius)\n #circle#1(black, true, pairs(NamedTuple()), circle, center, radius)\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This simply dispatches to the first method, passing along default values. pairs is applied to the named tuple of rest arguments to provide key-value pair iteration. Note that if the method doesn't accept rest keyword arguments then this argument is absent.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Finally there is the kwsorter definition:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function (::Core.kwftype(typeof(circle)))(kws, circle, center, radius)\n if haskey(kws, :color)\n color = kws.color\n else\n color = black\n end\n # etc.\n\n # put remaining kwargs in `options`\n options = structdiff(kws, NamedTuple{(:color, :fill)})\n\n # if the method doesn't accept rest keywords, throw an error\n # unless `options` is empty\n\n #circle#1(color, fill, pairs(options), circle, center, radius)\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The function Core.kwftype(t) creates the field t.name.mt.kwsorter (if it hasn't been created yet), and returns the type of that function.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This design has the feature that call sites that don't use keyword arguments require no special handling; everything works as if they were not part of the language at all. Call sites that do use keyword arguments are dispatched directly to the called function's kwsorter. For example the call:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"circle((0, 0), 1.0, color = red; other...)","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"is lowered to:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"kwcall(merge((color = red,), other), circle, (0, 0), 1.0)","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"kwcall (also inCore) denotes a kwcall signature and dispatch. The keyword splatting operation (written as other...) calls the named tuple merge function. This function further unpacks each element of other, expecting each one to contain two values (a symbol and a value). Naturally, a more efficient implementation is available if all splatted arguments are named tuples. Notice that the original circle function is passed through, to handle closures.","category":"page"},{"location":"devdocs/functions/#compiler-efficiency-issues","page":"Julia Functions","title":"Compiler efficiency issues","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Generating a new type for every function has potentially serious consequences for compiler resource use when combined with Julia's \"specialize on all arguments by default\" design. Indeed, the initial implementation of this design suffered from much longer build and test times, higher memory use, and a system image nearly 2x larger than the baseline. In a naive implementation, the problem is bad enough to make the system nearly unusable. Several significant optimizations were needed to make the design practical.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The first issue is excessive specialization of functions for different values of function-valued arguments. Many functions simply \"pass through\" an argument to somewhere else, e.g. to another function or to a storage location. Such functions do not need to be specialized for every closure that might be passed in. Fortunately this case is easy to distinguish by simply considering whether a function calls one of its arguments (i.e. the argument appears in \"head position\" somewhere). Performance-critical higher-order functions like map certainly call their argument function and so will still be specialized as expected. This optimization is implemented by recording which arguments are called during the analyze-variables pass in the front end. When cache_method sees an argument in the Function type hierarchy passed to a slot declared as Any or Function, it behaves as if the @nospecialize annotation were applied. This heuristic seems to be extremely effective in practice.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The next issue concerns the structure of method cache hash tables. Empirical studies show that the vast majority of dynamically-dispatched calls involve one or two arguments. In turn, many of these cases can be resolved by considering only the first argument. (Aside: proponents of single dispatch would not be surprised by this at all. However, this argument means \"multiple dispatch is easy to optimize in practice\", and that we should therefore use it, not \"we should use single dispatch\"!) So the method cache uses the type of the first argument as its primary key. Note, however, that this corresponds to the second element of the tuple type for a function call (the first element being the type of the function itself). Typically, type variation in head position is extremely low – indeed, the majority of functions belong to singleton types with no parameters. However, this is not the case for constructors, where a single method table holds constructors for every type. Therefore the Type method table is special-cased to use the first tuple type element instead of the second.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The front end generates type declarations for all closures. Initially, this was implemented by generating normal type declarations. However, this produced an extremely large number of constructors, all of which were trivial (simply passing all arguments through to new). Since methods are partially ordered, inserting all of these methods is O(n²), plus there are just too many of them to keep around. This was optimized by generating struct_type expressions directly (bypassing default constructor generation), and using new directly to create closure instances. Not the prettiest thing ever, but you do what you gotta do.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The next problem was the @test macro, which generated a 0-argument closure for each test case. This is not really necessary, since each test case is simply run once in place. Therefore, @test was modified to expand to a try-catch block that records the test result (true, false, or exception raised) and calls the test suite handler on it.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Profile/docs/src/index.md\"","category":"page"},{"location":"stdlib/Profile/#lib-profiling","page":"Profiling","title":"Profiling","text":"","category":"section"},{"location":"stdlib/Profile/#CPU-Profiling","page":"Profiling","title":"CPU Profiling","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"There are two main approaches to CPU profiling julia code:","category":"page"},{"location":"stdlib/Profile/#Via-@profile","page":"Profiling","title":"Via @profile","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Where profiling is enabled for a given call via the @profile macro.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> @profile foo()\n\njulia> Profile.print()\nOverhead ╎ [+additional indent] Count File:Line; Function\n=========================================================\n ╎147 @Base/client.jl:506; _start()\n ╎ 147 @Base/client.jl:318; exec_options(opts::Base.JLOptions)\n...","category":"page"},{"location":"stdlib/Profile/#Triggered-During-Execution","page":"Profiling","title":"Triggered During Execution","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Tasks that are already running can also be profiled for a fixed time period at any user-triggered time.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"To trigger the profiling:","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"MacOS & FreeBSD (BSD-based platforms): Use ctrl-t or pass a SIGINFO signal to the julia process i.e. % kill -INFO $julia_pid\nLinux: Pass a SIGUSR1 signal to the julia process i.e. % kill -USR1 $julia_pid\nWindows: Not currently supported.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"First, a single stack trace at the instant that the signal was thrown is shown, then a 1 second profile is collected, followed by the profile report at the next yield point, which may be at task completion for code without yield points e.g. tight loops.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Optionally set environment variable JULIA_PROFILE_PEEK_HEAP_SNAPSHOT to 1 to also automatically collect a heap snapshot.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> foo()\n##== the user sends a trigger while foo is running ==##\nload: 2.53 cmd: julia 88903 running 6.16u 0.97s\n\n======================================================================================\nInformation request received. A stacktrace will print followed by a 1.0 second profile\n======================================================================================\n\nsignal (29): Information request: 29\n__psynch_cvwait at /usr/lib/system/libsystem_kernel.dylib (unknown line)\n_pthread_cond_wait at /usr/lib/system/libsystem_pthread.dylib (unknown line)\n...\n\n======================================================================\nProfile collected. A report will print if the Profile module is loaded\n======================================================================\n\nOverhead ╎ [+additional indent] Count File:Line; Function\n=========================================================\nThread 1 Task 0x000000011687c010 Total snapshots: 572. Utilization: 100%\n ╎147 @Base/client.jl:506; _start()\n ╎ 147 @Base/client.jl:318; exec_options(opts::Base.JLOptions)\n...\n\nThread 2 Task 0x0000000116960010 Total snapshots: 572. Utilization: 0%\n ╎572 @Base/task.jl:587; task_done_hook(t::Task)\n ╎ 572 @Base/task.jl:879; wait()\n...","category":"page"},{"location":"stdlib/Profile/#Customization","page":"Profiling","title":"Customization","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The duration of the profiling can be adjusted via Profile.set_peek_duration","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The profile report is broken down by thread and task. Pass a no-arg function to Profile.peek_report[] to override this. i.e. Profile.peek_report[] = () -> Profile.print() to remove any grouping. This could also be overridden by an external profile data consumer.","category":"page"},{"location":"stdlib/Profile/#Reference","page":"Profiling","title":"Reference","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.@profile","category":"page"},{"location":"stdlib/Profile/#Profile.@profile","page":"Profiling","title":"Profile.@profile","text":"@profile\n\n@profile runs your expression while taking periodic backtraces. These are appended to an internal buffer of backtraces.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The methods in Profile are not exported and need to be called e.g. as Profile.print().","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.clear\nProfile.print\nProfile.init\nProfile.fetch\nProfile.retrieve\nProfile.callers\nProfile.clear_malloc_data\nProfile.get_peek_duration\nProfile.set_peek_duration","category":"page"},{"location":"stdlib/Profile/#Profile.clear","page":"Profiling","title":"Profile.clear","text":"clear()\n\nClear any existing backtraces from the internal buffer.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.print","page":"Profiling","title":"Profile.print","text":"print([io::IO = stdout,] [data::Vector = fetch()], [lidict::Union{LineInfoDict, LineInfoFlatDict} = getdict(data)]; kwargs...)\n\nPrints profiling results to io (by default, stdout). If you do not supply a data vector, the internal buffer of accumulated backtraces will be used.\n\nThe keyword arguments can be any combination of:\n\nformat – Determines whether backtraces are printed with (default, :tree) or without (:flat) indentation indicating tree structure.\nC – If true, backtraces from C and Fortran code are shown (normally they are excluded).\ncombine – If true (default), instruction pointers are merged that correspond to the same line of code.\nmaxdepth – Limits the depth higher than maxdepth in the :tree format.\nsortedby – Controls the order in :flat format. :filefuncline (default) sorts by the source line, :count sorts in order of number of collected samples, and :overhead sorts by the number of samples incurred by each function by itself.\ngroupby – Controls grouping over tasks and threads, or no grouping. Options are :none (default), :thread, :task, [:thread, :task], or [:task, :thread] where the last two provide nested grouping.\nnoisefloor – Limits frames that exceed the heuristic noise floor of the sample (only applies to format :tree). A suggested value to try for this is 2.0 (the default is 0). This parameter hides samples for which n <= noisefloor * √N, where n is the number of samples on this line, and N is the number of samples for the callee.\nmincount – Limits the printout to only those lines with at least mincount occurrences.\nrecur – Controls the recursion handling in :tree format. :off (default) prints the tree as normal. :flat instead compresses any recursion (by ip), showing the approximate effect of converting any self-recursion into an iterator. :flatc does the same but also includes collapsing of C frames (may do odd things around jl_apply).\nthreads::Union{Int,AbstractVector{Int}} – Specify which threads to include snapshots from in the report. Note that this does not control which threads samples are collected on (which may also have been collected on another machine).\ntasks::Union{Int,AbstractVector{Int}} – Specify which tasks to include snapshots from in the report. Note that this does not control which tasks samples are collected within.\n\ncompat: Julia 1.8\nThe groupby, threads, and tasks keyword arguments were introduced in Julia 1.8.\n\nnote: Note\nProfiling on windows is limited to the main thread. Other threads have not been sampled and will not show in the report.\n\n\n\n\n\nprint([io::IO = stdout,] data::Vector, lidict::LineInfoDict; kwargs...)\n\nPrints profiling results to io. This variant is used to examine results exported by a previous call to retrieve. Supply the vector data of backtraces and a dictionary lidict of line information.\n\nSee Profile.print([io], data) for an explanation of the valid keyword arguments.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.init","page":"Profiling","title":"Profile.init","text":"init(; n::Integer, delay::Real)\n\nConfigure the delay between backtraces (measured in seconds), and the number n of instruction pointers that may be stored per thread. Each instruction pointer corresponds to a single line of code; backtraces generally consist of a long list of instruction pointers. Note that 6 spaces for instruction pointers per backtrace are used to store metadata and two NULL end markers. Current settings can be obtained by calling this function with no arguments, and each can be set independently using keywords or in the order (n, delay).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.fetch","page":"Profiling","title":"Profile.fetch","text":"fetch(;include_meta = true) -> data\n\nReturn a copy of the buffer of profile backtraces. Note that the values in data have meaning only on this machine in the current session, because it depends on the exact memory addresses used in JIT-compiling. This function is primarily for internal use; retrieve may be a better choice for most users. By default metadata such as threadid and taskid is included. Set include_meta to false to strip metadata.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.retrieve","page":"Profiling","title":"Profile.retrieve","text":"retrieve(; kwargs...) -> data, lidict\n\n\"Exports\" profiling results in a portable format, returning the set of all backtraces (data) and a dictionary that maps the (session-specific) instruction pointers in data to LineInfo values that store the file name, function name, and line number. This function allows you to save profiling results for future analysis.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.callers","page":"Profiling","title":"Profile.callers","text":"callers(funcname, [data, lidict], [filename=], [linerange=]) -> Vector{Tuple{count, lineinfo}}\n\nGiven a previous profiling run, determine who called a particular function. Supplying the filename (and optionally, range of line numbers over which the function is defined) allows you to disambiguate an overloaded method. The returned value is a vector containing a count of the number of calls and line information about the caller. One can optionally supply backtrace data obtained from retrieve; otherwise, the current internal profile buffer is used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.clear_malloc_data","page":"Profiling","title":"Profile.clear_malloc_data","text":"clear_malloc_data()\n\nClears any stored memory allocation data when running julia with --track-allocation. Execute the command(s) you want to test (to force JIT-compilation), then call clear_malloc_data. Then execute your command(s) again, quit Julia, and examine the resulting *.mem files.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.get_peek_duration","page":"Profiling","title":"Profile.get_peek_duration","text":"get_peek_duration()\n\nGet the duration in seconds of the profile \"peek\" that is triggered via SIGINFO or SIGUSR1, depending on platform.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.set_peek_duration","page":"Profiling","title":"Profile.set_peek_duration","text":"set_peek_duration(t::Float64)\n\nSet the duration in seconds of the profile \"peek\" that is triggered via SIGINFO or SIGUSR1, depending on platform.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Memory-profiling","page":"Profiling","title":"Memory profiling","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.Allocs.@profile","category":"page"},{"location":"stdlib/Profile/#Profile.Allocs.@profile","page":"Profiling","title":"Profile.Allocs.@profile","text":"Profile.Allocs.@profile [sample_rate=0.1] expr\n\nProfile allocations that happen during expr, returning both the result and AllocResults struct.\n\nA sample rate of 1.0 will record everything; 0.0 will record nothing.\n\njulia> Profile.Allocs.@profile sample_rate=0.01 peakflops()\n1.03733270279065e11\n\njulia> results = Profile.Allocs.fetch()\n\njulia> last(sort(results.allocs, by=x->x.size))\nProfile.Allocs.Alloc(Vector{Any}, Base.StackTraces.StackFrame[_new_array_ at array.c:127, ...], 5576)\n\nThe best way to visualize these is currently with the PProf.jl package, by invoking PProf.Allocs.pprof.\n\nnote: Note\nThe current implementation of the Allocations Profiler does not capture types for all allocations. Allocations for which the profiler could not capture the type are represented as having type Profile.Allocs.UnknownType.You can read more about the missing types and the plan to improve this, here: https://github.com/JuliaLang/julia/issues/43688.\n\ncompat: Julia 1.8\nThe allocation profiler was added in Julia 1.8.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The methods in Profile.Allocs are not exported and need to be called e.g. as Profile.Allocs.fetch().","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.Allocs.clear\nProfile.Allocs.print\nProfile.Allocs.fetch\nProfile.Allocs.start\nProfile.Allocs.stop","category":"page"},{"location":"stdlib/Profile/#Profile.Allocs.clear","page":"Profiling","title":"Profile.Allocs.clear","text":"Profile.Allocs.clear()\n\nClear all previously profiled allocation information from memory.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.Allocs.print","page":"Profiling","title":"Profile.Allocs.print","text":"Profile.Allocs.print([io::IO = stdout,] [data::AllocResults = fetch()]; kwargs...)\n\nPrints profiling results to io (by default, stdout). If you do not supply a data vector, the internal buffer of accumulated backtraces will be used.\n\nSee Profile.print for an explanation of the valid keyword arguments.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.Allocs.fetch","page":"Profiling","title":"Profile.Allocs.fetch","text":"Profile.Allocs.fetch()\n\nRetrieve the recorded allocations, and decode them into Julia objects which can be analyzed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.Allocs.start","page":"Profiling","title":"Profile.Allocs.start","text":"Profile.Allocs.start(sample_rate::Real)\n\nBegin recording allocations with the given sample rate A sample rate of 1.0 will record everything; 0.0 will record nothing.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.Allocs.stop","page":"Profiling","title":"Profile.Allocs.stop","text":"Profile.Allocs.stop()\n\nStop recording allocations.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Heap-Snapshots","page":"Profiling","title":"Heap Snapshots","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.take_heap_snapshot","category":"page"},{"location":"stdlib/Profile/#Profile.take_heap_snapshot","page":"Profiling","title":"Profile.take_heap_snapshot","text":"Profile.take_heap_snapshot(filepath::String, all_one::Bool=false, streaming=false)\nProfile.take_heap_snapshot(all_one::Bool=false; dir::String, streaming=false)\n\nWrite a snapshot of the heap, in the JSON format expected by the Chrome Devtools Heap Snapshot viewer (.heapsnapshot extension) to a file ($pid_$timestamp.heapsnapshot) in the current directory by default (or tempdir if the current directory is unwritable), or in dir if given, or the given full file path, or IO stream.\n\nIf all_one is true, then report the size of every object as one so they can be easily counted. Otherwise, report the actual size.\n\nIf streaming is true, we will stream the snapshot data out into four files, using filepath as the prefix, to avoid having to hold the entire snapshot in memory. This option should be used for any setting where your memory is constrained. These files can then be reassembled by calling Profile.HeapSnapshot.assemble_snapshot(), which can be done offline.\n\nNOTE: We strongly recommend setting streaming=true for performance reasons. Reconstructing the snapshot from the parts requires holding the entire snapshot in memory, so if the snapshot is large, you can run out of memory while processing it. Streaming allows you to reconstruct the snapshot offline, after your workload is done running. If you do attempt to collect a snapshot with streaming=false (the default, for backwards-compatibility) and your process is killed, note that this will always save the parts in the same directory as your provided filepath, so you can still reconstruct the snapshot after the fact, via assemble_snapshot().\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The methods in Profile are not exported and need to be called e.g. as Profile.take_heap_snapshot().","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> Profile.take_heap_snapshot(\"snapshot.heapsnapshot\")","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Traces and records julia objects on the heap. This only records objects known to the Julia garbage collector. Memory allocated by external libraries not managed by the garbage collector will not show up in the snapshot.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"To avoid OOMing while recording the snapshot, we added a streaming option to stream out the heap snapshot into four files,","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> Profile.take_heap_snapshot(\"snapshot\"; streaming=true)","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"where \"snapshot\" is the filepath as the prefix for the generated files.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Once the snapshot files are generated, they could be assembled offline with the following command:","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> Profile.HeapSnapshot.assemble_snapshot(\"snapshot\", \"snapshot.heapsnapshot\")","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The resulting heap snapshot file can be uploaded to chrome devtools to be viewed. For more information, see the chrome devtools docs.","category":"page"},{"location":"stdlib/UUIDs/","page":"UUIDs","title":"UUIDs","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/UUIDs/docs/src/index.md\"","category":"page"},{"location":"stdlib/UUIDs/#UUIDs","page":"UUIDs","title":"UUIDs","text":"","category":"section"},{"location":"stdlib/UUIDs/","page":"UUIDs","title":"UUIDs","text":"UUIDs.uuid1\nUUIDs.uuid4\nUUIDs.uuid5\nUUIDs.uuid_version","category":"page"},{"location":"stdlib/UUIDs/#UUIDs.uuid1","page":"UUIDs","title":"UUIDs.uuid1","text":"uuid1([rng::AbstractRNG]) -> UUID\n\nGenerates a version 1 (time-based) universally unique identifier (UUID), as specified by RFC 4122. Note that the Node ID is randomly generated (does not identify the host) according to section 4.5 of the RFC.\n\nThe default rng used by uuid1 is not Random.default_rng() and every invocation of uuid1() without an argument should be expected to return a unique identifier. Importantly, the outputs of uuid1 do not repeat even when Random.seed!(seed) is called. Currently (as of Julia 1.6), uuid1 uses Random.RandomDevice as the default rng. However, this is an implementation detail that may change in the future.\n\ncompat: Julia 1.6\nThe output of uuid1 does not depend on Random.default_rng() as of Julia 1.6.\n\nExamples\n\njulia> using Random\n\njulia> rng = MersenneTwister(1234);\n\njulia> uuid1(rng)\nUUID(\"cfc395e8-590f-11e8-1f13-43a2532b2fa8\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/UUIDs/#UUIDs.uuid4","page":"UUIDs","title":"UUIDs.uuid4","text":"uuid4([rng::AbstractRNG]) -> UUID\n\nGenerates a version 4 (random or pseudo-random) universally unique identifier (UUID), as specified by RFC 4122.\n\nThe default rng used by uuid4 is not Random.default_rng() and every invocation of uuid4() without an argument should be expected to return a unique identifier. Importantly, the outputs of uuid4 do not repeat even when Random.seed!(seed) is called. Currently (as of Julia 1.6), uuid4 uses Random.RandomDevice as the default rng. However, this is an implementation detail that may change in the future.\n\ncompat: Julia 1.6\nThe output of uuid4 does not depend on Random.default_rng() as of Julia 1.6.\n\nExamples\n\njulia> using Random\n\njulia> rng = Xoshiro(123);\n\njulia> uuid4(rng)\nUUID(\"856e446e-0c6a-472a-9638-f7b8557cd282\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/UUIDs/#UUIDs.uuid5","page":"UUIDs","title":"UUIDs.uuid5","text":"uuid5(ns::UUID, name::String) -> UUID\n\nGenerates a version 5 (namespace and domain-based) universally unique identifier (UUID), as specified by RFC 4122.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nExamples\n\njulia> using Random\n\njulia> rng = Xoshiro(123);\n\njulia> u4 = uuid4(rng)\nUUID(\"856e446e-0c6a-472a-9638-f7b8557cd282\")\n\njulia> u5 = uuid5(u4, \"julia\")\nUUID(\"2df91e3f-da06-5362-a6fe-03772f2e14c9\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/UUIDs/#UUIDs.uuid_version","page":"UUIDs","title":"UUIDs.uuid_version","text":"uuid_version(u::UUID) -> Int\n\nInspects the given UUID and returns its version (see RFC 4122).\n\nExamples\n\njulia> uuid_version(uuid4())\n4\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Iteration-utilities","page":"Iteration utilities","title":"Iteration utilities","text":"","category":"section"},{"location":"base/iterators/","page":"Iteration utilities","title":"Iteration utilities","text":"Base.Iterators.Stateful\nBase.Iterators.zip\nBase.Iterators.enumerate\nBase.Iterators.rest\nBase.Iterators.countfrom\nBase.Iterators.take\nBase.Iterators.takewhile\nBase.Iterators.drop\nBase.Iterators.dropwhile\nBase.Iterators.cycle\nBase.Iterators.repeated\nBase.Iterators.product\nBase.Iterators.flatten\nBase.Iterators.flatmap\nBase.Iterators.partition\nBase.Iterators.map\nBase.Iterators.filter\nBase.Iterators.accumulate\nBase.Iterators.reverse\nBase.Iterators.only\nBase.Iterators.peel","category":"page"},{"location":"base/iterators/#Base.Iterators.Stateful","page":"Iteration utilities","title":"Base.Iterators.Stateful","text":"Stateful(itr)\n\nThere are several different ways to think about this iterator wrapper:\n\nIt provides a mutable wrapper around an iterator and its iteration state.\nIt turns an iterator-like abstraction into a Channel-like abstraction.\nIt's an iterator that mutates to become its own rest iterator whenever an item is produced.\n\nStateful provides the regular iterator interface. Like other mutable iterators (e.g. Base.Channel), if iteration is stopped early (e.g. by a break in a for loop), iteration can be resumed from the same spot by continuing to iterate over the same iterator object (in contrast, an immutable iterator would restart from the beginning).\n\nExamples\n\njulia> a = Iterators.Stateful(\"abcdef\");\n\njulia> isempty(a)\nfalse\n\njulia> popfirst!(a)\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> collect(Iterators.take(a, 3))\n3-element Vector{Char}:\n 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)\n 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)\n 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)\n\njulia> collect(a)\n2-element Vector{Char}:\n 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)\n 'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)\n\njulia> Iterators.reset!(a); popfirst!(a)\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> Iterators.reset!(a, \"hello\"); popfirst!(a)\n'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)\n\njulia> a = Iterators.Stateful([1,1,1,2,3,4]);\n\njulia> for x in a; x == 1 || break; end\n\njulia> peek(a)\n3\n\njulia> sum(a) # Sum the remaining elements\n7\n\n\n\n\n\n","category":"type"},{"location":"base/iterators/#Base.Iterators.zip","page":"Iteration utilities","title":"Base.Iterators.zip","text":"zip(iters...)\n\nRun multiple iterators at the same time, until any of them is exhausted. The value type of the zip iterator is a tuple of values of its subiterators.\n\nnote: Note\nzip orders the calls to its subiterators in such a way that stateful iterators will not advance when another iterator finishes in the current iteration.\n\nnote: Note\nzip() with no arguments yields an infinite iterator of empty tuples.\n\nSee also: enumerate, Base.splat.\n\nExamples\n\njulia> a = 1:5\n1:5\n\njulia> b = [\"e\",\"d\",\"b\",\"c\",\"a\"]\n5-element Vector{String}:\n \"e\"\n \"d\"\n \"b\"\n \"c\"\n \"a\"\n\njulia> c = zip(a,b)\nzip(1:5, [\"e\", \"d\", \"b\", \"c\", \"a\"])\n\njulia> length(c)\n5\n\njulia> first(c)\n(1, \"e\")\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.enumerate","page":"Iteration utilities","title":"Base.Iterators.enumerate","text":"enumerate(iter)\n\nAn iterator that yields (i, x) where i is a counter starting at 1, and x is the ith value from the given iterator. It's useful when you need not only the values x over which you are iterating, but also the number of iterations so far.\n\nNote that i may not be valid for indexing iter, or may index a different element. This will happen if iter has indices that do not start at 1, and may happen for strings, dictionaries, etc. See the pairs(IndexLinear(), iter) method if you want to ensure that i is an index.\n\nExamples\n\njulia> a = [\"a\", \"b\", \"c\"];\n\njulia> for (index, value) in enumerate(a)\n println(\"$index $value\")\n end\n1 a\n2 b\n3 c\n\njulia> str = \"naïve\";\n\njulia> for (i, val) in enumerate(str)\n print(\"i = \", i, \", val = \", val, \", \")\n try @show(str[i]) catch e println(e) end\n end\ni = 1, val = n, str[i] = 'n'\ni = 2, val = a, str[i] = 'a'\ni = 3, val = ï, str[i] = 'ï'\ni = 4, val = v, StringIndexError(\"naïve\", 4)\ni = 5, val = e, str[i] = 'v'\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.rest","page":"Iteration utilities","title":"Base.Iterators.rest","text":"rest(iter, state)\n\nAn iterator that yields the same elements as iter, but starting at the given state.\n\nSee also: Iterators.drop, Iterators.peel, Base.rest.\n\nExamples\n\njulia> collect(Iterators.rest([1,2,3,4], 2))\n3-element Vector{Int64}:\n 2\n 3\n 4\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.countfrom","page":"Iteration utilities","title":"Base.Iterators.countfrom","text":"countfrom(start=1, step=1)\n\nAn iterator that counts forever, starting at start and incrementing by step.\n\nExamples\n\njulia> for v in Iterators.countfrom(5, 2)\n v > 10 && break\n println(v)\n end\n5\n7\n9\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.take","page":"Iteration utilities","title":"Base.Iterators.take","text":"take(iter, n)\n\nAn iterator that generates at most the first n elements of iter.\n\nSee also: drop, peel, first, Base.take!.\n\nExamples\n\njulia> a = 1:2:11\n1:2:11\n\njulia> collect(a)\n6-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n 11\n\njulia> collect(Iterators.take(a,3))\n3-element Vector{Int64}:\n 1\n 3\n 5\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.takewhile","page":"Iteration utilities","title":"Base.Iterators.takewhile","text":"takewhile(pred, iter)\n\nAn iterator that generates element from iter as long as predicate pred is true, afterwards, drops every element.\n\ncompat: Julia 1.4\nThis function requires at least Julia 1.4.\n\nExamples\n\njulia> s = collect(1:5)\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n\njulia> collect(Iterators.takewhile(<(3),s))\n2-element Vector{Int64}:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.drop","page":"Iteration utilities","title":"Base.Iterators.drop","text":"drop(iter, n)\n\nAn iterator that generates all but the first n elements of iter.\n\nExamples\n\njulia> a = 1:2:11\n1:2:11\n\njulia> collect(a)\n6-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n 11\n\njulia> collect(Iterators.drop(a,4))\n2-element Vector{Int64}:\n 9\n 11\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.dropwhile","page":"Iteration utilities","title":"Base.Iterators.dropwhile","text":"dropwhile(pred, iter)\n\nAn iterator that drops element from iter as long as predicate pred is true, afterwards, returns every element.\n\ncompat: Julia 1.4\nThis function requires at least Julia 1.4.\n\nExamples\n\njulia> s = collect(1:5)\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n\njulia> collect(Iterators.dropwhile(<(3),s))\n3-element Vector{Int64}:\n 3\n 4\n 5\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.cycle","page":"Iteration utilities","title":"Base.Iterators.cycle","text":"cycle(iter[, n::Int])\n\nAn iterator that cycles through iter forever. If n is specified, then it cycles through iter that many times. When iter is empty, so are cycle(iter) and cycle(iter, n).\n\nIterators.cycle(iter, n) is the lazy equivalent of Base.repeat(vector, n), while Iterators.repeated(iter, n) is the lazy Base.fill(item, n).\n\ncompat: Julia 1.11\nThe method cycle(iter, n) was added in Julia 1.11.\n\nExamples\n\njulia> for (i, v) in enumerate(Iterators.cycle(\"hello\"))\n print(v)\n i > 10 && break\n end\nhellohelloh\n\njulia> foreach(print, Iterators.cycle(['j', 'u', 'l', 'i', 'a'], 3))\njuliajuliajulia\n\njulia> repeat([1,2,3], 4) == collect(Iterators.cycle([1,2,3], 4))\ntrue\n\njulia> fill([1,2,3], 4) == collect(Iterators.repeated([1,2,3], 4))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.repeated","page":"Iteration utilities","title":"Base.Iterators.repeated","text":"repeated(x[, n::Int])\n\nAn iterator that generates the value x forever. If n is specified, generates x that many times (equivalent to take(repeated(x), n)).\n\nSee also fill, and compare Iterators.cycle.\n\nExamples\n\njulia> a = Iterators.repeated([1 2], 4);\n\njulia> collect(a)\n4-element Vector{Matrix{Int64}}:\n [1 2]\n [1 2]\n [1 2]\n [1 2]\n\njulia> ans == fill([1 2], 4)\ntrue\n\njulia> Iterators.cycle([1 2], 4) |> collect |> println\n[1, 2, 1, 2, 1, 2, 1, 2]\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.product","page":"Iteration utilities","title":"Base.Iterators.product","text":"product(iters...)\n\nReturn an iterator over the product of several iterators. Each generated element is a tuple whose ith element comes from the ith argument iterator. The first iterator changes the fastest.\n\nSee also: zip, Iterators.flatten.\n\nExamples\n\njulia> collect(Iterators.product(1:2, 3:5))\n2×3 Matrix{Tuple{Int64, Int64}}:\n (1, 3) (1, 4) (1, 5)\n (2, 3) (2, 4) (2, 5)\n\njulia> ans == [(x,y) for x in 1:2, y in 3:5] # collects a generator involving Iterators.product\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.flatten","page":"Iteration utilities","title":"Base.Iterators.flatten","text":"flatten(iter)\n\nGiven an iterator that yields iterators, return an iterator that yields the elements of those iterators. Put differently, the elements of the argument iterator are concatenated.\n\nExamples\n\njulia> collect(Iterators.flatten((1:2, 8:9)))\n4-element Vector{Int64}:\n 1\n 2\n 8\n 9\n\njulia> [(x,y) for x in 0:1 for y in 'a':'c'] # collects generators involving Iterators.flatten\n6-element Vector{Tuple{Int64, Char}}:\n (0, 'a')\n (0, 'b')\n (0, 'c')\n (1, 'a')\n (1, 'b')\n (1, 'c')\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.flatmap","page":"Iteration utilities","title":"Base.Iterators.flatmap","text":"Iterators.flatmap(f, iterators...)\n\nEquivalent to flatten(map(f, iterators...)).\n\nSee also Iterators.flatten, Iterators.map.\n\ncompat: Julia 1.9\nThis function was added in Julia 1.9.\n\nExamples\n\njulia> Iterators.flatmap(n -> -n:2:n, 1:3) |> collect\n9-element Vector{Int64}:\n -1\n 1\n -2\n 0\n 2\n -3\n -1\n 1\n 3\n\njulia> stack(n -> -n:2:n, 1:3)\nERROR: DimensionMismatch: stack expects uniform slices, got axes(x) == (1:3,) while first had (1:2,)\n[...]\n\njulia> Iterators.flatmap(n -> (-n, 10n), 1:2) |> collect\n4-element Vector{Int64}:\n -1\n 10\n -2\n 20\n\njulia> ans == vec(stack(n -> (-n, 10n), 1:2))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.partition","page":"Iteration utilities","title":"Base.Iterators.partition","text":"partition(collection, n)\n\nIterate over a collection n elements at a time.\n\nExamples\n\njulia> collect(Iterators.partition([1,2,3,4,5], 2))\n3-element Vector{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}:\n [1, 2]\n [3, 4]\n [5]\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.map","page":"Iteration utilities","title":"Base.Iterators.map","text":"Iterators.map(f, iterators...)\n\nCreate a lazy mapping. This is another syntax for writing (f(args...) for args in zip(iterators...)).\n\ncompat: Julia 1.6\nThis function requires at least Julia 1.6.\n\nExamples\n\njulia> collect(Iterators.map(x -> x^2, 1:3))\n3-element Vector{Int64}:\n 1\n 4\n 9\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.filter","page":"Iteration utilities","title":"Base.Iterators.filter","text":"Iterators.filter(flt, itr)\n\nGiven a predicate function flt and an iterable object itr, return an iterable object which upon iteration yields the elements x of itr that satisfy flt(x). The order of the original iterator is preserved.\n\nThis function is lazy; that is, it is guaranteed to return in Θ(1) time and use Θ(1) additional space, and flt will not be called by an invocation of filter. Calls to flt will be made when iterating over the returned iterable object. These calls are not cached and repeated calls will be made when reiterating.\n\nwarning: Warning\nSubsequent lazy transformations on the iterator returned from filter, such as those performed by Iterators.reverse or cycle, will also delay calls to flt until collecting or iterating over the returned iterable object. If the filter predicate is nondeterministic or its return values depend on the order of iteration over the elements of itr, composition with lazy transformations may result in surprising behavior. If this is undesirable, either ensure that flt is a pure function or collect intermediate filter iterators before further transformations.\n\nSee Base.filter for an eager implementation of filtering for arrays.\n\nExamples\n\njulia> f = Iterators.filter(isodd, [1, 2, 3, 4, 5])\nBase.Iterators.Filter{typeof(isodd), Vector{Int64}}(isodd, [1, 2, 3, 4, 5])\n\njulia> foreach(println, f)\n1\n3\n5\n\njulia> [x for x in [1, 2, 3, 4, 5] if isodd(x)] # collects a generator over Iterators.filter\n3-element Vector{Int64}:\n 1\n 3\n 5\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.accumulate","page":"Iteration utilities","title":"Base.Iterators.accumulate","text":"Iterators.accumulate(f, itr; [init])\n\nGiven a 2-argument function f and an iterator itr, return a new iterator that successively applies f to the previous value and the next element of itr.\n\nThis is effectively a lazy version of Base.accumulate.\n\ncompat: Julia 1.5\nKeyword argument init is added in Julia 1.5.\n\nExamples\n\njulia> a = Iterators.accumulate(+, [1,2,3,4]);\n\njulia> foreach(println, a)\n1\n3\n6\n10\n\njulia> b = Iterators.accumulate(/, (2, 5, 2, 5); init = 100);\n\njulia> collect(b)\n4-element Vector{Float64}:\n 50.0\n 10.0\n 5.0\n 1.0\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.reverse","page":"Iteration utilities","title":"Base.Iterators.reverse","text":"Iterators.reverse(itr)\n\nGiven an iterator itr, then reverse(itr) is an iterator over the same collection but in the reverse order. This iterator is \"lazy\" in that it does not make a copy of the collection in order to reverse it; see Base.reverse for an eager implementation.\n\n(By default, this returns an Iterators.Reverse object wrapping itr, which is iterable if the corresponding iterate methods are defined, but some itr types may implement more specialized Iterators.reverse behaviors.)\n\nNot all iterator types T support reverse-order iteration. If T doesn't, then iterating over Iterators.reverse(itr::T) will throw a MethodError because of the missing iterate methods for Iterators.Reverse{T}. (To implement these methods, the original iterator itr::T can be obtained from an r::Iterators.Reverse{T} object by r.itr; more generally, one can use Iterators.reverse(r).)\n\nExamples\n\njulia> foreach(println, Iterators.reverse(1:5))\n5\n4\n3\n2\n1\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.only","page":"Iteration utilities","title":"Base.Iterators.only","text":"only(x)\n\nReturn the one and only element of collection x, or throw an ArgumentError if the collection has zero or multiple elements.\n\nSee also first, last.\n\ncompat: Julia 1.4\nThis method requires at least Julia 1.4.\n\nExamples\n\njulia> only([\"a\"])\n\"a\"\n\njulia> only(\"a\")\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> only(())\nERROR: ArgumentError: Tuple contains 0 elements, must contain exactly 1 element\nStacktrace:\n[...]\n\njulia> only(('a', 'b'))\nERROR: ArgumentError: Tuple contains 2 elements, must contain exactly 1 element\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.peel","page":"Iteration utilities","title":"Base.Iterators.peel","text":"peel(iter)\n\nReturns the first element and an iterator over the remaining elements.\n\nIf the iterator is empty return nothing (like iterate).\n\ncompat: Julia 1.7\nPrior versions throw a BoundsError if the iterator is empty.\n\nSee also: Iterators.drop, Iterators.take.\n\nExamples\n\njulia> (a, rest) = Iterators.peel(\"abc\");\n\njulia> a\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> collect(rest)\n2-element Vector{Char}:\n 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)\n 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"function"},{"location":"devdocs/isbitsunionarrays/#isbits-Union-Optimizations","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"","category":"section"},{"location":"devdocs/isbitsunionarrays/","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"In Julia, the Array type holds both \"bits\" values as well as heap-allocated \"boxed\" values. The distinction is whether the value itself is stored inline (in the direct allocated memory of the array), or if the memory of the array is simply a collection of pointers to objects allocated elsewhere. In terms of performance, accessing values inline is clearly an advantage over having to follow a pointer to the actual value. The definition of \"isbits\" generally means any Julia type with a fixed, determinate size, meaning no \"pointer\" fields, see ?isbitstype.","category":"page"},{"location":"devdocs/isbitsunionarrays/","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"Julia also supports Union types, quite literally the union of a set of types. Custom Union type definitions can be extremely handy for applications wishing to \"cut across\" the nominal type system (i.e. explicit subtype relationships) and define methods or functionality on these, otherwise unrelated, set of types. A compiler challenge, however, is in determining how to treat these Union types. The naive approach (and indeed, what Julia itself did pre-0.7), is to simply make a \"box\" and then a pointer in the box to the actual value, similar to the previously mentioned \"boxed\" values. This is unfortunate, however, because of the number of small, primitive \"bits\" types (think UInt8, Int32, Float64, etc.) that would easily fit themselves inline in this \"box\" without needing any indirection for value access. There are two main ways Julia can take advantage of this optimization as of 0.7: isbits Union fields in types, and isbits Union Arrays.","category":"page"},{"location":"devdocs/isbitsunionarrays/#isbits-Union-Structs","page":"isbits Union Optimizations","title":"isbits Union Structs","text":"","category":"section"},{"location":"devdocs/isbitsunionarrays/","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"Julia now includes an optimization wherein \"isbits Union\" fields in types (mutable struct, struct, etc.) will be stored inline. This is accomplished by determining the \"inline size\" of the Union type (e.g. Union{UInt8, Int16} will have a size of two bytes, which represents the size needed of the largest Union type Int16), and in addition, allocating an extra \"type tag byte\" (UInt8), whose value signals the type of the actual value stored inline of the \"Union bytes\". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of 0x02 for a field with type Union{Nothing, UInt8, Int16} would indicate that an Int16 value is stored in the 16 bits of the field in the structure's memory; a 0x01 value would indicate that a UInt8 value was stored in the first 8 bits of the 16 bits of the field's memory. Lastly, a value of 0x00 signals that the nothing value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory.","category":"page"},{"location":"devdocs/isbitsunionarrays/#isbits-Union-Memory","page":"isbits Union Optimizations","title":"isbits Union Memory","text":"","category":"section"},{"location":"devdocs/isbitsunionarrays/","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"Julia can now also store \"isbits Union\" values inline in a Memory, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra \"type tag memory\" of bytes, one byte per element, alongside the bytes of the actual data. This type tag memory serves the same function as the type field case: its value signals the type of the actual stored Union value. The \"type tag memory\" directly follows the regular data space. So the formula to access an isbits Union Array's type tag bytes is a->data + a->length * a->elsize.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"io = IOBuffer()\nrelease = isempty(VERSION.prerelease)\nv = \"$(VERSION.major).$(VERSION.minor)\"\n!release && (v = v*\"-$(first(VERSION.prerelease))\")\nprint(io, \"\"\"\n # Julia $(v) Documentation\n\n Welcome to the documentation for Julia $(v).\n\n \"\"\")\nif !release\n print(io,\"\"\"\n !!! warning \"Work in progress!\"\n This documentation is for an unreleased, in-development, version of Julia.\n \"\"\")\nend\nimport Markdown\nMarkdown.parse(String(take!(io)))","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Please read the release notes to see what has changed since the last release.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"release = isempty(VERSION.prerelease)\nfile = release ? \"julia-$(VERSION).pdf\" :\n \"julia-$(VERSION.major).$(VERSION.minor).$(VERSION.patch)-$(first(VERSION.prerelease)).pdf\"\nurl = \"https://raw.githubusercontent.com/JuliaLang/docs.julialang.org/assets/$(file)\"\nimport Markdown\nMarkdown.parse(\"\"\"\n!!! note\n The documentation is also available in PDF format: [$file]($url).\n\"\"\")","category":"page"},{"location":"#man-important-links","page":"Julia Documentation","title":"Important Links","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Below is a non-exhaustive list of links that will be useful as you learn and use the Julia programming language.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Julia Homepage\nDownload Julia\nDiscussion forum\nJulia YouTube\nFind Julia Packages\nLearning Resources\nRead and write blogs on Julia","category":"page"},{"location":"#man-introduction","page":"Julia Documentation","title":"Introduction","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Scientific computing has traditionally required the highest performance, yet domain experts have largely moved to slower dynamic languages for daily work. We believe there are many good reasons to prefer dynamic languages for these applications, and we do not expect their use to diminish. Fortunately, modern language design and compiler techniques make it possible to mostly eliminate the performance trade-off and provide a single environment productive enough for prototyping and efficient enough for deploying performance-intensive applications. The Julia programming language fills this role: it is a flexible dynamic language, appropriate for scientific and numerical computing, with performance comparable to traditional statically-typed languages.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Because Julia's compiler is different from the interpreters used for languages like Python or R, you may find that Julia's performance is unintuitive at first. If you find that something is slow, we highly recommend reading through the Performance Tips section before trying anything else. Once you understand how Julia works, it is easy to write code that is nearly as fast as C.","category":"page"},{"location":"#man-julia-compared-other-languages","page":"Julia Documentation","title":"Julia Compared to Other Languages","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Julia features optional typing, multiple dispatch, and good performance, achieved using type inference and just-in-time (JIT) compilation (and optional ahead-of-time compilation), implemented using LLVM. It is multi-paradigm, combining features of imperative, functional, and object-oriented programming. Julia provides ease and expressiveness for high-level numerical computing, in the same way as languages such as R, MATLAB, and Python, but also supports general programming. To achieve this, Julia builds upon the lineage of mathematical programming languages, but also borrows much from popular dynamic languages, including Lisp, Perl, Python, Lua, and Ruby.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"The most significant departures of Julia from typical dynamic languages are:","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"The core language imposes very little; Julia Base and the standard library are written in Julia itself, including primitive operations like integer arithmetic\nA rich language of types for constructing and describing objects, that can also optionally be used to make type declarations\nThe ability to define function behavior across many combinations of argument types via multiple dispatch\nAutomatic generation of efficient, specialized code for different argument types\nGood performance, approaching that of statically-compiled languages like C","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Although one sometimes speaks of dynamic languages as being \"typeless\", they are definitely not. Every object, whether primitive or user-defined, has a type. The lack of type declarations in most dynamic languages, however, means that one cannot instruct the compiler about the types of values, and often cannot explicitly talk about types at all. In static languages, on the other hand, while one can – and usually must – annotate types for the compiler, types exist only at compile time and cannot be manipulated or expressed at run time. In Julia, types are themselves run-time objects, and can also be used to convey information to the compiler.","category":"page"},{"location":"#man-what-makes-julia","page":"Julia Documentation","title":"What Makes Julia, Julia?","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"While the casual programmer need not explicitly use types or multiple dispatch, they are the core unifying features of Julia: functions are defined on different combinations of argument types, and applied by dispatching to the most specific matching definition. This model is a good fit for mathematical programming, where it is unnatural for the first argument to \"own\" an operation as in traditional object-oriented dispatch. Operators are just functions with special notation – to extend addition to new user-defined data types, you define new methods for the + function. Existing code then seamlessly applies to the new data types.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Partly because of run-time type inference (augmented by optional type annotations), and partly because of a strong focus on performance from the inception of the project, Julia's computational efficiency exceeds that of other dynamic languages, and even rivals that of statically-compiled languages. For large scale numerical problems, speed always has been, continues to be, and probably always will be crucial: the amount of data being processed has easily kept pace with Moore's Law over the past decades.","category":"page"},{"location":"#man-advantages-of-julia","page":"Julia Documentation","title":"Advantages of Julia","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Julia aims to create an unprecedented combination of ease-of-use, power, and efficiency in a single language. In addition to the above, some advantages of Julia over comparable systems include:","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Free and open source (MIT licensed)\nUser-defined types are as fast and compact as built-ins\nNo need to vectorize code for performance; devectorized code is fast\nDesigned for parallelism and distributed computation\nLightweight \"green\" threading (coroutines)\nUnobtrusive yet powerful type system\nElegant and extensible conversions and promotions for numeric and other types\nEfficient support for Unicode, including but not limited to UTF-8\nCall C functions directly (no wrappers or special APIs needed)\nPowerful shell-like capabilities for managing other processes\nLisp-like macros and other metaprogramming facilities","category":"page"},{"location":"manual/environment-variables/#Environment-Variables","page":"Environment Variables","title":"Environment Variables","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Julia can be configured with a number of environment variables, set either in the usual way for each operating system, or in a portable way from within Julia. Supposing that you want to set the environment variable JULIA_EDITOR to vim, you can type ENV[\"JULIA_EDITOR\"] = \"vim\" (for instance, in the REPL) to make this change on a case by case basis, or add the same to the user configuration file ~/.julia/config/startup.jl in the user's home directory to have a permanent effect. The current value of the same environment variable can be determined by evaluating ENV[\"JULIA_EDITOR\"].","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The environment variables that Julia uses generally start with JULIA. If InteractiveUtils.versioninfo is called with the keyword verbose=true, then the output will list any defined environment variables relevant for Julia, including those which include JULIA in their names.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nIt is recommended to avoid changing environment variables during runtime, such as within a ~/.julia/config/startup.jl.One reason is that some julia language variables, such as JULIA_NUM_THREADS and JULIA_PROJECT, need to be set before Julia starts.Similarly, __init__() functions of user modules in the sysimage (via PackageCompiler) are run before startup.jl, so setting environment variables in a startup.jl may be too late for user code.Further, changing environment variables during runtime can introduce data races into otherwise benign code.In Bash, environment variables can either be set manually by running, e.g., export JULIA_NUM_THREADS=4 before starting Julia, or by adding the same command to ~/.bashrc or ~/.bash_profile to set the variable each time Bash is started.","category":"page"},{"location":"manual/environment-variables/#File-locations","page":"Environment Variables","title":"File locations","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_BINDIR","page":"Environment Variables","title":"JULIA_BINDIR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The absolute path of the directory containing the Julia executable, which sets the global variable Sys.BINDIR. If $JULIA_BINDIR is not set, then Julia determines the value Sys.BINDIR at run-time.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The executable itself is one of","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$JULIA_BINDIR/julia\n$JULIA_BINDIR/julia-debug","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"by default.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The global variable Base.DATAROOTDIR determines a relative path from Sys.BINDIR to the data directory associated with Julia. Then the path","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$JULIA_BINDIR/$DATAROOTDIR/julia/base","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"determines the directory in which Julia initially searches for source files (via Base.find_source_file()).","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Likewise, the global variable Base.SYSCONFDIR determines a relative path to the configuration file directory. Then Julia searches for a startup.jl file at","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$JULIA_BINDIR/$SYSCONFDIR/julia/startup.jl\n$JULIA_BINDIR/../etc/julia/startup.jl","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"by default (via Base.load_julia_startup()).","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"For example, a Linux installation with a Julia executable located at /bin/julia, a DATAROOTDIR of ../share, and a SYSCONFDIR of ../etc will have JULIA_BINDIR set to /bin, a source-file search path of","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"/share/julia/base","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"and a global configuration search path of","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"/etc/julia/startup.jl","category":"page"},{"location":"manual/environment-variables/#JULIA_PROJECT","page":"Environment Variables","title":"JULIA_PROJECT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"A directory path that indicates which project should be the initial active project. Setting this environment variable has the same effect as specifying the --project start-up option, but --project has higher precedence. If the variable is set to @. (note the trailing dot) then Julia tries to find a project directory that contains Project.toml or JuliaProject.toml file from the current directory and its parents. See also the chapter on Code Loading.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nJULIA_PROJECT must be defined before starting julia; defining it in startup.jl is too late in the startup process.","category":"page"},{"location":"manual/environment-variables/#JULIA_LOAD_PATH","page":"Environment Variables","title":"JULIA_LOAD_PATH","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The JULIA_LOAD_PATH environment variable is used to populate the global Julia LOAD_PATH variable, which determines which packages can be loaded via import and using (see Code Loading).","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Unlike the shell PATH variable, empty entries in JULIA_LOAD_PATH are expanded to the default value of LOAD_PATH, [\"@\", \"@v#.#\", \"@stdlib\"] when populating LOAD_PATH. This allows easy appending, prepending, etc. of the load path value in shell scripts regardless of whether JULIA_LOAD_PATH is already set or not. For example, to prepend the directory /foo/bar to LOAD_PATH just do","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"export JULIA_LOAD_PATH=\"/foo/bar:$JULIA_LOAD_PATH\"","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If the JULIA_LOAD_PATH environment variable is already set, its old value will be prepended with /foo/bar. On the other hand, if JULIA_LOAD_PATH is not set, then it will be set to /foo/bar: which will expand to a LOAD_PATH value of [\"/foo/bar\", \"@\", \"@v#.#\", \"@stdlib\"]. If JULIA_LOAD_PATH is set to the empty string, it expands to an empty LOAD_PATH array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty load path via the environment variable. If you want the default load path, either unset the environment variable or if it must have a value, set it to the string :.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nOn Windows, path elements are separated by the ; character, as is the case with most path lists on Windows. Replace : with ; in the above paragraph.","category":"page"},{"location":"manual/environment-variables/#JULIA_DEPOT_PATH","page":"Environment Variables","title":"JULIA_DEPOT_PATH","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The JULIA_DEPOT_PATH environment variable is used to populate the global Julia DEPOT_PATH variable, which controls where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, configuration files, and the default location of the REPL's history file.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Unlike the shell PATH variable but similar to JULIA_LOAD_PATH, empty entries in JULIA_DEPOT_PATH are expanded to the default value of DEPOT_PATH, excluding the user depot. This allows easy overriding of the user depot, while still retaining access to resources that are bundled with Julia, like cache files, artifacts, etc. For example, to switch the user depot to /foo/bar just do","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"export JULIA_DEPOT_PATH=\"/foo/bar:\"","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"All package operations, like cloning registrise or installing packages, will now write to /foo/bar, but since the empty entry is expanded to the default system depot, any bundled resources will still be available. If you really only want to use the depot at /foo/bar, and not load any bundled resources, simply set the environment variable to /foo/bar without the trailing colon.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"There are two exceptions to the above rule. First, if JULIA_DEPOT_PATH is set to the empty string, it expands to an empty DEPOT_PATH array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty depot path via the environment variable.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Second, if no user depot is specified in JULIA_DEPOT_PATH, then the empty entry is expanded to the default depot including the user depot. This makes it possible to use the default depot, as if the environment variable was unset, by setting it to the string :.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nOn Windows, path elements are separated by the ; character, as is the case with most path lists on Windows. Replace : with ; in the above paragraph.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nJULIA_DEPOT_PATH must be defined before starting julia; defining it in startup.jl is too late in the startup process; at that point you can instead directly modify the DEPOT_PATH array, which is populated from the environment variable.","category":"page"},{"location":"manual/environment-variables/#JULIA_HISTORY","page":"Environment Variables","title":"JULIA_HISTORY","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The absolute path REPL.find_hist_file() of the REPL's history file. If $JULIA_HISTORY is not set, then REPL.find_hist_file() defaults to","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$(DEPOT_PATH[1])/logs/repl_history.jl","category":"page"},{"location":"manual/environment-variables/#JULIA_MAX_NUM_PRECOMPILE_FILES","page":"Environment Variables","title":"JULIA_MAX_NUM_PRECOMPILE_FILES","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Sets the maximum number of different instances of a single package that are to be stored in the precompile cache (default = 10).","category":"page"},{"location":"manual/environment-variables/#JULIA_VERBOSE_LINKING","page":"Environment Variables","title":"JULIA_VERBOSE_LINKING","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, linker commands will be displayed during precompilation.","category":"page"},{"location":"manual/environment-variables/#Pkg.jl","page":"Environment Variables","title":"Pkg.jl","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_CI","page":"Environment Variables","title":"JULIA_CI","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, this indicates to the package server that any package operations are part of a continuous integration (CI) system for the purposes of gathering package usage statistics.","category":"page"},{"location":"manual/environment-variables/#JULIA_NUM_PRECOMPILE_TASKS","page":"Environment Variables","title":"JULIA_NUM_PRECOMPILE_TASKS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The number of parallel tasks to use when precompiling packages. See Pkg.precompile.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_DEVDIR","page":"Environment Variables","title":"JULIA_PKG_DEVDIR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The default directory used by Pkg.develop for downloading packages.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_IGNORE_HASHES","page":"Environment Variables","title":"JULIA_PKG_IGNORE_HASHES","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to 1, this will ignore incorrect hashes in artifacts. This should be used carefully, as it disables verification of downloads, but can resolve issues when moving files across different types of file systems. See Pkg.jl issue #2317 for more details.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.6\nThis is only supported in Julia 1.6 and above.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_OFFLINE","page":"Environment Variables","title":"JULIA_PKG_OFFLINE","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, this will enable offline mode: see Pkg.offline.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.5\nPkg's offline mode requires Julia 1.5 or later.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_PRECOMPILE_AUTO","page":"Environment Variables","title":"JULIA_PKG_PRECOMPILE_AUTO","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to 0, this will disable automatic precompilation by package actions which change the manifest. See Pkg.precompile.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_SERVER","page":"Environment Variables","title":"JULIA_PKG_SERVER","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Specifies the URL of the package registry to use. By default, Pkg uses https://pkg.julialang.org to fetch Julia packages. In addition, you can disable the use of the PkgServer protocol, and instead access the packages directly from their hosts (GitHub, GitLab, etc.) by setting: export JULIA_PKG_SERVER=\"\"","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_SERVER_REGISTRY_PREFERENCE","page":"Environment Variables","title":"JULIA_PKG_SERVER_REGISTRY_PREFERENCE","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Specifies the preferred registry flavor. Currently supported values are conservative (the default), which will only publish resources that have been processed by the storage server (and thereby have a higher probability of being available from the PkgServers), whereas eager will publish registries whose resources have not necessarily been processed by the storage servers. Users behind restrictive firewalls that do not allow downloading from arbitrary servers should not use the eager flavor.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.7\nThis only affects Julia 1.7 and above.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_UNPACK_REGISTRY","page":"Environment Variables","title":"JULIA_PKG_UNPACK_REGISTRY","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, this will unpack the registry instead of storing it as a compressed tarball.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.7\nThis only affects Julia 1.7 and above. Earlier versions will always unpack the registry.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_USE_CLI_GIT","page":"Environment Variables","title":"JULIA_PKG_USE_CLI_GIT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, Pkg operations which use the git protocol will use an external git executable instead of the default libgit2 library.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.7\nUse of the git executable is only supported on Julia 1.7 and above.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKGRESOLVE_ACCURACY","page":"Environment Variables","title":"JULIA_PKGRESOLVE_ACCURACY","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The accuracy of the package resolver. This should be a positive integer, the default is 1.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_PRESERVE_TIERED_INSTALLED","page":"Environment Variables","title":"JULIA_PKG_PRESERVE_TIERED_INSTALLED","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Change the default package installation strategy to Pkg.PRESERVE_TIERED_INSTALLED to let the package manager try to install versions of packages while keeping as many versions of packages already installed as possible.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.9\nThis only affects Julia 1.9 and above.","category":"page"},{"location":"manual/environment-variables/#Network-transport","page":"Environment Variables","title":"Network transport","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_NO_VERIFY_HOSTS","page":"Environment Variables","title":"JULIA_NO_VERIFY_HOSTS","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_SSL_NO_VERIFY_HOSTS","page":"Environment Variables","title":"JULIA_SSL_NO_VERIFY_HOSTS","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_SSH_NO_VERIFY_HOSTS","page":"Environment Variables","title":"JULIA_SSH_NO_VERIFY_HOSTS","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_ALWAYS_VERIFY_HOSTS","page":"Environment Variables","title":"JULIA_ALWAYS_VERIFY_HOSTS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Specify hosts whose identity should or should not be verified for specific transport layers. See NetworkOptions.verify_host","category":"page"},{"location":"manual/environment-variables/#JULIA_SSL_CA_ROOTS_PATH","page":"Environment Variables","title":"JULIA_SSL_CA_ROOTS_PATH","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Specify the file or directory containing the certificate authority roots. See NetworkOptions.ca_roots","category":"page"},{"location":"manual/environment-variables/#External-applications","page":"Environment Variables","title":"External applications","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_SHELL","page":"Environment Variables","title":"JULIA_SHELL","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The absolute path of the shell with which Julia should execute external commands (via Base.repl_cmd()). Defaults to the environment variable $SHELL, and falls back to /bin/sh if $SHELL is unset.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nOn Windows, this environment variable is ignored, and external commands are executed directly.","category":"page"},{"location":"manual/environment-variables/#JULIA_EDITOR","page":"Environment Variables","title":"JULIA_EDITOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The editor returned by InteractiveUtils.editor() and used in, e.g., InteractiveUtils.edit, referring to the command of the preferred editor, for instance vim.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$JULIA_EDITOR takes precedence over $VISUAL, which in turn takes precedence over $EDITOR. If none of these environment variables is set, then the editor is taken to be open on Windows and OS X, or /etc/alternatives/editor if it exists, or emacs otherwise.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"To use Visual Studio Code on Windows, set $JULIA_EDITOR to code.cmd.","category":"page"},{"location":"manual/environment-variables/#Parallelization","page":"Environment Variables","title":"Parallelization","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_CPU_THREADS","page":"Environment Variables","title":"JULIA_CPU_THREADS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Overrides the global variable Base.Sys.CPU_THREADS, the number of logical CPU cores available.","category":"page"},{"location":"manual/environment-variables/#JULIA_WORKER_TIMEOUT","page":"Environment Variables","title":"JULIA_WORKER_TIMEOUT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"A Float64 that sets the value of Distributed.worker_timeout() (default: 60.0). This function gives the number of seconds a worker process will wait for a master process to establish a connection before dying.","category":"page"},{"location":"manual/environment-variables/#JULIA_NUM_THREADS","page":"Environment Variables","title":"JULIA_NUM_THREADS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"An unsigned 64-bit integer (uint64_t) that sets the maximum number of threads available to Julia. If $JULIA_NUM_THREADS is not positive or is not set, or if the number of CPU threads cannot be determined through system calls, then the number of threads is set to 1.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If $JULIA_NUM_THREADS is set to auto, then the number of threads will be set to the number of CPU threads.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nJULIA_NUM_THREADS must be defined before starting julia; defining it in startup.jl is too late in the startup process.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.5\nIn Julia 1.5 and above the number of threads can also be specified on startup using the -t/--threads command line argument.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.7\nThe auto value for $JULIA_NUM_THREADS requires Julia 1.7 or above.","category":"page"},{"location":"manual/environment-variables/#JULIA_THREAD_SLEEP_THRESHOLD","page":"Environment Variables","title":"JULIA_THREAD_SLEEP_THRESHOLD","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to a string that starts with the case-insensitive substring \"infinite\", then spinning threads never sleep. Otherwise, $JULIA_THREAD_SLEEP_THRESHOLD is interpreted as an unsigned 64-bit integer (uint64_t) and gives, in nanoseconds, the amount of time after which spinning threads should sleep.","category":"page"},{"location":"manual/environment-variables/#JULIA_NUM_GC_THREADS","page":"Environment Variables","title":"JULIA_NUM_GC_THREADS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Sets the number of threads used by Garbage Collection. If unspecified is set to half of the number of worker threads.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.10\nThe environment variable was added in 1.10","category":"page"},{"location":"manual/environment-variables/#JULIA_IMAGE_THREADS","page":"Environment Variables","title":"JULIA_IMAGE_THREADS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"An unsigned 32-bit integer that sets the number of threads used by image compilation in this Julia process. The value of this variable may be ignored if the module is a small module. If left unspecified, the smaller of the value of JULIA_CPU_THREADS or half the number of logical CPU cores is used in its place.","category":"page"},{"location":"manual/environment-variables/#JULIA_IMAGE_TIMINGS","page":"Environment Variables","title":"JULIA_IMAGE_TIMINGS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"A boolean value that determines if detailed timing information is printed during during image compilation. Defaults to 0.","category":"page"},{"location":"manual/environment-variables/#JULIA_EXCLUSIVE","page":"Environment Variables","title":"JULIA_EXCLUSIVE","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0, then Julia's thread policy is consistent with running on a dedicated machine: the master thread is on proc 0, and threads are affinitized. Otherwise, Julia lets the operating system handle thread policy.","category":"page"},{"location":"manual/environment-variables/#REPL-formatting","page":"Environment Variables","title":"REPL formatting","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Environment variables that determine how REPL output should be formatted at the terminal. Generally, these variables should be set to ANSI terminal escape sequences. Julia provides a high-level interface with much of the same functionality; see the section on The Julia REPL.","category":"page"},{"location":"manual/environment-variables/#JULIA_ERROR_COLOR","page":"Environment Variables","title":"JULIA_ERROR_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.error_color() (default: light red, \"\\033[91m\") that errors should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#JULIA_WARN_COLOR","page":"Environment Variables","title":"JULIA_WARN_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.warn_color() (default: yellow, \"\\033[93m\") that warnings should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#JULIA_INFO_COLOR","page":"Environment Variables","title":"JULIA_INFO_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.info_color() (default: cyan, \"\\033[36m\") that info should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#JULIA_INPUT_COLOR","page":"Environment Variables","title":"JULIA_INPUT_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.input_color() (default: normal, \"\\033[0m\") that input should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#JULIA_ANSWER_COLOR","page":"Environment Variables","title":"JULIA_ANSWER_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.answer_color() (default: normal, \"\\033[0m\") that output should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#System-and-Package-Image-Building","page":"Environment Variables","title":"System and Package Image Building","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_CPU_TARGET","page":"Environment Variables","title":"JULIA_CPU_TARGET","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Modify the target machine architecture for (pre)compiling system and package images. JULIA_CPU_TARGET only affects machine code image generation being output to a disk cache. Unlike the --cpu-target, or -C, command line option, it does not influence just-in-time (JIT) code generation within a Julia session where machine code is only stored in memory.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Valid values for JULIA_CPU_TARGET can be obtained by executing julia -C help.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Setting JULIA_CPU_TARGET is important for heterogeneous compute systems where processors of distinct types or features may be present. This is commonly encountered in high performance computing (HPC) clusters since the component nodes may be using distinct processors.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The CPU target string is a list of strings separated by ; each string starts with a CPU or architecture name and followed by an optional list of features separated by ,. A generic or empty CPU name means the basic required feature set of the target ISA which is at least the architecture the C/C++ runtime is compiled with. Each string is interpreted by LLVM.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"A few special features are supported:","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"clone_all\nThis forces the target to have all functions in sysimg cloned. When used in negative form (i.e. -clone_all), this disables full clone that's enabled by default for certain targets.\nbase([0-9]*)\nThis specifies the (0-based) base target index. The base target is the target that the current target is based on, i.e. the functions that are not being cloned will use the version in the base target. This option causes the base target to be fully cloned (as if clone_all is specified for it) if it is not the default target (0). The index can only be smaller than the current index.\nopt_size\nOptimize for size with minimum performance impact. Clang/GCC's -Os.\nmin_size\nOptimize only for size. Clang's -Oz.","category":"page"},{"location":"manual/environment-variables/#Debugging-and-profiling","page":"Environment Variables","title":"Debugging and profiling","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_DEBUG","page":"Environment Variables","title":"JULIA_DEBUG","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Enable debug logging for a file or module, see Logging for more information.","category":"page"},{"location":"manual/environment-variables/#JULIA_PROFILE_PEEK_HEAP_SNAPSHOT","page":"Environment Variables","title":"JULIA_PROFILE_PEEK_HEAP_SNAPSHOT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Enable collecting of a heap snapshot during execution via the profiling peek mechanism. See Triggered During Execution.","category":"page"},{"location":"manual/environment-variables/#JULIA_TIMING_SUBSYSTEMS","page":"Environment Variables","title":"JULIA_TIMING_SUBSYSTEMS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Allows you to enable or disable zones for a specific Julia run. For instance, setting the variable to +GC,-INFERENCE will enable the GC zones and disable the INFERENCE zones. See Dynamically Enabling and Disabling Zones.","category":"page"},{"location":"manual/environment-variables/#JULIA_GC_ALLOC_POOL","page":"Environment Variables","title":"JULIA_GC_ALLOC_POOL","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_GC_ALLOC_OTHER","page":"Environment Variables","title":"JULIA_GC_ALLOC_OTHER","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_GC_ALLOC_PRINT","page":"Environment Variables","title":"JULIA_GC_ALLOC_PRINT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set, these environment variables take strings that optionally start with the character 'r', followed by a string interpolation of a colon-separated list of three signed 64-bit integers (int64_t). This triple of integers a:b:c represents the arithmetic sequence a, a + b, a + 2*b, ... c.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If it's the nth time that jl_gc_pool_alloc() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_POOL, then garbage collection is forced.\nIf it's the nth time that maybe_collect() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_OTHER, then garbage collection is forced.\nIf it's the nth time that jl_gc_collect() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_PRINT, then counts for the number of calls to jl_gc_pool_alloc() and maybe_collect() are printed.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If the value of the environment variable begins with the character 'r', then the interval between garbage collection events is randomized.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nThese environment variables only have an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).","category":"page"},{"location":"manual/environment-variables/#JULIA_GC_NO_GENERATIONAL","page":"Environment Variables","title":"JULIA_GC_NO_GENERATIONAL","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0, then the Julia garbage collector never performs \"quick sweeps\" of memory.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nThis environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).","category":"page"},{"location":"manual/environment-variables/#JULIA_GC_WAIT_FOR_DEBUGGER","page":"Environment Variables","title":"JULIA_GC_WAIT_FOR_DEBUGGER","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0, then the Julia garbage collector will wait for a debugger to attach instead of aborting whenever there's a critical error.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nThis environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).","category":"page"},{"location":"manual/environment-variables/#ENABLE_JITPROFILING","page":"Environment Variables","title":"ENABLE_JITPROFILING","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0, then the compiler will create and register an event listener for just-in-time (JIT) profiling.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nThis environment variable only has an effect if Julia was compiled with JIT profiling support, using eitherIntel's VTune™ Amplifier (USE_INTEL_JITEVENTS set to 1 in the build configuration), or\nOProfile (USE_OPROFILE_JITEVENTS set to 1 in the build configuration).\nPerf (USE_PERF_JITEVENTS set to 1 in the build configuration). This integration is enabled by default.","category":"page"},{"location":"manual/environment-variables/#ENABLE_GDBLISTENER","page":"Environment Variables","title":"ENABLE_GDBLISTENER","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0 enables GDB registration of Julia code on release builds. On debug builds of Julia this is always enabled. Recommended to use with -g 2.","category":"page"},{"location":"manual/environment-variables/#JULIA_LLVM_ARGS","page":"Environment Variables","title":"JULIA_LLVM_ARGS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Arguments to be passed to the LLVM backend.","category":"page"},{"location":"manual/environment-variables/#JULIA_FALLBACK_REPL","page":"Environment Variables","title":"JULIA_FALLBACK_REPL","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Forces the fallback repl instead of REPL.jl.","category":"page"},{"location":"manual/faq/#Frequently-Asked-Questions","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"section"},{"location":"manual/faq/#General","page":"Frequently Asked Questions","title":"General","text":"","category":"section"},{"location":"manual/faq/#Is-Julia-named-after-someone-or-something?","page":"Frequently Asked Questions","title":"Is Julia named after someone or something?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"No.","category":"page"},{"location":"manual/faq/#Why-don't-you-compile-Matlab/Python/R/…-code-to-Julia?","page":"Frequently Asked Questions","title":"Why don't you compile Matlab/Python/R/… code to Julia?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Since many people are familiar with the syntax of other dynamic languages, and lots of code has already been written in those languages, it is natural to wonder why we didn't just plug a Matlab or Python front-end into a Julia back-end (or “transpile” code to Julia) in order to get all the performance benefits of Julia without requiring programmers to learn a new language. Simple, right?","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The basic issue is that there is nothing special about Julia's compiler: we use a commonplace compiler (LLVM) with no “secret sauce” that other language developers don't know about. Indeed, Julia's compiler is in many ways much simpler than those of other dynamic languages (e.g. PyPy or LuaJIT). Julia's performance advantage derives almost entirely from its front-end: its language semantics allow a well-written Julia program to give more opportunities to the compiler to generate efficient code and memory layouts. If you tried to compile Matlab or Python code to Julia, our compiler would be limited by the semantics of Matlab or Python to producing code no better than that of existing compilers for those languages (and probably worse). The key role of semantics is also why several existing Python compilers (like Numba and Pythran) only attempt to optimize a small subset of the language (e.g. operations on Numpy arrays and scalars), and for this subset they are already doing at least as well as we could for the same semantics. The people working on those projects are incredibly smart and have accomplished amazing things, but retrofitting a compiler onto a language that was designed to be interpreted is a very difficult problem.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia's advantage is that good performance is not limited to a small subset of “built-in” types and operations, and one can write high-level type-generic code that works on arbitrary user-defined types while remaining fast and memory-efficient. Types in languages like Python simply don't provide enough information to the compiler for similar capabilities, so as soon as you used those languages as a Julia front-end you would be stuck.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"For similar reasons, automated translation to Julia would also typically generate unreadable, slow, non-idiomatic code that would not be a good starting point for a native Julia port from another language.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"On the other hand, language interoperability is extremely useful: we want to exploit existing high-quality code in other languages from Julia (and vice versa)! The best way to enable this is not a transpiler, but rather via easy inter-language calling facilities. We have worked hard on this, from the built-in ccall intrinsic (to call C and Fortran libraries) to JuliaInterop packages that connect Julia to Python, Matlab, C++, and more.","category":"page"},{"location":"manual/faq/#man-api","page":"Frequently Asked Questions","title":"Public API","text":"","category":"section"},{"location":"manual/faq/#How-does-Julia-define-its-public-API?","page":"Frequently Asked Questions","title":"How does Julia define its public API?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia's public API is the behavior described in documentation of public symbols from Base and the standard libraries. Functions, types, and constants are not part of the public API if they are not public, even if they have docstrings or are described in the documentation. Further, only the documented behavior of public symbols is part of the public API. Undocumented behavior of public symbols is internal.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Public symbols are those marked with either public foo or export foo.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In other words:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Documented behavior of public symbols is part of the public API.\nUndocumented behavior of public symbols is not part of the public API.\nDocumented behavior of private symbols is not part of the public API.\nUndocumented behavior of private symbols is not part of the public API.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can get a complete list of the public symbols from a module with names(MyModule).","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Package authors are encouraged to define their public API similarly.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Anything in Julia's Public API is covered by SemVer and therefore will not be removed or receive meaningful breaking changes before Julia 2.0.","category":"page"},{"location":"manual/faq/#There-is-a-useful-undocumented-function/type/constant.-Can-I-use-it?","page":"Frequently Asked Questions","title":"There is a useful undocumented function/type/constant. Can I use it?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Updating Julia may break your code if you use non-public API. If the code is self-contained, it may be a good idea to copy it into your project. If you want to rely on a complex non-public API, especially when using it from a stable package, it is a good idea to open an issue or pull request to start a discussion for turning it into a public API. However, we do not discourage the attempt to create packages that expose stable public interfaces while relying on non-public implementation details of Julia and buffering the differences across different Julia versions.","category":"page"},{"location":"manual/faq/#The-documentation-is-not-accurate-enough.-Can-I-rely-on-the-existing-behavior?","page":"Frequently Asked Questions","title":"The documentation is not accurate enough. Can I rely on the existing behavior?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Please open an issue or pull request to start a discussion for turning the existing behavior into a public API.","category":"page"},{"location":"manual/faq/#Sessions-and-the-REPL","page":"Frequently Asked Questions","title":"Sessions and the REPL","text":"","category":"section"},{"location":"manual/faq/#How-do-I-delete-an-object-in-memory?","page":"Frequently Asked Questions","title":"How do I delete an object in memory?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia does not have an analog of MATLAB's clear function; once a name is defined in a Julia session (technically, in module Main), it is always present.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If memory usage is your concern, you can always replace objects with ones that consume less memory. For example, if A is a gigabyte-sized array that you no longer need, you can free the memory with A = nothing. The memory will be released the next time the garbage collector runs; you can force this to happen with GC.gc(). Moreover, an attempt to use A will likely result in an error, because most methods are not defined on type Nothing.","category":"page"},{"location":"manual/faq/#How-can-I-modify-the-declaration-of-a-type-in-my-session?","page":"Frequently Asked Questions","title":"How can I modify the declaration of a type in my session?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Perhaps you've defined a type and then realize you need to add a new field. If you try this at the REPL, you get the error:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"ERROR: invalid redefinition of constant MyType","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Types in module Main cannot be redefined.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"While this can be inconvenient when you are developing new code, there's an excellent workaround. Modules can be replaced by redefining them, and so if you wrap all your new code inside a module you can redefine types and constants. You can't import the type names into Main and then expect to be able to redefine them there, but you can use the module name to resolve the scope. In other words, while developing you might use a workflow something like this:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"include(\"mynewcode.jl\") # this defines a module MyModule\nobj1 = MyModule.ObjConstructor(a, b)\nobj2 = MyModule.somefunction(obj1)\n# Got an error. Change something in \"mynewcode.jl\"\ninclude(\"mynewcode.jl\") # reload the module\nobj1 = MyModule.ObjConstructor(a, b) # old objects are no longer valid, must reconstruct\nobj2 = MyModule.somefunction(obj1) # this time it worked!\nobj3 = MyModule.someotherfunction(obj2, c)\n...","category":"page"},{"location":"manual/faq/#man-scripting","page":"Frequently Asked Questions","title":"Scripting","text":"","category":"section"},{"location":"manual/faq/#How-do-I-check-if-the-current-file-is-being-run-as-the-main-script?","page":"Frequently Asked Questions","title":"How do I check if the current file is being run as the main script?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"When a file is run as the main script using julia file.jl one might want to activate extra functionality like command line argument handling. A way to determine that a file is run in this fashion is to check if abspath(PROGRAM_FILE) == @__FILE__ is true.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"However, it is recommended to not write files that double as a script and as an importable library. If one needs functionality both available as a library and a script, it is better to write is as a library, then import the functionality into a distinct script.","category":"page"},{"location":"manual/faq/#catch-ctrl-c","page":"Frequently Asked Questions","title":"How do I catch CTRL-C in a script?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Running a Julia script using julia file.jl does not throw InterruptException when you try to terminate it with CTRL-C (SIGINT). To run a certain code before terminating a Julia script, which may or may not be caused by CTRL-C, use atexit. Alternatively, you can use julia -e 'include(popfirst!(ARGS))' file.jl to execute a script while being able to catch InterruptException in the try block. Note that with this strategy PROGRAM_FILE will not be set.","category":"page"},{"location":"manual/faq/#How-do-I-pass-options-to-julia-using-#!/usr/bin/env?","page":"Frequently Asked Questions","title":"How do I pass options to julia using #!/usr/bin/env?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Passing options to julia in a so-called shebang line, as in #!/usr/bin/env julia --startup-file=no, will not work on many platforms (BSD, macOS, Linux) where the kernel, unlike the shell, does not split arguments at space characters. The option env -S, which splits a single argument string into multiple arguments at spaces, similar to a shell, offers a simple workaround:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"#!/usr/bin/env -S julia --color=yes --startup-file=no\n@show ARGS # put any Julia code here","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"note: Note\nOption env -S appeared in FreeBSD 6.0 (2005), macOS Sierra (2016) and GNU/Linux coreutils 8.30 (2018).","category":"page"},{"location":"manual/faq/#Why-doesn't-run-support-*-or-pipes-for-scripting-external-programs?","page":"Frequently Asked Questions","title":"Why doesn't run support * or pipes for scripting external programs?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia's run function launches external programs directly, without invoking an operating-system shell (unlike the system(\"...\") function in other languages like Python, R, or C). That means that run does not perform wildcard expansion of * (\"globbing\"), nor does it interpret shell pipelines like | or >.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can still do globbing and pipelines using Julia features, however. For example, the built-in pipeline function allows you to chain external programs and files, similar to shell pipes, and the Glob.jl package implements POSIX-compatible globbing.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can, of course, run programs through the shell by explicitly passing a shell and a command string to run, e.g. run(`sh -c \"ls > files.txt\"`) to use the Unix Bourne shell, but you should generally prefer pure-Julia scripting like run(pipeline(`ls`, \"files.txt\")). The reason why we avoid the shell by default is that shelling out sucks: launching processes via the shell is slow, fragile to quoting of special characters, has poor error handling, and is problematic for portability. (The Python developers came to a similar conclusion.)","category":"page"},{"location":"manual/faq/#Variables-and-Assignments","page":"Frequently Asked Questions","title":"Variables and Assignments","text":"","category":"section"},{"location":"manual/faq/#Why-am-I-getting-UndefVarError-from-a-simple-loop?","page":"Frequently Asked Questions","title":"Why am I getting UndefVarError from a simple loop?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You might have something like:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"x = 0\nwhile x < 10\n x += 1\nend","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"and notice that it works fine in an interactive environment (like the Julia REPL), but gives UndefVarError: `x` not defined when you try to run it in script or other file. What is going on is that Julia generally requires you to be explicit about assigning to global variables in a local scope.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Here, x is a global variable, while defines a local scope, and x += 1 is an assignment to a global in that local scope.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As mentioned above, Julia (version 1.5 or later) allows you to omit the global keyword for code in the REPL (and many other interactive environments), to simplify exploration (e.g. copy-pasting code from a function to run interactively). However, once you move to code in files, Julia requires a more disciplined approach to global variables. You have least three options:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Put the code into a function (so that x is a local variable in a function). In general, it is good software engineering to use functions rather than global scripts (search online for \"why global variables bad\" to see many explanations). In Julia, global variables are also slow.\nWrap the code in a let block. (This makes x a local variable within the let ... end statement, again eliminating the need for global).\nExplicitly mark x as global inside the local scope before assigning to it, e.g. write global x += 1.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"More explanation can be found in the manual section on soft scope.","category":"page"},{"location":"manual/faq/#Functions","page":"Frequently Asked Questions","title":"Functions","text":"","category":"section"},{"location":"manual/faq/#I-passed-an-argument-x-to-a-function,-modified-it-inside-that-function,-but-on-the-outside,-the-variable-x-is-still-unchanged.-Why?","page":"Frequently Asked Questions","title":"I passed an argument x to a function, modified it inside that function, but on the outside, the variable x is still unchanged. Why?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Suppose you call a function like this:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> x = 10\n10\n\njulia> function change_value!(y)\n y = 17\n end\nchange_value! (generic function with 1 method)\n\njulia> change_value!(x)\n17\n\njulia> x # x is unchanged!\n10","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In Julia, the binding of a variable x cannot be changed by passing x as an argument to a function. When calling change_value!(x) in the above example, y is a newly created variable, bound initially to the value of x, i.e. 10; then y is rebound to the constant 17, while the variable x of the outer scope is left untouched.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"However, if x is bound to an object of type Array (or any other mutable type). From within the function, you cannot \"unbind\" x from this Array, but you can change its content. For example:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> x = [1,2,3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> function change_array!(A)\n A[1] = 5\n end\nchange_array! (generic function with 1 method)\n\njulia> change_array!(x)\n5\n\njulia> x\n3-element Vector{Int64}:\n 5\n 2\n 3","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Here we created a function change_array!, that assigns 5 to the first element of the passed array (bound to x at the call site, and bound to A within the function). Notice that, after the function call, x is still bound to the same array, but the content of that array changed: the variables A and x were distinct bindings referring to the same mutable Array object.","category":"page"},{"location":"manual/faq/#Can-I-use-using-or-import-inside-a-function?","page":"Frequently Asked Questions","title":"Can I use using or import inside a function?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"No, you are not allowed to have a using or import statement inside a function. If you want to import a module but only use its symbols inside a specific function or set of functions, you have two options:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Use import:\nimport Foo\nfunction bar(...)\n # ... refer to Foo symbols via Foo.baz ...\nend\nThis loads the module Foo and defines a variable Foo that refers to the module, but does not import any of the other symbols from the module into the current namespace. You refer to the Foo symbols by their qualified names Foo.bar etc.\nWrap your function in a module:\nmodule Bar\nexport bar\nusing Foo\nfunction bar(...)\n # ... refer to Foo.baz as simply baz ....\nend\nend\nusing Bar\nThis imports all the symbols from Foo, but only inside the module Bar.","category":"page"},{"location":"manual/faq/#What-does-the-...-operator-do?","page":"Frequently Asked Questions","title":"What does the ... operator do?","text":"","category":"section"},{"location":"manual/faq/#The-two-uses-of-the-...-operator:-slurping-and-splatting","page":"Frequently Asked Questions","title":"The two uses of the ... operator: slurping and splatting","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Many newcomers to Julia find the use of ... operator confusing. Part of what makes the ... operator confusing is that it means two different things depending on context.","category":"page"},{"location":"manual/faq/#...-combines-many-arguments-into-one-argument-in-function-definitions","page":"Frequently Asked Questions","title":"... combines many arguments into one argument in function definitions","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In the context of function definitions, the ... operator is used to combine many different arguments into a single argument. This use of ... for combining many different arguments into a single argument is called slurping:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function printargs(args...)\n println(typeof(args))\n for (i, arg) in enumerate(args)\n println(\"Arg #$i = $arg\")\n end\n end\nprintargs (generic function with 1 method)\n\njulia> printargs(1, 2, 3)\nTuple{Int64, Int64, Int64}\nArg #1 = 1\nArg #2 = 2\nArg #3 = 3","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If Julia were a language that made more liberal use of ASCII characters, the slurping operator might have been written as <-... instead of ....","category":"page"},{"location":"manual/faq/#...-splits-one-argument-into-many-different-arguments-in-function-calls","page":"Frequently Asked Questions","title":"... splits one argument into many different arguments in function calls","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In contrast to the use of the ... operator to denote slurping many different arguments into one argument when defining a function, the ... operator is also used to cause a single function argument to be split apart into many different arguments when used in the context of a function call. This use of ... is called splatting:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function threeargs(a, b, c)\n println(\"a = $a::$(typeof(a))\")\n println(\"b = $b::$(typeof(b))\")\n println(\"c = $c::$(typeof(c))\")\n end\nthreeargs (generic function with 1 method)\n\njulia> x = [1, 2, 3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> threeargs(x...)\na = 1::Int64\nb = 2::Int64\nc = 3::Int64","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If Julia were a language that made more liberal use of ASCII characters, the splatting operator might have been written as ...-> instead of ....","category":"page"},{"location":"manual/faq/#What-is-the-return-value-of-an-assignment?","page":"Frequently Asked Questions","title":"What is the return value of an assignment?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The operator = always returns the right-hand side, therefore:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function threeint()\n x::Int = 3.0\n x # returns variable x\n end\nthreeint (generic function with 1 method)\n\njulia> function threefloat()\n x::Int = 3.0 # returns 3.0\n end\nthreefloat (generic function with 1 method)\n\njulia> threeint()\n3\n\njulia> threefloat()\n3.0","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"and similarly:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function twothreetup()\n x, y = [2, 3] # assigns 2 to x and 3 to y\n x, y # returns a tuple\n end\ntwothreetup (generic function with 1 method)\n\njulia> function twothreearr()\n x, y = [2, 3] # returns an array\n end\ntwothreearr (generic function with 1 method)\n\njulia> twothreetup()\n(2, 3)\n\njulia> twothreearr()\n2-element Vector{Int64}:\n 2\n 3","category":"page"},{"location":"manual/faq/#Types,-type-declarations,-and-constructors","page":"Frequently Asked Questions","title":"Types, type declarations, and constructors","text":"","category":"section"},{"location":"manual/faq/#man-type-stability","page":"Frequently Asked Questions","title":"What does \"type-stable\" mean?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"It means that the type of the output is predictable from the types of the inputs. In particular, it means that the type of the output cannot vary depending on the values of the inputs. The following code is not type-stable:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function unstable(flag::Bool)\n if flag\n return 1\n else\n return 1.0\n end\n end\nunstable (generic function with 1 method)","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"It returns either an Int or a Float64 depending on the value of its argument. Since Julia can't predict the return type of this function at compile-time, any computation that uses it must be able to cope with values of both types, which makes it hard to produce fast machine code.","category":"page"},{"location":"manual/faq/#faq-domain-errors","page":"Frequently Asked Questions","title":"Why does Julia give a DomainError for certain seemingly-sensible operations?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Certain operations make mathematical sense but result in errors:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> sqrt(-2.0)\nERROR: DomainError with -2.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This behavior is an inconvenient consequence of the requirement for type-stability. In the case of sqrt, most users want sqrt(2.0) to give a real number, and would be unhappy if it produced the complex number 1.4142135623730951 + 0.0im. One could write the sqrt function to switch to a complex-valued output only when passed a negative number (which is what sqrt does in some other languages), but then the result would not be type-stable and the sqrt function would have poor performance.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In these and other cases, you can get the result you want by choosing an input type that conveys your willingness to accept an output type in which the result can be represented:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> sqrt(-2.0+0im)\n0.0 + 1.4142135623730951im","category":"page"},{"location":"manual/faq/#How-can-I-constrain-or-compute-type-parameters?","page":"Frequently Asked Questions","title":"How can I constrain or compute type parameters?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The parameters of a parametric type can hold either types or bits values, and the type itself chooses how it makes use of these parameters. For example, Array{Float64, 2} is parameterized by the type Float64 to express its element type and the integer value 2 to express its number of dimensions. When defining your own parametric type, you can use subtype constraints to declare that a certain parameter must be a subtype (<:) of some abstract type or a previous type parameter. There is not, however, a dedicated syntax to declare that a parameter must be a value of a given type — that is, you cannot directly declare that a dimensionality-like parameter isa Int within the struct definition, for example. Similarly, you cannot do computations (including simple things like addition or subtraction) on type parameters. Instead, these sorts of constraints and relationships may be expressed through additional type parameters that are computed and enforced within the type's constructors.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As an example, consider","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"struct ConstrainedType{T,N,N+1} # NOTE: INVALID SYNTAX\n A::Array{T,N}\n B::Array{T,N+1}\nend","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"where the user would like to enforce that the third type parameter is always the second plus one. This can be implemented with an explicit type parameter that is checked by an inner constructor method (where it can be combined with other checks):","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"struct ConstrainedType{T,N,M}\n A::Array{T,N}\n B::Array{T,M}\n function ConstrainedType(A::Array{T,N}, B::Array{T,M}) where {T,N,M}\n N + 1 == M || throw(ArgumentError(\"second argument should have one more axis\" ))\n new{T,N,M}(A, B)\n end\nend","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This check is usually costless, as the compiler can elide the check for valid concrete types. If the second argument is also computed, it may be advantageous to provide an outer constructor method that performs this calculation:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"ConstrainedType(A) = ConstrainedType(A, compute_B(A))","category":"page"},{"location":"manual/faq/#faq-integer-arithmetic","page":"Frequently Asked Questions","title":"Why does Julia use native machine integer arithmetic?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia uses machine arithmetic for integer computations. This means that the range of Int values is bounded and wraps around at either end so that adding, subtracting and multiplying integers can overflow or underflow, leading to some results that can be unsettling at first:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> x = typemax(Int)\n9223372036854775807\n\njulia> y = x+1\n-9223372036854775808\n\njulia> z = -y\n-9223372036854775808\n\njulia> 2*z\n0","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Clearly, this is far from the way mathematical integers behave, and you might think it less than ideal for a high-level programming language to expose this to the user. For numerical work where efficiency and transparency are at a premium, however, the alternatives are worse.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"One alternative to consider would be to check each integer operation for overflow and promote results to bigger integer types such as Int128 or BigInt in the case of overflow. Unfortunately, this introduces major overhead on every integer operation (think incrementing a loop counter) – it requires emitting code to perform run-time overflow checks after arithmetic instructions and branches to handle potential overflows. Worse still, this would cause every computation involving integers to be type-unstable. As we mentioned above, type-stability is crucial for effective generation of efficient code. If you can't count on the results of integer operations being integers, it's impossible to generate fast, simple code the way C and Fortran compilers do.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"A variation on this approach, which avoids the appearance of type instability is to merge the Int and BigInt types into a single hybrid integer type, that internally changes representation when a result no longer fits into the size of a machine integer. While this superficially avoids type-instability at the level of Julia code, it just sweeps the problem under the rug by foisting all of the same difficulties onto the C code implementing this hybrid integer type. This approach can be made to work and can even be made quite fast in many cases, but has several drawbacks. One problem is that the in-memory representation of integers and arrays of integers no longer match the natural representation used by C, Fortran and other languages with native machine integers. Thus, to interoperate with those languages, we would ultimately need to introduce native integer types anyway. Any unbounded representation of integers cannot have a fixed number of bits, and thus cannot be stored inline in an array with fixed-size slots – large integer values will always require separate heap-allocated storage. And of course, no matter how clever a hybrid integer implementation one uses, there are always performance traps – situations where performance degrades unexpectedly. Complex representation, lack of interoperability with C and Fortran, the inability to represent integer arrays without additional heap storage, and unpredictable performance characteristics make even the cleverest hybrid integer implementations a poor choice for high-performance numerical work.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"An alternative to using hybrid integers or promoting to BigInts is to use saturating integer arithmetic, where adding to the largest integer value leaves it unchanged and likewise for subtracting from the smallest integer value. This is precisely what Matlab™ does:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":">> int64(9223372036854775807)\n\nans =\n\n 9223372036854775807\n\n>> int64(9223372036854775807) + 1\n\nans =\n\n 9223372036854775807\n\n>> int64(-9223372036854775808)\n\nans =\n\n -9223372036854775808\n\n>> int64(-9223372036854775808) - 1\n\nans =\n\n -9223372036854775808","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"At first blush, this seems reasonable enough since 9223372036854775807 is much closer to 9223372036854775808 than -9223372036854775808 is and integers are still represented with a fixed size in a natural way that is compatible with C and Fortran. Saturated integer arithmetic, however, is deeply problematic. The first and most obvious issue is that this is not the way machine integer arithmetic works, so implementing saturated operations requires emitting instructions after each machine integer operation to check for underflow or overflow and replace the result with typemin(Int) or typemax(Int) as appropriate. This alone expands each integer operation from a single, fast instruction into half a dozen instructions, probably including branches. Ouch. But it gets worse – saturating integer arithmetic isn't associative. Consider this Matlab computation:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":">> n = int64(2)^62\n4611686018427387904\n\n>> n + (n - 1)\n9223372036854775807\n\n>> (n + n) - 1\n9223372036854775806","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This makes it hard to write many basic integer algorithms since a lot of common techniques depend on the fact that machine addition with overflow is associative. Consider finding the midpoint between integer values lo and hi in Julia using the expression (lo + hi) >>> 1:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> n = 2^62\n4611686018427387904\n\njulia> (n + 2n) >>> 1\n6917529027641081856","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"See? No problem. That's the correct midpoint between 2^62 and 2^63, despite the fact that n + 2n is -4611686018427387904. Now try it in Matlab:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":">> (n + 2*n)/2\n\nans =\n\n 4611686018427387904","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Oops. Adding a >>> operator to Matlab wouldn't help, because saturation that occurs when adding n and 2n has already destroyed the information necessary to compute the correct midpoint.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Not only is lack of associativity unfortunate for programmers who cannot rely it for techniques like this, but it also defeats almost anything compilers might want to do to optimize integer arithmetic. For example, since Julia integers use normal machine integer arithmetic, LLVM is free to aggressively optimize simple little functions like f(k) = 5k-1. The machine code for this function is just this:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> code_native(f, Tuple{Int})\n .text\nFilename: none\n pushq %rbp\n movq %rsp, %rbp\nSource line: 1\n leaq -1(%rdi,%rdi,4), %rax\n popq %rbp\n retq\n nopl (%rax,%rax)","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The actual body of the function is a single leaq instruction, which computes the integer multiply and add at once. This is even more beneficial when f gets inlined into another function:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function g(k, n)\n for i = 1:n\n k = f(k)\n end\n return k\n end\ng (generic function with 1 methods)\n\njulia> code_native(g, Tuple{Int,Int})\n .text\nFilename: none\n pushq %rbp\n movq %rsp, %rbp\nSource line: 2\n testq %rsi, %rsi\n jle L26\n nopl (%rax)\nSource line: 3\nL16:\n leaq -1(%rdi,%rdi,4), %rdi\nSource line: 2\n decq %rsi\n jne L16\nSource line: 5\nL26:\n movq %rdi, %rax\n popq %rbp\n retq\n nop","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Since the call to f gets inlined, the loop body ends up being just a single leaq instruction. Next, consider what happens if we make the number of loop iterations fixed:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function g(k)\n for i = 1:10\n k = f(k)\n end\n return k\n end\ng (generic function with 2 methods)\n\njulia> code_native(g,(Int,))\n .text\nFilename: none\n pushq %rbp\n movq %rsp, %rbp\nSource line: 3\n imulq $9765625, %rdi, %rax # imm = 0x9502F9\n addq $-2441406, %rax # imm = 0xFFDABF42\nSource line: 5\n popq %rbp\n retq\n nopw %cs:(%rax,%rax)","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Because the compiler knows that integer addition and multiplication are associative and that multiplication distributes over addition – neither of which is true of saturating arithmetic – it can optimize the entire loop down to just a multiply and an add. Saturated arithmetic completely defeats this kind of optimization since associativity and distributivity can fail at each loop iteration, causing different outcomes depending on which iteration the failure occurs in. The compiler can unroll the loop, but it cannot algebraically reduce multiple operations into fewer equivalent operations.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The most reasonable alternative to having integer arithmetic silently overflow is to do checked arithmetic everywhere, raising errors when adds, subtracts, and multiplies overflow, producing values that are not value-correct. In this blog post, Dan Luu analyzes this and finds that rather than the trivial cost that this approach should in theory have, it ends up having a substantial cost due to compilers (LLVM and GCC) not gracefully optimizing around the added overflow checks. If this improves in the future, we could consider defaulting to checked integer arithmetic in Julia, but for now, we have to live with the possibility of overflow.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In the meantime, overflow-safe integer operations can be achieved through the use of external libraries such as SaferIntegers.jl. Note that, as stated previously, the use of these libraries significantly increases the execution time of code using the checked integer types. However, for limited usage, this is far less of an issue than if it were used for all integer operations. You can follow the status of the discussion here.","category":"page"},{"location":"manual/faq/#What-are-the-possible-causes-of-an-UndefVarError-during-remote-execution?","page":"Frequently Asked Questions","title":"What are the possible causes of an UndefVarError during remote execution?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As the error states, an immediate cause of an UndefVarError on a remote node is that a binding by that name does not exist. Let us explore some of the possible causes.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> module Foo\n foo() = remotecall_fetch(x->x, 2, \"Hello\")\n end\n\njulia> Foo.foo()\nERROR: On worker 2:\nUndefVarError: `Foo` not defined in `Main`\nStacktrace:\n[...]","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The closure x->x carries a reference to Foo, and since Foo is unavailable on node 2, an UndefVarError is thrown.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Globals under modules other than Main are not serialized by value to the remote node. Only a reference is sent. Functions which create global bindings (except under Main) may cause an UndefVarError to be thrown later.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> @everywhere module Foo\n function foo()\n global gvar = \"Hello\"\n remotecall_fetch(()->gvar, 2)\n end\n end\n\njulia> Foo.foo()\nERROR: On worker 2:\nUndefVarError: `gvar` not defined in `Main.Foo`\nStacktrace:\n[...]","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In the above example, @everywhere module Foo defined Foo on all nodes. However the call to Foo.foo() created a new global binding gvar on the local node, but this was not found on node 2 resulting in an UndefVarError error.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Note that this does not apply to globals created under module Main. Globals under module Main are serialized and new bindings created under Main on the remote node.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> gvar_self = \"Node1\"\n\"Node1\"\n\njulia> remotecall_fetch(()->gvar_self, 2)\n\"Node1\"\n\njulia> remotecall_fetch(varinfo, 2)\nname size summary\n––––––––– –––––––– –––––––\nBase Module\nCore Module\nMain Module\ngvar_self 13 bytes String","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This does not apply to function or struct declarations. However, anonymous functions bound to global variables are serialized as can be seen below.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> bar() = 1\nbar (generic function with 1 method)\n\njulia> remotecall_fetch(bar, 2)\nERROR: On worker 2:\nUndefVarError: `#bar` not defined in `Main`\n[...]\n\njulia> anon_bar = ()->1\n(::#21) (generic function with 1 method)\n\njulia> remotecall_fetch(anon_bar, 2)\n1","category":"page"},{"location":"manual/faq/#Troubleshooting-\"method-not-matched\":-parametric-type-invariance-and-MethodErrors","page":"Frequently Asked Questions","title":"Troubleshooting \"method not matched\": parametric type invariance and MethodErrors","text":"","category":"section"},{"location":"manual/faq/#Why-doesn't-it-work-to-declare-foo(bar::Vector{Real})-42-and-then-call-foo([1])?","page":"Frequently Asked Questions","title":"Why doesn't it work to declare foo(bar::Vector{Real}) = 42 and then call foo([1])?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As you'll see if you try this, the result is a MethodError:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> foo(x::Vector{Real}) = 42\nfoo (generic function with 1 method)\n\njulia> foo([1])\nERROR: MethodError: no method matching foo(::Vector{Int64})\nThe function `foo` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n foo(!Matched::Vector{Real})\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This is because Vector{Real} is not a supertype of Vector{Int}! You can solve this problem with something like foo(bar::Vector{T}) where {T<:Real} (or the short form foo(bar::Vector{<:Real}) if the static parameter T is not needed in the body of the function). The T is a wild card: you first specify that it must be a subtype of Real, then specify the function takes a Vector of with elements of that type.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This same issue goes for any composite type Comp, not just Vector. If Comp has a parameter declared of type Y, then another type Comp2 with a parameter of type X<:Y is not a subtype of Comp. This is type-invariance (by contrast, Tuple is type-covariant in its parameters). See Parametric Composite Types for more explanation of these.","category":"page"},{"location":"manual/faq/#Why-does-Julia-use-*-for-string-concatenation?-Why-not-or-something-else?","page":"Frequently Asked Questions","title":"Why does Julia use * for string concatenation? Why not + or something else?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The main argument against + is that string concatenation is not commutative, while + is generally used as a commutative operator. While the Julia community recognizes that other languages use different operators and * may be unfamiliar for some users, it communicates certain algebraic properties.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Note that you can also use string(...) to concatenate strings (and other values converted to strings); similarly, repeat can be used instead of ^ to repeat strings. The interpolation syntax is also useful for constructing strings.","category":"page"},{"location":"manual/faq/#Packages-and-Modules","page":"Frequently Asked Questions","title":"Packages and Modules","text":"","category":"section"},{"location":"manual/faq/#What-is-the-difference-between-\"using\"-and-\"import\"?","page":"Frequently Asked Questions","title":"What is the difference between \"using\" and \"import\"?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"There are several differences between using and import (see the Modules section), but there is an important difference that may not seem intuitive at first glance, and on the surface (i.e. syntax-wise) it may seem very minor. When loading modules with using, you need to say function Foo.bar(... to extend module Foo's function bar with a new method, but with import Foo.bar, you only need to say function bar(... and it automatically extends module Foo's function bar.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The reason this is important enough to have been given separate syntax is that you don't want to accidentally extend a function that you didn't know existed, because that could easily cause a bug. This is most likely to happen with a method that takes a common type like a string or integer, because both you and the other module could define a method to handle such a common type. If you use import, then you'll replace the other module's implementation of bar(s::AbstractString) with your new implementation, which could easily do something completely different (and break all/many future usages of the other functions in module Foo that depend on calling bar).","category":"page"},{"location":"manual/faq/#Nothingness-and-missing-values","page":"Frequently Asked Questions","title":"Nothingness and missing values","text":"","category":"section"},{"location":"manual/faq/#faq-nothing","page":"Frequently Asked Questions","title":"How does \"null\", \"nothingness\" or \"missingness\" work in Julia?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Unlike many languages (for example, C and Java), Julia objects cannot be \"null\" by default. When a reference (variable, object field, or array element) is uninitialized, accessing it will immediately throw an error. This situation can be detected using the isdefined or isassigned functions.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Some functions are used only for their side effects, and do not need to return a value. In these cases, the convention is to return the value nothing, which is just a singleton object of type Nothing. This is an ordinary type with no fields; there is nothing special about it except for this convention, and that the REPL does not print anything for it. Some language constructs that would not otherwise have a value also yield nothing, for example if false; end.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"For situations where a value x of type T exists only sometimes, the Union{T, Nothing} type can be used for function arguments, object fields and array element types as the equivalent of Nullable, Option or Maybe in other languages. If the value itself can be nothing (notably, when T is Any), the Union{Some{T}, Nothing} type is more appropriate since x == nothing then indicates the absence of a value, and x == Some(nothing) indicates the presence of a value equal to nothing. The something function allows unwrapping Some objects and using a default value instead of nothing arguments. Note that the compiler is able to generate efficient code when working with Union{T, Nothing} arguments or fields.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"To represent missing data in the statistical sense (NA in R or NULL in SQL), use the missing object. See the Missing Values section for more details.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In some languages, the empty tuple (()) is considered the canonical form of nothingness. However, in julia it is best thought of as just a regular tuple that happens to contain zero values.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The empty (or \"bottom\") type, written as Union{} (an empty union type), is a type with no values and no subtypes (except itself). You will generally not need to use this type.","category":"page"},{"location":"manual/faq/#Memory","page":"Frequently Asked Questions","title":"Memory","text":"","category":"section"},{"location":"manual/faq/#Why-does-x-y-allocate-memory-when-x-and-y-are-arrays?","page":"Frequently Asked Questions","title":"Why does x += y allocate memory when x and y are arrays?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In Julia, x += y gets replaced during lowering by x = x + y. For arrays, this has the consequence that, rather than storing the result in the same location in memory as x, it allocates a new array to store the result. If you prefer to mutate x, use x .+= y to update each element individually.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"While this behavior might surprise some, the choice is deliberate. The main reason is the presence of immutable objects within Julia, which cannot change their value once created. Indeed, a number is an immutable object; the statements x = 5; x += 1 do not modify the meaning of 5, they modify the value bound to x. For an immutable, the only way to change the value is to reassign it.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"To amplify a bit further, consider the following function:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"function power_by_squaring(x, n::Int)\n ispow2(n) || error(\"This implementation only works for powers of 2\")\n while n >= 2\n x *= x\n n >>= 1\n end\n x\nend","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"After a call like x = 5; y = power_by_squaring(x, 4), you would get the expected result: x == 5 && y == 625. However, now suppose that *=, when used with matrices, instead mutated the left hand side. There would be two problems:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"For general square matrices, A = A*B cannot be implemented without temporary storage: A[1,1] gets computed and stored on the left hand side before you're done using it on the right hand side.\nSuppose you were willing to allocate a temporary for the computation (which would eliminate most of the point of making *= work in-place); if you took advantage of the mutability of x, then this function would behave differently for mutable vs. immutable inputs. In particular, for immutable x, after the call you'd have (in general) y != x, but for mutable x you'd have y == x.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Because supporting generic programming is deemed more important than potential performance optimizations that can be achieved by other means (e.g., using broadcasting or explicit loops), operators like += and *= work by rebinding new values.","category":"page"},{"location":"manual/faq/#faq-async-io","page":"Frequently Asked Questions","title":"Asynchronous IO and concurrent synchronous writes","text":"","category":"section"},{"location":"manual/faq/#Why-do-concurrent-writes-to-the-same-stream-result-in-inter-mixed-output?","page":"Frequently Asked Questions","title":"Why do concurrent writes to the same stream result in inter-mixed output?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"While the streaming I/O API is synchronous, the underlying implementation is fully asynchronous.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Consider the printed output from the following:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> @sync for i in 1:3\n @async write(stdout, string(i), \" Foo \", \" Bar \")\n end\n123 Foo Foo Foo Bar Bar Bar","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This is happening because, while the write call is synchronous, the writing of each argument yields to other tasks while waiting for that part of the I/O to complete.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"print and println \"lock\" the stream during a call. Consequently changing write to println in the above example results in:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> @sync for i in 1:3\n @async println(stdout, string(i), \" Foo \", \" Bar \")\n end\n1 Foo Bar\n2 Foo Bar\n3 Foo Bar","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can lock your writes with a ReentrantLock like this:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> l = ReentrantLock();\n\njulia> @sync for i in 1:3\n @async begin\n lock(l)\n try\n write(stdout, string(i), \" Foo \", \" Bar \")\n finally\n unlock(l)\n end\n end\n end\n1 Foo Bar 2 Foo Bar 3 Foo Bar","category":"page"},{"location":"manual/faq/#Arrays","page":"Frequently Asked Questions","title":"Arrays","text":"","category":"section"},{"location":"manual/faq/#faq-array-0dim","page":"Frequently Asked Questions","title":"What are the differences between zero-dimensional arrays and scalars?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Zero-dimensional arrays are arrays of the form Array{T,0}. They behave similar to scalars, but there are important differences. They deserve a special mention because they are a special case which makes logical sense given the generic definition of arrays, but might be a bit unintuitive at first. The following line defines a zero-dimensional array:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> A = zeros()\n0-dimensional Array{Float64,0}:\n0.0","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In this example, A is a mutable container that contains one element, which can be set by A[] = 1.0 and retrieved with A[]. All zero-dimensional arrays have the same size (size(A) == ()), and length (length(A) == 1). In particular, zero-dimensional arrays are not empty. If you find this unintuitive, here are some ideas that might help to understand Julia's definition.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Zero-dimensional arrays are the \"point\" to vector's \"line\" and matrix's \"plane\". Just as a line has no area (but still represents a set of things), a point has no length or any dimensions at all (but still represents a thing).\nWe define prod(()) to be 1, and the total number of elements in an array is the product of the size. The size of a zero-dimensional array is (), and therefore its length is 1.\nZero-dimensional arrays don't natively have any dimensions into which you index – they’re just A[]. We can apply the same \"trailing one\" rule for them as for all other array dimensionalities, so you can indeed index them as A[1], A[1,1], etc; see Omitted and extra indices.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"It is also important to understand the differences to ordinary scalars. Scalars are not mutable containers (even though they are iterable and define things like length, getindex, e.g. 1[] == 1). In particular, if x = 0.0 is defined as a scalar, it is an error to attempt to change its value via x[] = 1.0. A scalar x can be converted into a zero-dimensional array containing it via fill(x), and conversely, a zero-dimensional array a can be converted to the contained scalar via a[]. Another difference is that a scalar can participate in linear algebra operations such as 2 * rand(2,2), but the analogous operation with a zero-dimensional array fill(2) * rand(2,2) is an error.","category":"page"},{"location":"manual/faq/#Why-are-my-Julia-benchmarks-for-linear-algebra-operations-different-from-other-languages?","page":"Frequently Asked Questions","title":"Why are my Julia benchmarks for linear algebra operations different from other languages?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You may find that simple benchmarks of linear algebra building blocks like","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using BenchmarkTools\nA = randn(1000, 1000)\nB = randn(1000, 1000)\n@btime $A \\ $B\n@btime $A * $B","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"can be different when compared to other languages like Matlab or R.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Since operations like this are very thin wrappers over the relevant BLAS functions, the reason for the discrepancy is very likely to be","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"the BLAS library each language is using,\nthe number of concurrent threads.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia compiles and uses its own copy of OpenBLAS, with threads currently capped at 8 (or the number of your cores).","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg Intel MKL, may provide performance improvements. You can use MKL.jl, a package that makes Julia's linear algebra use Intel MKL BLAS and LAPACK instead of OpenBLAS, or search the discussion forum for suggestions on how to set this up manually. Note that Intel MKL cannot be bundled with Julia, as it is not open source.","category":"page"},{"location":"manual/faq/#Computing-cluster","page":"Frequently Asked Questions","title":"Computing cluster","text":"","category":"section"},{"location":"manual/faq/#How-do-I-manage-precompilation-caches-in-distributed-file-systems?","page":"Frequently Asked Questions","title":"How do I manage precompilation caches in distributed file systems?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"When using Julia in high-performance computing (HPC) facilities with shared filesystems, it is recommended to use a shared depot (via the JULIA_DEPOT_PATH environment variable). Since Julia v1.10, multiple Julia processes on functionally similar workers and using the same depot will coordinate via pidfile locks to only spend effort precompiling on one process while the others wait. The precompilation process will indicate when the process is precompiling or waiting for another that is precompiling. If non-interactive the messages are via @debug.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"However, due to caching of binary code, the cache rejection since v1.9 is more strict and users may need to set the JULIA_CPU_TARGET environment variable appropriately to get a single cache that is usable throughout the HPC environment.","category":"page"},{"location":"manual/faq/#Julia-Releases","page":"Frequently Asked Questions","title":"Julia Releases","text":"","category":"section"},{"location":"manual/faq/#Do-I-want-to-use-the-Stable,-LTS,-or-nightly-version-of-Julia?","page":"Frequently Asked Questions","title":"Do I want to use the Stable, LTS, or nightly version of Julia?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The Stable version of Julia is the latest released version of Julia, this is the version most people will want to run. It has the latest features, including improved performance. The Stable version of Julia is versioned according to SemVer as v1.x.y. A new minor release of Julia corresponding to a new Stable version is made approximately every 4-5 months after a few weeks of testing as a release candidate. Unlike the LTS version the Stable version will not normally receive bugfixes after another Stable version of Julia has been released. However, upgrading to the next Stable release will always be possible as each release of Julia v1.x will continue to run code written for earlier versions.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You may prefer the LTS (Long Term Support) version of Julia if you are looking for a very stable code base. The current LTS version of Julia is versioned according to SemVer as v1.6.x; this branch will continue to receive bugfixes until a new LTS branch is chosen, at which point the v1.6.x series will no longer received regular bug fixes and all but the most conservative users will be advised to upgrade to the new LTS version series. As a package developer, you may prefer to develop for the LTS version, to maximize the number of users who can use your package. As per SemVer, code written for v1.0 will continue to work for all future LTS and Stable versions. In general, even if targeting the LTS, one can develop and run code in the latest Stable version, to take advantage of the improved performance; so long as one avoids using new features (such as added library functions or new methods).","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You may prefer the nightly version of Julia if you want to take advantage of the latest updates to the language, and don't mind if the version available today occasionally doesn't actually work. As the name implies, releases to the nightly version are made roughly every night (depending on build infrastructure stability). In general nightly released are fairly safe to use—your code will not catch on fire. However, they may be occasional regressions and or issues that will not be found until more thorough pre-release testing. You may wish to test against the nightly version to ensure that such regressions that affect your use case are caught before a release is made.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Finally, you may also consider building Julia from source for yourself. This option is mainly for those individuals who are comfortable at the command line, or interested in learning. If this describes you, you may also be interested in reading our guidelines for contributing.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Links to each of these download types can be found on the download page at https://julialang.org/downloads/. Note that not all versions of Julia are available for all platforms.","category":"page"},{"location":"manual/faq/#How-can-I-transfer-the-list-of-installed-packages-after-updating-my-version-of-Julia?","page":"Frequently Asked Questions","title":"How can I transfer the list of installed packages after updating my version of Julia?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Each minor version of julia has its own default environment. As a result, upon installing a new minor version of Julia, the packages you added using the previous minor version will not be available by default. The environment for a given julia version is defined by the files Project.toml and Manifest.toml in a folder matching the version number in .julia/environments/, for instance, .julia/environments/v1.3.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If you install a new minor version of Julia, say 1.4, and want to use in its default environment the same packages as in a previous version (e.g. 1.3), you can copy the contents of the file Project.toml from the 1.3 folder to 1.4. Then, in a session of the new Julia version, enter the \"package management mode\" by typing the key ], and run the command instantiate.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This operation will resolve a set of feasible packages from the copied file that are compatible with the target Julia version, and will install or update them if suitable. If you want to reproduce not only the set of packages, but also the versions you were using in the previous Julia version, you should also copy the Manifest.toml file before running the Pkg command instantiate. However, note that packages may define compatibility constraints that may be affected by changing the version of Julia, so the exact set of versions you had in 1.3 may not work for 1.4.","category":"page"},{"location":"devdocs/eval/#Eval-of-Julia-code","page":"Eval of Julia code","title":"Eval of Julia code","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"One of the hardest parts about learning how the Julia Language runs code is learning how all of the pieces work together to execute a block of code.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Each chunk of code typically makes a trip through many steps with potentially unfamiliar names, such as (in no particular order): flisp, AST, C++, LLVM, eval, typeinf, macroexpand, sysimg (or system image), bootstrapping, compile, parse, execute, JIT, interpret, box, unbox, intrinsic function, and primitive function, before turning into the desired result (hopefully).","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"sidebar: Definitions\nREPL\nREPL stands for Read-Eval-Print Loop. It's just what we call the command line environment for short.\nAST\nAbstract Syntax Tree The AST is the digital representation of the code structure. In this form the code has been tokenized for meaning so that it is more suitable for manipulation and execution.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"(Image: Diagram of the compiler flow)","category":"page"},{"location":"devdocs/eval/#Julia-Execution","page":"Eval of Julia code","title":"Julia Execution","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The 10,000 foot view of the whole process is as follows:","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The user starts julia.\nThe C function main() from cli/loader_exe.c gets called. This function processes the command line arguments, filling in the jl_options struct and setting the variable ARGS. It then initializes Julia (by calling julia_init in init.c, which may load a previously compiled sysimg). Finally, it passes off control to Julia by calling Base._start().\nWhen _start() takes over control, the subsequent sequence of commands depends on the command line arguments given. For example, if a filename was supplied, it will proceed to execute that file. Otherwise, it will start an interactive REPL.\nSkipping the details about how the REPL interacts with the user, let's just say the program ends up with a block of code that it wants to run.\nIf the block of code to run is in a file, jl_load(char *filename) gets invoked to load the file and parse it. Each fragment of code is then passed to eval to execute.\nEach fragment of code (or AST), is handed off to eval() to turn into results.\neval() takes each code fragment and tries to run it in jl_toplevel_eval_flex().\njl_toplevel_eval_flex() decides whether the code is a \"toplevel\" action (such as using or module), which would be invalid inside a function. If so, it passes off the code to the toplevel interpreter.\njl_toplevel_eval_flex() then expands the code to eliminate any macros and to \"lower\" the AST to make it simpler to execute.\njl_toplevel_eval_flex() then uses some simple heuristics to decide whether to JIT compile the AST or to interpret it directly.\nThe bulk of the work to interpret code is handled by eval in interpreter.c.\nIf instead, the code is compiled, the bulk of the work is handled by codegen.cpp. Whenever a Julia function is called for the first time with a given set of argument types, type inference will be run on that function. This information is used by the codegen step to generate faster code.\nEventually, the user quits the REPL, or the end of the program is reached, and the _start() method returns.\nJust before exiting, main() calls jl_atexit_hook(exit_code). This calls Base._atexit() (which calls any functions registered to atexit() inside Julia). Then it calls jl_gc_run_all_finalizers(). Finally, it gracefully cleans up all libuv handles and waits for them to flush and close.","category":"page"},{"location":"devdocs/eval/#dev-parsing","page":"Eval of Julia code","title":"Parsing","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The Julia parser is a small lisp program written in femtolisp, the source-code for which is distributed inside Julia in src/flisp.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The interface functions for this are primarily defined in jlfrontend.scm. The code in ast.c handles this handoff on the Julia side.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The other relevant files at this stage are julia-parser.scm, which handles tokenizing Julia code and turning it into an AST, and julia-syntax.scm, which handles transforming complex AST representations into simpler, \"lowered\" AST representations which are more suitable for analysis and execution.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"If you want to test the parser without re-building Julia in its entirety, you can run the frontend on its own as follows:","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"$ cd src\n$ flisp/flisp\n> (load \"jlfrontend.scm\")\n> (jl-parse-file \"\")","category":"page"},{"location":"devdocs/eval/#dev-macro-expansion","page":"Eval of Julia code","title":"Macro Expansion","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"When eval() encounters a macro, it expands that AST node before attempting to evaluate the expression. Macro expansion involves a handoff from eval() (in Julia), to the parser function jl_macroexpand() (written in flisp) to the Julia macro itself (written in - what else - Julia) via fl_invoke_julia_macro(), and back.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Typically, macro expansion is invoked as a first step during a call to Meta.lower()/jl_expand(), although it can also be invoked directly by a call to macroexpand()/jl_macroexpand().","category":"page"},{"location":"devdocs/eval/#dev-type-inference","page":"Eval of Julia code","title":"Type Inference","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Type inference is implemented in Julia by typeinf() in compiler/typeinfer.jl. Type inference is the process of examining a Julia function and determining bounds for the types of each of its variables, as well as bounds on the type of the return value from the function. This enables many future optimizations, such as unboxing of known immutable values, and compile-time hoisting of various run-time operations such as computing field offsets and function pointers. Type inference may also include other steps such as constant propagation and inlining.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"sidebar: More Definitions\nJIT\nJust-In-Time Compilation The process of generating native-machine code into memory right when it is needed.\nLLVM\nLow-Level Virtual Machine (a compiler) The Julia JIT compiler is a program/library called libLLVM. Codegen in Julia refers both to the process of taking a Julia AST and turning it into LLVM instructions, and the process of LLVM optimizing that and turning it into native assembly instructions.\nC++\nThe programming language that LLVM is implemented in, which means that codegen is also implemented in this language. The rest of Julia's library is implemented in C, in part because its smaller feature set makes it more usable as a cross-language interface layer.\nbox\nThis term is used to describe the process of taking a value and allocating a wrapper around the data that is tracked by the garbage collector (gc) and is tagged with the object's type.\nunbox\nThe reverse of boxing a value. This operation enables more efficient manipulation of data when the type of that data is fully known at compile-time (through type inference).\ngeneric function\nA Julia function composed of multiple \"methods\" that are selected for dynamic dispatch based on the argument type-signature\nanonymous function or \"method\"\nA Julia function without a name and without type-dispatch capabilities\nprimitive function\nA function implemented in C but exposed in Julia as a named function \"method\" (albeit without generic function dispatch capabilities, similar to a anonymous function)\nintrinsic function\nA low-level operation exposed as a function in Julia. These pseudo-functions implement operations on raw bits such as add and sign extend that cannot be expressed directly in any other way. Since they operate on bits directly, they must be compiled into a function and surrounded by a call to Core.Intrinsics.box(T, ...) to reassign type information to the value.","category":"page"},{"location":"devdocs/eval/#dev-codegen","page":"Eval of Julia code","title":"JIT Code Generation","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Codegen is the process of turning a Julia AST into native machine code.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The JIT environment is initialized by an early call to jl_init_codegen in codegen.cpp.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"On demand, a Julia method is converted into a native function by the function emit_function(jl_method_instance_t*). (note, when using the MCJIT (in LLVM v3.4+), each function must be JIT into a new module.) This function recursively calls emit_expr() until the entire function has been emitted.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Much of the remaining bulk of this file is devoted to various manual optimizations of specific code patterns. For example, emit_known_call() knows how to inline many of the primitive functions (defined in builtins.c) for various combinations of argument types.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Other parts of codegen are handled by various helper files:","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"debuginfo.cpp\nHandles backtraces for JIT functions\nccall.cpp\nHandles the ccall and llvmcall FFI, along with various abi_*.cpp files\nintrinsics.cpp\nHandles the emission of various low-level intrinsic functions","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"sidebar: Bootstrapping\nThe process of creating a new system image is called \"bootstrapping\".The etymology of this word comes from the phrase \"pulling oneself up by the bootstraps\", and refers to the idea of starting from a very limited set of available functions and definitions and ending with the creation of a full-featured environment.","category":"page"},{"location":"devdocs/eval/#dev-sysimg","page":"Eval of Julia code","title":"System Image","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The system image is a precompiled archive of a set of Julia files. The sys.ji file distributed with Julia is one such system image, generated by executing the file sysimg.jl, and serializing the resulting environment (including Types, Functions, Modules, and all other defined values) into a file. Therefore, it contains a frozen version of the Main, Core, and Base modules (and whatever else was in the environment at the end of bootstrapping). This serializer/deserializer is implemented by jl_save_system_image/jl_restore_system_image in staticdata.c.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"If there is no sysimg file (jl_options.image_file == NULL), this also implies that --build was given on the command line, so the final result should be a new sysimg file. During Julia initialization, minimal Core and Main modules are created. Then a file named boot.jl is evaluated from the current directory. Julia then evaluates any file given as a command line argument until it reaches the end. Finally, it saves the resulting environment to a \"sysimg\" file for use as a starting point for a future Julia run.","category":"page"},{"location":"devdocs/gc-sa/#Static-analyzer-annotations-for-GC-correctness-in-C-code","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"","category":"section"},{"location":"devdocs/gc-sa/#Running-the-analysis","page":"Static analyzer annotations for GC correctness in C code","title":"Running the analysis","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The analyzer plugin that drives the analysis ships with julia. Its source code can be found in src/clangsa. Running it requires the clang dependency to be build. Set the BUILD_LLVM_CLANG variable in your Make.user in order to build an appropriate version of clang. You may also want to use the prebuilt binaries using the USE_BINARYBUILDER_LLVM options.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Alternatively (or if these do not suffice), try","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"make -C src install-analysis-deps","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"from Julia's toplevel directory.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Afterwards, running the analysis over the source tree is as simple as running make -C src analyzegc.","category":"page"},{"location":"devdocs/gc-sa/#General-Overview","page":"Static analyzer annotations for GC correctness in C code","title":"General Overview","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Since Julia's GC is precise, it needs to maintain correct rooting information for any value that may be referenced at any time GC may occur. These places are known as safepoints and in the function local context, we extend this designation to any function call that may recursively end up at a safepoint.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"In generated code, this is taken care of automatically by the GC root placement pass (see the chapter on GC rooting in the LLVM codegen devdocs). However, in C code, we need to inform the runtime of any GC roots manually. This is done using the following macros:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"// The value assigned to any slot passed as an argument to these\n// is rooted for the duration of this GC frame.\nJL_GC_PUSH{1,...,6}(args...)\n// The values assigned into the size `n` array `rts` are rooted\n// for the duration of this GC frame.\nJL_GC_PUSHARGS(rts, n)\n// Pop a GC frame\nJL_GC_POP","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"If these macros are not used where they need to be, or they are used incorrectly, the result is silent memory corruption. As such it is very important that they are placed correctly in all applicable code.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"As such, we employ static analysis (and in particular the clang static analyzer) to help ensure that these macros are used correctly. The remainder of this document gives an overview of this static analysis and describes the support needed in the julia code base to make things work.","category":"page"},{"location":"devdocs/gc-sa/#GC-Invariants","page":"Static analyzer annotations for GC correctness in C code","title":"GC Invariants","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"There is two simple invariants correctness:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"All GC_PUSH calls need to be followed by an appropriate GC_POP (in practice we enforce this at the function level)\nIf a value was previously not rooted at any safepoint, it may no longer be referenced afterwards","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Of course the devil is in the details here. In particular to satisfy the second of the above conditions, we need to know:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Which calls are safepoints and which are not\nWhich values are rooted at any given safepoint and which are not\nWhen is a value referenced","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"For the second point in particular, we need to know which memory locations will be considered rooting at runtime (i.e. values assigned to such locations are rooted). This includes locations explicitly designated as such by passing them to one of the GC_PUSH macros, globally rooted locations and values, as well as any location recursively reachable from one of those locations.","category":"page"},{"location":"devdocs/gc-sa/#Static-Analysis-Algorithm","page":"Static analyzer annotations for GC correctness in C code","title":"Static Analysis Algorithm","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The idea itself is very simple, although the implementation is quite a bit more complicated (mainly due to a large number of special cases and intricacies of C and C++). In essence, we keep track of all locations that are rooting, all values that are rootable and any expression (assignments, allocations, etc) affect the rootedness of any rootable values. Then, at any safepoint, we perform a \"symbolic GC\" and poison any values that are not rooted at said location. If these values are later referenced, we emit an error.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The clang static analyzer works by constructing a graph of states and exploring this graph for sources of errors. Several nodes in this graph are generated by the analyzer itself (e.g. for control flow), but the definitions above augment this graph with our own state.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The static analyzer is interprocedural and can analyze control flow across function boundaries. However, the static analyzer is not fully recursive and makes heuristic decisions about which calls to explore (additionally some calls are cross-translation unit and invisible to the analyzer). In our case, our definition of correctness requires total information. As such, we need to annotate the prototypes of all function calls with whatever information the analysis required, even if that information would otherwise be available by interprocedural static analysis.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Luckily however, we can still use this interprocedural analysis to ensure that the annotations we place on a given function are indeed correct given the implementation of said function.","category":"page"},{"location":"devdocs/gc-sa/#The-analyzer-annotations","page":"Static analyzer annotations for GC correctness in C code","title":"The analyzer annotations","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"These annotations are found in src/support/analyzer_annotations.h. The are only active when the analyzer is being used and expand either to nothing (for prototype annotations) or to no-ops (for function like annotations).","category":"page"},{"location":"devdocs/gc-sa/#JL_NOTSAFEPOINT","page":"Static analyzer annotations for GC correctness in C code","title":"JL_NOTSAFEPOINT","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This is perhaps the most common annotation, and should be placed on any function that is known not to possibly lead to reaching a GC safepoint. In general, it is only safe for such a function to perform arithmetic, memory accesses and calls to functions either annotated JL_NOTSAFEPOINT or otherwise known not to be safepoints (e.g. function in the C standard library, which are hardcoded as such in the analyzer)","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"It is valid to keep values unrooted across calls to any function annotated with this attribute:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage Example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void jl_get_one() JL_NOTSAFEPOINT {\n return 1;\n}\n\njl_value_t *example() {\n jl_value_t *val = jl_alloc_whatever();\n // This is valid, even though `val` is unrooted, because\n // jl_get_one is not a safepoint\n jl_get_one();\n return val;\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY","page":"Static analyzer annotations for GC correctness in C code","title":"JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"When JL_MAYBE_UNROOTED is annotated as an argument on a function, indicates that said argument may be passed, even if it is not rooted. In the ordinary course of events, the julia ABI guarantees that callers root values before passing them to callees. However, some functions do not follow this ABI and allow values to be passed to them even though they are not rooted. Note however, that this does not automatically imply that said argument will be preserved. The ROOTS_TEMPORARILY annotation provides the stronger guarantee that, not only may the value be unrooted when passed, it will also be preserved across any internal safepoints by the callee.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Note that JL_NOTSAFEPOINT essentially implies JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY, because the rootedness of an argument is irrelevant if the function contains no safepoints.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"One additional point to note is that these annotations apply on both the caller and the callee side. On the caller side, they lift rootedness restrictions that are normally required for julia ABI functions. On the callee side, they have the reverse effect of preventing these arguments from being considered implicitly rooted.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"If either of these annotations is applied to the function as a whole, it applies to all arguments of the function. This should generally only be necessary for varargs functions.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"JL_DLLEXPORT void JL_NORETURN jl_throw(jl_value_t *e JL_MAYBE_UNROOTED);\njl_value_t *jl_alloc_error();\n\nvoid example() {\n // The return value of the allocation is unrooted. This would normally\n // be an error, but is allowed because of the above annotation.\n jl_throw(jl_alloc_error());\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_PROPAGATES_ROOT","page":"Static analyzer annotations for GC correctness in C code","title":"JL_PROPAGATES_ROOT","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotation is commonly found on accessor functions that return one rootable object stored within another. When annotated on a function argument, it tells the analyzer that the root for that argument also applies to the value returned by the function.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage Example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"jl_value_t *jl_svecref(jl_svec_t *t JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT;\n\nsize_t example(jl_svec_t *svec) {\n jl_value_t *val = jl_svecref(svec, 1)\n // This is valid, because, as annotated by the PROPAGATES_ROOT annotation,\n // jl_svecref propagates the rooted-ness from `svec` to `val`\n jl_gc_safepoint();\n return jl_unbox_long(val);\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_ROOTING_ARGUMENT/JL_ROOTED_ARGUMENT","page":"Static analyzer annotations for GC correctness in C code","title":"JL_ROOTING_ARGUMENT/JL_ROOTED_ARGUMENT","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This is essentially the assignment counterpart to JL_PROPAGATES_ROOT. When assigning a value to a field of another value that is already rooted, the assigned value will inherit the root of the value it is assigned into.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage Example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void jl_svecset(void *t JL_ROOTING_ARGUMENT, size_t i, void *x JL_ROOTED_ARGUMENT) JL_NOTSAFEPOINT\n\n\nsize_t example(jl_svec_t *svec) {\n jl_value_t *val = jl_box_long(10000);\n jl_svecset(svec, val);\n // This is valid, because the annotations imply that the\n // jl_svecset propagates the rooted-ness from `svec` to `val`\n jl_gc_safepoint();\n return jl_unbox_long(val);\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_GC_DISABLED","page":"Static analyzer annotations for GC correctness in C code","title":"JL_GC_DISABLED","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotation implies that this function is only called with the GC runtime-disabled. Functions of this kind are most often encountered during startup and in the GC code itself. Note that this annotation is checked against the runtime enable/disable calls, so clang will know if you lie. This is not a good way to disable processing of a given function if the GC is not actually disabled (use ifdef __clang_analyzer__ for that if you must).","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void jl_do_magic() JL_GC_DISABLED {\n // Wildly allocate here with no regard for roots\n}\n\nvoid example() {\n int en = jl_gc_enable(0);\n jl_do_magic();\n jl_gc_enable(en);\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_REQUIRE_ROOTED_SLOT","page":"Static analyzer annotations for GC correctness in C code","title":"JL_REQUIRE_ROOTED_SLOT","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotation requires the caller to pass in a slot that is rooted (i.e. values assigned to this slot will be rooted).","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void jl_do_processing(jl_value_t **slot JL_REQUIRE_ROOTED_SLOT) {\n *slot = jl_box_long(1);\n // Ok, only, because the slot was annotated as rooting\n jl_gc_safepoint();\n}\n\nvoid example() {\n jl_value_t *slot = NULL;\n JL_GC_PUSH1(&slot);\n jl_do_processing(&slot);\n JL_GC_POP();\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_GLOBALLY_ROOTED","page":"Static analyzer annotations for GC correctness in C code","title":"JL_GLOBALLY_ROOTED","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotation implies that a given value is always globally rooted. It can be applied to global variable declarations, in which case it will apply to the value of those variables (or values if the declaration if for an array), or to functions, in which case it will apply to the return value of such functions (e.g. for functions that always return some private, globally rooted value).","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"extern JL_DLLEXPORT jl_datatype_t *jl_any_type JL_GLOBALLY_ROOTED;\njl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED;","category":"page"},{"location":"devdocs/gc-sa/#JL_ALWAYS_LEAFTYPE","page":"Static analyzer annotations for GC correctness in C code","title":"JL_ALWAYS_LEAFTYPE","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that is should only be used if those values are globally rooted by virtue of being a leaftype. The rooting of leaftypes is a bit complicated. They are generally rooted through cache field of the corresponding TypeName, which itself is rooted by the containing module (so they're rooted as long as the containing module is ok) and we can generally assume that leaftypes are rooted where they are used, but we may refine this property in the future, so the separate annotation helps split out the reason for being globally rooted.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The analyzer also automatically detects checks for leaftype-ness and will not complain about missing GC roots on these paths.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"JL_DLLEXPORT jl_value_t *jl_apply_array_type(jl_value_t *type, size_t dim) JL_ALWAYS_LEAFTYPE;","category":"page"},{"location":"devdocs/gc-sa/#JL_GC_PROMISE_ROOTED","page":"Static analyzer annotations for GC correctness in C code","title":"JL_GC_PROMISE_ROOTED","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This is a function-like annotation. Any value passed to this annotation will be considered rooted for the scope of the current function. It is designed as an escape hatch for analyzer inadequacy or complicated situations. However, it should be used sparingly, in favor of improving the analyzer itself.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void example() {\n jl_value_t *val = jl_alloc_something();\n if (some_condition) {\n // We happen to know for complicated external reasons\n // that val is rooted under these conditions\n JL_GC_PROMISE_ROOTED(val);\n }\n}","category":"page"},{"location":"devdocs/gc-sa/#Completeness-of-analysis","page":"Static analyzer annotations for GC correctness in C code","title":"Completeness of analysis","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The analyzer only looks at local information. In particular, e.g. in the PROPAGATES_ROOT case above, it assumes that such memory is only modified in ways it can see, not in any called functions (unless it happens to decide to consider them in its analysis) and not in any concurrently running threads. As such, it may miss a few problematic cases, though in practice such concurrent modification is fairly rare. Improving the analyzer to handle more such cases may be an interesting topic for future work.","category":"page"},{"location":"devdocs/llvm/#Working-with-LLVM","page":"Working with LLVM","title":"Working with LLVM","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"This is not a replacement for the LLVM documentation, but a collection of tips for working on LLVM for Julia.","category":"page"},{"location":"devdocs/llvm/#Overview-of-Julia-to-LLVM-Interface","page":"Working with LLVM","title":"Overview of Julia to LLVM Interface","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Julia dynamically links against LLVM by default. Build with USE_LLVM_SHLIB=0 to link statically.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The code for lowering Julia AST to LLVM IR or interpreting it directly is in directory src/.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"File Description\naotcompile.cpp Compiler C-interface entry and object file emission\nbuiltins.c Builtin functions\nccall.cpp Lowering ccall\ncgutils.cpp Lowering utilities, notably for array and tuple accesses\ncodegen.cpp Top-level of code generation, pass list, lowering builtins\ndebuginfo.cpp Tracks debug information for JIT code\ndisasm.cpp Handles native object file and JIT code diassembly\ngf.c Generic functions\nintrinsics.cpp Lowering intrinsics\njitlayers.cpp JIT-specific code, ORC compilation layers/utilities\nllvm-alloc-helpers.cpp Julia-specific escape analysis\nllvm-alloc-opt.cpp Custom LLVM pass to demote heap allocations to the stack\nllvm-cpufeatures.cpp Custom LLVM pass to lower CPU-based functions (e.g. haveFMA)\nllvm-demote-float16.cpp Custom LLVM pass to lower 16b float ops to 32b float ops\nllvm-final-gc-lowering.cpp Custom LLVM pass to lower GC calls to their final form\nllvm-gc-invariant-verifier.cpp Custom LLVM pass to verify Julia GC invariants\nllvm-julia-licm.cpp Custom LLVM pass to hoist/sink Julia-specific intrinsics\nllvm-late-gc-lowering.cpp Custom LLVM pass to root GC-tracked values\nllvm-lower-handlers.cpp Custom LLVM pass to lower try-catch blocks\nllvm-muladd.cpp Custom LLVM pass for fast-match FMA\nllvm-multiversioning.cpp Custom LLVM pass to generate sysimg code on multiple architectures\nllvm-propagate-addrspaces.cpp Custom LLVM pass to canonicalize addrspaces\nllvm-ptls.cpp Custom LLVM pass to lower TLS operations\nllvm-remove-addrspaces.cpp Custom LLVM pass to remove Julia addrspaces\nllvm-remove-ni.cpp Custom LLVM pass to remove Julia non-integral addrspaces\nllvm-simdloop.cpp Custom LLVM pass for @simd\npipeline.cpp New pass manager pipeline, pass pipeline parsing\nsys.c I/O and operating system utility functions","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Some of the .cpp files form a group that compile to a single object.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The difference between an intrinsic and a builtin is that a builtin is a first class function that can be used like any other Julia function. An intrinsic can operate only on unboxed data, and therefore its arguments must be statically typed.","category":"page"},{"location":"devdocs/llvm/#LLVM-Alias-Analysis","page":"Working with LLVM","title":"Alias Analysis","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Julia currently uses LLVM's Type Based Alias Analysis. To find the comments that document the inclusion relationships, look for static MDNode* in src/codegen.cpp.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The -O option enables LLVM's Basic Alias Analysis.","category":"page"},{"location":"devdocs/llvm/#Building-Julia-with-a-different-version-of-LLVM","page":"Working with LLVM","title":"Building Julia with a different version of LLVM","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The default version of LLVM is specified in deps/llvm.version. You can override it by creating a file called Make.user in the top-level directory and adding a line to it such as:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"LLVM_VER = 13.0.0","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Besides the LLVM release numerals, you can also use DEPS_GIT = llvm in combination with USE_BINARYBUILDER_LLVM = 0 to build against the latest development version of LLVM.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"You can also specify to build a debug version of LLVM, by setting either LLVM_DEBUG = 1 or LLVM_DEBUG = Release in your Make.user file. The former will be a fully unoptimized build of LLVM and the latter will produce an optimized build of LLVM. Depending on your needs the latter will suffice and it quite a bit faster. If you use LLVM_DEBUG = Release you will also want to set LLVM_ASSERTIONS = 1 to enable diagnostics for different passes. Only LLVM_DEBUG = 1 implies that option by default.","category":"page"},{"location":"devdocs/llvm/#Passing-options-to-LLVM","page":"Working with LLVM","title":"Passing options to LLVM","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"You can pass options to LLVM via the environment variable JULIA_LLVM_ARGS. Here are example settings using bash syntax:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"export JULIA_LLVM_ARGS=-print-after-all dumps IR after each pass.\nexport JULIA_LLVM_ARGS=-debug-only=loop-vectorize dumps LLVM DEBUG(...) diagnostics for loop vectorizer. If you get warnings about \"Unknown command line argument\", rebuild LLVM with LLVM_ASSERTIONS = 1.\nexport JULIA_LLVM_ARGS=-help shows a list of available options. export JULIA_LLVM_ARGS=-help-hidden shows even more.\nexport JULIA_LLVM_ARGS=\"-fatal-warnings -print-options\" is an example how to use multiple options.","category":"page"},{"location":"devdocs/llvm/#Useful-JULIA_LLVM_ARGS-parameters","page":"Working with LLVM","title":"Useful JULIA_LLVM_ARGS parameters","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"-print-after=PASS: prints the IR after any execution of PASS, useful for checking changes done by a pass.\n-print-before=PASS: prints the IR before any execution of PASS, useful for checking the input to a pass.\n-print-changed: prints the IR whenever a pass changes the IR, useful for narrowing down which passes are causing problems.\n-print-(before|after)=MARKER-PASS: the Julia pipeline ships with a number of marker passes in the pipeline, which can be used to identify where problems or optimizations are occurring. A marker pass is defined as a pass which appears once in the pipeline and performs no transformations on the IR, and is only useful for targeting print-before/print-after. Currently, the following marker passes exist in the pipeline:\nBeforeOptimization\nBeforeEarlySimplification\nAfterEarlySimplification\nBeforeEarlyOptimization\nAfterEarlyOptimization\nBeforeLoopOptimization\nBeforeLICM\nAfterLICM\nBeforeLoopSimplification\nAfterLoopSimplification\nAfterLoopOptimization\nBeforeScalarOptimization\nAfterScalarOptimization\nBeforeVectorization\nAfterVectorization\nBeforeIntrinsicLowering\nAfterIntrinsicLowering\nBeforeCleanup\nAfterCleanup\nAfterOptimization\n-time-passes: prints the time spent in each pass, useful for identifying which passes are taking a long time.\n-print-module-scope: used in conjunction with -print-(before|after), gets the entire module rather than the IR unit received by the pass\n-debug: prints out a lot of debugging information throughout LLVM\n-debug-only=NAME, prints out debugging statements from files with DEBUG_TYPE defined to NAME, useful for getting additional context about a problem","category":"page"},{"location":"devdocs/llvm/#Debugging-LLVM-transformations-in-isolation","page":"Working with LLVM","title":"Debugging LLVM transformations in isolation","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"On occasion, it can be useful to debug LLVM's transformations in isolation from the rest of the Julia system, e.g. because reproducing the issue inside julia would take too long, or because one wants to take advantage of LLVM's tooling (e.g. bugpoint).","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"To start with, you can install the developer tools to work with LLVM via:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"make -C deps install-llvm-tools","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"To get unoptimized IR for the entire system image, pass the --output-unopt-bc unopt.bc option to the system image build process, which will output the unoptimized IR to an unopt.bc file. This file can then be passed to LLVM tools as usual. libjulia can function as an LLVM pass plugin and can be loaded into LLVM tools, to make julia-specific passes available in this environment. In addition, it exposes the -julia meta-pass, which runs the entire Julia pass-pipeline over the IR. As an example, to generate a system image with the old pass manager, one could do:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"\nllc -o sys.o opt.bc\ncc -shared -o sys.so sys.o","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"To generate a system image with the new pass manager, one could do:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"opt -load-pass-plugin=libjulia-codegen.so --passes='julia' -o opt.bc unopt.bc\nllc -o sys.o opt.bc\ncc -shared -o sys.so sys.o","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"This system image can then be loaded by julia as usual.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"It is also possible to dump an LLVM IR module for just one Julia function, using:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"fun, T = +, Tuple{Int,Int} # Substitute your function of interest here\noptimize = false\nopen(\"plus.ll\", \"w\") do file\n println(file, InteractiveUtils._dump_function(fun, T, false, false, false, true, :att, optimize, :default, false))\nend","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"These files can be processed the same way as the unoptimized sysimg IR shown above.","category":"page"},{"location":"devdocs/llvm/#Running-the-LLVM-test-suite","page":"Working with LLVM","title":"Running the LLVM test suite","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"To run the llvm tests locally, you need to first install the tools, build julia, then you can run the tests:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"make -C deps install-llvm-tools\nmake -j julia-src-release\nmake -C test/llvmpasses","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"If you want to run the individual test files directly, via the commands at the top of each test file, the first step here will have installed the tools into ./usr/tools/opt. Then you'll want to manually replace %s with the name of the test file.","category":"page"},{"location":"devdocs/llvm/#Improving-LLVM-optimizations-for-Julia","page":"Working with LLVM","title":"Improving LLVM optimizations for Julia","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Improving LLVM code generation usually involves either changing Julia lowering to be more friendly to LLVM's passes, or improving a pass.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"If you are planning to improve a pass, be sure to read the LLVM developer policy. The best strategy is to create a code example in a form where you can use LLVM's opt tool to study it and the pass of interest in isolation.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Create an example Julia code of interest.\nUse JULIA_LLVM_ARGS=-print-after-all to dump the IR.\nPick out the IR at the point just before the pass of interest runs.\nStrip the debug metadata and fix up the TBAA metadata by hand.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The last step is labor intensive. Suggestions on a better way would be appreciated.","category":"page"},{"location":"devdocs/llvm/#The-jlcall-calling-convention","page":"Working with LLVM","title":"The jlcall calling convention","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Julia has a generic calling convention for unoptimized code, which looks somewhat as follows:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"jl_value_t *any_unoptimized_call(jl_value_t *, jl_value_t **, int);","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"where the first argument is the boxed function object, the second argument is an on-stack array of arguments and the third is the number of arguments. Now, we could perform a straightforward lowering and emit an alloca for the argument array. However, this would betray the SSA nature of the uses at the call site, making optimizations (including GC root placement), significantly harder. Instead, we emit it as follows:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"call %jl_value_t *@julia.call(jl_value_t *(*)(...) @any_unoptimized_call, %jl_value_t *%arg1, %jl_value_t *%arg2)","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"This allows us to retain the SSA-ness of the uses throughout the optimizer. GC root placement will later lower this call to the original C ABI.","category":"page"},{"location":"devdocs/llvm/#GC-root-placement","page":"Working with LLVM","title":"GC root placement","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"GC root placement is done by an LLVM pass late in the pass pipeline. Doing GC root placement this late enables LLVM to make more aggressive optimizations around code that requires GC roots, as well as allowing us to reduce the number of required GC roots and GC root store operations (since LLVM doesn't understand our GC, it wouldn't otherwise know what it is and is not allowed to do with values stored to the GC frame, so it'll conservatively do very little). As an example, consider an error path","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"if some_condition()\n #= Use some variables maybe =#\n error(\"An error occurred\")\nend","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"During constant folding, LLVM may discover that the condition is always false, and can remove the basic block. However, if GC root lowering is done early, the GC root slots used in the deleted block, as well as any values kept alive in those slots only because they were used in the error path, would be kept alive by LLVM. By doing GC root lowering late, we give LLVM the license to do any of its usual optimizations (constant folding, dead code elimination, etc.), without having to worry (too much) about which values may or may not be GC tracked.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"However, in order to be able to do late GC root placement, we need to be able to identify a) which pointers are GC tracked and b) all uses of such pointers. The goal of the GC placement pass is thus simple:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Minimize the number of needed GC roots/stores to them subject to the constraint that at every safepoint, any live GC-tracked pointer (i.e. for which there is a path after this point that contains a use of this pointer) is in some GC slot.","category":"page"},{"location":"devdocs/llvm/#Representation","page":"Working with LLVM","title":"Representation","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The primary difficulty is thus choosing an IR representation that allows us to identify GC-tracked pointers and their uses, even after the program has been run through the optimizer. Our design makes use of three LLVM features to achieve this:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Custom address spaces\nOperand Bundles\nNon-integral pointers","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Custom address spaces allow us to tag every point with an integer that needs to be preserved through optimizations. The compiler may not insert casts between address spaces that did not exist in the original program and it must never change the address space of a pointer on a load/store/etc operation. This allows us to annotate which pointers are GC-tracked in an optimizer-resistant way. Note that metadata would not be able to achieve the same purpose. Metadata is supposed to always be discardable without altering the semantics of the program. However, failing to identify a GC-tracked pointer alters the resulting program behavior dramatically - it'll probably crash or return wrong results. We currently use three different address spaces (their numbers are defined in src/codegen_shared.cpp):","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"GC Tracked Pointers (currently 10): These are pointers to boxed values that may be put into a GC frame. It is loosely equivalent to a jl_value_t* pointer on the C side. N.B. It is illegal to ever have a pointer in this address space that may not be stored to a GC slot.\nDerived Pointers (currently 11): These are pointers that are derived from some GC tracked pointer. Uses of these pointers generate uses of the original pointer. However, they need not themselves be known to the GC. The GC root placement pass MUST always find the GC tracked pointer from which this pointer is derived and use that as the pointer to root.\nCallee Rooted Pointers (currently 12): This is a utility address space to express the notion of a callee rooted value. All values of this address space MUST be storable to a GC root (though it is possible to relax this condition in the future), but unlike the other pointers need not be rooted if passed to a call (they do still need to be rooted if they are live across another safepoint between the definition and the call).\nPointers loaded from tracked object (currently 13): This is used by arrays, which themselves contain a pointer to the managed data. This data area is owned by the array, but is not a GC-tracked object by itself. The compiler guarantees that as long as this pointer is live, the object that this pointer was loaded from will keep being live.","category":"page"},{"location":"devdocs/llvm/#Invariants","page":"Working with LLVM","title":"Invariants","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The GC root placement pass makes use of several invariants, which need to be observed by the frontend and are preserved by the optimizer.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"First, only the following address space casts are allowed:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"0->{Tracked,Derived,CalleeRooted}: It is allowable to decay an untracked pointer to any of the others. However, do note that the optimizer has broad license to not root such a value. It is never safe to have a value in address space 0 in any part of the program if it is (or is derived from) a value that requires a GC root.\nTracked->Derived: This is the standard decay route for interior values. The placement pass will look for these to identify the base pointer for any use.\nTracked->CalleeRooted: Addrspace CalleeRooted serves merely as a hint that a GC root is not required. However, do note that the Derived->CalleeRooted decay is prohibited, since pointers should generally be storable to a GC slot, even in this address space.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Now let us consider what constitutes a use:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Loads whose loaded values is in one of the address spaces\nStores of a value in one of the address spaces to a location\nStores to a pointer in one of the address spaces\nCalls for which a value in one of the address spaces is an operand\nCalls in jlcall ABI, for which the argument array contains a value\nReturn instructions.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"We explicitly allow load/stores and simple calls in address spaces Tracked/Derived. Elements of jlcall argument arrays must always be in address space Tracked (it is required by the ABI that they are valid jl_value_t* pointers). The same is true for return instructions (though note that struct return arguments are allowed to have any of the address spaces). The only allowable use of an address space CalleeRooted pointer is to pass it to a call (which must have an appropriately typed operand).","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Further, we disallow getelementptr in addrspace Tracked. This is because unless the operation is a noop, the resulting pointer will not be validly storable to a GC slot and may thus not be in this address space. If such a pointer is required, it should be decayed to addrspace Derived first.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Lastly, we disallow inttoptr/ptrtoint instructions in these address spaces. Having these instructions would mean that some i64 values are really GC tracked. This is problematic, because it breaks that stated requirement that we're able to identify GC-relevant pointers. This invariant is accomplished using the LLVM \"non-integral pointers\" feature, which is new in LLVM 5.0. It prohibits the optimizer from making optimizations that would introduce these operations. Note we can still insert static constants at JIT time by using inttoptr in address space 0 and then decaying to the appropriate address space afterwards.","category":"page"},{"location":"devdocs/llvm/#Supporting-[ccall](@ref)","page":"Working with LLVM","title":"Supporting ccall","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"One important aspect missing from the discussion so far is the handling of ccall. ccall has the peculiar feature that the location and scope of a use do not coincide. As an example consider:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"A = randn(1024)\nccall(:foo, Cvoid, (Ptr{Float64},), A)","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"In lowering, the compiler will insert a conversion from the array to the pointer which drops the reference to the array value. However, we of course need to make sure that the array does stay alive while we're doing the ccall. To understand how this is done, lets look at a hypothetical approximate possible lowering of the above code:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"return $(Expr(:foreigncall, :(:foo), Cvoid, svec(Ptr{Float64}), 0, :(:ccall), Expr(:foreigncall, :(:jl_array_ptr), Ptr{Float64}, svec(Any), 0, :(:ccall), :(A)), :(A)))","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The last :(A), is an extra argument list inserted during lowering that informs the code generator which Julia level values need to be kept alive for the duration of this ccall. We then take this information and represent it in an \"operand bundle\" at the IR level. An operand bundle is essentially a fake use that is attached to the call site. At the IR level, this looks like so:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"call void inttoptr (i64 ... to void (double*)*)(double* %5) [ \"jl_roots\"(%jl_value_t addrspace(10)* %A) ]","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The GC root placement pass will treat the jl_roots operand bundle as if it were a regular operand. However, as a final step, after the GC roots are inserted, it will drop the operand bundle to avoid confusing instruction selection.","category":"page"},{"location":"devdocs/llvm/#Supporting-[pointer_from_objref](@ref)","page":"Working with LLVM","title":"Supporting pointer_from_objref","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"pointer_from_objref is special because it requires the user to take explicit control of GC rooting. By our above invariants, this function is illegal, because it performs an address space cast from 10 to 0. However, it can be useful, in certain situations, so we provide a special intrinsic:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"declared %jl_value_t *julia.pointer_from_objref(%jl_value_t addrspace(10)*)","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"which is lowered to the corresponding address space cast after GC root lowering. Do note however that by using this intrinsic, the caller assumes all responsibility for making sure that the value in question is rooted. Further this intrinsic is not considered a use, so the GC root placement pass will not provide a GC root for the function. As a result, the external rooting must be arranged while the value is still tracked by the system. I.e. it is not valid to attempt to use the result of this operation to establish a global root - the optimizer may have already dropped the value.","category":"page"},{"location":"devdocs/llvm/#Keeping-values-alive-in-the-absence-of-uses","page":"Working with LLVM","title":"Keeping values alive in the absence of uses","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"In certain cases it is necessary to keep an object alive, even though there is no compiler-visible use of said object. This may be case for low level code that operates on the memory-representation of an object directly or code that needs to interface with C code. In order to allow this, we provide the following intrinsics at the LLVM level:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"token @llvm.julia.gc_preserve_begin(...)\nvoid @llvm.julia.gc_preserve_end(token)","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"(The llvm. in the name is required in order to be able to use the token type). The semantics of these intrinsics are as follows: At any safepoint that is dominated by a gc_preserve_begin call, but that is not not dominated by a corresponding gc_preserve_end call (i.e. a call whose argument is the token returned by a gc_preserve_begin call), the values passed as arguments to that gc_preserve_begin will be kept live. Note that the gc_preserve_begin still counts as a regular use of those values, so the standard lifetime semantics will ensure that the values will be kept alive before entering the preserve region.","category":"page"},{"location":"manual/variables-and-scoping/#scope-of-variables","page":"Scope of Variables","title":"Scope of Variables","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The scope of a variable is the region of code within which a variable is accessible. Variable scoping helps avoid variable naming conflicts. The concept is intuitive: two functions can both have arguments called x without the two x's referring to the same thing. Similarly, there are many other cases where different blocks of code can use the same name without referring to the same thing. The rules for when the same variable name does or doesn't refer to the same thing are called scope rules; this section spells them out in detail.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Certain constructs in the language introduce scope blocks, which are regions of code that are eligible to be the scope of some set of variables. The scope of a variable cannot be an arbitrary set of source lines; instead, it will always line up with one of these blocks. There are two main types of scopes in Julia, global scope and local scope. The latter can be nested. There is also a distinction in Julia between constructs which introduce a \"hard scope\" and those which only introduce a \"soft scope\", which affects whether shadowing a global variable by the same name is allowed or not.","category":"page"},{"location":"manual/variables-and-scoping/#man-scope-table","page":"Scope of Variables","title":"Scope constructs","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The constructs introducing scope blocks are:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Construct Scope type Allowed within\nmodule, baremodule global global\nstruct local (soft) global\nfor, while, try local (soft) global, local\nmacro local (hard) global\nfunctions, do blocks, let blocks, comprehensions, generators local (hard) global, local","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Notably missing from this table are begin blocks and if blocks which do not introduce new scopes. The three types of scopes follow somewhat different rules which will be explained below.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Julia uses lexical scoping, meaning that a function's scope does not inherit from its caller's scope, but from the scope in which the function was defined. For example, in the following code the x inside foo refers to the x in the global scope of its module Bar:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> module Bar\n x = 1\n foo() = x\n end;","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"and not a x in the scope where foo is used:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> import .Bar\n\njulia> x = -1;\n\njulia> Bar.foo()\n1","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Thus lexical scope means that what a variable in a particular piece of code refers to can be deduced from the code in which it appears alone and does not depend on how the program executes. A scope nested inside another scope can \"see\" variables in all the outer scopes in which it is contained. Outer scopes, on the other hand, cannot see variables in inner scopes.","category":"page"},{"location":"manual/variables-and-scoping/#Global-Scope","page":"Scope of Variables","title":"Global Scope","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Each module introduces a new global scope, separate from the global scope of all other modules—there is no all-encompassing global scope. Modules can introduce variables of other modules into their scope through the using or import statements or through qualified access using the dot-notation, i.e. each module is a so-called namespace as well as a first-class data structure associating names with values.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"If a top-level expression contains a variable declaration with keyword local, then that variable is not accessible outside that expression. The variable inside the expression does not affect global variables of the same name. An example is to declare local x in a begin or if block at the top-level:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x = 1\n begin\n local x = 0\n @show x\n end\n @show x;\nx = 0\nx = 1","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Note that the interactive prompt (aka REPL) is in the global scope of the module Main.","category":"page"},{"location":"manual/variables-and-scoping/#local-scope","page":"Scope of Variables","title":"Local Scope","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"A new local scope is introduced by most code blocks (see above table for a complete list). If such a block is syntactically nested inside of another local scope, the scope it creates is nested inside of all the local scopes that it appears within, which are all ultimately nested inside of the global scope of the module in which the code is evaluated. Variables in outer scopes are visible from any scope they contain — meaning that they can be read and written in inner scopes — unless there is a local variable with the same name that \"shadows\" the outer variable of the same name. This is true even if the outer local is declared after (in the sense of textually below) an inner block. When we say that a variable \"exists\" in a given scope, this means that a variable by that name exists in any of the scopes that the current scope is nested inside of, including the current one.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Some programming languages require explicitly declaring new variables before using them. Explicit declaration works in Julia too: in any local scope, writing local x declares a new local variable in that scope, regardless of whether there is already a variable named x in an outer scope or not. Declaring each new variable like this is somewhat verbose and tedious, however, so Julia, like many other languages, considers assignment to a variable name that doesn't already exist to implicitly declare that variable. If the current scope is global, the new variable is global; if the current scope is local, the new variable is local to the innermost local scope and will be visible inside of that scope but not outside of it. If you assign to an existing local, it always updates that existing local: you can only shadow a local by explicitly declaring a new local in a nested scope with the local keyword. In particular, this applies to variables assigned in inner functions, which may surprise users coming from Python where assignment in an inner function creates a new local unless the variable is explicitly declared to be non-local.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Mostly this is pretty intuitive, but as with many things that behave intuitively, the details are more subtle than one might naïvely imagine.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"When x = occurs in a local scope, Julia applies the following rules to decide what the expression means based on where the assignment expression occurs and what x already refers to at that location:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Existing local: If x is already a local variable, then the existing local x is assigned;\nHard scope: If x is not already a local variable and assignment occurs inside of any hard scope construct (i.e. within a let block, function or macro body, comprehension, or generator), a new local named x is created in the scope of the assignment;\nSoft scope: If x is not already a local variable and all of the scope constructs containing the assignment are soft scopes (loops, try/catch blocks, or struct blocks), the behavior depends on whether the global variable x is defined:\nif global x is undefined, a new local named x is created in the scope of the assignment;\nif global x is defined, the assignment is considered ambiguous:\nin non-interactive contexts (files, eval), an ambiguity warning is printed and a new local is created;\nin interactive contexts (REPL, notebooks), the global variable x is assigned.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"You may note that in non-interactive contexts the hard and soft scope behaviors are identical except that a warning is printed when an implicitly local variable (i.e. not declared with local x) shadows a global. In interactive contexts, the rules follow a more complex heuristic for the sake of convenience. This is covered in depth in examples that follow.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Now that you know the rules, let's look at some examples. Each example is assumed to be evaluated in a fresh REPL session so that the only globals in each snippet are the ones that are assigned in that block of code.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"We'll begin with a nice and clear-cut situation—assignment inside of a hard scope, in this case a function body, when no local variable by that name already exists:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function greet()\n x = \"hello\" # new local\n println(x)\n end\ngreet (generic function with 1 method)\n\njulia> greet()\nhello\n\njulia> x # global\nERROR: UndefVarError: `x` not defined in `Main`","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Inside of the greet function, the assignment x = \"hello\" causes x to be a new local variable in the function's scope. There are two relevant facts: the assignment occurs in local scope and there is no existing local x variable. Since x is local, it doesn't matter if there is a global named x or not. Here for example we define x = 123 before defining and calling greet:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x = 123 # global\n123\n\njulia> function greet()\n x = \"hello\" # new local\n println(x)\n end\ngreet (generic function with 1 method)\n\njulia> greet()\nhello\n\njulia> x # global\n123","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since the x in greet is local, the value (or lack thereof) of the global x is unaffected by calling greet. The hard scope rule doesn't care whether a global named x exists or not: assignment to x in a hard scope is local (unless x is declared global).","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The next clear cut situation we'll consider is when there is already a local variable named x, in which case x = always assigns to this existing local x. This is true whether the assignment occurs in the same local scope, an inner local scope in the same function body, or in the body of a function nested inside of another function, also known as a closure.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"We'll use the sum_to function, which computes the sum of integers from one up to n, as an example:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"function sum_to(n)\n s = 0 # new local\n for i = 1:n\n s = s + i # assign existing local\n end\n return s # same local\nend","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"As in the previous example, the first assignment to s at the top of sum_to causes s to be a new local variable in the body of the function. The for loop has its own inner local scope within the function scope. At the point where s = s + i occurs, s is already a local variable, so the assignment updates the existing s instead of creating a new local. We can test this out by calling sum_to in the REPL:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function sum_to(n)\n s = 0 # new local\n for i = 1:n\n s = s + i # assign existing local\n end\n return s # same local\n end\nsum_to (generic function with 1 method)\n\njulia> sum_to(10)\n55\n\njulia> s # global\nERROR: UndefVarError: `s` not defined in `Main`","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since s is local to the function sum_to, calling the function has no effect on the global variable s. We can also see that the update s = s + i in the for loop must have updated the same s created by the initialization s = 0 since we get the correct sum of 55 for the integers 1 through 10.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Let's dig into the fact that the for loop body has its own scope for a second by writing a slightly more verbose variation which we'll call sum_to_def, in which we save the sum s + i in a variable t before updating s:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function sum_to_def(n)\n s = 0 # new local\n for i = 1:n\n t = s + i # new local `t`\n s = t # assign existing local `s`\n end\n return s, @isdefined(t)\n end\nsum_to_def (generic function with 1 method)\n\njulia> sum_to_def(10)\n(55, false)","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This version returns s as before but it also uses the @isdefined macro to return a boolean indicating whether there is a local variable named t defined in the function's outermost local scope. As you can see, there is no t defined outside of the for loop body. This is because of the hard scope rule again: since the assignment to t occurs inside of a function, which introduces a hard scope, the assignment causes t to become a new local variable in the local scope where it appears, i.e. inside of the loop body. Even if there were a global named t, it would make no difference—the hard scope rule isn't affected by anything in global scope.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Note that the local scope of a for loop body is no different from the local scope of an inner function. This means that we could rewrite this example so that the loop body is implemented as a call to an inner helper function and it behaves the same way:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function sum_to_def_closure(n)\n function loop_body(i)\n t = s + i # new local `t`\n s = t # assign same local `s` as below\n end\n s = 0 # new local\n for i = 1:n\n loop_body(i)\n end\n return s, @isdefined(t)\n end\nsum_to_def_closure (generic function with 1 method)\n\njulia> sum_to_def_closure(10)\n(55, false)","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This example illustrates a couple of key points:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Inner function scopes are just like any other nested local scope. In particular, if a variable is already a local outside of an inner function and you assign to it in the inner function, the outer local variable is updated.\nIt doesn't matter if the definition of an outer local happens below where it is updated, the rule remains the same. The entire enclosing local scope is parsed and its locals determined before inner local meanings are resolved.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This design means that you can generally move code in or out of an inner function without changing its meaning, which facilitates a number of common idioms in the language using closures (see do blocks).","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Let's move onto some more ambiguous cases covered by the soft scope rule. We'll explore this by extracting the bodies of the greet and sum_to_def functions into soft scope contexts. First, let's put the body of greet in a for loop—which is soft, rather than hard—and evaluate it in the REPL:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> for i = 1:3\n x = \"hello\" # new local\n println(x)\n end\nhello\nhello\nhello\n\njulia> x\nERROR: UndefVarError: `x` not defined in `Main`","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since the global x is not defined when the for loop is evaluated, the first clause of the soft scope rule applies and x is created as local to the for loop and therefore global x remains undefined after the loop executes. Next, let's consider the body of sum_to_def extracted into global scope, fixing its argument to n = 10","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"s = 0\nfor i = 1:10\n t = s + i\n s = t\nend\ns\n@isdefined(t)","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"What does this code do? Hint: it's a trick question. The answer is \"it depends.\" If this code is entered interactively, it behaves the same way it does in a function body. But if the code appears in a file, it prints an ambiguity warning and throws an undefined variable error. Let's see it working in the REPL first:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> s = 0 # global\n0\n\njulia> for i = 1:10\n t = s + i # new local `t`\n s = t # assign global `s`\n end\n\njulia> s # global\n55\n\njulia> @isdefined(t) # global\nfalse","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The REPL approximates being in the body of a function by deciding whether assignment inside the loop assigns to a global or creates new local based on whether a global variable by that name is defined or not. If a global by the name exists, then the assignment updates it. If no global exists, then the assignment creates a new local variable. In this example we see both cases in action:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"There is no global named t, so t = s + i creates a new t that is local to the for loop;\nThere is a global named s, so s = t assigns to it.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The second fact is why execution of the loop changes the global value of s and the first fact is why t is still undefined after the loop executes. Now, let's try evaluating this same code as though it were in a file instead:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> code = \"\"\"\n s = 0 # global\n for i = 1:10\n t = s + i # new local `t`\n s = t # new local `s` with warning\n end\n s, # global\n @isdefined(t) # global\n \"\"\";\n\njulia> include_string(Main, code)\n┌ Warning: Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or `global s` to assign to the existing global variable.\n└ @ string:4\nERROR: LoadError: UndefVarError: `s` not defined in local scope","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Here we use include_string, to evaluate code as though it were the contents of a file. We could also save code to a file and then call include on that file—the result would be the same. As you can see, this behaves quite different from evaluating the same code in the REPL. Let's break down what's happening here:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"global s is defined with the value 0 before the loop is evaluated\nthe assignment s = t occurs in a soft scope—a for loop outside of any function body or other hard scope construct\ntherefore the second clause of the soft scope rule applies, and the assignment is ambiguous so a warning is emitted\nexecution continues, making s local to the for loop body\nsince s is local to the for loop, it is undefined when t = s + i is evaluated, causing an error\nevaluation stops there, but if it got to s and @isdefined(t), it would return 0 and false.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This demonstrates some important aspects of scope: in a scope, each variable can only have one meaning, and that meaning is determined regardless of the order of expressions. The presence of the expression s = t in the loop causes s to be local to the loop, which means that it is also local when it appears on the right hand side of t = s + i, even though that expression appears first and is evaluated first. One might imagine that the s on the first line of the loop could be global while the s on the second line of the loop is local, but that's not possible since the two lines are in the same scope block and each variable can only mean one thing in a given scope.","category":"page"},{"location":"manual/variables-and-scoping/#on-soft-scope","page":"Scope of Variables","title":"On Soft Scope","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"We have now covered all the local scope rules, but before wrapping up this section, perhaps a few words should be said about why the ambiguous soft scope case is handled differently in interactive and non-interactive contexts. There are two obvious questions one could ask:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Why doesn't it just work like the REPL everywhere?\nWhy doesn't it just work like in files everywhere? And maybe skip the warning?","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"In Julia ≤ 0.6, all global scopes did work like the current REPL: when x = occurred in a loop (or try/catch, or struct body) but outside of a function body (or let block or comprehension), it was decided based on whether a global named x was defined or not whether x should be local to the loop. This behavior has the advantage of being intuitive and convenient since it approximates the behavior inside of a function body as closely as possible. In particular, it makes it easy to move code back and forth between a function body and the REPL when trying to debug the behavior of a function. However, it has some downsides. First, it's quite a complex behavior: many people over the years were confused about this behavior and complained that it was complicated and hard both to explain and understand. Fair point. Second, and arguably worse, is that it's bad for programming \"at scale.\" When you see a small piece of code in one place like this, it's quite clear what's going on:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"s = 0\nfor i = 1:10\n s += i\nend","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Obviously the intention is to modify the existing global variable s. What else could it mean? However, not all real world code is so short or so clear. We found that code like the following often occurs in the wild:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"x = 123\n\n# much later\n# maybe in a different file\n\nfor i = 1:10\n x = \"hello\"\n println(x)\nend\n\n# much later\n# maybe in yet another file\n# or maybe back in the first one where `x = 123`\n\ny = x + 234","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"It's far less clear what should happen here. Since x + \"hello\" is a method error, it seems probable that the intention is for x to be local to the for loop. But runtime values and what methods happen to exist cannot be used to determine the scopes of variables. With the Julia ≤ 0.6 behavior, it's especially concerning that someone might have written the for loop first, had it working just fine, but later when someone else adds a new global far away—possibly in a different file—the code suddenly changes meaning and either breaks noisily or, worse still, silently does the wrong thing. This kind of \"spooky action at a distance\" is something that good programming language designs should prevent.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"So in Julia 1.0, we simplified the rules for scope: in any local scope, assignment to a name that wasn't already a local variable created a new local variable. This eliminated the notion of soft scope entirely as well as removing the potential for spooky action. We uncovered and fixed a significant number of bugs due to the removal of soft scope, vindicating the choice to get rid of it. And there was much rejoicing! Well, no, not really. Because some people were angry that they now had to write:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"s = 0\nfor i = 1:10\n global s += i\nend","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Do you see that global annotation in there? Hideous. Obviously this situation could not be tolerated. But seriously, there are two main issues with requiring global for this kind of top-level code:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"It's no longer convenient to copy and paste the code from inside a function body into the REPL to debug it—you have to add global annotations and then remove them again to go back;\nBeginners will write this kind of code without the global and have no idea why their code doesn't work—the error that they get is that s is undefined, which does not seem to enlighten anyone who happens to make this mistake.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"As of Julia 1.5, this code works without the global annotation in interactive contexts like the REPL or Jupyter notebooks (just like Julia 0.6) and in files and other non-interactive contexts, it prints this very direct warning:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Assignment to s in soft scope is ambiguous because a global variable by the same name exists: s will be treated as a new local. Disambiguate by using local s to suppress this warning or global s to assign to the existing global variable.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This addresses both issues while preserving the \"programming at scale\" benefits of the 1.0 behavior: global variables have no spooky effect on the meaning of code that may be far away; in the REPL copy-and-paste debugging works and beginners don't have any issues; any time someone either forgets a global annotation or accidentally shadows an existing global with a local in a soft scope, which would be confusing anyway, they get a nice clear warning.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"An important property of this design is that any code that executes in a file without a warning will behave the same way in a fresh REPL. And on the flip side, if you take a REPL session and save it to file, if it behaves differently than it did in the REPL, then you will get a warning.","category":"page"},{"location":"manual/variables-and-scoping/#Let-Blocks","page":"Scope of Variables","title":"Let Blocks","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"let statements create a new hard scope block (see above) and introduce new variable bindings each time they run. The variable need not be immediately assigned:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> var1 = let x\n for i in 1:5\n (i == 4) && (x = i; break)\n end\n x\n end\n4","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Whereas assignments might reassign a new value to an existing value location, let always creates a new location. This difference is usually not important, and is only detectable in the case of variables that outlive their scope via closures. The let syntax accepts a comma-separated series of assignments and variable names:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x, y, z = -1, -1, -1;\n\njulia> let x = 1, z\n println(\"x: $x, y: $y\") # x is local variable, y the global\n println(\"z: $z\") # errors as z has not been assigned yet but is local\n end\nx: 1, y: -1\nERROR: UndefVarError: `z` not defined in local scope","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The assignments are evaluated in order, with each right-hand side evaluated in the scope before the new variable on the left-hand side has been introduced. Therefore it makes sense to write something like let x = x since the two x variables are distinct and have separate storage. Here is an example where the behavior of let is needed:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> Fs = Vector{Any}(undef, 2); i = 1;\n\njulia> while i <= 2\n Fs[i] = ()->i\n global i += 1\n end\n\njulia> Fs[1]()\n3\n\njulia> Fs[2]()\n3","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Here we create and store two closures that return variable i. However, it is always the same variable i, so the two closures behave identically. We can use let to create a new binding for i:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> Fs = Vector{Any}(undef, 2); i = 1;\n\njulia> while i <= 2\n let i = i\n Fs[i] = ()->i\n end\n global i += 1\n end\n\njulia> Fs[1]()\n1\n\njulia> Fs[2]()\n2","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since the begin construct does not introduce a new scope, it can be useful to use a zero-argument let to just introduce a new scope block without creating any new bindings immediately:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> let\n local x = 1\n let\n local x = 2\n end\n x\n end\n1","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since let introduces a new scope block, the inner local x is a different variable than the outer local x. This particular example is equivalent to:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> let x = 1\n let x = 2\n end\n x\n end\n1","category":"page"},{"location":"manual/variables-and-scoping/#Loops-and-Comprehensions","page":"Scope of Variables","title":"Loops and Comprehensions","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"In loops and comprehensions, new variables introduced in their body scopes are freshly allocated for each loop iteration, as if the loop body were surrounded by a let block, as demonstrated by this example:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> Fs = Vector{Any}(undef, 2);\n\njulia> for j = 1:2\n Fs[j] = ()->j\n end\n\njulia> Fs[1]()\n1\n\njulia> Fs[2]()\n2","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"A for loop or comprehension iteration variable is always a new variable:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function f()\n i = 0\n for i = 1:3\n # empty\n end\n return i\n end;\n\njulia> f()\n0","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"However, it is occasionally useful to reuse an existing local variable as the iteration variable. This can be done conveniently by adding the keyword outer:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function f()\n i = 0\n for outer i = 1:3\n # empty\n end\n return i\n end;\n\njulia> f()\n3","category":"page"},{"location":"manual/variables-and-scoping/#Constants","page":"Scope of Variables","title":"Constants","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"A common use of variables is giving names to specific, unchanging values. Such variables are only assigned once. This intent can be conveyed to the compiler using the const keyword:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const e = 2.71828182845904523536;\n\njulia> const pi = 3.14159265358979323846;","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Multiple variables can be declared in a single const statement:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const a, b = 1, 2\n(1, 2)","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The const declaration should only be used in global scope on globals. It is difficult for the compiler to optimize code involving global variables, since their values (or even their types) might change at almost any time. If a global variable will not change, adding a const declaration solves this performance problem.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Local constants are quite different. The compiler is able to determine automatically when a local variable is constant, so local constant declarations are not necessary, and in fact are currently not supported.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Special top-level assignments, such as those performed by the function and struct keywords, are constant by default.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Note that const only affects the variable binding; the variable may be bound to a mutable object (such as an array), and that object may still be modified. Additionally when one tries to assign a value to a variable that is declared constant the following scenarios are possible:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"if a new value has a different type than the type of the constant then an error is thrown:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const x = 1.0\n1.0\n\njulia> x = 1\nERROR: invalid redefinition of constant x","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"if a new value has the same type as the constant then a warning is printed:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const y = 1.0\n1.0\n\njulia> y = 2.0\nWARNING: redefinition of constant y. This may fail, cause incorrect answers, or produce other errors.\n2.0","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"if an assignment would not result in the change of variable value no message is given:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const z = 100\n100\n\njulia> z = 100\n100","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The last rule applies to immutable objects even if the variable binding would change, e.g.:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const s1 = \"1\"\n\"1\"\n\njulia> s2 = \"1\"\n\"1\"\n\njulia> pointer.([s1, s2], 1)\n2-element Array{Ptr{UInt8},1}:\n Ptr{UInt8} @0x00000000132c9638\n Ptr{UInt8} @0x0000000013dd3d18\n\njulia> s1 = s2\n\"1\"\n\njulia> pointer.([s1, s2], 1)\n2-element Array{Ptr{UInt8},1}:\n Ptr{UInt8} @0x0000000013dd3d18\n Ptr{UInt8} @0x0000000013dd3d18","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"However, for mutable objects the warning is printed as expected:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const a = [1]\n1-element Vector{Int64}:\n 1\n\njulia> a = [1]\nWARNING: redefinition of constant a. This may fail, cause incorrect answers, or produce other errors.\n1-element Vector{Int64}:\n 1","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Note that although sometimes possible, changing the value of a const variable is strongly discouraged, and is intended only for convenience during interactive use. Changing constants can cause various problems or unexpected behaviors. For instance, if a method references a constant and is already compiled before the constant is changed, then it might keep using the old value:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const x = 1\n1\n\njulia> f() = x\nf (generic function with 1 method)\n\njulia> f()\n1\n\njulia> x = 2\nWARNING: redefinition of constant x. This may fail, cause incorrect answers, or produce other errors.\n2\n\njulia> f()\n1","category":"page"},{"location":"manual/variables-and-scoping/#man-typed-globals","page":"Scope of Variables","title":"Typed Globals","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"compat: Julia 1.8\nSupport for typed globals was added in Julia 1.8","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Similar to being declared as constants, global bindings can also be declared to always be of a constant type. This can either be done without assigning an actual value using the syntax global x::T or upon assignment as x::T = 123.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x::Float64 = 2.718\n2.718\n\njulia> f() = x\nf (generic function with 1 method)\n\njulia> Base.return_types(f)\n1-element Vector{Any}:\n Float64","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"For any assignment to a global, Julia will first try to convert it to the appropriate type using convert:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> global y::Int\n\njulia> y = 1.0\n1.0\n\njulia> y\n1\n\njulia> y = 3.14\nERROR: InexactError: Int64(3.14)\nStacktrace:\n[...]","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The type does not need to be concrete, but annotations with abstract types typically have little performance benefit.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Once a global has either been assigned to or its type has been set, the binding type is not allowed to change:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x = 1\n1\n\njulia> global x::Int\nERROR: cannot set type for global x. It already has a value or is already set to a different type.\nStacktrace:\n[...]","category":"page"},{"location":"base/simd-types/#SIMD-Support","page":"SIMD Support","title":"SIMD Support","text":"","category":"section"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"Type VecElement{T} is intended for building libraries of SIMD operations. Practical use of it requires using llvmcall. The type is defined as:","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"struct VecElement{T}\n value::T\nend","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"It has a special compilation rule: a homogeneous tuple of VecElement{T} maps to an LLVM vector type when T is a primitive bits type.","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"At -O3, the compiler might automatically vectorize operations on such tuples. For example, the following program, when compiled with julia -O3 generates two SIMD addition instructions (addps) on x86 systems:","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"const m128 = NTuple{4,VecElement{Float32}}\n\nfunction add(a::m128, b::m128)\n (VecElement(a[1].value+b[1].value),\n VecElement(a[2].value+b[2].value),\n VecElement(a[3].value+b[3].value),\n VecElement(a[4].value+b[4].value))\nend\n\ntriple(c::m128) = add(add(c,c),c)\n\ncode_native(triple,(m128,))","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"However, since the automatic vectorization cannot be relied upon, future use will mostly be via libraries that use llvmcall.","category":"page"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Artifacts/docs/src/index.md\"","category":"page"},{"location":"stdlib/Artifacts/#Artifacts","page":"Artifacts","title":"Artifacts","text":"","category":"section"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"DocTestSetup = :(using Artifacts)","category":"page"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"Starting with Julia 1.6, the artifacts support has moved from Pkg.jl to Julia itself. Until proper documentation can be added here, you can learn more about artifacts in the Pkg.jl manual at https://julialang.github.io/Pkg.jl/v1/artifacts/.","category":"page"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"compat: Julia 1.6\nJulia's artifacts API requires at least Julia 1.6. In Julia versions 1.3 to 1.5, you can use Pkg.Artifacts instead.","category":"page"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"Artifacts.artifact_meta\nArtifacts.artifact_hash\nArtifacts.find_artifacts_toml\nArtifacts.@artifact_str\nArtifacts.artifact_exists\nArtifacts.artifact_path\nArtifacts.select_downloadable_artifacts","category":"page"},{"location":"stdlib/Artifacts/#Artifacts.artifact_meta","page":"Artifacts","title":"Artifacts.artifact_meta","text":"artifact_meta(name::String, artifacts_toml::String;\n platform::AbstractPlatform = HostPlatform(),\n pkg_uuid::Union{Base.UUID,Nothing}=nothing)\n\nGet metadata about a given artifact (identified by name) stored within the given (Julia)Artifacts.toml file. If the artifact is platform-specific, use platform to choose the most appropriate mapping. If none is found, return nothing.\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.artifact_hash","page":"Artifacts","title":"Artifacts.artifact_hash","text":"artifact_hash(name::String, artifacts_toml::String;\n platform::AbstractPlatform = HostPlatform())\n\nThin wrapper around artifact_meta() to return the hash of the specified, platform- collapsed artifact. Returns nothing if no mapping can be found.\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.find_artifacts_toml","page":"Artifacts","title":"Artifacts.find_artifacts_toml","text":"find_artifacts_toml(path::String)\n\nGiven the path to a .jl file, (such as the one returned by __source__.file in a macro context), find the (Julia)Artifacts.toml that is contained within the containing project (if it exists), otherwise return nothing.\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.@artifact_str","page":"Artifacts","title":"Artifacts.@artifact_str","text":"macro artifact_str(name)\n\nReturn the on-disk path to an artifact. Automatically looks the artifact up by name in the project's (Julia)Artifacts.toml file. Throws an error on if the requested artifact is not present. If run in the REPL, searches for the toml file starting in the current directory, see find_artifacts_toml() for more.\n\nIf the artifact is marked \"lazy\" and the package has using LazyArtifacts defined, the artifact will be downloaded on-demand with Pkg the first time this macro tries to compute the path. The files will then be left installed locally for later.\n\nIf name contains a forward or backward slash, all elements after the first slash will be taken to be path names indexing into the artifact, allowing for an easy one-liner to access a single file/directory within an artifact. Example:\n\nffmpeg_path = @artifact\"FFMPEG/bin/ffmpeg\"\n\ncompat: Julia 1.3\nThis macro requires at least Julia 1.3.\n\ncompat: Julia 1.6\nSlash-indexing requires at least Julia 1.6.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Artifacts/#Artifacts.artifact_exists","page":"Artifacts","title":"Artifacts.artifact_exists","text":"artifact_exists(hash::SHA1; honor_overrides::Bool=true)\n\nReturn whether or not the given artifact (identified by its sha1 git tree hash) exists on-disk. Note that it is possible that the given artifact exists in multiple locations (e.g. within multiple depots).\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.artifact_path","page":"Artifacts","title":"Artifacts.artifact_path","text":"artifact_path(hash::SHA1; honor_overrides::Bool=true)\n\nGiven an artifact (identified by SHA1 git tree hash), return its installation path. If the artifact does not exist, returns the location it would be installed to.\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.select_downloadable_artifacts","page":"Artifacts","title":"Artifacts.select_downloadable_artifacts","text":"select_downloadable_artifacts(artifacts_toml::String;\n platform = HostPlatform,\n include_lazy = false,\n pkg_uuid = nothing)\n\nReturn a dictionary where every entry is an artifact from the given Artifacts.toml that should be downloaded for the requested platform. Lazy artifacts are included if include_lazy is set.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/inference/#Inference","page":"Inference","title":"Inference","text":"","category":"section"},{"location":"devdocs/inference/#How-inference-works","page":"Inference","title":"How inference works","text":"","category":"section"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"In Julia compiler, \"type inference\" refers to the process of deducing the types of later values from the types of input values. Julia's approach to inference has been described in the blog posts below:","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"Shows a simplified implementation of the data-flow analysis algorithm, that Julia's type inference routine is based on.\nGives a high level view of inference with a focus on its inter-procedural convergence guarantee.\nExplains a refinement on the algorithm introduced in 2.","category":"page"},{"location":"devdocs/inference/#Debugging-compiler.jl","page":"Inference","title":"Debugging compiler.jl","text":"","category":"section"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"You can start a Julia session, edit compiler/*.jl (for example to insert print statements), and then replace Core.Compiler in your running session by navigating to base and executing include(\"compiler/compiler.jl\"). This trick typically leads to much faster development than if you rebuild Julia for each change.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"Alternatively, you can use the Revise.jl package to track the compiler changes by using the command Revise.track(Core.Compiler) at the beginning of your Julia session. As explained in the Revise documentation, the modifications to the compiler will be reflected when the modified files are saved.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"A convenient entry point into inference is typeinf_code. Here's a demo running inference on convert(Int, UInt(1)):","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"# Get the method\natypes = Tuple{Type{Int}, UInt} # argument types\nmths = methods(convert, atypes) # worth checking that there is only one\nm = first(mths)\n\n# Create variables needed to call `typeinf_code`\ninterp = Core.Compiler.NativeInterpreter()\nsparams = Core.svec() # this particular method doesn't have type-parameters\nrun_optimizer = true # run all inference optimizations\ntypes = Tuple{typeof(convert), atypes.parameters...} # Tuple{typeof(convert), Type{Int}, UInt}\nCore.Compiler.typeinf_code(interp, m, types, sparams, run_optimizer)","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"If your debugging adventures require a MethodInstance, you can look it up by calling Core.Compiler.specialize_method using many of the variables above. A CodeInfo object may be obtained with","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"# Returns the CodeInfo object for `convert(Int, ::UInt)`:\nci = (@code_typed convert(Int, UInt(1)))[1]","category":"page"},{"location":"devdocs/inference/#The-inlining-algorithm-(inline_worthy)","page":"Inference","title":"The inlining algorithm (inline_worthy)","text":"","category":"section"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"Much of the hardest work for inlining runs in ssa_inlining_pass!. However, if your question is \"why didn't my function inline?\" then you will most likely be interested in inline_worthy, which makes a decision to inline the function call or not.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"inline_worthy implements a cost-model, where \"cheap\" functions get inlined; more specifically, we inline functions if their anticipated run-time is not large compared to the time it would take to issue a call to them if they were not inlined. The cost-model is extremely simple and ignores many important details: for example, all for loops are analyzed as if they will be executed once, and the cost of an if...else...end includes the summed cost of all branches. It's also worth acknowledging that we currently lack a suite of functions suitable for testing how well the cost model predicts the actual run-time cost, although BaseBenchmarks provides a great deal of indirect information about the successes and failures of any modification to the inlining algorithm.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"The foundation of the cost-model is a lookup table, implemented in add_tfunc and its callers, that assigns an estimated cost (measured in CPU cycles) to each of Julia's intrinsic functions. These costs are based on standard ranges for common architectures (see Agner Fog's analysis for more detail).","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"We supplement this low-level lookup table with a number of special cases. For example, an :invoke expression (a call for which all input and output types were inferred in advance) is assigned a fixed cost (currently 20 cycles). In contrast, a :call expression, for functions other than intrinsics/builtins, indicates that the call will require dynamic dispatch, in which case we assign a cost set by Params.inline_nonleaf_penalty (currently set at 1000). Note that this is not a \"first-principles\" estimate of the raw cost of dynamic dispatch, but a mere heuristic indicating that dynamic dispatch is extremely expensive.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"Each statement gets analyzed for its total cost in a function called statement_cost. You can display the cost associated with each statement as follows:","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"julia> Base.print_statement_costs(stdout, map, (typeof(sqrt), Tuple{Int},)) # map(sqrt, (2,))\nmap(f, t::Tuple{Any}) @ Base tuple.jl:281\n 0 1 ─ %1 = $(Expr(:boundscheck, true))::Bool\n 0 │ %2 = Base.getfield(_3, 1, %1)::Int64\n 1 │ %3 = Base.sitofp(Float64, %2)::Float64\n 0 │ %4 = Base.lt_float(%3, 0.0)::Bool\n 0 └── goto #3 if not %4\n 0 2 ─ invoke Base.Math.throw_complex_domainerror(:sqrt::Symbol, %3::Float64)::Union{}\n 0 └── unreachable\n 20 3 ─ %8 = Base.Math.sqrt_llvm(%3)::Float64\n 0 └── goto #4\n 0 4 ─ goto #5\n 0 5 ─ %11 = Core.tuple(%8)::Tuple{Float64}\n 0 └── return %11\n","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"The line costs are in the left column. This includes the consequences of inlining and other forms of optimization.","category":"page"},{"location":"manual/complex-and-rational-numbers/#Complex-and-Rational-Numbers","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"","category":"section"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Julia includes predefined types for both complex and rational numbers, and supports all the standard Mathematical Operations and Elementary Functions on them. Conversion and Promotion are defined so that operations on any combination of predefined numeric types, whether primitive or composite, behave as expected.","category":"page"},{"location":"manual/complex-and-rational-numbers/#Complex-Numbers","page":"Complex and Rational Numbers","title":"Complex Numbers","text":"","category":"section"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"The global constant im is bound to the complex number i, representing the principal square root of -1. (Using mathematicians' i or engineers' j for this global constant was rejected since they are such popular index variable names.) Since Julia allows numeric literals to be juxtaposed with identifiers as coefficients, this binding suffices to provide convenient syntax for complex numbers, similar to the traditional mathematical notation:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 1+2im\n1 + 2im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"You can perform all the standard arithmetic operations with complex numbers:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> (1 + 2im)*(2 - 3im)\n8 + 1im\n\njulia> (1 + 2im)/(1 - 2im)\n-0.6 + 0.8im\n\njulia> (1 + 2im) + (1 - 2im)\n2 + 0im\n\njulia> (-3 + 2im) - (5 - 1im)\n-8 + 3im\n\njulia> (-1 + 2im)^2\n-3 - 4im\n\njulia> (-1 + 2im)^2.5\n2.729624464784009 - 6.9606644595719im\n\njulia> (-1 + 2im)^(1 + 1im)\n-0.27910381075826657 + 0.08708053414102428im\n\njulia> 3(2 - 5im)\n6 - 15im\n\njulia> 3(2 - 5im)^2\n-63 - 60im\n\njulia> 3(2 - 5im)^-1.0\n0.20689655172413793 + 0.5172413793103449im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"The promotion mechanism ensures that combinations of operands of different types just work:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 2(1 - 1im)\n2 - 2im\n\njulia> (2 + 3im) - 1\n1 + 3im\n\njulia> (1 + 2im) + 0.5\n1.5 + 2.0im\n\njulia> (2 + 3im) - 0.5im\n2.0 + 2.5im\n\njulia> 0.75(1 + 2im)\n0.75 + 1.5im\n\njulia> (2 + 3im) / 2\n1.0 + 1.5im\n\njulia> (1 - 3im) / (2 + 2im)\n-0.5 - 1.0im\n\njulia> 2im^2\n-2 + 0im\n\njulia> 1 + 3/4im\n1.0 - 0.75im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Note that 3/4im == 3/(4*im) == -(3/4*im), since a literal coefficient binds more tightly than division.","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Standard functions to manipulate complex values are provided:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> z = 1 + 2im\n1 + 2im\n\njulia> real(1 + 2im) # real part of z\n1\n\njulia> imag(1 + 2im) # imaginary part of z\n2\n\njulia> conj(1 + 2im) # complex conjugate of z\n1 - 2im\n\njulia> abs(1 + 2im) # absolute value of z\n2.23606797749979\n\njulia> abs2(1 + 2im) # squared absolute value\n5\n\njulia> angle(1 + 2im) # phase angle in radians\n1.1071487177940904","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"As usual, the absolute value (abs) of a complex number is its distance from zero. abs2 gives the square of the absolute value, and is of particular use for complex numbers since it avoids taking a square root. angle returns the phase angle in radians (also known as the argument or arg function). The full gamut of other Elementary Functions is also defined for complex numbers:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> sqrt(1im)\n0.7071067811865476 + 0.7071067811865475im\n\njulia> sqrt(1 + 2im)\n1.272019649514069 + 0.7861513777574233im\n\njulia> cos(1 + 2im)\n2.0327230070196656 - 3.0518977991517997im\n\njulia> exp(1 + 2im)\n-1.1312043837568135 + 2.4717266720048188im\n\njulia> sinh(1 + 2im)\n-0.4890562590412937 + 1.4031192506220405im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Note that mathematical functions typically return real values when applied to real numbers and complex values when applied to complex numbers. For example, sqrt behaves differently when applied to -1 versus -1 + 0im even though -1 == -1 + 0im:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> sqrt(-1)\nERROR: DomainError with -1.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]\n\njulia> sqrt(-1 + 0im)\n0.0 + 1.0im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"The literal numeric coefficient notation does not work when constructing a complex number from variables. Instead, the multiplication must be explicitly written out:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> a = 1; b = 2; a + b*im\n1 + 2im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"However, this is not recommended. Instead, use the more efficient complex function to construct a complex value directly from its real and imaginary parts:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> a = 1; b = 2; complex(a, b)\n1 + 2im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"This construction avoids the multiplication and addition operations.","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Inf and NaN propagate through complex numbers in the real and imaginary parts of a complex number as described in the Special floating-point values section:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 1 + Inf*im\n1.0 + Inf*im\n\njulia> 1 + NaN*im\n1.0 + NaN*im","category":"page"},{"location":"manual/complex-and-rational-numbers/#Rational-Numbers","page":"Complex and Rational Numbers","title":"Rational Numbers","text":"","category":"section"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Julia has a rational number type to represent exact ratios of integers. Rationals are constructed using the // operator:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 2//3\n2//3","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"If the numerator and denominator of a rational have common factors, they are reduced to lowest terms such that the denominator is non-negative:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 6//9\n2//3\n\njulia> -4//8\n-1//2\n\njulia> 5//-15\n-1//3\n\njulia> -4//-12\n1//3","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"This normalized form for a ratio of integers is unique, so equality of rational values can be tested by checking for equality of the numerator and denominator. The standardized numerator and denominator of a rational value can be extracted using the numerator and denominator functions:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> numerator(2//3)\n2\n\njulia> denominator(2//3)\n3","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Direct comparison of the numerator and denominator is generally not necessary, since the standard arithmetic and comparison operations are defined for rational values:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 2//3 == 6//9\ntrue\n\njulia> 2//3 == 9//27\nfalse\n\njulia> 3//7 < 1//2\ntrue\n\njulia> 3//4 > 2//3\ntrue\n\njulia> 2//4 + 1//6\n2//3\n\njulia> 5//12 - 1//4\n1//6\n\njulia> 5//8 * 3//12\n5//32\n\njulia> 6//5 / 10//7\n21//25","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Rationals can easily be converted to floating-point numbers:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> float(3//4)\n0.75","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Conversion from rational to floating-point respects the following identity for any integral values of a and b, with the exception of the two cases b == 0 and a == 0 && b < 0:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> a = 1; b = 2;\n\njulia> isequal(float(a//b), a/b)\ntrue","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Constructing infinite rational values is acceptable:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 5//0\n1//0\n\njulia> x = -3//0\n-1//0\n\njulia> typeof(x)\nRational{Int64}","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Trying to construct a NaN rational value, however, is invalid:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 0//0\nERROR: ArgumentError: invalid rational: zero(Int64)//zero(Int64)\nStacktrace:\n[...]","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"As usual, the promotion system makes interactions with other numeric types effortless:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 3//5 + 1\n8//5\n\njulia> 3//5 - 0.5\n0.09999999999999998\n\njulia> 2//7 * (1 + 2im)\n2//7 + 4//7*im\n\njulia> 2//7 * (1.5 + 2im)\n0.42857142857142855 + 0.5714285714285714im\n\njulia> 3//2 / (1 + 2im)\n3//10 - 3//5*im\n\njulia> 1//2 + 2im\n1//2 + 2//1*im\n\njulia> 1 + 2//3im\n1//1 - 2//3*im\n\njulia> 0.5 == 1//2\ntrue\n\njulia> 0.33 == 1//3\nfalse\n\njulia> 0.33 < 1//3\ntrue\n\njulia> 1//3 - 0.33\n0.0033333333333332993","category":"page"},{"location":"devdocs/types/#More-about-types","page":"More about types","title":"More about types","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"If you've used Julia for a while, you understand the fundamental role that types play. Here we try to get under the hood, focusing particularly on Parametric Types.","category":"page"},{"location":"devdocs/types/#Types-and-sets-(and-Any-and-Union{}/Bottom)","page":"More about types","title":"Types and sets (and Any and Union{}/Bottom)","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"It's perhaps easiest to conceive of Julia's type system in terms of sets. While programs manipulate individual values, a type refers to a set of values. This is not the same thing as a collection; for example a Set of values is itself a single Set value. Rather, a type describes a set of possible values, expressing uncertainty about which value we have.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"A concrete type T describes the set of values whose direct tag, as returned by the typeof function, is T. An abstract type describes some possibly-larger set of values.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Any describes the entire universe of possible values. Integer is a subset of Any that includes Int, Int8, and other concrete types. Internally, Julia also makes heavy use of another type known as Bottom, which can also be written as Union{}. This corresponds to the empty set.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Julia's types support the standard operations of set theory: you can ask whether T1 is a \"subset\" (subtype) of T2 with T1 <: T2. Likewise, you intersect two types using typeintersect, take their union with Union, and compute a type that contains their union with typejoin:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> typeintersect(Int, Float64)\nUnion{}\n\njulia> Union{Int, Float64}\nUnion{Float64, Int64}\n\njulia> typejoin(Int, Float64)\nReal\n\njulia> typeintersect(Signed, Union{UInt8, Int8})\nInt8\n\njulia> Union{Signed, Union{UInt8, Int8}}\nUnion{UInt8, Signed}\n\njulia> typejoin(Signed, Union{UInt8, Int8})\nInteger\n\njulia> typeintersect(Tuple{Integer, Float64}, Tuple{Int, Real})\nTuple{Int64, Float64}\n\njulia> Union{Tuple{Integer, Float64}, Tuple{Int, Real}}\nUnion{Tuple{Int64, Real}, Tuple{Integer, Float64}}\n\njulia> typejoin(Tuple{Integer, Float64}, Tuple{Int, Real})\nTuple{Integer, Real}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"While these operations may seem abstract, they lie at the heart of Julia. For example, method dispatch is implemented by stepping through the items in a method list until reaching one for which the type of the argument tuple is a subtype of the method signature. For this algorithm to work, it's important that methods be sorted by their specificity, and that the search begins with the most specific methods. Consequently, Julia also implements a partial order on types; this is achieved by functionality that is similar to <:, but with differences that will be discussed below.","category":"page"},{"location":"devdocs/types/#UnionAll-types","page":"More about types","title":"UnionAll types","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Julia's type system can also express an iterated union of types: a union of types over all values of some variable. This is needed to describe parametric types where the values of some parameters are not known.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"For example, Array has two parameters as in Array{Int,2}. If we did not know the element type, we could write Array{T,2} where T, which is the union of Array{T,2} for all values of T: Union{Array{Int8,2}, Array{Int16,2}, ...}.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Such a type is represented by a UnionAll object, which contains a variable (T in this example, of type TypeVar), and a wrapped type (Array{T,2} in this example).","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Consider the following methods:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f1(A::Array) = 1\nf2(A::Array{Int}) = 2\nf3(A::Array{T}) where {T<:Any} = 3\nf4(A::Array{Any}) = 4","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The signature - as described in Function calls - of f3 is a UnionAll type wrapping a tuple type: Tuple{typeof(f3), Array{T}} where T. All but f4 can be called with a = [1,2]; all but f2 can be called with b = Any[1,2].","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Let's look at these types a little more closely:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> dump(Array)\nUnionAll\n var: TypeVar\n name: Symbol T\n lb: Union{}\n ub: abstract type Any\n body: UnionAll\n var: TypeVar\n name: Symbol N\n lb: Union{}\n ub: abstract type Any\n body: mutable struct Array{T, N} <: DenseArray{T, N}\n ref::MemoryRef{T}\n size::NTuple{N, Int64}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"This indicates that Array actually names a UnionAll type. There is one UnionAll type for each parameter, nested. The syntax Array{Int,2} is equivalent to Array{Int}{2}; internally each UnionAll is instantiated with a particular variable value, one at a time, outermost-first. This gives a natural meaning to the omission of trailing type parameters; Array{Int} gives a type equivalent to Array{Int,N} where N.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"A TypeVar is not itself a type, but rather should be considered part of the structure of a UnionAll type. Type variables have lower and upper bounds on their values (in the fields lb and ub). The symbol name is purely cosmetic. Internally, TypeVars are compared by address, so they are defined as mutable types to ensure that \"different\" type variables can be distinguished. However, by convention they should not be mutated.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"One can construct TypeVars manually:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> TypeVar(:V, Signed, Real)\nSigned<:V<:Real","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"There are convenience versions that allow you to omit any of these arguments except the name symbol.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The syntax Array{T} where T<:Integer is lowered to","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"let T = TypeVar(:T,Integer)\n UnionAll(T, Array{T})\nend","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"so it is seldom necessary to construct a TypeVar manually (indeed, this is to be avoided).","category":"page"},{"location":"devdocs/types/#Free-variables","page":"More about types","title":"Free variables","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The concept of a free type variable is extremely important in the type system. We say that a variable V is free in type T if T does not contain the UnionAll that introduces variable V. For example, the type Array{Array{V} where V<:Integer} has no free variables, but the Array{V} part inside of it does have a free variable, V.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"A type with free variables is, in some sense, not really a type at all. Consider the type Array{Array{T}} where T, which refers to all homogeneous arrays of arrays. The inner type Array{T}, seen by itself, might seem to refer to any kind of array. However, every element of the outer array must have the same array type, so Array{T} cannot refer to just any old array. One could say that Array{T} effectively \"occurs\" multiple times, and T must have the same value each \"time\".","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"For this reason, the function jl_has_free_typevars in the C API is very important. Types for which it returns true will not give meaningful answers in subtyping and other type functions.","category":"page"},{"location":"devdocs/types/#TypeNames","page":"More about types","title":"TypeNames","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The following two Array types are functionally equivalent, yet print differently:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> TV, NV = TypeVar(:T), TypeVar(:N)\n(T, N)\n\njulia> Array\nArray\n\njulia> Array{TV, NV}\nArray{T, N}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"These can be distinguished by examining the name field of the type, which is an object of type TypeName:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> dump(Array{Int,1}.name)\nTypeName\n name: Symbol Array\n module: Module Core\n names: empty SimpleVector\n wrapper: UnionAll\n var: TypeVar\n name: Symbol T\n lb: Union{}\n ub: abstract type Any\n body: UnionAll\n var: TypeVar\n name: Symbol N\n lb: Union{}\n ub: abstract type Any\n body: mutable struct Array{T, N} <: DenseArray{T, N}\n cache: SimpleVector\n ...\n\n linearcache: SimpleVector\n ...\n\n hash: Int64 -7900426068641098781\n mt: MethodTable\n name: Symbol Array\n defs: Nothing nothing\n cache: Nothing nothing\n max_args: Int64 0\n module: Module Core\n : Int64 0\n : Int64 0","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"In this case, the relevant field is wrapper, which holds a reference to the top-level type used to make new Array types.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> pointer_from_objref(Array)\nPtr{Cvoid} @0x00007fcc7de64850\n\njulia> pointer_from_objref(Array.body.body.name.wrapper)\nPtr{Cvoid} @0x00007fcc7de64850\n\njulia> pointer_from_objref(Array{TV,NV})\nPtr{Cvoid} @0x00007fcc80c4d930\n\njulia> pointer_from_objref(Array{TV,NV}.name.wrapper)\nPtr{Cvoid} @0x00007fcc7de64850","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The wrapper field of Array points to itself, but for Array{TV,NV} it points back to the original definition of the type.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"What about the other fields? hash assigns an integer to each type. To examine the cache field, it's helpful to pick a type that is less heavily used than Array. Let's first create our own type:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> struct MyType{T,N} end\n\njulia> MyType{Int,2}\nMyType{Int64, 2}\n\njulia> MyType{Float32, 5}\nMyType{Float32, 5}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"When you instantiate a parametric type, each concrete type gets saved in a type cache (MyType.body.body.name.cache). However, instances containing free type variables are not cached.","category":"page"},{"location":"devdocs/types/#Tuple-types","page":"More about types","title":"Tuple types","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Tuple types constitute an interesting special case. For dispatch to work on declarations like x::Tuple, the type has to be able to accommodate any tuple. Let's check the parameters:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> Tuple\nTuple\n\njulia> Tuple.parameters\nsvec(Vararg{Any})","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Unlike other types, tuple types are covariant in their parameters, so this definition permits Tuple to match any type of tuple:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> typeintersect(Tuple, Tuple{Int,Float64})\nTuple{Int64, Float64}\n\njulia> typeintersect(Tuple{Vararg{Any}}, Tuple{Int,Float64})\nTuple{Int64, Float64}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"However, if a variadic (Vararg) tuple type has free variables it can describe different kinds of tuples:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> typeintersect(Tuple{Vararg{T} where T}, Tuple{Int,Float64})\nTuple{Int64, Float64}\n\njulia> typeintersect(Tuple{Vararg{T}} where T, Tuple{Int,Float64})\nUnion{}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Notice that when T is free with respect to the Tuple type (i.e. its binding UnionAll type is outside the Tuple type), only one T value must work over the whole type. Therefore a heterogeneous tuple does not match.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Finally, it's worth noting that Tuple{} is distinct:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> Tuple{}\nTuple{}\n\njulia> Tuple{}.parameters\nsvec()\n\njulia> typeintersect(Tuple{}, Tuple{Int})\nUnion{}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"What is the \"primary\" tuple-type?","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> pointer_from_objref(Tuple)\nPtr{Cvoid} @0x00007f5998a04370\n\njulia> pointer_from_objref(Tuple{})\nPtr{Cvoid} @0x00007f5998a570d0\n\njulia> pointer_from_objref(Tuple.name.wrapper)\nPtr{Cvoid} @0x00007f5998a04370\n\njulia> pointer_from_objref(Tuple{}.name.wrapper)\nPtr{Cvoid} @0x00007f5998a04370","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"so Tuple == Tuple{Vararg{Any}} is indeed the primary type.","category":"page"},{"location":"devdocs/types/#Diagonal-types","page":"More about types","title":"Diagonal types","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Consider the type Tuple{T,T} where T. A method with this signature would look like:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(x::T, y::T) where {T} = ...","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"According to the usual interpretation of a UnionAll type, this T ranges over all types, including Any, so this type should be equivalent to Tuple{Any,Any}. However, this interpretation causes some practical problems.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"First, a value of T needs to be available inside the method definition. For a call like f(1, 1.0), it's not clear what T should be. It could be Union{Int,Float64}, or perhaps Real. Intuitively, we expect the declaration x::T to mean T === typeof(x). To make sure that invariant holds, we need typeof(x) === typeof(y) === T in this method. That implies the method should only be called for arguments of the exact same type.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"It turns out that being able to dispatch on whether two values have the same type is very useful (this is used by the promotion system for example), so we have multiple reasons to want a different interpretation of Tuple{T,T} where T. To make this work we add the following rule to subtyping: if a variable occurs more than once in covariant position, it is restricted to ranging over only concrete types. (\"Covariant position\" means that only Tuple and Union types occur between an occurrence of a variable and the UnionAll type that introduces it.) Such variables are called \"diagonal variables\" or \"concrete variables\".","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"So for example, Tuple{T,T} where T can be seen as Union{Tuple{Int8,Int8}, Tuple{Int16,Int16}, ...}, where T ranges over all concrete types. This gives rise to some interesting subtyping results. For example Tuple{Real,Real} is not a subtype of Tuple{T,T} where T, because it includes some types like Tuple{Int8,Int16} where the two elements have different types. Tuple{Real,Real} and Tuple{T,T} where T have the non-trivial intersection Tuple{T,T} where T<:Real. However, Tuple{Real} is a subtype of Tuple{T} where T, because in that case T occurs only once and so is not diagonal.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Next consider a signature like the following:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(a::Array{T}, x::T, y::T) where {T} = ...","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"In this case, T occurs in invariant position inside Array{T}. That means whatever type of array is passed unambiguously determines the value of T – we say T has an equality constraint on it. Therefore in this case the diagonal rule is not really necessary, since the array determines T and we can then allow x and y to be of any subtypes of T. So variables that occur in invariant position are never considered diagonal. This choice of behavior is slightly controversial – some feel this definition should be written as","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(a::Array{T}, x::S, y::S) where {T, S<:T} = ...","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"to clarify whether x and y need to have the same type. In this version of the signature they would, or we could introduce a third variable for the type of y if x and y can have different types.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The next complication is the interaction of unions and diagonal variables, e.g.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(x::Union{Nothing,T}, y::T) where {T} = ...","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Consider what this declaration means. y has type T. x then can have either the same type T, or else be of type Nothing. So all of the following calls should match:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(1, 1)\nf(\"\", \"\")\nf(2.0, 2.0)\nf(nothing, 1)\nf(nothing, \"\")\nf(nothing, 2.0)","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"These examples are telling us something: when x is nothing::Nothing, there are no extra constraints on y. It is as if the method signature had y::Any. Indeed, we have the following type equivalence:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"(Tuple{Union{Nothing,T},T} where T) == Union{Tuple{Nothing,Any}, Tuple{T,T} where T}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The general rule is: a concrete variable in covariant position acts like it's not concrete if the subtyping algorithm only uses it once. When x has type Nothing, we don't need to use the T in Union{Nothing,T}; we only use it in the second slot. This arises naturally from the observation that in Tuple{T} where T restricting T to concrete types makes no difference; the type is equal to Tuple{Any} either way.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"However, appearing in invariant position disqualifies a variable from being concrete whether that appearance of the variable is used or not. Otherwise types can behave differently depending on which other types they are compared to, making subtyping not transitive. For example, consider","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Tuple{Int,Int8,Vector{Integer}} <: Tuple{T,T,Vector{Union{Integer,T}}} where T","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"If the T inside the Union is ignored, then T is concrete and the answer is \"false\" since the first two types aren't the same. But consider instead","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Tuple{Int,Int8,Vector{Any}} <: Tuple{T,T,Vector{Union{Integer,T}}} where T","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Now we cannot ignore the T in the Union (we must have T == Any), so T is not concrete and the answer is \"true\". That would make the concreteness of T depend on the other type, which is not acceptable since a type must have a clear meaning on its own. Therefore the appearance of T inside Vector is considered in both cases.","category":"page"},{"location":"devdocs/types/#Subtyping-diagonal-variables","page":"More about types","title":"Subtyping diagonal variables","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The subtyping algorithm for diagonal variables has two components: (1) identifying variable occurrences, and (2) ensuring that diagonal variables range over concrete types only.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The first task is accomplished by keeping counters occurs_inv and occurs_cov (in src/subtype.c) for each variable in the environment, tracking the number of invariant and covariant occurrences, respectively. A variable is diagonal when occurs_inv == 0 && occurs_cov > 1.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The second task is accomplished by imposing a condition on a variable's lower bound. As the subtyping algorithm runs, it narrows the bounds of each variable (raising lower bounds and lowering upper bounds) to keep track of the range of variable values for which the subtype relation would hold. When we are done evaluating the body of a UnionAll type whose variable is diagonal, we look at the final values of the bounds. Since the variable must be concrete, a contradiction occurs if its lower bound could not be a subtype of a concrete type. For example, an abstract type like AbstractArray cannot be a subtype of a concrete type, but a concrete type like Int can be, and the empty type Bottom can be as well. If a lower bound fails this test the algorithm stops with the answer false.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"For example, in the problem Tuple{Int,String} <: Tuple{T,T} where T, we derive that this would be true if T were a supertype of Union{Int,String}. However, Union{Int,String} is an abstract type, so the relation does not hold.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"This concreteness test is done by the function is_leaf_bound. Note that this test is slightly different from jl_is_leaf_type, since it also returns true for Bottom. Currently this function is heuristic, and does not catch all possible concrete types. The difficulty is that whether a lower bound is concrete might depend on the values of other type variable bounds. For example, Vector{T} is equivalent to the concrete type Vector{Int} only if both the upper and lower bounds of T equal Int. We have not yet worked out a complete algorithm for this.","category":"page"},{"location":"devdocs/types/#Introduction-to-the-internal-machinery","page":"More about types","title":"Introduction to the internal machinery","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Most operations for dealing with types are found in the files jltypes.c and subtype.c. A good way to start is to watch subtyping in action. Build Julia with make debug and fire up Julia within a debugger. gdb debugging tips has some tips which may be useful.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Because the subtyping code is used heavily in the REPL itself – and hence breakpoints in this code get triggered often – it will be easiest if you make the following definition:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> function mysubtype(a,b)\n ccall(:jl_breakpoint, Cvoid, (Any,), nothing)\n a <: b\n end","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"and then set a breakpoint in jl_breakpoint. Once this breakpoint gets triggered, you can set breakpoints in other functions.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"As a warm-up, try the following:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"mysubtype(Tuple{Int, Float64}, Tuple{Integer, Real})","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"We can make it more interesting by trying a more complex case:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"mysubtype(Tuple{Array{Int,2}, Int8}, Tuple{Array{T}, T} where T)","category":"page"},{"location":"devdocs/types/#Subtyping-and-method-sorting","page":"More about types","title":"Subtyping and method sorting","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The type_morespecific functions are used for imposing a partial order on functions in method tables (from most-to-least specific). Specificity is strict; if a is more specific than b, then a does not equal b and b is not more specific than a.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"If a is a strict subtype of b, then it is automatically considered more specific. From there, type_morespecific employs some less formal rules. For example, subtype is sensitive to the number of arguments, but type_morespecific may not be. In particular, Tuple{Int,AbstractFloat} is more specific than Tuple{Integer}, even though it is not a subtype. (Of Tuple{Int,AbstractFloat} and Tuple{Integer,Float64}, neither is more specific than the other.) Likewise, Tuple{Int,Vararg{Int}} is not a subtype of Tuple{Integer}, but it is considered more specific. However, morespecific does get a bonus for length: in particular, Tuple{Int,Int} is more specific than Tuple{Int,Vararg{Int}}.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Additionally, if 2 methods are defined with identical signatures, per type-equal, then they will instead by compared by order of addition, such that the later method is more specific than the earlier one.","category":"page"},{"location":"devdocs/locks/#Proper-maintenance-and-care-of-multi-threading-locks","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"","category":"section"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following strategies are used to ensure that the code is dead-lock free (generally by addressing the 4th Coffman condition: circular wait).","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"structure code such that only one lock will need to be acquired at a time\nalways acquire shared locks in the same order, as given by the table below\navoid constructs that expect to need unrestricted recursion","category":"page"},{"location":"devdocs/locks/#Locks","page":"Proper maintenance and care of multi-threading locks","title":"Locks","text":"","category":"section"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Below are all of the locks that exist in the system and the mechanisms for using them that avoid the potential for deadlocks (no Ostrich algorithm allowed here):","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following are definitely leaf locks (level 1), and must not try to acquire any other lock:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"safepoint\nNote that this lock is acquired implicitly by JL_LOCK and JL_UNLOCK. use the _NOGC variants to avoid that for level 1 locks.While holding this lock, the code must not do any allocation or hit any safepoints. Note that there are safepoints when doing allocation, enabling / disabling GC, entering / restoring exception frames, and taking / releasing locks.\nshared_map\nfinalizers\npagealloc\ngcpermlock\nflisp\njlinstackwalk (Win32)\nResourcePool::mutex\nRLST_mutex\nllvmprintingmutex\njllockedstream::mutex\ndebuginfo_asyncsafe\ninferencetimingmutex\nExecutionEngine::SessionLock\nflisp itself is already threadsafe, this lock only protects the jl_ast_context_list_t pool likewise, the ResourcePool::mutexes just protect the associated resource pool","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is a leaf lock (level 2), and only acquires level 1 locks (safepoint) internally:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"globalrootslock\nModule->lock\nJLDebuginfoPlugin::PluginMutex\nnewlyinferredmutex","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is a level 3 lock, which can only acquire level 1 or level 2 locks internally:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Method->writelock\ntypecache","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is a level 4 lock, which can only recurse to acquire level 1, 2, or 3 locks:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"MethodTable->writelock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"No Julia code may be called while holding a lock above this point.","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"orc::ThreadSafeContext (TSCtx) locks occupy a special spot in the locking hierarchy. They are used to protect LLVM's global non-threadsafe state, but there may be an arbitrary number of them. By default, all of these locks may be treated as level 5 locks for the purposes of comparing with the rest of the hierarchy. Acquiring a TSCtx should only be done from the JIT's pool of TSCtx's, and all locks on that TSCtx should be released prior to returning it to the pool. If multiple TSCtx locks must be acquired at the same time (due to recursive compilation), then locks should be acquired in the order that the TSCtxs were borrowed from the pool.","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is a level 5 lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"JuliaOJIT::EmissionMutex","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following are a level 6 lock, which can only recurse to acquire locks at lower levels:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"codegen\njlmodulesmutex","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is an almost root lock (level end-1), meaning only the root look may be held when trying to acquire it:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"typeinf\nthis one is perhaps one of the most tricky ones, since type-inference can be invoked from many pointscurrently the lock is merged with the codegen lock, since they call each other recursively","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following lock synchronizes IO operation. Be aware that doing any I/O (for example, printing warning messages or debug information) while holding any other lock listed above may result in pernicious and hard-to-find deadlocks. BE VERY CAREFUL!","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"iolock\nIndividual ThreadSynchronizers locks\nthis may continue to be held after releasing the iolock, or acquired without it, but be very careful to never attempt to acquire the iolock while holding it\nLibdl.LazyLibrary lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is the root lock, meaning no other lock shall be held when trying to acquire it:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"toplevel\nthis should be held while attempting a top-level action (such as making a new type or defining a new method): trying to obtain this lock inside a staged function will cause a deadlock condition!additionally, it's unclear if any code can safely run in parallel with an arbitrary toplevel expression, so it may require all threads to get to a safepoint first","category":"page"},{"location":"devdocs/locks/#Broken-Locks","page":"Proper maintenance and care of multi-threading locks","title":"Broken Locks","text":"","category":"section"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following locks are broken:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"toplevel\ndoesn't exist right nowfix: create it\nModule->lock\nThis is vulnerable to deadlocks since it can't be certain it is acquired in sequence. Some operations (such as import_module) are missing a lock.fix: replace with jl_modules_mutex?\nloading.jl: require and register_root_module\nThis file potentially has numerous problems.fix: needs locks","category":"page"},{"location":"devdocs/locks/#Shared-Global-Data-Structures","page":"Proper maintenance and care of multi-threading locks","title":"Shared Global Data Structures","text":"","category":"section"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"These data structures each need locks due to being shared mutable global state. It is the inverse list for the above lock priority list. This list does not include level 1 leaf resources due to their simplicity.","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"MethodTable modifications (def, cache) : MethodTable->writelock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Type declarations : toplevel lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Type application : typecache lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Global variable tables : Module->lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Module serializer : toplevel lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"JIT & type-inference : codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"MethodInstance/CodeInstance updates : Method->writelock, codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"These are set at construction and immutable:\nspecTypes\nsparam_vals\ndef\nowner","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"These are set by jl_type_infer (while holding codegen lock):\ncache\nrettype\ninferred","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":" * valid ages","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"inInference flag:\noptimization to quickly avoid recurring into jl_type_infer while it is already running\nactual state (of setting inferred, then fptr) is protected by codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Function pointers:\nthese transition once, from NULL to a value, while the codegen lock is held\nCode-generator cache (the contents of functionObjectsDecls):\nthese can transition multiple times, but only while the codegen lock is held\nit is valid to use old version of this, or block for new versions of this, so races are benign, as long as the code is careful not to reference other data in the method instance (such as rettype) and assume it is coordinated, unless also holding the codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"LLVMContext : codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Method : Method->writelock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"roots array (serializer and codegen)\ninvoke / specializations / tfunc modifications","category":"page"},{"location":"manual/parallel-computing/#Parallel-Computing","page":"Parallel Computing","title":"Parallel Computing","text":"","category":"section"},{"location":"manual/parallel-computing/","page":"Parallel Computing","title":"Parallel Computing","text":"Julia supports these four categories of concurrent and parallel programming:","category":"page"},{"location":"manual/parallel-computing/","page":"Parallel Computing","title":"Parallel Computing","text":"Asynchronous \"tasks\", or coroutines:\nJulia Tasks allow suspending and resuming computations for I/O, event handling, producer-consumer processes, and similar patterns. Tasks can synchronize through operations like wait and fetch, and communicate via Channels. While strictly not parallel computing by themselves, Julia lets you schedule Tasks on several threads.\nMulti-threading:\nJulia's multi-threading provides the ability to schedule Tasks simultaneously on more than one thread or CPU core, sharing memory. This is usually the easiest way to get parallelism on one's PC or on a single large multi-core server. Julia's multi-threading is composable. When one multi-threaded function calls another multi-threaded function, Julia will schedule all the threads globally on available resources, without oversubscribing.\nDistributed computing:\nDistributed computing runs multiple Julia processes with separate memory spaces. These can be on the same computer or multiple computers. The Distributed standard library provides the capability for remote execution of a Julia function. With this basic building block, it is possible to build many different kinds of distributed computing abstractions. Packages like DistributedArrays.jl are an example of such an abstraction. On the other hand, packages like MPI.jl and Elemental.jl provide access to the existing MPI ecosystem of libraries.\nGPU computing:\nThe Julia GPU compiler provides the ability to run Julia code natively on GPUs. There is a rich ecosystem of Julia packages that target GPUs. The JuliaGPU.org website provides a list of capabilities, supported GPUs, related packages and documentation.","category":"page"},{"location":"manual/style-guide/#Style-Guide","page":"Style Guide","title":"Style Guide","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The following sections explain a few aspects of idiomatic Julia coding style. None of these rules are absolute; they are only suggestions to help familiarize you with the language and to help you choose among alternative designs.","category":"page"},{"location":"manual/style-guide/#Indentation","page":"Style Guide","title":"Indentation","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Use 4 spaces per indentation level.","category":"page"},{"location":"manual/style-guide/#Write-functions,-not-just-scripts","page":"Style Guide","title":"Write functions, not just scripts","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Writing code as a series of steps at the top level is a quick way to get started solving a problem, but you should try to divide a program into functions as soon as possible. Functions are more reusable and testable, and clarify what steps are being done and what their inputs and outputs are. Furthermore, code inside functions tends to run much faster than top level code, due to how Julia's compiler works.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"It is also worth emphasizing that functions should take arguments, instead of operating directly on global variables (aside from constants like pi).","category":"page"},{"location":"manual/style-guide/#Avoid-writing-overly-specific-types","page":"Style Guide","title":"Avoid writing overly-specific types","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Code should be as generic as possible. Instead of writing:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Complex{Float64}(x)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"it's better to use available generic functions:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"complex(float(x))","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The second version will convert x to an appropriate type, instead of always the same type.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"This style point is especially relevant to function arguments. For example, don't declare an argument to be of type Int or Int32 if it really could be any integer, expressed with the abstract type Integer. In fact, in many cases you can omit the argument type altogether, unless it is needed to disambiguate from other method definitions, since a MethodError will be thrown anyway if a type is passed that does not support any of the requisite operations. (This is known as duck typing.)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"For example, consider the following definitions of a function addone that returns one plus its argument:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"addone(x::Int) = x + 1 # works only for Int\naddone(x::Integer) = x + oneunit(x) # any integer type\naddone(x::Number) = x + oneunit(x) # any numeric type\naddone(x) = x + oneunit(x) # any type supporting + and oneunit","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The last definition of addone handles any type supporting oneunit (which returns 1 in the same type as x, which avoids unwanted type promotion) and the + function with those arguments. The key thing to realize is that there is no performance penalty to defining only the general addone(x) = x + oneunit(x), because Julia will automatically compile specialized versions as needed. For example, the first time you call addone(12), Julia will automatically compile a specialized addone function for x::Int arguments, with the call to oneunit replaced by its inlined value 1. Therefore, the first three definitions of addone above are completely redundant with the fourth definition.","category":"page"},{"location":"manual/style-guide/#Handle-excess-argument-diversity-in-the-caller","page":"Style Guide","title":"Handle excess argument diversity in the caller","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Instead of:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"function foo(x, y)\n x = Int(x); y = Int(y)\n ...\nend\nfoo(x, y)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"use:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"function foo(x::Int, y::Int)\n ...\nend\nfoo(Int(x), Int(y))","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"This is better style because foo does not really accept numbers of all types; it really needs Int s.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"One issue here is that if a function inherently requires integers, it might be better to force the caller to decide how non-integers should be converted (e.g. floor or ceiling). Another issue is that declaring more specific types leaves more \"space\" for future method definitions.","category":"page"},{"location":"manual/style-guide/#bang-convention","page":"Style Guide","title":"Append ! to names of functions that modify their arguments","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Instead of:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"function double(a::AbstractArray{<:Number})\n for i in eachindex(a)\n a[i] *= 2\n end\n return a\nend","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"use:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"function double!(a::AbstractArray{<:Number})\n for i in eachindex(a)\n a[i] *= 2\n end\n return a\nend","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Julia Base uses this convention throughout and contains examples of functions with both copying and modifying forms (e.g., sort and sort!), and others which are just modifying (e.g., push!, pop!, splice!). It is typical for such functions to also return the modified array for convenience.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Functions related to IO or making use of random number generators (RNG) are notable exceptions: Since these functions almost invariably must mutate the IO or RNG, functions ending with ! are used to signify a mutation other than mutating the IO or advancing the RNG state. For example, rand(x) mutates the RNG, whereas rand!(x) mutates both the RNG and x; similarly, read(io) mutates io, whereas read!(io, x) mutates both arguments.","category":"page"},{"location":"manual/style-guide/#Avoid-strange-type-Unions","page":"Style Guide","title":"Avoid strange type Unions","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Types such as Union{Function,AbstractString} are often a sign that some design could be cleaner.","category":"page"},{"location":"manual/style-guide/#Avoid-elaborate-container-types","page":"Style Guide","title":"Avoid elaborate container types","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"It is usually not much help to construct arrays like the following:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"In this case Vector{Any}(undef, n) is better. It is also more helpful to the compiler to annotate specific uses (e.g. a[i]::Int) than to try to pack many alternatives into one type.","category":"page"},{"location":"manual/style-guide/#Prefer-exported-methods-over-direct-field-access","page":"Style Guide","title":"Prefer exported methods over direct field access","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Idiomatic Julia code should generally treat a module's exported methods as the interface to its types. An object's fields are generally considered implementation details and user code should only access them directly if this is stated to be the API. This has several benefits:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Package developers are freer to change the implementation without breaking user code.\nMethods can be passed to higher-order constructs like map (e.g. map(imag, zs)) rather than [z.im for z in zs]).\nMethods can be defined on abstract types.\nMethods can describe a conceptual operation that can be shared across disparate types (e.g. real(z) works on Complex numbers or Quaternions).","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Julia's dispatch system encourages this style because play(x::MyType) only defines the play method on that particular type, leaving other types to have their own implementation.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Similarly, non-exported functions are typically internal and subject to change, unless the documentations states otherwise. Names sometimes are given a _ prefix (or suffix) to further suggest that something is \"internal\" or an implementation-detail, but it is not a rule.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Counter-examples to this rule include NamedTuple, RegexMatch, StatStruct.","category":"page"},{"location":"manual/style-guide/#Use-naming-conventions-consistent-with-Julia-base/","page":"Style Guide","title":"Use naming conventions consistent with Julia base/","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"modules and type names use capitalization and camel case: module SparseArrays, struct UnitRange.\nfunctions are lowercase (maximum, convert) and, when readable, with multiple words squashed together (isequal, haskey). When necessary, use underscores as word separators. Underscores are also used to indicate a combination of concepts (remotecall_fetch as a more efficient implementation of fetch(remotecall(...))) or as modifiers.\nfunctions mutating at least one of their arguments end in !.\nconciseness is valued, but avoid abbreviation (indexin rather than indxin) as it becomes difficult to remember whether and how particular words are abbreviated.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"If a function name requires multiple words, consider whether it might represent more than one concept and might be better split into pieces.","category":"page"},{"location":"manual/style-guide/#Write-functions-with-argument-ordering-similar-to-Julia-Base","page":"Style Guide","title":"Write functions with argument ordering similar to Julia Base","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"As a general rule, the Base library uses the following order of arguments to functions, as applicable:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Function argument. Putting a function argument first permits the use of do blocks for passing multiline anonymous functions.\nI/O stream. Specifying the IO object first permits passing the function to functions such as sprint, e.g. sprint(show, x).\nInput being mutated. For example, in fill!(x, v), x is the object being mutated and it appears before the value to be inserted into x.\nType. Passing a type typically means that the output will have the given type. In parse(Int, \"1\"), the type comes before the string to parse. There are many such examples where the type appears first, but it's useful to note that in read(io, String), the IO argument appears before the type, which is in keeping with the order outlined here.\nInput not being mutated. In fill!(x, v), v is not being mutated and it comes after x.\nKey. For associative collections, this is the key of the key-value pair(s). For other indexed collections, this is the index.\nValue. For associative collections, this is the value of the key-value pair(s). In cases like fill!(x, v), this is v.\nEverything else. Any other arguments.\nVarargs. This refers to arguments that can be listed indefinitely at the end of a function call. For example, in Matrix{T}(undef, dims), the dimensions can be given as a Tuple, e.g. Matrix{T}(undef, (1,2)), or as Varargs, e.g. Matrix{T}(undef, 1, 2).\nKeyword arguments. In Julia keyword arguments have to come last anyway in function definitions; they're listed here for the sake of completeness.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The vast majority of functions will not take every kind of argument listed above; the numbers merely denote the precedence that should be used for any applicable arguments to a function.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"There are of course a few exceptions. For example, in convert, the type should always come first. In setindex!, the value comes before the indices so that the indices can be provided as varargs.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"When designing APIs, adhering to this general order as much as possible is likely to give users of your functions a more consistent experience.","category":"page"},{"location":"manual/style-guide/#Don't-overuse-try-catch","page":"Style Guide","title":"Don't overuse try-catch","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"It is better to avoid errors than to rely on catching them.","category":"page"},{"location":"manual/style-guide/#Don't-parenthesize-conditions","page":"Style Guide","title":"Don't parenthesize conditions","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Julia doesn't require parens around conditions in if and while. Write:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"if a == b","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"instead of:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"if (a == b)","category":"page"},{"location":"manual/style-guide/#Don't-overuse-...","page":"Style Guide","title":"Don't overuse ...","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Splicing function arguments can be addictive. Instead of [a..., b...], use simply [a; b], which already concatenates arrays. collect(a) is better than [a...], but since a is already iterable it is often even better to leave it alone, and not convert it to an array.","category":"page"},{"location":"manual/style-guide/#Ensure-constructors-return-an-instance-of-their-own-type","page":"Style Guide","title":"Ensure constructors return an instance of their own type","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"When a method T(x) is called on a type T, it is generally expected to return a value of type T. Defining a constructor that returns an unexpected type can lead to confusing and unpredictable behavior:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"julia> struct Foo{T}\n x::T\n end\n\njulia> Base.Float64(foo::Foo) = Foo(Float64(foo.x)) # Do not define methods like this\n\njulia> Float64(Foo(3)) # Should return `Float64`\nFoo{Float64}(3.0)\n\njulia> Foo{Int}(x) = Foo{Float64}(x) # Do not define methods like this\n\njulia> Foo{Int}(3) # Should return `Foo{Int}`\nFoo{Float64}(3.0)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"To maintain code clarity and ensure type consistency, always design constructors to return an instance of the type they are supposed to construct.","category":"page"},{"location":"manual/style-guide/#Don't-use-unnecessary-static-parameters","page":"Style Guide","title":"Don't use unnecessary static parameters","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"A function signature:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"foo(x::T) where {T<:Real} = ...","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"should be written as:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"foo(x::Real) = ...","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"instead, especially if T is not used in the function body. Even if T is used, it can be replaced with typeof(x) if convenient. There is no performance difference. Note that this is not a general caution against static parameters, just against uses where they are not needed.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Note also that container types, specifically may need type parameters in function calls. See the FAQ Avoid fields with abstract containers for more information.","category":"page"},{"location":"manual/style-guide/#Avoid-confusion-about-whether-something-is-an-instance-or-a-type","page":"Style Guide","title":"Avoid confusion about whether something is an instance or a type","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Sets of definitions like the following are confusing:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"foo(::Type{MyType}) = ...\nfoo(::MyType) = foo(MyType)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Decide whether the concept in question will be written as MyType or MyType(), and stick to it.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The preferred style is to use instances by default, and only add methods involving Type{MyType} later if they become necessary to solve some problems.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"If a type is effectively an enumeration, it should be defined as a single (ideally immutable struct or primitive) type, with the enumeration values being instances of it. Constructors and conversions can check whether values are valid. This design is preferred over making the enumeration an abstract type, with the \"values\" as subtypes.","category":"page"},{"location":"manual/style-guide/#Don't-overuse-macros","page":"Style Guide","title":"Don't overuse macros","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Be aware of when a macro could really be a function instead.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Calling eval inside a macro is a particularly dangerous warning sign; it means the macro will only work when called at the top level. If such a macro is written as a function instead, it will naturally have access to the run-time values it needs.","category":"page"},{"location":"manual/style-guide/#Don't-expose-unsafe-operations-at-the-interface-level","page":"Style Guide","title":"Don't expose unsafe operations at the interface level","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"If you have a type that uses a native pointer:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"mutable struct NativeType\n p::Ptr{UInt8}\n ...\nend","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"don't write definitions like the following:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"getindex(x::NativeType, i) = unsafe_load(x.p, i)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The problem is that users of this type can write x[i] without realizing that the operation is unsafe, and then be susceptible to memory bugs.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Such a function should either check the operation to ensure it is safe, or have unsafe somewhere in its name to alert callers.","category":"page"},{"location":"manual/style-guide/#Don't-overload-methods-of-base-container-types","page":"Style Guide","title":"Don't overload methods of base container types","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"It is possible to write definitions like the following:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"show(io::IO, v::Vector{MyType}) = ...","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"This would provide custom showing of vectors with a specific new element type. While tempting, this should be avoided. The trouble is that users will expect a well-known type like Vector() to behave in a certain way, and overly customizing its behavior can make it harder to work with.","category":"page"},{"location":"manual/style-guide/#avoid-type-piracy","page":"Style Guide","title":"Avoid type piracy","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"\"Type piracy\" refers to the practice of extending or redefining methods in Base or other packages on types that you have not defined. In extreme cases, you can crash Julia (e.g. if your method extension or redefinition causes invalid input to be passed to a ccall). Type piracy can complicate reasoning about code, and may introduce incompatibilities that are hard to predict and diagnose.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"As an example, suppose you wanted to define multiplication on symbols in a module:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"module A\nimport Base.*\n*(x::Symbol, y::Symbol) = Symbol(x,y)\nend","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The problem is that now any other module that uses Base.* will also see this definition. Since Symbol is defined in Base and is used by other modules, this can change the behavior of unrelated code unexpectedly. There are several alternatives here, including using a different function name, or wrapping the Symbols in another type that you define.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Sometimes, coupled packages may engage in type piracy to separate features from definitions, especially when the packages were designed by collaborating authors, and when the definitions are reusable. For example, one package might provide some types useful for working with colors; another package could define methods for those types that enable conversions between color spaces. Another example might be a package that acts as a thin wrapper for some C code, which another package might then pirate to implement a higher-level, Julia-friendly API.","category":"page"},{"location":"manual/style-guide/#Be-careful-with-type-equality","page":"Style Guide","title":"Be careful with type equality","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"You generally want to use isa and <: for testing types, not ==. Checking types for exact equality typically only makes sense when comparing to a known concrete type (e.g. T == Float64), or if you really, really know what you're doing.","category":"page"},{"location":"manual/style-guide/#Don't-write-a-trivial-anonymous-function-x-f(x)-for-a-named-function-f","page":"Style Guide","title":"Don't write a trivial anonymous function x->f(x) for a named function f","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Since higher-order functions are often called with anonymous functions, it is easy to conclude that this is desirable or even necessary. But any function can be passed directly, without being \"wrapped\" in an anonymous function. Instead of writing map(x->f(x), a), write map(f, a).","category":"page"},{"location":"manual/style-guide/#Avoid-using-floats-for-numeric-literals-in-generic-code-when-possible","page":"Style Guide","title":"Avoid using floats for numeric literals in generic code when possible","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"If you write generic code which handles numbers, and which can be expected to run with many different numeric type arguments, try using literals of a numeric type that will affect the arguments as little as possible through promotion.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"For example,","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"julia> f(x) = 2.0 * x\nf (generic function with 1 method)\n\njulia> f(1//2)\n1.0\n\njulia> f(1/2)\n1.0\n\njulia> f(1)\n2.0","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"while","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"julia> g(x) = 2 * x\ng (generic function with 1 method)\n\njulia> g(1//2)\n1//1\n\njulia> g(1/2)\n1.0\n\njulia> g(1)\n2","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"As you can see, the second version, where we used an Int literal, preserved the type of the input argument, while the first didn't. This is because e.g. promote_type(Int, Float64) == Float64, and promotion happens with the multiplication. Similarly, Rational literals are less type disruptive than Float64 literals, but more disruptive than Ints:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"julia> h(x) = 2//1 * x\nh (generic function with 1 method)\n\njulia> h(1//2)\n1//1\n\njulia> h(1/2)\n1.0\n\njulia> h(1)\n2//1","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Thus, use Int literals when possible, with Rational{Int} for literal non-integer numbers, in order to make it easier to use your code.","category":"page"},{"location":"base/math/#Mathematics","page":"Mathematics","title":"Mathematics","text":"","category":"section"},{"location":"base/math/#math-ops","page":"Mathematics","title":"Mathematical Operators","text":"","category":"section"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Base.:-(::Any)\nBase.:(+)\nBase.:-(::Any, ::Any)\nBase.:*(::Any, ::Any...)\nBase.:(/)\nBase.:\\(::Any, ::Any)\nBase.:^(::Number, ::Number)\nBase.fma\nBase.muladd\nBase.inv(::Number)\nBase.div\nBase.div(::Any, ::Any, ::RoundingMode)\nBase.fld\nBase.cld\nBase.mod\nBase.rem\nBase.rem(::Any, ::Any, ::RoundingMode)\nBase.rem2pi\nBase.Math.mod2pi\nBase.divrem\nBase.fldmod\nBase.fld1\nBase.mod1\nBase.fldmod1\nBase.:(//)\nBase.rationalize\nBase.numerator\nBase.denominator\nBase.:(<<)\nBase.:(>>)\nBase.:(>>>)\nBase.bitrotate\nBase.:(:)\nBase.range\nBase.OneTo\nBase.StepRangeLen\nBase.logrange\nBase.LogRange\nBase.:(==)\nBase.:(!=)\nBase.:(!==)\nBase.:(<)\nBase.:(<=)\nBase.:(>)\nBase.:(>=)\nBase.cmp\nBase.:(~)\nBase.:(&)\nBase.:(|)\nBase.xor\nBase.nand\nBase.nor\nBase.:(!)\n&&\n||","category":"page"},{"location":"base/math/#Base.:--Tuple{Any}","page":"Mathematics","title":"Base.:-","text":"-(x)\n\nUnary minus operator.\n\nSee also: abs, flipsign.\n\nExamples\n\njulia> -1\n-1\n\njulia> -(2)\n-2\n\njulia> -[1 2; 3 4]\n2×2 Matrix{Int64}:\n -1 -2\n -3 -4\n\njulia> -(true) # promotes to Int\n-1\n\njulia> -(0x003)\n0xfffd\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.:+","page":"Mathematics","title":"Base.:+","text":"dt::Date + t::Time -> DateTime\n\nThe addition of a Date with a Time produces a DateTime. The hour, minute, second, and millisecond parts of the Time are used along with the year, month, and day of the Date to create the new DateTime. Non-zero microseconds or nanoseconds in the Time type will result in an InexactError being thrown.\n\n\n\n\n\n+(x, y...)\n\nAddition operator.\n\nInfix x+y+z+... calls this function with all arguments, i.e. +(x, y, z, ...), which by default then calls (x+y) + z + ... starting from the left.\n\nNote that overflow is possible for most integer types, including the default Int, when adding large numbers.\n\nExamples\n\njulia> 1 + 20 + 4\n25\n\njulia> +(1, 20, 4)\n25\n\njulia> [1,2] + [3,4]\n2-element Vector{Int64}:\n 4\n 6\n\njulia> typemax(Int) + 1 < 0\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:--Tuple{Any, Any}","page":"Mathematics","title":"Base.:-","text":"-(x, y)\n\nSubtraction operator.\n\nExamples\n\njulia> 2 - 3\n-1\n\njulia> -(2, 4.5)\n-2.5\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.:*-Tuple{Any, Vararg{Any}}","page":"Mathematics","title":"Base.:*","text":"*(x, y...)\n\nMultiplication operator.\n\nInfix x*y*z*... calls this function with all arguments, i.e. *(x, y, z, ...), which by default then calls (x*y) * z * ... starting from the left.\n\nJuxtaposition such as 2pi also calls *(2, pi). Note that this operation has higher precedence than a literal *. Note also that juxtaposition \"0x...\" (integer zero times a variable whose name starts with x) is forbidden as it clashes with unsigned integer literals: 0x01 isa UInt8.\n\nNote that overflow is possible for most integer types, including the default Int, when multiplying large numbers.\n\nExamples\n\njulia> 2 * 7 * 8\n112\n\njulia> *(2, 7, 8)\n112\n\njulia> [2 0; 0 3] * [1, 10] # matrix * vector\n2-element Vector{Int64}:\n 2\n 30\n\njulia> 1/2pi, 1/2*pi # juxtaposition has higher precedence\n(0.15915494309189535, 1.5707963267948966)\n\njulia> x = [1, 2]; x'x # adjoint vector * vector\n5\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.:/","page":"Mathematics","title":"Base.:/","text":"/(x, y)\n\nRight division operator: multiplication of x by the inverse of y on the right.\n\nGives floating-point results for integer arguments. See ÷ for integer division, or // for Rational results.\n\nExamples\n\njulia> 1/2\n0.5\n\njulia> 4/2\n2.0\n\njulia> 4.5/2\n2.25\n\n\n\n\n\nA / B\n\nMatrix right-division: A / B is equivalent to (B' \\ A')' where \\ is the left-division operator. For square matrices, the result X is such that A == X*B.\n\nSee also: rdiv!.\n\nExamples\n\njulia> A = Float64[1 4 5; 3 9 2]; B = Float64[1 4 2; 3 4 2; 8 7 1];\n\njulia> X = A / B\n2×3 Matrix{Float64}:\n -0.65 3.75 -1.2\n 3.25 -2.75 1.0\n\njulia> isapprox(A, X*B)\ntrue\n\njulia> isapprox(X, A*pinv(B))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:\\-Tuple{Any, Any}","page":"Mathematics","title":"Base.:\\","text":"\\(x, y)\n\nLeft division operator: multiplication of y by the inverse of x on the left. Gives floating-point results for integer arguments.\n\nExamples\n\njulia> 3 \\ 6\n2.0\n\njulia> inv(3) * 6\n2.0\n\njulia> A = [4 3; 2 1]; x = [5, 6];\n\njulia> A \\ x\n2-element Vector{Float64}:\n 6.5\n -7.0\n\njulia> inv(A) * x\n2-element Vector{Float64}:\n 6.5\n -7.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.:^-Tuple{Number, Number}","page":"Mathematics","title":"Base.:^","text":"^(x, y)\n\nExponentiation operator.\n\nIf x and y are integers, the result may overflow. To enter numbers in scientific notation, use Float64 literals such as 1.2e3 rather than 1.2 * 10^3.\n\nIf y is an Int literal (e.g. 2 in x^2 or -3 in x^-3), the Julia code x^y is transformed by the compiler to Base.literal_pow(^, x, Val(y)), to enable compile-time specialization on the value of the exponent. (As a default fallback we have Base.literal_pow(^, x, Val(y)) = ^(x,y), where usually ^ == Base.^ unless ^ has been defined in the calling namespace.) If y is a negative integer literal, then Base.literal_pow transforms the operation to inv(x)^-y by default, where -y is positive.\n\nSee also exp2, <<.\n\nExamples\n\njulia> 3^5\n243\n\njulia> 3^-1 # uses Base.literal_pow\n0.3333333333333333\n\njulia> p = -1;\n\njulia> 3^p\nERROR: DomainError with -1:\nCannot raise an integer x to a negative power -1.\n[...]\n\njulia> 3.0^p\n0.3333333333333333\n\njulia> 10^19 > 0 # integer overflow\nfalse\n\njulia> big(10)^19 == 1e19\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.fma","page":"Mathematics","title":"Base.fma","text":"fma(x, y, z)\n\nComputes x*y+z without rounding the intermediate result x*y. On some systems this is significantly more expensive than x*y+z. fma is used to improve accuracy in certain algorithms. See muladd.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.muladd","page":"Mathematics","title":"Base.muladd","text":"muladd(x, y, z)\n\nCombined multiply-add: computes x*y+z, but allowing the add and multiply to be merged with each other or with surrounding operations for performance. For example, this may be implemented as an fma if the hardware supports it efficiently. The result can be different on different machines and can also be different on the same machine due to constant propagation or other optimizations. See fma.\n\nExamples\n\njulia> muladd(3, 2, 1)\n7\n\njulia> 3 * 2 + 1\n7\n\n\n\n\n\nmuladd(A, y, z)\n\nCombined multiply-add, A*y .+ z, for matrix-matrix or matrix-vector multiplication. The result is always the same size as A*y, but z may be smaller, or a scalar.\n\ncompat: Julia 1.6\nThese methods require Julia 1.6 or later.\n\nExamples\n\njulia> A=[1.0 2.0; 3.0 4.0]; B=[1.0 1.0; 1.0 1.0]; z=[0, 100];\n\njulia> muladd(A, B, z)\n2×2 Matrix{Float64}:\n 3.0 3.0\n 107.0 107.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.inv-Tuple{Number}","page":"Mathematics","title":"Base.inv","text":"inv(x)\n\nReturn the multiplicative inverse of x, such that x*inv(x) or inv(x)*x yields one(x) (the multiplicative identity) up to roundoff errors.\n\nIf x is a number, this is essentially the same as one(x)/x, but for some types inv(x) may be slightly more efficient.\n\nExamples\n\njulia> inv(2)\n0.5\n\njulia> inv(1 + 2im)\n0.2 - 0.4im\n\njulia> inv(1 + 2im) * (1 + 2im)\n1.0 + 0.0im\n\njulia> inv(2//3)\n3//2\n\ncompat: Julia 1.2\ninv(::Missing) requires at least Julia 1.2.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.div","page":"Mathematics","title":"Base.div","text":"div(x, y)\n÷(x, y)\n\nThe quotient from Euclidean (integer) division. Generally equivalent to a mathematical operation x/y without a fractional part.\n\nSee also: cld, fld, rem, divrem.\n\nExamples\n\njulia> 9 ÷ 4\n2\n\njulia> -5 ÷ 3\n-1\n\njulia> 5.0 ÷ 2\n2.0\n\njulia> div.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n -1 -1 -1 0 0 0 0 0 1 1 1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.div-Tuple{Any, Any, RoundingMode}","page":"Mathematics","title":"Base.div","text":"div(x, y, r::RoundingMode=RoundToZero)\n\nThe quotient from Euclidean (integer) division. Computes x / y, rounded to an integer according to the rounding mode r. In other words, the quantity\n\nround(x / y, r)\n\nwithout any intermediate rounding.\n\ncompat: Julia 1.4\nThe three-argument method taking a RoundingMode requires Julia 1.4 or later.\n\nSee also fld and cld, which are special cases of this function.\n\ncompat: Julia 1.9\nRoundFromZero requires at least Julia 1.9.\n\nExamples:\n\njulia> div(4, 3, RoundToZero) # Matches div(4, 3)\n1\njulia> div(4, 3, RoundDown) # Matches fld(4, 3)\n1\njulia> div(4, 3, RoundUp) # Matches cld(4, 3)\n2\njulia> div(5, 2, RoundNearest)\n2\njulia> div(5, 2, RoundNearestTiesAway)\n3\njulia> div(-5, 2, RoundNearest)\n-2\njulia> div(-5, 2, RoundNearestTiesAway)\n-3\njulia> div(-5, 2, RoundNearestTiesUp)\n-2\njulia> div(4, 3, RoundFromZero)\n2\njulia> div(-4, 3, RoundFromZero)\n-2\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.fld","page":"Mathematics","title":"Base.fld","text":"fld(x, y)\n\nLargest integer less than or equal to x / y. Equivalent to div(x, y, RoundDown).\n\nSee also div, cld, fld1.\n\nExamples\n\njulia> fld(7.3, 5.5)\n1.0\n\njulia> fld.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n -2 -2 -1 -1 -1 0 0 0 1 1 1\n\nBecause fld(x, y) implements strictly correct floored rounding based on the true value of floating-point numbers, unintuitive situations can arise. For example:\n\njulia> fld(6.0, 0.1)\n59.0\njulia> 6.0 / 0.1\n60.0\njulia> 6.0 / big(0.1)\n59.99999999999999666933092612453056361837965690217069245739573412231113406246995\n\nWhat is happening here is that the true value of the floating-point number written as 0.1 is slightly larger than the numerical value 1/10 while 6.0 represents the number 6 precisely. Therefore the true value of 6.0 / 0.1 is slightly less than 60. When doing division, this is rounded to precisely 60.0, but fld(6.0, 0.1) always takes the floor of the true value, so the result is 59.0.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.cld","page":"Mathematics","title":"Base.cld","text":"cld(x, y)\n\nSmallest integer larger than or equal to x / y. Equivalent to div(x, y, RoundUp).\n\nSee also div, fld.\n\nExamples\n\njulia> cld(5.5, 2.2)\n3.0\n\njulia> cld.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n -1 -1 -1 0 0 0 1 1 1 2 2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.mod","page":"Mathematics","title":"Base.mod","text":"mod(x::Integer, r::AbstractUnitRange)\n\nFind y in the range r such that x y (mod n), where n = length(r), i.e. y = mod(x - first(r), n) + first(r).\n\nSee also mod1.\n\nExamples\n\njulia> mod(0, Base.OneTo(3)) # mod1(0, 3)\n3\n\njulia> mod(3, 0:2) # mod(3, 3)\n0\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\n\n\n\n\nmod(x, y)\nrem(x, y, RoundDown)\n\nThe reduction of x modulo y, or equivalently, the remainder of x after floored division by y, i.e. x - y*fld(x,y) if computed without intermediate rounding.\n\nThe result will have the same sign as y, and magnitude less than abs(y) (with some exceptions, see note below).\n\nnote: Note\nWhen used with floating point values, the exact result may not be representable by the type, and so rounding error may occur. In particular, if the exact result is very close to y, then it may be rounded to y.\n\nSee also: rem, div, fld, mod1, invmod.\n\njulia> mod(8, 3)\n2\n\njulia> mod(9, 3)\n0\n\njulia> mod(8.9, 3)\n2.9000000000000004\n\njulia> mod(eps(), 3)\n2.220446049250313e-16\n\njulia> mod(-eps(), 3)\n3.0\n\njulia> mod.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n 1 2 0 1 2 0 1 2 0 1 2\n\n\n\n\n\nrem(x::Integer, T::Type{<:Integer}) -> T\nmod(x::Integer, T::Type{<:Integer}) -> T\n%(x::Integer, T::Type{<:Integer}) -> T\n\nFind y::T such that x ≡ y (mod n), where n is the number of integers representable in T, and y is an integer in [typemin(T),typemax(T)]. If T can represent any integer (e.g. T == BigInt), then this operation corresponds to a conversion to T.\n\nExamples\n\njulia> x = 129 % Int8\n-127\n\njulia> typeof(x)\nInt8\n\njulia> x = 129 % BigInt\n129\n\njulia> typeof(x)\nBigInt\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.rem","page":"Mathematics","title":"Base.rem","text":"rem(x, y)\n%(x, y)\n\nRemainder from Euclidean division, returning a value of the same sign as x, and smaller in magnitude than y. This value is always exact.\n\nSee also: div, mod, mod1, divrem.\n\nExamples\n\njulia> x = 15; y = 4;\n\njulia> x % y\n3\n\njulia> x == div(x, y) * y + rem(x, y)\ntrue\n\njulia> rem.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n -2 -1 0 -2 -1 0 1 2 0 1 2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.rem-Tuple{Any, Any, RoundingMode}","page":"Mathematics","title":"Base.rem","text":"rem(x, y, r::RoundingMode=RoundToZero)\n\nCompute the remainder of x after integer division by y, with the quotient rounded according to the rounding mode r. In other words, the quantity\n\nx - y * round(x / y, r)\n\nwithout any intermediate rounding.\n\nif r == RoundNearest, then the result is exact, and in the interval -y 2 y 2. See also RoundNearest.\nif r == RoundToZero (default), then the result is exact, and in the interval 0 y) if x is positive, or (-y 0 otherwise. See also RoundToZero.\nif r == RoundDown, then the result is in the interval 0 y) if y is positive, or (y 0 otherwise. The result may not be exact if x and y have different signs, and abs(x) < abs(y). See also RoundDown.\nif r == RoundUp, then the result is in the interval (-y 0 if y is positive, or 0 -y) otherwise. The result may not be exact if x and y have the same sign, and abs(x) < abs(y). See also RoundUp.\nif r == RoundFromZero, then the result is in the interval (-y 0 if y is positive, or 0 -y) otherwise. The result may not be exact if x and y have the same sign, and abs(x) < abs(y). See also RoundFromZero.\n\ncompat: Julia 1.9\nRoundFromZero requires at least Julia 1.9.\n\nExamples:\n\njulia> x = 9; y = 4;\n\njulia> x % y # same as rem(x, y)\n1\n\njulia> x ÷ y # same as div(x, y)\n2\n\njulia> x == div(x, y) * y + rem(x, y)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.rem2pi","page":"Mathematics","title":"Base.Math.rem2pi","text":"rem2pi(x, r::RoundingMode)\n\nCompute the remainder of x after integer division by 2π, with the quotient rounded according to the rounding mode r. In other words, the quantity\n\nx - 2π*round(x/(2π),r)\n\nwithout any intermediate rounding. This internally uses a high precision approximation of 2π, and so will give a more accurate result than rem(x,2π,r)\n\nif r == RoundNearest, then the result is in the interval -π π. This will generally be the most accurate result. See also RoundNearest.\nif r == RoundToZero, then the result is in the interval 0 2π if x is positive,. or -2π 0 otherwise. See also RoundToZero.\nif r == RoundDown, then the result is in the interval 0 2π. See also RoundDown.\nif r == RoundUp, then the result is in the interval -2π 0. See also RoundUp.\n\nExamples\n\njulia> rem2pi(7pi/4, RoundNearest)\n-0.7853981633974485\n\njulia> rem2pi(7pi/4, RoundDown)\n5.497787143782138\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.mod2pi","page":"Mathematics","title":"Base.Math.mod2pi","text":"mod2pi(x)\n\nModulus after division by 2π, returning in the range 02π).\n\nThis function computes a floating point representation of the modulus after division by numerically exact 2π, and is therefore not exactly the same as mod(x,2π), which would compute the modulus of x relative to division by the floating-point number 2π.\n\nnote: Note\nDepending on the format of the input value, the closest representable value to 2π may be less than 2π. For example, the expression mod2pi(2π) will not return 0, because the intermediate value of 2*π is a Float64 and 2*Float64(π) < 2*big(π). See rem2pi for more refined control of this behavior.\n\nExamples\n\njulia> mod2pi(9*pi/4)\n0.7853981633974481\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.divrem","page":"Mathematics","title":"Base.divrem","text":"divrem(x, y, r::RoundingMode=RoundToZero)\n\nThe quotient and remainder from Euclidean division. Equivalent to (div(x, y, r), rem(x, y, r)). Equivalently, with the default value of r, this call is equivalent to (x ÷ y, x % y).\n\nSee also: fldmod, cld.\n\nExamples\n\njulia> divrem(3, 7)\n(0, 3)\n\njulia> divrem(7, 3)\n(2, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.fldmod","page":"Mathematics","title":"Base.fldmod","text":"fldmod(x, y)\n\nThe floored quotient and modulus after division. A convenience wrapper for divrem(x, y, RoundDown). Equivalent to (fld(x, y), mod(x, y)).\n\nSee also: fld, cld, fldmod1.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.fld1","page":"Mathematics","title":"Base.fld1","text":"fld1(x, y)\n\nFlooring division, returning a value consistent with mod1(x,y)\n\nSee also mod1, fldmod1.\n\nExamples\n\njulia> x = 15; y = 4;\n\njulia> fld1(x, y)\n4\n\njulia> x == fld(x, y) * y + mod(x, y)\ntrue\n\njulia> x == (fld1(x, y) - 1) * y + mod1(x, y)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.mod1","page":"Mathematics","title":"Base.mod1","text":"mod1(x, y)\n\nModulus after flooring division, returning a value r such that mod(r, y) == mod(x, y) in the range (0 y for positive y and in the range y0) for negative y.\n\nWith integer arguments and positive y, this is equal to mod(x, 1:y), and hence natural for 1-based indexing. By comparison, mod(x, y) == mod(x, 0:y-1) is natural for computations with offsets or strides.\n\nSee also mod, fld1, fldmod1.\n\nExamples\n\njulia> mod1(4, 2)\n2\n\njulia> mod1.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n 1 2 3 1 2 3 1 2 3 1 2\n\njulia> mod1.([-0.1, 0, 0.1, 1, 2, 2.9, 3, 3.1]', 3)\n1×8 Matrix{Float64}:\n 2.9 3.0 0.1 1.0 2.0 2.9 3.0 0.1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.fldmod1","page":"Mathematics","title":"Base.fldmod1","text":"fldmod1(x, y)\n\nReturn (fld1(x,y), mod1(x,y)).\n\nSee also fld1, mod1.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.://","page":"Mathematics","title":"Base.://","text":"//(num, den)\n\nDivide two integers or rational numbers, giving a Rational result. More generally, // can be used for exact rational division of other numeric types with integer or rational components, such as complex numbers with integer components.\n\nNote that floating-point (AbstractFloat) arguments are not permitted by // (even if the values are rational). The arguments must be subtypes of Integer, Rational, or composites thereof.\n\nExamples\n\njulia> 3 // 5\n3//5\n\njulia> (3 // 5) // (2 // 1)\n3//10\n\njulia> (1+2im) // (3+4im)\n11//25 + 2//25*im\n\njulia> 1.0 // 2\nERROR: MethodError: no method matching //(::Float64, ::Int64)\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.rationalize","page":"Mathematics","title":"Base.rationalize","text":"rationalize([T<:Integer=Int,] x; tol::Real=eps(x))\n\nApproximate floating point number x as a Rational number with components of the given integer type. The result will differ from x by no more than tol.\n\nExamples\n\njulia> rationalize(5.6)\n28//5\n\njulia> a = rationalize(BigInt, 10.3)\n103//10\n\njulia> typeof(numerator(a))\nBigInt\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.numerator","page":"Mathematics","title":"Base.numerator","text":"numerator(x)\n\nNumerator of the rational representation of x.\n\nExamples\n\njulia> numerator(2//3)\n2\n\njulia> numerator(4)\n4\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.denominator","page":"Mathematics","title":"Base.denominator","text":"denominator(x)\n\nDenominator of the rational representation of x.\n\nExamples\n\njulia> denominator(2//3)\n3\n\njulia> denominator(4)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:<<","page":"Mathematics","title":"Base.:<<","text":"<<(x, n)\n\nLeft bit shift operator, x << n. For n >= 0, the result is x shifted left by n bits, filling with 0s. This is equivalent to x * 2^n. For n < 0, this is equivalent to x >> -n.\n\nExamples\n\njulia> Int8(3) << 2\n12\n\njulia> bitstring(Int8(3))\n\"00000011\"\n\njulia> bitstring(Int8(12))\n\"00001100\"\n\nSee also >>, >>>, exp2, ldexp.\n\n\n\n\n\n<<(B::BitVector, n) -> BitVector\n\nLeft bit shift operator, B << n. For n >= 0, the result is B with elements shifted n positions backwards, filling with false values. If n < 0, elements are shifted forwards. Equivalent to B >> -n.\n\nExamples\n\njulia> B = BitVector([true, false, true, false, false])\n5-element BitVector:\n 1\n 0\n 1\n 0\n 0\n\njulia> B << 1\n5-element BitVector:\n 0\n 1\n 0\n 0\n 0\n\njulia> B << -1\n5-element BitVector:\n 0\n 1\n 0\n 1\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:>>","page":"Mathematics","title":"Base.:>>","text":">>(x, n)\n\nRight bit shift operator, x >> n. For n >= 0, the result is x shifted right by n bits, filling with 0s if x >= 0, 1s if x < 0, preserving the sign of x. This is equivalent to fld(x, 2^n). For n < 0, this is equivalent to x << -n.\n\nExamples\n\njulia> Int8(13) >> 2\n3\n\njulia> bitstring(Int8(13))\n\"00001101\"\n\njulia> bitstring(Int8(3))\n\"00000011\"\n\njulia> Int8(-14) >> 2\n-4\n\njulia> bitstring(Int8(-14))\n\"11110010\"\n\njulia> bitstring(Int8(-4))\n\"11111100\"\n\nSee also >>>, <<.\n\n\n\n\n\n>>(B::BitVector, n) -> BitVector\n\nRight bit shift operator, B >> n. For n >= 0, the result is B with elements shifted n positions forward, filling with false values. If n < 0, elements are shifted backwards. Equivalent to B << -n.\n\nExamples\n\njulia> B = BitVector([true, false, true, false, false])\n5-element BitVector:\n 1\n 0\n 1\n 0\n 0\n\njulia> B >> 1\n5-element BitVector:\n 0\n 1\n 0\n 1\n 0\n\njulia> B >> -1\n5-element BitVector:\n 0\n 1\n 0\n 0\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:>>>","page":"Mathematics","title":"Base.:>>>","text":">>>(x, n)\n\nUnsigned right bit shift operator, x >>> n. For n >= 0, the result is x shifted right by n bits, filling with 0s. For n < 0, this is equivalent to x << -n.\n\nFor Unsigned integer types, this is equivalent to >>. For Signed integer types, this is equivalent to signed(unsigned(x) >> n).\n\nExamples\n\njulia> Int8(-14) >>> 2\n60\n\njulia> bitstring(Int8(-14))\n\"11110010\"\n\njulia> bitstring(Int8(60))\n\"00111100\"\n\nBigInts are treated as if having infinite size, so no filling is required and this is equivalent to >>.\n\nSee also >>, <<.\n\n\n\n\n\n>>>(B::BitVector, n) -> BitVector\n\nUnsigned right bitshift operator, B >>> n. Equivalent to B >> n. See >> for details and examples.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.bitrotate","page":"Mathematics","title":"Base.bitrotate","text":"bitrotate(x::Base.BitInteger, k::Integer)\n\nbitrotate(x, k) implements bitwise rotation. It returns the value of x with its bits rotated left k times. A negative value of k will rotate to the right instead.\n\ncompat: Julia 1.5\nThis function requires Julia 1.5 or later.\n\nSee also: <<, circshift, BitArray.\n\njulia> bitrotate(UInt8(114), 2)\n0xc9\n\njulia> bitstring(bitrotate(0b01110010, 2))\n\"11001001\"\n\njulia> bitstring(bitrotate(0b01110010, -2))\n\"10011100\"\n\njulia> bitstring(bitrotate(0b01110010, 8))\n\"01110010\"\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.::","page":"Mathematics","title":"Base.::","text":":expr\n\nQuote an expression expr, returning the abstract syntax tree (AST) of expr. The AST may be of type Expr, Symbol, or a literal value. The syntax :identifier evaluates to a Symbol.\n\nSee also: Expr, Symbol, Meta.parse\n\nExamples\n\njulia> expr = :(a = b + 2*x)\n:(a = b + 2x)\n\njulia> sym = :some_identifier\n:some_identifier\n\njulia> value = :0xff\n0xff\n\njulia> typeof((expr, sym, value))\nTuple{Expr, Symbol, UInt8}\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.range","page":"Mathematics","title":"Base.range","text":"range(start, stop, length)\nrange(start, stop; length, step)\nrange(start; length, stop, step)\nrange(;start, length, stop, step)\n\nConstruct a specialized array with evenly spaced elements and optimized storage (an AbstractRange) from the arguments. Mathematically a range is uniquely determined by any three of start, step, stop and length. Valid invocations of range are:\n\nCall range with any three of start, step, stop, length.\nCall range with two of start, stop, length. In this case step will be assumed to be one. If both arguments are Integers, a UnitRange will be returned.\nCall range with one of stop or length. start and step will be assumed to be one.\n\nSee Extended Help for additional details on the returned type. See also logrange for logarithmically spaced points.\n\nExamples\n\njulia> range(1, length=100)\n1:100\n\njulia> range(1, stop=100)\n1:100\n\njulia> range(1, step=5, length=100)\n1:5:496\n\njulia> range(1, step=5, stop=100)\n1:5:96\n\njulia> range(1, 10, length=101)\n1.0:0.09:10.0\n\njulia> range(1, 100, step=5)\n1:5:96\n\njulia> range(stop=10, length=5)\n6:10\n\njulia> range(stop=10, step=1, length=5)\n6:1:10\n\njulia> range(start=1, step=1, stop=10)\n1:1:10\n\njulia> range(; length = 10)\nBase.OneTo(10)\n\njulia> range(; stop = 6)\nBase.OneTo(6)\n\njulia> range(; stop = 6.5)\n1.0:1.0:6.0\n\nIf length is not specified and stop - start is not an integer multiple of step, a range that ends before stop will be produced.\n\njulia> range(1, 3.5, step=2)\n1.0:2.0:3.0\n\nSpecial care is taken to ensure intermediate values are computed rationally. To avoid this induced overhead, see the LinRange constructor.\n\ncompat: Julia 1.1\nstop as a positional argument requires at least Julia 1.1.\n\ncompat: Julia 1.7\nThe versions without keyword arguments and start as a keyword argument require at least Julia 1.7.\n\ncompat: Julia 1.8\nThe versions with stop as a sole keyword argument, or length as a sole keyword argument require at least Julia 1.8.\n\nExtended Help\n\nrange will produce a Base.OneTo when the arguments are Integers and\n\nOnly length is provided\nOnly stop is provided\n\nrange will produce a UnitRange when the arguments are Integers and\n\nOnly start and stop are provided\nOnly length and stop are provided\n\nA UnitRange is not produced if step is provided even if specified as one.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.OneTo","page":"Mathematics","title":"Base.OneTo","text":"Base.OneTo(n)\n\nDefine an AbstractUnitRange that behaves like 1:n, with the added distinction that the lower limit is guaranteed (by the type system) to be 1.\n\n\n\n\n\n","category":"type"},{"location":"base/math/#Base.StepRangeLen","page":"Mathematics","title":"Base.StepRangeLen","text":"StepRangeLen( ref::R, step::S, len, [offset=1]) where { R,S}\nStepRangeLen{T,R,S}( ref::R, step::S, len, [offset=1]) where {T,R,S}\nStepRangeLen{T,R,S,L}(ref::R, step::S, len, [offset=1]) where {T,R,S,L}\n\nA range r where r[i] produces values of type T (in the first form, T is deduced automatically), parameterized by a reference value, a step, and the length. By default ref is the starting value r[1], but alternatively you can supply it as the value of r[offset] for some other index 1 <= offset <= len. The syntax a:b or a:b:c, where any of a, b, or c are floating-point numbers, creates a StepRangeLen.\n\ncompat: Julia 1.7\nThe 4th type parameter L requires at least Julia 1.7.\n\n\n\n\n\n","category":"type"},{"location":"base/math/#Base.logrange","page":"Mathematics","title":"Base.logrange","text":"logrange(start, stop, length)\nlogrange(start, stop; length)\n\nConstruct a specialized array whose elements are spaced logarithmically between the given endpoints. That is, the ratio of successive elements is a constant, calculated from the length.\n\nThis is similar to geomspace in Python. Unlike PowerRange in Mathematica, you specify the number of elements not the ratio. Unlike logspace in Python and Matlab, the start and stop arguments are always the first and last elements of the result, not powers applied to some base.\n\nExamples\n\njulia> logrange(10, 4000, length=3)\n3-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}:\n 10.0, 200.0, 4000.0\n\njulia> ans[2] ≈ sqrt(10 * 4000) # middle element is the geometric mean\ntrue\n\njulia> range(10, 40, length=3)[2] ≈ (10 + 40)/2 # arithmetic mean\ntrue\n\njulia> logrange(1f0, 32f0, 11)\n11-element Base.LogRange{Float32, Float64}:\n 1.0, 1.41421, 2.0, 2.82843, 4.0, 5.65685, 8.0, 11.3137, 16.0, 22.6274, 32.0\n\njulia> logrange(1, 1000, length=4) ≈ 10 .^ (0:3)\ntrue\n\nSee the LogRange type for further details.\n\nSee also range for linearly spaced points.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.LogRange","page":"Mathematics","title":"Base.LogRange","text":"LogRange{T}(start, stop, len) <: AbstractVector{T}\n\nA range whose elements are spaced logarithmically between start and stop, with spacing controlled by len. Returned by logrange.\n\nLike LinRange, the first and last elements will be exactly those provided, but intermediate values may have small floating-point errors. These are calculated using the logs of the endpoints, which are stored on construction, often in higher precision than T.\n\nExamples\n\njulia> logrange(1, 4, length=5)\n5-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}:\n 1.0, 1.41421, 2.0, 2.82843, 4.0\n\njulia> Base.LogRange{Float16}(1, 4, 5)\n5-element Base.LogRange{Float16, Float64}:\n 1.0, 1.414, 2.0, 2.828, 4.0\n\njulia> logrange(1e-310, 1e-300, 11)[1:2:end]\n6-element Vector{Float64}:\n 1.0e-310\n 9.999999999999974e-309\n 9.999999999999981e-307\n 9.999999999999988e-305\n 9.999999999999994e-303\n 1.0e-300\n\njulia> prevfloat(1e-308, 5) == ans[2]\ntrue\n\nNote that integer eltype T is not allowed. Use for instance round.(Int, xs), or explicit powers of some integer base:\n\njulia> xs = logrange(1, 512, 4)\n4-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}:\n 1.0, 8.0, 64.0, 512.0\n\njulia> 2 .^ (0:3:9) |> println\n[1, 8, 64, 512]\n\ncompat: Julia 1.11\nThis type requires at least Julia 1.11.\n\n\n\n\n\n","category":"type"},{"location":"base/math/#Base.:==","page":"Mathematics","title":"Base.:==","text":"==(x, y)\n\nGeneric equality operator. Falls back to ===. Should be implemented for all types with a notion of equality, based on the abstract value that an instance represents. For example, all numeric types are compared by numeric value, ignoring type. Strings are compared as sequences of characters, ignoring encoding. Collections of the same type generally compare their key sets, and if those are ==, then compare the values for each of those keys, returning true if all such pairs are ==. Other properties are typically not taken into account (such as the exact type).\n\nThis operator follows IEEE semantics for floating-point numbers: 0.0 == -0.0 and NaN != NaN.\n\nThe result is of type Bool, except when one of the operands is missing, in which case missing is returned (three-valued logic). Collections generally implement three-valued logic akin to all, returning missing if any operands contain missing values and all other pairs are equal. Use isequal or === to always get a Bool result.\n\nImplementation\n\nNew numeric types should implement this function for two arguments of the new type, and handle comparison to other types via promotion rules where possible.\n\nisequal falls back to ==, so new methods of == will be used by the Dict type to compare keys. If your type will be used as a dictionary key, it should therefore also implement hash.\n\nIf some type defines ==, isequal, and isless then it should also implement < to ensure consistency of comparisons.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:!=","page":"Mathematics","title":"Base.:!=","text":"!=(x, y)\n≠(x,y)\n\nNot-equals comparison operator. Always gives the opposite answer as ==.\n\nImplementation\n\nNew types should generally not implement this, and rely on the fallback definition !=(x,y) = !(x==y) instead.\n\nExamples\n\njulia> 3 != 2\ntrue\n\njulia> \"foo\" ≠ \"foo\"\nfalse\n\n\n\n\n\n!=(x)\n\nCreate a function that compares its argument to x using !=, i.e. a function equivalent to y -> y != x. The returned function is of type Base.Fix2{typeof(!=)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:!==","page":"Mathematics","title":"Base.:!==","text":"!==(x, y)\n≢(x,y)\n\nAlways gives the opposite answer as ===.\n\nExamples\n\njulia> a = [1, 2]; b = [1, 2];\n\njulia> a ≢ b\ntrue\n\njulia> a ≢ a\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:<","page":"Mathematics","title":"Base.:<","text":"<(x, y)\n\nLess-than comparison operator. Falls back to isless. Because of the behavior of floating-point NaN values, this operator implements a partial order.\n\nImplementation\n\nNew types with a canonical partial order should implement this function for two arguments of the new type. Types with a canonical total order should implement isless instead.\n\nSee also isunordered.\n\nExamples\n\njulia> 'a' < 'b'\ntrue\n\njulia> \"abc\" < \"abd\"\ntrue\n\njulia> 5 < 3\nfalse\n\n\n\n\n\n<(x)\n\nCreate a function that compares its argument to x using <, i.e. a function equivalent to y -> y < x. The returned function is of type Base.Fix2{typeof(<)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:<=","page":"Mathematics","title":"Base.:<=","text":"<=(x, y)\n≤(x,y)\n\nLess-than-or-equals comparison operator. Falls back to (x < y) | (x == y).\n\nExamples\n\njulia> 'a' <= 'b'\ntrue\n\njulia> 7 ≤ 7 ≤ 9\ntrue\n\njulia> \"abc\" ≤ \"abc\"\ntrue\n\njulia> 5 <= 3\nfalse\n\n\n\n\n\n<=(x)\n\nCreate a function that compares its argument to x using <=, i.e. a function equivalent to y -> y <= x. The returned function is of type Base.Fix2{typeof(<=)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:>","page":"Mathematics","title":"Base.:>","text":">(x, y)\n\nGreater-than comparison operator. Falls back to y < x.\n\nImplementation\n\nGenerally, new types should implement < instead of this function, and rely on the fallback definition >(x, y) = y < x.\n\nExamples\n\njulia> 'a' > 'b'\nfalse\n\njulia> 7 > 3 > 1\ntrue\n\njulia> \"abc\" > \"abd\"\nfalse\n\njulia> 5 > 3\ntrue\n\n\n\n\n\n>(x)\n\nCreate a function that compares its argument to x using >, i.e. a function equivalent to y -> y > x. The returned function is of type Base.Fix2{typeof(>)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:>=","page":"Mathematics","title":"Base.:>=","text":">=(x, y)\n≥(x,y)\n\nGreater-than-or-equals comparison operator. Falls back to y <= x.\n\nExamples\n\njulia> 'a' >= 'b'\nfalse\n\njulia> 7 ≥ 7 ≥ 3\ntrue\n\njulia> \"abc\" ≥ \"abc\"\ntrue\n\njulia> 5 >= 3\ntrue\n\n\n\n\n\n>=(x)\n\nCreate a function that compares its argument to x using >=, i.e. a function equivalent to y -> y >= x. The returned function is of type Base.Fix2{typeof(>=)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.cmp","page":"Mathematics","title":"Base.cmp","text":"cmp(x,y)\n\nReturn -1, 0, or 1 depending on whether x is less than, equal to, or greater than y, respectively. Uses the total order implemented by isless.\n\nExamples\n\njulia> cmp(1, 2)\n-1\n\njulia> cmp(2, 1)\n1\n\njulia> cmp(2+im, 3-im)\nERROR: MethodError: no method matching isless(::Complex{Int64}, ::Complex{Int64})\n[...]\n\n\n\n\n\ncmp(<, x, y)\n\nReturn -1, 0, or 1 depending on whether x is less than, equal to, or greater than y, respectively. The first argument specifies a less-than comparison function to use.\n\n\n\n\n\ncmp(a::AbstractString, b::AbstractString) -> Int\n\nCompare two strings. Return 0 if both strings have the same length and the character at each index is the same in both strings. Return -1 if a is a prefix of b, or if a comes before b in alphabetical order. Return 1 if b is a prefix of a, or if b comes before a in alphabetical order (technically, lexicographical order by Unicode code points).\n\nExamples\n\njulia> cmp(\"abc\", \"abc\")\n0\n\njulia> cmp(\"ab\", \"abc\")\n-1\n\njulia> cmp(\"abc\", \"ab\")\n1\n\njulia> cmp(\"ab\", \"ac\")\n-1\n\njulia> cmp(\"ac\", \"ab\")\n1\n\njulia> cmp(\"α\", \"a\")\n1\n\njulia> cmp(\"b\", \"β\")\n-1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:~","page":"Mathematics","title":"Base.:~","text":"~(x)\n\nBitwise not.\n\nSee also: !, &, |.\n\nExamples\n\njulia> ~4\n-5\n\njulia> ~10\n-11\n\njulia> ~true\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:&","page":"Mathematics","title":"Base.:&","text":"x & y\n\nBitwise and. Implements three-valued logic, returning missing if one operand is missing and the other is true. Add parentheses for function application form: (&)(x, y).\n\nSee also: |, xor, &&.\n\nExamples\n\njulia> 4 & 10\n0\n\njulia> 4 & 12\n4\n\njulia> true & missing\nmissing\n\njulia> false & missing\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:|","page":"Mathematics","title":"Base.:|","text":"x | y\n\nBitwise or. Implements three-valued logic, returning missing if one operand is missing and the other is false.\n\nSee also: &, xor, ||.\n\nExamples\n\njulia> 4 | 10\n14\n\njulia> 4 | 1\n5\n\njulia> true | missing\ntrue\n\njulia> false | missing\nmissing\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.xor","page":"Mathematics","title":"Base.xor","text":"xor(x, y)\n⊻(x, y)\n\nBitwise exclusive or of x and y. Implements three-valued logic, returning missing if one of the arguments is missing.\n\nThe infix operation a ⊻ b is a synonym for xor(a,b), and ⊻ can be typed by tab-completing \\xor or \\veebar in the Julia REPL.\n\nExamples\n\njulia> xor(true, false)\ntrue\n\njulia> xor(true, true)\nfalse\n\njulia> xor(true, missing)\nmissing\n\njulia> false ⊻ false\nfalse\n\njulia> [true; true; false] .⊻ [true; false; false]\n3-element BitVector:\n 0\n 1\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.nand","page":"Mathematics","title":"Base.nand","text":"nand(x, y)\n⊼(x, y)\n\nBitwise nand (not and) of x and y. Implements three-valued logic, returning missing if one of the arguments is missing.\n\nThe infix operation a ⊼ b is a synonym for nand(a,b), and ⊼ can be typed by tab-completing \\nand or \\barwedge in the Julia REPL.\n\nExamples\n\njulia> nand(true, false)\ntrue\n\njulia> nand(true, true)\nfalse\n\njulia> nand(true, missing)\nmissing\n\njulia> false ⊼ false\ntrue\n\njulia> [true; true; false] .⊼ [true; false; false]\n3-element BitVector:\n 0\n 1\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.nor","page":"Mathematics","title":"Base.nor","text":"nor(x, y)\n⊽(x, y)\n\nBitwise nor (not or) of x and y. Implements three-valued logic, returning missing if one of the arguments is missing and the other is not true.\n\nThe infix operation a ⊽ b is a synonym for nor(a,b), and ⊽ can be typed by tab-completing \\nor or \\barvee in the Julia REPL.\n\nExamples\n\njulia> nor(true, false)\nfalse\n\njulia> nor(true, true)\nfalse\n\njulia> nor(true, missing)\nfalse\n\njulia> false ⊽ false\ntrue\n\njulia> false ⊽ missing\nmissing\n\njulia> [true; true; false] .⊽ [true; false; false]\n3-element BitVector:\n 0\n 0\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:!","page":"Mathematics","title":"Base.:!","text":"!(x)\n\nBoolean not. Implements three-valued logic, returning missing if x is missing.\n\nSee also ~ for bitwise not.\n\nExamples\n\njulia> !true\nfalse\n\njulia> !false\ntrue\n\njulia> !missing\nmissing\n\njulia> .![true false true]\n1×3 BitMatrix:\n 0 1 0\n\n\n\n\n\n!f::Function\n\nPredicate function negation: when the argument of ! is a function, it returns a composed function which computes the boolean negation of f.\n\nSee also ∘.\n\nExamples\n\njulia> str = \"∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε\"\n\"∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε\"\n\njulia> filter(isletter, str)\n\"εδxyδfxfyε\"\n\njulia> filter(!isletter, str)\n\"∀ > 0, ∃ > 0: |-| < ⇒ |()-()| < \"\n\ncompat: Julia 1.9\nStarting with Julia 1.9, !f returns a ComposedFunction instead of an anonymous function.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#&&","page":"Mathematics","title":"&&","text":"x && y\n\nShort-circuiting boolean AND.\n\nSee also &, the ternary operator ? :, and the manual section on control flow.\n\nExamples\n\njulia> x = 3;\n\njulia> x > 1 && x < 10 && x isa Int\ntrue\n\njulia> x < 0 && error(\"expected positive x\")\nfalse\n\n\n\n\n\n","category":"keyword"},{"location":"base/math/#||","page":"Mathematics","title":"||","text":"x || y\n\nShort-circuiting boolean OR.\n\nSee also: |, xor, &&.\n\nExamples\n\njulia> pi < 3 || ℯ < 3\ntrue\n\njulia> false || true || println(\"neither is true!\")\ntrue\n\n\n\n\n\n","category":"keyword"},{"location":"base/math/#Mathematical-Functions","page":"Mathematics","title":"Mathematical Functions","text":"","category":"section"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Base.isapprox\nBase.sin(::Number)\nBase.cos(::Number)\nBase.sincos(::Float64)\nBase.tan(::Number)\nBase.Math.sind\nBase.Math.cosd\nBase.Math.tand\nBase.Math.sincosd\nBase.Math.sinpi\nBase.Math.cospi\nBase.Math.sincospi\nBase.sinh(::Number)\nBase.cosh(::Number)\nBase.tanh(::Number)\nBase.asin(::Number)\nBase.acos(::Number)\nBase.atan(::Number)\nBase.Math.asind\nBase.Math.acosd\nBase.Math.atand\nBase.Math.sec(::Number)\nBase.Math.csc(::Number)\nBase.Math.cot(::Number)\nBase.Math.secd\nBase.Math.cscd\nBase.Math.cotd\nBase.Math.asec(::Number)\nBase.Math.acsc(::Number)\nBase.Math.acot(::Number)\nBase.Math.asecd\nBase.Math.acscd\nBase.Math.acotd\nBase.Math.sech(::Number)\nBase.Math.csch(::Number)\nBase.Math.coth(::Number)\nBase.asinh(::Number)\nBase.acosh(::Number)\nBase.atanh(::Number)\nBase.Math.asech(::Number)\nBase.Math.acsch(::Number)\nBase.Math.acoth(::Number)\nBase.Math.sinc\nBase.Math.cosc\nBase.Math.deg2rad\nBase.Math.rad2deg\nBase.Math.hypot\nBase.log(::Number)\nBase.log(::Number, ::Number)\nBase.log2\nBase.log10\nBase.log1p\nBase.Math.frexp\nBase.exp(::Float64)\nBase.exp2\nBase.exp10\nBase.Math.ldexp\nBase.Math.modf\nBase.expm1\nBase.round\nBase.Rounding.RoundingMode\nBase.Rounding.RoundNearest\nBase.Rounding.RoundNearestTiesAway\nBase.Rounding.RoundNearestTiesUp\nBase.Rounding.RoundToZero\nBase.Rounding.RoundFromZero\nBase.Rounding.RoundUp\nBase.Rounding.RoundDown\nBase.round(::Complex{<: AbstractFloat}, ::RoundingMode, ::RoundingMode)\nBase.ceil\nBase.floor\nBase.trunc\nBase.unsafe_trunc\nBase.min\nBase.max\nBase.minmax\nBase.Math.clamp\nBase.Math.clamp!\nBase.abs\nBase.Checked\nBase.Checked.checked_abs\nBase.Checked.checked_neg\nBase.Checked.checked_add\nBase.Checked.checked_sub\nBase.Checked.checked_mul\nBase.Checked.checked_div\nBase.Checked.checked_rem\nBase.Checked.checked_fld\nBase.Checked.checked_mod\nBase.Checked.checked_cld\nBase.Checked.checked_pow\nBase.Checked.add_with_overflow\nBase.Checked.sub_with_overflow\nBase.Checked.mul_with_overflow\nBase.abs2\nBase.copysign\nBase.sign\nBase.signbit\nBase.flipsign\nBase.sqrt(::Number)\nBase.isqrt\nBase.Math.cbrt(::AbstractFloat)\nBase.real\nBase.imag\nBase.reim\nBase.conj\nBase.angle\nBase.cis\nBase.cispi\nBase.binomial\nBase.factorial\nBase.gcd\nBase.lcm\nBase.gcdx\nBase.ispow2\nBase.nextpow\nBase.prevpow\nBase.nextprod\nBase.invmod\nBase.powermod\nBase.ndigits\nBase.add_sum\nBase.widemul\nBase.Math.evalpoly\nBase.Math.@evalpoly\nBase.FastMath.@fastmath","category":"page"},{"location":"base/math/#Base.isapprox","page":"Mathematics","title":"Base.isapprox","text":"isapprox(x, y; atol::Real=0, rtol::Real=atol>0 ? 0 : √eps, nans::Bool=false[, norm::Function])\n\nInexact equality comparison. Two numbers compare equal if their relative distance or their absolute distance is within tolerance bounds: isapprox returns true if norm(x-y) <= max(atol, rtol*max(norm(x), norm(y))). The default atol (absolute tolerance) is zero and the default rtol (relative tolerance) depends on the types of x and y. The keyword argument nans determines whether or not NaN values are considered equal (defaults to false).\n\nFor real or complex floating-point values, if an atol > 0 is not specified, rtol defaults to the square root of eps of the type of x or y, whichever is bigger (least precise). This corresponds to requiring equality of about half of the significant digits. Otherwise, e.g. for integer arguments or if an atol > 0 is supplied, rtol defaults to zero.\n\nThe norm keyword defaults to abs for numeric (x,y) and to LinearAlgebra.norm for arrays (where an alternative norm choice is sometimes useful). When x and y are arrays, if norm(x-y) is not finite (i.e. ±Inf or NaN), the comparison falls back to checking whether all elements of x and y are approximately equal component-wise.\n\nThe binary operator ≈ is equivalent to isapprox with the default arguments, and x ≉ y is equivalent to !isapprox(x,y).\n\nNote that x ≈ 0 (i.e., comparing to zero with the default tolerances) is equivalent to x == 0 since the default atol is 0. In such cases, you should either supply an appropriate atol (or use norm(x) ≤ atol) or rearrange your code (e.g. use x ≈ y rather than x - y ≈ 0). It is not possible to pick a nonzero atol automatically because it depends on the overall scaling (the \"units\") of your problem: for example, in x - y ≈ 0, atol=1e-9 is an absurdly small tolerance if x is the radius of the Earth in meters, but an absurdly large tolerance if x is the radius of a Hydrogen atom in meters.\n\ncompat: Julia 1.6\nPassing the norm keyword argument when comparing numeric (non-array) arguments requires Julia 1.6 or later.\n\nExamples\n\njulia> isapprox(0.1, 0.15; atol=0.05)\ntrue\n\njulia> isapprox(0.1, 0.15; rtol=0.34)\ntrue\n\njulia> isapprox(0.1, 0.15; rtol=0.33)\nfalse\n\njulia> 0.1 + 1e-10 ≈ 0.1\ntrue\n\njulia> 1e-10 ≈ 0\nfalse\n\njulia> isapprox(1e-10, 0, atol=1e-8)\ntrue\n\njulia> isapprox([10.0^9, 1.0], [10.0^9, 2.0]) # using `norm`\ntrue\n\n\n\n\n\nisapprox(x; kwargs...) / ≈(x; kwargs...)\n\nCreate a function that compares its argument to x using ≈, i.e. a function equivalent to y -> y ≈ x.\n\nThe keyword arguments supported here are the same as those in the 2-argument isapprox.\n\ncompat: Julia 1.5\nThis method requires Julia 1.5 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.sin-Tuple{Number}","page":"Mathematics","title":"Base.sin","text":"sin(x::T) where {T <: Number} -> float(T)\n\nCompute sine of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also sind, sinpi, sincos, cis, asin.\n\nExamples\n\njulia> round.(sin.(range(0, 2pi, length=9)'), digits=3)\n1×9 Matrix{Float64}:\n 0.0 0.707 1.0 0.707 0.0 -0.707 -1.0 -0.707 -0.0\n\njulia> sind(45)\n0.7071067811865476\n\njulia> sinpi(1/4)\n0.7071067811865475\n\njulia> round.(sincos(pi/6), digits=3)\n(0.5, 0.866)\n\njulia> round(cis(pi/6), digits=3)\n0.866 + 0.5im\n\njulia> round(exp(im*pi/6), digits=3)\n0.866 + 0.5im\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.cos-Tuple{Number}","page":"Mathematics","title":"Base.cos","text":"cos(x::T) where {T <: Number} -> float(T)\n\nCompute cosine of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also cosd, cospi, sincos, cis.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.sincos-Tuple{Float64}","page":"Mathematics","title":"Base.Math.sincos","text":"sincos(x::T) where T -> float(T)\n\nSimultaneously compute the sine and cosine of x, where x is in radians, returning a tuple (sine, cosine).\n\nThrow a DomainError if isinf(x), return a (T(NaN), T(NaN)) if isnan(x).\n\nSee also cis, sincospi, sincosd.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.tan-Tuple{Number}","page":"Mathematics","title":"Base.tan","text":"tan(x::T) where {T <: Number} -> float(T)\n\nCompute tangent of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also tanh.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.sind","page":"Mathematics","title":"Base.Math.sind","text":"sind(x::T) where T -> float(T)\n\nCompute sine of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cosd","page":"Mathematics","title":"Base.Math.cosd","text":"cosd(x::T) where T -> float(T)\n\nCompute cosine of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.tand","page":"Mathematics","title":"Base.Math.tand","text":"tand(x::T) where T -> float(T)\n\nCompute tangent of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sincosd","page":"Mathematics","title":"Base.Math.sincosd","text":"sincosd(x::T) where T -> float(T)\n\nSimultaneously compute the sine and cosine of x, where x is in degrees.\n\nThrow a DomainError if isinf(x), return a (T(NaN), T(NaN)) tuple if isnan(x).\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sinpi","page":"Mathematics","title":"Base.Math.sinpi","text":"sinpi(x::T) where T -> float(T)\n\nCompute sin(pi x) more accurately than sin(pi*x), especially for large x.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also sind, cospi, sincospi.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cospi","page":"Mathematics","title":"Base.Math.cospi","text":"cospi(x::T) where T -> float(T)\n\nCompute cos(pi x) more accurately than cos(pi*x), especially for large x.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also: cispi, sincosd, cospi.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sincospi","page":"Mathematics","title":"Base.Math.sincospi","text":"sincospi(x::T) where T -> float(T)\n\nSimultaneously compute sinpi(x) and cospi(x) (the sine and cosine of π*x, where x is in radians), returning a tuple (sine, cosine).\n\nThrow a DomainError if isinf(x), return a (T(NaN), T(NaN)) tuple if isnan(x).\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\nSee also: cispi, sincosd, sinpi.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.sinh-Tuple{Number}","page":"Mathematics","title":"Base.sinh","text":"sinh(x)\n\nCompute hyperbolic sine of x.\n\nSee also sin.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.cosh-Tuple{Number}","page":"Mathematics","title":"Base.cosh","text":"cosh(x)\n\nCompute hyperbolic cosine of x.\n\nSee also cos.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.tanh-Tuple{Number}","page":"Mathematics","title":"Base.tanh","text":"tanh(x)\n\nCompute hyperbolic tangent of x.\n\nSee also tan, atanh.\n\nExamples\n\njulia> tanh.(-3:3f0) # Here 3f0 isa Float32\n7-element Vector{Float32}:\n -0.9950548\n -0.9640276\n -0.7615942\n 0.0\n 0.7615942\n 0.9640276\n 0.9950548\n\njulia> tan.(im .* (1:3))\n3-element Vector{ComplexF64}:\n 0.0 + 0.7615941559557649im\n 0.0 + 0.9640275800758169im\n 0.0 + 0.9950547536867306im\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.asin-Tuple{Number}","page":"Mathematics","title":"Base.asin","text":"asin(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse sine of x, where the output is in radians.\n\nReturn a T(NaN) if isnan(x).\n\nSee also asind for output in degrees.\n\nExamples\n\njulia> asin.((0, 1/2, 1))\n(0.0, 0.5235987755982989, 1.5707963267948966)\n\njulia> asind.((0, 1/2, 1))\n(0.0, 30.000000000000004, 90.0)\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.acos-Tuple{Number}","page":"Mathematics","title":"Base.acos","text":"acos(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse cosine of x, where the output is in radians\n\nReturn a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.atan-Tuple{Number}","page":"Mathematics","title":"Base.atan","text":"atan(y)\natan(y, x)\n\nCompute the inverse tangent of y or y/x, respectively.\n\nFor one real argument, this is the angle in radians between the positive x-axis and the point (1, y), returning a value in the interval -pi2 pi2.\n\nFor two arguments, this is the angle in radians between the positive x-axis and the point (x, y), returning a value in the interval -pi pi. This corresponds to a standard atan2 function. Note that by convention atan(0.0,x) is defined as pi and atan(-0.0,x) is defined as -pi when x < 0.\n\nSee also atand for degrees.\n\nExamples\n\njulia> rad2deg(atan(-1/√3))\n-30.000000000000004\n\njulia> rad2deg(atan(-1, √3))\n-30.000000000000004\n\njulia> rad2deg(atan(1, -√3))\n150.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.asind","page":"Mathematics","title":"Base.Math.asind","text":"asind(x)\n\nCompute the inverse sine of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.acosd","page":"Mathematics","title":"Base.Math.acosd","text":"acosd(x)\n\nCompute the inverse cosine of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.atand","page":"Mathematics","title":"Base.Math.atand","text":"atand(y::T) where T -> float(T)\natand(y::T, x::S) where {T,S} -> promote_type(T,S)\natand(y::AbstractMatrix{T}) where T -> AbstractMatrix{Complex{float(T)}}\n\nCompute the inverse tangent of y or y/x, respectively, where the output is in degrees.\n\nReturn a NaN if isnan(y) or isnan(x). The returned NaN is either a T in the single argument version, or a promote_type(T,S) in the two argument version.\n\ncompat: Julia 1.7\nThe one-argument method supports square matrix arguments as of Julia 1.7.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sec-Tuple{Number}","page":"Mathematics","title":"Base.Math.sec","text":"sec(x::T) where {T <: Number} -> float(T)\n\nCompute the secant of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.csc-Tuple{Number}","page":"Mathematics","title":"Base.Math.csc","text":"csc(x::T) where {T <: Number} -> float(T)\n\nCompute the cosecant of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.cot-Tuple{Number}","page":"Mathematics","title":"Base.Math.cot","text":"cot(x::T) where {T <: Number} -> float(T)\n\nCompute the cotangent of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.secd","page":"Mathematics","title":"Base.Math.secd","text":"secd(x::T) where {T <: Number} -> float(T)\n\nCompute the secant of x, where x is in degrees.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cscd","page":"Mathematics","title":"Base.Math.cscd","text":"cscd(x::T) where {T <: Number} -> float(T)\n\nCompute the cosecant of x, where x is in degrees.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cotd","page":"Mathematics","title":"Base.Math.cotd","text":"cotd(x::T) where {T <: Number} -> float(T)\n\nCompute the cotangent of x, where x is in degrees.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.asec-Tuple{Number}","page":"Mathematics","title":"Base.Math.asec","text":"asec(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse secant of x, where the output is in radians.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.acsc-Tuple{Number}","page":"Mathematics","title":"Base.Math.acsc","text":"acsc(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse cosecant of x, where the output is in radians.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.acot-Tuple{Number}","page":"Mathematics","title":"Base.Math.acot","text":"acot(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse cotangent of x, where the output is in radians.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.asecd","page":"Mathematics","title":"Base.Math.asecd","text":"asecd(x)\n\nCompute the inverse secant of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.acscd","page":"Mathematics","title":"Base.Math.acscd","text":"acscd(x)\n\nCompute the inverse cosecant of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.acotd","page":"Mathematics","title":"Base.Math.acotd","text":"acotd(x)\n\nCompute the inverse cotangent of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sech-Tuple{Number}","page":"Mathematics","title":"Base.Math.sech","text":"sech(x::T) where {T <: Number} -> float(T)\n\nCompute the hyperbolic secant of x.\n\nReturn a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.csch-Tuple{Number}","page":"Mathematics","title":"Base.Math.csch","text":"csch(x::T) where {T <: Number} -> float(T)\n\nCompute the hyperbolic cosecant of x.\n\nReturn a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.coth-Tuple{Number}","page":"Mathematics","title":"Base.Math.coth","text":"coth(x::T) where {T <: Number} -> float(T)\n\nCompute the hyperbolic cotangent of x.\n\nReturn a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.asinh-Tuple{Number}","page":"Mathematics","title":"Base.asinh","text":"asinh(x)\n\nCompute the inverse hyperbolic sine of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.acosh-Tuple{Number}","page":"Mathematics","title":"Base.acosh","text":"acosh(x)\n\nCompute the inverse hyperbolic cosine of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.atanh-Tuple{Number}","page":"Mathematics","title":"Base.atanh","text":"atanh(x)\n\nCompute the inverse hyperbolic tangent of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.asech-Tuple{Number}","page":"Mathematics","title":"Base.Math.asech","text":"asech(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse hyperbolic secant of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.acsch-Tuple{Number}","page":"Mathematics","title":"Base.Math.acsch","text":"acsch(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse hyperbolic cosecant of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.acoth-Tuple{Number}","page":"Mathematics","title":"Base.Math.acoth","text":"acoth(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse hyperbolic cotangent of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.sinc","page":"Mathematics","title":"Base.Math.sinc","text":"sinc(x::T) where {T <: Number} -> float(T)\n\nCompute normalized sinc function operatornamesinc(x) = sin(pi x) (pi x) if x neq 0, and 1 if x = 0.\n\nReturn a T(NaN) if isnan(x).\n\nSee also cosc, its derivative.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cosc","page":"Mathematics","title":"Base.Math.cosc","text":"cosc(x::T) where {T <: Number} -> float(T)\n\nCompute cos(pi x) x - sin(pi x) (pi x^2) if x neq 0, and 0 if x = 0. This is the derivative of sinc(x).\n\nReturn a T(NaN) if isnan(x).\n\nSee also sinc.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.deg2rad","page":"Mathematics","title":"Base.Math.deg2rad","text":"deg2rad(x)\n\nConvert x from degrees to radians.\n\nSee also rad2deg, sind, pi.\n\nExamples\n\njulia> deg2rad(90)\n1.5707963267948966\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.rad2deg","page":"Mathematics","title":"Base.Math.rad2deg","text":"rad2deg(x)\n\nConvert x from radians to degrees.\n\nSee also deg2rad.\n\nExamples\n\njulia> rad2deg(pi)\n180.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.hypot","page":"Mathematics","title":"Base.Math.hypot","text":"hypot(x, y)\n\nCompute the hypotenuse sqrtx^2+y^2 avoiding overflow and underflow.\n\nThis code is an implementation of the algorithm described in: An Improved Algorithm for hypot(a,b) by Carlos F. Borges The article is available online at arXiv at the link https://arxiv.org/abs/1904.09481\n\nhypot(x...)\n\nCompute the hypotenuse sqrtsum x_i^2 avoiding overflow and underflow.\n\nSee also norm in the LinearAlgebra standard library.\n\nExamples\n\njulia> a = Int64(10)^10;\n\njulia> hypot(a, a)\n1.4142135623730951e10\n\njulia> √(a^2 + a^2) # a^2 overflows\nERROR: DomainError with -2.914184810805068e18:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]\n\njulia> hypot(3, 4im)\n5.0\n\njulia> hypot(-5.7)\n5.7\n\njulia> hypot(3, 4im, 12.0)\n13.0\n\njulia> using LinearAlgebra\n\njulia> norm([a, a, a, a]) == hypot(a, a, a, a)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.log-Tuple{Number}","page":"Mathematics","title":"Base.log","text":"log(x)\n\nCompute the natural logarithm of x.\n\nThrow a DomainError for negative Real arguments. Use Complex arguments to obtain Complex results.\n\nnote: Branch cut\nlog has a branch cut along the negative real axis; -0.0im is taken to be below the axis.\n\nSee also ℯ, log1p, log2, log10.\n\nExamples\n\njulia> log(2)\n0.6931471805599453\n\njulia> log(-3)\nERROR: DomainError with -3.0:\nlog was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31\n[...]\n\njulia> log(-3 + 0im)\n1.0986122886681098 + 3.141592653589793im\n\njulia> log(-3 - 0.0im)\n1.0986122886681098 - 3.141592653589793im\n\njulia> log.(exp.(-1:1))\n3-element Vector{Float64}:\n -1.0\n 0.0\n 1.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.log-Tuple{Number, Number}","page":"Mathematics","title":"Base.log","text":"log(b,x)\n\nCompute the base b logarithm of x. Throw a DomainError for negative Real arguments.\n\nExamples\n\njulia> log(4,8)\n1.5\n\njulia> log(4,2)\n0.5\n\njulia> log(-2, 3)\nERROR: DomainError with -2.0:\nlog was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31\n[...]\n\njulia> log(2, -3)\nERROR: DomainError with -3.0:\nlog was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31\n[...]\n\nnote: Note\nIf b is a power of 2 or 10, log2 or log10 should be used, as these will typically be faster and more accurate. For example,julia> log(100,1000000)\n2.9999999999999996\n\njulia> log10(1000000)/2\n3.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.log2","page":"Mathematics","title":"Base.log2","text":"log2(x)\n\nCompute the logarithm of x to base 2. Throw a DomainError for negative Real arguments.\n\nSee also: exp2, ldexp, ispow2.\n\nExamples\n\njulia> log2(4)\n2.0\n\njulia> log2(10)\n3.321928094887362\n\njulia> log2(-2)\nERROR: DomainError with -2.0:\nlog2 was called with a negative real argument but will only return a complex result if called with a complex argument. Try log2(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(f::Symbol, x::Float64) at ./math.jl:31\n[...]\n\njulia> log2.(2.0 .^ (-1:1))\n3-element Vector{Float64}:\n -1.0\n 0.0\n 1.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.log10","page":"Mathematics","title":"Base.log10","text":"log10(x)\n\nCompute the logarithm of x to base 10. Throw a DomainError for negative Real arguments.\n\nExamples\n\njulia> log10(100)\n2.0\n\njulia> log10(2)\n0.3010299956639812\n\njulia> log10(-2)\nERROR: DomainError with -2.0:\nlog10 was called with a negative real argument but will only return a complex result if called with a complex argument. Try log10(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(f::Symbol, x::Float64) at ./math.jl:31\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.log1p","page":"Mathematics","title":"Base.log1p","text":"log1p(x)\n\nAccurate natural logarithm of 1+x. Throw a DomainError for Real arguments less than -1.\n\nExamples\n\njulia> log1p(-0.5)\n-0.6931471805599453\n\njulia> log1p(0)\n0.0\n\njulia> log1p(-2)\nERROR: DomainError with -2.0:\nlog1p was called with a real argument < -1 but will only return a complex result if called with a complex argument. Try log1p(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.frexp","page":"Mathematics","title":"Base.Math.frexp","text":"frexp(val)\n\nReturn (x,exp) such that x has a magnitude in the interval 12 1) or 0, and val is equal to x times 2^exp.\n\nSee also significand, exponent, ldexp.\n\nExamples\n\njulia> frexp(6.0)\n(0.75, 3)\n\njulia> significand(6.0), exponent(6.0) # interval [1, 2) instead\n(1.5, 2)\n\njulia> frexp(0.0), frexp(NaN), frexp(-Inf) # exponent would give an error\n((0.0, 0), (NaN, 0), (-Inf, 0))\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.exp-Tuple{Float64}","page":"Mathematics","title":"Base.exp","text":"exp(x)\n\nCompute the natural base exponential of x, in other words ℯ^x.\n\nSee also exp2, exp10 and cis.\n\nExamples\n\njulia> exp(1.0)\n2.718281828459045\n\njulia> exp(im * pi) ≈ cis(pi)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.exp2","page":"Mathematics","title":"Base.exp2","text":"exp2(x)\n\nCompute the base 2 exponential of x, in other words 2^x.\n\nSee also ldexp, <<.\n\nExamples\n\njulia> exp2(5)\n32.0\n\njulia> 2^5\n32\n\njulia> exp2(63) > typemax(Int)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.exp10","page":"Mathematics","title":"Base.exp10","text":"exp10(x)\n\nCompute the base 10 exponential of x, in other words 10^x.\n\nExamples\n\njulia> exp10(2)\n100.0\n\njulia> 10^2\n100\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.ldexp","page":"Mathematics","title":"Base.Math.ldexp","text":"ldexp(x, n)\n\nCompute x times 2^n.\n\nSee also frexp, exponent.\n\nExamples\n\njulia> ldexp(5.0, 2)\n20.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.modf","page":"Mathematics","title":"Base.Math.modf","text":"modf(x)\n\nReturn a tuple (fpart, ipart) of the fractional and integral parts of a number. Both parts have the same sign as the argument.\n\nExamples\n\njulia> modf(3.5)\n(0.5, 3.0)\n\njulia> modf(-3.5)\n(-0.5, -3.0)\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.expm1","page":"Mathematics","title":"Base.expm1","text":"expm1(x)\n\nAccurately compute e^x-1. It avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small values of x.\n\nExamples\n\njulia> expm1(1e-16)\n1.0e-16\n\njulia> exp(1e-16) - 1\n0.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.round","page":"Mathematics","title":"Base.round","text":"round([T,] x, [r::RoundingMode])\nround(x, [r::RoundingMode]; digits::Integer=0, base = 10)\nround(x, [r::RoundingMode]; sigdigits::Integer, base = 10)\n\nRounds the number x.\n\nWithout keyword arguments, x is rounded to an integer value, returning a value of type T, or of the same type of x if no T is provided. An InexactError will be thrown if the value is not representable by T, similar to convert.\n\nIf the digits keyword argument is provided, it rounds to the specified number of digits after the decimal place (or before if negative), in base base.\n\nIf the sigdigits keyword argument is provided, it rounds to the specified number of significant digits, in base base.\n\nThe RoundingMode r controls the direction of the rounding; the default is RoundNearest, which rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer. Note that round may give incorrect results if the global rounding mode is changed (see rounding).\n\nExamples\n\njulia> round(1.7)\n2.0\n\njulia> round(Int, 1.7)\n2\n\njulia> round(1.5)\n2.0\n\njulia> round(2.5)\n2.0\n\njulia> round(pi; digits=2)\n3.14\n\njulia> round(pi; digits=3, base=2)\n3.125\n\njulia> round(123.456; sigdigits=2)\n120.0\n\njulia> round(357.913; sigdigits=4, base=2)\n352.0\n\nnote: Note\nRounding to specified digits in bases other than 2 can be inexact when operating on binary floating point numbers. For example, the Float64 value represented by 1.15 is actually less than 1.15, yet will be rounded to 1.2. For example:julia> x = 1.15\n1.15\n\njulia> big(1.15)\n1.149999999999999911182158029987476766109466552734375\n\njulia> x < 115//100\ntrue\n\njulia> round(x, digits=1)\n1.2\n\nExtensions\n\nTo extend round to new numeric types, it is typically sufficient to define Base.round(x::NewType, r::RoundingMode).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Rounding.RoundingMode","page":"Mathematics","title":"Base.Rounding.RoundingMode","text":"RoundingMode\n\nA type used for controlling the rounding mode of floating point operations (via rounding/setrounding functions), or as optional arguments for rounding to the nearest integer (via the round function).\n\nCurrently supported rounding modes are:\n\nRoundNearest (default)\nRoundNearestTiesAway\nRoundNearestTiesUp\nRoundToZero\nRoundFromZero\nRoundUp\nRoundDown\n\ncompat: Julia 1.9\nRoundFromZero requires at least Julia 1.9. Prior versions support RoundFromZero for BigFloats only.\n\n\n\n\n\n","category":"type"},{"location":"base/math/#Base.Rounding.RoundNearest","page":"Mathematics","title":"Base.Rounding.RoundNearest","text":"RoundNearest\n\nThe default rounding mode. Rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer.\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundNearestTiesAway","page":"Mathematics","title":"Base.Rounding.RoundNearestTiesAway","text":"RoundNearestTiesAway\n\nRounds to nearest integer, with ties rounded away from zero (C/C++ round behaviour).\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundNearestTiesUp","page":"Mathematics","title":"Base.Rounding.RoundNearestTiesUp","text":"RoundNearestTiesUp\n\nRounds to nearest integer, with ties rounded toward positive infinity (Java/JavaScript round behaviour).\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundToZero","page":"Mathematics","title":"Base.Rounding.RoundToZero","text":"RoundToZero\n\nround using this rounding mode is an alias for trunc.\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundFromZero","page":"Mathematics","title":"Base.Rounding.RoundFromZero","text":"RoundFromZero\n\nRounds away from zero.\n\ncompat: Julia 1.9\nRoundFromZero requires at least Julia 1.9. Prior versions support RoundFromZero for BigFloats only.\n\nExamples\n\njulia> BigFloat(\"1.0000000000000001\", 5, RoundFromZero)\n1.06\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundUp","page":"Mathematics","title":"Base.Rounding.RoundUp","text":"RoundUp\n\nround using this rounding mode is an alias for ceil.\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundDown","page":"Mathematics","title":"Base.Rounding.RoundDown","text":"RoundDown\n\nround using this rounding mode is an alias for floor.\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.round-Tuple{Complex{<:AbstractFloat}, RoundingMode, RoundingMode}","page":"Mathematics","title":"Base.round","text":"round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]])\nround(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]; digits=0, base=10)\nround(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]; sigdigits, base=10)\n\nReturn the nearest integral value of the same type as the complex-valued z to z, breaking ties using the specified RoundingModes. The first RoundingMode is used for rounding the real components while the second is used for rounding the imaginary components.\n\nRoundingModeReal and RoundingModeImaginary default to RoundNearest, which rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer.\n\nExamples\n\njulia> round(3.14 + 4.5im)\n3.0 + 4.0im\n\njulia> round(3.14 + 4.5im, RoundUp, RoundNearestTiesUp)\n4.0 + 5.0im\n\njulia> round(3.14159 + 4.512im; digits = 1)\n3.1 + 4.5im\n\njulia> round(3.14159 + 4.512im; sigdigits = 3)\n3.14 + 4.51im\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.ceil","page":"Mathematics","title":"Base.ceil","text":"ceil([T,] x)\nceil(x; digits::Integer= [, base = 10])\nceil(x; sigdigits::Integer= [, base = 10])\n\nceil(x) returns the nearest integral value of the same type as x that is greater than or equal to x.\n\nceil(T, x) converts the result to type T, throwing an InexactError if the ceiled value is not representable as a T.\n\nKeywords digits, sigdigits and base work as for round.\n\nTo support ceil for a new type, define Base.round(x::NewType, ::RoundingMode{:Up}).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.floor","page":"Mathematics","title":"Base.floor","text":"floor([T,] x)\nfloor(x; digits::Integer= [, base = 10])\nfloor(x; sigdigits::Integer= [, base = 10])\n\nfloor(x) returns the nearest integral value of the same type as x that is less than or equal to x.\n\nfloor(T, x) converts the result to type T, throwing an InexactError if the floored value is not representable a T.\n\nKeywords digits, sigdigits and base work as for round.\n\nTo support floor for a new type, define Base.round(x::NewType, ::RoundingMode{:Down}).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.trunc","page":"Mathematics","title":"Base.trunc","text":"trunc([T,] x)\ntrunc(x; digits::Integer= [, base = 10])\ntrunc(x; sigdigits::Integer= [, base = 10])\n\ntrunc(x) returns the nearest integral value of the same type as x whose absolute value is less than or equal to the absolute value of x.\n\ntrunc(T, x) converts the result to type T, throwing an InexactError if the truncated value is not representable a T.\n\nKeywords digits, sigdigits and base work as for round.\n\nTo support trunc for a new type, define Base.round(x::NewType, ::RoundingMode{:ToZero}).\n\nSee also: %, floor, unsigned, unsafe_trunc.\n\nExamples\n\njulia> trunc(2.22)\n2.0\n\njulia> trunc(-2.22, digits=1)\n-2.2\n\njulia> trunc(Int, -2.22)\n-2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.unsafe_trunc","page":"Mathematics","title":"Base.unsafe_trunc","text":"unsafe_trunc(T, x)\n\nReturn the nearest integral value of type T whose absolute value is less than or equal to the absolute value of x. If the value is not representable by T, an arbitrary value will be returned. See also trunc.\n\nExamples\n\njulia> unsafe_trunc(Int, -2.2)\n-2\n\njulia> unsafe_trunc(Int, NaN)\n-9223372036854775808\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.min","page":"Mathematics","title":"Base.min","text":"min(x, y, ...)\n\nReturn the minimum of the arguments, with respect to isless. If any of the arguments is missing, return missing. See also the minimum function to take the minimum element from a collection.\n\nExamples\n\njulia> min(2, 5, 1)\n1\n\njulia> min(4, missing, 6)\nmissing\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.max","page":"Mathematics","title":"Base.max","text":"max(x, y, ...)\n\nReturn the maximum of the arguments, with respect to isless. If any of the arguments is missing, return missing. See also the maximum function to take the maximum element from a collection.\n\nExamples\n\njulia> max(2, 5, 1)\n5\n\njulia> max(5, missing, 6)\nmissing\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.minmax","page":"Mathematics","title":"Base.minmax","text":"minmax(x, y)\n\nReturn (min(x,y), max(x,y)).\n\nSee also extrema that returns (minimum(x), maximum(x)).\n\nExamples\n\njulia> minmax('c','b')\n('b', 'c')\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.clamp","page":"Mathematics","title":"Base.Math.clamp","text":"clamp(x, lo, hi)\n\nReturn x if lo <= x <= hi. If x > hi, return hi. If x < lo, return lo. Arguments are promoted to a common type.\n\nSee also clamp!, min, max.\n\ncompat: Julia 1.3\nmissing as the first argument requires at least Julia 1.3.\n\nExamples\n\njulia> clamp.([pi, 1.0, big(10)], 2.0, 9.0)\n3-element Vector{BigFloat}:\n 3.141592653589793238462643383279502884197169399375105820974944592307816406286198\n 2.0\n 9.0\n\njulia> clamp.([11, 8, 5], 10, 6) # an example where lo > hi\n3-element Vector{Int64}:\n 6\n 6\n 10\n\n\n\n\n\nclamp(x, T)::T\n\nClamp x between typemin(T) and typemax(T) and convert the result to type T.\n\nSee also trunc.\n\nExamples\n\njulia> clamp(200, Int8)\n127\n\njulia> clamp(-200, Int8)\n-128\n\njulia> trunc(Int, 4pi^2)\n39\n\n\n\n\n\nclamp(x::Integer, r::AbstractUnitRange)\n\nClamp x to lie within range r.\n\ncompat: Julia 1.6\nThis method requires at least Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.clamp!","page":"Mathematics","title":"Base.Math.clamp!","text":"clamp!(array::AbstractArray, lo, hi)\n\nRestrict values in array to the specified range, in-place. See also clamp.\n\ncompat: Julia 1.3\nmissing entries in array require at least Julia 1.3.\n\nExamples\n\njulia> row = collect(-4:4)';\n\njulia> clamp!(row, 0, Inf)\n1×9 adjoint(::Vector{Int64}) with eltype Int64:\n 0 0 0 0 0 1 2 3 4\n\njulia> clamp.((-4:4)', 0, Inf)\n1×9 Matrix{Float64}:\n 0.0 0.0 0.0 0.0 0.0 1.0 2.0 3.0 4.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.abs","page":"Mathematics","title":"Base.abs","text":"abs(x)\n\nThe absolute value of x.\n\nWhen abs is applied to signed integers, overflow may occur, resulting in the return of a negative value. This overflow occurs only when abs is applied to the minimum representable value of a signed integer. That is, when x == typemin(typeof(x)), abs(x) == x < 0, not -x as might be expected.\n\nSee also: abs2, unsigned, sign.\n\nExamples\n\njulia> abs(-3)\n3\n\njulia> abs(1 + im)\n1.4142135623730951\n\njulia> abs.(Int8[-128 -127 -126 0 126 127]) # overflow at typemin(Int8)\n1×6 Matrix{Int8}:\n -128 127 126 0 126 127\n\njulia> maximum(abs, [1, -2, 3, -4])\n4\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked","page":"Mathematics","title":"Base.Checked","text":"Checked\n\nThe Checked module provides arithmetic functions for the built-in signed and unsigned Integer types which throw an error when an overflow occurs. They are named like checked_sub, checked_div, etc. In addition, add_with_overflow, sub_with_overflow, mul_with_overflow return both the unchecked results and a boolean value denoting the presence of an overflow.\n\n\n\n\n\n","category":"module"},{"location":"base/math/#Base.Checked.checked_abs","page":"Mathematics","title":"Base.Checked.checked_abs","text":"Base.checked_abs(x)\n\nCalculates abs(x), checking for overflow errors where applicable. For example, standard two's complement signed integers (e.g. Int) cannot represent abs(typemin(Int)), thus leading to an overflow.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_neg","page":"Mathematics","title":"Base.Checked.checked_neg","text":"Base.checked_neg(x)\n\nCalculates -x, checking for overflow errors where applicable. For example, standard two's complement signed integers (e.g. Int) cannot represent -typemin(Int), thus leading to an overflow.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_add","page":"Mathematics","title":"Base.Checked.checked_add","text":"Base.checked_add(x, y)\n\nCalculates x+y, checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_sub","page":"Mathematics","title":"Base.Checked.checked_sub","text":"Base.checked_sub(x, y)\n\nCalculates x-y, checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_mul","page":"Mathematics","title":"Base.Checked.checked_mul","text":"Base.checked_mul(x, y)\n\nCalculates x*y, checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_div","page":"Mathematics","title":"Base.Checked.checked_div","text":"Base.checked_div(x, y)\n\nCalculates div(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_rem","page":"Mathematics","title":"Base.Checked.checked_rem","text":"Base.checked_rem(x, y)\n\nCalculates x%y, checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_fld","page":"Mathematics","title":"Base.Checked.checked_fld","text":"Base.checked_fld(x, y)\n\nCalculates fld(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_mod","page":"Mathematics","title":"Base.Checked.checked_mod","text":"Base.checked_mod(x, y)\n\nCalculates mod(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_cld","page":"Mathematics","title":"Base.Checked.checked_cld","text":"Base.checked_cld(x, y)\n\nCalculates cld(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_pow","page":"Mathematics","title":"Base.Checked.checked_pow","text":"Base.checked_pow(x, y)\n\nCalculates ^(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.add_with_overflow","page":"Mathematics","title":"Base.Checked.add_with_overflow","text":"Base.add_with_overflow(x, y) -> (r, f)\n\nCalculates r = x+y, with the flag f indicating whether overflow has occurred.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.sub_with_overflow","page":"Mathematics","title":"Base.Checked.sub_with_overflow","text":"Base.sub_with_overflow(x, y) -> (r, f)\n\nCalculates r = x-y, with the flag f indicating whether overflow has occurred.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.mul_with_overflow","page":"Mathematics","title":"Base.Checked.mul_with_overflow","text":"Base.mul_with_overflow(x, y) -> (r, f)\n\nCalculates r = x*y, with the flag f indicating whether overflow has occurred.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.abs2","page":"Mathematics","title":"Base.abs2","text":"abs2(x)\n\nSquared absolute value of x.\n\nThis can be faster than abs(x)^2, especially for complex numbers where abs(x) requires a square root via hypot.\n\nSee also abs, conj, real.\n\nExamples\n\njulia> abs2(-3)\n9\n\njulia> abs2(3.0 + 4.0im)\n25.0\n\njulia> sum(abs2, [1+2im, 3+4im]) # LinearAlgebra.norm(x)^2\n30\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.copysign","page":"Mathematics","title":"Base.copysign","text":"copysign(x, y) -> z\n\nReturn z which has the magnitude of x and the same sign as y.\n\nExamples\n\njulia> copysign(1, -2)\n-1\n\njulia> copysign(-1, 2)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.sign","page":"Mathematics","title":"Base.sign","text":"sign(x)\n\nReturn zero if x==0 and xx otherwise (i.e., ±1 for real x).\n\nSee also signbit, zero, copysign, flipsign.\n\nExamples\n\njulia> sign(-4.0)\n-1.0\n\njulia> sign(99)\n1\n\njulia> sign(-0.0)\n-0.0\n\njulia> sign(0 + im)\n0.0 + 1.0im\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.signbit","page":"Mathematics","title":"Base.signbit","text":"signbit(x)\n\nReturn true if the value of the sign of x is negative, otherwise false.\n\nSee also sign and copysign.\n\nExamples\n\njulia> signbit(-4)\ntrue\n\njulia> signbit(5)\nfalse\n\njulia> signbit(5.5)\nfalse\n\njulia> signbit(-4.1)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.flipsign","page":"Mathematics","title":"Base.flipsign","text":"flipsign(x, y)\n\nReturn x with its sign flipped if y is negative. For example abs(x) = flipsign(x,x).\n\nExamples\n\njulia> flipsign(5, 3)\n5\n\njulia> flipsign(5, -3)\n-5\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.sqrt-Tuple{Number}","page":"Mathematics","title":"Base.sqrt","text":"sqrt(x)\n\nReturn sqrtx.\n\nThrow a DomainError for negative Real arguments. Use Complex negative arguments instead to obtain a Complex result.\n\nThe prefix operator √ is equivalent to sqrt.\n\nnote: Branch cut\nsqrt has a branch cut along the negative real axis; -0.0im is taken to be below the axis.\n\nSee also: hypot.\n\nExamples\n\njulia> sqrt(big(81))\n9.0\n\njulia> sqrt(big(-81))\nERROR: DomainError with -81.0:\nNaN result for non-NaN input.\nStacktrace:\n [1] sqrt(::BigFloat) at ./mpfr.jl:501\n[...]\n\njulia> sqrt(big(complex(-81)))\n0.0 + 9.0im\n\njulia> sqrt(-81 - 0.0im) # -0.0im is below the branch cut\n0.0 - 9.0im\n\njulia> .√(1:4)\n4-element Vector{Float64}:\n 1.0\n 1.4142135623730951\n 1.7320508075688772\n 2.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.isqrt","page":"Mathematics","title":"Base.isqrt","text":"isqrt(n::Integer)\n\nInteger square root: the largest integer m such that m*m <= n.\n\njulia> isqrt(5)\n2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cbrt-Tuple{AbstractFloat}","page":"Mathematics","title":"Base.Math.cbrt","text":"cbrt(x::Real)\n\nReturn the cube root of x, i.e. x^13. Negative values are accepted (returning the negative real root when x 0).\n\nThe prefix operator ∛ is equivalent to cbrt.\n\nExamples\n\njulia> cbrt(big(27))\n3.0\n\njulia> cbrt(big(-27))\n-3.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.real","page":"Mathematics","title":"Base.real","text":"real(z)\n\nReturn the real part of the complex number z.\n\nSee also: imag, reim, complex, isreal, Real.\n\nExamples\n\njulia> real(1 + 3im)\n1\n\n\n\n\n\nreal(T::Type)\n\nReturn the type that represents the real part of a value of type T. e.g: for T == Complex{R}, returns R. Equivalent to typeof(real(zero(T))).\n\nExamples\n\njulia> real(Complex{Int})\nInt64\n\njulia> real(Float64)\nFloat64\n\n\n\n\n\nreal(A::AbstractArray)\n\nReturn an array containing the real part of each entry in array A.\n\nEquivalent to real.(A), except that when eltype(A) <: Real A is returned without copying, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).\n\nExamples\n\njulia> real([1, 2im, 3 + 4im])\n3-element Vector{Int64}:\n 1\n 0\n 3\n\njulia> real(fill(2 - im))\n0-dimensional Array{Int64, 0}:\n2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.imag","page":"Mathematics","title":"Base.imag","text":"imag(z)\n\nReturn the imaginary part of the complex number z.\n\nSee also: conj, reim, adjoint, angle.\n\nExamples\n\njulia> imag(1 + 3im)\n3\n\n\n\n\n\nimag(A::AbstractArray)\n\nReturn an array containing the imaginary part of each entry in array A.\n\nEquivalent to imag.(A), except that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).\n\nExamples\n\njulia> imag([1, 2im, 3 + 4im])\n3-element Vector{Int64}:\n 0\n 2\n 4\n\njulia> imag(fill(2 - im))\n0-dimensional Array{Int64, 0}:\n-1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.reim","page":"Mathematics","title":"Base.reim","text":"reim(z)\n\nReturn a tuple of the real and imaginary parts of the complex number z.\n\nExamples\n\njulia> reim(1 + 3im)\n(1, 3)\n\n\n\n\n\nreim(A::AbstractArray)\n\nReturn a tuple of two arrays containing respectively the real and the imaginary part of each entry in A.\n\nEquivalent to (real.(A), imag.(A)), except that when eltype(A) <: Real A is returned without copying to represent the real part, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).\n\nExamples\n\njulia> reim([1, 2im, 3 + 4im])\n([1, 0, 3], [0, 2, 4])\n\njulia> reim(fill(2 - im))\n(fill(2), fill(-1))\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.conj","page":"Mathematics","title":"Base.conj","text":"conj(z)\n\nCompute the complex conjugate of a complex number z.\n\nSee also: angle, adjoint.\n\nExamples\n\njulia> conj(1 + 3im)\n1 - 3im\n\n\n\n\n\nconj(A::AbstractArray)\n\nReturn an array containing the complex conjugate of each entry in array A.\n\nEquivalent to conj.(A), except that when eltype(A) <: Real A is returned without copying, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).\n\nExamples\n\njulia> conj([1, 2im, 3 + 4im])\n3-element Vector{Complex{Int64}}:\n 1 + 0im\n 0 - 2im\n 3 - 4im\n\njulia> conj(fill(2 - im))\n0-dimensional Array{Complex{Int64}, 0}:\n2 + 1im\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.angle","page":"Mathematics","title":"Base.angle","text":"angle(z)\n\nCompute the phase angle in radians of a complex number z.\n\nReturns a number -pi ≤ angle(z) ≤ pi, and is thus discontinuous along the negative real axis.\n\nSee also: atan, cis, rad2deg.\n\nExamples\n\njulia> rad2deg(angle(1 + im))\n45.0\n\njulia> rad2deg(angle(1 - im))\n-45.0\n\njulia> rad2deg(angle(-1 + 1e-20im))\n180.0\n\njulia> rad2deg(angle(-1 - 1e-20im))\n-180.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.cis","page":"Mathematics","title":"Base.cis","text":"cis(x)\n\nMore efficient method for exp(im*x) by using Euler's formula: cos(x) + i sin(x) = exp(i x).\n\nSee also cispi, sincos, exp, angle.\n\nExamples\n\njulia> cis(π) ≈ -1\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.cispi","page":"Mathematics","title":"Base.cispi","text":"cispi(x)\n\nMore accurate method for cis(pi*x) (especially for large x).\n\nSee also cis, sincospi, exp, angle.\n\nExamples\n\njulia> cispi(10000)\n1.0 + 0.0im\n\njulia> cispi(0.25 + 1im)\n0.030556854645954562 + 0.03055685464595456im\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.binomial","page":"Mathematics","title":"Base.binomial","text":"binomial(n::Integer, k::Integer)\n\nThe binomial coefficient binomnk, being the coefficient of the kth term in the polynomial expansion of (1+x)^n.\n\nIf n is non-negative, then it is the number of ways to choose k out of n items:\n\nbinomnk = fracnk (n-k)\n\nwhere n is the factorial function.\n\nIf n is negative, then it is defined in terms of the identity\n\nbinomnk = (-1)^k binomk-n-1k\n\nSee also factorial.\n\nExamples\n\njulia> binomial(5, 3)\n10\n\njulia> factorial(5) ÷ (factorial(5-3) * factorial(3))\n10\n\njulia> binomial(-5, 3)\n-35\n\nExternal links\n\nBinomial coefficient on Wikipedia.\n\n\n\n\n\nbinomial(x::Number, k::Integer)\n\nThe generalized binomial coefficient, defined for k ≥ 0 by the polynomial\n\nfrac1k prod_j=0^k-1 (x - j)\n\nWhen k < 0 it returns zero.\n\nFor the case of integer x, this is equivalent to the ordinary integer binomial coefficient\n\nbinomnk = fracnk (n-k)\n\nFurther generalizations to non-integer k are mathematically possible, but involve the Gamma function and/or the beta function, which are not provided by the Julia standard library but are available in external packages such as SpecialFunctions.jl.\n\nExternal links\n\nBinomial coefficient on Wikipedia.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.factorial","page":"Mathematics","title":"Base.factorial","text":"factorial(n::Integer)\n\nFactorial of n. If n is an Integer, the factorial is computed as an integer (promoted to at least 64 bits). Note that this may overflow if n is not small, but you can use factorial(big(n)) to compute the result exactly in arbitrary precision.\n\nSee also binomial.\n\nExamples\n\njulia> factorial(6)\n720\n\njulia> factorial(21)\nERROR: OverflowError: 21 is too large to look up in the table; consider using `factorial(big(21))` instead\nStacktrace:\n[...]\n\njulia> factorial(big(21))\n51090942171709440000\n\nExternal links\n\nFactorial on Wikipedia.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.gcd","page":"Mathematics","title":"Base.gcd","text":"gcd(x, y...)\n\nGreatest common (positive) divisor (or zero if all arguments are zero). The arguments may be integer and rational numbers.\n\ncompat: Julia 1.4\nRational arguments require Julia 1.4 or later.\n\nExamples\n\njulia> gcd(6, 9)\n3\n\njulia> gcd(6, -9)\n3\n\njulia> gcd(6, 0)\n6\n\njulia> gcd(0, 0)\n0\n\njulia> gcd(1//3, 2//3)\n1//3\n\njulia> gcd(1//3, -2//3)\n1//3\n\njulia> gcd(1//3, 2)\n1//3\n\njulia> gcd(0, 0, 10, 15)\n5\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.lcm","page":"Mathematics","title":"Base.lcm","text":"lcm(x, y...)\n\nLeast common (positive) multiple (or zero if any argument is zero). The arguments may be integer and rational numbers.\n\ncompat: Julia 1.4\nRational arguments require Julia 1.4 or later.\n\nExamples\n\njulia> lcm(2, 3)\n6\n\njulia> lcm(-2, 3)\n6\n\njulia> lcm(0, 3)\n0\n\njulia> lcm(0, 0)\n0\n\njulia> lcm(1//3, 2//3)\n2//3\n\njulia> lcm(1//3, -2//3)\n2//3\n\njulia> lcm(1//3, 2)\n2//1\n\njulia> lcm(1, 3, 5, 7)\n105\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.gcdx","page":"Mathematics","title":"Base.gcdx","text":"gcdx(a, b)\n\nComputes the greatest common (positive) divisor of a and b and their Bézout coefficients, i.e. the integer coefficients u and v that satisfy ua+vb = d = gcd(a b). gcdx(a b) returns (d u v).\n\nThe arguments may be integer and rational numbers.\n\ncompat: Julia 1.4\nRational arguments require Julia 1.4 or later.\n\nExamples\n\njulia> gcdx(12, 42)\n(6, -3, 1)\n\njulia> gcdx(240, 46)\n(2, -9, 47)\n\nnote: Note\nBézout coefficients are not uniquely defined. gcdx returns the minimal Bézout coefficients that are computed by the extended Euclidean algorithm. (Ref: D. Knuth, TAoCP, 2/e, p. 325, Algorithm X.) For signed integers, these coefficients u and v are minimal in the sense that u bd and v ad. Furthermore, the signs of u and v are chosen so that d is positive. For unsigned integers, the coefficients u and v might be near their typemax, and the identity then holds only via the unsigned integers' modulo arithmetic.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.ispow2","page":"Mathematics","title":"Base.ispow2","text":"ispow2(n::Number) -> Bool\n\nTest whether n is an integer power of two.\n\nSee also count_ones, prevpow, nextpow.\n\nExamples\n\njulia> ispow2(4)\ntrue\n\njulia> ispow2(5)\nfalse\n\njulia> ispow2(4.5)\nfalse\n\njulia> ispow2(0.25)\ntrue\n\njulia> ispow2(1//8)\ntrue\n\ncompat: Julia 1.6\nSupport for non-Integer arguments was added in Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.nextpow","page":"Mathematics","title":"Base.nextpow","text":"nextpow(a, x)\n\nThe smallest a^n not less than x, where n is a non-negative integer. a must be greater than 1, and x must be greater than 0.\n\nSee also prevpow.\n\nExamples\n\njulia> nextpow(2, 7)\n8\n\njulia> nextpow(2, 9)\n16\n\njulia> nextpow(5, 20)\n25\n\njulia> nextpow(4, 16)\n16\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.prevpow","page":"Mathematics","title":"Base.prevpow","text":"prevpow(a, x)\n\nThe largest a^n not greater than x, where n is a non-negative integer. a must be greater than 1, and x must not be less than 1.\n\nSee also nextpow, isqrt.\n\nExamples\n\njulia> prevpow(2, 7)\n4\n\njulia> prevpow(2, 9)\n8\n\njulia> prevpow(5, 20)\n5\n\njulia> prevpow(4, 16)\n16\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.nextprod","page":"Mathematics","title":"Base.nextprod","text":"nextprod(factors::Union{Tuple,AbstractVector}, n)\n\nNext integer greater than or equal to n that can be written as prod k_i^p_i for integers p_1, p_2, etcetera, for factors k_i in factors.\n\nExamples\n\njulia> nextprod((2, 3), 105)\n108\n\njulia> 2^2 * 3^3\n108\n\ncompat: Julia 1.6\nThe method that accepts a tuple requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.invmod","page":"Mathematics","title":"Base.invmod","text":"invmod(n::Integer, m::Integer)\n\nTake the inverse of n modulo m: y such that n y = 1 pmod m, and div(ym) = 0. This will throw an error if m = 0, or if gcd(nm) neq 1.\n\nExamples\n\njulia> invmod(2, 5)\n3\n\njulia> invmod(2, 3)\n2\n\njulia> invmod(5, 6)\n5\n\n\n\n\n\ninvmod(n::Integer, T) where {T <: Base.BitInteger}\ninvmod(n::T) where {T <: Base.BitInteger}\n\nCompute the modular inverse of n in the integer ring of type T, i.e. modulo 2^N where N = 8*sizeof(T) (e.g. N = 32 for Int32). In other words these methods satisfy the following identities:\n\nn * invmod(n) == 1\n(n * invmod(n, T)) % T == 1\n(n % T) * invmod(n, T) == 1\n\nNote that * here is modular multiplication in the integer ring, T.\n\nSpecifying the modulus implied by an integer type as an explicit value is often inconvenient since the modulus is by definition too big to be represented by the type.\n\nThe modular inverse is computed much more efficiently than the general case using the algorithm described in https://arxiv.org/pdf/2204.04342.pdf.\n\ncompat: Julia 1.11\nThe invmod(n) and invmod(n, T) methods require Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.powermod","page":"Mathematics","title":"Base.powermod","text":"powermod(x::Integer, p::Integer, m)\n\nCompute x^p pmod m.\n\nExamples\n\njulia> powermod(2, 6, 5)\n4\n\njulia> mod(2^6, 5)\n4\n\njulia> powermod(5, 2, 20)\n5\n\njulia> powermod(5, 2, 19)\n6\n\njulia> powermod(5, 3, 19)\n11\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.ndigits","page":"Mathematics","title":"Base.ndigits","text":"ndigits(n::Integer; base::Integer=10, pad::Integer=1)\n\nCompute the number of digits in integer n written in base base (base must not be in [-1, 0, 1]), optionally padded with zeros to a specified size (the result will never be less than pad).\n\nSee also digits, count_ones.\n\nExamples\n\njulia> ndigits(0)\n1\n\njulia> ndigits(12345)\n5\n\njulia> ndigits(1022, base=16)\n3\n\njulia> string(1022, base=16)\n\"3fe\"\n\njulia> ndigits(123, pad=5)\n5\n\njulia> ndigits(-123)\n3\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.add_sum","page":"Mathematics","title":"Base.add_sum","text":"Base.add_sum(x, y)\n\nThe reduction operator used in sum. The main difference from + is that small integers are promoted to Int/UInt.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.widemul","page":"Mathematics","title":"Base.widemul","text":"widemul(x, y)\n\nMultiply x and y, giving the result as a larger type.\n\nSee also promote, Base.add_sum.\n\nExamples\n\njulia> widemul(Float32(3.0), 4.0) isa BigFloat\ntrue\n\njulia> typemax(Int8) * typemax(Int8)\n1\n\njulia> widemul(typemax(Int8), typemax(Int8)) # == 127^2\n16129\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.evalpoly","page":"Mathematics","title":"Base.Math.evalpoly","text":"evalpoly(x, p)\n\nEvaluate the polynomial sum_k x^k-1 pk for the coefficients p[1], p[2], ...; that is, the coefficients are given in ascending order by power of x. Loops are unrolled at compile time if the number of coefficients is statically known, i.e. when p is a Tuple. This function generates efficient code using Horner's method if x is real, or using a Goertzel-like [DK62] algorithm if x is complex.\n\n[DK62]: Donald Knuth, Art of Computer Programming, Volume 2: Seminumerical Algorithms, Sec. 4.6.4.\n\ncompat: Julia 1.4\nThis function requires Julia 1.4 or later.\n\nExamples\n\njulia> evalpoly(2, (1, 2, 3))\n17\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.@evalpoly","page":"Mathematics","title":"Base.Math.@evalpoly","text":"@evalpoly(z, c...)\n\nEvaluate the polynomial sum_k z^k-1 ck for the coefficients c[1], c[2], ...; that is, the coefficients are given in ascending order by power of z. This macro expands to efficient inline code that uses either Horner's method or, for complex z, a more efficient Goertzel-like algorithm.\n\nSee also evalpoly.\n\nExamples\n\njulia> @evalpoly(3, 1, 0, 1)\n10\n\njulia> @evalpoly(2, 1, 0, 1)\n5\n\njulia> @evalpoly(2, 1, 1, 1)\n7\n\n\n\n\n\n","category":"macro"},{"location":"base/math/#Base.FastMath.@fastmath","page":"Mathematics","title":"Base.FastMath.@fastmath","text":"@fastmath expr\n\nExecute a transformed version of the expression, which calls functions that may violate strict IEEE semantics. This allows the fastest possible operation, but results are undefined – be careful when doing this, as it may change numerical results.\n\nThis sets the LLVM Fast-Math flags, and corresponds to the -ffast-math option in clang. See the notes on performance annotations for more details.\n\nExamples\n\njulia> @fastmath 1+2\n3\n\njulia> @fastmath(sin(3))\n0.1411200080598672\n\n\n\n\n\n","category":"macro"},{"location":"base/math/#Customizable-binary-operators","page":"Mathematics","title":"Customizable binary operators","text":"","category":"section"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Some unicode characters can be used to define new binary operators that support infix notation. For example ⊗(x,y) = kron(x,y) defines the ⊗ (otimes) function to be the Kronecker product, and one can call it as binary operator using infix syntax: C = A ⊗ B as well as with the usual prefix syntax C = ⊗(A,B).","category":"page"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Other characters that support such extensions include \\odot ⊙ and \\oplus ⊕","category":"page"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"The complete list is in the parser code: https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm","category":"page"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Those that are parsed like * (in terms of precedence) include * / ÷ % & ⋅ ∘ × |\\\\| ∩ ∧ ⊗ ⊘ ⊙ ⊚ ⊛ ⊠ ⊡ ⊓ ∗ ∙ ∤ ⅋ ≀ ⊼ ⋄ ⋆ ⋇ ⋉ ⋊ ⋋ ⋌ ⋏ ⋒ ⟑ ⦸ ⦼ ⦾ ⦿ ⧶ ⧷ ⨇ ⨰ ⨱ ⨲ ⨳ ⨴ ⨵ ⨶ ⨷ ⨸ ⨻ ⨼ ⨽ ⩀ ⩃ ⩄ ⩋ ⩍ ⩎ ⩑ ⩓ ⩕ ⩘ ⩚ ⩜ ⩞ ⩟ ⩠ ⫛ ⊍ ▷ ⨝ ⟕ ⟖ ⟗ and those that are parsed like + include + - |\\|| ⊕ ⊖ ⊞ ⊟ |++| ∪ ∨ ⊔ ± ∓ ∔ ∸ ≏ ⊎ ⊻ ⊽ ⋎ ⋓ ⟇ ⧺ ⧻ ⨈ ⨢ ⨣ ⨤ ⨥ ⨦ ⨧ ⨨ ⨩ ⨪ ⨫ ⨬ ⨭ ⨮ ⨹ ⨺ ⩁ ⩂ ⩅ ⩊ ⩌ ⩏ ⩐ ⩒ ⩔ ⩖ ⩗ ⩛ ⩝ ⩡ ⩢ ⩣ There are many others that are related to arrows, comparisons, and powers.","category":"page"},{"location":"stdlib/ArgTools/","page":"ArgTools","title":"ArgTools","text":"EditURL = \"https://github.com/JuliaIO/ArgTools.jl/blob/master/docs/src/index.md\"","category":"page"},{"location":"stdlib/ArgTools/#ArgTools","page":"ArgTools","title":"ArgTools","text":"","category":"section"},{"location":"stdlib/ArgTools/#Argument-Handling","page":"ArgTools","title":"Argument Handling","text":"","category":"section"},{"location":"stdlib/ArgTools/","page":"ArgTools","title":"ArgTools","text":"ArgTools.ArgRead\nArgTools.ArgWrite\nArgTools.arg_read\nArgTools.arg_write\nArgTools.arg_isdir\nArgTools.arg_mkdir","category":"page"},{"location":"stdlib/ArgTools/#ArgTools.ArgRead","page":"ArgTools","title":"ArgTools.ArgRead","text":"ArgRead = Union{AbstractString, AbstractCmd, IO}\n\nThe ArgRead types is a union of the types that the arg_read function knows how to convert into readable IO handles. See arg_read for details.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/ArgTools/#ArgTools.ArgWrite","page":"ArgTools","title":"ArgTools.ArgWrite","text":"ArgWrite = Union{AbstractString, AbstractCmd, IO}\n\nThe ArgWrite types is a union of the types that the arg_write function knows how to convert into writeable IO handles, except for Nothing which arg_write handles by generating a temporary file. See arg_write for details.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/ArgTools/#ArgTools.arg_read","page":"ArgTools","title":"ArgTools.arg_read","text":"arg_read(f::Function, arg::ArgRead) -> f(arg_io)\n\nThe arg_read function accepts an argument arg that can be any of these:\n\nAbstractString: a file path to be opened for reading\nAbstractCmd: a command to be run, reading from its standard output\nIO: an open IO handle to be read from\n\nWhether the body returns normally or throws an error, a path which is opened will be closed before returning from arg_read and an IO handle will be flushed but not closed before returning from arg_read.\n\nNote: when opening a file, ArgTools will pass lock = false to the file open(...) call. Therefore, the object returned by this function should not be used from multiple threads. This restriction may be relaxed in the future, which would not break any working code.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.arg_write","page":"ArgTools","title":"ArgTools.arg_write","text":"arg_write(f::Function, arg::ArgWrite) -> arg\narg_write(f::Function, arg::Nothing) -> tempname()\n\nThe arg_read function accepts an argument arg that can be any of these:\n\nAbstractString: a file path to be opened for writing\nAbstractCmd: a command to be run, writing to its standard input\nIO: an open IO handle to be written to\nNothing: a temporary path should be written to\n\nIf the body returns normally, a path that is opened will be closed upon completion; an IO handle argument is left open but flushed before return. If the argument is nothing then a temporary path is opened for writing and closed open completion and the path is returned from arg_write. In all other cases, arg itself is returned. This is a useful pattern since you can consistently return whatever was written, whether an argument was passed or not.\n\nIf there is an error during the evaluation of the body, a path that is opened by arg_write for writing will be deleted, whether it's passed in as a string or a temporary path generated when arg is nothing.\n\nNote: when opening a file, ArgTools will pass lock = false to the file open(...) call. Therefore, the object returned by this function should not be used from multiple threads. This restriction may be relaxed in the future, which would not break any working code.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.arg_isdir","page":"ArgTools","title":"ArgTools.arg_isdir","text":"arg_isdir(f::Function, arg::AbstractString) -> f(arg)\n\nThe arg_isdir function takes arg which must be the path to an existing directory (an error is raised otherwise) and passes that path to f finally returning the result of f(arg). This is definitely the least useful tool offered by ArgTools and mostly exists for symmetry with arg_mkdir and to give consistent error messages.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.arg_mkdir","page":"ArgTools","title":"ArgTools.arg_mkdir","text":"arg_mkdir(f::Function, arg::AbstractString) -> arg\narg_mkdir(f::Function, arg::Nothing) -> mktempdir()\n\nThe arg_mkdir function takes arg which must either be one of:\n\na path to an already existing empty directory,\na non-existent path which can be created as a directory, or\nnothing in which case a temporary directory is created.\n\nIn all cases the path to the directory is returned. If an error occurs during f(arg), the directory is returned to its original state: if it already existed but was empty, it will be emptied; if it did not exist it will be deleted.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#Function-Testing","page":"ArgTools","title":"Function Testing","text":"","category":"section"},{"location":"stdlib/ArgTools/","page":"ArgTools","title":"ArgTools","text":"ArgTools.arg_readers\nArgTools.arg_writers\nArgTools.@arg_test","category":"page"},{"location":"stdlib/ArgTools/#ArgTools.arg_readers","page":"ArgTools","title":"ArgTools.arg_readers","text":"arg_readers(arg :: AbstractString, [ type = ArgRead ]) do arg::Function\n ## pre-test setup ##\n @arg_test arg begin\n arg :: ArgRead\n ## test using `arg` ##\n end\n ## post-test cleanup ##\nend\n\nThe arg_readers function takes a path to be read and a single-argument do block, which is invoked once for each test reader type that arg_read can handle. If the optional type argument is given then the do block is only invoked for readers that produce arguments of that type.\n\nThe arg passed to the do block is not the argument value itself, because some of test argument types need to be initialized and finalized for each test case. Consider an open file handle argument: once you've used it for one test, you can't use it again; you need to close it and open the file again for the next test. This function arg can be converted into an ArgRead instance using @arg_test arg begin ... end.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.arg_writers","page":"ArgTools","title":"ArgTools.arg_writers","text":"arg_writers([ type = ArgWrite ]) do path::String, arg::Function\n ## pre-test setup ##\n @arg_test arg begin\n arg :: ArgWrite\n ## test using `arg` ##\n end\n ## post-test cleanup ##\nend\n\nThe arg_writers function takes a do block, which is invoked once for each test writer type that arg_write can handle with a temporary (non-existent) path and arg which can be converted into various writable argument types which write to path. If the optional type argument is given then the do block is only invoked for writers that produce arguments of that type.\n\nThe arg passed to the do block is not the argument value itself, because some of test argument types need to be initialized and finalized for each test case. Consider an open file handle argument: once you've used it for one test, you can't use it again; you need to close it and open the file again for the next test. This function arg can be converted into an ArgWrite instance using @arg_test arg begin ... end.\n\nThere is also an arg_writers method that takes a path name like arg_readers:\n\narg_writers(path::AbstractString, [ type = ArgWrite ]) do arg::Function\n ## pre-test setup ##\n @arg_test arg begin\n # here `arg :: ArgWrite`\n ## test using `arg` ##\n end\n ## post-test cleanup ##\nend\n\nThis method is useful if you need to specify path instead of using path name generated by tempname(). Since path is passed from outside of arg_writers, the path is not an argument to the do block in this form.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.@arg_test","page":"ArgTools","title":"ArgTools.@arg_test","text":"@arg_test arg1 arg2 ... body\n\nThe @arg_test macro is used to convert arg functions provided by arg_readers and arg_writers into actual argument values. When you write @arg_test arg body it is equivalent to arg(arg -> body).\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/JuliaSyntaxHighlighting/#Julia-Syntax-Highlighting","page":"Julia Syntax Highlighting","title":"Julia Syntax Highlighting","text":"","category":"section"},{"location":"stdlib/JuliaSyntaxHighlighting/","page":"Julia Syntax Highlighting","title":"Julia Syntax Highlighting","text":"JuliaSyntaxHighlighting.highlight\nJuliaSyntaxHighlighting.highlight!","category":"page"},{"location":"stdlib/JuliaSyntaxHighlighting/#JuliaSyntaxHighlighting.highlight","page":"Julia Syntax Highlighting","title":"JuliaSyntaxHighlighting.highlight","text":"highlight(content::Union{AbstractString, IOBuffer, IOContext{IOBuffer}})\n\nApply syntax highlighting to content using JuliaSyntax.\n\nReturns an AnnotatedString{String}.\n\nExamples\n\njulia> JuliaSyntaxHighlighting.highlight(\"sum(1:8)\")\n\"sum(1:8)\"\n\njulia> JuliaSyntaxHighlighting.highlight(\"sum(1:8)\") |> Base.annotations\n6-element Vector{Tuple{UnitRange{Int64}, Pair{Symbol, Any}}}:\n (1:3, :face => :julia_funcall)\n (4:4, :face => :julia_rainbow_paren_1)\n (5:5, :face => :julia_number)\n (6:6, :face => :julia_operator)\n (7:7, :face => :julia_number)\n (8:8, :face => :julia_rainbow_paren_1)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/JuliaSyntaxHighlighting/#JuliaSyntaxHighlighting.highlight!","page":"Julia Syntax Highlighting","title":"JuliaSyntaxHighlighting.highlight!","text":"highlight!(content::Union{AnnotatedString, SubString{AnnotatedString}})\n\nModify content by applying syntax highlighting using JuliaSyntax.\n\nExamples\n\njulia> str = Base.AnnotatedString(\"sum(1:8)\")\n\"sum(1:8)\"\n\njulia> JuliaSyntaxHighlighting.highlight!(str)\n\"sum(1:8)\"\n\njulia> Base.annotations(str)\n6-element Vector{Tuple{UnitRange{Int64}, Pair{Symbol, Any}}}:\n (1:3, :face => :julia_funcall)\n (4:4, :face => :julia_rainbow_paren_1)\n (5:5, :face => :julia_number)\n (6:6, :face => :julia_operator)\n (7:7, :face => :julia_number)\n (8:8, :face => :julia_rainbow_paren_1)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Markdown/docs/src/index.md\"","category":"page"},{"location":"stdlib/Markdown/#markdown_stdlib","page":"Markdown","title":"Markdown","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This section describes Julia's markdown syntax, which is enabled by the Markdown standard library. The following Markdown elements are supported:","category":"page"},{"location":"stdlib/Markdown/#Inline-elements","page":"Markdown","title":"Inline elements","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Here \"inline\" refers to elements that can be found within blocks of text, i.e. paragraphs. These include the following elements.","category":"page"},{"location":"stdlib/Markdown/#Bold","page":"Markdown","title":"Bold","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Surround words with two asterisks, **, to display the enclosed text in boldface.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing a **bold** word.","category":"page"},{"location":"stdlib/Markdown/#Italics","page":"Markdown","title":"Italics","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Surround words with one asterisk, *, to display the enclosed text in italics.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing an *italicized* word.","category":"page"},{"location":"stdlib/Markdown/#Literals","page":"Markdown","title":"Literals","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Surround text that should be displayed exactly as written with single backticks, ` .","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing a `literal` word.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Literals should be used when writing text that refers to names of variables, functions, or other parts of a Julia program.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"tip: Tip\nTo include a backtick character within literal text use three backticks rather than one to enclose the text.A paragraph containing ``` `backtick` characters ```.By extension any odd number of backticks may be used to enclose a lesser number of backticks.","category":"page"},{"location":"stdlib/Markdown/#\\LaTeX","page":"Markdown","title":"LaTeX","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Surround text that should be displayed as mathematics using LaTeX syntax with double backticks, `` .","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing some ``\\LaTeX`` markup.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"tip: Tip\nAs with literals in the previous section, if literal backticks need to be written within double backticks use an even number greater than two. Note that if a single literal backtick needs to be included within LaTeX markup then two enclosing backticks is sufficient.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nThe \\ character should be escaped appropriately if the text is embedded in a Julia source code, for example, \"``\\\\LaTeX`` syntax in a docstring.\", since it is interpreted as a string literal. Alternatively, in order to avoid escaping, it is possible to use the raw string macro together with the @doc macro:@doc raw\"``\\LaTeX`` syntax in a docstring.\" functionname","category":"page"},{"location":"stdlib/Markdown/#Links","page":"Markdown","title":"Links","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Links to either external or internal targets can be written using the following syntax, where the text enclosed in square brackets, [ ], is the name of the link and the text enclosed in parentheses, ( ), is the URL.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing a link to [Julia](https://www.julialang.org).","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"It's also possible to add cross-references to other documented functions/methods/variables within the Julia documentation itself. For example:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"\"\"\"\n tryparse(type, str; base)\n\nLike [`parse`](@ref), but returns either a value of the requested type,\nor [`nothing`](@ref) if the string does not contain a valid number.\n\"\"\"","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This will create a link in the generated docs to the parse documentation (which has more information about what this function actually does), and to the nothing documentation. It's good to include cross references to mutating/non-mutating versions of a function, or to highlight a difference between two similar-seeming functions.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nThe above cross referencing is not a Markdown feature, and relies on Documenter.jl, which is used to build base Julia's documentation.","category":"page"},{"location":"stdlib/Markdown/#Footnote-references","page":"Markdown","title":"Footnote references","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Named and numbered footnote references can be written using the following syntax. A footnote name must be a single alphanumeric word containing no punctuation.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing a numbered footnote [^1] and a named one [^named].","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nThe text associated with a footnote can be written anywhere within the same page as the footnote reference. The syntax used to define the footnote text is discussed in the Footnotes section below.","category":"page"},{"location":"stdlib/Markdown/#Toplevel-elements","page":"Markdown","title":"Toplevel elements","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The following elements can be written either at the \"toplevel\" of a document or within another \"toplevel\" element.","category":"page"},{"location":"stdlib/Markdown/#Paragraphs","page":"Markdown","title":"Paragraphs","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph is a block of plain text, possibly containing any number of inline elements defined in the Inline elements section above, with one or more blank lines above and below it.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This is a paragraph.\n\nAnd this is *another* paragraph containing some emphasized text.\nA new line, but still part of the same paragraph.","category":"page"},{"location":"stdlib/Markdown/#Headers","page":"Markdown","title":"Headers","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A document can be split up into different sections using headers. Headers use the following syntax:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"# Level One\n## Level Two\n### Level Three\n#### Level Four\n##### Level Five\n###### Level Six","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A header line can contain any inline syntax in the same way as a paragraph can.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"tip: Tip\nTry to avoid using too many levels of header within a single document. A heavily nested document may be indicative of a need to restructure it or split it into several pages covering separate topics.","category":"page"},{"location":"stdlib/Markdown/#Code-blocks","page":"Markdown","title":"Code blocks","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Source code can be displayed as a literal block using an indent of four spaces or one tab as shown in the following example.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This is a paragraph.\n\n function func(x)\n # ...\n end\n\nAnother paragraph.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Additionally, code blocks can be enclosed using triple backticks with an optional \"language\" to specify how a block of code should be highlighted.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A code block without a \"language\":\n\n```\nfunction func(x)\n # ...\nend\n```\n\nand another one with the \"language\" specified as `julia`:\n\n```julia\nfunction func(x)\n # ...\nend\n```","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\n\"Fenced\" code blocks, as shown in the last example, should be preferred over indented code blocks since there is no way to specify what language an indented code block is written in.","category":"page"},{"location":"stdlib/Markdown/#Block-quotes","page":"Markdown","title":"Block quotes","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Text from external sources, such as quotations from books or websites, can be quoted using > characters prepended to each line of the quote as follows.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Here's a quote:\n\n> Julia is a high-level, high-performance dynamic programming language for\n> technical computing, with syntax that is familiar to users of other\n> technical computing environments.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Note that a single space must appear after the > character on each line. Quoted blocks may themselves contain other toplevel or inline elements.","category":"page"},{"location":"stdlib/Markdown/#Images","page":"Markdown","title":"Images","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The syntax for images is similar to the link syntax mentioned above. Prepending a ! character to a link will display an image from the specified URL rather than a link to it.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"![alternative text](link/to/image.png)","category":"page"},{"location":"stdlib/Markdown/#Lists","page":"Markdown","title":"Lists","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Unordered lists can be written by prepending each item in a list with either *, +, or -.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A list of items:\n\n * item one\n * item two\n * item three","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Note the two spaces before each * and the single space after each one.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Lists can contain other nested toplevel elements such as lists, code blocks, or quoteblocks. A blank line should be left between each list item when including any toplevel elements within a list.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Another list:\n\n * item one\n\n * item two\n\n ```\n f(x) = x\n ```\n\n * And a sublist:\n\n + sub-item one\n + sub-item two","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nThe contents of each item in the list must line up with the first line of the item. In the above example the fenced code block must be indented by four spaces to align with the i in item two.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Ordered lists are written by replacing the \"bullet\" character, either *, +, or -, with a positive integer followed by either . or ).","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Two ordered lists:\n\n 1. item one\n 2. item two\n 3. item three\n\n 5) item five\n 6) item six\n 7) item seven","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"An ordered list may start from a number other than one, as in the second list of the above example, where it is numbered from five. As with unordered lists, ordered lists can contain nested toplevel elements.","category":"page"},{"location":"stdlib/Markdown/#Display-equations","page":"Markdown","title":"Display equations","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Large LaTeX equations that do not fit inline within a paragraph may be written as display equations using a fenced code block with the \"language\" math as in the example below.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"```math\nf(a) = \\frac{1}{2\\pi}\\int_{0}^{2\\pi} (\\alpha+R\\cos(\\theta))d\\theta\n```","category":"page"},{"location":"stdlib/Markdown/#Footnotes","page":"Markdown","title":"Footnotes","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This syntax is paired with the inline syntax for Footnote references. Make sure to read that section as well.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Footnote text is defined using the following syntax, which is similar to footnote reference syntax, aside from the : character that is appended to the footnote label.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"[^1]: Numbered footnote text.\n\n[^note]:\n\n Named footnote text containing several toplevel elements\n indented by 4 spaces or one tab.\n\n * item one\n * item two\n * item three\n\n ```julia\n function func(x)\n # ...\n end\n ```","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nNo checks are done during parsing to make sure that all footnote references have matching footnotes.","category":"page"},{"location":"stdlib/Markdown/#Horizontal-rules","page":"Markdown","title":"Horizontal rules","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The equivalent of an
    HTML tag can be achieved using three hyphens (---). For example:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Text above the line.\n\n---\n\nAnd text below the line.","category":"page"},{"location":"stdlib/Markdown/#Tables","page":"Markdown","title":"Tables","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Basic tables can be written using the syntax described below. Note that markdown tables have limited features and cannot contain nested toplevel elements unlike other elements discussed above – only inline elements are allowed. Tables must always contain a header row with column names. Cells cannot span multiple rows or columns of the table.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"| Column One | Column Two | Column Three |\n|:---------- | ---------- |:------------:|\n| Row `1` | Column `2` | |\n| *Row* 2 | **Row** 2 | Column ``3`` |","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nAs illustrated in the above example each column of | characters must be aligned vertically.A : character on either end of a column's header separator (the row containing - characters) specifies whether the row is left-aligned, right-aligned, or (when : appears on both ends) center-aligned. Providing no : characters will default to right-aligning the column.","category":"page"},{"location":"stdlib/Markdown/#Admonitions","page":"Markdown","title":"Admonitions","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Specially formatted blocks, known as admonitions, can be used to highlight particular remarks. They can be defined using the following !!! syntax:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"!!! note\n\n This is the content of the note.\n It is indented by 4 spaces. A tab would work as well.\n\n!!! warning \"Beware!\"\n\n And this is another one.\n\n This warning admonition has a custom title: `\"Beware!\"`.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The first word after !!! declares the type of the admonition. There are standard admonition types that should produce special styling. Namely (in order of decreasing severity): danger, warning, info/note, and tip.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"You can also use your own admonition types, as long as the type name only contains lowercase Latin characters (a-z). For example, you could have a terminology block like this:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"!!! terminology \"julia vs Julia\"\n\n Strictly speaking, \"Julia\" refers to the language,\n and \"julia\" to the standard implementation.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"However, unless the code rendering the Markdown special-cases that particular admonition type, it will get the default styling.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A custom title for the box can be provided as a string (in double quotes) after the admonition type. If no title text is specified after the admonition type, then the type name will be used as the title (e.g. \"Note\" for the note admonition).","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Admonitions, like most other toplevel elements, can contain other toplevel elements (e.g. lists, images).","category":"page"},{"location":"stdlib/Markdown/#stdlib-markdown-literals","page":"Markdown","title":"Markdown String Literals","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The md\"\" macro allows you to embed Markdown strings directly into your Julia code. This macro is designed to simplify the inclusion of Markdown-formatted text within your Julia source files.","category":"page"},{"location":"stdlib/Markdown/#Usage","page":"Markdown","title":"Usage","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"result = md\"This is a **custom** Markdown string with [a link](http://example.com).\"","category":"page"},{"location":"stdlib/Markdown/#Markdown-Syntax-Extensions","page":"Markdown","title":"Markdown Syntax Extensions","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Julia's markdown supports interpolation in a very similar way to basic string literals, with the difference that it will store the object itself in the Markdown tree (as opposed to converting it to a string). When the Markdown content is rendered the usual show methods will be called, and these can be overridden as usual. This design allows the Markdown to be extended with arbitrarily complex features (such as references) without cluttering the basic syntax.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"In principle, the Markdown parser itself can also be arbitrarily extended by packages, or an entirely custom flavour of Markdown can be used, but this should generally be unnecessary.","category":"page"},{"location":"stdlib/Markdown/#stdlib-markdown-api","page":"Markdown","title":"API reference","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Markdown.MD\nMarkdown.@md_str\nMarkdown.@doc_str\nMarkdown.html\nMarkdown.latex","category":"page"},{"location":"stdlib/Markdown/#Markdown.MD","page":"Markdown","title":"Markdown.MD","text":"MD\n\nMD represents a Markdown document. Note that the MD constructor should not generally be used directly, since it constructs the internal data structures. Instead, you can construct MD objects using the exported macros @md_str and @doc_str.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Markdown/#Markdown.@md_str","page":"Markdown","title":"Markdown.@md_str","text":"@md_str -> MD\n\nParse the given string as Markdown text and return a corresponding MD object.\n\nExamples\n\njulia> s = md\"# Hello, world!\"\n Hello, world!\n ≡≡≡≡≡≡≡≡≡≡≡≡≡\n\njulia> typeof(s)\nMarkdown.MD\n\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Markdown/#Markdown.@doc_str","page":"Markdown","title":"Markdown.@doc_str","text":"@doc_str -> MD\n\nParse the given string as Markdown text, add line and module information and return a corresponding MD object.\n\n@doc_str can be used in conjunction with the Base.Docs module. Please also refer to the manual section on documentation for more information.\n\nExamples\n\njulia> s = doc\"f(x) = 2*x\"\n f(x) = 2*x\n\njulia> typeof(s)\nMarkdown.MD\n\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Markdown/#Markdown.html","page":"Markdown","title":"Markdown.html","text":"html([io::IO], md)\n\nOutput the contents of the Markdown object md in HTML format, either writing to an (optional) io stream or returning a string.\n\nOne can alternatively use show(io, \"text/html\", md) or repr(\"text/html\", md), which differ in that they wrap the output in a
    ...
    element.\n\nExamples\n\njulia> html(md\"hello _world_\")\n\"

    hello world

    \\n\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Markdown/#Markdown.latex","page":"Markdown","title":"Markdown.latex","text":"latex([io::IO], md)\n\nOutput the contents of the Markdown object md in LaTeX format, either writing to an (optional) io stream or returning a string.\n\nOne can alternatively use show(io, \"text/latex\", md) or repr(\"text/latex\", md).\n\nExamples\n\njulia> latex(md\"hello _world_\")\n\"hello \\\\emph{world}\\n\\n\"\n\n\n\n\n\n","category":"function"},{"location":"devdocs/subarrays/#SubArrays","page":"SubArrays","title":"SubArrays","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Julia's SubArray type is a container encoding a \"view\" of a parent AbstractArray. This page documents some of the design principles and implementation of SubArrays.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"One of the major design goals is to ensure high performance for views of both IndexLinear and IndexCartesian arrays. Furthermore, views of IndexLinear arrays should themselves be IndexLinear to the extent that it is possible.","category":"page"},{"location":"devdocs/subarrays/#Index-replacement","page":"SubArrays","title":"Index replacement","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Consider making 2d slices of a 3d array:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"DocTestSetup = :(import Random; Random.seed!(1234))","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> A = rand(2,3,4);\n\njulia> S1 = view(A, :, 1, 2:3)\n2×2 view(::Array{Float64, 3}, :, 1, 2:3) with eltype Float64:\n 0.839622 0.711389\n 0.967143 0.103929\n\njulia> S2 = view(A, 1, :, 2:3)\n3×2 view(::Array{Float64, 3}, 1, :, 2:3) with eltype Float64:\n 0.839622 0.711389\n 0.789764 0.806704\n 0.566704 0.962715","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"DocTestSetup = nothing","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"view drops \"singleton\" dimensions (ones that are specified by an Int), so both S1 and S2 are two-dimensional SubArrays. Consequently, the natural way to index these is with S1[i,j]. To extract the value from the parent array A, the natural approach is to replace S1[i,j] with A[i,1,(2:3)[j]] and S2[i,j] with A[1,i,(2:3)[j]].","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"The key feature of the design of SubArrays is that this index replacement can be performed without any runtime overhead.","category":"page"},{"location":"devdocs/subarrays/#SubArray-design","page":"SubArrays","title":"SubArray design","text":"","category":"section"},{"location":"devdocs/subarrays/#Type-parameters-and-fields","page":"SubArrays","title":"Type parameters and fields","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"The strategy adopted is first and foremost expressed in the definition of the type:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"struct SubArray{T,N,P,I,L} <: AbstractArray{T,N}\n parent::P\n indices::I\n offset1::Int # for linear indexing and pointer, only valid when L==true\n stride1::Int # used only for linear indexing\n ...\nend","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"SubArray has 5 type parameters. The first two are the standard element type and dimensionality. The next is the type of the parent AbstractArray. The most heavily-used is the fourth parameter, a Tuple of the types of the indices for each dimension. The final one, L, is only provided as a convenience for dispatch; it's a boolean that represents whether the index types support fast linear indexing. More on that later.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"If in our example above A is a Array{Float64, 3}, our S1 case above would be a SubArray{Float64,2,Array{Float64,3},Tuple{Base.Slice{Base.OneTo{Int64}},Int64,UnitRange{Int64}},false}. Note in particular the tuple parameter, which stores the types of the indices used to create S1. Likewise,","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> S1.indices\n(Base.Slice(Base.OneTo(2)), 1, 2:3)","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Storing these values allows index replacement, and having the types encoded as parameters allows one to dispatch to efficient algorithms.","category":"page"},{"location":"devdocs/subarrays/#Index-translation","page":"SubArrays","title":"Index translation","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Performing index translation requires that you do different things for different concrete SubArray types. For example, for S1, one needs to apply the i,j indices to the first and third dimensions of the parent array, whereas for S2 one needs to apply them to the second and third. The simplest approach to indexing would be to do the type-analysis at runtime:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"parentindices = Vector{Any}()\nfor thisindex in S.indices\n ...\n if isa(thisindex, Int)\n # Don't consume one of the input indices\n push!(parentindices, thisindex)\n elseif isa(thisindex, AbstractVector)\n # Consume an input index\n push!(parentindices, thisindex[inputindex[j]])\n j += 1\n elseif isa(thisindex, AbstractMatrix)\n # Consume two input indices\n push!(parentindices, thisindex[inputindex[j], inputindex[j+1]])\n j += 2\n elseif ...\nend\nS.parent[parentindices...]","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Unfortunately, this would be disastrous in terms of performance: each element access would allocate memory, and involves the running of a lot of poorly-typed code.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"The better approach is to dispatch to specific methods to handle each type of stored index. That's what reindex does: it dispatches on the type of the first stored index and consumes the appropriate number of input indices, and then it recurses on the remaining indices. In the case of S1, this expands to","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Base.reindex(S1, S1.indices, (i, j)) == (i, S1.indices[2], S1.indices[3][j])","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"for any pair of indices (i,j) (except CartesianIndexs and arrays thereof, see below).","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"This is the core of a SubArray; indexing methods depend upon reindex to do this index translation. Sometimes, though, we can avoid the indirection and make it even faster.","category":"page"},{"location":"devdocs/subarrays/#Linear-indexing","page":"SubArrays","title":"Linear indexing","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Linear indexing can be implemented efficiently when the entire array has a single stride that separates successive elements, starting from some offset. This means that we can pre-compute these values and represent linear indexing simply as an addition and multiplication, avoiding the indirection of reindex and (more importantly) the slow computation of the cartesian coordinates entirely.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"For SubArray types, the availability of efficient linear indexing is based purely on the types of the indices, and does not depend on values like the size of the parent array. You can ask whether a given set of indices supports fast linear indexing with the internal Base.viewindexing function:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> Base.viewindexing(S1.indices)\nIndexCartesian()\n\njulia> Base.viewindexing(S2.indices)\nIndexLinear()","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"This is computed during construction of the SubArray and stored in the L type parameter as a boolean that encodes fast linear indexing support. While not strictly necessary, it means that we can define dispatch directly on SubArray{T,N,A,I,true} without any intermediaries.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Since this computation doesn't depend on runtime values, it can miss some cases in which the stride happens to be uniform:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> A = reshape(1:4*2, 4, 2)\n4×2 reshape(::UnitRange{Int64}, 4, 2) with eltype Int64:\n 1 5\n 2 6\n 3 7\n 4 8\n\njulia> diff(A[2:2:4,:][:])\n3-element Vector{Int64}:\n 2\n 2\n 2","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"A view constructed as view(A, 2:2:4, :) happens to have uniform stride, and therefore linear indexing indeed could be performed efficiently. However, success in this case depends on the size of the array: if the first dimension instead were odd,","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> A = reshape(1:5*2, 5, 2)\n5×2 reshape(::UnitRange{Int64}, 5, 2) with eltype Int64:\n 1 6\n 2 7\n 3 8\n 4 9\n 5 10\n\njulia> diff(A[2:2:4,:][:])\n3-element Vector{Int64}:\n 2\n 3\n 2","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"then A[2:2:4,:] does not have uniform stride, so we cannot guarantee efficient linear indexing. Since we have to base this decision based purely on types encoded in the parameters of the SubArray, S = view(A, 2:2:4, :) cannot implement efficient linear indexing.","category":"page"},{"location":"devdocs/subarrays/#A-few-details","page":"SubArrays","title":"A few details","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Note that the Base.reindex function is agnostic to the types of the input indices; it simply determines how and where the stored indices should be reindexed. It not only supports integer indices, but it supports non-scalar indexing, too. This means that views of views don't need two levels of indirection; they can simply re-compute the indices into the original parent array!\nHopefully by now it's fairly clear that supporting slices means that the dimensionality, given by the parameter N, is not necessarily equal to the dimensionality of the parent array or the length of the indices tuple. Neither do user-supplied indices necessarily line up with entries in the indices tuple (e.g., the second user-supplied index might correspond to the third dimension of the parent array, and the third element in the indices tuple).\nWhat might be less obvious is that the dimensionality of the stored parent array must be equal to the number of effective indices in the indices tuple. Some examples:\nA = reshape(1:35, 5, 7) # A 2d parent Array\nS = view(A, 2:7) # A 1d view created by linear indexing\nS = view(A, :, :, 1:1) # Appending extra indices is supported\nNaively, you'd think you could just set S.parent = A and S.indices = (:,:,1:1), but supporting this dramatically complicates the reindexing process, especially for views of views. Not only do you need to dispatch on the types of the stored indices, but you need to examine whether a given index is the final one and \"merge\" any remaining stored indices together. This is not an easy task, and even worse: it's slow since it implicitly depends upon linear indexing.\nFortunately, this is precisely the computation that ReshapedArray performs, and it does so linearly if possible. Consequently, view ensures that the parent array is the appropriate dimensionality for the given indices by reshaping it if needed. The inner SubArray constructor ensures that this invariant is satisfied.\nCartesianIndex and arrays thereof throw a nasty wrench into the reindex scheme. Recall that reindex simply dispatches on the type of the stored indices in order to determine how many passed indices should be used and where they should go. But with CartesianIndex, there's no longer a one-to-one correspondence between the number of passed arguments and the number of dimensions that they index into. If we return to the above example of Base.reindex(S1, S1.indices, (i, j)), you can see that the expansion is incorrect for i, j = CartesianIndex(), CartesianIndex(2,1). It should skip the CartesianIndex() entirely and return:\n(CartesianIndex(2,1)[1], S1.indices[2], S1.indices[3][CartesianIndex(2,1)[2]])\nInstead, though, we get:\n(CartesianIndex(), S1.indices[2], S1.indices[3][CartesianIndex(2,1)])\nDoing this correctly would require combined dispatch on both the stored and passed indices across all combinations of dimensionalities in an intractable manner. As such, reindex must never be called with CartesianIndex indices. Fortunately, the scalar case is easily handled by first flattening the CartesianIndex arguments to plain integers. Arrays of CartesianIndex, however, cannot be split apart into orthogonal pieces so easily. Before attempting to use reindex, view must ensure that there are no arrays of CartesianIndex in the argument list. If there are, it can simply \"punt\" by avoiding the reindex calculation entirely, constructing a nested SubArray with two levels of indirection instead.","category":"page"},{"location":"devdocs/object/#Memory-layout-of-Julia-Objects","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"","category":"section"},{"location":"devdocs/object/#Object-layout-(jl_value_t)","page":"Memory layout of Julia Objects","title":"Object layout (jl_value_t)","text":"","category":"section"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The jl_value_t struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it is simply an opaque pointer:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"typedef struct jl_value_t* jl_pvalue_t;","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Each jl_value_t struct is contained in a jl_typetag_t struct that contains metadata information about the Julia object, such as its type and garbage collector (gc) reachability:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"typedef struct {\n opaque metadata;\n jl_value_t value;\n} jl_typetag_t;","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The type of any Julia object is an instance of a leaf jl_datatype_t object. The jl_typeof() function can be used to query for it:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_typeof(jl_value_t *v);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The layout of the object depends on its type. Reflection methods can be used to inspect that layout. A field can be accessed by calling one of the get-field methods:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i);\njl_value_t *jl_get_field(jl_value_t *o, char *fld);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"If the field types are known, a priori, to be all pointers, the values can also be extracted directly as an array access:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *v = value->fieldptr[n];","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"As an example, a \"boxed\" uint16_t is stored as follows:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"struct {\n opaque metadata;\n struct {\n uint16_t data; // -- 2 bytes\n } jl_value_t;\n};","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"This object is created by jl_box_uint16(). Note that the jl_value_t pointer references the data portion, not the metadata at the top of the struct.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"A value may be stored \"unboxed\" in many circumstances (just the data, without the metadata, and possibly not even stored but just kept in registers), so it is unsafe to assume that the address of a box is a unique identifier. The \"egal\" test (corresponding to the === function in Julia), should instead be used to compare two unknown objects for equivalence:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"int jl_egal(jl_value_t *a, jl_value_t *b);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"This optimization should be relatively transparent to the API, since the object will be \"boxed\" on-demand, whenever a jl_value_t pointer is needed.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Note that modification of a jl_value_t pointer in memory is permitted only if the object is mutable. Otherwise, modification of the value may corrupt the program and the result will be undefined. The mutability property of a value can be queried for with:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"int jl_is_mutable(jl_value_t *v);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"If the object being stored is a jl_value_t, the Julia garbage collector must be notified also:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"void jl_gc_wb(jl_value_t *parent, jl_value_t *ptr);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"However, the Embedding Julia section of the manual is also required reading at this point, for covering other details of boxing and unboxing various types, and understanding the gc interactions.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Mirror structs for some of the built-in types are defined in julia.h. The corresponding global jl_datatype_t objects are created by jl_init_types in jltypes.c.","category":"page"},{"location":"devdocs/object/#Garbage-collector-mark-bits","page":"Memory layout of Julia Objects","title":"Garbage collector mark bits","text":"","category":"section"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The garbage collector uses several bits from the metadata portion of the jl_typetag_t to track each object in the system. Further details about this algorithm can be found in the comments of the garbage collector implementation in gc.c.","category":"page"},{"location":"devdocs/object/#Object-allocation","page":"Memory layout of Julia Objects","title":"Object allocation","text":"","category":"section"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Most new objects are allocated by jl_new_structv():","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_new_struct(jl_datatype_t *type, ...);\njl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uint32_t na);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Although, isbits objects can be also constructed directly from memory:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_new_bits(jl_value_t *bt, void *data)","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"And some objects have special constructors that must be used instead of the above functions:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Types:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_datatype_t *jl_apply_type(jl_datatype_t *tc, jl_tuple_t *params);\njl_datatype_t *jl_apply_array_type(jl_datatype_t *type, size_t dim);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"While these are the most commonly used options, there are more low-level constructors too, which you can find declared in julia.h. These are used in jl_init_types() to create the initial types needed to bootstrap the creation of the Julia system image.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Tuples:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_tuple_t *jl_tuple(size_t n, ...);\njl_tuple_t *jl_tuplev(size_t n, jl_value_t **v);\njl_tuple_t *jl_alloc_tuple(size_t n);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The representation of tuples is highly unique in the Julia object representation ecosystem. In some cases, a Base.tuple() object may be an array of pointers to the objects contained by the tuple equivalent to:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"typedef struct {\n size_t length;\n jl_value_t *data[length];\n} jl_tuple_t;","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"However, in other cases, the tuple may be converted to an anonymous isbits type and stored unboxed, or it may not stored at all (if it is not being used in a generic context as a jl_value_t*).","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Symbols:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_sym_t *jl_symbol(const char *str);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Functions and MethodInstance:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_function_t *jl_new_generic_function(jl_sym_t *name);\njl_method_instance_t *jl_new_method_instance(jl_value_t *ast, jl_tuple_t *sparams);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Arrays:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_array_t *jl_new_array(jl_value_t *atype, jl_tuple_t *dims);\njl_array_t *jl_alloc_array_1d(jl_value_t *atype, size_t nr);\njl_array_t *jl_alloc_array_nd(jl_value_t *atype, size_t *dims, size_t ndims);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Note that many of these have alternative allocation functions for various special-purposes. The list here reflects the more common usages, but a more complete list can be found by reading the julia.h header file.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Internal to Julia, storage is typically allocated by newstruct() (or newobj() for the special types):","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *newstruct(jl_value_t *type);\njl_value_t *newobj(jl_value_t *type, size_t nfields);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"And at the lowest level, memory is getting allocated by a call to the garbage collector (in gc.c), then tagged with its type:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_gc_allocobj(size_t nbytes);\nvoid jl_set_typeof(jl_value_t *v, jl_datatype_t *type);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"note: Out of date Warning\nThe documentation and usage for the function jl_gc_allocobj may be out of date","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Note that all objects are allocated in multiples of 4 bytes and aligned to the platform pointer size. Memory is allocated from a pool for smaller objects, or directly with malloc() for large objects.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"sidebar: Singleton Types\nSingleton types have only one instance and no data fields. Singleton instances have a size of 0 bytes, and consist only of their metadata. e.g. nothing::Nothing.See Singleton Types and Nothingness and missing values","category":"page"},{"location":"devdocs/build/windows/#Windows","page":"Windows","title":"Windows","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"This file describes how to install, or build, and use Julia on Windows.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"For more general information about Julia, please see the main README or the documentation.","category":"page"},{"location":"devdocs/build/windows/#General-Information-for-Windows","page":"Windows","title":"General Information for Windows","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"We highly recommend running Julia using a modern terminal application, in particular Windows Terminal, which can be installed from the Microsoft Store.","category":"page"},{"location":"devdocs/build/windows/#Line-endings","page":"Windows","title":"Line endings","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Julia uses binary-mode files exclusively. Unlike many other Windows programs, if you write \\n to a file, you get a \\n in the file, not some other bit pattern. This matches the behavior exhibited by other operating systems. If you have installed Git for Windows, it is suggested, but not required, that you configure your system Git to use the same convention:","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"git config --global core.eol lf\ngit config --global core.autocrlf input","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"or edit %USERPROFILE%\\.gitconfig and add/edit the lines:","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"[core]\n eol = lf\n autocrlf = input","category":"page"},{"location":"devdocs/build/windows/#Binary-distribution","page":"Windows","title":"Binary distribution","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"For the binary distribution installation notes on Windows please see the instructions at https://julialang.org/downloads/platform/#windows.","category":"page"},{"location":"devdocs/build/windows/#Source-distribution","page":"Windows","title":"Source distribution","text":"","category":"section"},{"location":"devdocs/build/windows/#Cygwin-to-MinGW-cross-compiling","page":"Windows","title":"Cygwin-to-MinGW cross-compiling","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"The recommended way of compiling Julia from source on Windows is by cross compiling from Cygwin, using versions of the MinGW-w64 compilers available through Cygwin's package manager.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Download and run Cygwin setup for 32 bit or 64 bit. Note, that you can compile either 32 or 64 bit Julia from either 32 or 64 bit Cygwin. 64 bit Cygwin has a slightly smaller but often more up-to-date selection of packages.\nAdvanced: you may skip steps 2-4 by running:\nsetup-x86_64.exe -s -q -P cmake,gcc-g++,git,make,patch,curl,m4,python3,p7zip,mingw64-i686-gcc-g++,mingw64-i686-gcc-fortran,mingw64-x86_64-gcc-g++,mingw64-x86_64-gcc-fortran\nreplacing with a site from https://cygwin.com/mirrors.html or run setup manually first and select a mirror.\nSelect installation location and a mirror to download from.\nAt the Select Packages step, select the following:\nFrom the Devel category: cmake, gcc-g++, git, make, patch\nFrom the Net category: curl\nFrom Interpreters (or Python) category: m4, python3\nFrom the Archive category: p7zip\nFor 32 bit Julia, and also from the Devel category: mingw64-i686-gcc-g++ and mingw64-i686-gcc-fortran\nFor 64 bit Julia, and also from the Devel category: mingw64-x86_64-gcc-g++ and mingw64-x86_64-gcc-fortran\nAllow Cygwin installation to finish, then start from the installed shortcut 'Cygwin Terminal', or 'Cygwin64 Terminal', respectively.\nBuild Julia and its dependencies from source:\nGet the Julia sources\ngit clone https://github.com/JuliaLang/julia.git\ncd julia\nTip: If you get an error: cannot fork() for fetch-pack: Resource temporarily unavailable from git, add alias git=\"env PATH=/usr/bin git\" to ~/.bashrc and restart Cygwin.\nSet the XC_HOST variable in Make.user to indicate MinGW-w64 cross compilation\necho 'XC_HOST = i686-w64-mingw32' > Make.user # for 32 bit Julia\n# or\necho 'XC_HOST = x86_64-w64-mingw32' > Make.user # for 64 bit Julia\nStart the build\nmake -j 4 # Adjust the number of threads (4) to match your build environment.\nmake -j 4 debug # This builds julia-debug.exe\nRun Julia using the Julia executables directly\nusr/bin/julia.exe\nusr/bin/julia-debug.exe","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"note: Pro tip: build both!\nmake O=julia-win32 configure\nmake O=julia-win64 configure\necho 'XC_HOST = i686-w64-mingw32' > julia-win32/Make.user\necho 'XC_HOST = x86_64-w64-mingw32' > julia-win64/Make.user\necho 'ifeq ($(BUILDROOT),$(JULIAHOME))\n $(error \"in-tree build disabled\")\n endif' >> Make.user\nmake -C julia-win32 # build for Windows x86 in julia-win32 folder\nmake -C julia-win64 # build for Windows x86-64 in julia-win64 folder","category":"page"},{"location":"devdocs/build/windows/#Compiling-with-MinGW/MSYS2","page":"Windows","title":"Compiling with MinGW/MSYS2","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"MSYS2 is a software distribution and build environment for Windows.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Note: MSYS2 requires 64 bit Windows 7 or newer.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Install and configure MSYS2.\nDownload and run the latest installer for the 64-bit distribution. The installer will have a name like msys2-x86_64-yyyymmdd.exe.\nOpen the MSYS2 shell. Update the package database and base packages:\npacman -Syu\nExit and restart MSYS2. Update the rest of the base packages:\npacman -Syu\nThen install tools required to build julia:\npacman -S cmake diffutils git m4 make patch tar p7zip curl python\nFor 64 bit Julia, install the x86_64 version:\npacman -S mingw-w64-x86_64-gcc\nFor 32 bit Julia, install the i686 version:\npacman -S mingw-w64-i686-gcc\nConfiguration of MSYS2 is complete. Now exit the MSYS2 shell.\nBuild Julia and its dependencies with pre-build dependencies.\nOpen a new MINGW64/MINGW32 shell. Currently we can't use both mingw32 and mingw64, so if you want to build the x86_64 and i686 versions, you'll need to build them in each environment separately.\nClone the Julia sources:\ngit clone https://github.com/JuliaLang/julia.git cd julia\nStart the build\nmake -j$(nproc)","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"note: Pro tip: build in dir\nmake O=julia-mingw-w64 configure\necho 'ifeq ($(BUILDROOT),$(JULIAHOME))\n $(error \"in-tree build disabled\")\n endif' >> Make.user\nmake -C julia-mingw-w64","category":"page"},{"location":"devdocs/build/windows/#Cross-compiling-from-Unix-(Linux/Mac/WSL)","page":"Windows","title":"Cross-compiling from Unix (Linux/Mac/WSL)","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"You can also use MinGW-w64 cross compilers to build a Windows version of Julia from Linux, Mac, or the Windows Subsystem for Linux (WSL).","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"First, you will need to ensure your system has the required dependencies. We need wine (>=1.7.5), a system compiler, and some downloaders. Note: a Cygwin install might interfere with this method if using WSL.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"On Ubuntu (on other Linux systems the dependency names are likely to be similar):","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"apt-get install wine-stable gcc wget p7zip-full winbind mingw-w64 gfortran-mingw-w64\ndpkg --add-architecture i386 && apt-get update && apt-get install wine32 # add sudo to each if needed\n# switch all of the following to their \"-posix\" variants (interactively):\nfor pkg in i686-w64-mingw32-g++ i686-w64-mingw32-gcc i686-w64-mingw32-gfortran x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gfortran; do\n sudo update-alternatives --config $pkg\ndone","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"On Mac: Install XCode, XCode command line tools, X11 (now XQuartz), and MacPorts or Homebrew. Then run port install wine wget mingw-w64, or brew install wine wget mingw-w64, as appropriate.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Then run the build:","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"git clone https://github.com/JuliaLang/julia.git julia-win32\ncd julia-win32\necho override XC_HOST = i686-w64-mingw32 >> Make.user\nmake\nmake win-extras (Necessary before running make binary-dist)\nmake binary-dist then make exe to create the Windows installer.\nmove the julia-*.exe installer to the target machine","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"If you are building for 64-bit Windows, the steps are essentially the same. Just replace i686 in XC_HOST with x86_64. (Note: on Mac, wine only runs in 32-bit mode).","category":"page"},{"location":"devdocs/build/windows/#Debugging-a-cross-compiled-build-under-wine","page":"Windows","title":"Debugging a cross-compiled build under wine","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"The most effective way to debug a cross-compiled version of Julia on the cross-compilation host is to install a Windows version of GDB and run it under wine as usual. The pre-built packages available as part of the MSYS2 project are known to work. Apart from the GDB package you may also need the python and termcap packages. Finally, GDB's prompt may not work when launched from the command line. This can be worked around by prepending wineconsole to the regular GDB invocation.","category":"page"},{"location":"devdocs/build/windows/#After-compiling","page":"Windows","title":"After compiling","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Compiling using one of the options above creates a basic Julia build, but not some extra components that are included if you run the full Julia binary installer. If you need these components, the easiest way to get them is to build the installer yourself using make win-extras followed by make binary-dist and make exe. Then run the resulting installer.","category":"page"},{"location":"devdocs/build/windows/#Windows-Build-Debugging","page":"Windows","title":"Windows Build Debugging","text":"","category":"section"},{"location":"devdocs/build/windows/#GDB-hangs-with-Cygwin-mintty","page":"Windows","title":"GDB hangs with Cygwin mintty","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Run GDB under the Windows console (cmd) instead. GDB may not function properly under mintty with non- Cygwin applications. You can use cmd /c start to start the Windows console from mintty if necessary.","category":"page"},{"location":"devdocs/build/windows/#GDB-not-attaching-to-the-right-process","page":"Windows","title":"GDB not attaching to the right process","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Use the PID from the Windows task manager or WINPID from the ps command instead of the PID from unix-style command line tools (e.g. pgrep). You may need to add the PID column if it is not shown by default in the Windows task manager.","category":"page"},{"location":"devdocs/build/windows/#GDB-not-showing-the-right-backtrace","page":"Windows","title":"GDB not showing the right backtrace","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"When attaching to the julia process, GDB may not be attaching to the right thread. Use info threads command to show all the threads and thread to switch threads.\nBe sure to use a 32 bit version of GDB to debug a 32 bit build of Julia, or a 64 bit version of GDB to debug a 64 bit build of Julia.","category":"page"},{"location":"devdocs/build/windows/#Build-process-is-slow/eats-memory/hangs-my-computer","page":"Windows","title":"Build process is slow/eats memory/hangs my computer","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Disable the Windows Superfetch and Program Compatibility Assistant services, as they are known to have spurious interactions with MinGW/Cygwin.\nAs mentioned in the link above: excessive memory use by svchost specifically may be investigated in the Task Manager by clicking on the high-memory svchost.exe process and selecting Go to Services. Disable child services one-by-one until a culprit is found.\nBeware of BLODA. The vmmap tool is indispensable for identifying such software conflicts. Use vmmap to inspect the list of loaded DLLs for bash, mintty, or another persistent process used to drive the build. Essentially any DLL outside of the Windows System directory is potential BLODA.","category":"page"},{"location":"base/io-network/#I/O-and-Network","page":"I/O and Network","title":"I/O and Network","text":"","category":"section"},{"location":"base/io-network/#General-I/O","page":"I/O and Network","title":"General I/O","text":"","category":"section"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.stdout\nBase.stderr\nBase.stdin\nBase.read(::AbstractString)\nBase.write(::AbstractString, ::Any)\nBase.open\nBase.IOStream\nBase.IOBuffer\nBase.take!(::Base.GenericIOBuffer)\nBase.Pipe\nBase.link_pipe!\nBase.fdio\nBase.flush\nBase.close\nBase.closewrite\nBase.write\nBase.read\nBase.read!\nBase.readbytes!\nBase.unsafe_read\nBase.unsafe_write\nBase.readeach\nBase.peek\nBase.position\nBase.seek\nBase.seekstart\nBase.seekend\nBase.skip\nBase.mark\nBase.unmark\nBase.reset(::IO)\nBase.ismarked\nBase.eof\nBase.isreadonly\nBase.iswritable\nBase.isreadable\nBase.isexecutable\nBase.isopen\nBase.fd\nBase.redirect_stdio\nBase.redirect_stdout\nBase.redirect_stdout(::Function, ::Any)\nBase.redirect_stderr\nBase.redirect_stderr(::Function, ::Any)\nBase.redirect_stdin\nBase.redirect_stdin(::Function, ::Any)\nBase.readchomp\nBase.truncate\nBase.skipchars\nBase.countlines\nBase.PipeBuffer\nBase.readavailable\nBase.IOContext\nBase.IOContext(::IO, ::Pair)\nBase.IOContext(::IO, ::IOContext)","category":"page"},{"location":"base/io-network/#Base.stdout","page":"I/O and Network","title":"Base.stdout","text":"stdout::IO\n\nGlobal variable referring to the standard out stream.\n\n\n\n\n\n","category":"constant"},{"location":"base/io-network/#Base.stderr","page":"I/O and Network","title":"Base.stderr","text":"stderr::IO\n\nGlobal variable referring to the standard error stream.\n\n\n\n\n\n","category":"constant"},{"location":"base/io-network/#Base.stdin","page":"I/O and Network","title":"Base.stdin","text":"stdin::IO\n\nGlobal variable referring to the standard input stream.\n\n\n\n\n\n","category":"constant"},{"location":"base/io-network/#Base.read-Tuple{AbstractString}","page":"I/O and Network","title":"Base.read","text":"read(filename::AbstractString)\n\nRead the entire contents of a file as a Vector{UInt8}.\n\nread(filename::AbstractString, String)\n\nRead the entire contents of a file as a string.\n\nread(filename::AbstractString, args...)\n\nOpen a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.write-Tuple{AbstractString, Any}","page":"I/O and Network","title":"Base.write","text":"write(filename::AbstractString, content)\n\nWrite the canonical binary representation of content to a file, which will be created if it does not exist yet or overwritten if it does exist.\n\nReturn the number of bytes written into the file.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.open","page":"I/O and Network","title":"Base.open","text":"open(f::Function, args...; kwargs...)\n\nApply the function f to the result of open(args...; kwargs...) and close the resulting file descriptor upon completion.\n\nExamples\n\njulia> write(\"myfile.txt\", \"Hello world!\");\n\njulia> open(io->read(io, String), \"myfile.txt\")\n\"Hello world!\"\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\nopen(filename::AbstractString; lock = true, keywords...) -> IOStream\n\nOpen a file in a mode specified by five boolean keyword arguments:\n\nKeyword Description Default\nread open for reading !write\nwrite open for writing truncate | append\ncreate create if non-existent !read & write | truncate | append\ntruncate truncate to zero size !read & write\nappend seek to end false\n\nThe default when no keywords are passed is to open files for reading only. Returns a stream for accessing the opened file.\n\nThe lock keyword argument controls whether operations will be locked for safe multi-threaded access.\n\ncompat: Julia 1.5\nThe lock argument is available as of Julia 1.5.\n\n\n\n\n\nopen(filename::AbstractString, [mode::AbstractString]; lock = true) -> IOStream\n\nAlternate syntax for open, where a string-based mode specifier is used instead of the five booleans. The values of mode correspond to those from fopen(3) or Perl open, and are equivalent to setting the following boolean groups:\n\nMode Description Keywords\nr read none\nw write, create, truncate write = true\na write, create, append append = true\nr+ read, write read = true, write = true\nw+ read, write, create, truncate truncate = true, read = true\na+ read, write, create, append append = true, read = true\n\nThe lock keyword argument controls whether operations will be locked for safe multi-threaded access.\n\nExamples\n\njulia> io = open(\"myfile.txt\", \"w\");\n\njulia> write(io, \"Hello world!\");\n\njulia> close(io);\n\njulia> io = open(\"myfile.txt\", \"r\");\n\njulia> read(io, String)\n\"Hello world!\"\n\njulia> write(io, \"This file is read only\")\nERROR: ArgumentError: write failed, IOStream is not writeable\n[...]\n\njulia> close(io)\n\njulia> io = open(\"myfile.txt\", \"a\");\n\njulia> write(io, \"This stream is not read only\")\n28\n\njulia> close(io)\n\njulia> rm(\"myfile.txt\")\n\ncompat: Julia 1.5\nThe lock argument is available as of Julia 1.5.\n\n\n\n\n\nopen(fd::OS_HANDLE) -> IO\n\nTake a raw file descriptor wrap it in a Julia-aware IO type, and take ownership of the fd handle. Call open(Libc.dup(fd)) to avoid the ownership capture of the original handle.\n\nwarning: Warning\nDo not call this on a handle that's already owned by some other part of the system.\n\n\n\n\n\nopen(command, mode::AbstractString, stdio=devnull)\n\nRun command asynchronously. Like open(command, stdio; read, write) except specifying the read and write flags via a mode string instead of keyword arguments. Possible mode strings are:\n\nMode Description Keywords\nr read none\nw write write = true\nr+ read, write read = true, write = true\nw+ read, write read = true, write = true\n\n\n\n\n\nopen(command, stdio=devnull; write::Bool = false, read::Bool = !write)\n\nStart running command asynchronously, and return a process::IO object. If read is true, then reads from the process come from the process's standard output and stdio optionally specifies the process's standard input stream. If write is true, then writes go to the process's standard input and stdio optionally specifies the process's standard output stream. The process's standard error stream is connected to the current global stderr.\n\n\n\n\n\nopen(f::Function, command, args...; kwargs...)\n\nSimilar to open(command, args...; kwargs...), but calls f(stream) on the resulting process stream, then closes the input stream and waits for the process to complete. Return the value returned by f on success. Throw an error if the process failed, or if the process attempts to print anything to stdout.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.IOStream","page":"I/O and Network","title":"Base.IOStream","text":"IOStream\n\nA buffered IO stream wrapping an OS file descriptor. Mostly used to represent files returned by open.\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.IOBuffer","page":"I/O and Network","title":"Base.IOBuffer","text":"IOBuffer([data::AbstractVector{UInt8}]; keywords...) -> IOBuffer\n\nCreate an in-memory I/O stream, which may optionally operate on a pre-existing array.\n\nIt may take optional keyword arguments:\n\nread, write, append: restricts operations to the buffer; see open for details.\ntruncate: truncates the buffer size to zero length.\nmaxsize: specifies a size beyond which the buffer may not be grown.\nsizehint: suggests a capacity of the buffer (data must implement sizehint!(data, size)).\n\nWhen data is not given, the buffer will be both readable and writable by default.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\", \" It has many members.\")\n56\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization. It has many members.\"\n\njulia> io = IOBuffer(b\"JuliaLang is a GitHub organization.\")\nIOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=35, maxsize=Inf, ptr=1, mark=-1)\n\njulia> read(io, String)\n\"JuliaLang is a GitHub organization.\"\n\njulia> write(io, \"This isn't writable.\")\nERROR: ArgumentError: ensureroom failed, IOBuffer is not writeable\n\njulia> io = IOBuffer(UInt8[], read=true, write=true, maxsize=34)\nIOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=34, ptr=1, mark=-1)\n\njulia> write(io, \"JuliaLang is a GitHub organization.\")\n34\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization\"\n\njulia> length(read(IOBuffer(b\"data\", read=true, truncate=false)))\n4\n\njulia> length(read(IOBuffer(b\"data\", read=true, truncate=true)))\n0\n\n\n\n\n\nIOBuffer(string::String)\n\nCreate a read-only IOBuffer on the data underlying the given string.\n\nExamples\n\njulia> io = IOBuffer(\"Haho\");\n\njulia> String(take!(io))\n\"Haho\"\n\njulia> String(take!(io))\n\"Haho\"\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.take!-Tuple{Base.GenericIOBuffer}","page":"I/O and Network","title":"Base.take!","text":"take!(b::IOBuffer)\n\nObtain the contents of an IOBuffer as an array. Afterwards, the IOBuffer is reset to its initial state.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\", \" It has many members.\")\n56\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization. It has many members.\"\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.Pipe","page":"I/O and Network","title":"Base.Pipe","text":"Pipe()\n\nConstruct an uninitialized Pipe object, especially for IO communication between multiple processes.\n\nThe appropriate end of the pipe will be automatically initialized if the object is used in process spawning. This can be useful to easily obtain references in process pipelines, e.g.:\n\njulia> err = Pipe()\n\n# After this `err` will be initialized and you may read `foo`'s\n# stderr from the `err` pipe, or pass `err` to other pipelines.\njulia> run(pipeline(pipeline(`foo`, stderr=err), `cat`), wait=false)\n\n# Now destroy the write half of the pipe, so that the read half will get EOF\njulia> closewrite(err)\n\njulia> read(err, String)\n\"stderr messages\"\n\nSee also Base.link_pipe!.\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.link_pipe!","page":"I/O and Network","title":"Base.link_pipe!","text":"link_pipe!(pipe; reader_supports_async=false, writer_supports_async=false)\n\nInitialize pipe and link the in endpoint to the out endpoint. The keyword arguments reader_supports_async/writer_supports_async correspond to OVERLAPPED on Windows and O_NONBLOCK on POSIX systems. They should be true unless they'll be used by an external program (e.g. the output of a command executed with run).\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.fdio","page":"I/O and Network","title":"Base.fdio","text":"fdio([name::AbstractString, ]fd::Integer[, own::Bool=false]) -> IOStream\n\nCreate an IOStream object from an integer file descriptor. If own is true, closing this object will close the underlying descriptor. By default, an IOStream is closed when it is garbage collected. name allows you to associate the descriptor with a named file.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.flush","page":"I/O and Network","title":"Base.flush","text":"flush(stream)\n\nCommit all currently buffered writes to the given stream.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.close","page":"I/O and Network","title":"Base.close","text":"close(stream)\n\nClose an I/O stream. Performs a flush first.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.closewrite","page":"I/O and Network","title":"Base.closewrite","text":"closewrite(stream)\n\nShutdown the write half of a full-duplex I/O stream. Performs a flush first. Notify the other end that no more data will be written to the underlying file. This is not supported by all IO types.\n\nIf implemented, closewrite causes subsequent read or eof calls that would block to instead throw EOF or return true, respectively. If the stream is already closed, this is idempotent.\n\nExamples\n\njulia> io = Base.BufferStream(); # this never blocks, so we can read and write on the same Task\n\njulia> write(io, \"request\");\n\njulia> # calling `read(io)` here would block forever\n\njulia> closewrite(io);\n\njulia> read(io, String)\n\"request\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.write","page":"I/O and Network","title":"Base.write","text":"write(io::IO, x)\n\nWrite the canonical binary representation of a value to the given I/O stream or file. Return the number of bytes written into the stream. See also print to write a text representation (with an encoding that may depend upon io).\n\nThe endianness of the written value depends on the endianness of the host system. Convert to/from a fixed endianness when writing/reading (e.g. using htol and ltoh) to get results that are consistent across platforms.\n\nYou can write multiple values with the same write call. i.e. the following are equivalent:\n\nwrite(io, x, y...)\nwrite(io, x) + write(io, y...)\n\nExamples\n\nConsistent serialization:\n\njulia> fname = tempname(); # random temporary filename\n\njulia> open(fname,\"w\") do f\n # Make sure we write 64bit integer in little-endian byte order\n write(f,htol(Int64(42)))\n end\n8\n\njulia> open(fname,\"r\") do f\n # Convert back to host byte order and host integer type\n Int(ltoh(read(f,Int64)))\n end\n42\n\nMerging write calls:\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\", \" It has many members.\")\n56\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization. It has many members.\"\n\njulia> write(io, \"Sometimes those members\") + write(io, \" write documentation.\")\n44\n\njulia> String(take!(io))\n\"Sometimes those members write documentation.\"\n\nUser-defined plain-data types without write methods can be written when wrapped in a Ref:\n\njulia> struct MyStruct; x::Float64; end\n\njulia> io = IOBuffer()\nIOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)\n\njulia> write(io, Ref(MyStruct(42.0)))\n8\n\njulia> seekstart(io); read!(io, Ref(MyStruct(NaN)))\nBase.RefValue{MyStruct}(MyStruct(42.0))\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.read","page":"I/O and Network","title":"Base.read","text":"read(io::IO, T)\n\nRead a single value of type T from io, in canonical binary representation.\n\nNote that Julia does not convert the endianness for you. Use ntoh or ltoh for this purpose.\n\nread(io::IO, String)\n\nRead the entirety of io, as a String (see also readchomp).\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization\");\n\njulia> read(io, Char)\n'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization\");\n\njulia> read(io, String)\n\"JuliaLang is a GitHub organization\"\n\n\n\n\n\nread(filename::AbstractString)\n\nRead the entire contents of a file as a Vector{UInt8}.\n\nread(filename::AbstractString, String)\n\nRead the entire contents of a file as a string.\n\nread(filename::AbstractString, args...)\n\nOpen a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).\n\n\n\n\n\nread(s::IO, nb=typemax(Int))\n\nRead at most nb bytes from s, returning a Vector{UInt8} of the bytes read.\n\n\n\n\n\nread(s::IOStream, nb::Integer; all=true)\n\nRead at most nb bytes from s, returning a Vector{UInt8} of the bytes read.\n\nIf all is true (the default), this function will block repeatedly trying to read all requested bytes, until an error or end-of-file occurs. If all is false, at most one read call is performed, and the amount of data returned is device-dependent. Note that not all stream types support the all option.\n\n\n\n\n\nread(command::Cmd)\n\nRun command and return the resulting output as an array of bytes.\n\n\n\n\n\nread(command::Cmd, String)\n\nRun command and return the resulting output as a String.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.read!","page":"I/O and Network","title":"Base.read!","text":"read!(stream::IO, array::AbstractArray)\nread!(filename::AbstractString, array::AbstractArray)\n\nRead binary data from an I/O stream or file, filling in array.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readbytes!","page":"I/O and Network","title":"Base.readbytes!","text":"readbytes!(stream::IO, b::AbstractVector{UInt8}, nb=length(b))\n\nRead at most nb bytes from stream into b, returning the number of bytes read. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.\n\n\n\n\n\nreadbytes!(stream::IOStream, b::AbstractVector{UInt8}, nb=length(b); all::Bool=true)\n\nRead at most nb bytes from stream into b, returning the number of bytes read. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.\n\nIf all is true (the default), this function will block repeatedly trying to read all requested bytes, until an error or end-of-file occurs. If all is false, at most one read call is performed, and the amount of data returned is device-dependent. Note that not all stream types support the all option.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.unsafe_read","page":"I/O and Network","title":"Base.unsafe_read","text":"unsafe_read(io::IO, ref, nbytes::UInt)\n\nCopy nbytes from the IO stream object into ref (converted to a pointer).\n\nIt is recommended that subtypes T<:IO override the following method signature to provide more efficient implementations: unsafe_read(s::T, p::Ptr{UInt8}, n::UInt)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.unsafe_write","page":"I/O and Network","title":"Base.unsafe_write","text":"unsafe_write(io::IO, ref, nbytes::UInt)\n\nCopy nbytes from ref (converted to a pointer) into the IO object.\n\nIt is recommended that subtypes T<:IO override the following method signature to provide more efficient implementations: unsafe_write(s::T, p::Ptr{UInt8}, n::UInt)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readeach","page":"I/O and Network","title":"Base.readeach","text":"readeach(io::IO, T)\n\nReturn an iterable object yielding read(io, T).\n\nSee also skipchars, eachline, readuntil.\n\ncompat: Julia 1.6\nreadeach requires Julia 1.6 or later.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\\n It has many members.\\n\");\n\njulia> for c in readeach(io, Char)\n c == '\\n' && break\n print(c)\n end\nJuliaLang is a GitHub organization.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.peek","page":"I/O and Network","title":"Base.peek","text":"peek(stream[, T=UInt8])\n\nRead and return a value of type T from a stream without advancing the current position in the stream. See also startswith(stream, char_or_string).\n\nExamples\n\njulia> b = IOBuffer(\"julia\");\n\njulia> peek(b)\n0x6a\n\njulia> position(b)\n0\n\njulia> peek(b, Char)\n'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase)\n\ncompat: Julia 1.5\nThe method which accepts a type requires Julia 1.5 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.position","page":"I/O and Network","title":"Base.position","text":"position(l::Lexer)\n\nReturns the current position.\n\n\n\n\n\nposition(s)\n\nGet the current position of a stream.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> seek(io, 5);\n\njulia> position(io)\n5\n\njulia> skip(io, 10);\n\njulia> position(io)\n15\n\njulia> seekend(io);\n\njulia> position(io)\n35\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.seek","page":"I/O and Network","title":"Base.seek","text":"seek(s, pos)\n\nSeek a stream to the given position.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> seek(io, 5);\n\njulia> read(io, Char)\n'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.seekstart","page":"I/O and Network","title":"Base.seekstart","text":"seekstart(s)\n\nSeek a stream to its beginning.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> seek(io, 5);\n\njulia> read(io, Char)\n'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)\n\njulia> seekstart(io);\n\njulia> read(io, Char)\n'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.seekend","page":"I/O and Network","title":"Base.seekend","text":"seekend(s)\n\nSeek a stream to its end.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.skip","page":"I/O and Network","title":"Base.skip","text":"skip(s, offset)\n\nSeek a stream relative to the current position.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> seek(io, 5);\n\njulia> skip(io, 10);\n\njulia> read(io, Char)\n'G': ASCII/Unicode U+0047 (category Lu: Letter, uppercase)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.mark","page":"I/O and Network","title":"Base.mark","text":"mark(s::IO)\n\nAdd a mark at the current position of stream s. Return the marked position.\n\nSee also unmark, reset, ismarked.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.unmark","page":"I/O and Network","title":"Base.unmark","text":"unmark(s::IO)\n\nRemove a mark from stream s. Return true if the stream was marked, false otherwise.\n\nSee also mark, reset, ismarked.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.reset-Tuple{IO}","page":"I/O and Network","title":"Base.reset","text":"reset(s::IO)\n\nReset a stream s to a previously marked position, and remove the mark. Return the previously marked position. Throw an error if the stream is not marked.\n\nSee also mark, unmark, ismarked.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.ismarked","page":"I/O and Network","title":"Base.ismarked","text":"ismarked(s::IO)\n\nReturn true if stream s is marked.\n\nSee also mark, unmark, reset.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.eof","page":"I/O and Network","title":"Base.eof","text":"eof(stream) -> Bool\n\nTest whether an I/O stream is at end-of-file. If the stream is not yet exhausted, this function will block to wait for more data if necessary, and then return false. Therefore it is always safe to read one byte after seeing eof return false. eof will return false as long as buffered data is still available, even if the remote end of a connection is closed.\n\nExamples\n\njulia> b = IOBuffer(\"my buffer\");\n\njulia> eof(b)\nfalse\n\njulia> seekend(b);\n\njulia> eof(b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.isreadonly","page":"I/O and Network","title":"Base.isreadonly","text":"isreadonly(io) -> Bool\n\nDetermine whether a stream is read-only.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization\");\n\njulia> isreadonly(io)\ntrue\n\njulia> io = IOBuffer();\n\njulia> isreadonly(io)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.iswritable","page":"I/O and Network","title":"Base.iswritable","text":"iswritable(path::String)\n\nReturn true if the access permissions for the given path permitted writing by the current user.\n\nnote: Note\nThis permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling iswritable first.\n\nnote: Note\nCurrently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also ispath, isexecutable, isreadable.\n\n\n\n\n\niswritable(io) -> Bool\n\nReturn false if the specified IO object is not writable.\n\nExamples\n\njulia> open(\"myfile.txt\", \"w\") do io\n print(io, \"Hello world!\");\n iswritable(io)\n end\ntrue\n\njulia> open(\"myfile.txt\", \"r\") do io\n iswritable(io)\n end\nfalse\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.isreadable","page":"I/O and Network","title":"Base.isreadable","text":"isreadable(path::String)\n\nReturn true if the access permissions for the given path permitted reading by the current user.\n\nnote: Note\nThis permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling isreadable first.\n\nnote: Note\nCurrently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also ispath, isexecutable, iswritable.\n\n\n\n\n\nisreadable(io) -> Bool\n\nReturn false if the specified IO object is not readable.\n\nExamples\n\njulia> open(\"myfile.txt\", \"w\") do io\n print(io, \"Hello world!\");\n isreadable(io)\n end\nfalse\n\njulia> open(\"myfile.txt\", \"r\") do io\n isreadable(io)\n end\ntrue\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.isexecutable","page":"I/O and Network","title":"Base.isexecutable","text":"isexecutable(path::String)\n\nReturn true if the given path has executable permissions.\n\nnote: Note\nThis permission may change before the user executes path, so it is recommended to execute the file and handle the error if that fails, rather than calling isexecutable first.\n\nnote: Note\nPrior to Julia 1.6, this did not correctly interrogate filesystem ACLs on Windows, therefore it would return true for any file. From Julia 1.6 on, it correctly determines whether the file is marked as executable or not.\n\nSee also ispath, isreadable, iswritable.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.isopen","page":"I/O and Network","title":"Base.isopen","text":"isopen(object) -> Bool\n\nDetermine whether an object - such as a stream or timer – is not yet closed. Once an object is closed, it will never produce a new event. However, since a closed stream may still have data to read in its buffer, use eof to check for the ability to read data. Use the FileWatching package to be notified when a stream might be writable or readable.\n\nExamples\n\njulia> io = open(\"my_file.txt\", \"w+\");\n\njulia> isopen(io)\ntrue\n\njulia> close(io)\n\njulia> isopen(io)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.fd","page":"I/O and Network","title":"Base.fd","text":"fd(stream)\n\nReturn the file descriptor backing the stream or file. Note that this function only applies to synchronous File's and IOStream's not to any of the asynchronous streams.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stdio","page":"I/O and Network","title":"Base.redirect_stdio","text":"redirect_stdio(;stdin=stdin, stderr=stderr, stdout=stdout)\n\nRedirect a subset of the streams stdin, stderr, stdout. Each argument must be an IOStream, TTY, Pipe, socket, or devnull.\n\ncompat: Julia 1.7\nredirect_stdio requires Julia 1.7 or later.\n\n\n\n\n\nredirect_stdio(f; stdin=nothing, stderr=nothing, stdout=nothing)\n\nRedirect a subset of the streams stdin, stderr, stdout, call f() and restore each stream.\n\nPossible values for each stream are:\n\nnothing indicating the stream should not be redirected.\npath::AbstractString redirecting the stream to the file at path.\nio an IOStream, TTY, Pipe, socket, or devnull.\n\nExamples\n\njulia> redirect_stdio(stdout=\"stdout.txt\", stderr=\"stderr.txt\") do\n print(\"hello stdout\")\n print(stderr, \"hello stderr\")\n end\n\njulia> read(\"stdout.txt\", String)\n\"hello stdout\"\n\njulia> read(\"stderr.txt\", String)\n\"hello stderr\"\n\nEdge cases\n\nIt is possible to pass the same argument to stdout and stderr:\n\njulia> redirect_stdio(stdout=\"log.txt\", stderr=\"log.txt\", stdin=devnull) do\n ...\nend\n\nHowever it is not supported to pass two distinct descriptors of the same file.\n\njulia> io1 = open(\"same/path\", \"w\")\n\njulia> io2 = open(\"same/path\", \"w\")\n\njulia> redirect_stdio(f, stdout=io1, stderr=io2) # not supported\n\nAlso the stdin argument may not be the same descriptor as stdout or stderr.\n\njulia> io = open(...)\n\njulia> redirect_stdio(f, stdout=io, stdin=io) # not supported\n\ncompat: Julia 1.7\nredirect_stdio requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stdout","page":"I/O and Network","title":"Base.redirect_stdout","text":"redirect_stdout([stream]) -> stream\n\nCreate a pipe to which all C and Julia level stdout output will be redirected. Return a stream representing the pipe ends. Data written to stdout may now be read from the rd end of the pipe.\n\nnote: Note\nstream must be a compatible objects, such as an IOStream, TTY, Pipe, socket, or devnull.\n\nSee also redirect_stdio.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stdout-Tuple{Function, Any}","page":"I/O and Network","title":"Base.redirect_stdout","text":"redirect_stdout(f::Function, stream)\n\nRun the function f while redirecting stdout to stream. Upon completion, stdout is restored to its prior setting.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.redirect_stderr","page":"I/O and Network","title":"Base.redirect_stderr","text":"redirect_stderr([stream]) -> stream\n\nLike redirect_stdout, but for stderr.\n\nnote: Note\nstream must be a compatible objects, such as an IOStream, TTY, Pipe, socket, or devnull.\n\nSee also redirect_stdio.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stderr-Tuple{Function, Any}","page":"I/O and Network","title":"Base.redirect_stderr","text":"redirect_stderr(f::Function, stream)\n\nRun the function f while redirecting stderr to stream. Upon completion, stderr is restored to its prior setting.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.redirect_stdin","page":"I/O and Network","title":"Base.redirect_stdin","text":"redirect_stdin([stream]) -> stream\n\nLike redirect_stdout, but for stdin. Note that the direction of the stream is reversed.\n\nnote: Note\nstream must be a compatible objects, such as an IOStream, TTY, Pipe, socket, or devnull.\n\nSee also redirect_stdio.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stdin-Tuple{Function, Any}","page":"I/O and Network","title":"Base.redirect_stdin","text":"redirect_stdin(f::Function, stream)\n\nRun the function f while redirecting stdin to stream. Upon completion, stdin is restored to its prior setting.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.readchomp","page":"I/O and Network","title":"Base.readchomp","text":"readchomp(x)\n\nRead the entirety of x as a string and remove a single trailing newline if there is one. Equivalent to chomp(read(x, String)).\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> readchomp(\"my_file.txt\")\n\"JuliaLang is a GitHub organization.\\nIt has many members.\"\n\njulia> rm(\"my_file.txt\");\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.truncate","page":"I/O and Network","title":"Base.truncate","text":"truncate(file, n)\n\nResize the file or buffer given by the first argument to exactly n bytes, filling previously unallocated space with '\\0' if the file or buffer is grown.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\")\n35\n\njulia> truncate(io, 15)\nIOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=15, maxsize=Inf, ptr=16, mark=-1)\n\njulia> String(take!(io))\n\"JuliaLang is a \"\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\");\n\njulia> truncate(io, 40);\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization.\\0\\0\\0\\0\\0\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.skipchars","page":"I/O and Network","title":"Base.skipchars","text":"skipchars(predicate, io::IO; linecomment=nothing)\n\nAdvance the stream io such that the next-read character will be the first remaining for which predicate returns false. If the keyword argument linecomment is specified, all characters from that character until the start of the next line are ignored.\n\nExamples\n\njulia> buf = IOBuffer(\" text\")\nIOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=1, mark=-1)\n\njulia> skipchars(isspace, buf)\nIOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=5, mark=-1)\n\njulia> String(readavailable(buf))\n\"text\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.countlines","page":"I/O and Network","title":"Base.countlines","text":"countlines(io::IO; eol::AbstractChar = '\\n')\ncountlines(filename::AbstractString; eol::AbstractChar = '\\n')\n\nRead io until the end of the stream/file and count the number of lines. To specify a file pass the filename as the first argument. EOL markers other than '\\n' are supported by passing them as the second argument. The last non-empty line of io is counted even if it does not end with the EOL, matching the length returned by eachline and readlines.\n\nTo count lines of a String, countlines(IOBuffer(str)) can be used.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\\n\");\n\njulia> countlines(io)\n1\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> countlines(io)\n1\n\njulia> eof(io) # counting lines moves the file pointer\ntrue\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> countlines(io, eol = '.')\n1\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\n\")\n36\n\njulia> countlines(\"my_file.txt\")\n1\n\njulia> countlines(\"my_file.txt\", eol = 'n')\n4\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.PipeBuffer","page":"I/O and Network","title":"Base.PipeBuffer","text":"PipeBuffer(data::AbstractVector{UInt8}=UInt8[]; maxsize::Integer = typemax(Int))\n\nAn IOBuffer that allows reading and performs writes by appending. Seeking and truncating are not supported. See IOBuffer for the available constructors. If data is given, creates a PipeBuffer to operate on a data vector, optionally specifying a size beyond which the underlying Array may not be grown.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readavailable","page":"I/O and Network","title":"Base.readavailable","text":"readavailable(stream)\n\nRead available buffered data from a stream. Actual I/O is performed only if no data has already been buffered. The result is a Vector{UInt8}.\n\nwarning: Warning\nThe amount of data returned is implementation-dependent; for example it can depend on the internal choice of buffer size. Other functions such as read should generally be used instead.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.IOContext","page":"I/O and Network","title":"Base.IOContext","text":"IOContext\n\nIOContext provides a mechanism for passing output configuration settings among show methods.\n\nIn short, it is an immutable dictionary that is a subclass of IO. It supports standard dictionary operations such as getindex, and can also be used as an I/O stream.\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.IOContext-Tuple{IO, Pair}","page":"I/O and Network","title":"Base.IOContext","text":"IOContext(io::IO, KV::Pair...)\n\nCreate an IOContext that wraps a given stream, adding the specified key=>value pairs to the properties of that stream (note that io can itself be an IOContext).\n\nuse (key => value) in io to see if this particular combination is in the properties set\nuse get(io, key, default) to retrieve the most recent value for a particular key\n\nThe following properties are in common use:\n\n:compact: Boolean specifying that values should be printed more compactly, e.g. that numbers should be printed with fewer digits. This is set when printing array elements. :compact output should not contain line breaks.\n:limit: Boolean specifying that containers should be truncated, e.g. showing … in place of most elements.\n:displaysize: A Tuple{Int,Int} giving the size in rows and columns to use for text output. This can be used to override the display size for called functions, but to get the size of the screen use the displaysize function.\n:typeinfo: a Type characterizing the information already printed concerning the type of the object about to be displayed. This is mainly useful when displaying a collection of objects of the same type, so that redundant type information can be avoided (e.g. [Float16(0)] can be shown as \"Float16[0.0]\" instead of \"Float16[Float16(0.0)]\" : while displaying the elements of the array, the :typeinfo property will be set to Float16).\n:color: Boolean specifying whether ANSI color/escape codes are supported/expected. By default, this is determined by whether io is a compatible terminal and by any --color command-line flag when julia was launched.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> printstyled(IOContext(io, :color => true), \"string\", color=:red)\n\njulia> String(take!(io))\n\"\\e[31mstring\\e[39m\"\n\njulia> printstyled(io, \"string\", color=:red)\n\njulia> String(take!(io))\n\"string\"\n\njulia> print(IOContext(stdout, :compact => false), 1.12341234)\n1.12341234\njulia> print(IOContext(stdout, :compact => true), 1.12341234)\n1.12341\n\njulia> function f(io::IO)\n if get(io, :short, false)\n print(io, \"short\")\n else\n print(io, \"loooooong\")\n end\n end\nf (generic function with 1 method)\n\njulia> f(stdout)\nloooooong\njulia> f(IOContext(stdout, :short => true))\nshort\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.IOContext-Tuple{IO, IOContext}","page":"I/O and Network","title":"Base.IOContext","text":"IOContext(io::IO, context::IOContext)\n\nCreate an IOContext that wraps an alternate IO but inherits the properties of context.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Text-I/O","page":"I/O and Network","title":"Text I/O","text":"","category":"section"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.show(::IO, ::Any)\nBase.summary\nBase.print\nBase.println\nBase.printstyled\nBase.sprint\nBase.showerror\nBase.dump\nMeta.@dump\nBase.readline\nBase.readuntil\nBase.readlines\nBase.eachline\nBase.copyline\nBase.copyuntil\nBase.displaysize","category":"page"},{"location":"base/io-network/#Base.show-Tuple{IO, Any}","page":"I/O and Network","title":"Base.show","text":"show([io::IO = stdout], x)\n\nWrite a text representation of a value x to the output stream io. New types T should overload show(io::IO, x::T). The representation used by show generally includes Julia-specific formatting and type information, and should be parseable Julia code when possible.\n\nrepr returns the output of show as a string.\n\nFor a more verbose human-readable text output for objects of type T, define show(io::IO, ::MIME\"text/plain\", ::T) in addition. Checking the :compact IOContext key (often checked as get(io, :compact, false)::Bool) of io in such methods is recommended, since some containers show their elements by calling this method with :compact => true.\n\nSee also print, which writes un-decorated representations.\n\nExamples\n\njulia> show(\"Hello World!\")\n\"Hello World!\"\njulia> print(\"Hello World!\")\nHello World!\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.summary","page":"I/O and Network","title":"Base.summary","text":"summary(io::IO, x)\nstr = summary(x)\n\nPrint to a stream io, or return a string str, giving a brief description of a value. By default returns string(typeof(x)), e.g. Int64.\n\nFor arrays, returns a string of size and type info, e.g. 10-element Array{Int64,1}.\n\nExamples\n\njulia> summary(1)\n\"Int64\"\n\njulia> summary(zeros(2))\n\"2-element Vector{Float64}\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.print","page":"I/O and Network","title":"Base.print","text":"print([io::IO], xs...)\n\nWrite to io (or to the default output stream stdout if io is not given) a canonical (un-decorated) text representation. The representation used by print includes minimal formatting and tries to avoid Julia-specific details.\n\nprint falls back to calling show, so most types should just define show. Define print if your type has a separate \"plain\" representation. For example, show displays strings with quotes, and print displays strings without quotes.\n\nSee also println, string, printstyled.\n\nExamples\n\njulia> print(\"Hello World!\")\nHello World!\njulia> io = IOBuffer();\n\njulia> print(io, \"Hello\", ' ', :World!)\n\njulia> String(take!(io))\n\"Hello World!\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.println","page":"I/O and Network","title":"Base.println","text":"println([io::IO], xs...)\n\nPrint (using print) xs to io followed by a newline. If io is not supplied, prints to the default output stream stdout.\n\nSee also printstyled to add colors etc.\n\nExamples\n\njulia> println(\"Hello, world\")\nHello, world\n\njulia> io = IOBuffer();\n\njulia> println(io, \"Hello\", ',', \" world.\")\n\njulia> String(take!(io))\n\"Hello, world.\\n\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.printstyled","page":"I/O and Network","title":"Base.printstyled","text":"printstyled([io], xs...; bold::Bool=false, italic::Bool=false, underline::Bool=false, blink::Bool=false, reverse::Bool=false, hidden::Bool=false, color::Union{Symbol,Int}=:normal)\n\nPrint xs in a color specified as a symbol or integer, optionally in bold.\n\nKeyword color may take any of the values :normal, :italic, :default, :bold, :black, :blink, :blue, :cyan, :green, :hidden, :light_black, :light_blue, :light_cyan, :light_green, :light_magenta, :light_red, :light_white, :light_yellow, :magenta, :nothing, :red, :reverse, :underline, :white, or :yellow or an integer between 0 and 255 inclusive. Note that not all terminals support 256 colors.\n\nKeywords bold=true, italic=true, underline=true, blink=true are self-explanatory. Keyword reverse=true prints with foreground and background colors exchanged, and hidden=true should be invisible in the terminal but can still be copied. These properties can be used in any combination.\n\nSee also print, println, show.\n\nnote: Note\nNot all terminals support italic output. Some terminals interpret italic as reverse or blink.\n\ncompat: Julia 1.7\nKeywords except color and bold were added in Julia 1.7.\n\ncompat: Julia 1.10\nSupport for italic output was added in Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.sprint","page":"I/O and Network","title":"Base.sprint","text":"sprint(f::Function, args...; context=nothing, sizehint=0)\n\nCall the given function with an I/O stream and the supplied extra arguments. Everything written to this I/O stream is returned as a string. context can be an IOContext whose properties will be used, a Pair specifying a property and its value, or a tuple of Pair specifying multiple properties and their values. sizehint suggests the capacity of the buffer (in bytes).\n\nThe optional keyword argument context can be set to a :key=>value pair, a tuple of :key=>value pairs, or an IO or IOContext object whose attributes are used for the I/O stream passed to f. The optional sizehint is a suggested size (in bytes) to allocate for the buffer used to write the string.\n\ncompat: Julia 1.7\nPassing a tuple to keyword context requires Julia 1.7 or later.\n\nExamples\n\njulia> sprint(show, 66.66666; context=:compact => true)\n\"66.6667\"\n\njulia> sprint(showerror, BoundsError([1], 100))\n\"BoundsError: attempt to access 1-element Vector{Int64} at index [100]\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.showerror","page":"I/O and Network","title":"Base.showerror","text":"showerror(io, e)\n\nShow a descriptive representation of an exception object e. This method is used to display the exception after a call to throw.\n\nExamples\n\njulia> struct MyException <: Exception\n msg::String\n end\n\njulia> function Base.showerror(io::IO, err::MyException)\n print(io, \"MyException: \")\n print(io, err.msg)\n end\n\njulia> err = MyException(\"test exception\")\nMyException(\"test exception\")\n\njulia> sprint(showerror, err)\n\"MyException: test exception\"\n\njulia> throw(MyException(\"test exception\"))\nERROR: MyException: test exception\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.dump","page":"I/O and Network","title":"Base.dump","text":"dump(x; maxdepth=8)\n\nShow every part of the representation of a value. The depth of the output is truncated at maxdepth.\n\nExamples\n\njulia> struct MyStruct\n x\n y\n end\n\njulia> x = MyStruct(1, (2,3));\n\njulia> dump(x)\nMyStruct\n x: Int64 1\n y: Tuple{Int64, Int64}\n 1: Int64 2\n 2: Int64 3\n\njulia> dump(x; maxdepth = 1)\nMyStruct\n x: Int64 1\n y: Tuple{Int64, Int64}\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Meta.@dump","page":"I/O and Network","title":"Base.Meta.@dump","text":"@dump expr\n\nShow every part of the representation of the given expression. Equivalent to dump(:(expr)).\n\n\n\n\n\n","category":"macro"},{"location":"base/io-network/#Base.readline","page":"I/O and Network","title":"Base.readline","text":"readline(io::IO=stdin; keep::Bool=false)\nreadline(filename::AbstractString; keep::Bool=false)\n\nRead a single line of text from the given I/O stream or file (defaults to stdin). When reading from a file, the text is assumed to be encoded in UTF-8. Lines in the input end with '\\n' or \"\\r\\n\" or the end of an input stream. When keep is false (as it is by default), these trailing newline characters are removed from the line before it is returned. When keep is true, they are returned as part of the line.\n\nReturn a String. See also copyline to instead write in-place to another stream (which can be a preallocated IOBuffer).\n\nSee also readuntil for reading until more general delimiters.\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> readline(\"my_file.txt\")\n\"JuliaLang is a GitHub organization.\"\n\njulia> readline(\"my_file.txt\", keep=true)\n\"JuliaLang is a GitHub organization.\\n\"\n\njulia> rm(\"my_file.txt\")\n\njulia> print(\"Enter your name: \")\nEnter your name:\n\njulia> your_name = readline()\nLogan\n\"Logan\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readuntil","page":"I/O and Network","title":"Base.readuntil","text":"readuntil(stream::IO, delim; keep::Bool = false)\nreaduntil(filename::AbstractString, delim; keep::Bool = false)\n\nRead a string from an I/O stream or a file, up to the given delimiter. The delimiter can be a UInt8, AbstractChar, string, or vector. Keyword argument keep controls whether the delimiter is included in the result. The text is assumed to be encoded in UTF-8.\n\nReturn a String if delim is an AbstractChar or a string or otherwise return a Vector{typeof(delim)}. See also copyuntil to instead write in-place to another stream (which can be a preallocated IOBuffer).\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> readuntil(\"my_file.txt\", 'L')\n\"Julia\"\n\njulia> readuntil(\"my_file.txt\", '.', keep = true)\n\"JuliaLang is a GitHub organization.\"\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readlines","page":"I/O and Network","title":"Base.readlines","text":"readlines(io::IO=stdin; keep::Bool=false)\nreadlines(filename::AbstractString; keep::Bool=false)\n\nRead all lines of an I/O stream or a file as a vector of strings. Behavior is equivalent to saving the result of reading readline repeatedly with the same arguments and saving the resulting lines as a vector of strings. See also eachline to iterate over the lines without reading them all at once.\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> readlines(\"my_file.txt\")\n2-element Vector{String}:\n \"JuliaLang is a GitHub organization.\"\n \"It has many members.\"\n\njulia> readlines(\"my_file.txt\", keep=true)\n2-element Vector{String}:\n \"JuliaLang is a GitHub organization.\\n\"\n \"It has many members.\\n\"\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.eachline","page":"I/O and Network","title":"Base.eachline","text":"eachline(io::IO=stdin; keep::Bool=false)\neachline(filename::AbstractString; keep::Bool=false)\n\nCreate an iterable EachLine object that will yield each line from an I/O stream or a file. Iteration calls readline on the stream argument repeatedly with keep passed through, determining whether trailing end-of-line characters are retained. When called with a file name, the file is opened once at the beginning of iteration and closed at the end. If iteration is interrupted, the file will be closed when the EachLine object is garbage collected.\n\nTo iterate over each line of a String, eachline(IOBuffer(str)) can be used.\n\nIterators.reverse can be used on an EachLine object to read the lines in reverse order (for files, buffers, and other I/O streams supporting seek), and first or last can be used to extract the initial or final lines, respectively.\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\n It has many members.\\n\");\n\njulia> for line in eachline(\"my_file.txt\")\n print(line)\n end\nJuliaLang is a GitHub organization. It has many members.\n\njulia> rm(\"my_file.txt\");\n\ncompat: Julia 1.8\nJulia 1.8 is required to use Iterators.reverse or last with eachline iterators.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.copyline","page":"I/O and Network","title":"Base.copyline","text":"copyline(out::IO, io::IO=stdin; keep::Bool=false)\ncopyline(out::IO, filename::AbstractString; keep::Bool=false)\n\nCopy a single line of text from an I/O stream or a file to the out stream, returning out.\n\nWhen reading from a file, the text is assumed to be encoded in UTF-8. Lines in the input end with '\\n' or \"\\r\\n\" or the end of an input stream. When keep is false (as it is by default), these trailing newline characters are removed from the line before it is returned. When keep is true, they are returned as part of the line.\n\nSimilar to readline, which returns a String; in contrast, copyline writes directly to out, without allocating a string. (This can be used, for example, to read data into a pre-allocated IOBuffer.)\n\nSee also copyuntil for reading until more general delimiters.\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> String(take!(copyline(IOBuffer(), \"my_file.txt\")))\n\"JuliaLang is a GitHub organization.\"\n\njulia> String(take!(copyline(IOBuffer(), \"my_file.txt\", keep=true)))\n\"JuliaLang is a GitHub organization.\\n\"\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.copyuntil","page":"I/O and Network","title":"Base.copyuntil","text":"copyuntil(out::IO, stream::IO, delim; keep::Bool = false)\ncopyuntil(out::IO, filename::AbstractString, delim; keep::Bool = false)\n\nCopy a string from an I/O stream or a file, up to the given delimiter, to the out stream, returning out. The delimiter can be a UInt8, AbstractChar, string, or vector. Keyword argument keep controls whether the delimiter is included in the result. The text is assumed to be encoded in UTF-8.\n\nSimilar to readuntil, which returns a String; in contrast, copyuntil writes directly to out, without allocating a string. (This can be used, for example, to read data into a pre-allocated IOBuffer.)\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> String(take!(copyuntil(IOBuffer(), \"my_file.txt\", 'L')))\n\"Julia\"\n\njulia> String(take!(copyuntil(IOBuffer(), \"my_file.txt\", '.', keep = true)))\n\"JuliaLang is a GitHub organization.\"\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.displaysize","page":"I/O and Network","title":"Base.displaysize","text":"displaysize([io::IO]) -> (lines, columns)\n\nReturn the nominal size of the screen that may be used for rendering output to this IO object. If no input is provided, the environment variables LINES and COLUMNS are read. If those are not set, a default size of (24, 80) is returned.\n\nExamples\n\njulia> withenv(\"LINES\" => 30, \"COLUMNS\" => 100) do\n displaysize()\n end\n(30, 100)\n\nTo get your TTY size,\n\njulia> displaysize(stdout)\n(34, 147)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Multimedia-I/O","page":"I/O and Network","title":"Multimedia I/O","text":"","category":"section"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Just as text output is performed by print and user-defined types can indicate their textual representation by overloading show, Julia provides a standardized mechanism for rich multimedia output (such as images, formatted text, or even audio and video), consisting of three parts:","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"A function display(x) to request the richest available multimedia display of a Julia object x (with a plain-text fallback).\nOverloading show allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types.\nMultimedia-capable display backends may be registered by subclassing a generic AbstractDisplay type and pushing them onto a stack of display backends via pushdisplay.","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"The base Julia runtime provides only plain-text display, but richer displays may be enabled by loading external modules or by using graphical Julia environments (such as the IPython-based IJulia notebook).","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.AbstractDisplay\nBase.Multimedia.display\nBase.Multimedia.redisplay\nBase.Multimedia.displayable\nBase.show(::IO, ::Any, ::Any)\nBase.Multimedia.showable\nBase.repr(::MIME, ::Any)\nBase.MIME\nBase.@MIME_str","category":"page"},{"location":"base/io-network/#Base.Multimedia.AbstractDisplay","page":"I/O and Network","title":"Base.Multimedia.AbstractDisplay","text":"AbstractDisplay\n\nAbstract supertype for rich display output devices. TextDisplay is a subtype of this.\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.Multimedia.display","page":"I/O and Network","title":"Base.Multimedia.display","text":"display(x)\ndisplay(d::AbstractDisplay, x)\ndisplay(mime, x)\ndisplay(d::AbstractDisplay, mime, x)\n\nDisplay x using the topmost applicable display in the display stack, typically using the richest supported multimedia output for x, with plain-text stdout output as a fallback. The display(d, x) variant attempts to display x on the given display d only, throwing a MethodError if d cannot display objects of this type.\n\nIn general, you cannot assume that display output goes to stdout (unlike print(x) or show(x)). For example, display(x) may open up a separate window with an image. display(x) means \"show x in the best way you can for the current output device(s).\" If you want REPL-like text output that is guaranteed to go to stdout, use show(stdout, \"text/plain\", x) instead.\n\nThere are also two variants with a mime argument (a MIME type string, such as \"image/png\"), which attempt to display x using the requested MIME type only, throwing a MethodError if this type is not supported by either the display(s) or by x. With these variants, one can also supply the \"raw\" data in the requested MIME type by passing x::AbstractString (for MIME types with text-based storage, such as text/html or application/postscript) or x::Vector{UInt8} (for binary MIME types).\n\nTo customize how instances of a type are displayed, overload show rather than display, as explained in the manual section on custom pretty-printing.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Multimedia.redisplay","page":"I/O and Network","title":"Base.Multimedia.redisplay","text":"redisplay(x)\nredisplay(d::AbstractDisplay, x)\nredisplay(mime, x)\nredisplay(d::AbstractDisplay, mime, x)\n\nBy default, the redisplay functions simply call display. However, some display backends may override redisplay to modify an existing display of x (if any). Using redisplay is also a hint to the backend that x may be redisplayed several times, and the backend may choose to defer the display until (for example) the next interactive prompt.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Multimedia.displayable","page":"I/O and Network","title":"Base.Multimedia.displayable","text":"displayable(mime) -> Bool\ndisplayable(d::AbstractDisplay, mime) -> Bool\n\nReturn a boolean value indicating whether the given mime type (string) is displayable by any of the displays in the current display stack, or specifically by the display d in the second variant.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.show-Tuple{IO, Any, Any}","page":"I/O and Network","title":"Base.show","text":"show(io::IO, mime, x)\n\nThe display functions ultimately call show in order to write an object x as a given mime type to a given I/O stream io (usually a memory buffer), if possible. In order to provide a rich multimedia representation of a user-defined type T, it is only necessary to define a new show method for T, via: show(io, ::MIME\"mime\", x::T) = ..., where mime is a MIME-type string and the function body calls write (or similar) to write that representation of x to io. (Note that the MIME\"\" notation only supports literal strings; to construct MIME types in a more flexible manner use MIME{Symbol(\"\")}.)\n\nFor example, if you define a MyImage type and know how to write it to a PNG file, you could define a function show(io, ::MIME\"image/png\", x::MyImage) = ... to allow your images to be displayed on any PNG-capable AbstractDisplay (such as IJulia). As usual, be sure to import Base.show in order to add new methods to the built-in Julia function show.\n\nTechnically, the MIME\"mime\" macro defines a singleton type for the given mime string, which allows us to exploit Julia's dispatch mechanisms in determining how to display objects of any given type.\n\nThe default MIME type is MIME\"text/plain\". There is a fallback definition for text/plain output that calls show with 2 arguments, so it is not always necessary to add a method for that case. If a type benefits from custom human-readable output though, show(::IO, ::MIME\"text/plain\", ::T) should be defined. For example, the Day type uses 1 day as the output for the text/plain MIME type, and Day(1) as the output of 2-argument show.\n\nExamples\n\njulia> struct Day\n n::Int\n end\n\njulia> Base.show(io::IO, ::MIME\"text/plain\", d::Day) = print(io, d.n, \" day\")\n\njulia> Day(1)\n1 day\n\nContainer types generally implement 3-argument show by calling show(io, MIME\"text/plain\"(), x) for elements x, with :compact => true set in an IOContext passed as the first argument.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.Multimedia.showable","page":"I/O and Network","title":"Base.Multimedia.showable","text":"showable(mime, x)\n\nReturn a boolean value indicating whether or not the object x can be written as the given mime type.\n\n(By default, this is determined automatically by the existence of the corresponding show method for typeof(x). Some types provide custom showable methods; for example, if the available MIME formats depend on the value of x.)\n\nExamples\n\njulia> showable(MIME(\"text/plain\"), rand(5))\ntrue\n\njulia> showable(\"image/png\", rand(5))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.repr-Tuple{MIME, Any}","page":"I/O and Network","title":"Base.repr","text":"repr(mime, x; context=nothing)\n\nReturn an AbstractString or Vector{UInt8} containing the representation of x in the requested mime type, as written by show(io, mime, x) (throwing a MethodError if no appropriate show is available). An AbstractString is returned for MIME types with textual representations (such as \"text/html\" or \"application/postscript\"), whereas binary data is returned as Vector{UInt8}. (The function istextmime(mime) returns whether or not Julia treats a given mime type as text.)\n\nThe optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to show.\n\nAs a special case, if x is an AbstractString (for textual MIME types) or a Vector{UInt8} (for binary MIME types), the repr function assumes that x is already in the requested mime format and simply returns x. This special case does not apply to the \"text/plain\" MIME type. This is useful so that raw data can be passed to display(m::MIME, x).\n\nIn particular, repr(\"text/plain\", x) is typically a \"pretty-printed\" version of x designed for human consumption. See also repr(x) to instead return a string corresponding to show(x) that may be closer to how the value of x would be entered in Julia.\n\nExamples\n\njulia> A = [1 2; 3 4];\n\njulia> repr(\"text/plain\", A)\n\"2×2 Matrix{Int64}:\\n 1 2\\n 3 4\"\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.Multimedia.MIME","page":"I/O and Network","title":"Base.Multimedia.MIME","text":"MIME\n\nA type representing a standard internet data format. \"MIME\" stands for \"Multipurpose Internet Mail Extensions\", since the standard was originally used to describe multimedia attachments to email messages.\n\nA MIME object can be passed as the second argument to show to request output in that format.\n\nExamples\n\njulia> show(stdout, MIME(\"text/plain\"), \"hi\")\n\"hi\"\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.Multimedia.@MIME_str","page":"I/O and Network","title":"Base.Multimedia.@MIME_str","text":"@MIME_str\n\nA convenience macro for writing MIME types, typically used when adding methods to show. For example the syntax show(io::IO, ::MIME\"text/html\", x::MyType) = ... could be used to define how to write an HTML representation of MyType.\n\n\n\n\n\n","category":"macro"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"As mentioned above, one can also define new display backends. For example, a module that can display PNG images in a window can register this capability with Julia, so that calling display(x) on types with PNG representations will automatically display the image using the module's window.","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"In order to define a new display backend, one should first create a subtype D of the abstract class AbstractDisplay. Then, for each MIME type (mime string) that can be displayed on D, one should define a function display(d::D, ::MIME\"mime\", x) = ... that displays x as that MIME type, usually by calling show(io, mime, x) or repr(io, mime, x). A MethodError should be thrown if x cannot be displayed as that MIME type; this is automatic if one calls show or repr. Finally, one should define a function display(d::D, x) that queries showable(mime, x) for the mime types supported by D and displays the \"best\" one; a MethodError should be thrown if no supported MIME types are found for x. Similarly, some subtypes may wish to override redisplay(d::D, ...). (Again, one should import Base.display to add new methods to display.) The return values of these functions are up to the implementation (since in some cases it may be useful to return a display \"handle\" of some type). The display functions for D can then be called directly, but they can also be invoked automatically from display(x) simply by pushing a new display onto the display-backend stack with:","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.Multimedia.pushdisplay\nBase.Multimedia.popdisplay\nBase.Multimedia.TextDisplay\nBase.Multimedia.istextmime","category":"page"},{"location":"base/io-network/#Base.Multimedia.pushdisplay","page":"I/O and Network","title":"Base.Multimedia.pushdisplay","text":"pushdisplay(d::AbstractDisplay)\n\nPushes a new display d on top of the global display-backend stack. Calling display(x) or display(mime, x) will display x on the topmost compatible backend in the stack (i.e., the topmost backend that does not throw a MethodError).\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Multimedia.popdisplay","page":"I/O and Network","title":"Base.Multimedia.popdisplay","text":"popdisplay()\npopdisplay(d::AbstractDisplay)\n\nPop the topmost backend off of the display-backend stack, or the topmost copy of d in the second variant.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Multimedia.TextDisplay","page":"I/O and Network","title":"Base.Multimedia.TextDisplay","text":"TextDisplay(io::IO)\n\nReturn a TextDisplay <: AbstractDisplay, which displays any object as the text/plain MIME type (by default), writing the text representation to the given I/O stream. (This is how objects are printed in the Julia REPL.)\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.Multimedia.istextmime","page":"I/O and Network","title":"Base.Multimedia.istextmime","text":"istextmime(m::MIME)\n\nDetermine whether a MIME type is text data. MIME types are assumed to be binary data except for a set of types known to be text data (possibly Unicode).\n\nExamples\n\njulia> istextmime(MIME(\"text/plain\"))\ntrue\n\njulia> istextmime(MIME(\"image/png\"))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Network-I/O","page":"I/O and Network","title":"Network I/O","text":"","category":"section"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.bytesavailable\nBase.ntoh\nBase.hton\nBase.ltoh\nBase.htol\nBase.ENDIAN_BOM","category":"page"},{"location":"base/io-network/#Base.bytesavailable","page":"I/O and Network","title":"Base.bytesavailable","text":"bytesavailable(io)\n\nReturn the number of bytes available for reading before a read from this stream or buffer will block.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization\");\n\njulia> bytesavailable(io)\n34\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.ntoh","page":"I/O and Network","title":"Base.ntoh","text":"ntoh(x)\n\nConvert the endianness of a value from Network byte order (big-endian) to that used by the Host.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.hton","page":"I/O and Network","title":"Base.hton","text":"hton(x)\n\nConvert the endianness of a value from that used by the Host to Network byte order (big-endian).\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.ltoh","page":"I/O and Network","title":"Base.ltoh","text":"ltoh(x)\n\nConvert the endianness of a value from Little-endian to that used by the Host.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.htol","page":"I/O and Network","title":"Base.htol","text":"htol(x)\n\nConvert the endianness of a value from that used by the Host to Little-endian.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.ENDIAN_BOM","page":"I/O and Network","title":"Base.ENDIAN_BOM","text":"ENDIAN_BOM\n\nThe 32-bit byte-order-mark indicates the native byte order of the host machine. Little-endian machines will contain the value 0x04030201. Big-endian machines will contain the value 0x01020304.\n\n\n\n\n\n","category":"constant"},{"location":"base/c/#C-Interface","page":"C Interface","title":"C Interface","text":"","category":"section"},{"location":"base/c/","page":"C Interface","title":"C Interface","text":"@ccall\nccall\nCore.Intrinsics.cglobal\nBase.@cfunction\nBase.CFunction\nBase.unsafe_convert\nBase.cconvert\nBase.unsafe_load\nBase.unsafe_store!\nBase.unsafe_modify!\nBase.unsafe_replace!\nBase.unsafe_swap!\nBase.unsafe_copyto!{T}(::Ptr{T}, ::Ptr{T}, ::Any)\nBase.unsafe_copyto!(::Array, ::Any, ::Array, ::Any, ::Any)\nBase.copyto!\nBase.pointer\nBase.unsafe_wrap{T,N}(::Union{Type{Array},Type{Array{T}},Type{Array{T,N}}}, ::Ptr{T}, ::NTuple{N,Int})\nBase.pointer_from_objref\nBase.unsafe_pointer_to_objref\nBase.disable_sigint\nBase.reenable_sigint\nBase.exit_on_sigint\nBase.systemerror\nBase.windowserror\nCore.Ptr\nCore.Ref\nBase.isassigned(::Base.RefValue)\nBase.Cchar\nBase.Cuchar\nBase.Cshort\nBase.Cstring\nBase.Cushort\nBase.Cint\nBase.Cuint\nBase.Clong\nBase.Culong\nBase.Clonglong\nBase.Culonglong\nBase.Cintmax_t\nBase.Cuintmax_t\nBase.Csize_t\nBase.Cssize_t\nBase.Cptrdiff_t\nBase.Cwchar_t\nBase.Cwstring\nBase.Cfloat\nBase.Cdouble","category":"page"},{"location":"base/c/#Base.@ccall","page":"C Interface","title":"Base.@ccall","text":"@ccall library.function_name(argvalue1::argtype1, ...)::returntype\n@ccall function_name(argvalue1::argtype1, ...)::returntype\n@ccall $function_pointer(argvalue1::argtype1, ...)::returntype\n\nCall a function in a C-exported shared library, specified by library.function_name, where library is a string constant or literal. The library may be omitted, in which case the function_name is resolved in the current process. Alternatively, @ccall may also be used to call a function pointer $function_pointer, such as one returned by dlsym.\n\nEach argvalue to @ccall is converted to the corresponding argtype, by automatic insertion of calls to unsafe_convert(argtype, cconvert(argtype, argvalue)). (See also the documentation for unsafe_convert and cconvert for further details.) In most cases, this simply results in a call to convert(argtype, argvalue).\n\nExamples\n\n@ccall strlen(s::Cstring)::Csize_t\n\nThis calls the C standard library function:\n\nsize_t strlen(char *)\n\nwith a Julia variable named s. See also ccall.\n\nVarargs are supported with the following convention:\n\n@ccall printf(\"%s = %d\"::Cstring ; \"foo\"::Cstring, foo::Cint)::Cint\n\nThe semicolon is used to separate required arguments (of which there must be at least one) from variadic arguments.\n\nExample using an external library:\n\n# C signature of g_uri_escape_string:\n# char *g_uri_escape_string(const char *unescaped, const char *reserved_chars_allowed, gboolean allow_utf8);\n\nconst glib = \"libglib-2.0\"\n@ccall glib.g_uri_escape_string(my_uri::Cstring, \":/\"::Cstring, true::Cint)::Cstring\n\nThe string literal could also be used directly before the function name, if desired \"libglib-2.0\".g_uri_escape_string(...\n\n\n\n\n\n","category":"macro"},{"location":"base/c/#ccall","page":"C Interface","title":"ccall","text":"ccall((function_name, library), returntype, (argtype1, ...), argvalue1, ...)\nccall(function_name, returntype, (argtype1, ...), argvalue1, ...)\nccall(function_pointer, returntype, (argtype1, ...), argvalue1, ...)\n\nCall a function in a C-exported shared library, specified by the tuple (function_name, library), where each component is either a string or symbol. Instead of specifying a library, one can also use a function_name symbol or string, which is resolved in the current process. Alternatively, ccall may also be used to call a function pointer function_pointer, such as one returned by dlsym.\n\nNote that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression.\n\nEach argvalue to the ccall will be converted to the corresponding argtype, by automatic insertion of calls to unsafe_convert(argtype, cconvert(argtype, argvalue)). (See also the documentation for unsafe_convert and cconvert for further details.) In most cases, this simply results in a call to convert(argtype, argvalue).\n\n\n\n\n\n","category":"keyword"},{"location":"base/c/#Core.Intrinsics.cglobal","page":"C Interface","title":"Core.Intrinsics.cglobal","text":"cglobal((symbol, library) [, type=Cvoid])\n\nObtain a pointer to a global variable in a C-exported shared library, specified exactly as in ccall. Returns a Ptr{Type}, defaulting to Ptr{Cvoid} if no Type argument is supplied. The values can be read or written by unsafe_load or unsafe_store!, respectively.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.@cfunction","page":"C Interface","title":"Base.@cfunction","text":"@cfunction(callable, ReturnType, (ArgumentTypes...,)) -> Ptr{Cvoid}\n@cfunction($callable, ReturnType, (ArgumentTypes...,)) -> CFunction\n\nGenerate a C-callable function pointer from the Julia function callable for the given type signature. To pass the return value to a ccall, use the argument type Ptr{Cvoid} in the signature.\n\nNote that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression (although it can include a splat expression). And that these arguments will be evaluated in global scope during compile-time (not deferred until runtime). Adding a '$' in front of the function argument changes this to instead create a runtime closure over the local variable callable (this is not supported on all architectures).\n\nSee manual section on ccall and cfunction usage.\n\nExamples\n\njulia> function foo(x::Int, y::Int)\n return x + y\n end\n\njulia> @cfunction(foo, Int, (Int, Int))\nPtr{Cvoid} @0x000000001b82fcd0\n\n\n\n\n\n","category":"macro"},{"location":"base/c/#Base.CFunction","page":"C Interface","title":"Base.CFunction","text":"CFunction struct\n\nGarbage-collection handle for the return value from @cfunction when the first argument is annotated with '$'. Like all cfunction handles, it should be passed to ccall as a Ptr{Cvoid}, and will be converted automatically at the call site to the appropriate type.\n\nSee @cfunction.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.unsafe_convert","page":"C Interface","title":"Base.unsafe_convert","text":"unsafe_convert(T, x)\n\nConvert x to a C argument of type T where the input x must be the return value of cconvert(T, ...).\n\nIn cases where convert would need to take a Julia object and turn it into a Ptr, this function should be used to define and perform that conversion.\n\nBe careful to ensure that a Julia reference to x exists as long as the result of this function will be used. Accordingly, the argument x to this function should never be an expression, only a variable name or field reference. For example, x=a.b.c is acceptable, but x=[a,b,c] is not.\n\nThe unsafe prefix on this function indicates that using the result of this function after the x argument to this function is no longer accessible to the program may cause undefined behavior, including program corruption or segfaults, at any later time.\n\nSee also cconvert\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.cconvert","page":"C Interface","title":"Base.cconvert","text":"cconvert(T,x)\n\nConvert x to a value to be passed to C code as type T, typically by calling convert(T, x).\n\nIn cases where x cannot be safely converted to T, unlike convert, cconvert may return an object of a type different from T, which however is suitable for unsafe_convert to handle. The result of this function should be kept valid (for the GC) until the result of unsafe_convert is not needed anymore. This can be used to allocate memory that will be accessed by the ccall. If multiple objects need to be allocated, a tuple of the objects can be used as return value.\n\nNeither convert nor cconvert should take a Julia object and turn it into a Ptr.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_load","page":"C Interface","title":"Base.unsafe_load","text":"unsafe_load(p::Ptr{T}, i::Integer=1)\nunsafe_load(p::Ptr{T}, order::Symbol)\nunsafe_load(p::Ptr{T}, i::Integer, order::Symbol)\n\nLoad a value of type T from the address of the ith element (1-indexed) starting at p. This is equivalent to the C expression p[i-1]. Optionally, an atomic memory ordering can be provided.\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program or return garbage answers. Unlike C, dereferencing memory region allocated as different type may be valid provided that the types are compatible.\n\ncompat: Julia 1.10\nThe order argument is available as of Julia 1.10.\n\nSee also: atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_store!","page":"C Interface","title":"Base.unsafe_store!","text":"unsafe_store!(p::Ptr{T}, x, i::Integer=1)\nunsafe_store!(p::Ptr{T}, x, order::Symbol)\nunsafe_store!(p::Ptr{T}, x, i::Integer, order::Symbol)\n\nStore a value of type T to the address of the ith element (1-indexed) starting at p. This is equivalent to the C expression p[i-1] = x. Optionally, an atomic memory ordering can be provided.\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program. Unlike C, storing memory region allocated as different type may be valid provided that that the types are compatible.\n\ncompat: Julia 1.10\nThe order argument is available as of Julia 1.10.\n\nSee also: atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_modify!","page":"C Interface","title":"Base.unsafe_modify!","text":"unsafe_modify!(p::Ptr{T}, op, x, [order::Symbol]) -> Pair\n\nThese atomically perform the operations to get and set a memory address after applying the function op. If supported by the hardware (for example, atomic increment), this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:\n\ny = unsafe_load(p)\nz = op(y, x)\nunsafe_store!(p, z)\nreturn y => z\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\nSee also: modifyproperty!, atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_replace!","page":"C Interface","title":"Base.unsafe_replace!","text":"unsafe_replace!(p::Ptr{T}, expected, desired,\n [success_order::Symbol[, fail_order::Symbol=success_order]]) -> (; old, success::Bool)\n\nThese atomically perform the operations to get and conditionally set a memory address to a given value. If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:\n\ny = unsafe_load(p, fail_order)\nok = y === expected\nif ok\n unsafe_store!(p, desired, success_order)\nend\nreturn (; old = y, success = ok)\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\nSee also: replaceproperty!, atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_swap!","page":"C Interface","title":"Base.unsafe_swap!","text":"unsafe_swap!(p::Ptr{T}, x, [order::Symbol])\n\nThese atomically perform the operations to simultaneously get and set a memory address. If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:\n\ny = unsafe_load(p)\nunsafe_store!(p, x)\nreturn y\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\nSee also: swapproperty!, atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_copyto!-Union{Tuple{T}, Tuple{Ptr{T}, Ptr{T}, Any}} where T","page":"C Interface","title":"Base.unsafe_copyto!","text":"unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)\n\nCopy N elements from a source pointer to a destination, with no checking. The size of an element is determined by the type of the pointers.\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointers dest and src to ensure that they are valid. Incorrect usage may corrupt or segfault your program, in the same manner as C.\n\n\n\n\n\n","category":"method"},{"location":"base/c/#Base.unsafe_copyto!-Tuple{Array, Any, Array, Any, Any}","page":"C Interface","title":"Base.unsafe_copyto!","text":"unsafe_copyto!(dest::Array, do, src::Array, so, N)\n\nCopy N elements from a source array to a destination, starting at the linear index so in the source and do in the destination (1-indexed).\n\nThe unsafe prefix on this function indicates that no validation is performed to ensure that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in the same manner as C.\n\n\n\n\n\n","category":"method"},{"location":"base/c/#Base.copyto!","page":"C Interface","title":"Base.copyto!","text":"copyto!(B::AbstractMatrix, ir_dest::AbstractUnitRange, jr_dest::AbstractUnitRange,\n tM::AbstractChar,\n M::AbstractVecOrMat, ir_src::AbstractUnitRange, jr_src::AbstractUnitRange) -> B\n\nEfficiently copy elements of matrix M to B conditioned on the character parameter tM as follows:\n\ntM Destination Source\n'N' B[ir_dest, jr_dest] M[ir_src, jr_src]\n'T' B[ir_dest, jr_dest] transpose(M)[ir_src, jr_src]\n'C' B[ir_dest, jr_dest] adjoint(M)[ir_src, jr_src]\n\nThe elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(ir_src) and length(jr_dest) == length(jr_src).\n\nSee also copy_transpose! and copy_adjoint!.\n\n\n\n\n\ncopyto!(dest::AbstractMatrix, src::UniformScaling)\n\nCopies a UniformScaling onto a matrix.\n\ncompat: Julia 1.1\nIn Julia 1.0 this method only supported a square destination matrix. Julia 1.1. added support for a rectangular matrix.\n\n\n\n\n\ncopyto!(dest, do, src, so, N)\n\nCopy N elements from collection src starting at the linear index so, to array dest starting at the index do. Return dest.\n\n\n\n\n\ncopyto!(dest::AbstractArray, src) -> dest\n\nCopy all elements from collection src to array dest, whose length must be greater than or equal to the length n of src. The first n elements of dest are overwritten, the other elements are left untouched.\n\nSee also copy!, copy.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> x = [1., 0., 3., 0., 5.];\n\njulia> y = zeros(7);\n\njulia> copyto!(y, x);\n\njulia> y\n7-element Vector{Float64}:\n 1.0\n 0.0\n 3.0\n 0.0\n 5.0\n 0.0\n 0.0\n\n\n\n\n\ncopyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest\n\nCopy the block of src in the range of Rsrc to the block of dest in the range of Rdest. The sizes of the two regions must match.\n\nExamples\n\njulia> A = zeros(5, 5);\n\njulia> B = [1 2; 3 4];\n\njulia> Ainds = CartesianIndices((2:3, 2:3));\n\njulia> Binds = CartesianIndices(B);\n\njulia> copyto!(A, Ainds, B, Binds)\n5×5 Matrix{Float64}:\n 0.0 0.0 0.0 0.0 0.0\n 0.0 1.0 2.0 0.0 0.0\n 0.0 3.0 4.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.pointer","page":"C Interface","title":"Base.pointer","text":"pointer(array [, index])\n\nGet the native address of an array or string, optionally at a given location index.\n\nThis function is \"unsafe\". Be careful to ensure that a Julia reference to array exists as long as this pointer will be used. The GC.@preserve macro should be used to protect the array argument from garbage collection within a given block of code.\n\nCalling Ref(array[, index]) is generally preferable to this function as it guarantees validity.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_wrap-Union{Tuple{N}, Tuple{T}, Tuple{Union{Type{Array}, Type{Array{T}}, Type{Array{T, N}}}, Ptr{T}, NTuple{N, Int64}}} where {T, N}","page":"C Interface","title":"Base.unsafe_wrap","text":"unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)\n\nWrap a Julia Array object around the data at the address given by pointer, without making a copy. The pointer element type T determines the array element type. dims is either an integer (for a 1d array) or a tuple of the array dimensions. own optionally specifies whether Julia should take ownership of the memory, calling free on the pointer when the array is no longer referenced.\n\nThis function is labeled \"unsafe\" because it will crash if pointer is not a valid memory address to data of the requested length. Unlike unsafe_load and unsafe_store!, the programmer is responsible also for ensuring that the underlying data is not accessed through two arrays of different element type, similar to the strict aliasing rule in C.\n\n\n\n\n\n","category":"method"},{"location":"base/c/#Base.pointer_from_objref","page":"C Interface","title":"Base.pointer_from_objref","text":"pointer_from_objref(x)\n\nGet the memory address of a Julia object as a Ptr. The existence of the resulting Ptr will not protect the object from garbage collection, so you must ensure that the object remains referenced for the whole time that the Ptr will be used.\n\nThis function may not be called on immutable objects, since they do not have stable memory addresses.\n\nSee also unsafe_pointer_to_objref.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_pointer_to_objref","page":"C Interface","title":"Base.unsafe_pointer_to_objref","text":"unsafe_pointer_to_objref(p::Ptr)\n\nConvert a Ptr to an object reference. Assumes the pointer refers to a valid heap-allocated Julia object. If this is not the case, undefined behavior results, hence this function is considered \"unsafe\" and should be used with care.\n\nSee also pointer_from_objref.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.disable_sigint","page":"C Interface","title":"Base.disable_sigint","text":"disable_sigint(f::Function)\n\nDisable Ctrl-C handler during execution of a function on the current task, for calling external code that may call julia code that is not interrupt safe. Intended to be called using do block syntax as follows:\n\ndisable_sigint() do\n # interrupt-unsafe code\n ...\nend\n\nThis is not needed on worker threads (Threads.threadid() != 1) since the InterruptException will only be delivered to the master thread. External functions that do not call julia code or julia runtime automatically disable sigint during their execution.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.reenable_sigint","page":"C Interface","title":"Base.reenable_sigint","text":"reenable_sigint(f::Function)\n\nRe-enable Ctrl-C handler during execution of a function. Temporarily reverses the effect of disable_sigint.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.exit_on_sigint","page":"C Interface","title":"Base.exit_on_sigint","text":"exit_on_sigint(on::Bool)\n\nSet exit_on_sigint flag of the julia runtime. If false, Ctrl-C (SIGINT) is capturable as InterruptException in try block. This is the default behavior in REPL, any code run via -e and -E and in Julia script run with -i option.\n\nIf true, InterruptException is not thrown by Ctrl-C. Running code upon such event requires atexit. This is the default behavior in Julia script run without -i option.\n\ncompat: Julia 1.5\nFunction exit_on_sigint requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.systemerror","page":"C Interface","title":"Base.systemerror","text":"systemerror(sysfunc[, errno::Cint=Libc.errno()])\nsystemerror(sysfunc, iftrue::Bool)\n\nRaises a SystemError for errno with the descriptive string sysfunc if iftrue is true\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.windowserror","page":"C Interface","title":"Base.windowserror","text":"windowserror(sysfunc[, code::UInt32=Libc.GetLastError()])\nwindowserror(sysfunc, iftrue::Bool)\n\nLike systemerror, but for Windows API functions that use GetLastError to return an error code instead of setting errno.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Core.Ptr","page":"C Interface","title":"Core.Ptr","text":"Ptr{T}\n\nA memory address referring to data of type T. However, there is no guarantee that the memory is actually valid, or that it actually represents data of the specified type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Core.Ref","page":"C Interface","title":"Core.Ref","text":"Ref{T}\n\nAn object that safely references data of type T. This type is guaranteed to point to valid, Julia-allocated memory of the correct type. The underlying data is protected from freeing by the garbage collector as long as the Ref itself is referenced.\n\nIn Julia, Ref objects are dereferenced (loaded or stored) with [].\n\nCreation of a Ref to a value x of type T is usually written Ref(x). Additionally, for creating interior pointers to containers (such as Array or Ptr), it can be written Ref(a, i) for creating a reference to the i-th element of a.\n\nRef{T}() creates a reference to a value of type T without initialization. For a bitstype T, the value will be whatever currently resides in the memory allocated. For a non-bitstype T, the reference will be undefined and attempting to dereference it will result in an error, \"UndefRefError: access to undefined reference\".\n\nTo check if a Ref is an undefined reference, use isassigned(ref::RefValue). For example, isassigned(Ref{T}()) is false if T is not a bitstype. If T is a bitstype, isassigned(Ref{T}()) will always be true.\n\nWhen passed as a ccall argument (either as a Ptr or Ref type), a Ref object will be converted to a native pointer to the data it references. For most T, or when converted to a Ptr{Cvoid}, this is a pointer to the object data. When T is an isbits type, this value may be safely mutated, otherwise mutation is strictly undefined behavior.\n\nAs a special case, setting T = Any will instead cause the creation of a pointer to the reference itself when converted to a Ptr{Any} (a jl_value_t const* const* if T is immutable, else a jl_value_t *const *). When converted to a Ptr{Cvoid}, it will still return a pointer to the data region as for any other T.\n\nA C_NULL instance of Ptr can be passed to a ccall Ref argument to initialize it.\n\nUse in broadcasting\n\nRef is sometimes used in broadcasting in order to treat the referenced values as a scalar.\n\nExamples\n\njulia> r = Ref(5) # Create a Ref with an initial value\nBase.RefValue{Int64}(5)\n\njulia> r[] # Getting a value from a Ref\n5\n\njulia> r[] = 7 # Storing a new value in a Ref\n7\n\njulia> r # The Ref now contains 7\nBase.RefValue{Int64}(7)\n\njulia> isa.(Ref([1,2,3]), [Array, Dict, Int]) # Treat reference values as scalar during broadcasting\n3-element BitVector:\n 1\n 0\n 0\n\njulia> Ref{Function}() # Undefined reference to a non-bitstype, Function\nBase.RefValue{Function}(#undef)\n\njulia> try\n Ref{Function}()[] # Dereferencing an undefined reference will result in an error\n catch e\n println(e)\n end\nUndefRefError()\n\njulia> Ref{Int64}()[]; # A reference to a bitstype refers to an undetermined value if not given\n\njulia> isassigned(Ref{Int64}()) # A reference to a bitstype is always assigned\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.isassigned-Tuple{Base.RefValue}","page":"C Interface","title":"Base.isassigned","text":"isassigned(ref::RefValue) -> Bool\n\nTest whether the given Ref is associated with a value. This is always true for a Ref of a bitstype object. Return false if the reference is undefined.\n\nExamples\n\njulia> ref = Ref{Function}()\nBase.RefValue{Function}(#undef)\n\njulia> isassigned(ref)\nfalse\n\njulia> ref[] = (foobar(x) = x)\nfoobar (generic function with 1 method)\n\njulia> isassigned(ref)\ntrue\n\njulia> isassigned(Ref{Int}())\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/c/#Base.Cchar","page":"C Interface","title":"Base.Cchar","text":"Cchar\n\nEquivalent to the native char c-type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cuchar","page":"C Interface","title":"Base.Cuchar","text":"Cuchar\n\nEquivalent to the native unsigned char c-type (UInt8).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cshort","page":"C Interface","title":"Base.Cshort","text":"Cshort\n\nEquivalent to the native signed short c-type (Int16).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cstring","page":"C Interface","title":"Base.Cstring","text":"Cstring\n\nA C-style string composed of the native character type Cchars. Cstrings are NUL-terminated. For C-style strings composed of the native wide character type, see Cwstring. For more information about string interoperability with C, see the manual.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cushort","page":"C Interface","title":"Base.Cushort","text":"Cushort\n\nEquivalent to the native unsigned short c-type (UInt16).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cint","page":"C Interface","title":"Base.Cint","text":"Cint\n\nEquivalent to the native signed int c-type (Int32).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cuint","page":"C Interface","title":"Base.Cuint","text":"Cuint\n\nEquivalent to the native unsigned int c-type (UInt32).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Clong","page":"C Interface","title":"Base.Clong","text":"Clong\n\nEquivalent to the native signed long c-type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Culong","page":"C Interface","title":"Base.Culong","text":"Culong\n\nEquivalent to the native unsigned long c-type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Clonglong","page":"C Interface","title":"Base.Clonglong","text":"Clonglong\n\nEquivalent to the native signed long long c-type (Int64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Culonglong","page":"C Interface","title":"Base.Culonglong","text":"Culonglong\n\nEquivalent to the native unsigned long long c-type (UInt64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cintmax_t","page":"C Interface","title":"Base.Cintmax_t","text":"Cintmax_t\n\nEquivalent to the native intmax_t c-type (Int64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cuintmax_t","page":"C Interface","title":"Base.Cuintmax_t","text":"Cuintmax_t\n\nEquivalent to the native uintmax_t c-type (UInt64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Csize_t","page":"C Interface","title":"Base.Csize_t","text":"Csize_t\n\nEquivalent to the native size_t c-type (UInt).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cssize_t","page":"C Interface","title":"Base.Cssize_t","text":"Cssize_t\n\nEquivalent to the native ssize_t c-type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cptrdiff_t","page":"C Interface","title":"Base.Cptrdiff_t","text":"Cptrdiff_t\n\nEquivalent to the native ptrdiff_t c-type (Int).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cwchar_t","page":"C Interface","title":"Base.Cwchar_t","text":"Cwchar_t\n\nEquivalent to the native wchar_t c-type (Int32).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cwstring","page":"C Interface","title":"Base.Cwstring","text":"Cwstring\n\nA C-style string composed of the native wide character type Cwchar_ts. Cwstrings are NUL-terminated. For C-style strings composed of the native character type, see Cstring. For more information about string interoperability with C, see the manual.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cfloat","page":"C Interface","title":"Base.Cfloat","text":"Cfloat\n\nEquivalent to the native float c-type (Float32).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cdouble","page":"C Interface","title":"Base.Cdouble","text":"Cdouble\n\nEquivalent to the native double c-type (Float64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#LLVM-Interface","page":"C Interface","title":"LLVM Interface","text":"","category":"section"},{"location":"base/c/","page":"C Interface","title":"C Interface","text":"Core.Intrinsics.llvmcall","category":"page"},{"location":"base/c/#Core.Intrinsics.llvmcall","page":"C Interface","title":"Core.Intrinsics.llvmcall","text":"llvmcall(fun_ir::String, returntype, Tuple{argtype1, ...}, argvalue1, ...)\nllvmcall((mod_ir::String, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)\nllvmcall((mod_bc::Vector{UInt8}, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)\n\nCall the LLVM code provided in the first argument. There are several ways to specify this first argument:\n\nas a literal string, representing function-level IR (similar to an LLVM define block), with arguments are available as consecutive unnamed SSA variables (%0, %1, etc.);\nas a 2-element tuple, containing a string of module IR and a string representing the name of the entry-point function to call;\nas a 2-element tuple, but with the module provided as an Vector{UInt8} with bitcode.\n\nNote that contrary to ccall, the argument types must be specified as a tuple type, and not a tuple of types. All types, as well as the LLVM code, should be specified as literals, and not as variables or expressions (it may be necessary to use @eval to generate these literals).\n\nOpaque pointers (written as ptr) are not allowed in the LLVM code.\n\nSee test/llvmcall.jl for usage examples.\n\n\n\n\n\n","category":"function"},{"location":"manual/code-loading/#code-loading","page":"Code Loading","title":"Code Loading","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"note: Note\nThis chapter covers the technical details of package loading. To install packages, use Pkg, Julia's built-in package manager, to add packages to your active environment. To use packages already in your active environment, write import X or using X, as described in the Modules documentation.","category":"page"},{"location":"manual/code-loading/#Definitions","page":"Code Loading","title":"Definitions","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Julia has two mechanisms for loading code:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Code inclusion: e.g. include(\"source.jl\"). Inclusion allows you to split a single program across multiple source files. The expression include(\"source.jl\") causes the contents of the file source.jl to be evaluated in the global scope of the module where the include call occurs. If include(\"source.jl\") is called multiple times, source.jl is evaluated multiple times. The included path, source.jl, is interpreted relative to the file where the include call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, pwd().\nPackage loading: e.g. import X or using X. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name X inside of the importing module. If the same X package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that import X can load different packages in different contexts: X can refer to one package named X in the main project but potentially to different packages also named X in each dependency. More on this below.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Code inclusion is quite straightforward and simple: it evaluates the given source file in the context of the caller. Package loading is built on top of code inclusion and serves a different purpose. The rest of this chapter focuses on the behavior and mechanics of package loading.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A package is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by import X or using X statements. These statements also make the module named X—which results from loading the package code—available within the module where the import statement occurs. The meaning of X in import X is context-dependent: which X package is loaded depends on what code the statement occurs in. Thus, handling of import X happens in two stages: first, it determines what package is defined to be X in this context; second, it determines where that particular X package is found.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"These questions are answered by searching through the project environments listed in LOAD_PATH for project files (Project.toml or JuliaProject.toml), manifest files (Manifest.toml or JuliaManifest.toml, or the same names suffixed by -v{major}.{minor}.toml for specific versions), or folders of source files.","category":"page"},{"location":"manual/code-loading/#Federation-of-packages","page":"Code Loading","title":"Federation of packages","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Most of the time, a package is uniquely identifiable simply from its name. However, sometimes a project might encounter a situation where it needs to use two different packages that share the same name. While you might be able fix this by renaming one of the packages, being forced to do so can be highly disruptive in a large, shared code base. Instead, Julia's code loading mechanism allows the same package name to refer to different packages in different components of an application.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Julia supports federated package management, which means that multiple independent parties can maintain both public and private packages and registries of packages, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The Pkg package manager that ships with Julia lets you install and manage your projects' dependencies. It assists in creating and manipulating project files (which describe what other projects that your project depends on), and manifest files (which snapshot exact versions of your project's complete dependency graph).","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project may end up depending on different packages that have the same name. Julia's package loading mechanism does not require package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by universally unique identifiers (UUIDs), which get assigned when each package is created. Usually you won't have to work directly with these somewhat cumbersome 128-bit identifiers since Pkg will take care of generating and tracking them for you. However, these UUIDs provide the definitive answer to the question of \"what package does X refer to?\"","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called App, which uses two packages: Pub and Priv. Priv is a private package that you created, whereas Pub is a public package that you use but don't control. When you created Priv, there was no public package by the name Priv. Subsequently, however, an unrelated package also named Priv has been published and become popular. In fact, the Pub package has started to use it. Therefore, when you next upgrade Pub to get the latest bug fixes and features, App will end up depending on two different packages named Priv—through no action of yours other than upgrading. App has a direct dependency on your private Priv package, and an indirect dependency, through Pub, on the new public Priv package. Since these two Priv packages are different but are both required for App to continue working correctly, the expression import Priv must refer to different Priv packages depending on whether it occurs in App's code or in Pub's code. To handle this, Julia's package loading mechanism distinguishes the two Priv packages by their UUID and picks the correct one based on its context (the module that called import). How this distinction works is determined by environments, as explained in the following sections.","category":"page"},{"location":"manual/code-loading/#Environments","page":"Code Loading","title":"Environments","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"An environment determines what import X and using X mean in various code contexts and what files these statements cause to be loaded. Julia understands two kinds of environments:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A project environment is a directory with a project file and an optional manifest file, and forms an explicit environment. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version.\nA package directory is a directory containing the source trees of a set of packages as subdirectories, and forms an implicit environment. If X is a subdirectory of a package directory and X/src/X.jl exists, then the package X is available in the package directory environment and X/src/X.jl is the source file by which it is loaded.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"These can be intermixed to create a stacked environment: an ordered set of project environments and package directories, overlaid to make a single composite environment. The precedence and visibility rules then combine to determine which packages are available and where they get loaded from. Julia's load path forms a stacked environment, for example.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"These environment each serve a different purpose:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Project environments provide reproducibility. By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project and all of its dependencies. The manifest file, in particular, captures the exact version of every dependency, identified by a cryptographic hash of its source tree, which makes it possible for Pkg to retrieve the correct versions and be sure that you are running the exact code that was recorded for all dependencies.\nPackage directories provide convenience when a full carefully-tracked project environment is unnecessary. They are useful when you want to put a set of packages somewhere and be able to directly use them, without needing to create a project environment for them.\nStacked environments allow for adding tools to the primary environment. You can push an environment of development tools onto the end of the stack to make them available from the REPL and scripts, but not from inside packages.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"At a high-level, each environment conceptually defines three maps: roots, graph and paths. When resolving the meaning of import X, the roots and graph maps are used to determine the identity of X, while the paths map is used to locate the source code of X. The specific roles of the three maps are:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"roots: name::Symbol ⟶ uuid::UUID\nAn environment's roots map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in Main). When Julia encounters import X in the main project, it looks up the identity of X as roots[:X].\ngraph: context::UUID ⟶ name::Symbol ⟶ uuid::UUID\nAn environment's graph is a multilevel map which assigns, for each context UUID, a map from names to UUIDs, similar to the roots map but specific to that context. When Julia sees import X in the code of the package whose UUID is context, it looks up the identity of X as graph[context][:X]. In particular, this means that import X can refer to different packages depending on context.\npaths: uuid::UUID × name::Symbol ⟶ path::String\nThe paths map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of X in import X has been resolved to a UUID via roots or graph (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire X by looking up paths[uuid,:X] in the environment. Including this file should define a module named X. Once this package is loaded, any subsequent import resolving to the same uuid will create a new binding to the already-loaded package module.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Each kind of environment defines these three maps differently, as detailed in the following sections.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"note: Note\nFor ease of understanding, the examples throughout this chapter show full data structures for roots, graph and paths. However, Julia's package loading code does not explicitly create these. Instead, it lazily computes only as much of each structure as it needs to load a given package.","category":"page"},{"location":"manual/code-loading/#Project-environments","page":"Code Loading","title":"Project environments","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A project environment is determined by a directory containing a project file called Project.toml, and optionally a manifest file called Manifest.toml. These files may also be called JuliaProject.toml and JuliaManifest.toml, in which case Project.toml and Manifest.toml are ignored. This allows for coexistence with other tools that might consider files called Project.toml and Manifest.toml significant. For pure Julia projects, however, the names Project.toml and Manifest.toml are preferred. However, from Julia v1.11 onwards, (Julia)Manifest-v{major}.{minor}.toml is recognized as a format to make a given julia version use a specific manifest file i.e. in the same folder, a Manifest-v1.11.toml would be used by v1.11 and Manifest.toml by any other julia version.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The roots, graph and paths maps of a project environment are defined as follows:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The roots map of the environment is determined by the contents of the project file, specifically, its top-level name and uuid entries and its [deps] section (all optional). Consider the following example project file for the hypothetical application, App, as described earlier:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"name = \"App\"\nuuid = \"8f986787-14fe-4607-ba5d-fbff2944afa9\"\n\n[deps]\nPriv = \"ba13f791-ae1d-465a-978b-69c3ad90f72b\"\nPub = \"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"This project file implies the following roots map, if it was represented by a Julia dictionary:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"roots = Dict(\n :App => UUID(\"8f986787-14fe-4607-ba5d-fbff2944afa9\"),\n :Priv => UUID(\"ba13f791-ae1d-465a-978b-69c3ad90f72b\"),\n :Pub => UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"),\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Given this roots map, in App's code the statement import Priv will cause Julia to look up roots[:Priv], which yields ba13f791-ae1d-465a-978b-69c3ad90f72b, the UUID of the Priv package that is to be loaded in that context. This UUID identifies which Priv package to load and use when the main application evaluates import Priv.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The dependency graph of a project environment is determined by the contents of the manifest file, if present. If there is no manifest file, graph is empty. A manifest file contains a stanza for each of a project's direct or indirect dependencies. For each dependency, the file lists the package's UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for App:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"[[Priv]] # the private one\ndeps = [\"Pub\", \"Zebra\"]\nuuid = \"ba13f791-ae1d-465a-978b-69c3ad90f72b\"\npath = \"deps/Priv\"\n\n[[Priv]] # the public one\nuuid = \"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\"\ngit-tree-sha1 = \"1bf63d3be994fe83456a03b874b409cfd59a6373\"\nversion = \"0.1.5\"\n\n[[Pub]]\nuuid = \"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"\ngit-tree-sha1 = \"9ebd50e2b0dd1e110e842df3b433cb5869b0dd38\"\nversion = \"2.1.4\"\n\n [Pub.deps]\n Priv = \"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\"\n Zebra = \"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"\n\n[[Zebra]]\nuuid = \"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"\ngit-tree-sha1 = \"e808e36a5d7173974b90a15a353b564f3494092f\"\nversion = \"3.4.2\"","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"This manifest file describes a possible complete dependency graph for the App project:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"There are two different packages named Priv that the application uses. It uses a private package, which is a root dependency, and a public one, which is an indirect dependency through Pub. These are differentiated by their distinct UUIDs, and they have different deps:\nThe private Priv depends on the Pub and Zebra packages.\nThe public Priv has no dependencies.\nThe application also depends on the Pub package, which in turn depends on the public Priv and the same Zebra package that the private Priv package depends on.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"This dependency graph represented as a dictionary, looks like this:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"graph = Dict(\n # Priv – the private one:\n UUID(\"ba13f791-ae1d-465a-978b-69c3ad90f72b\") => Dict(\n :Pub => UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"),\n :Zebra => UUID(\"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"),\n ),\n # Priv – the public one:\n UUID(\"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\") => Dict(),\n # Pub:\n UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\") => Dict(\n :Priv => UUID(\"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\"),\n :Zebra => UUID(\"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"),\n ),\n # Zebra:\n UUID(\"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\") => Dict(),\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Given this dependency graph, when Julia sees import Priv in the Pub package—which has UUID c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1—it looks up:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"graph[UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\")][:Priv]","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"and gets 2d15fe94-a1f7-436c-a4d8-07a9a496e01c, which indicates that in the context of the Pub package, import Priv refers to the public Priv package, rather than the private one which the app depends on directly. This is how the name Priv can refer to different packages in the main project than it does in one of its package's dependencies, which allows for duplicate names in the package ecosystem.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"What happens if import Zebra is evaluated in the main App code base? Since Zebra does not appear in the project file, the import will fail even though Zebra does appear in the manifest file. Moreover, if import Zebra occurs in the public Priv package—the one with UUID 2d15fe94-a1f7-436c-a4d8-07a9a496e01c—then that would also fail since that Priv package has no declared dependencies in the manifest file and therefore cannot load any packages. The Zebra package can only be loaded by packages for which it appear as an explicit dependency in the manifest file: the Pub package and one of the Priv packages.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The paths map of a project environment is extracted from the manifest file. The path of a package uuid named X is determined by these rules (in order):","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If the project file in the directory matches uuid and name X, then either:\nIt has a toplevel path entry, then uuid will be mapped to that path, interpreted relative to the directory containing the project file.\nOtherwise, uuid is mapped to src/X.jl relative to the directory containing the project file.\nIf the above is not the case and the project file has a corresponding manifest file and the manifest contains a stanza matching uuid then:\nIf it has a path entry, use that path (relative to the directory containing the manifest file).\nIf it has a git-tree-sha1 entry, compute a deterministic hash function of uuid and git-tree-sha1—call it slug—and look for a directory named packages/X/$slug in each directory in the Julia DEPOT_PATH global array. Use the first such directory that exists.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If any of these result in success, the path to the source code entry point will be either that result, the relative path from that result plus src/X.jl; otherwise, there is no path mapping for uuid. When loading X, if no source code path is found, the lookup will fail, and the user may be prompted to install the appropriate package version or to take other corrective action (e.g. declaring X as a dependency).","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"In the example manifest file above, to find the path of the first Priv package—the one with UUID ba13f791-ae1d-465a-978b-69c3ad90f72b—Julia looks for its stanza in the manifest file, sees that it has a path entry, looks at deps/Priv relative to the App project directory—let's suppose the App code lives in /home/me/projects/App—sees that /home/me/projects/App/deps/Priv exists and therefore loads Priv from there.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If, on the other hand, Julia was loading the other Priv package—the one with UUID 2d15fe94-a1f7-436c-a4d8-07a9a496e01c—it finds its stanza in the manifest, see that it does not have a path entry, but that it does have a git-tree-sha1 entry. It then computes the slug for this UUID/SHA-1 pair, which is HDkrT (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this Priv package will be packages/Priv/HDkrT/src/Priv.jl in one of the package depots. Suppose the contents of DEPOT_PATH is [\"/home/me/.julia\", \"/usr/local/julia\"], then Julia will look at the following paths to see if they exist:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"/home/me/.julia/packages/Priv/HDkrT\n/usr/local/julia/packages/Priv/HDkrT","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Julia uses the first of these that exists to try to load the public Priv package from the file packages/Priv/HDKrT/src/Priv.jl in the depot where it was found.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Here is a representation of a possible paths map for our example App project environment, as provided in the Manifest given above for the dependency graph, after searching the local file system:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"paths = Dict(\n # Priv – the private one:\n (UUID(\"ba13f791-ae1d-465a-978b-69c3ad90f72b\"), :Priv) =>\n # relative entry-point inside `App` repo:\n \"/home/me/projects/App/deps/Priv/src/Priv.jl\",\n # Priv – the public one:\n (UUID(\"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\"), :Priv) =>\n # package installed in the system depot:\n \"/usr/local/julia/packages/Priv/HDkr/src/Priv.jl\",\n # Pub:\n (UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"), :Pub) =>\n # package installed in the user depot:\n \"/home/me/.julia/packages/Pub/oKpw/src/Pub.jl\",\n # Zebra:\n (UUID(\"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"), :Zebra) =>\n # package installed in the system depot:\n \"/usr/local/julia/packages/Zebra/me9k/src/Zebra.jl\",\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"This example map includes three different kinds of package locations (the first and third are part of the default load path):","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The private Priv package is \"vendored\" inside the App repository.\nThe public Priv and Zebra packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system.\nThe Pub package is in the user depot, where packages installed by the user live. These are only available to the user who installed them.","category":"page"},{"location":"manual/code-loading/#Package-directories","page":"Code Loading","title":"Package directories","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Package directories provide a simpler kind of environment without the ability to handle name collisions. In a package directory, the set of top-level packages is the set of subdirectories that \"look like\" packages. A package X exists in a package directory if the directory contains one of the following \"entry point\" files:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"X.jl\nX/src/X.jl\nX.jl/src/X.jl","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Which dependencies a package in a package directory can import depends on whether the package contains a project file:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If it has a project file, it can only import those packages which are identified in the [deps] section of the project file.\nIf it does not have a project file, it can import any top-level package—i.e. the same packages that can be loaded in Main or the REPL.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The roots map is determined by examining the contents of the package directory to generate a list of all packages that exist. Additionally, a UUID will be assigned to each entry as follows: For a given package found inside the folder X...","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If X/Project.toml exists and has a uuid entry, then uuid is that value.\nIf X/Project.toml exists and but does not have a top-level UUID entry, uuid is a dummy UUID generated by hashing the canonical (real) path to X/Project.toml.\nOtherwise (if Project.toml does not exist), then uuid is the all-zero nil UUID.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The dependency graph of a project directory is determined by the presence and contents of project files in the subdirectory of each package. The rules are:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If a package subdirectory has no project file, then it is omitted from graph and import statements in its code are treated as top-level, the same as the main project and REPL.\nIf a package subdirectory has a project file, then the graph entry for its UUID is the [deps] map of the project file, which is considered to be empty if the section is absent.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"As an example, suppose a package directory has the following structure and content:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Aardvark/\n src/Aardvark.jl:\n import Bobcat\n import Cobra\n\nBobcat/\n Project.toml:\n [deps]\n Cobra = \"4725e24d-f727-424b-bca0-c4307a3456fa\"\n Dingo = \"7a7925be-828c-4418-bbeb-bac8dfc843bc\"\n\n src/Bobcat.jl:\n import Cobra\n import Dingo\n\nCobra/\n Project.toml:\n uuid = \"4725e24d-f727-424b-bca0-c4307a3456fa\"\n [deps]\n Dingo = \"7a7925be-828c-4418-bbeb-bac8dfc843bc\"\n\n src/Cobra.jl:\n import Dingo\n\nDingo/\n Project.toml:\n uuid = \"7a7925be-828c-4418-bbeb-bac8dfc843bc\"\n\n src/Dingo.jl:\n # no imports","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Here is a corresponding roots structure, represented as a dictionary:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"roots = Dict(\n :Aardvark => UUID(\"00000000-0000-0000-0000-000000000000\"), # no project file, nil UUID\n :Bobcat => UUID(\"85ad11c7-31f6-5d08-84db-0a4914d4cadf\"), # dummy UUID based on path\n :Cobra => UUID(\"4725e24d-f727-424b-bca0-c4307a3456fa\"), # UUID from project file\n :Dingo => UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\"), # UUID from project file\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Here is the corresponding graph structure, represented as a dictionary:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"graph = Dict(\n # Bobcat:\n UUID(\"85ad11c7-31f6-5d08-84db-0a4914d4cadf\") => Dict(\n :Cobra => UUID(\"4725e24d-f727-424b-bca0-c4307a3456fa\"),\n :Dingo => UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\"),\n ),\n # Cobra:\n UUID(\"4725e24d-f727-424b-bca0-c4307a3456fa\") => Dict(\n :Dingo => UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\"),\n ),\n # Dingo:\n UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\") => Dict(),\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A few general rules to note:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A package without a project file can depend on any top-level dependency, and since every package in a package directory is available at the top-level, it can import all packages in the environment.\nA package with a project file cannot depend on one without a project file since packages with project files can only load packages in graph and packages without project files do not appear in graph.\nA package with a project file but no explicit UUID can only be depended on by packages without project files since dummy UUIDs assigned to these packages are strictly internal.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Observe the following specific instances of these rules in our example:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Aardvark can import on any of Bobcat, Cobra or Dingo; it does import Bobcat and Cobra.\nBobcat can and does import both Cobra and Dingo, which both have project files with UUIDs and are declared as dependencies in Bobcat's [deps] section.\nBobcat cannot depend on Aardvark since Aardvark does not have a project file.\nCobra can and does import Dingo, which has a project file and UUID, and is declared as a dependency in Cobra's [deps] section.\nCobra cannot depend on Aardvark or Bobcat since neither have real UUIDs.\nDingo cannot import anything because it has a project file without a [deps] section.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The paths map in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is /home/me/animals then the paths map could be represented by this dictionary:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"paths = Dict(\n (UUID(\"00000000-0000-0000-0000-000000000000\"), :Aardvark) =>\n \"/home/me/AnimalPackages/Aardvark/src/Aardvark.jl\",\n (UUID(\"85ad11c7-31f6-5d08-84db-0a4914d4cadf\"), :Bobcat) =>\n \"/home/me/AnimalPackages/Bobcat/src/Bobcat.jl\",\n (UUID(\"4725e24d-f727-424b-bca0-c4307a3456fa\"), :Cobra) =>\n \"/home/me/AnimalPackages/Cobra/src/Cobra.jl\",\n (UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\"), :Dingo) =>\n \"/home/me/AnimalPackages/Dingo/src/Dingo.jl\",\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Since all packages in a package directory environment are, by definition, subdirectories with the expected entry-point files, their paths map entries always have this form.","category":"page"},{"location":"manual/code-loading/#Environment-stacks","page":"Code Loading","title":"Environment stacks","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The third and final kind of environment is one that combines other environments by overlaying several of them, making the packages in each available in a single composite environment. These composite environments are called environment stacks. The Julia LOAD_PATH global defines an environment stack—the environment in which the Julia process operates. If you want your Julia process to have access only to the packages in one project or package directory, make it the only entry in LOAD_PATH. It is often quite useful, however, to have access to some of your favorite tools—standard libraries, profilers, debuggers, personal utilities, etc.—even if they are not dependencies of the project you're working on. By adding an environment containing these tools to the load path, you immediately have access to them in top-level code without needing to add them to your project.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The mechanism for combining the roots, graph and paths data structures of the components of an environment stack is simple: they are merged as dictionaries, favoring earlier entries over later ones in the case of key collisions. In other words, if we have stack = [env₁, env₂, …] then we have:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"roots = reduce(merge, reverse([roots₁, roots₂, …]))\ngraph = reduce(merge, reverse([graph₁, graph₂, …]))\npaths = reduce(merge, reverse([paths₁, paths₂, …]))","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The subscripted rootsᵢ, graphᵢ and pathsᵢ variables correspond to the subscripted environments, envᵢ, contained in stack. The reverse is present because merge favors the last argument rather than first when there are collisions between keys in its argument dictionaries. There are a couple of noteworthy features of this design:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The primary environment—i.e. the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies.\nPackages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack (either by graph or path, or both).","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right trade-off: it's better to break your development tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project.","category":"page"},{"location":"manual/code-loading/#man-extensions","page":"Code Loading","title":"Package Extensions","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A package \"extension\" is a module that is automatically loaded when a specified set of other packages (its \"extension dependencies\") are loaded in the current Julia session. Extensions are defined under the [extensions] section in the project file. The extension dependencies of an extension are a subset of those packages listed under the [weakdeps] section of the project file. Those packages can have compat entries like other packages.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"name = \"MyPackage\"\n\n[compat]\nExtDep = \"1.0\"\nOtherExtDep = \"1.0\"\n\n[weakdeps]\nExtDep = \"c9a23...\" # uuid\nOtherExtDep = \"862e...\" # uuid\n\n[extensions]\nBarExt = [\"ExtDep\", \"OtherExtDep\"]\nFooExt = \"ExtDep\"\n...","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The keys under extensions are the names of the extensions. They are loaded when all the packages on the right hand side (the extension dependencies) of that extension are loaded. If an extension only has one extension dependency the list of extension dependencies can be written as just a string for brevity. The location for the entry point of the extension is either in ext/FooExt.jl or ext/FooExt/FooExt.jl for extension FooExt. The content of an extension is often structured as:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"module FooExt\n\n# Load main package and extension dependencies\nusing MyPackage, ExtDep\n\n# Extend functionality in main package with types from the extension dependencies\nMyPackage.func(x::ExtDep.SomeStruct) = ...\n\nend","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"When a package with extensions is added to an environment, the weakdeps and extensions sections are stored in the manifest file in the section for that package. The dependency lookup rules for a package are the same as for its \"parent\" except that the listed extension dependencies are also considered as dependencies.","category":"page"},{"location":"manual/code-loading/#workspaces","page":"Code Loading","title":"Workspaces","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A project file can define a workspace by giving a set of projects that is part of that workspace:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"[workspace]\nprojects = [\"test\", \"benchmarks\", \"docs\", \"SomePackage\"]","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Each subfolder contains its own Project.toml file, which may include additional dependencies and compatibility constraints. In such cases, the package manager gathers all dependency information from all the projects in the workspace generating a single manifest file that combines the versions of all dependencies.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Furthermore, workspaces can be \"nested\", meaning a project defining a workspace can also be part of another workspace. In this scenario, a single manifest file is still utilized, stored alongside the \"root project\" (the project that doesn't have another workspace including it). An example file structure could look like this:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Project.toml # projects = [\"MyPackage\"]\nManifest.toml\nMyPackage/\n Project.toml # projects = [\"test\"]\n test/\n Project.toml","category":"page"},{"location":"manual/code-loading/#preferences","page":"Code Loading","title":"Package/Environment Preferences","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Preferences are dictionaries of metadata that influence package behavior within an environment. The preferences system supports reading preferences at compile-time, which means that at code-loading time, we must ensure that the precompilation files selected by Julia were built with the same preferences as the current environment before loading them. The public API for modifying Preferences is contained within the Preferences.jl package. Preferences are stored as TOML dictionaries within a (Julia)LocalPreferences.toml file next to the currently-active project. If a preference is \"exported\", it is instead stored within the (Julia)Project.toml instead. The intention is to allow shared projects to contain shared preferences, while allowing for users themselves to override those preferences with their own settings in the LocalPreferences.toml file, which should be .gitignored as the name implies.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Preferences that are accessed during compilation are automatically marked as compile-time preferences, and any change recorded to these preferences will cause the Julia compiler to recompile any cached precompilation file(s) (.ji and corresponding .so, .dll, or .dylib files) for that module. This is done by serializing the hash of all compile-time preferences during compilation, then checking that hash against the current environment when searching for the proper file(s) to load.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Preferences can be set with depot-wide defaults; if package Foo is installed within your global environment and it has preferences set, these preferences will apply as long as your global environment is part of your LOAD_PATH. Preferences in environments higher up in the environment stack get overridden by the more proximal entries in the load path, ending with the currently active project. This allows depot-wide preference defaults to exist, with active projects able to merge or even completely overwrite these inherited preferences. See the docstring for Preferences.set_preferences!() for the full details of how to set preferences to allow or disallow merging.","category":"page"},{"location":"manual/code-loading/#Conclusion","page":"Code Loading","title":"Conclusion","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Typically, Julia users should be able to use the built-in package manager to manage their projects without needing a precise understanding of these interactions. A call to Pkg.add(\"X\") will add to the appropriate project and manifest files, selected via Pkg.activate(\"Y\"), so that a future call to import X will load X without further thought.","category":"page"},{"location":"manual/mathematical-operations/#Mathematical-Operations-and-Elementary-Functions","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia provides a complete collection of basic arithmetic and bitwise operators across all of its numeric primitive types, as well as providing portable, efficient implementations of a comprehensive collection of standard mathematical functions.","category":"page"},{"location":"manual/mathematical-operations/#Arithmetic-Operators","page":"Mathematical Operations and Elementary Functions","title":"Arithmetic Operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The following arithmetic operators are supported on all primitive numeric types:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Expression Name Description\n+x unary plus the identity operation\n-x unary minus maps values to their additive inverses\nx + y binary plus performs addition\nx - y binary minus performs subtraction\nx * y times performs multiplication\nx / y divide performs division\nx ÷ y integer divide x / y, truncated to an integer\nx \\ y inverse divide equivalent to y / x\nx ^ y power raises x to the yth power\nx % y remainder equivalent to rem(x, y)","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"A numeric literal placed directly before an identifier or parentheses, e.g. 2x or 2(x + y), is treated as a multiplication, except with higher precedence than other binary operations. See Numeric Literal Coefficients for details.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia's promotion system makes arithmetic operations on mixtures of argument types \"just work\" naturally and automatically. See Conversion and Promotion for details of the promotion system.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The ÷ sign can be conveniently typed by writing \\div to the REPL or Julia IDE. See the manual section on Unicode input for more information.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Here are some simple examples using arithmetic operators:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> 1 + 2 + 3\n6\n\njulia> 1 - 2\n-1\n\njulia> 3*2/12\n0.5","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"(By convention, we tend to space operators more tightly if they get applied before other nearby operators. For instance, we would generally write -x + 2 to reflect that first x gets negated, and then 2 is added to that result.)","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"When used in multiplication, false acts as a strong zero:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> NaN * false\n0.0\n\njulia> false * Inf\n0.0","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"This is useful for preventing the propagation of NaN values in quantities that are known to be zero. See Knuth (1992) for motivation.","category":"page"},{"location":"manual/mathematical-operations/#Boolean-Operators","page":"Mathematical Operations and Elementary Functions","title":"Boolean Operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The following Boolean operators are supported on Bool types:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Expression Name\n!x negation\nx && y short-circuiting and\nx || y short-circuiting or","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Negation changes true to false and vice versa. The short-circuiting operations are explained on the linked page.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Note that Bool is an integer type and all the usual promotion rules and numeric operators are also defined on it.","category":"page"},{"location":"manual/mathematical-operations/#Bitwise-Operators","page":"Mathematical Operations and Elementary Functions","title":"Bitwise Operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The following bitwise operators are supported on all primitive integer types:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Expression Name\n~x bitwise not\nx & y bitwise and\nx | y bitwise or\nx ⊻ y bitwise xor (exclusive or)\nx ⊼ y bitwise nand (not and)\nx ⊽ y bitwise nor (not or)\nx >>> y logical shift right\nx >> y arithmetic shift right\nx << y logical/arithmetic shift left","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Here are some examples with bitwise operators:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> ~123\n-124\n\njulia> 123 & 234\n106\n\njulia> 123 | 234\n251\n\njulia> 123 ⊻ 234\n145\n\njulia> xor(123, 234)\n145\n\njulia> nand(123, 123)\n-124\n\njulia> 123 ⊼ 123\n-124\n\njulia> nor(123, 124)\n-128\n\njulia> 123 ⊽ 124\n-128\n\njulia> ~UInt32(123)\n0xffffff84\n\njulia> ~UInt8(123)\n0x84","category":"page"},{"location":"manual/mathematical-operations/#Updating-operators","page":"Mathematical Operations and Elementary Functions","title":"Updating operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Every binary arithmetic and bitwise operator also has an updating version that assigns the result of the operation back into its left operand. The updating version of the binary operator is formed by placing a = immediately after the operator. For example, writing x += 3 is equivalent to writing x = x + 3:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> x = 1\n1\n\njulia> x += 3\n4\n\njulia> x\n4","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The updating versions of all the binary arithmetic and bitwise operators are:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"+= -= *= /= \\= ÷= %= ^= &= |= ⊻= >>>= >>= <<=","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"note: Note\nAn updating operator rebinds the variable on the left-hand side. As a result, the type of the variable may change.julia> x = 0x01; typeof(x)\nUInt8\n\njulia> x *= 2 # Same as x = x * 2\n2\n\njulia> typeof(x)\nInt64","category":"page"},{"location":"manual/mathematical-operations/#man-dot-operators","page":"Mathematical Operations and Elementary Functions","title":"Vectorized \"dot\" operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"For every binary operation like ^, there is a corresponding \"dot\" operation .^ that is automatically defined to perform ^ element-by-element on arrays. For example, [1, 2, 3] ^ 3 is not defined, since there is no standard mathematical meaning to \"cubing\" a (non-square) array, but [1, 2, 3] .^ 3 is defined as computing the elementwise (or \"vectorized\") result [1^3, 2^3, 3^3]. Similarly for unary operators like ! or √, there is a corresponding .√ that applies the operator elementwise.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> [1, 2, 3] .^ 3\n3-element Vector{Int64}:\n 1\n 8\n 27","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"More specifically, a .^ b is parsed as the \"dot\" call (^).(a,b), which performs a broadcast operation: it can combine arrays and scalars, arrays of the same size (performing the operation elementwise), and even arrays of different shapes (e.g. combining row and column vectors to produce a matrix). Moreover, like all vectorized \"dot calls,\" these \"dot operators\" are fusing. For example, if you compute 2 .* A.^2 .+ sin.(A) (or equivalently @. 2A^2 + sin(A), using the @. macro) for an array A, it performs a single loop over A, computing 2a^2 + sin(a) for each element a of A. In particular, nested dot calls like f.(g.(x)) are fused, and \"adjacent\" binary operators like x .+ 3 .* x.^2 are equivalent to nested dot calls (+).(x, (*).(3, (^).(x, 2))).","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Furthermore, \"dotted\" updating operators like a .+= b (or @. a += b) are parsed as a .= a .+ b, where .= is a fused in-place assignment operation (see the dot syntax documentation).","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Note the dot syntax is also applicable to user-defined operators. For example, if you define ⊗(A, B) = kron(A, B) to give a convenient infix syntax A ⊗ B for Kronecker products (kron), then [A, B] .⊗ [C, D] will compute [A⊗C, B⊗D] with no additional coding.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Combining dot operators with numeric literals can be ambiguous. For example, it is not clear whether 1.+x means 1. + x or 1 .+ x. Therefore this syntax is disallowed, and spaces must be used around the operator in such cases.","category":"page"},{"location":"manual/mathematical-operations/#Numeric-Comparisons","page":"Mathematical Operations and Elementary Functions","title":"Numeric Comparisons","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Standard comparison operations are defined for all the primitive numeric types:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Operator Name\n== equality\n!=, ≠ inequality\n< less than\n<=, ≤ less than or equal to\n> greater than\n>=, ≥ greater than or equal to","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Here are some simple examples:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> 1 == 1\ntrue\n\njulia> 1 == 2\nfalse\n\njulia> 1 != 2\ntrue\n\njulia> 1 == 1.0\ntrue\n\njulia> 1 < 2\ntrue\n\njulia> 1.0 > 3\nfalse\n\njulia> 1 >= 1.0\ntrue\n\njulia> -1 <= 1\ntrue\n\njulia> -1 <= -1\ntrue\n\njulia> -1 <= -2\nfalse\n\njulia> 3 < -0.5\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Integers are compared in the standard manner – by comparison of bits. Floating-point numbers are compared according to the IEEE 754 standard:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Finite numbers are ordered in the usual manner.\nPositive zero is equal but not greater than negative zero.\nInf is equal to itself and greater than everything else except NaN.\n-Inf is equal to itself and less than everything else except NaN.\nNaN is not equal to, not less than, and not greater than anything, including itself.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The last point is potentially surprising and thus worth noting:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> NaN == NaN\nfalse\n\njulia> NaN != NaN\ntrue\n\njulia> NaN < NaN\nfalse\n\njulia> NaN > NaN\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"and can cause headaches when working with arrays:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> [1 NaN] == [1 NaN]\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia provides additional functions to test numbers for special values, which can be useful in situations like hash key comparisons:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Tests if\nisequal(x, y) x and y are identical\nisfinite(x) x is a finite number\nisinf(x) x is infinite\nisnan(x) x is not a number","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"isequal considers NaNs equal to each other:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> isequal(NaN, NaN)\ntrue\n\njulia> isequal([1 NaN], [1 NaN])\ntrue\n\njulia> isequal(NaN, NaN32)\ntrue","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"isequal can also be used to distinguish signed zeros:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> -0.0 == 0.0\ntrue\n\njulia> isequal(-0.0, 0.0)\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Mixed-type comparisons between signed integers, unsigned integers, and floats can be tricky. A great deal of care has been taken to ensure that Julia does them correctly.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"For other types, isequal defaults to calling ==, so if you want to define equality for your own types then you only need to add a == method. If you define your own equality function, you should probably define a corresponding hash method to ensure that isequal(x,y) implies hash(x) == hash(y).","category":"page"},{"location":"manual/mathematical-operations/#Chaining-comparisons","page":"Mathematical Operations and Elementary Functions","title":"Chaining comparisons","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Unlike most languages, with the notable exception of Python, comparisons can be arbitrarily chained:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5\ntrue","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Chaining comparisons is often quite convenient in numerical code. Chained comparisons use the && operator for scalar comparisons, and the & operator for elementwise comparisons, which allows them to work on arrays. For example, 0 .< A .< 1 gives a boolean array whose entries are true where the corresponding elements of A are between 0 and 1.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Note the evaluation behavior of chained comparisons:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> v(x) = (println(x); x)\nv (generic function with 1 method)\n\njulia> v(1) < v(2) <= v(3)\n2\n1\n3\ntrue\n\njulia> v(1) > v(2) <= v(3)\n2\n1\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The middle expression is only evaluated once, rather than twice as it would be if the expression were written as v(1) < v(2) && v(2) <= v(3). However, the order of evaluations in a chained comparison is undefined. It is strongly recommended not to use expressions with side effects (such as printing) in chained comparisons. If side effects are required, the short-circuit && operator should be used explicitly (see Short-Circuit Evaluation).","category":"page"},{"location":"manual/mathematical-operations/#Elementary-Functions","page":"Mathematical Operations and Elementary Functions","title":"Elementary Functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia provides a comprehensive collection of mathematical functions and operators. These mathematical operations are defined over as broad a class of numerical values as permit sensible definitions, including integers, floating-point numbers, rationals, and complex numbers, wherever such definitions make sense.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Moreover, these functions (like any Julia function) can be applied in \"vectorized\" fashion to arrays and other collections with the dot syntax f.(A), e.g. sin.(A) will compute the sine of each element of an array A.","category":"page"},{"location":"manual/mathematical-operations/#Operator-Precedence-and-Associativity","page":"Mathematical Operations and Elementary Functions","title":"Operator Precedence and Associativity","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia applies the following order and associativity of operations, from highest precedence to lowest:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Category Operators Associativity\nSyntax . followed by :: Left\nExponentiation ^ Right\nUnary + - ! ~ ¬ √ ∛ ∜ ⋆ ± ∓ <: >: Right[1]\nBitshifts << >> >>> Left\nFractions // Left\nMultiplication * / % & \\ ÷ Left[2]\nAddition + - | ⊻ Left[2]\nSyntax : .. Left\nSyntax |> Left\nSyntax <| Right\nComparisons > < >= <= == === != !== <: Non-associative\nControl flow && followed by || followed by ? Right\nPair => Right\nAssignments = += -= *= /= //= \\= ^= ÷= %= |= &= ⊻= <<= >>= >>>= Right","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"[1]: The unary operators + and - require explicit parentheses around their argument to disambiguate them from the operator ++, etc. Other compositions of unary operators are parsed with right-associativity, e. g., √√-a as √(√(-a)).","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"[2]: The operators +, ++ and * are non-associative. a + b + c is parsed as +(a, b, c) not +(+(a, b), c). However, the fallback methods for +(a, b, c, d...) and *(a, b, c, d...) both default to left-associative evaluation.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"For a complete list of every Julia operator's precedence, see the top of this file: src/julia-parser.scm. Note that some of the operators there are not defined in the Base module but may be given definitions by standard libraries, packages or user code.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"You can also find the numerical precedence for any given operator via the built-in function Base.operator_precedence, where higher numbers take precedence:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.)\n(11, 12, 17)\n\njulia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.operator_precedence(:(=)) # (Note the necessary parens on `:(=)`)\n(0, 1, 1)","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"A symbol representing the operator associativity can also be found by calling the built-in function Base.operator_associativity:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> Base.operator_associativity(:-), Base.operator_associativity(:+), Base.operator_associativity(:^)\n(:left, :none, :right)\n\njulia> Base.operator_associativity(:⊗), Base.operator_associativity(:sin), Base.operator_associativity(:→)\n(:left, :none, :right)","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Note that symbols such as :sin return precedence 0. This value represents invalid operators and not operators of lowest precedence. Similarly, such operators are assigned associativity :none.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Numeric literal coefficients, e.g. 2x, are treated as multiplications with higher precedence than any other binary operation, with the exception of ^ where they have higher precedence only as the exponent.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> x = 3; 2x^2\n18\n\njulia> x = 3; 2^2x\n64","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Juxtaposition parses like a unary operator, which has the same natural asymmetry around exponents: -x^y and 2x^y parse as -(x^y) and 2(x^y) whereas x^-y and x^2y parse as x^(-y) and x^(2y).","category":"page"},{"location":"manual/mathematical-operations/#Numerical-Conversions","page":"Mathematical Operations and Elementary Functions","title":"Numerical Conversions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia supports three forms of numerical conversion, which differ in their handling of inexact conversions.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The notation T(x) or convert(T, x) converts x to a value of type T.\nIf T is a floating-point type, the result is the nearest representable value, which could be positive or negative infinity.\nIf T is an integer type, an InexactError is raised if x is not representable by T.\nx % T converts an integer x to a value of integer type T congruent to x modulo 2^n, where n is the number of bits in T. In other words, the binary representation is truncated to fit.\nThe Rounding functions take a type T as an optional argument. For example, round(Int,x) is a shorthand for Int(round(x)).","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The following examples show the different forms.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> Int8(127)\n127\n\njulia> Int8(128)\nERROR: InexactError: trunc(Int8, 128)\nStacktrace:\n[...]\n\njulia> Int8(127.0)\n127\n\njulia> Int8(3.14)\nERROR: InexactError: Int8(3.14)\nStacktrace:\n[...]\n\njulia> Int8(128.0)\nERROR: InexactError: Int8(128.0)\nStacktrace:\n[...]\n\njulia> 127 % Int8\n127\n\njulia> 128 % Int8\n-128\n\njulia> round(Int8,127.4)\n127\n\njulia> round(Int8,127.6)\nERROR: InexactError: Int8(128.0)\nStacktrace:\n[...]","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"See Conversion and Promotion for how to define your own conversions and promotions.","category":"page"},{"location":"manual/mathematical-operations/#Rounding-functions","page":"Mathematical Operations and Elementary Functions","title":"Rounding functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Description Return type\nround(x) round x to the nearest integer typeof(x)\nround(T, x) round x to the nearest integer T\nfloor(x) round x towards -Inf typeof(x)\nfloor(T, x) round x towards -Inf T\nceil(x) round x towards +Inf typeof(x)\nceil(T, x) round x towards +Inf T\ntrunc(x) round x towards zero typeof(x)\ntrunc(T, x) round x towards zero T","category":"page"},{"location":"manual/mathematical-operations/#Division-functions","page":"Mathematical Operations and Elementary Functions","title":"Division functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Description\ndiv(x, y), x÷y truncated division; quotient rounded towards zero\nfld(x, y) floored division; quotient rounded towards -Inf\ncld(x, y) ceiling division; quotient rounded towards +Inf\nrem(x, y), x%y remainder; satisfies x == div(x, y)*y + rem(x, y); sign matches x\nmod(x, y) modulus; satisfies x == fld(x, y)*y + mod(x, y); sign matches y\nmod1(x, y) mod with offset 1; returns r∈(0, y] for y>0 or r∈[y, 0) for y<0, where mod(r, y) == mod(x, y)\nmod2pi(x) modulus with respect to 2pi; 0 <= mod2pi(x) < 2pi\ndivrem(x, y) returns (div(x, y),rem(x, y))\nfldmod(x, y) returns (fld(x, y), mod(x, y))\ngcd(x, y...) greatest positive common divisor of x, y,...\nlcm(x, y...) least positive common multiple of x, y,...","category":"page"},{"location":"manual/mathematical-operations/#Sign-and-absolute-value-functions","page":"Mathematical Operations and Elementary Functions","title":"Sign and absolute value functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Description\nabs(x) a positive value with the magnitude of x\nabs2(x) the squared magnitude of x\nsign(x) indicates the sign of x, returning -1, 0, or +1\nsignbit(x) indicates whether the sign bit is on (true) or off (false)\ncopysign(x, y) a value with the magnitude of x and the sign of y\nflipsign(x, y) a value with the magnitude of x and the sign of x*y","category":"page"},{"location":"manual/mathematical-operations/#Powers,-logs-and-roots","page":"Mathematical Operations and Elementary Functions","title":"Powers, logs and roots","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Description\nsqrt(x), √x square root of x\ncbrt(x), ∛x cube root of x\nhypot(x, y) hypotenuse of right-angled triangle with other sides of length x and y\nexp(x) natural exponential function at x\nexpm1(x) accurate exp(x) - 1 for x near zero\nldexp(x, n) x * 2^n computed efficiently for integer values of n\nlog(x) natural logarithm of x\nlog(b, x) base b logarithm of x\nlog2(x) base 2 logarithm of x\nlog10(x) base 10 logarithm of x\nlog1p(x) accurate log(1 + x) for x near zero\nexponent(x) binary exponent of x\nsignificand(x) binary significand (a.k.a. mantissa) of a floating-point number x","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"For an overview of why functions like hypot, expm1, and log1p are necessary and useful, see John D. Cook's excellent pair of blog posts on the subject: expm1, log1p, erfc, and hypot.","category":"page"},{"location":"manual/mathematical-operations/#Trigonometric-and-hyperbolic-functions","page":"Mathematical Operations and Elementary Functions","title":"Trigonometric and hyperbolic functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"All the standard trigonometric and hyperbolic functions are also defined:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"sin cos tan cot sec csc\nsinh cosh tanh coth sech csch\nasin acos atan acot asec acsc\nasinh acosh atanh acoth asech acsch\nsinc cosc","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"These are all single-argument functions, with atan also accepting two arguments corresponding to a traditional atan2 function.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Additionally, sinpi(x) and cospi(x) are provided for more accurate computations of sin(pi * x) and cos(pi * x) respectively.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"In order to compute trigonometric functions with degrees instead of radians, suffix the function with d. For example, sind(x) computes the sine of x where x is specified in degrees. The complete list of trigonometric functions with degree variants is:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"sind cosd tand cotd secd cscd\nasind acosd atand acotd asecd acscd","category":"page"},{"location":"manual/mathematical-operations/#Special-functions","page":"Mathematical Operations and Elementary Functions","title":"Special functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Many other special mathematical functions are provided by the package SpecialFunctions.jl.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Calling-C-and-Fortran-Code","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Though most code can be written in Julia, there are many high-quality, mature libraries for numerical computing already written in C and Fortran. To allow easy use of this existing code, Julia makes it simple and efficient to call C and Fortran functions. Julia has a \"no boilerplate\" philosophy: functions can be called directly from Julia without any \"glue\" code, code generation, or compilation – even from the interactive prompt. This is accomplished just by making an appropriate call with the @ccall macro (or the less convenient ccall syntax, see the ccall syntax section).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The code to be called must be available as a shared library. Most C and Fortran libraries ship compiled as shared libraries already, but if you are compiling the code yourself using GCC (or Clang), you will need to use the -shared and -fPIC options. The machine instructions generated by Julia's JIT are the same as a native C call would be, so the resulting overhead is the same as calling a library function from C code. [1]","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"By default, Fortran compilers generate mangled names (for example, converting function names to lowercase or uppercase, often appending an underscore), and so to call a Fortran function you must pass the mangled identifier corresponding to the rule followed by your Fortran compiler. Also, when calling a Fortran function, all inputs must be passed as pointers to allocated values on the heap or stack. This applies not only to arrays and other mutable objects which are normally heap-allocated, but also to scalar values such as integers and floats which are normally stack-allocated and commonly passed in registers when using C or Julia calling conventions.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The syntax for @ccall to generate a call to the library function is:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":" @ccall library.function_name(argvalue1::argtype1, ...)::returntype\n @ccall function_name(argvalue1::argtype1, ...)::returntype\n @ccall $function_pointer(argvalue1::argtype1, ...)::returntype","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"where library is a string constant or literal (but see Non-constant Function Specifications below). The library may be omitted, in which case the function name is resolved in the current process. This form can be used to call C library functions, functions in the Julia runtime, or functions in an application linked to Julia. The full path to the library may also be specified. Alternatively, @ccall may also be used to call a function pointer $function_pointer, such as one returned by Libdl.dlsym. The argtypes corresponds to the C-function signature and the argvalues are the actual argument values to be passed to the function.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nSee below for how to map C types to Julia types.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"As a complete but simple example, the following calls the clock function from the standard C library on most Unix-derived systems:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> t = @ccall clock()::Int32\n2292761\n\njulia> typeof(t)\nInt32","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"clock takes no arguments and returns an Int32. To call the getenv function to get a pointer to the value of an environment variable, one makes a call like this:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> path = @ccall getenv(\"SHELL\"::Cstring)::Cstring\nCstring(@0x00007fff5fbffc45)\n\njulia> unsafe_string(path)\n\"/bin/bash\"","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In practice, especially when providing reusable functionality, one generally wraps @ccall uses in Julia functions that set up arguments and then check for errors in whatever manner the C or Fortran function specifies. And if an error occurs it is thrown as a normal Julia exception. This is especially important since C and Fortran APIs are notoriously inconsistent about how they indicate error conditions. For example, the getenv C library function is wrapped in the following Julia function, which is a simplified version of the actual definition from env.jl:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"function getenv(var::AbstractString)\n val = @ccall getenv(var::Cstring)::Cstring\n if val == C_NULL\n error(\"getenv: undefined variable: \", var)\n end\n return unsafe_string(val)\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The C getenv function indicates an error by returning C_NULL, but other standard C functions indicate errors in different ways, including by returning -1, 0, 1, and other special values. This wrapper throws an exception indicating the problem if the caller tries to get a non-existent environment variable:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> getenv(\"SHELL\")\n\"/bin/bash\"\n\njulia> getenv(\"FOOBAR\")\nERROR: getenv: undefined variable: FOOBAR","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Here is a slightly more complex example that discovers the local machine's hostname.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"function gethostname()\n hostname = Vector{UInt8}(undef, 256) # MAXHOSTNAMELEN\n err = @ccall gethostname(hostname::Ptr{UInt8}, sizeof(hostname)::Csize_t)::Int32\n Base.systemerror(\"gethostname\", err != 0)\n hostname[end] = 0 # ensure null-termination\n return GC.@preserve hostname unsafe_string(pointer(hostname))\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"This example first allocates an array of bytes. It then calls the C library function gethostname to populate the array with the hostname. Finally, it takes a pointer to the hostname buffer, and converts the pointer to a Julia string, assuming that it is a null-terminated C string.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"It is common for C libraries to use this pattern of requiring the caller to allocate memory to be passed to the callee and populated. Allocation of memory from Julia like this is generally accomplished by creating an uninitialized array and passing a pointer to its data to the C function. This is why we don't use the Cstring type here: as the array is uninitialized, it could contain null bytes. Converting to a Cstring as part of the @ccall checks for contained null bytes and could therefore throw a conversion error.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Dereferencing pointer(hostname) with unsafe_string is an unsafe operation as it requires access to the memory allocated for hostname that may have been in the meanwhile garbage collected. The macro GC.@preserve prevents this from happening and therefore accessing an invalid memory location.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Finally, here is an example of specifying a library via a path. We create a shared library with the following content","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"#include \n\nvoid say_y(int y)\n{\n printf(\"Hello from C: got y = %d.\\n\", y);\n}","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"and compile it with gcc -fPIC -shared -o mylib.so mylib.c. It can then be called by specifying the (absolute) path as the library name:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> @ccall \"./mylib.so\".say_y(5::Cint)::Cvoid\nHello from C: got y = 5.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Creating-C-Compatible-Julia-Function-Pointers","page":"Calling C and Fortran Code","title":"Creating C-Compatible Julia Function Pointers","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"It is possible to pass Julia functions to native C functions that accept function pointer arguments. For example, to match C prototypes of the form:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"typedef returntype (*functiontype)(argumenttype, ...)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The macro @cfunction generates the C-compatible function pointer for a call to a Julia function. The arguments to @cfunction are:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"A Julia function\nThe function's return type\nA tuple of input types, corresponding to the function signature","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nAs with @ccall, the return type and the input types must be literal constants.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nCurrently, only the platform-default C calling convention is supported. This means that @cfunction-generated pointers cannot be used in calls where WINAPI expects a stdcall function on 32-bit Windows, but can be used on WIN64 (where stdcall is unified with the C calling convention).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nCallback functions exposed via @cfunction should not throw errors, as that will return control to the Julia runtime unexpectedly and may leave the program in an undefined state.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"A classic example is the standard C library qsort function, declared as:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"void qsort(void *base, size_t nitems, size_t size,\n int (*compare)(const void*, const void*));","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The base argument is a pointer to an array of length nitems, with elements of size bytes each. compare is a callback function which takes pointers to two elements a and b and returns an integer less/greater than zero if a should appear before/after b (or zero if any order is permitted).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Now, suppose that we have a 1-d array A of values in Julia that we want to sort using the qsort function (rather than Julia's built-in sort function). Before we consider calling qsort and passing arguments, we need to write a comparison function:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> function mycompare(a, b)::Cint\n return (a < b) ? -1 : ((a > b) ? +1 : 0)\n end;","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"qsort expects a comparison function that return a C int, so we annotate the return type to be Cint.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In order to pass this function to C, we obtain its address using the macro @cfunction:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> mycompare_c = @cfunction(mycompare, Cint, (Ref{Cdouble}, Ref{Cdouble}));","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"@cfunction requires three arguments: the Julia function (mycompare), the return type (Cint), and a literal tuple of the input argument types, in this case to sort an array of Cdouble (Float64) elements.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The final call to qsort looks like this:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> A = [1.3, -2.7, 4.4, 3.1];\n\njulia> @ccall qsort(A::Ptr{Cdouble}, length(A)::Csize_t, sizeof(eltype(A))::Csize_t, mycompare_c::Ptr{Cvoid})::Cvoid\n\njulia> A\n4-element Vector{Float64}:\n -2.7\n 1.3\n 3.1\n 4.4","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"As the example shows, the original Julia array A has now been sorted: [-2.7, 1.3, 3.1, 4.4]. Note that Julia takes care of converting the array to a Ptr{Cdouble}), computing the size of the element type in bytes, and so on.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For fun, try inserting a println(\"mycompare($a, $b)\") line into mycompare, which will allow you to see the comparisons that qsort is performing (and to verify that it is really calling the Julia function that you passed to it).","category":"page"},{"location":"manual/calling-c-and-fortran-code/#mapping-c-types-to-julia","page":"Calling C and Fortran Code","title":"Mapping C Types to Julia","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"It is critical to exactly match the declared C type with its declaration in Julia. Inconsistencies can cause code that works correctly on one system to fail or produce indeterminate results on a different system.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Note that no C header files are used anywhere in the process of calling C functions: you are responsible for making sure that your Julia types and call signatures accurately reflect those in the C header file.[2]","category":"page"},{"location":"manual/calling-c-and-fortran-code/#automatic-type-conversion","page":"Calling C and Fortran Code","title":"Automatic Type Conversion","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Julia automatically inserts calls to the Base.cconvert function to convert each argument to the specified type. For example, the following call:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"@ccall \"libfoo\".foo(x::Int32, y::Float64)::Cvoid","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"will behave as if it were written like this:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"c_x = Base.cconvert(Int32, x)\nc_y = Base.cconvert(Float64, y)\nGC.@preserve c_x c_y begin\n @ccall \"libfoo\".foo(\n Base.unsafe_convert(Int32, c_x)::Int32,\n Base.unsafe_convert(Float64, c_y)::Float64\n )::Cvoid\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Base.cconvert normally just calls convert, but can be defined to return an arbitrary new object more appropriate for passing to C. This should be used to perform all allocations of memory that will be accessed by the C code. For example, this is used to convert an Array of objects (e.g. strings) to an array of pointers.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Base.unsafe_convert handles conversion to Ptr types. It is considered unsafe because converting an object to a native pointer can hide the object from the garbage collector, causing it to be freed prematurely.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Type-Correspondences","page":"Calling C and Fortran Code","title":"Type Correspondences","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"First, let's review some relevant Julia type terminology:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Syntax / Keyword Example Description\nmutable struct BitSet \"Leaf Type\" :: A group of related data that includes a type-tag, is managed by the Julia GC, and is defined by object-identity. The type parameters of a leaf type must be fully defined (no TypeVars are allowed) in order for the instance to be constructed.\nabstract type Any, AbstractArray{T, N}, Complex{T} \"Super Type\" :: A super-type (not a leaf-type) that cannot be instantiated, but can be used to describe a group of types.\nT{A} Vector{Int} \"Type Parameter\" :: A specialization of a type (typically used for dispatch or storage optimization).\n \"TypeVar\" :: The T in the type parameter declaration is referred to as a TypeVar (short for type variable).\nprimitive type Int, Float64 \"Primitive Type\" :: A type with no fields, but a size. It is stored and defined by-value.\nstruct Pair{Int, Int} \"Struct\" :: A type with all fields defined to be constant. It is defined by-value, and may be stored with a type-tag.\n ComplexF64 (isbits) \"Is-Bits\" :: A primitive type, or a struct type where all fields are other isbits types. It is defined by-value, and is stored without a type-tag.\nstruct ...; end nothing \"Singleton\" :: a Leaf Type or Struct with no fields.\n(...) or tuple(...) (1, 2, 3) \"Tuple\" :: an immutable data-structure similar to an anonymous struct type, or a constant array. Represented as either an array or a struct.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#man-bits-types","page":"Calling C and Fortran Code","title":"Bits Types","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"There are several special types to be aware of, as no other type can be defined to behave the same:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Float32\nExactly corresponds to the float type in C (or REAL*4 in Fortran).\nFloat64\nExactly corresponds to the double type in C (or REAL*8 in Fortran).\nComplexF32\nExactly corresponds to the complex float type in C (or COMPLEX*8 in Fortran).\nComplexF64\nExactly corresponds to the complex double type in C (or COMPLEX*16 in Fortran).\nSigned\nExactly corresponds to the signed type annotation in C (or any INTEGER type in Fortran). Any Julia type that is not a subtype of Signed is assumed to be unsigned.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Ref{T}\nBehaves like a Ptr{T} that can manage its memory via the Julia GC.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Array{T,N}\nWhen an array is passed to C as a Ptr{T} argument, it is not reinterpret-cast: Julia requires that the element type of the array matches T, and the address of the first element is passed.\nTherefore, if an Array contains data in the wrong format, it will have to be explicitly converted using a call such as trunc.(Int32, A).\nTo pass an array A as a pointer of a different type without converting the data beforehand (for example, to pass a Float64 array to a function that operates on uninterpreted bytes), you can declare the argument as Ptr{Cvoid}.\nIf an array of eltype Ptr{T} is passed as a Ptr{Ptr{T}} argument, Base.cconvert will attempt to first make a null-terminated copy of the array with each element replaced by its Base.cconvert version. This allows, for example, passing an argv pointer array of type Vector{String} to an argument of type Ptr{Ptr{Cchar}}.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"On all systems we currently support, basic C/C++ value types may be translated to Julia types as follows. Every C type also has a corresponding Julia type with the same name, prefixed by C. This can help when writing portable code (and remembering that an int in C is not the same as an Int in Julia).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"System Independent Types","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"C name Fortran name Standard Julia Alias Julia Base Type\nunsigned char CHARACTER Cuchar UInt8\nbool (_Bool in C99+) Cuchar UInt8\nshort INTEGER*2, LOGICAL*2 Cshort Int16\nunsigned short Cushort UInt16\nint, BOOL (C, typical) INTEGER*4, LOGICAL*4 Cint Int32\nunsigned int Cuint UInt32\nlong long INTEGER*8, LOGICAL*8 Clonglong Int64\nunsigned long long Culonglong UInt64\nintmax_t Cintmax_t Int64\nuintmax_t Cuintmax_t UInt64\nfloat REAL*4i Cfloat Float32\ndouble REAL*8 Cdouble Float64\ncomplex float COMPLEX*8 ComplexF32 Complex{Float32}\ncomplex double COMPLEX*16 ComplexF64 Complex{Float64}\nptrdiff_t Cptrdiff_t Int\nssize_t Cssize_t Int\nsize_t Csize_t UInt\nvoid Cvoid\nvoid and [[noreturn]] or _Noreturn Union{}\nvoid* Ptr{Cvoid} (or similarly Ref{Cvoid})\nT* (where T represents an appropriately defined type) Ref{T} (T may be safely mutated only if T is an isbits type)\nchar* (or char[], e.g. a string) CHARACTER*N Cstring if null-terminated, or Ptr{UInt8} if not\nchar** (or *char[]) Ptr{Ptr{UInt8}}\njl_value_t* (any Julia Type) Any\njl_value_t* const* (a reference to a Julia value) Ref{Any} (const, since mutation would require a write barrier, which is not possible to insert correctly)\nva_arg Not supported\n... (variadic function specification) T... (where T is one of the above types, when using the ccall function)\n... (variadic function specification) ; va_arg1::T, va_arg2::S, etc. (only supported with @ccall macro)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The Cstring type is essentially a synonym for Ptr{UInt8}, except the conversion to Cstring throws an error if the Julia string contains any embedded null characters (which would cause the string to be silently truncated if the C routine treats null as the terminator). If you are passing a char* to a C routine that does not assume null termination (e.g. because you pass an explicit string length), or if you know for certain that your Julia string does not contain null and want to skip the check, you can use Ptr{UInt8} as the argument type. Cstring can also be used as the ccall return type, but in that case it obviously does not introduce any extra checks and is only meant to improve the readability of the call.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"System Dependent Types","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"C name Standard Julia Alias Julia Base Type\nchar Cchar Int8 (x86, x86_64), UInt8 (powerpc, arm)\nlong Clong Int (UNIX), Int32 (Windows)\nunsigned long Culong UInt (UNIX), UInt32 (Windows)\nwchar_t Cwchar_t Int32 (UNIX), UInt16 (Windows)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nWhen calling Fortran, all inputs must be passed by pointers to heap- or stack-allocated values, so all type correspondences above should contain an additional Ptr{..} or Ref{..} wrapper around their type specification.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"warning: Warning\nFor string arguments (char*) the Julia type should be Cstring (if null-terminated data is expected), or either Ptr{Cchar} or Ptr{UInt8} otherwise (these two pointer types have the same effect), as described above, not String. Similarly, for array arguments (T[] or T*), the Julia type should again be Ptr{T}, not Vector{T}.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"warning: Warning\nJulia's Char type is 32 bits, which is not the same as the wide-character type (wchar_t or wint_t) on all platforms.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"warning: Warning\nA return type of Union{} means the function will not return, i.e., C++11 [[noreturn]] or C11 _Noreturn (e.g. jl_throw or longjmp). Do not use this for functions that return no value (void) but do return, for those, use Cvoid instead.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nFor wchar_t* arguments, the Julia type should be Cwstring (if the C routine expects a null-terminated string), or Ptr{Cwchar_t} otherwise. Note also that UTF-8 string data in Julia is internally null-terminated, so it can be passed to C functions expecting null-terminated data without making a copy (but using the Cwstring type will cause an error to be thrown if the string itself contains null characters).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nC functions that take an argument of type char** can be called by using a Ptr{Ptr{UInt8}} type within Julia. For example, C functions of the form:int main(int argc, char **argv);can be called via the following Julia code:argv = [ \"a.out\", \"arg1\", \"arg2\" ]\n@ccall main(length(argv)::Int32, argv::Ptr{Ptr{UInt8}})::Int32","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nFor Fortran functions taking variable length strings of type character(len=*) the string lengths are provided as hidden arguments. Type and position of these arguments in the list are compiler specific, where compiler vendors usually default to using Csize_t as type and append the hidden arguments at the end of the argument list. While this behaviour is fixed for some compilers (GNU), others optionally permit placing hidden arguments directly after the character argument (Intel, PGI). For example, Fortran subroutines of the formsubroutine test(str1, str2)\ncharacter(len=*) :: str1,str2can be called via the following Julia code, where the lengths are appendedstr1 = \"foo\"\nstr2 = \"bar\"\nccall(:test, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Csize_t, Csize_t),\n str1, str2, sizeof(str1), sizeof(str2))","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"warning: Warning\nFortran compilers may also add other hidden arguments for pointers, assumed-shape (:) and assumed-size (*) arrays. Such behaviour can be avoided by using ISO_C_BINDING and including bind(c) in the definition of the subroutine, which is strongly recommended for interoperable code. In this case, there will be no hidden arguments, at the cost of some language features (e.g. only character(len=1) will be permitted to pass strings).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nA C function declared to return Cvoid will return the value nothing in Julia.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Struct-Type-Correspondences","page":"Calling C and Fortran Code","title":"Struct Type Correspondences","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Composite types such as struct in C or TYPE in Fortran90 (or STRUCTURE / RECORD in some variants of F77), can be mirrored in Julia by creating a struct definition with the same field layout.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"When used recursively, isbits types are stored inline. All other types are stored as a pointer to the data. When mirroring a struct used by-value inside another struct in C, it is imperative that you do not attempt to manually copy the fields over, as this will not preserve the correct field alignment. Instead, declare an isbits struct type and use that instead. Unnamed structs are not possible in the translation to Julia.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Packed structs and union declarations are not supported by Julia.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"You can get an approximation of a union if you know, a priori, the field that will have the greatest size (potentially including padding). When translating your fields to Julia, declare the Julia field to be only of that type.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Arrays of parameters can be expressed with NTuple. For example, the struct in C notation is written as","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"struct B {\n int A[3];\n};\n\nb_a_2 = B.A[2];","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"can be written in Julia as","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"struct B\n A::NTuple{3, Cint}\nend\n\nb_a_2 = B.A[3] # note the difference in indexing (1-based in Julia, 0-based in C)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Arrays of unknown size (C99-compliant variable length structs specified by [] or [0]) are not directly supported. Often the best way to deal with these is to deal with the byte offsets directly. For example, if a C library declared a proper string type and returned a pointer to it:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"struct String {\n int strlen;\n char data[];\n};","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In Julia, we can access the parts independently to make a copy of that string:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"str = from_c::Ptr{Cvoid}\nlen = unsafe_load(Ptr{Cint}(str))\nunsafe_string(str + Core.sizeof(Cint), len)","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Type-Parameters","page":"Calling C and Fortran Code","title":"Type Parameters","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The type arguments to @ccall and @cfunction are evaluated statically, when the method containing the usage is defined. They therefore must take the form of a literal tuple, not a variable, and cannot reference local variables.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"This may sound like a strange restriction, but remember that since C is not a dynamic language like Julia, its functions can only accept argument types with a statically-known, fixed signature.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"However, while the type layout must be known statically to compute the intended C ABI, the static parameters of the function are considered to be part of this static environment. The static parameters of the function may be used as type parameters in the call signature, as long as they don't affect the layout of the type. For example, f(x::T) where {T} = @ccall valid(x::Ptr{T})::Ptr{T} is valid, since Ptr is always a word-size primitive type. But, g(x::T) where {T} = @ccall notvalid(x::T)::T is not valid, since the type layout of T is not known statically.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#SIMD-Values","page":"Calling C and Fortran Code","title":"SIMD Values","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Note: This feature is currently implemented on 64-bit x86 and AArch64 platforms only.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"If a C/C++ routine has an argument or return value that is a native SIMD type, the corresponding Julia type is a homogeneous tuple of VecElement that naturally maps to the SIMD type. Specifically:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The tuple must be the same size as the SIMD type. For example, a tuple representing an __m128 on x86 must have a size of 16 bytes.\nThe element type of the tuple must be an instance of VecElement{T} where T is a primitive type that is 1, 2, 4 or 8 bytes.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For instance, consider this C routine that uses AVX intrinsics:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"#include \n\n__m256 dist( __m256 a, __m256 b ) {\n return _mm256_sqrt_ps(_mm256_add_ps(_mm256_mul_ps(a, a),\n _mm256_mul_ps(b, b)));\n}","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The following Julia code calls dist using ccall:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"const m256 = NTuple{8, VecElement{Float32}}\n\na = m256(ntuple(i -> VecElement(sin(Float32(i))), 8))\nb = m256(ntuple(i -> VecElement(cos(Float32(i))), 8))\n\nfunction call_dist(a::m256, b::m256)\n @ccall \"libdist\".dist(a::m256, b::m256)::m256\nend\n\nprintln(call_dist(a,b))","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The host machine must have the requisite SIMD registers. For example, the code above will not work on hosts without AVX support.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Memory-Ownership","page":"Calling C and Fortran Code","title":"Memory Ownership","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"malloc/free","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Memory allocation and deallocation of such objects must be handled by calls to the appropriate cleanup routines in the libraries being used, just like in any C program. Do not try to free an object received from a C library with Libc.free in Julia, as this may result in the free function being called via the wrong library and cause the process to abort. The reverse (passing an object allocated in Julia to be freed by an external library) is equally invalid.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#When-to-use-T,-Ptr{T}-and-Ref{T}","page":"Calling C and Fortran Code","title":"When to use T, Ptr{T} and Ref{T}","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In Julia code wrapping calls to external C routines, ordinary (non-pointer) data should be declared to be of type T inside the @ccall, as they are passed by value. For C code accepting pointers, Ref{T} should generally be used for the types of input arguments, allowing the use of pointers to memory managed by either Julia or C through the implicit call to Base.cconvert. In contrast, pointers returned by the C function called should be declared to be of the output type Ptr{T}, reflecting that the memory pointed to is managed by C only. Pointers contained in C structs should be represented as fields of type Ptr{T} within the corresponding Julia struct types designed to mimic the internal structure of corresponding C structs.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In Julia code wrapping calls to external Fortran routines, all input arguments should be declared as of type Ref{T}, as Fortran passes all variables by pointers to memory locations. The return type should either be Cvoid for Fortran subroutines, or a T for Fortran functions returning the type T.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Mapping-C-Functions-to-Julia","page":"Calling C and Fortran Code","title":"Mapping C Functions to Julia","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/#@ccall-/-@cfunction-argument-translation-guide","page":"Calling C and Fortran Code","title":"@ccall / @cfunction argument translation guide","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For translating a C argument list to Julia:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"T, where T is one of the primitive types: char, int, long, short, float, double, complex, enum or any of their typedef equivalents\nT, where T is an equivalent Julia Bits Type (per the table above)\nif T is an enum, the argument type should be equivalent to Cint or Cuint\nargument value will be copied (passed by value)\nstruct T (including typedef to a struct)\nT, where T is a Julia leaf type\nargument value will be copied (passed by value)\nvoid*\ndepends on how this parameter is used, first translate this to the intended pointer type, then determine the Julia equivalent using the remaining rules in this list\nthis argument may be declared as Ptr{Cvoid} if it really is just an unknown pointer\njl_value_t*\nAny\nargument value must be a valid Julia object\njl_value_t* const*\nRef{Any}\nargument list must be a valid Julia object (or C_NULL)\ncannot be used for an output parameter, unless the user is able to separately arrange for the object to be GC-preserved\nT*\nRef{T}, where T is the Julia type corresponding to T\nargument value will be copied if it is an inlinealloc type (which includes isbits otherwise, the value must be a valid Julia object\nT (*)(...) (e.g. a pointer to a function)\nPtr{Cvoid} (you may need to use @cfunction explicitly to create this pointer)\n... (e.g. a vararg)\n[for ccall]: T..., where T is the single Julia type of all remaining arguments\n[for @ccall]: ; va_arg1::T, va_arg2::S, etc, where T and S are the Julia type (i.e. separate the regular arguments from varargs with a ;)\ncurrently unsupported by @cfunction\nva_arg\nnot supported by ccall or @cfunction","category":"page"},{"location":"manual/calling-c-and-fortran-code/#@ccall-/-@cfunction-return-type-translation-guide","page":"Calling C and Fortran Code","title":"@ccall / @cfunction return type translation guide","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For translating a C return type to Julia:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"void\nCvoid (this will return the singleton instance nothing::Cvoid)\nT, where T is one of the primitive types: char, int, long, short, float, double, complex, enum or any of their typedef equivalents\nT, where T is an equivalent Julia Bits Type (per the table above)\nif T is an enum, the argument type should be equivalent to Cint or Cuint\nargument value will be copied (returned by-value)\nstruct T (including typedef to a struct)\nT, where T is a Julia Leaf Type\nargument value will be copied (returned by-value)\nvoid*\ndepends on how this parameter is used, first translate this to the intended pointer type, then determine the Julia equivalent using the remaining rules in this list\nthis argument may be declared as Ptr{Cvoid} if it really is just an unknown pointer\njl_value_t*\nAny\nargument value must be a valid Julia object\njl_value_t**\nPtr{Any} (Ref{Any} is invalid as a return type)\nT*\nIf the memory is already owned by Julia, or is an isbits type, and is known to be non-null:\nRef{T}, where T is the Julia type corresponding to T\na return type of Ref{Any} is invalid, it should either be Any (corresponding to jl_value_t*) or Ptr{Any} (corresponding to jl_value_t**)\nC MUST NOT modify the memory returned via Ref{T} if T is an isbits type\nIf the memory is owned by C:\nPtr{T}, where T is the Julia type corresponding to T\nT (*)(...) (e.g. a pointer to a function)\nPtr{Cvoid} to call this directly from Julia you will need to pass this as the first argument to @ccall. See Indirect Calls.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Passing-Pointers-for-Modifying-Inputs","page":"Calling C and Fortran Code","title":"Passing Pointers for Modifying Inputs","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Because C doesn't support multiple return values, often C functions will take pointers to data that the function will modify. To accomplish this within a @ccall, you need to first encapsulate the value inside a Ref{T} of the appropriate type. When you pass this Ref object as an argument, Julia will automatically pass a C pointer to the encapsulated data:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"width = Ref{Cint}(0)\nrange = Ref{Cfloat}(0)\n@ccall foo(width::Ref{Cint}, range::Ref{Cfloat})::Cvoid","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Upon return, the contents of width and range can be retrieved (if they were changed by foo) by width[] and range[]; that is, they act like zero-dimensional arrays.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#C-Wrapper-Examples","page":"Calling C and Fortran Code","title":"C Wrapper Examples","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Let's start with a simple example of a C wrapper that returns a Ptr type:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"mutable struct gsl_permutation\nend\n\n# The corresponding C signature is\n# gsl_permutation * gsl_permutation_alloc (size_t n);\nfunction permutation_alloc(n::Integer)\n output_ptr = @ccall \"libgsl\".gsl_permutation_alloc(n::Csize_t)::Ptr{gsl_permutation}\n if output_ptr == C_NULL # Could not allocate memory\n throw(OutOfMemoryError())\n end\n return output_ptr\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The GNU Scientific Library (here assumed to be accessible through :libgsl) defines an opaque pointer, gsl_permutation *, as the return type of the C function gsl_permutation_alloc. As user code never has to look inside the gsl_permutation struct, the corresponding Julia wrapper simply needs a new type declaration, gsl_permutation, that has no internal fields and whose sole purpose is to be placed in the type parameter of a Ptr type. The return type of the ccall is declared as Ptr{gsl_permutation}, since the memory allocated and pointed to by output_ptr is controlled by C.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The input n is passed by value, and so the function's input signature is simply declared as ::Csize_t without any Ref or Ptr necessary. (If the wrapper was calling a Fortran function instead, the corresponding function input signature would instead be ::Ref{Csize_t}, since Fortran variables are passed by pointers.) Furthermore, n can be any type that is convertible to a Csize_t integer; the ccall implicitly calls Base.cconvert(Csize_t, n).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Here is a second example wrapping the corresponding destructor:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"# The corresponding C signature is\n# void gsl_permutation_free (gsl_permutation * p);\nfunction permutation_free(p::Ptr{gsl_permutation})\n @ccall \"libgsl\".gsl_permutation_free(p::Ptr{gsl_permutation})::Cvoid\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Here is a third example passing Julia arrays:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"# The corresponding C signature is\n# int gsl_sf_bessel_Jn_array (int nmin, int nmax, double x,\n# double result_array[])\nfunction sf_bessel_Jn_array(nmin::Integer, nmax::Integer, x::Real)\n if nmax < nmin\n throw(DomainError())\n end\n result_array = Vector{Cdouble}(undef, nmax - nmin + 1)\n errorcode = @ccall \"libgsl\".gsl_sf_bessel_Jn_array(\n nmin::Cint, nmax::Cint, x::Cdouble, result_array::Ref{Cdouble})::Cint\n if errorcode != 0\n error(\"GSL error code $errorcode\")\n end\n return result_array\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The C function wrapped returns an integer error code; the results of the actual evaluation of the Bessel J function populate the Julia array result_array. This variable is declared as a Ref{Cdouble}, since its memory is allocated and managed by Julia. The implicit call to Base.cconvert(Ref{Cdouble}, result_array) unpacks the Julia pointer to a Julia array data structure into a form understandable by C.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Fortran-Wrapper-Example","page":"Calling C and Fortran Code","title":"Fortran Wrapper Example","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The following example utilizes ccall to call a function in a common Fortran library (libBLAS) to compute a dot product. Notice that the argument mapping is a bit different here than above, as we need to map from Julia to Fortran. On every argument type, we specify Ref or Ptr. This mangling convention may be specific to your Fortran compiler and operating system and is likely undocumented. However, wrapping each in a Ref (or Ptr, where equivalent) is a frequent requirement of Fortran compiler implementations:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"function compute_dot(DX::Vector{Float64}, DY::Vector{Float64})\n @assert length(DX) == length(DY)\n n = length(DX)\n incx = incy = 1\n product = @ccall \"libLAPACK\".ddot(\n n::Ref{Int32}, DX::Ptr{Float64}, incx::Ref{Int32}, DY::Ptr{Float64}, incy::Ref{Int32})::Float64\n return product\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Garbage-Collection-Safety","page":"Calling C and Fortran Code","title":"Garbage Collection Safety","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"When passing data to a @ccall, it is best to avoid using the pointer function. Instead define a Base.cconvert method and pass the variables directly to the @ccall. @ccall automatically arranges that all of its arguments will be preserved from garbage collection until the call returns. If a C API will store a reference to memory allocated by Julia, after the @ccall returns, you must ensure that the object remains visible to the garbage collector. The suggested way to do this is to make a global variable of type Array{Ref,1} to hold these values until the C library notifies you that it is finished with them.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Whenever you have created a pointer to Julia data, you must ensure the original data exists until you have finished using the pointer. Many methods in Julia such as unsafe_load and String make copies of data instead of taking ownership of the buffer, so that it is safe to free (or alter) the original data without affecting Julia. A notable exception is unsafe_wrap which, for performance reasons, shares (or can be told to take ownership of) the underlying buffer.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The garbage collector does not guarantee any order of finalization. That is, if a contained a reference to b and both a and b are due for garbage collection, there is no guarantee that b would be finalized after a. If proper finalization of a depends on b being valid, it must be handled in other ways.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Non-constant-Function-Specifications","page":"Calling C and Fortran Code","title":"Non-constant Function Specifications","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In some cases, the exact name or path of the needed library is not known in advance and must be computed at run time. To handle such cases, the library component specification can be a function call, e.g. find_blas().dgemm. The call expression will be executed when the ccall itself is executed. However, it is assumed that the library location does not change once it is determined, so the result of the call can be cached and reused. Therefore, the number of times the expression executes is unspecified, and returning different values for multiple calls results in unspecified behavior.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"If even more flexibility is needed, it is possible to use computed values as function names by staging through eval as follows:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"@eval @ccall \"lib\".$(string(\"a\", \"b\"))()::Cint","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"This expression constructs a name using string, then substitutes this name into a new @ccall expression, which is then evaluated. Keep in mind that eval only operates at the top level, so within this expression local variables will not be available (unless their values are substituted with $). For this reason, eval is typically only used to form top-level definitions, for example when wrapping libraries that contain many similar functions. A similar example can be constructed for @cfunction.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep reading. The next section discusses how to use indirect calls to efficiently achieve a similar effect.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Indirect-Calls","page":"Calling C and Fortran Code","title":"Indirect Calls","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The first argument to @ccall can also be an expression evaluated at run time. In this case, the expression must evaluate to a Ptr, which will be used as the address of the native function to call. This behavior occurs when the first @ccall argument contains references to non-constants, such as local variables, function arguments, or non-constant globals.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For example, you might look up the function via dlsym, then cache it in a shared reference for that session. For example:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"macro dlsym(lib, func)\n z = Ref{Ptr{Cvoid}}(C_NULL)\n quote\n let zlocal = $z[]\n if zlocal == C_NULL\n zlocal = dlsym($(esc(lib))::Ptr{Cvoid}, $(esc(func)))::Ptr{Cvoid}\n $z[] = zlocal\n end\n zlocal\n end\n end\nend\n\nmylibvar = Libdl.dlopen(\"mylib\")\n@ccall $(@dlsym(mylibvar, \"myfunc\"))()::Cvoid","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Closure-cfunctions","page":"Calling C and Fortran Code","title":"Closure cfunctions","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The first argument to @cfunction can be marked with a $, in which case the return value will instead be a struct CFunction which closes over the argument. You must ensure that this return object is kept alive until all uses of it are done. The contents and code at the cfunction pointer will be erased via a finalizer when this reference is dropped and atexit. This is not usually needed, since this functionality is not present in C, but can be useful for dealing with ill-designed APIs which don't provide a separate closure environment parameter.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"function qsort(a::Vector{T}, cmp) where T\n isbits(T) || throw(ArgumentError(\"this method can only qsort isbits arrays\"))\n callback = @cfunction $cmp Cint (Ref{T}, Ref{T})\n # Here, `callback` isa Base.CFunction, which will be converted to Ptr{Cvoid}\n # (and protected against finalization) by the ccall\n @ccall qsort(a::Ptr{T}, length(a)::Csize_t, Base.elsize(a)::Csize_t, callback::Ptr{Cvoid})\n # We could instead use:\n # GC.@preserve callback begin\n # use(Base.unsafe_convert(Ptr{Cvoid}, callback))\n # end\n # if we needed to use it outside of a `ccall`\n return a\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nClosure @cfunction relies on LLVM trampolines, which are not available on all platforms (for example ARM and PowerPC).","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Closing-a-Library","page":"Calling C and Fortran Code","title":"Closing a Library","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"It is sometimes useful to close (unload) a library so that it can be reloaded. For instance, when developing C code for use with Julia, one may need to compile, call the C code from Julia, then close the library, make an edit, recompile, and load in the new changes. One can either restart Julia or use the Libdl functions to manage the library explicitly, such as:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"lib = Libdl.dlopen(\"./my_lib.so\") # Open the library explicitly.\nsym = Libdl.dlsym(lib, :my_fcn) # Get a symbol for the function to call.\n@ccall $sym(...) # Use the pointer `sym` instead of the library.symbol tuple.\nLibdl.dlclose(lib) # Close the library explicitly.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Note that when using @ccall with the input (e.g., @ccall \"./my_lib.so\".my_fcn(...)::Cvoid), the library is opened implicitly and it may not be explicitly closed.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Variadic-function-calls","page":"Calling C and Fortran Code","title":"Variadic function calls","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"To call variadic C functions a semicolon can be used in the argument list to separate required arguments from variadic arguments. An example with the printf function is given below:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> @ccall printf(\"%s = %d\\n\"::Cstring ; \"foo\"::Cstring, foo::Cint)::Cint\nfoo = 3\n8","category":"page"},{"location":"manual/calling-c-and-fortran-code/#ccall-interface","page":"Calling C and Fortran Code","title":"ccall interface","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"There is another alternative interface to @ccall. This interface is slightly less convenient but it does allow one to specify a calling convention.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The arguments to ccall are:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"A (:function, \"library\") pair (most common),\nOR\na :function name symbol or \"function\" name string (for symbols in the current process or libc),\nOR\na function pointer (for example, from dlsym).\nThe function's return type\nA tuple of input types, corresponding to the function signature. One common mistake is forgetting that a 1-tuple of argument types must be written with a trailing comma.\nThe actual argument values to be passed to the function, if any; each is a separate parameter.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nThe (:function, \"library\") pair, return type, and input types must be literal constants (i.e., they can't be variables, but see Non-constant Function Specifications).The remaining parameters are evaluated at compile-time, when the containing method is defined.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"A table of translations between the macro and function interfaces is given below.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"@ccall ccall\n@ccall clock()::Int32 ccall(:clock, Int32, ())\n@ccall f(a::Cint)::Cint ccall(:a, Cint, (Cint,), a)\n@ccall \"mylib\".f(a::Cint, b::Cdouble)::Cvoid ccall((:f, \"mylib\"), Cvoid, (Cint, Cdouble), (a, b))\n@ccall $fptr.f()::Cvoid ccall(fptr, f, Cvoid, ())\n@ccall printf(\"%s = %d\\n\"::Cstring ; \"foo\"::Cstring, foo::Cint)::Cint \n@ccall printf(\"%s = %s\\n\"::Cstring ; \"2 + 2\"::Cstring, \"5\"::Cstring)::Cint ccall(:printf, Cint, (Cstring, Cstring...), \"%s = %s\\n\", \"2 + 2\", \"5\")\n ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn))","category":"page"},{"location":"manual/calling-c-and-fortran-code/#calling-convention","page":"Calling C and Fortran Code","title":"Calling Convention","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The second argument to ccall (immediately preceding return type) can optionally be a calling convention specifier (the @ccall macro currently does not support giving a calling convention). Without any specifier, the platform-default C calling convention is used. Other supported conventions are: stdcall, cdecl, fastcall, and thiscall (no-op on 64-bit Windows). For example (from base/libc.jl) we see the same gethostnameccall as above, but with the correct signature for Windows:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"hn = Vector{UInt8}(undef, 256)\nerr = ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn))","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For more information, please see the LLVM Language Reference.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"There is one additional special calling convention llvmcall, which allows inserting calls to LLVM intrinsics directly. This can be especially useful when targeting unusual platforms such as GPGPUs. For example, for CUDA, we need to be able to read the thread index:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"ccall(\"llvm.nvvm.read.ptx.sreg.tid.x\", llvmcall, Int32, ())","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"As with any ccall, it is essential to get the argument signature exactly correct. Also, note that there is no compatibility layer that ensures the intrinsic makes sense and works on the current target, unlike the equivalent Julia functions exposed by Core.Intrinsics.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Accessing-Global-Variables","page":"Calling C and Fortran Code","title":"Accessing Global Variables","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Global variables exported by native libraries can be accessed by name using the cglobal function. The arguments to cglobal are a symbol specification identical to that used by ccall, and a type describing the value stored in the variable:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> cglobal((:errno, :libc), Int32)\nPtr{Int32} @0x00007f418d0816b8","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The result is a pointer giving the address of the value. The value can be manipulated through this pointer using unsafe_load and unsafe_store!.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nThis errno symbol may not be found in a library named \"libc\", as this is an implementation detail of your system compiler. Typically standard library symbols should be accessed just by name, allowing the compiler to fill in the correct one. Also, however, the errno symbol shown in this example is special in most compilers, and so the value seen here is probably not what you expect or want. Compiling the equivalent code in C on any multi-threaded-capable system would typically actually call a different function (via macro preprocessor overloading), and may give a different result than the legacy value printed here.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Accessing-Data-through-a-Pointer","page":"Calling C and Fortran Code","title":"Accessing Data through a Pointer","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The following methods are described as \"unsafe\" because a bad pointer or type declaration can cause Julia to terminate abruptly.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Given a Ptr{T}, the contents of type T can generally be copied from the referenced memory into a Julia object using unsafe_load(ptr, [index]). The index argument is optional (default is 1), and follows the Julia-convention of 1-based indexing. This function is intentionally similar to the behavior of getindex and setindex! (e.g. [] access syntax).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The return value will be a new object initialized to contain a copy of the contents of the referenced memory. The referenced memory can safely be freed or released.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"If T is Any, then the memory is assumed to contain a reference to a Julia object (a jl_value_t*), the result will be a reference to this object, and the object will not be copied. You must be careful in this case to ensure that the object was always visible to the garbage collector (pointers do not count, but the new reference does) to ensure the memory is not prematurely freed. Note that if the object was not originally allocated by Julia, the new object will never be finalized by Julia's garbage collector. If the Ptr itself is actually a jl_value_t*, it can be converted back to a Julia object reference by unsafe_pointer_to_objref(ptr). (Julia values v can be converted to jl_value_t* pointers, as Ptr{Cvoid}, by calling pointer_from_objref(v).)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The reverse operation (writing data to a Ptr{T}), can be performed using unsafe_store!(ptr, value, [index]). Currently, this is only supported for primitive types or other pointer-free (isbits) immutable struct types.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Any operation that throws an error is probably currently unimplemented and should be posted as a bug so that it can be resolved.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"If the pointer of interest is a plain-data array (primitive type or immutable struct), the function unsafe_wrap(Array, ptr,dims, own = false) may be more useful. The final parameter should be true if Julia should \"take ownership\" of the underlying buffer and call free(ptr) when the returned Array object is finalized. If the own parameter is omitted or false, the caller must ensure the buffer remains in existence until all access is complete.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Arithmetic on the Ptr type in Julia (e.g. using +) does not behave the same as C's pointer arithmetic. Adding an integer to a Ptr in Julia always moves the pointer by some number of bytes, not elements. This way, the address values obtained from pointer arithmetic do not depend on the element types of pointers.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Thread-safety","page":"Calling C and Fortran Code","title":"Thread-safety","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Some C libraries execute their callbacks from a different thread, and since Julia isn't thread-safe you'll need to take some extra precautions. In particular, you'll need to set up a two-layered system: the C callback should only schedule (via Julia's event loop) the execution of your \"real\" callback. To do this, create an AsyncCondition object and wait on it:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"cond = Base.AsyncCondition()\nwait(cond)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The callback you pass to C should only execute a ccall to :uv_async_send, passing cond.handle as the argument, taking care to avoid any allocations or other interactions with the Julia runtime.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Note that events may be coalesced, so multiple calls to uv_async_send may result in a single wakeup notification to the condition.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#More-About-Callbacks","page":"Calling C and Fortran Code","title":"More About Callbacks","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For more details on how to pass callbacks to C libraries, see this blog post.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#C","page":"Calling C and Fortran Code","title":"C++","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For tools to create C++ bindings, see the CxxWrap package.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"[1]: Non-library function calls in both C and Julia can be inlined and thus may have even less overhead than calls to shared library functions. The point above is that the cost of actually doing foreign function call is about the same as doing a call in either native language.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"[2]: The Clang package can be used to auto-generate Julia code from a C header file.","category":"page"},{"location":"base/libc/#C-Standard-Library","page":"C Standard Library","title":"C Standard Library","text":"","category":"section"},{"location":"base/libc/","page":"C Standard Library","title":"C Standard Library","text":"Base.Libc.malloc\nBase.Libc.calloc\nBase.Libc.realloc\nBase.Libc.memcpy\nBase.Libc.memmove\nBase.Libc.memset\nBase.Libc.memcmp\nBase.Libc.free\nBase.Libc.errno\nBase.Libc.strerror\nBase.Libc.GetLastError\nBase.Libc.FormatMessage\nBase.Libc.time(::Base.Libc.TmStruct)\nBase.Libc.strftime\nBase.Libc.strptime\nBase.Libc.TmStruct\nBase.Libc.FILE\nBase.Libc.flush_cstdio\nBase.Libc.systemsleep\nBase.Libc.mkfifo","category":"page"},{"location":"base/libc/#Base.Libc.malloc","page":"C Standard Library","title":"Base.Libc.malloc","text":"malloc(size::Integer) -> Ptr{Cvoid}\n\nCall malloc from the C standard library.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.calloc","page":"C Standard Library","title":"Base.Libc.calloc","text":"calloc(num::Integer, size::Integer) -> Ptr{Cvoid}\n\nCall calloc from the C standard library.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.realloc","page":"C Standard Library","title":"Base.Libc.realloc","text":"realloc(addr::Ptr, size::Integer) -> Ptr{Cvoid}\n\nCall realloc from the C standard library.\n\nSee warning in the documentation for free regarding only using this on memory originally obtained from malloc.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.memcpy","page":"C Standard Library","title":"Base.memcpy","text":"memcpy(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid}\n\nCall memcpy from the C standard library.\n\ncompat: Julia 1.10\nSupport for memcpy requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.memmove","page":"C Standard Library","title":"Base.memmove","text":"memmove(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid}\n\nCall memmove from the C standard library.\n\ncompat: Julia 1.10\nSupport for memmove requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.memset","page":"C Standard Library","title":"Base.memset","text":"memset(dst::Ptr, val, n::Integer) -> Ptr{Cvoid}\n\nCall memset from the C standard library.\n\ncompat: Julia 1.10\nSupport for memset requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.memcmp","page":"C Standard Library","title":"Base.memcmp","text":"memcmp(a::Ptr, b::Ptr, n::Integer) -> Int\n\nCall memcmp from the C standard library.\n\ncompat: Julia 1.10\nSupport for memcmp requires at least Julia 1.9.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.free","page":"C Standard Library","title":"Base.Libc.free","text":"free(addr::Ptr)\n\nCall free from the C standard library. Only use this on memory obtained from malloc, not on pointers retrieved from other C libraries. Ptr objects obtained from C libraries should be freed by the free functions defined in that library, to avoid assertion failures if multiple libc libraries exist on the system.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.errno","page":"C Standard Library","title":"Base.Libc.errno","text":"errno([code])\n\nGet the value of the C library's errno. If an argument is specified, it is used to set the value of errno.\n\nThe value of errno is only valid immediately after a ccall to a C library routine that sets it. Specifically, you cannot call errno at the next prompt in a REPL, because lots of code is executed between prompts.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.strerror","page":"C Standard Library","title":"Base.Libc.strerror","text":"strerror(n=errno())\n\nConvert a system call error code to a descriptive string\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.GetLastError","page":"C Standard Library","title":"Base.Libc.GetLastError","text":"GetLastError()\n\nCall the Win32 GetLastError function [only available on Windows].\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.FormatMessage","page":"C Standard Library","title":"Base.Libc.FormatMessage","text":"FormatMessage(n=GetLastError())\n\nConvert a Win32 system call error code to a descriptive string [only available on Windows].\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.time-Tuple{Base.Libc.TmStruct}","page":"C Standard Library","title":"Base.Libc.time","text":"time(t::TmStruct) -> Float64\n\nConverts a TmStruct struct to a number of seconds since the epoch.\n\n\n\n\n\n","category":"method"},{"location":"base/libc/#Base.Libc.strftime","page":"C Standard Library","title":"Base.Libc.strftime","text":"strftime([format], time)\n\nConvert time, given as a number of seconds since the epoch or a TmStruct, to a formatted string using the given format. Supported formats are the same as those in the standard C library.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.strptime","page":"C Standard Library","title":"Base.Libc.strptime","text":"strptime([format], timestr)\n\nParse a formatted time string into a TmStruct giving the seconds, minute, hour, date, etc. Supported formats are the same as those in the standard C library. On some platforms, timezones will not be parsed correctly. If the result of this function will be passed to time to convert it to seconds since the epoch, the isdst field should be filled in manually. Setting it to -1 will tell the C library to use the current system settings to determine the timezone.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.TmStruct","page":"C Standard Library","title":"Base.Libc.TmStruct","text":"TmStruct([seconds])\n\nConvert a number of seconds since the epoch to broken-down format, with fields sec, min, hour, mday, month, year, wday, yday, and isdst.\n\n\n\n\n\n","category":"type"},{"location":"base/libc/#Base.Libc.FILE","page":"C Standard Library","title":"Base.Libc.FILE","text":"FILE(::Ptr)\nFILE(::IO)\n\nA libc FILE*, representing an opened file.\n\nIt can be passed as a Ptr{FILE} argument to ccall and also supports seek, position and close.\n\nA FILE can be constructed from an ordinary IO object, provided it is an open file. It must be closed afterward.\n\nExamples\n\njulia> using Base.Libc\n\njulia> mktemp() do _, io\n # write to the temporary file using `puts(char*, FILE*)` from libc\n file = FILE(io)\n ccall(:fputs, Cint, (Cstring, Ptr{FILE}), \"hello world\", file)\n close(file)\n # read the file again\n seek(io, 0)\n read(io, String)\n end\n\"hello world\"\n\n\n\n\n\n","category":"type"},{"location":"base/libc/#Base.Libc.flush_cstdio","page":"C Standard Library","title":"Base.Libc.flush_cstdio","text":"flush_cstdio()\n\nFlushes the C stdout and stderr streams (which may have been written to by external C code).\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.systemsleep","page":"C Standard Library","title":"Base.Libc.systemsleep","text":"systemsleep(s::Real)\n\nSuspends execution for s seconds. This function does not yield to Julia's scheduler and therefore blocks the Julia thread that it is running on for the duration of the sleep time.\n\nSee also sleep.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.mkfifo","page":"C Standard Library","title":"Base.Libc.mkfifo","text":"mkfifo(path::AbstractString, [mode::Integer]) -> path\n\nMake a FIFO special file (a named pipe) at path. Return path as-is on success.\n\nmkfifo is supported only in Unix platforms.\n\ncompat: Julia 1.11\nmkfifo requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/DelimitedFiles/#Delimited-Files","page":"Delimited Files","title":"Delimited Files","text":"","category":"section"},{"location":"stdlib/DelimitedFiles/","page":"Delimited Files","title":"Delimited Files","text":"DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type, ::AbstractChar)\nDelimitedFiles.readdlm(::Any, ::AbstractChar, ::AbstractChar)\nDelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type)\nDelimitedFiles.readdlm(::Any, ::AbstractChar)\nDelimitedFiles.readdlm(::Any, ::Type)\nDelimitedFiles.readdlm(::Any)\nDelimitedFiles.writedlm","category":"page"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, AbstractChar, Type, AbstractChar}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, delim::AbstractChar, T::Type, eol::AbstractChar; header=false, skipstart=0, skipblanks=true, use_mmap, quotes=true, dims, comments=false, comment_char='#')\n\nRead a matrix from the source where each line (separated by eol) gives one row, with elements separated by the given delimiter. The source can be a text file, stream or byte array. Memory mapped files can be used by passing the byte array representation of the mapped segment as source.\n\nIf T is a numeric type, the result is an array of that type, with any non-numeric elements as NaN for floating-point types, or zero. Other useful values of T include String, AbstractString, and Any.\n\nIf header is true, the first row of data will be read as header and the tuple (data_cells, header_cells) is returned instead of only data_cells.\n\nSpecifying skipstart will ignore the corresponding number of initial lines from the input.\n\nIf skipblanks is true, blank lines in the input will be ignored.\n\nIf use_mmap is true, the file specified by source is memory mapped for potential speedups if the file is large. Default is false. On a Windows filesystem, use_mmap should not be set to true unless the file is only read once and is also not written to. Some edge cases exist where an OS is Unix-like but the filesystem is Windows-like.\n\nIf quotes is true, columns enclosed within double-quote (\") characters are allowed to contain new lines and column delimiters. Double-quote characters within a quoted field must be escaped with another double-quote. Specifying dims as a tuple of the expected rows and columns (including header, if any) may speed up reading of large files. If comments is true, lines beginning with comment_char and text following comment_char in any line are ignored.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [5; 6; 7; 8];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y])\n end\n\njulia> readdlm(\"delim_file.txt\", '\\t', Int, '\\n')\n4×2 Matrix{Int64}:\n 1 5\n 2 6\n 3 7\n 4 8\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, AbstractChar, AbstractChar}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, delim::AbstractChar, eol::AbstractChar; options...)\n\nIf all data is numeric, the result will be a numeric array. If some elements cannot be parsed as numbers, a heterogeneous array of numbers and strings is returned.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, AbstractChar, Type}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, delim::AbstractChar, T::Type; options...)\n\nThe end of line delimiter is taken as \\n.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [1.1; 2.2; 3.3; 4.4];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y], ',')\n end;\n\njulia> readdlm(\"delim_file.txt\", ',', Float64)\n4×2 Matrix{Float64}:\n 1.0 1.1\n 2.0 2.2\n 3.0 3.3\n 4.0 4.4\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, AbstractChar}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, delim::AbstractChar; options...)\n\nThe end of line delimiter is taken as \\n. If all data is numeric, the result will be a numeric array. If some elements cannot be parsed as numbers, a heterogeneous array of numbers and strings is returned.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [1.1; 2.2; 3.3; 4.4];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y], ',')\n end;\n\njulia> readdlm(\"delim_file.txt\", ',')\n4×2 Matrix{Float64}:\n 1.0 1.1\n 2.0 2.2\n 3.0 3.3\n 4.0 4.4\n\njulia> z = [\"a\"; \"b\"; \"c\"; \"d\"];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x z], ',')\n end;\n\njulia> readdlm(\"delim_file.txt\", ',')\n4×2 Matrix{Any}:\n 1 \"a\"\n 2 \"b\"\n 3 \"c\"\n 4 \"d\"\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, Type}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, T::Type; options...)\n\nThe columns are assumed to be separated by one or more whitespaces. The end of line delimiter is taken as \\n.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [5; 6; 7; 8];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y])\n end;\n\njulia> readdlm(\"delim_file.txt\", Int64)\n4×2 Matrix{Int64}:\n 1 5\n 2 6\n 3 7\n 4 8\n\njulia> readdlm(\"delim_file.txt\", Float64)\n4×2 Matrix{Float64}:\n 1.0 5.0\n 2.0 6.0\n 3.0 7.0\n 4.0 8.0\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source; options...)\n\nThe columns are assumed to be separated by one or more whitespaces. The end of line delimiter is taken as \\n. If all data is numeric, the result will be a numeric array. If some elements cannot be parsed as numbers, a heterogeneous array of numbers and strings is returned.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [\"a\"; \"b\"; \"c\"; \"d\"];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y])\n end;\n\njulia> readdlm(\"delim_file.txt\")\n4×2 Matrix{Any}:\n 1 \"a\"\n 2 \"b\"\n 3 \"c\"\n 4 \"d\"\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.writedlm","page":"Delimited Files","title":"DelimitedFiles.writedlm","text":"writedlm(f, A, delim='\\t'; opts)\n\nWrite A (a vector, matrix, or an iterable collection of iterable rows) as text to f (either a filename string or an IO stream) using the given delimiter delim (which defaults to tab, but can be any printable Julia object, typically a Char or AbstractString).\n\nFor example, two vectors x and y of the same length can be written as two columns of tab-delimited text to f by either writedlm(f, [x y]) or by writedlm(f, zip(x, y)).\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [5; 6; 7; 8];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y])\n end\n\njulia> readdlm(\"delim_file.txt\", '\\t', Int, '\\n')\n4×2 Matrix{Int64}:\n 1 5\n 2 6\n 3 7\n 4 8\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/docs/src/index.md\"","category":"page"},{"location":"stdlib/LinearAlgebra/#man-linalg","page":"Linear Algebra","title":"Linear Algebra","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"DocTestSetup = :(using LinearAlgebra)","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations of many common and useful linear algebra operations which can be loaded with using LinearAlgebra. Basic operations, such as tr, det, and inv are all supported:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> A = [1 2 3; 4 1 6; 7 8 1]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 1 6\n 7 8 1\n\njulia> tr(A)\n3\n\njulia> det(A)\n104.0\n\njulia> inv(A)\n3×3 Matrix{Float64}:\n -0.451923 0.211538 0.0865385\n 0.365385 -0.192308 0.0576923\n 0.240385 0.0576923 -0.0673077","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"As well as other useful operations, such as finding eigenvalues or eigenvectors:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> A = [-4. -17.; 2. 2.]\n2×2 Matrix{Float64}:\n -4.0 -17.0\n 2.0 2.0\n\njulia> eigvals(A)\n2-element Vector{ComplexF64}:\n -1.0 - 5.0im\n -1.0 + 5.0im\n\njulia> eigvecs(A)\n2×2 Matrix{ComplexF64}:\n 0.945905-0.0im 0.945905+0.0im\n -0.166924+0.278207im -0.166924-0.278207im","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In addition, Julia provides many factorizations which can be used to speed up problems such as linear solve or matrix exponentiation by pre-factorizing a matrix into a form more amenable (for performance or memory reasons) to the problem. See the documentation on factorize for more information. As an example:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> A = [1.5 2 -4; 3 -1 -6; -10 2.3 4]\n3×3 Matrix{Float64}:\n 1.5 2.0 -4.0\n 3.0 -1.0 -6.0\n -10.0 2.3 4.0\n\njulia> factorize(A)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n -0.15 1.0 0.0\n -0.3 -0.132196 1.0\nU factor:\n3×3 Matrix{Float64}:\n -10.0 2.3 4.0\n 0.0 2.345 -3.4\n 0.0 0.0 -5.24947","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Since A is not Hermitian, symmetric, triangular, tridiagonal, or bidiagonal, an LU factorization may be the best we can do. Compare with:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5]\n3×3 Matrix{Float64}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0\n\njulia> factorize(B)\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n3×3 Tridiagonal{Float64, Vector{Float64}}:\n -1.64286 0.0 ⋅\n 0.0 -2.8 0.0\n ⋅ 0.0 5.0\nU factor:\n3×3 UnitUpperTriangular{Float64, Matrix{Float64}}:\n 1.0 0.142857 -0.8\n ⋅ 1.0 -0.6\n ⋅ ⋅ 1.0\npermutation:\n3-element Vector{Int64}:\n 1\n 2\n 3","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Here, Julia was able to detect that B is in fact symmetric, and used a more appropriate factorization. Often it's possible to write more efficient code for a matrix that is known to have certain properties e.g. it is symmetric, or tridiagonal. Julia provides some special types so that you can \"tag\" matrices as having these properties. For instance:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5]\n3×3 Matrix{Float64}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0\n\njulia> sB = Symmetric(B)\n3×3 Symmetric{Float64, Matrix{Float64}}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"sB has been tagged as a matrix that's (real) symmetric, so for later operations we might perform on it, such as eigenfactorization or computing matrix-vector products, efficiencies can be found by only referencing half of it. For example:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5]\n3×3 Matrix{Float64}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0\n\njulia> sB = Symmetric(B)\n3×3 Symmetric{Float64, Matrix{Float64}}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0\n\njulia> x = [1; 2; 3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> sB\\x\n3-element Vector{Float64}:\n -1.7391304347826084\n -1.1086956521739126\n -1.4565217391304346","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The \\ operation here performs the linear solution. The left-division operator is pretty powerful and it's easy to write compact, readable code that is flexible enough to solve all sorts of systems of linear equations.","category":"page"},{"location":"stdlib/LinearAlgebra/#Special-matrices","page":"Linear Algebra","title":"Special matrices","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Matrices with special symmetries and structures arise often in linear algebra and are frequently associated with various matrix factorizations. Julia features a rich collection of special matrix types, which allow for fast computation with specialized routines that are specially developed for particular matrix types.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The following tables summarize the types of special matrices that have been implemented in Julia, as well as whether hooks to various optimized methods for them in LAPACK are available.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Type Description\nSymmetric Symmetric matrix\nHermitian Hermitian matrix\nUpperTriangular Upper triangular matrix\nUnitUpperTriangular Upper triangular matrix with unit diagonal\nLowerTriangular Lower triangular matrix\nUnitLowerTriangular Lower triangular matrix with unit diagonal\nUpperHessenberg Upper Hessenberg matrix\nTridiagonal Tridiagonal matrix\nSymTridiagonal Symmetric tridiagonal matrix\nBidiagonal Upper/lower bidiagonal matrix\nDiagonal Diagonal matrix\nUniformScaling Uniform scaling operator","category":"page"},{"location":"stdlib/LinearAlgebra/#Elementary-operations","page":"Linear Algebra","title":"Elementary operations","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Matrix type + - * \\ Other functions with optimized methods\nSymmetric MV inv, sqrt, cbrt, exp\nHermitian MV inv, sqrt, cbrt, exp\nUpperTriangular MV MV inv, det, logdet\nUnitUpperTriangular MV MV inv, det, logdet\nLowerTriangular MV MV inv, det, logdet\nUnitLowerTriangular MV MV inv, det, logdet\nUpperHessenberg MM inv, det\nSymTridiagonal M M MS MV eigmax, eigmin\nTridiagonal M M MS MV \nBidiagonal M M MS MV \nDiagonal M M MV MV inv, det, logdet, /\nUniformScaling M M MVS MVS /","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Legend:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Key Description\nM (matrix) An optimized method for matrix-matrix operations is available\nV (vector) An optimized method for matrix-vector operations is available\nS (scalar) An optimized method for matrix-scalar operations is available","category":"page"},{"location":"stdlib/LinearAlgebra/#Matrix-factorizations","page":"Linear Algebra","title":"Matrix factorizations","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Matrix type LAPACK eigen eigvals eigvecs svd svdvals\nSymmetric SY ARI \nHermitian HE ARI \nUpperTriangular TR A A A \nUnitUpperTriangular TR A A A \nLowerTriangular TR A A A \nUnitLowerTriangular TR A A A \nSymTridiagonal ST A ARI AV \nTridiagonal GT \nBidiagonal BD A A\nDiagonal DI A ","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Legend:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Key Description Example\nA (all) An optimized method to find all the characteristic values and/or vectors is available e.g. eigvals(M)\nR (range) An optimized method to find the ilth through the ihth characteristic values are available eigvals(M, il, ih)\nI (interval) An optimized method to find the characteristic values in the interval [vl, vh] is available eigvals(M, vl, vh)\nV (vectors) An optimized method to find the characteristic vectors corresponding to the characteristic values x=[x1, x2,...] is available eigvecs(M, x)","category":"page"},{"location":"stdlib/LinearAlgebra/#The-uniform-scaling-operator","page":"Linear Algebra","title":"The uniform scaling operator","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"A UniformScaling operator represents a scalar times the identity operator, λ*I. The identity operator I is defined as a constant and is an instance of UniformScaling. The size of these operators are generic and match the other matrix in the binary operations +, -, * and \\. For A+I and A-I this means that A must be square. Multiplication with the identity operator I is a noop (except for checking that the scaling factor is one) and therefore almost without overhead.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"To see the UniformScaling operator in action:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> U = UniformScaling(2);\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> a + U\n2×2 Matrix{Int64}:\n 3 2\n 3 6\n\njulia> a * U\n2×2 Matrix{Int64}:\n 2 4\n 6 8\n\njulia> [a U]\n2×4 Matrix{Int64}:\n 1 2 2 0\n 3 4 0 2\n\njulia> b = [1 2 3; 4 5 6]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> b - U\nERROR: DimensionMismatch: matrix is not square: dimensions are (2, 3)\nStacktrace:\n[...]","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"If you need to solve many systems of the form (A+μI)x = b for the same A and different μ, it might be beneficial to first compute the Hessenberg factorization F of A via the hessenberg function. Given F, Julia employs an efficient algorithm for (F+μ*I) \\ b (equivalent to (A+μ*I)x \\ b) and related operations like determinants.","category":"page"},{"location":"stdlib/LinearAlgebra/#man-linalg-factorizations","page":"Linear Algebra","title":"Matrix factorizations","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Matrix factorizations (a.k.a. matrix decompositions) compute the factorization of a matrix into a product of matrices, and are one of the central concepts in (numerical) linear algebra.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The following table summarizes the types of matrix factorizations that have been implemented in Julia. Details of their associated methods can be found in the Standard functions section of the Linear Algebra documentation.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Type Description\nBunchKaufman Bunch-Kaufman factorization\nCholesky Cholesky factorization\nCholeskyPivoted Pivoted Cholesky factorization\nLDLt LDL(T) factorization\nLU LU factorization\nQR QR factorization\nQRCompactWY Compact WY form of the QR factorization\nQRPivoted Pivoted QR factorization\nLQ QR factorization of transpose(A)\nHessenberg Hessenberg decomposition\nEigen Spectral decomposition\nGeneralizedEigen Generalized spectral decomposition\nSVD Singular value decomposition\nGeneralizedSVD Generalized SVD\nSchur Schur decomposition\nGeneralizedSchur Generalized Schur decomposition","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Adjoints and transposes of Factorization objects are lazily wrapped in AdjointFactorization and TransposeFactorization objects, respectively. Generically, transpose of real Factorizations are wrapped as AdjointFactorization.","category":"page"},{"location":"stdlib/LinearAlgebra/#man-linalg-abstractq","page":"Linear Algebra","title":"Orthogonal matrices (AbstractQ)","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Some matrix factorizations generate orthogonal/unitary \"matrix\" factors. These factorizations include QR-related factorizations obtained from calls to qr, i.e., QR, QRCompactWY and QRPivoted, the Hessenberg factorization obtained from calls to hessenberg, and the LQ factorization obtained from lq. While these orthogonal/unitary factors admit a matrix representation, their internal representation is, for performance and memory reasons, different. Hence, they should be rather viewed as matrix-backed, function-based linear operators. In particular, reading, for instance, a column of its matrix representation requires running \"matrix\"-vector multiplication code, rather than simply reading out data from memory (possibly filling parts of the vector with structural zeros). Another clear distinction from other, non-triangular matrix types is that the underlying multiplication code allows for in-place modification during multiplication. Furthermore, objects of specific AbstractQ subtypes as those created via qr, hessenberg and lq can behave like a square or a rectangular matrix depending on context:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> using LinearAlgebra\n\njulia> Q = qr(rand(3,2)).Q\n3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}\n\njulia> Matrix(Q)\n3×2 Matrix{Float64}:\n -0.320597 0.865734\n -0.765834 -0.475694\n -0.557419 0.155628\n\njulia> Q*I\n3×3 Matrix{Float64}:\n -0.320597 0.865734 -0.384346\n -0.765834 -0.475694 -0.432683\n -0.557419 0.155628 0.815514\n\njulia> Q*ones(2)\n3-element Vector{Float64}:\n 0.5451367118802273\n -1.241527373086654\n -0.40179067589600226\n\njulia> Q*ones(3)\n3-element Vector{Float64}:\n 0.16079054743832022\n -1.674209978965636\n 0.41372375588835797\n\njulia> ones(1,2) * Q'\n1×3 Matrix{Float64}:\n 0.545137 -1.24153 -0.401791\n\njulia> ones(1,3) * Q'\n1×3 Matrix{Float64}:\n 0.160791 -1.67421 0.413724","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Due to this distinction from dense or structured matrices, the abstract AbstractQ type does not subtype AbstractMatrix, but instead has its own type hierarchy. Custom types that subtype AbstractQ can rely on generic fallbacks if the following interface is satisfied. For example, for","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"struct MyQ{T} <: LinearAlgebra.AbstractQ{T}\n # required fields\nend","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"provide overloads for","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Base.size(Q::MyQ) # size of corresponding square matrix representation\nBase.convert(::Type{AbstractQ{T}}, Q::MyQ) # eltype promotion [optional]\nLinearAlgebra.lmul!(Q::MyQ, x::AbstractVecOrMat) # left-multiplication\nLinearAlgebra.rmul!(A::AbstractMatrix, Q::MyQ) # right-multiplication","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"If eltype promotion is not of interest, the convert method is unnecessary, since by default convert(::Type{AbstractQ{T}}, Q::AbstractQ{T}) returns Q itself. Adjoints of AbstractQ-typed objects are lazily wrapped in an AdjointQ wrapper type, which requires its own LinearAlgebra.lmul! and LinearAlgebra.rmul! methods. Given this set of methods, any Q::MyQ can be used like a matrix, preferably in a multiplicative context: multiplication via * with scalars, vectors and matrices from left and right, obtaining a matrix representation of Q via Matrix(Q) (or Q*I) and indexing into the matrix representation all work. In contrast, addition and subtraction as well as more generally broadcasting over elements in the matrix representation fail because that would be highly inefficient. For such use cases, consider computing the matrix representation up front and cache it for future reuse.","category":"page"},{"location":"stdlib/LinearAlgebra/#man-linalg-pivoting-strategies","page":"Linear Algebra","title":"Pivoting Strategies","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Several of Julia's matrix factorizations support pivoting, which can be used to improve their numerical stability. In fact, some matrix factorizations, such as the LU factorization, may fail without pivoting.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In pivoting, first, a pivot element with good numerical properties is chosen based on a pivoting strategy. Next, the rows and columns of the original matrix are permuted to bring the chosen element in place for subsequent computation. Furthermore, the process is repeated for each stage of the factorization.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Consequently, besides the conventional matrix factors, the outputs of pivoted factorization schemes also include permutation matrices.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In the following, the pivoting strategies implemented in Julia are briefly described. Note that not all matrix factorizations may support them. Consult the documentation of the respective matrix factorization for details on the supported pivoting strategies.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"See also LinearAlgebra.ZeroPivotException.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.NoPivot\nLinearAlgebra.RowNonZero\nLinearAlgebra.RowMaximum\nLinearAlgebra.ColumnNorm","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.NoPivot","page":"Linear Algebra","title":"LinearAlgebra.NoPivot","text":"NoPivot\n\nPivoting is not performed. Matrix factorizations such as the LU factorization may fail without pivoting, and may also be numerically unstable for floating-point matrices in the face of roundoff error. This pivot strategy is mainly useful for pedagogical purposes.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.RowNonZero","page":"Linear Algebra","title":"LinearAlgebra.RowNonZero","text":"RowNonZero\n\nFirst non-zero element in the remaining rows is chosen as the pivot element.\n\nBeware that for floating-point matrices, the resulting LU algorithm is numerically unstable — this strategy is mainly useful for comparison to hand calculations (which typically use this strategy) or for other algebraic types (e.g. rational numbers) not susceptible to roundoff errors. Otherwise, the default RowMaximum pivoting strategy should be generally preferred in Gaussian elimination.\n\nNote that the element type of the matrix must admit an iszero method.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.RowMaximum","page":"Linear Algebra","title":"LinearAlgebra.RowMaximum","text":"RowMaximum\n\nThe maximum-magnitude element in the remaining rows is chosen as the pivot element. This is the default strategy for LU factorization of floating-point matrices, and is sometimes referred to as the \"partial pivoting\" algorithm.\n\nNote that the element type of the matrix must admit an abs method, whose result type must admit a < method.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ColumnNorm","page":"Linear Algebra","title":"LinearAlgebra.ColumnNorm","text":"ColumnNorm\n\nThe column with the maximum norm is used for subsequent computation. This is used for pivoted QR factorization.\n\nNote that the element type of the matrix must admit norm and abs methods, whose respective result types must admit a < method.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#Standard-functions","page":"Linear Algebra","title":"Standard functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Linear algebra functions in Julia are largely implemented by calling functions from LAPACK. Sparse matrix factorizations call functions from SuiteSparse. Other sparse solvers are available as Julia packages.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Base.:*(::AbstractMatrix, ::AbstractMatrix)\nBase.:*(::AbstractMatrix, ::AbstractMatrix, ::AbstractVector)\nBase.:\\(::AbstractMatrix, ::AbstractVecOrMat)\nBase.:/(::AbstractVecOrMat, ::AbstractVecOrMat)\nLinearAlgebra.SingularException\nLinearAlgebra.PosDefException\nLinearAlgebra.ZeroPivotException\nLinearAlgebra.RankDeficientException\nLinearAlgebra.LAPACKException\nLinearAlgebra.dot\nLinearAlgebra.dot(::Any, ::Any, ::Any)\nLinearAlgebra.cross\nLinearAlgebra.axpy!\nLinearAlgebra.axpby!\nLinearAlgebra.rotate!\nLinearAlgebra.reflect!\nLinearAlgebra.factorize\nLinearAlgebra.Diagonal\nLinearAlgebra.Bidiagonal\nLinearAlgebra.SymTridiagonal\nLinearAlgebra.Tridiagonal\nLinearAlgebra.Symmetric\nLinearAlgebra.Hermitian\nLinearAlgebra.LowerTriangular\nLinearAlgebra.UpperTriangular\nLinearAlgebra.UnitLowerTriangular\nLinearAlgebra.UnitUpperTriangular\nLinearAlgebra.UpperHessenberg\nLinearAlgebra.UniformScaling\nLinearAlgebra.I\nLinearAlgebra.UniformScaling(::Integer)\nLinearAlgebra.Factorization\nLinearAlgebra.LU\nLinearAlgebra.lu\nLinearAlgebra.lu!\nLinearAlgebra.Cholesky\nLinearAlgebra.CholeskyPivoted\nLinearAlgebra.cholesky\nLinearAlgebra.cholesky!\nLinearAlgebra.lowrankupdate\nLinearAlgebra.lowrankdowndate\nLinearAlgebra.lowrankupdate!\nLinearAlgebra.lowrankdowndate!\nLinearAlgebra.LDLt\nLinearAlgebra.ldlt\nLinearAlgebra.ldlt!\nLinearAlgebra.QR\nLinearAlgebra.QRCompactWY\nLinearAlgebra.QRPivoted\nLinearAlgebra.qr\nLinearAlgebra.qr!\nLinearAlgebra.LQ\nLinearAlgebra.lq\nLinearAlgebra.lq!\nLinearAlgebra.BunchKaufman\nLinearAlgebra.bunchkaufman\nLinearAlgebra.bunchkaufman!\nLinearAlgebra.Eigen\nLinearAlgebra.GeneralizedEigen\nLinearAlgebra.eigvals\nLinearAlgebra.eigvals!\nLinearAlgebra.eigmax\nLinearAlgebra.eigmin\nLinearAlgebra.eigvecs\nLinearAlgebra.eigen\nLinearAlgebra.eigen!\nLinearAlgebra.Hessenberg\nLinearAlgebra.hessenberg\nLinearAlgebra.hessenberg!\nLinearAlgebra.Schur\nLinearAlgebra.GeneralizedSchur\nLinearAlgebra.schur\nLinearAlgebra.schur!\nLinearAlgebra.ordschur\nLinearAlgebra.ordschur!\nLinearAlgebra.SVD\nLinearAlgebra.GeneralizedSVD\nLinearAlgebra.svd\nLinearAlgebra.svd!\nLinearAlgebra.svdvals\nLinearAlgebra.svdvals!\nLinearAlgebra.Givens\nLinearAlgebra.givens\nLinearAlgebra.triu\nLinearAlgebra.triu!\nLinearAlgebra.tril\nLinearAlgebra.tril!\nLinearAlgebra.diagind\nLinearAlgebra.diag\nLinearAlgebra.diagm\nLinearAlgebra.rank\nLinearAlgebra.norm\nLinearAlgebra.opnorm\nLinearAlgebra.normalize!\nLinearAlgebra.normalize\nLinearAlgebra.cond\nLinearAlgebra.condskeel\nLinearAlgebra.tr\nLinearAlgebra.det\nLinearAlgebra.logdet\nLinearAlgebra.logabsdet\nBase.inv(::AbstractMatrix)\nLinearAlgebra.pinv\nLinearAlgebra.nullspace\nBase.kron\nBase.kron!\nLinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat})\nBase.cis(::AbstractMatrix)\nBase.:^(::AbstractMatrix, ::Number)\nBase.:^(::Number, ::AbstractMatrix)\nLinearAlgebra.log(::StridedMatrix)\nLinearAlgebra.sqrt(::StridedMatrix)\nLinearAlgebra.cbrt(::AbstractMatrix{<:Real})\nLinearAlgebra.cos(::StridedMatrix{<:Real})\nLinearAlgebra.sin(::StridedMatrix{<:Real})\nLinearAlgebra.sincos(::StridedMatrix{<:Real})\nLinearAlgebra.tan(::StridedMatrix{<:Real})\nLinearAlgebra.sec(::StridedMatrix)\nLinearAlgebra.csc(::StridedMatrix)\nLinearAlgebra.cot(::StridedMatrix)\nLinearAlgebra.cosh(::StridedMatrix)\nLinearAlgebra.sinh(::StridedMatrix)\nLinearAlgebra.tanh(::StridedMatrix)\nLinearAlgebra.sech(::StridedMatrix)\nLinearAlgebra.csch(::StridedMatrix)\nLinearAlgebra.coth(::StridedMatrix)\nLinearAlgebra.acos(::StridedMatrix)\nLinearAlgebra.asin(::StridedMatrix)\nLinearAlgebra.atan(::StridedMatrix)\nLinearAlgebra.asec(::StridedMatrix)\nLinearAlgebra.acsc(::StridedMatrix)\nLinearAlgebra.acot(::StridedMatrix)\nLinearAlgebra.acosh(::StridedMatrix)\nLinearAlgebra.asinh(::StridedMatrix)\nLinearAlgebra.atanh(::StridedMatrix)\nLinearAlgebra.asech(::StridedMatrix)\nLinearAlgebra.acsch(::StridedMatrix)\nLinearAlgebra.acoth(::StridedMatrix)\nLinearAlgebra.lyap\nLinearAlgebra.sylvester\nLinearAlgebra.issuccess\nLinearAlgebra.issymmetric\nLinearAlgebra.isposdef\nLinearAlgebra.isposdef!\nLinearAlgebra.istril\nLinearAlgebra.istriu\nLinearAlgebra.isdiag\nLinearAlgebra.ishermitian\nBase.transpose\nLinearAlgebra.transpose!\nLinearAlgebra.Transpose\nLinearAlgebra.TransposeFactorization\nBase.adjoint\nLinearAlgebra.adjoint!\nLinearAlgebra.Adjoint\nLinearAlgebra.AdjointFactorization\nBase.copy(::Union{Transpose,Adjoint})\nLinearAlgebra.stride1\nLinearAlgebra.checksquare\nLinearAlgebra.peakflops\nLinearAlgebra.hermitianpart\nLinearAlgebra.hermitianpart!\nLinearAlgebra.copy_adjoint!\nLinearAlgebra.copy_transpose!","category":"page"},{"location":"stdlib/LinearAlgebra/#Base.:*-Tuple{AbstractMatrix, AbstractMatrix}","page":"Linear Algebra","title":"Base.:*","text":"*(A::AbstractMatrix, B::AbstractMatrix)\n\nMatrix multiplication.\n\nExamples\n\njulia> [1 1; 0 1] * [1 0; 1 1]\n2×2 Matrix{Int64}:\n 2 1\n 1 1\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:*-Tuple{AbstractMatrix, AbstractMatrix, AbstractVector}","page":"Linear Algebra","title":"Base.:*","text":"*(A, B::AbstractMatrix, C)\nA * B * C * D\n\nChained multiplication of 3 or 4 matrices is done in the most efficient sequence, based on the sizes of the arrays. That is, the number of scalar multiplications needed for (A * B) * C (with 3 dense matrices) is compared to that for A * (B * C) to choose which of these to execute.\n\nIf the last factor is a vector, or the first a transposed vector, then it is efficient to deal with these first. In particular x' * B * y means (x' * B) * y for an ordinary column-major B::Matrix. Unlike dot(x, B, y), this allocates an intermediate array.\n\nIf the first or last factor is a number, this will be fused with the matrix multiplication, using 5-arg mul!.\n\nSee also muladd, dot.\n\ncompat: Julia 1.7\nThese optimisations require at least Julia 1.7.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:\\-Tuple{AbstractMatrix, AbstractVecOrMat}","page":"Linear Algebra","title":"Base.:\\","text":"\\(A, B)\n\nMatrix division using a polyalgorithm. For input matrices A and B, the result X is such that A*X == B when A is square. The solver that is used depends upon the structure of A. If A is upper or lower triangular (or diagonal), no factorization of A is required and the system is solved with either forward or backward substitution. For non-triangular square matrices, an LU factorization is used.\n\nFor rectangular A the result is the minimum-norm least squares solution computed by a pivoted QR factorization of A and a rank estimate of A based on the R factor.\n\nWhen A is sparse, a similar polyalgorithm is used. For indefinite matrices, the LDLt factorization does not use pivoting during the numerical factorization and therefore the procedure can fail even for invertible matrices.\n\nSee also: factorize, pinv.\n\nExamples\n\njulia> A = [1 0; 1 -2]; B = [32; -4];\n\njulia> X = A \\ B\n2-element Vector{Float64}:\n 32.0\n 18.0\n\njulia> A * X == B\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:/-Tuple{AbstractVecOrMat, AbstractVecOrMat}","page":"Linear Algebra","title":"Base.:/","text":"A / B\n\nMatrix right-division: A / B is equivalent to (B' \\ A')' where \\ is the left-division operator. For square matrices, the result X is such that A == X*B.\n\nSee also: rdiv!.\n\nExamples\n\njulia> A = Float64[1 4 5; 3 9 2]; B = Float64[1 4 2; 3 4 2; 8 7 1];\n\njulia> X = A / B\n2×3 Matrix{Float64}:\n -0.65 3.75 -1.2\n 3.25 -2.75 1.0\n\njulia> isapprox(A, X*B)\ntrue\n\njulia> isapprox(X, A*pinv(B))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.SingularException","page":"Linear Algebra","title":"LinearAlgebra.SingularException","text":"SingularException\n\nException thrown when the input matrix has one or more zero-valued eigenvalues, and is not invertible. A linear solve involving such a matrix cannot be computed. The info field indicates the location of (one of) the singular value(s).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.PosDefException","page":"Linear Algebra","title":"LinearAlgebra.PosDefException","text":"PosDefException\n\nException thrown when the input matrix was not positive definite. Some linear algebra functions and factorizations are only applicable to positive definite matrices. The info field indicates the location of (one of) the eigenvalue(s) which is (are) less than/equal to 0.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ZeroPivotException","page":"Linear Algebra","title":"LinearAlgebra.ZeroPivotException","text":"ZeroPivotException <: Exception\n\nException thrown when a matrix factorization/solve encounters a zero in a pivot (diagonal) position and cannot proceed. This may not mean that the matrix is singular: it may be fruitful to switch to a different factorization such as pivoted LU that can re-order variables to eliminate spurious zero pivots. The info field indicates the location of (one of) the zero pivot(s).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.RankDeficientException","page":"Linear Algebra","title":"LinearAlgebra.RankDeficientException","text":"RankDeficientException\n\nException thrown when the input matrix is rank deficient. Some linear algebra functions, such as the Cholesky decomposition, are only applicable to matrices that are not rank deficient. The info field indicates the computed rank of the matrix.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACKException","page":"Linear Algebra","title":"LinearAlgebra.LAPACKException","text":"LAPACKException\n\nGeneric LAPACK exception thrown either during direct calls to the LAPACK functions or during calls to other functions that use the LAPACK functions internally but lack specialized error handling. The info field contains additional information on the underlying error and depends on the LAPACK function that was invoked.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.dot","page":"Linear Algebra","title":"LinearAlgebra.dot","text":"dot(x, y)\nx ⋅ y\n\nCompute the dot product between two vectors. For complex vectors, the first vector is conjugated.\n\ndot also works on arbitrary iterable objects, including arrays of any dimension, as long as dot is defined on the elements.\n\ndot is semantically equivalent to sum(dot(vx,vy) for (vx,vy) in zip(x, y)), with the added restriction that the arguments must have equal lengths.\n\nx ⋅ y (where ⋅ can be typed by tab-completing \\cdot in the REPL) is a synonym for dot(x, y).\n\nExamples\n\njulia> dot([1; 1], [2; 3])\n5\n\njulia> dot([im; im], [1; 1])\n0 - 2im\n\njulia> dot(1:5, 2:6)\n70\n\njulia> x = fill(2., (5,5));\n\njulia> y = fill(3., (5,5));\n\njulia> dot(x, y)\n150.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.dot-Tuple{Any, Any, Any}","page":"Linear Algebra","title":"LinearAlgebra.dot","text":"dot(x, A, y)\n\nCompute the generalized dot product dot(x, A*y) between two vectors x and y, without storing the intermediate result of A*y. As for the two-argument dot(_,_), this acts recursively. Moreover, for complex vectors, the first vector is conjugated.\n\ncompat: Julia 1.4\nThree-argument dot requires at least Julia 1.4.\n\nExamples\n\njulia> dot([1; 1], [1 2; 3 4], [2; 3])\n26\n\njulia> dot(1:5, reshape(1:25, 5, 5), 2:6)\n4850\n\njulia> ⋅(1:5, reshape(1:25, 5, 5), 2:6) == dot(1:5, reshape(1:25, 5, 5), 2:6)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.cross","page":"Linear Algebra","title":"LinearAlgebra.cross","text":"cross(x, y)\n×(x,y)\n\nCompute the cross product of two 3-vectors.\n\nExamples\n\njulia> a = [0;1;0]\n3-element Vector{Int64}:\n 0\n 1\n 0\n\njulia> b = [0;0;1]\n3-element Vector{Int64}:\n 0\n 0\n 1\n\njulia> cross(a,b)\n3-element Vector{Int64}:\n 1\n 0\n 0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.axpy!","page":"Linear Algebra","title":"LinearAlgebra.axpy!","text":"axpy!(α, x::AbstractArray, y::AbstractArray)\n\nOverwrite y with x * α + y and return y. If x and y have the same axes, it's equivalent with y .+= x .* a.\n\nExamples\n\njulia> x = [1; 2; 3];\n\njulia> y = [4; 5; 6];\n\njulia> axpy!(2, x, y)\n3-element Vector{Int64}:\n 6\n 9\n 12\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.axpby!","page":"Linear Algebra","title":"LinearAlgebra.axpby!","text":"axpby!(α, x::AbstractArray, β, y::AbstractArray)\n\nOverwrite y with x * α + y * β and return y. If x and y have the same axes, it's equivalent with y .= x .* a .+ y .* β.\n\nExamples\n\njulia> x = [1; 2; 3];\n\njulia> y = [4; 5; 6];\n\njulia> axpby!(2, x, 2, y)\n3-element Vector{Int64}:\n 10\n 14\n 18\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.rotate!","page":"Linear Algebra","title":"LinearAlgebra.rotate!","text":"rotate!(x, y, c, s)\n\nOverwrite x with c*x + s*y and y with -conj(s)*x + c*y. Returns x and y.\n\ncompat: Julia 1.5\nrotate! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.reflect!","page":"Linear Algebra","title":"LinearAlgebra.reflect!","text":"reflect!(x, y, c, s)\n\nOverwrite x with c*x + s*y and y with conj(s)*x - c*y. Returns x and y.\n\ncompat: Julia 1.5\nreflect! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.factorize","page":"Linear Algebra","title":"LinearAlgebra.factorize","text":"factorize(A)\n\nCompute a convenient factorization of A, based upon the type of the input matrix. factorize checks A to see if it is symmetric/triangular/etc. if A is passed as a generic matrix. factorize checks every element of A to verify/rule out each property. It will short-circuit as soon as it can rule out symmetry/triangular structure. The return value can be reused for efficient solving of multiple systems. For example: A=factorize(A); x=A\\b; y=A\\C.\n\nProperties of A type of factorization\nPositive-definite Cholesky (see cholesky)\nDense Symmetric/Hermitian Bunch-Kaufman (see bunchkaufman)\nSparse Symmetric/Hermitian LDLt (see ldlt)\nTriangular Triangular\nDiagonal Diagonal\nBidiagonal Bidiagonal\nTridiagonal LU (see lu)\nSymmetric real tridiagonal LDLt (see ldlt)\nGeneral square LU (see lu)\nGeneral non-square QR (see qr)\n\nIf factorize is called on a Hermitian positive-definite matrix, for instance, then factorize will return a Cholesky factorization.\n\nExamples\n\njulia> A = Array(Bidiagonal(fill(1.0, (5, 5)), :U))\n5×5 Matrix{Float64}:\n 1.0 1.0 0.0 0.0 0.0\n 0.0 1.0 1.0 0.0 0.0\n 0.0 0.0 1.0 1.0 0.0\n 0.0 0.0 0.0 1.0 1.0\n 0.0 0.0 0.0 0.0 1.0\n\njulia> factorize(A) # factorize will check to see that A is already factorized\n5×5 Bidiagonal{Float64, Vector{Float64}}:\n 1.0 1.0 ⋅ ⋅ ⋅\n ⋅ 1.0 1.0 ⋅ ⋅\n ⋅ ⋅ 1.0 1.0 ⋅\n ⋅ ⋅ ⋅ 1.0 1.0\n ⋅ ⋅ ⋅ ⋅ 1.0\n\nThis returns a 5×5 Bidiagonal{Float64}, which can now be passed to other linear algebra functions (e.g. eigensolvers) which will use specialized methods for Bidiagonal types.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Diagonal","page":"Linear Algebra","title":"LinearAlgebra.Diagonal","text":"Diagonal(V::AbstractVector)\n\nConstruct a lazy matrix with V as its diagonal.\n\nSee also UniformScaling for the lazy identity matrix I, diagm to make a dense matrix, and diag to extract diagonal elements.\n\nExamples\n\njulia> d = Diagonal([1, 10, 100])\n3×3 Diagonal{Int64, Vector{Int64}}:\n 1 ⋅ ⋅\n ⋅ 10 ⋅\n ⋅ ⋅ 100\n\njulia> diagm([7, 13])\n2×2 Matrix{Int64}:\n 7 0\n 0 13\n\njulia> ans + I\n2×2 Matrix{Int64}:\n 8 0\n 0 14\n\njulia> I(2)\n2×2 Diagonal{Bool, Vector{Bool}}:\n 1 ⋅\n ⋅ 1\n\nnote: Note\nA one-column matrix is not treated like a vector, but instead calls the method Diagonal(A::AbstractMatrix) which extracts 1-element diag(A):\n\njulia> A = transpose([7.0 13.0])\n2×1 transpose(::Matrix{Float64}) with eltype Float64:\n 7.0\n 13.0\n\njulia> Diagonal(A)\n1×1 Diagonal{Float64, Vector{Float64}}:\n 7.0\n\n\n\n\n\nDiagonal(A::AbstractMatrix)\n\nConstruct a matrix from the principal diagonal of A. The input matrix A may be rectangular, but the output will be square.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> D = Diagonal(A)\n2×2 Diagonal{Int64, Vector{Int64}}:\n 1 ⋅\n ⋅ 4\n\njulia> A = [1 2 3; 4 5 6]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> Diagonal(A)\n2×2 Diagonal{Int64, Vector{Int64}}:\n 1 ⋅\n ⋅ 5\n\n\n\n\n\nDiagonal{T}(undef, n)\n\nConstruct an uninitialized Diagonal{T} of length n. See undef.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Bidiagonal","page":"Linear Algebra","title":"LinearAlgebra.Bidiagonal","text":"Bidiagonal(dv::V, ev::V, uplo::Symbol) where V <: AbstractVector\n\nConstructs an upper (uplo=:U) or lower (uplo=:L) bidiagonal matrix using the given diagonal (dv) and off-diagonal (ev) vectors. The result is of type Bidiagonal and provides efficient specialized linear solvers, but may be converted into a regular matrix with convert(Array, _) (or Array(_) for short). The length of ev must be one less than the length of dv.\n\nExamples\n\njulia> dv = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> ev = [7, 8, 9]\n3-element Vector{Int64}:\n 7\n 8\n 9\n\njulia> Bu = Bidiagonal(dv, ev, :U) # ev is on the first superdiagonal\n4×4 Bidiagonal{Int64, Vector{Int64}}:\n 1 7 ⋅ ⋅\n ⋅ 2 8 ⋅\n ⋅ ⋅ 3 9\n ⋅ ⋅ ⋅ 4\n\njulia> Bl = Bidiagonal(dv, ev, :L) # ev is on the first subdiagonal\n4×4 Bidiagonal{Int64, Vector{Int64}}:\n 1 ⋅ ⋅ ⋅\n 7 2 ⋅ ⋅\n ⋅ 8 3 ⋅\n ⋅ ⋅ 9 4\n\n\n\n\n\nBidiagonal(A, uplo::Symbol)\n\nConstruct a Bidiagonal matrix from the main diagonal of A and its first super- (if uplo=:U) or sub-diagonal (if uplo=:L).\n\nExamples\n\njulia> A = [1 1 1 1; 2 2 2 2; 3 3 3 3; 4 4 4 4]\n4×4 Matrix{Int64}:\n 1 1 1 1\n 2 2 2 2\n 3 3 3 3\n 4 4 4 4\n\njulia> Bidiagonal(A, :U) # contains the main diagonal and first superdiagonal of A\n4×4 Bidiagonal{Int64, Vector{Int64}}:\n 1 1 ⋅ ⋅\n ⋅ 2 2 ⋅\n ⋅ ⋅ 3 3\n ⋅ ⋅ ⋅ 4\n\njulia> Bidiagonal(A, :L) # contains the main diagonal and first subdiagonal of A\n4×4 Bidiagonal{Int64, Vector{Int64}}:\n 1 ⋅ ⋅ ⋅\n 2 2 ⋅ ⋅\n ⋅ 3 3 ⋅\n ⋅ ⋅ 4 4\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.SymTridiagonal","page":"Linear Algebra","title":"LinearAlgebra.SymTridiagonal","text":"SymTridiagonal(dv::V, ev::V) where V <: AbstractVector\n\nConstruct a symmetric tridiagonal matrix from the diagonal (dv) and first sub/super-diagonal (ev), respectively. The result is of type SymTridiagonal and provides efficient specialized eigensolvers, but may be converted into a regular matrix with convert(Array, _) (or Array(_) for short).\n\nFor SymTridiagonal block matrices, the elements of dv are symmetrized. The argument ev is interpreted as the superdiagonal. Blocks from the subdiagonal are (materialized) transpose of the corresponding superdiagonal blocks.\n\nExamples\n\njulia> dv = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> ev = [7, 8, 9]\n3-element Vector{Int64}:\n 7\n 8\n 9\n\njulia> SymTridiagonal(dv, ev)\n4×4 SymTridiagonal{Int64, Vector{Int64}}:\n 1 7 ⋅ ⋅\n 7 2 8 ⋅\n ⋅ 8 3 9\n ⋅ ⋅ 9 4\n\njulia> A = SymTridiagonal(fill([1 2; 3 4], 3), fill([1 2; 3 4], 2));\n\njulia> A[1,1]\n2×2 Symmetric{Int64, Matrix{Int64}}:\n 1 2\n 2 4\n\njulia> A[1,2]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> A[2,1]\n2×2 Matrix{Int64}:\n 1 3\n 2 4\n\n\n\n\n\nSymTridiagonal(A::AbstractMatrix)\n\nConstruct a symmetric tridiagonal matrix from the diagonal and first superdiagonal of the symmetric matrix A.\n\nExamples\n\njulia> A = [1 2 3; 2 4 5; 3 5 6]\n3×3 Matrix{Int64}:\n 1 2 3\n 2 4 5\n 3 5 6\n\njulia> SymTridiagonal(A)\n3×3 SymTridiagonal{Int64, Vector{Int64}}:\n 1 2 ⋅\n 2 4 5\n ⋅ 5 6\n\njulia> B = reshape([[1 2; 2 3], [1 2; 3 4], [1 3; 2 4], [1 2; 2 3]], 2, 2);\n\njulia> SymTridiagonal(B)\n2×2 SymTridiagonal{Matrix{Int64}, Vector{Matrix{Int64}}}:\n [1 2; 2 3] [1 3; 2 4]\n [1 2; 3 4] [1 2; 2 3]\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Tridiagonal","page":"Linear Algebra","title":"LinearAlgebra.Tridiagonal","text":"Tridiagonal(dl::V, d::V, du::V) where V <: AbstractVector\n\nConstruct a tridiagonal matrix from the first subdiagonal, diagonal, and first superdiagonal, respectively. The result is of type Tridiagonal and provides efficient specialized linear solvers, but may be converted into a regular matrix with convert(Array, _) (or Array(_) for short). The lengths of dl and du must be one less than the length of d.\n\nnote: Note\nThe subdiagonal dl and the superdiagonal du must not be aliased to each other. If aliasing is detected, the constructor will use a copy of du as its argument.\n\nExamples\n\njulia> dl = [1, 2, 3];\n\njulia> du = [4, 5, 6];\n\njulia> d = [7, 8, 9, 0];\n\njulia> Tridiagonal(dl, d, du)\n4×4 Tridiagonal{Int64, Vector{Int64}}:\n 7 4 ⋅ ⋅\n 1 8 5 ⋅\n ⋅ 2 9 6\n ⋅ ⋅ 3 0\n\n\n\n\n\nTridiagonal(A)\n\nConstruct a tridiagonal matrix from the first sub-diagonal, diagonal and first super-diagonal of the matrix A.\n\nExamples\n\njulia> A = [1 2 3 4; 1 2 3 4; 1 2 3 4; 1 2 3 4]\n4×4 Matrix{Int64}:\n 1 2 3 4\n 1 2 3 4\n 1 2 3 4\n 1 2 3 4\n\njulia> Tridiagonal(A)\n4×4 Tridiagonal{Int64, Vector{Int64}}:\n 1 2 ⋅ ⋅\n 1 2 3 ⋅\n ⋅ 2 3 4\n ⋅ ⋅ 3 4\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Symmetric","page":"Linear Algebra","title":"LinearAlgebra.Symmetric","text":"Symmetric(A, uplo=:U)\n\nConstruct a Symmetric view of the upper (if uplo = :U) or lower (if uplo = :L) triangle of the matrix A.\n\nSymmetric views are mainly useful for real-symmetric matrices, for which specialized algorithms (e.g. for eigenproblems) are enabled for Symmetric types. More generally, see also Hermitian(A) for Hermitian matrices A == A', which is effectively equivalent to Symmetric for real matrices but is also useful for complex matrices. (Whereas complex Symmetric matrices are supported but have few if any specialized algorithms.)\n\nTo compute the symmetric part of a real matrix, or more generally the Hermitian part (A + A') / 2 of a real or complex matrix A, use hermitianpart.\n\nExamples\n\njulia> A = [1 2 3; 4 5 6; 7 8 9]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n 7 8 9\n\njulia> Supper = Symmetric(A)\n3×3 Symmetric{Int64, Matrix{Int64}}:\n 1 2 3\n 2 5 6\n 3 6 9\n\njulia> Slower = Symmetric(A, :L)\n3×3 Symmetric{Int64, Matrix{Int64}}:\n 1 4 7\n 4 5 8\n 7 8 9\n\njulia> hermitianpart(A)\n3×3 Hermitian{Float64, Matrix{Float64}}:\n 1.0 3.0 5.0\n 3.0 5.0 7.0\n 5.0 7.0 9.0\n\nNote that Supper will not be equal to Slower unless A is itself symmetric (e.g. if A == transpose(A)).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Hermitian","page":"Linear Algebra","title":"LinearAlgebra.Hermitian","text":"Hermitian(A, uplo=:U)\n\nConstruct a Hermitian view of the upper (if uplo = :U) or lower (if uplo = :L) triangle of the matrix A.\n\nTo compute the Hermitian part of A, use hermitianpart.\n\nExamples\n\njulia> A = [1 2+2im 3-3im; 4 5 6-6im; 7 8+8im 9]\n3×3 Matrix{Complex{Int64}}:\n 1+0im 2+2im 3-3im\n 4+0im 5+0im 6-6im\n 7+0im 8+8im 9+0im\n\njulia> Hupper = Hermitian(A)\n3×3 Hermitian{Complex{Int64}, Matrix{Complex{Int64}}}:\n 1+0im 2+2im 3-3im\n 2-2im 5+0im 6-6im\n 3+3im 6+6im 9+0im\n\njulia> Hlower = Hermitian(A, :L)\n3×3 Hermitian{Complex{Int64}, Matrix{Complex{Int64}}}:\n 1+0im 4+0im 7+0im\n 4+0im 5+0im 8-8im\n 7+0im 8+8im 9+0im\n\njulia> hermitianpart(A)\n3×3 Hermitian{ComplexF64, Matrix{ComplexF64}}:\n 1.0+0.0im 3.0+1.0im 5.0-1.5im\n 3.0-1.0im 5.0+0.0im 7.0-7.0im\n 5.0+1.5im 7.0+7.0im 9.0+0.0im\n\nNote that Hupper will not be equal to Hlower unless A is itself Hermitian (e.g. if A == adjoint(A)).\n\nAll non-real parts of the diagonal will be ignored.\n\nHermitian(fill(complex(1,1), 1, 1)) == fill(1, 1, 1)\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LowerTriangular","page":"Linear Algebra","title":"LinearAlgebra.LowerTriangular","text":"LowerTriangular(A::AbstractMatrix)\n\nConstruct a LowerTriangular view of the matrix A.\n\nExamples\n\njulia> A = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]\n3×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> LowerTriangular(A)\n3×3 LowerTriangular{Float64, Matrix{Float64}}:\n 1.0 ⋅ ⋅\n 4.0 5.0 ⋅\n 7.0 8.0 9.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UpperTriangular","page":"Linear Algebra","title":"LinearAlgebra.UpperTriangular","text":"UpperTriangular(A::AbstractMatrix)\n\nConstruct an UpperTriangular view of the matrix A.\n\nExamples\n\njulia> A = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]\n3×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> UpperTriangular(A)\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 1.0 2.0 3.0\n ⋅ 5.0 6.0\n ⋅ ⋅ 9.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UnitLowerTriangular","page":"Linear Algebra","title":"LinearAlgebra.UnitLowerTriangular","text":"UnitLowerTriangular(A::AbstractMatrix)\n\nConstruct a UnitLowerTriangular view of the matrix A. Such a view has the oneunit of the eltype of A on its diagonal.\n\nExamples\n\njulia> A = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]\n3×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> UnitLowerTriangular(A)\n3×3 UnitLowerTriangular{Float64, Matrix{Float64}}:\n 1.0 ⋅ ⋅\n 4.0 1.0 ⋅\n 7.0 8.0 1.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UnitUpperTriangular","page":"Linear Algebra","title":"LinearAlgebra.UnitUpperTriangular","text":"UnitUpperTriangular(A::AbstractMatrix)\n\nConstruct an UnitUpperTriangular view of the matrix A. Such a view has the oneunit of the eltype of A on its diagonal.\n\nExamples\n\njulia> A = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]\n3×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> UnitUpperTriangular(A)\n3×3 UnitUpperTriangular{Float64, Matrix{Float64}}:\n 1.0 2.0 3.0\n ⋅ 1.0 6.0\n ⋅ ⋅ 1.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UpperHessenberg","page":"Linear Algebra","title":"LinearAlgebra.UpperHessenberg","text":"UpperHessenberg(A::AbstractMatrix)\n\nConstruct an UpperHessenberg view of the matrix A. Entries of A below the first subdiagonal are ignored.\n\ncompat: Julia 1.3\nThis type was added in Julia 1.3.\n\nEfficient algorithms are implemented for H \\ b, det(H), and similar.\n\nSee also the hessenberg function to factor any matrix into a similar upper-Hessenberg matrix.\n\nIf F::Hessenberg is the factorization object, the unitary matrix can be accessed with F.Q and the Hessenberg matrix with F.H. When Q is extracted, the resulting type is the HessenbergQ object, and may be converted to a regular matrix with convert(Array, _) (or Array(_) for short).\n\nIterating the decomposition produces the factors F.Q and F.H.\n\nExamples\n\njulia> A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]\n4×4 Matrix{Int64}:\n 1 2 3 4\n 5 6 7 8\n 9 10 11 12\n 13 14 15 16\n\njulia> UpperHessenberg(A)\n4×4 UpperHessenberg{Int64, Matrix{Int64}}:\n 1 2 3 4\n 5 6 7 8\n ⋅ 10 11 12\n ⋅ ⋅ 15 16\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UniformScaling","page":"Linear Algebra","title":"LinearAlgebra.UniformScaling","text":"UniformScaling{T<:Number}\n\nGenerically sized uniform scaling operator defined as a scalar times the identity operator, λ*I. Although without an explicit size, it acts similarly to a matrix in many cases and includes support for some indexing. See also I.\n\ncompat: Julia 1.6\nIndexing using ranges is available as of Julia 1.6.\n\nExamples\n\njulia> J = UniformScaling(2.)\nUniformScaling{Float64}\n2.0*I\n\njulia> A = [1. 2.; 3. 4.]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> J*A\n2×2 Matrix{Float64}:\n 2.0 4.0\n 6.0 8.0\n\njulia> J[1:2, 1:2]\n2×2 Matrix{Float64}:\n 2.0 0.0\n 0.0 2.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.I","page":"Linear Algebra","title":"LinearAlgebra.I","text":"I\n\nAn object of type UniformScaling, representing an identity matrix of any size.\n\nExamples\n\njulia> fill(1, (5,6)) * I == fill(1, (5,6))\ntrue\n\njulia> [1 2im 3; 1im 2 3] * I\n2×3 Matrix{Complex{Int64}}:\n 1+0im 0+2im 3+0im\n 0+1im 2+0im 3+0im\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UniformScaling-Tuple{Integer}","page":"Linear Algebra","title":"LinearAlgebra.UniformScaling","text":"(I::UniformScaling)(n::Integer)\n\nConstruct a Diagonal matrix from a UniformScaling.\n\ncompat: Julia 1.2\nThis method is available as of Julia 1.2.\n\nExamples\n\njulia> I(3)\n3×3 Diagonal{Bool, Vector{Bool}}:\n 1 ⋅ ⋅\n ⋅ 1 ⋅\n ⋅ ⋅ 1\n\njulia> (0.7*I)(3)\n3×3 Diagonal{Float64, Vector{Float64}}:\n 0.7 ⋅ ⋅\n ⋅ 0.7 ⋅\n ⋅ ⋅ 0.7\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Factorization","page":"Linear Algebra","title":"LinearAlgebra.Factorization","text":"LinearAlgebra.Factorization\n\nAbstract type for matrix factorizations a.k.a. matrix decompositions. See online documentation for a list of available matrix factorizations.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LU","page":"Linear Algebra","title":"LinearAlgebra.LU","text":"LU <: Factorization\n\nMatrix factorization type of the LU factorization of a square matrix A. This is the return type of lu, the corresponding matrix factorization function.\n\nThe individual components of the factorization F::LU can be accessed via getproperty:\n\nComponent Description\nF.L L (unit lower triangular) part of LU\nF.U U (upper triangular) part of LU\nF.p (right) permutation Vector\nF.P (right) permutation Matrix\n\nIterating the factorization produces the components F.L, F.U, and F.p.\n\nExamples\n\njulia> A = [4 3; 6 3]\n2×2 Matrix{Int64}:\n 4 3\n 6 3\n\njulia> F = lu(A)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.666667 1.0\nU factor:\n2×2 Matrix{Float64}:\n 6.0 3.0\n 0.0 1.0\n\njulia> F.L * F.U == A[F.p, :]\ntrue\n\njulia> l, u, p = lu(A); # destructuring via iteration\n\njulia> l == F.L && u == F.U && p == F.p\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lu","page":"Linear Algebra","title":"LinearAlgebra.lu","text":"lu(A::AbstractSparseMatrixCSC; check = true, q = nothing, control = get_umfpack_control()) -> F::UmfpackLU\n\nCompute the LU factorization of a sparse matrix A.\n\nFor sparse A with real or complex element type, the return type of F is UmfpackLU{Tv, Ti}, with Tv = Float64 or ComplexF64 respectively and Ti is an integer type (Int32 or Int64).\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nThe permutation q can either be a permutation vector or nothing. If no permutation vector is provided or q is nothing, UMFPACK's default is used. If the permutation is not zero-based, a zero-based copy is made.\n\nThe control vector defaults to the Julia SparseArrays package's default configuration for UMFPACK (NB: this is modified from the UMFPACK defaults to disable iterative refinement), but can be changed by passing a vector of length UMFPACK_CONTROL, see the UMFPACK manual for possible configurations. For example to reenable iterative refinement:\n\numfpack_control = SparseArrays.UMFPACK.get_umfpack_control(Float64, Int64) # read Julia default configuration for a Float64 sparse matrix\nSparseArrays.UMFPACK.show_umf_ctrl(umfpack_control) # optional - display values\numfpack_control[SparseArrays.UMFPACK.JL_UMFPACK_IRSTEP] = 2.0 # reenable iterative refinement (2 is UMFPACK default max iterative refinement steps)\n\nAlu = lu(A; control = umfpack_control)\nx = Alu \\ b # solve Ax = b, including UMFPACK iterative refinement\n\nThe individual components of the factorization F can be accessed by indexing:\n\nComponent Description\nL L (lower triangular) part of LU\nU U (upper triangular) part of LU\np right permutation Vector\nq left permutation Vector\nRs Vector of scaling factors\n: (L,U,p,q,Rs) components\n\nThe relation between F and A is\n\nF.L*F.U == (F.Rs .* A)[F.p, F.q]\n\nF further supports the following functions:\n\n\\\ndet\n\nSee also lu!\n\nnote: Note\nlu(A::AbstractSparseMatrixCSC) uses the UMFPACK[ACM832] library that is part of SuiteSparse. As this library only supports sparse matrices with Float64 or ComplexF64 elements, lu converts A into a copy that is of type SparseMatrixCSC{Float64} or SparseMatrixCSC{ComplexF64} as appropriate.\n\n[ACM832]: Davis, Timothy A. (2004b). Algorithm 832: UMFPACK V4.3–-an Unsymmetric-Pattern Multifrontal Method. ACM Trans. Math. Softw., 30(2), 196–199. doi:10.1145/992200.992206\n\n\n\n\n\nlu(A, pivot = RowMaximum(); check = true, allowsingular = false) -> F::LU\n\nCompute the LU factorization of A.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nBy default, with check = true, an error is also thrown when the decomposition produces valid factors, but the upper-triangular factor U is rank-deficient. This may be changed by passing allowsingular = true.\n\nIn most cases, if A is a subtype S of AbstractMatrix{T} with an element type T supporting +, -, * and /, the return type is LU{T,S{T}}.\n\nIn general, LU factorization involves a permutation of the rows of the matrix (corresponding to the F.p output described below), known as \"pivoting\" (because it corresponds to choosing which row contains the \"pivot\", the diagonal entry of F.U). One of the following pivoting strategies can be selected via the optional pivot argument:\n\nRowMaximum() (default): the standard pivoting strategy; the pivot corresponds to the element of maximum absolute value among the remaining, to be factorized rows. This pivoting strategy requires the element type to also support abs and <. (This is generally the only numerically stable option for floating-point matrices.)\nRowNonZero(): the pivot corresponds to the first non-zero element among the remaining, to be factorized rows. (This corresponds to the typical choice in hand calculations, and is also useful for more general algebraic number types that support iszero but not abs or <.)\nNoPivot(): pivoting turned off (will fail if a zero entry is encountered in a pivot position, even when allowsingular = true).\n\nThe individual components of the factorization F can be accessed via getproperty:\n\nComponent Description\nF.L L (lower triangular) part of LU\nF.U U (upper triangular) part of LU\nF.p (right) permutation Vector\nF.P (right) permutation Matrix\n\nIterating the factorization produces the components F.L, F.U, and F.p.\n\nThe relationship between F and A is\n\nF.L*F.U == A[F.p, :]\n\nF further supports the following functions:\n\nSupported function LU LU{T,Tridiagonal{T}}\n/ ✓ \n\\ ✓ ✓\ninv ✓ ✓\ndet ✓ ✓\nlogdet ✓ ✓\nlogabsdet ✓ ✓\nsize ✓ ✓\n\ncompat: Julia 1.11\nThe allowsingular keyword argument was added in Julia 1.11.\n\nExamples\n\njulia> A = [4 3; 6 3]\n2×2 Matrix{Int64}:\n 4 3\n 6 3\n\njulia> F = lu(A)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.666667 1.0\nU factor:\n2×2 Matrix{Float64}:\n 6.0 3.0\n 0.0 1.0\n\njulia> F.L * F.U == A[F.p, :]\ntrue\n\njulia> l, u, p = lu(A); # destructuring via iteration\n\njulia> l == F.L && u == F.U && p == F.p\ntrue\n\njulia> lu([1 2; 1 2], allowsingular = true)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 1.0 1.0\nU factor (rank-deficient):\n2×2 Matrix{Float64}:\n 1.0 2.0\n 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lu!","page":"Linear Algebra","title":"LinearAlgebra.lu!","text":"lu!(F::UmfpackLU, A::AbstractSparseMatrixCSC; check=true, reuse_symbolic=true, q=nothing) -> F::UmfpackLU\n\nCompute the LU factorization of a sparse matrix A, reusing the symbolic factorization of an already existing LU factorization stored in F. Unless reuse_symbolic is set to false, the sparse matrix A must have an identical nonzero pattern as the matrix used to create the LU factorization F, otherwise an error is thrown. If the size of A and F differ, all vectors will be resized accordingly.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nThe permutation q can either be a permutation vector or nothing. If no permutation vector is provided or q is nothing, UMFPACK's default is used. If the permutation is not zero based, a zero based copy is made.\n\nSee also lu\n\nnote: Note\nlu!(F::UmfpackLU, A::AbstractSparseMatrixCSC) uses the UMFPACK library that is part of SuiteSparse. As this library only supports sparse matrices with Float64 or ComplexF64 elements, lu! will automatically convert the types to those set by the LU factorization or SparseMatrixCSC{ComplexF64} as appropriate.\n\ncompat: Julia 1.5\nlu! for UmfpackLU requires at least Julia 1.5.\n\nExamples\n\njulia> A = sparse(Float64[1.0 2.0; 0.0 3.0]);\n\njulia> F = lu(A);\n\njulia> B = sparse(Float64[1.0 1.0; 0.0 1.0]);\n\njulia> lu!(F, B);\n\njulia> F \\ ones(2)\n2-element Vector{Float64}:\n 0.0\n 1.0\n\n\n\n\n\nlu!(A, pivot = RowMaximum(); check = true, allowsingular = false) -> LU\n\nlu! is the same as lu, but saves space by overwriting the input A, instead of creating a copy. An InexactError exception is thrown if the factorization produces a number not representable by the element type of A, e.g. for integer types.\n\ncompat: Julia 1.11\nThe allowsingular keyword argument was added in Julia 1.11.\n\nExamples\n\njulia> A = [4. 3.; 6. 3.]\n2×2 Matrix{Float64}:\n 4.0 3.0\n 6.0 3.0\n\njulia> F = lu!(A)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.666667 1.0\nU factor:\n2×2 Matrix{Float64}:\n 6.0 3.0\n 0.0 1.0\n\njulia> iA = [4 3; 6 3]\n2×2 Matrix{Int64}:\n 4 3\n 6 3\n\njulia> lu!(iA)\nERROR: InexactError: Int64(0.6666666666666666)\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Cholesky","page":"Linear Algebra","title":"LinearAlgebra.Cholesky","text":"Cholesky <: Factorization\n\nMatrix factorization type of the Cholesky factorization of a dense symmetric/Hermitian positive definite matrix A. This is the return type of cholesky, the corresponding matrix factorization function.\n\nThe triangular Cholesky factor can be obtained from the factorization F::Cholesky via F.L and F.U, where A ≈ F.U' * F.U ≈ F.L * F.L'.\n\nThe following functions are available for Cholesky objects: size, \\, inv, det, logdet and isposdef.\n\nIterating the decomposition produces the components L and U.\n\nExamples\n\njulia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.]\n3×3 Matrix{Float64}:\n 4.0 12.0 -16.0\n 12.0 37.0 -43.0\n -16.0 -43.0 98.0\n\njulia> C = cholesky(A)\nCholesky{Float64, Matrix{Float64}}\nU factor:\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 2.0 6.0 -8.0\n ⋅ 1.0 5.0\n ⋅ ⋅ 3.0\n\njulia> C.U\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 2.0 6.0 -8.0\n ⋅ 1.0 5.0\n ⋅ ⋅ 3.0\n\njulia> C.L\n3×3 LowerTriangular{Float64, Matrix{Float64}}:\n 2.0 ⋅ ⋅\n 6.0 1.0 ⋅\n -8.0 5.0 3.0\n\njulia> C.L * C.U == A\ntrue\n\njulia> l, u = C; # destructuring via iteration\n\njulia> l == C.L && u == C.U\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.CholeskyPivoted","page":"Linear Algebra","title":"LinearAlgebra.CholeskyPivoted","text":"CholeskyPivoted\n\nMatrix factorization type of the pivoted Cholesky factorization of a dense symmetric/Hermitian positive semi-definite matrix A. This is the return type of cholesky(_, ::RowMaximum), the corresponding matrix factorization function.\n\nThe triangular Cholesky factor can be obtained from the factorization F::CholeskyPivoted via F.L and F.U, and the permutation via F.p, where A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr' with Ur = F.U[1:F.rank, :] and Lr = F.L[:, 1:F.rank], or alternatively A ≈ Up' * Up ≈ Lp * Lp' with Up = F.U[1:F.rank, invperm(F.p)] and Lp = F.L[invperm(F.p), 1:F.rank].\n\nThe following functions are available for CholeskyPivoted objects: size, \\, inv, det, and rank.\n\nIterating the decomposition produces the components L and U.\n\nExamples\n\njulia> X = [1.0, 2.0, 3.0, 4.0];\n\njulia> A = X * X';\n\njulia> C = cholesky(A, RowMaximum(), check = false)\nCholeskyPivoted{Float64, Matrix{Float64}, Vector{Int64}}\nU factor with rank 1:\n4×4 UpperTriangular{Float64, Matrix{Float64}}:\n 4.0 2.0 3.0 1.0\n ⋅ 0.0 6.0 2.0\n ⋅ ⋅ 9.0 3.0\n ⋅ ⋅ ⋅ 1.0\npermutation:\n4-element Vector{Int64}:\n 4\n 2\n 3\n 1\n\njulia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p]\ntrue\n\njulia> l, u = C; # destructuring via iteration\n\njulia> l == C.L && u == C.U\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.cholesky","page":"Linear Algebra","title":"LinearAlgebra.cholesky","text":"cholesky(A, NoPivot(); check = true) -> Cholesky\n\nCompute the Cholesky factorization of a dense symmetric positive definite matrix A and return a Cholesky factorization. The matrix A can either be a Symmetric or Hermitian AbstractMatrix or a perfectly symmetric or Hermitian AbstractMatrix.\n\nThe triangular Cholesky factor can be obtained from the factorization F via F.L and F.U, where A ≈ F.U' * F.U ≈ F.L * F.L'.\n\nThe following functions are available for Cholesky objects: size, \\, inv, det, logdet and isposdef.\n\nIf you have a matrix A that is slightly non-Hermitian due to roundoff errors in its construction, wrap it in Hermitian(A) before passing it to cholesky in order to treat it as perfectly Hermitian.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nExamples\n\njulia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.]\n3×3 Matrix{Float64}:\n 4.0 12.0 -16.0\n 12.0 37.0 -43.0\n -16.0 -43.0 98.0\n\njulia> C = cholesky(A)\nCholesky{Float64, Matrix{Float64}}\nU factor:\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 2.0 6.0 -8.0\n ⋅ 1.0 5.0\n ⋅ ⋅ 3.0\n\njulia> C.U\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 2.0 6.0 -8.0\n ⋅ 1.0 5.0\n ⋅ ⋅ 3.0\n\njulia> C.L\n3×3 LowerTriangular{Float64, Matrix{Float64}}:\n 2.0 ⋅ ⋅\n 6.0 1.0 ⋅\n -8.0 5.0 3.0\n\njulia> C.L * C.U == A\ntrue\n\n\n\n\n\ncholesky(A, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted\n\nCompute the pivoted Cholesky factorization of a dense symmetric positive semi-definite matrix A and return a CholeskyPivoted factorization. The matrix A can either be a Symmetric or Hermitian AbstractMatrix or a perfectly symmetric or Hermitian AbstractMatrix.\n\nThe triangular Cholesky factor can be obtained from the factorization F via F.L and F.U, and the permutation via F.p, where A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr' with Ur = F.U[1:F.rank, :] and Lr = F.L[:, 1:F.rank], or alternatively A ≈ Up' * Up ≈ Lp * Lp' with Up = F.U[1:F.rank, invperm(F.p)] and Lp = F.L[invperm(F.p), 1:F.rank].\n\nThe following functions are available for CholeskyPivoted objects: size, \\, inv, det, and rank.\n\nThe argument tol determines the tolerance for determining the rank. For negative values, the tolerance is the machine precision.\n\nIf you have a matrix A that is slightly non-Hermitian due to roundoff errors in its construction, wrap it in Hermitian(A) before passing it to cholesky in order to treat it as perfectly Hermitian.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nExamples\n\njulia> X = [1.0, 2.0, 3.0, 4.0];\n\njulia> A = X * X';\n\njulia> C = cholesky(A, RowMaximum(), check = false)\nCholeskyPivoted{Float64, Matrix{Float64}, Vector{Int64}}\nU factor with rank 1:\n4×4 UpperTriangular{Float64, Matrix{Float64}}:\n 4.0 2.0 3.0 1.0\n ⋅ 0.0 6.0 2.0\n ⋅ ⋅ 9.0 3.0\n ⋅ ⋅ ⋅ 1.0\npermutation:\n4-element Vector{Int64}:\n 4\n 2\n 3\n 1\n\njulia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p]\ntrue\n\njulia> l, u = C; # destructuring via iteration\n\njulia> l == C.L && u == C.U\ntrue\n\n\n\n\n\ncholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.Factor\n\nCompute the Cholesky factorization of a sparse positive definite matrix A. A must be a SparseMatrixCSC or a Symmetric/Hermitian view of a SparseMatrixCSC. Note that even if A doesn't have the type tag, it must still be symmetric or Hermitian. If perm is not given, a fill-reducing permutation is used. F = cholesky(A) is most frequently used to solve systems of equations with F\\b, but also the methods diag, det, and logdet are defined for F. You can also extract individual factors from F, using F.L. However, since pivoting is on by default, the factorization is internally represented as A == P'*L*L'*P with a permutation matrix P; using just L without accounting for P will give incorrect answers. To include the effects of permutation, it's typically preferable to extract \"combined\" factors like PtL = F.PtL (the equivalent of P'*L) and LtP = F.UP (the equivalent of L'*P).\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nSetting the optional shift keyword argument computes the factorization of A+shift*I instead of A. If the perm argument is provided, it should be a permutation of 1:size(A,1) giving the ordering to use (instead of CHOLMOD's default AMD ordering).\n\nExamples\n\nIn the following example, the fill-reducing permutation used is [3, 2, 1]. If perm is set to 1:3 to enforce no permutation, the number of nonzero elements in the factor is 6.\n\njulia> A = [2 1 1; 1 2 0; 1 0 2]\n3×3 Matrix{Int64}:\n 2 1 1\n 1 2 0\n 1 0 2\n\njulia> C = cholesky(sparse(A))\nSparseArrays.CHOLMOD.Factor{Float64, Int64}\ntype: LLt\nmethod: simplicial\nmaxnnz: 5\nnnz: 5\nsuccess: true\n\njulia> C.p\n3-element Vector{Int64}:\n 3\n 2\n 1\n\njulia> L = sparse(C.L);\n\njulia> Matrix(L)\n3×3 Matrix{Float64}:\n 1.41421 0.0 0.0\n 0.0 1.41421 0.0\n 0.707107 0.707107 1.0\n\njulia> L * L' ≈ A[C.p, C.p]\ntrue\n\njulia> P = sparse(1:3, C.p, ones(3))\n3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:\n ⋅ ⋅ 1.0\n ⋅ 1.0 ⋅\n 1.0 ⋅ ⋅\n\njulia> P' * L * L' * P ≈ A\ntrue\n\njulia> C = cholesky(sparse(A), perm=1:3)\nSparseArrays.CHOLMOD.Factor{Float64, Int64}\ntype: LLt\nmethod: simplicial\nmaxnnz: 6\nnnz: 6\nsuccess: true\n\njulia> L = sparse(C.L);\n\njulia> Matrix(L)\n3×3 Matrix{Float64}:\n 1.41421 0.0 0.0\n 0.707107 1.22474 0.0\n 0.707107 -0.408248 1.1547\n\njulia> L * L' ≈ A\ntrue\n\nnote: Note\nThis method uses the CHOLMOD[ACM887][DavisHager2009] library from SuiteSparse. CHOLMOD only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.Many other functions from CHOLMOD are wrapped but not exported from the Base.SparseArrays.CHOLMOD module.\n\n[ACM887]: Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008). Algorithm 887: CHOLMOD, Supernodal Sparse Cholesky Factorization and Update/Downdate. ACM Trans. Math. Softw., 35(3). doi:10.1145/1391989.1391995\n\n[DavisHager2009]: Davis, Timothy A., & Hager, W. W. (2009). Dynamic Supernodes in Sparse Cholesky Update/Downdate and Triangular Solves. ACM Trans. Math. Softw., 35(4). doi:10.1145/1462173.1462176\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.cholesky!","page":"Linear Algebra","title":"LinearAlgebra.cholesky!","text":"cholesky!(A::AbstractMatrix, NoPivot(); check = true) -> Cholesky\n\nThe same as cholesky, but saves space by overwriting the input A, instead of creating a copy. An InexactError exception is thrown if the factorization produces a number not representable by the element type of A, e.g. for integer types.\n\nExamples\n\njulia> A = [1 2; 2 50]\n2×2 Matrix{Int64}:\n 1 2\n 2 50\n\njulia> cholesky!(A)\nERROR: InexactError: Int64(6.782329983125268)\nStacktrace:\n[...]\n\n\n\n\n\ncholesky!(A::AbstractMatrix, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted\n\nThe same as cholesky, but saves space by overwriting the input A, instead of creating a copy. An InexactError exception is thrown if the factorization produces a number not representable by the element type of A, e.g. for integer types.\n\n\n\n\n\ncholesky!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.Factor\n\nCompute the Cholesky (LL) factorization of A, reusing the symbolic factorization F. A must be a SparseMatrixCSC or a Symmetric/ Hermitian view of a SparseMatrixCSC. Note that even if A doesn't have the type tag, it must still be symmetric or Hermitian.\n\nSee also cholesky.\n\nnote: Note\nThis method uses the CHOLMOD library from SuiteSparse, which only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lowrankupdate","page":"Linear Algebra","title":"LinearAlgebra.lowrankupdate","text":"lowrankupdate(C::Cholesky, v::AbstractVector) -> CC::Cholesky\n\nUpdate a Cholesky factorization C with the vector v. If A = C.U'C.U then CC = cholesky(C.U'C.U + v*v') but the computation of CC only uses O(n^2) operations.\n\n\n\n\n\nlowrankupdate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor\n\nGet an LDLt Factorization of A + C*C' given an LDLt or LLt factorization F of A.\n\nThe returned factor is always an LDLt factorization.\n\nSee also lowrankupdate!, lowrankdowndate, lowrankdowndate!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lowrankdowndate","page":"Linear Algebra","title":"LinearAlgebra.lowrankdowndate","text":"lowrankdowndate(C::Cholesky, v::AbstractVector) -> CC::Cholesky\n\nDowndate a Cholesky factorization C with the vector v. If A = C.U'C.U then CC = cholesky(C.U'C.U - v*v') but the computation of CC only uses O(n^2) operations.\n\n\n\n\n\nlowrankdowndate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor\n\nGet an LDLt Factorization of A + C*C' given an LDLt or LLt factorization F of A.\n\nThe returned factor is always an LDLt factorization.\n\nSee also lowrankdowndate!, lowrankupdate, lowrankupdate!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lowrankupdate!","page":"Linear Algebra","title":"LinearAlgebra.lowrankupdate!","text":"lowrankupdate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky\n\nUpdate a Cholesky factorization C with the vector v. If A = C.U'C.U then CC = cholesky(C.U'C.U + v*v') but the computation of CC only uses O(n^2) operations. The input factorization C is updated in place such that on exit C == CC. The vector v is destroyed during the computation.\n\n\n\n\n\nlowrankupdate!(F::CHOLMOD.Factor, C::AbstractArray)\n\nUpdate an LDLt or LLt Factorization F of A to a factorization of A + C*C'.\n\nLLt factorizations are converted to LDLt.\n\nSee also lowrankupdate, lowrankdowndate, lowrankdowndate!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lowrankdowndate!","page":"Linear Algebra","title":"LinearAlgebra.lowrankdowndate!","text":"lowrankdowndate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky\n\nDowndate a Cholesky factorization C with the vector v. If A = C.U'C.U then CC = cholesky(C.U'C.U - v*v') but the computation of CC only uses O(n^2) operations. The input factorization C is updated in place such that on exit C == CC. The vector v is destroyed during the computation.\n\n\n\n\n\nlowrankdowndate!(F::CHOLMOD.Factor, C::AbstractArray)\n\nUpdate an LDLt or LLt Factorization F of A to a factorization of A - C*C'.\n\nLLt factorizations are converted to LDLt.\n\nSee also lowrankdowndate, lowrankupdate, lowrankupdate!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LDLt","page":"Linear Algebra","title":"LinearAlgebra.LDLt","text":"LDLt <: Factorization\n\nMatrix factorization type of the LDLt factorization of a real SymTridiagonal matrix S such that S = L*Diagonal(d)*L', where L is a UnitLowerTriangular matrix and d is a vector. The main use of an LDLt factorization F = ldlt(S) is to solve the linear system of equations Sx = b with F\\b. This is the return type of ldlt, the corresponding matrix factorization function.\n\nThe individual components of the factorization F::LDLt can be accessed via getproperty:\n\nComponent Description\nF.L L (unit lower triangular) part of LDLt\nF.D D (diagonal) part of LDLt\nF.Lt Lt (unit upper triangular) part of LDLt\nF.d diagonal values of D as a Vector\n\nExamples\n\njulia> S = SymTridiagonal([3., 4., 5.], [1., 2.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 3.0 1.0 ⋅\n 1.0 4.0 2.0\n ⋅ 2.0 5.0\n\njulia> F = ldlt(S)\nLDLt{Float64, SymTridiagonal{Float64, Vector{Float64}}}\nL factor:\n3×3 UnitLowerTriangular{Float64, SymTridiagonal{Float64, Vector{Float64}}}:\n 1.0 ⋅ ⋅\n 0.333333 1.0 ⋅\n 0.0 0.545455 1.0\nD factor:\n3×3 Diagonal{Float64, Vector{Float64}}:\n 3.0 ⋅ ⋅\n ⋅ 3.66667 ⋅\n ⋅ ⋅ 3.90909\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ldlt","page":"Linear Algebra","title":"LinearAlgebra.ldlt","text":"ldlt(S::SymTridiagonal) -> LDLt\n\nCompute an LDLt (i.e., LDL^T) factorization of the real symmetric tridiagonal matrix S such that S = L*Diagonal(d)*L' where L is a unit lower triangular matrix and d is a vector. The main use of an LDLt factorization F = ldlt(S) is to solve the linear system of equations Sx = b with F\\b.\n\nSee also bunchkaufman for a similar, but pivoted, factorization of arbitrary symmetric or Hermitian matrices.\n\nExamples\n\njulia> S = SymTridiagonal([3., 4., 5.], [1., 2.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 3.0 1.0 ⋅\n 1.0 4.0 2.0\n ⋅ 2.0 5.0\n\njulia> ldltS = ldlt(S);\n\njulia> b = [6., 7., 8.];\n\njulia> ldltS \\ b\n3-element Vector{Float64}:\n 1.7906976744186047\n 0.627906976744186\n 1.3488372093023255\n\njulia> S \\ b\n3-element Vector{Float64}:\n 1.7906976744186047\n 0.627906976744186\n 1.3488372093023255\n\n\n\n\n\nldlt(A::SparseMatrixCSC; shift = 0.0, check = true, perm=nothing) -> CHOLMOD.Factor\n\nCompute the LDL factorization of a sparse matrix A. A must be a SparseMatrixCSC or a Symmetric/Hermitian view of a SparseMatrixCSC. Note that even if A doesn't have the type tag, it must still be symmetric or Hermitian. A fill-reducing permutation is used. F = ldlt(A) is most frequently used to solve systems of equations A*x = b with F\\b. The returned factorization object F also supports the methods diag, det, logdet, and inv. You can extract individual factors from F using F.L. However, since pivoting is on by default, the factorization is internally represented as A == P'*L*D*L'*P with a permutation matrix P; using just L without accounting for P will give incorrect answers. To include the effects of permutation, it is typically preferable to extract \"combined\" factors like PtL = F.PtL (the equivalent of P'*L) and LtP = F.UP (the equivalent of L'*P). The complete list of supported factors is :L, :PtL, :D, :UP, :U, :LD, :DU, :PtLD, :DUP.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nSetting the optional shift keyword argument computes the factorization of A+shift*I instead of A. If the perm argument is provided, it should be a permutation of 1:size(A,1) giving the ordering to use (instead of CHOLMOD's default AMD ordering).\n\nnote: Note\nThis method uses the CHOLMOD[ACM887][DavisHager2009] library from SuiteSparse. CHOLMOD only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.Many other functions from CHOLMOD are wrapped but not exported from the Base.SparseArrays.CHOLMOD module.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ldlt!","page":"Linear Algebra","title":"LinearAlgebra.ldlt!","text":"ldlt!(S::SymTridiagonal) -> LDLt\n\nSame as ldlt, but saves space by overwriting the input S, instead of creating a copy.\n\nExamples\n\njulia> S = SymTridiagonal([3., 4., 5.], [1., 2.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 3.0 1.0 ⋅\n 1.0 4.0 2.0\n ⋅ 2.0 5.0\n\njulia> ldltS = ldlt!(S);\n\njulia> ldltS === S\nfalse\n\njulia> S\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 3.0 0.333333 ⋅\n 0.333333 3.66667 0.545455\n ⋅ 0.545455 3.90909\n\n\n\n\n\nldlt!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.Factor\n\nCompute the LDL factorization of A, reusing the symbolic factorization F. A must be a SparseMatrixCSC or a Symmetric/Hermitian view of a SparseMatrixCSC. Note that even if A doesn't have the type tag, it must still be symmetric or Hermitian.\n\nSee also ldlt.\n\nnote: Note\nThis method uses the CHOLMOD library from SuiteSparse, which only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.QR","page":"Linear Algebra","title":"LinearAlgebra.QR","text":"QR <: Factorization\n\nA QR matrix factorization stored in a packed format, typically obtained from qr. If A is an m×n matrix, then\n\nA = Q R\n\nwhere Q is an orthogonal/unitary matrix and R is upper triangular. The matrix Q is stored as a sequence of Householder reflectors v_i and coefficients tau_i where:\n\nQ = prod_i=1^min(mn) (I - tau_i v_i v_i^T)\n\nIterating the decomposition produces the components Q and R.\n\nThe object has two fields:\n\nfactors is an m×n matrix.\nThe upper triangular part contains the elements of R, that is R = triu(F.factors) for a QR object F.\nThe subdiagonal part contains the reflectors v_i stored in a packed format where v_i is the ith column of the matrix V = I + tril(F.factors, -1).\nτ is a vector of length min(m,n) containing the coefficients au_i.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.QRCompactWY","page":"Linear Algebra","title":"LinearAlgebra.QRCompactWY","text":"QRCompactWY <: Factorization\n\nA QR matrix factorization stored in a compact blocked format, typically obtained from qr. If A is an m×n matrix, then\n\nA = Q R\n\nwhere Q is an orthogonal/unitary matrix and R is upper triangular. It is similar to the QR format except that the orthogonal/unitary matrix Q is stored in Compact WY format [Schreiber1989]. For the block size n_b, it is stored as a m×n lower trapezoidal matrix V and a matrix T = (T_1 T_2 T_b-1 T_b) composed of b = lceil min(mn) n_b rceil upper triangular matrices T_j of size n_b×n_b (j = 1 b-1) and an upper trapezoidal n_b×min(mn) - (b-1) n_b matrix T_b (j=b) whose upper square part denoted with T_b satisfying\n\nQ = prod_i=1^min(mn) (I - tau_i v_i v_i^T)\n= prod_j=1^b (I - V_j T_j V_j^T)\n\nsuch that v_i is the ith column of V, tau_i is the ith element of [diag(T_1); diag(T_2); …; diag(T_b)], and (V_1 V_2 V_b) is the left m×min(m, n) block of V. When constructed using qr, the block size is given by n_b = min(m n 36).\n\nIterating the decomposition produces the components Q and R.\n\nThe object has two fields:\n\nfactors, as in the QR type, is an m×n matrix.\nThe upper triangular part contains the elements of R, that is R = triu(F.factors) for a QR object F.\nThe subdiagonal part contains the reflectors v_i stored in a packed format such that V = I + tril(F.factors, -1).\nT is a n_b-by-min(mn) matrix as described above. The subdiagonal elements for each triangular matrix T_j are ignored.\n\nnote: Note\nThis format should not to be confused with the older WY representation [Bischof1987].\n\n[Bischof1987]: C Bischof and C Van Loan, \"The WY representation for products of Householder matrices\", SIAM J Sci Stat Comput 8 (1987), s2-s13. doi:10.1137/0908009\n\n[Schreiber1989]: R Schreiber and C Van Loan, \"A storage-efficient WY representation for products of Householder transformations\", SIAM J Sci Stat Comput 10 (1989), 53-57. doi:10.1137/0910005\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.QRPivoted","page":"Linear Algebra","title":"LinearAlgebra.QRPivoted","text":"QRPivoted <: Factorization\n\nA QR matrix factorization with column pivoting in a packed format, typically obtained from qr. If A is an m×n matrix, then\n\nA P = Q R\n\nwhere P is a permutation matrix, Q is an orthogonal/unitary matrix and R is upper triangular. The matrix Q is stored as a sequence of Householder reflectors:\n\nQ = prod_i=1^min(mn) (I - tau_i v_i v_i^T)\n\nIterating the decomposition produces the components Q, R, and p.\n\nThe object has three fields:\n\nfactors is an m×n matrix.\nThe upper triangular part contains the elements of R, that is R = triu(F.factors) for a QR object F.\nThe subdiagonal part contains the reflectors v_i stored in a packed format where v_i is the ith column of the matrix V = I + tril(F.factors, -1).\nτ is a vector of length min(m,n) containing the coefficients au_i.\njpvt is an integer vector of length n corresponding to the permutation P.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.qr","page":"Linear Algebra","title":"LinearAlgebra.qr","text":"qr(A::SparseMatrixCSC; tol=_default_tol(A), ordering=ORDERING_DEFAULT) -> QRSparse\n\nCompute the QR factorization of a sparse matrix A. Fill-reducing row and column permutations are used such that F.R = F.Q'*A[F.prow,F.pcol]. The main application of this type is to solve least squares or underdetermined problems with \\. The function calls the C library SPQR[ACM933].\n\nnote: Note\nqr(A::SparseMatrixCSC) uses the SPQR library that is part of SuiteSparse. As this library only supports sparse matrices with Float64 or ComplexF64 elements, as of Julia v1.4 qr converts A into a copy that is of type SparseMatrixCSC{Float64} or SparseMatrixCSC{ComplexF64} as appropriate.\n\nExamples\n\njulia> A = sparse([1,2,3,4], [1,1,2,2], [1.0,1.0,1.0,1.0])\n4×2 SparseMatrixCSC{Float64, Int64} with 4 stored entries:\n 1.0 ⋅\n 1.0 ⋅\n ⋅ 1.0\n ⋅ 1.0\n\njulia> qr(A)\nSparseArrays.SPQR.QRSparse{Float64, Int64}\nQ factor:\n4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64}\nR factor:\n2×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries:\n -1.41421 ⋅\n ⋅ -1.41421\nRow permutation:\n4-element Vector{Int64}:\n 1\n 3\n 4\n 2\nColumn permutation:\n2-element Vector{Int64}:\n 1\n 2\n\n[ACM933]: Foster, L. V., & Davis, T. A. (2013). Algorithm 933: Reliable Calculation of Numerical Rank, Null Space Bases, Pseudoinverse Solutions, and Basic Solutions Using SuitesparseQR. ACM Trans. Math. Softw., 40(1). doi:10.1145/2513109.2513116\n\n\n\n\n\nqr(A, pivot = NoPivot(); blocksize) -> F\n\nCompute the QR factorization of the matrix A: an orthogonal (or unitary if A is complex-valued) matrix Q, and an upper triangular matrix R such that\n\nA = Q R\n\nThe returned object F stores the factorization in a packed format:\n\nif pivot == ColumnNorm() then F is a QRPivoted object,\notherwise if the element type of A is a BLAS type (Float32, Float64, ComplexF32 or ComplexF64), then F is a QRCompactWY object,\notherwise F is a QR object.\n\nThe individual components of the decomposition F can be retrieved via property accessors:\n\nF.Q: the orthogonal/unitary matrix Q\nF.R: the upper triangular matrix R\nF.p: the permutation vector of the pivot (QRPivoted only)\nF.P: the permutation matrix of the pivot (QRPivoted only)\n\nnote: Note\nEach reference to the upper triangular factor via F.R allocates a new array. It is therefore advisable to cache that array, say, by R = F.R and continue working with R.\n\nIterating the decomposition produces the components Q, R, and if extant p.\n\nThe following functions are available for the QR objects: inv, size, and \\. When A is rectangular, \\ will return a least squares solution and if the solution is not unique, the one with smallest norm is returned. When A is not full rank, factorization with (column) pivoting is required to obtain a minimum norm solution.\n\nMultiplication with respect to either full/square or non-full/square Q is allowed, i.e. both F.Q*F.R and F.Q*A are supported. A Q matrix can be converted into a regular matrix with Matrix. This operation returns the \"thin\" Q factor, i.e., if A is m×n with m>=n, then Matrix(F.Q) yields an m×n matrix with orthonormal columns. To retrieve the \"full\" Q factor, an m×m orthogonal matrix, use F.Q*I or collect(F.Q). If m<=n, then Matrix(F.Q) yields an m×m orthogonal matrix.\n\nThe block size for QR decomposition can be specified by keyword argument blocksize :: Integer when pivot == NoPivot() and A isa StridedMatrix{<:BlasFloat}. It is ignored when blocksize > minimum(size(A)). See QRCompactWY.\n\ncompat: Julia 1.4\nThe blocksize keyword argument requires Julia 1.4 or later.\n\nExamples\n\njulia> A = [3.0 -6.0; 4.0 -8.0; 0.0 1.0]\n3×2 Matrix{Float64}:\n 3.0 -6.0\n 4.0 -8.0\n 0.0 1.0\n\njulia> F = qr(A)\nLinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}\nQ factor: 3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}\nR factor:\n2×2 Matrix{Float64}:\n -5.0 10.0\n 0.0 -1.0\n\njulia> F.Q * F.R == A\ntrue\n\nnote: Note\nqr returns multiple types because LAPACK uses several representations that minimize the memory storage requirements of products of Householder elementary reflectors, so that the Q and R matrices can be stored compactly rather as two separate dense matrices.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.qr!","page":"Linear Algebra","title":"LinearAlgebra.qr!","text":"qr!(A, pivot = NoPivot(); blocksize)\n\nqr! is the same as qr when A is a subtype of AbstractMatrix, but saves space by overwriting the input A, instead of creating a copy. An InexactError exception is thrown if the factorization produces a number not representable by the element type of A, e.g. for integer types.\n\ncompat: Julia 1.4\nThe blocksize keyword argument requires Julia 1.4 or later.\n\nExamples\n\njulia> a = [1. 2.; 3. 4.]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> qr!(a)\nLinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}\nQ factor: 2×2 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}\nR factor:\n2×2 Matrix{Float64}:\n -3.16228 -4.42719\n 0.0 -0.632456\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> qr!(a)\nERROR: InexactError: Int64(3.1622776601683795)\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LQ","page":"Linear Algebra","title":"LinearAlgebra.LQ","text":"LQ <: Factorization\n\nMatrix factorization type of the LQ factorization of a matrix A. The LQ decomposition is the QR decomposition of transpose(A). This is the return type of lq, the corresponding matrix factorization function.\n\nIf S::LQ is the factorization object, the lower triangular component can be obtained via S.L, and the orthogonal/unitary component via S.Q, such that A ≈ S.L*S.Q.\n\nIterating the decomposition produces the components S.L and S.Q.\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> S = lq(A)\nLQ{Float64, Matrix{Float64}, Vector{Float64}}\nL factor:\n2×2 Matrix{Float64}:\n -8.60233 0.0\n 4.41741 -0.697486\nQ factor: 2×2 LinearAlgebra.LQPackedQ{Float64, Matrix{Float64}, Vector{Float64}}\n\njulia> S.L * S.Q\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> l, q = S; # destructuring via iteration\n\njulia> l == S.L && q == S.Q\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lq","page":"Linear Algebra","title":"LinearAlgebra.lq","text":"lq(A) -> S::LQ\n\nCompute the LQ decomposition of A. The decomposition's lower triangular component can be obtained from the LQ object S via S.L, and the orthogonal/unitary component via S.Q, such that A ≈ S.L*S.Q.\n\nIterating the decomposition produces the components S.L and S.Q.\n\nThe LQ decomposition is the QR decomposition of transpose(A), and it is useful in order to compute the minimum-norm solution lq(A) \\ b to an underdetermined system of equations (A has more columns than rows, but has full row rank).\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> S = lq(A)\nLQ{Float64, Matrix{Float64}, Vector{Float64}}\nL factor:\n2×2 Matrix{Float64}:\n -8.60233 0.0\n 4.41741 -0.697486\nQ factor: 2×2 LinearAlgebra.LQPackedQ{Float64, Matrix{Float64}, Vector{Float64}}\n\njulia> S.L * S.Q\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> l, q = S; # destructuring via iteration\n\njulia> l == S.L && q == S.Q\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lq!","page":"Linear Algebra","title":"LinearAlgebra.lq!","text":"lq!(A) -> LQ\n\nCompute the LQ factorization of A, using the input matrix as a workspace. See also lq.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BunchKaufman","page":"Linear Algebra","title":"LinearAlgebra.BunchKaufman","text":"BunchKaufman <: Factorization\n\nMatrix factorization type of the Bunch-Kaufman factorization of a symmetric or Hermitian matrix A as P'UDU'P or P'LDL'P, depending on whether the upper (the default) or the lower triangle is stored in A. If A is complex symmetric then U' and L' denote the unconjugated transposes, i.e. transpose(U) and transpose(L), respectively. This is the return type of bunchkaufman, the corresponding matrix factorization function.\n\nIf S::BunchKaufman is the factorization object, the components can be obtained via S.D, S.U or S.L as appropriate given S.uplo, and S.p.\n\nIterating the decomposition produces the components S.D, S.U or S.L as appropriate given S.uplo, and S.p.\n\nExamples\n\njulia> A = Float64.([1 2; 2 3])\n2×2 Matrix{Float64}:\n 1.0 2.0\n 2.0 3.0\n\njulia> S = bunchkaufman(A) # A gets wrapped internally by Symmetric(A)\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n2×2 Tridiagonal{Float64, Vector{Float64}}:\n -0.333333 0.0\n 0.0 3.0\nU factor:\n2×2 UnitUpperTriangular{Float64, Matrix{Float64}}:\n 1.0 0.666667\n ⋅ 1.0\npermutation:\n2-element Vector{Int64}:\n 1\n 2\n\njulia> d, u, p = S; # destructuring via iteration\n\njulia> d == S.D && u == S.U && p == S.p\ntrue\n\njulia> S = bunchkaufman(Symmetric(A, :L))\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n2×2 Tridiagonal{Float64, Vector{Float64}}:\n 3.0 0.0\n 0.0 -0.333333\nL factor:\n2×2 UnitLowerTriangular{Float64, Matrix{Float64}}:\n 1.0 ⋅\n 0.666667 1.0\npermutation:\n2-element Vector{Int64}:\n 2\n 1\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.bunchkaufman","page":"Linear Algebra","title":"LinearAlgebra.bunchkaufman","text":"bunchkaufman(A, rook::Bool=false; check = true) -> S::BunchKaufman\n\nCompute the Bunch-Kaufman [Bunch1977] factorization of a symmetric or Hermitian matrix A as P'*U*D*U'*P or P'*L*D*L'*P, depending on which triangle is stored in A, and return a BunchKaufman object. Note that if A is complex symmetric then U' and L' denote the unconjugated transposes, i.e. transpose(U) and transpose(L).\n\nIterating the decomposition produces the components S.D, S.U or S.L as appropriate given S.uplo, and S.p.\n\nIf rook is true, rook pivoting is used. If rook is false, rook pivoting is not used.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nThe following functions are available for BunchKaufman objects: size, \\, inv, issymmetric, ishermitian, getindex.\n\n[Bunch1977]: J R Bunch and L Kaufman, Some stable methods for calculating inertia and solving symmetric linear systems, Mathematics of Computation 31:137 (1977), 163-179. url.\n\nExamples\n\njulia> A = Float64.([1 2; 2 3])\n2×2 Matrix{Float64}:\n 1.0 2.0\n 2.0 3.0\n\njulia> S = bunchkaufman(A) # A gets wrapped internally by Symmetric(A)\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n2×2 Tridiagonal{Float64, Vector{Float64}}:\n -0.333333 0.0\n 0.0 3.0\nU factor:\n2×2 UnitUpperTriangular{Float64, Matrix{Float64}}:\n 1.0 0.666667\n ⋅ 1.0\npermutation:\n2-element Vector{Int64}:\n 1\n 2\n\njulia> d, u, p = S; # destructuring via iteration\n\njulia> d == S.D && u == S.U && p == S.p\ntrue\n\njulia> S.U*S.D*S.U' - S.P*A*S.P'\n2×2 Matrix{Float64}:\n 0.0 0.0\n 0.0 0.0\n\njulia> S = bunchkaufman(Symmetric(A, :L))\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n2×2 Tridiagonal{Float64, Vector{Float64}}:\n 3.0 0.0\n 0.0 -0.333333\nL factor:\n2×2 UnitLowerTriangular{Float64, Matrix{Float64}}:\n 1.0 ⋅\n 0.666667 1.0\npermutation:\n2-element Vector{Int64}:\n 2\n 1\n\njulia> S.L*S.D*S.L' - A[S.p, S.p]\n2×2 Matrix{Float64}:\n 0.0 0.0\n 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.bunchkaufman!","page":"Linear Algebra","title":"LinearAlgebra.bunchkaufman!","text":"bunchkaufman!(A, rook::Bool=false; check = true) -> BunchKaufman\n\nbunchkaufman! is the same as bunchkaufman, but saves space by overwriting the input A, instead of creating a copy.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Eigen","page":"Linear Algebra","title":"LinearAlgebra.Eigen","text":"Eigen <: Factorization\n\nMatrix factorization type of the eigenvalue/spectral decomposition of a square matrix A. This is the return type of eigen, the corresponding matrix factorization function.\n\nIf F::Eigen is the factorization object, the eigenvalues can be obtained via F.values and the eigenvectors as the columns of the matrix F.vectors. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nExamples\n\njulia> F = eigen([1.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 18.0])\nEigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}\nvalues:\n3-element Vector{Float64}:\n 1.0\n 3.0\n 18.0\nvectors:\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> F.values\n3-element Vector{Float64}:\n 1.0\n 3.0\n 18.0\n\njulia> F.vectors\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> vals, vecs = F; # destructuring via iteration\n\njulia> vals == F.values && vecs == F.vectors\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.GeneralizedEigen","page":"Linear Algebra","title":"LinearAlgebra.GeneralizedEigen","text":"GeneralizedEigen <: Factorization\n\nMatrix factorization type of the generalized eigenvalue/spectral decomposition of A and B. This is the return type of eigen, the corresponding matrix factorization function, when called with two matrix arguments.\n\nIf F::GeneralizedEigen is the factorization object, the eigenvalues can be obtained via F.values and the eigenvectors as the columns of the matrix F.vectors. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nExamples\n\njulia> A = [1 0; 0 -1]\n2×2 Matrix{Int64}:\n 1 0\n 0 -1\n\njulia> B = [0 1; 1 0]\n2×2 Matrix{Int64}:\n 0 1\n 1 0\n\njulia> F = eigen(A, B)\nGeneralizedEigen{ComplexF64, ComplexF64, Matrix{ComplexF64}, Vector{ComplexF64}}\nvalues:\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\nvectors:\n2×2 Matrix{ComplexF64}:\n 0.0+1.0im 0.0-1.0im\n -1.0+0.0im -1.0-0.0im\n\njulia> F.values\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\n\njulia> F.vectors\n2×2 Matrix{ComplexF64}:\n 0.0+1.0im 0.0-1.0im\n -1.0+0.0im -1.0-0.0im\n\njulia> vals, vecs = F; # destructuring via iteration\n\njulia> vals == F.values && vecs == F.vectors\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigvals","page":"Linear Algebra","title":"LinearAlgebra.eigvals","text":"eigvals(A; permute::Bool=true, scale::Bool=true, sortby) -> values\n\nReturn the eigenvalues of A.\n\nFor general non-symmetric matrices it is possible to specify how the matrix is balanced before the eigenvalue calculation. The permute, scale, and sortby keywords are the same as for eigen.\n\nExamples\n\njulia> diag_matrix = [1 0; 0 4]\n2×2 Matrix{Int64}:\n 1 0\n 0 4\n\njulia> eigvals(diag_matrix)\n2-element Vector{Float64}:\n 1.0\n 4.0\n\n\n\n\n\nFor a scalar input, eigvals will return a scalar.\n\nExamples\n\njulia> eigvals(-2)\n-2\n\n\n\n\n\neigvals(A, B) -> values\n\nCompute the generalized eigenvalues of A and B.\n\nExamples\n\njulia> A = [1 0; 0 -1]\n2×2 Matrix{Int64}:\n 1 0\n 0 -1\n\njulia> B = [0 1; 1 0]\n2×2 Matrix{Int64}:\n 0 1\n 1 0\n\njulia> eigvals(A,B)\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\n\n\n\n\n\neigvals(A::Union{SymTridiagonal, Hermitian, Symmetric}, irange::UnitRange) -> values\n\nReturn the eigenvalues of A. It is possible to calculate only a subset of the eigenvalues by specifying a UnitRange irange covering indices of the sorted eigenvalues, e.g. the 2nd to 8th eigenvalues.\n\nExamples\n\njulia> A = SymTridiagonal([1.; 2.; 1.], [2.; 3.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 1.0 2.0 ⋅\n 2.0 2.0 3.0\n ⋅ 3.0 1.0\n\njulia> eigvals(A, 2:2)\n1-element Vector{Float64}:\n 0.9999999999999996\n\njulia> eigvals(A)\n3-element Vector{Float64}:\n -2.1400549446402604\n 1.0000000000000002\n 5.140054944640259\n\n\n\n\n\neigvals(A::Union{SymTridiagonal, Hermitian, Symmetric}, vl::Real, vu::Real) -> values\n\nReturn the eigenvalues of A. It is possible to calculate only a subset of the eigenvalues by specifying a pair vl and vu for the lower and upper boundaries of the eigenvalues.\n\nExamples\n\njulia> A = SymTridiagonal([1.; 2.; 1.], [2.; 3.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 1.0 2.0 ⋅\n 2.0 2.0 3.0\n ⋅ 3.0 1.0\n\njulia> eigvals(A, -1, 2)\n1-element Vector{Float64}:\n 1.0000000000000009\n\njulia> eigvals(A)\n3-element Vector{Float64}:\n -2.1400549446402604\n 1.0000000000000002\n 5.140054944640259\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigvals!","page":"Linear Algebra","title":"LinearAlgebra.eigvals!","text":"eigvals!(A; permute::Bool=true, scale::Bool=true, sortby) -> values\n\nSame as eigvals, but saves space by overwriting the input A, instead of creating a copy. The permute, scale, and sortby keywords are the same as for eigen.\n\nnote: Note\nThe input matrix A will not contain its eigenvalues after eigvals! is called on it - A is used as a workspace.\n\nExamples\n\njulia> A = [1. 2.; 3. 4.]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> eigvals!(A)\n2-element Vector{Float64}:\n -0.3722813232690143\n 5.372281323269014\n\njulia> A\n2×2 Matrix{Float64}:\n -0.372281 -1.0\n 0.0 5.37228\n\n\n\n\n\neigvals!(A, B; sortby) -> values\n\nSame as eigvals, but saves space by overwriting the input A (and B), instead of creating copies.\n\nnote: Note\nThe input matrices A and B will not contain their eigenvalues after eigvals! is called. They are used as workspaces.\n\nExamples\n\njulia> A = [1. 0.; 0. -1.]\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 -1.0\n\njulia> B = [0. 1.; 1. 0.]\n2×2 Matrix{Float64}:\n 0.0 1.0\n 1.0 0.0\n\njulia> eigvals!(A, B)\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\n\njulia> A\n2×2 Matrix{Float64}:\n -0.0 -1.0\n 1.0 -0.0\n\njulia> B\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\n\n\n\n\n\neigvals!(A::Union{SymTridiagonal, Hermitian, Symmetric}, irange::UnitRange) -> values\n\nSame as eigvals, but saves space by overwriting the input A, instead of creating a copy. irange is a range of eigenvalue indices to search for - for instance, the 2nd to 8th eigenvalues.\n\n\n\n\n\neigvals!(A::Union{SymTridiagonal, Hermitian, Symmetric}, vl::Real, vu::Real) -> values\n\nSame as eigvals, but saves space by overwriting the input A, instead of creating a copy. vl is the lower bound of the interval to search for eigenvalues, and vu is the upper bound.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigmax","page":"Linear Algebra","title":"LinearAlgebra.eigmax","text":"eigmax(A; permute::Bool=true, scale::Bool=true)\n\nReturn the largest eigenvalue of A. The option permute=true permutes the matrix to become closer to upper triangular, and scale=true scales the matrix by its diagonal elements to make rows and columns more equal in norm. Note that if the eigenvalues of A are complex, this method will fail, since complex numbers cannot be sorted.\n\nExamples\n\njulia> A = [0 im; -im 0]\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+1im\n 0-1im 0+0im\n\njulia> eigmax(A)\n1.0\n\njulia> A = [0 im; -1 0]\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+1im\n -1+0im 0+0im\n\njulia> eigmax(A)\nERROR: DomainError with Complex{Int64}[0+0im 0+1im; -1+0im 0+0im]:\n`A` cannot have complex eigenvalues.\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigmin","page":"Linear Algebra","title":"LinearAlgebra.eigmin","text":"eigmin(A; permute::Bool=true, scale::Bool=true)\n\nReturn the smallest eigenvalue of A. The option permute=true permutes the matrix to become closer to upper triangular, and scale=true scales the matrix by its diagonal elements to make rows and columns more equal in norm. Note that if the eigenvalues of A are complex, this method will fail, since complex numbers cannot be sorted.\n\nExamples\n\njulia> A = [0 im; -im 0]\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+1im\n 0-1im 0+0im\n\njulia> eigmin(A)\n-1.0\n\njulia> A = [0 im; -1 0]\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+1im\n -1+0im 0+0im\n\njulia> eigmin(A)\nERROR: DomainError with Complex{Int64}[0+0im 0+1im; -1+0im 0+0im]:\n`A` cannot have complex eigenvalues.\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigvecs","page":"Linear Algebra","title":"LinearAlgebra.eigvecs","text":"eigvecs(A::SymTridiagonal[, eigvals]) -> Matrix\n\nReturn a matrix M whose columns are the eigenvectors of A. (The kth eigenvector can be obtained from the slice M[:, k].)\n\nIf the optional vector of eigenvalues eigvals is specified, eigvecs returns the specific corresponding eigenvectors.\n\nExamples\n\njulia> A = SymTridiagonal([1.; 2.; 1.], [2.; 3.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 1.0 2.0 ⋅\n 2.0 2.0 3.0\n ⋅ 3.0 1.0\n\njulia> eigvals(A)\n3-element Vector{Float64}:\n -2.1400549446402604\n 1.0000000000000002\n 5.140054944640259\n\njulia> eigvecs(A)\n3×3 Matrix{Float64}:\n 0.418304 -0.83205 0.364299\n -0.656749 -7.39009e-16 0.754109\n 0.627457 0.5547 0.546448\n\njulia> eigvecs(A, [1.])\n3×1 Matrix{Float64}:\n 0.8320502943378438\n 4.263514128092366e-17\n -0.5547001962252291\n\n\n\n\n\neigvecs(A; permute::Bool=true, scale::Bool=true, `sortby`) -> Matrix\n\nReturn a matrix M whose columns are the eigenvectors of A. (The kth eigenvector can be obtained from the slice M[:, k].) The permute, scale, and sortby keywords are the same as for eigen.\n\nExamples\n\njulia> eigvecs([1.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 18.0])\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\n\n\n\n\neigvecs(A, B) -> Matrix\n\nReturn a matrix M whose columns are the generalized eigenvectors of A and B. (The kth eigenvector can be obtained from the slice M[:, k].)\n\nExamples\n\njulia> A = [1 0; 0 -1]\n2×2 Matrix{Int64}:\n 1 0\n 0 -1\n\njulia> B = [0 1; 1 0]\n2×2 Matrix{Int64}:\n 0 1\n 1 0\n\njulia> eigvecs(A, B)\n2×2 Matrix{ComplexF64}:\n 0.0+1.0im 0.0-1.0im\n -1.0+0.0im -1.0-0.0im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigen","page":"Linear Algebra","title":"LinearAlgebra.eigen","text":"eigen(A; permute::Bool=true, scale::Bool=true, sortby) -> Eigen\n\nCompute the eigenvalue decomposition of A, returning an Eigen factorization object F which contains the eigenvalues in F.values and the eigenvectors in the columns of the matrix F.vectors. This corresponds to solving an eigenvalue problem of the form Ax = λx, where A is a matrix, x is an eigenvector, and λ is an eigenvalue. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nThe following functions are available for Eigen objects: inv, det, and isposdef.\n\nFor general nonsymmetric matrices it is possible to specify how the matrix is balanced before the eigenvector calculation. The option permute=true permutes the matrix to become closer to upper triangular, and scale=true scales the matrix by its diagonal elements to make rows and columns more equal in norm. The default is true for both options.\n\nBy default, the eigenvalues and vectors are sorted lexicographically by (real(λ),imag(λ)). A different comparison function by(λ) can be passed to sortby, or you can pass sortby=nothing to leave the eigenvalues in an arbitrary order. Some special matrix types (e.g. Diagonal or SymTridiagonal) may implement their own sorting convention and not accept a sortby keyword.\n\nExamples\n\njulia> F = eigen([1.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 18.0])\nEigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}\nvalues:\n3-element Vector{Float64}:\n 1.0\n 3.0\n 18.0\nvectors:\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> F.values\n3-element Vector{Float64}:\n 1.0\n 3.0\n 18.0\n\njulia> F.vectors\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> vals, vecs = F; # destructuring via iteration\n\njulia> vals == F.values && vecs == F.vectors\ntrue\n\n\n\n\n\neigen(A, B; sortby) -> GeneralizedEigen\n\nCompute the generalized eigenvalue decomposition of A and B, returning a GeneralizedEigen factorization object F which contains the generalized eigenvalues in F.values and the generalized eigenvectors in the columns of the matrix F.vectors. This corresponds to solving a generalized eigenvalue problem of the form Ax = λBx, where A, B are matrices, x is an eigenvector, and λ is an eigenvalue. (The kth generalized eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nBy default, the eigenvalues and vectors are sorted lexicographically by (real(λ),imag(λ)). A different comparison function by(λ) can be passed to sortby, or you can pass sortby=nothing to leave the eigenvalues in an arbitrary order.\n\nExamples\n\njulia> A = [1 0; 0 -1]\n2×2 Matrix{Int64}:\n 1 0\n 0 -1\n\njulia> B = [0 1; 1 0]\n2×2 Matrix{Int64}:\n 0 1\n 1 0\n\njulia> F = eigen(A, B);\n\njulia> F.values\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\n\njulia> F.vectors\n2×2 Matrix{ComplexF64}:\n 0.0+1.0im 0.0-1.0im\n -1.0+0.0im -1.0-0.0im\n\njulia> vals, vecs = F; # destructuring via iteration\n\njulia> vals == F.values && vecs == F.vectors\ntrue\n\n\n\n\n\neigen(A::Union{SymTridiagonal, Hermitian, Symmetric}, irange::UnitRange) -> Eigen\n\nCompute the eigenvalue decomposition of A, returning an Eigen factorization object F which contains the eigenvalues in F.values and the eigenvectors in the columns of the matrix F.vectors. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nThe following functions are available for Eigen objects: inv, det, and isposdef.\n\nThe UnitRange irange specifies indices of the sorted eigenvalues to search for.\n\nnote: Note\nIf irange is not 1:n, where n is the dimension of A, then the returned factorization will be a truncated factorization.\n\n\n\n\n\neigen(A::Union{SymTridiagonal, Hermitian, Symmetric}, vl::Real, vu::Real) -> Eigen\n\nCompute the eigenvalue decomposition of A, returning an Eigen factorization object F which contains the eigenvalues in F.values and the eigenvectors in the columns of the matrix F.vectors. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nThe following functions are available for Eigen objects: inv, det, and isposdef.\n\nvl is the lower bound of the window of eigenvalues to search for, and vu is the upper bound.\n\nnote: Note\nIf [vl, vu] does not contain all eigenvalues of A, then the returned factorization will be a truncated factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigen!","page":"Linear Algebra","title":"LinearAlgebra.eigen!","text":"eigen!(A; permute, scale, sortby)\neigen!(A, B; sortby)\n\nSame as eigen, but saves space by overwriting the input A (and B), instead of creating a copy.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Hessenberg","page":"Linear Algebra","title":"LinearAlgebra.Hessenberg","text":"Hessenberg <: Factorization\n\nA Hessenberg object represents the Hessenberg factorization QHQ' of a square matrix, or a shift Q(H+μI)Q' thereof, which is produced by the hessenberg function.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.hessenberg","page":"Linear Algebra","title":"LinearAlgebra.hessenberg","text":"hessenberg(A) -> Hessenberg\n\nCompute the Hessenberg decomposition of A and return a Hessenberg object. If F is the factorization object, the unitary matrix can be accessed with F.Q (of type LinearAlgebra.HessenbergQ) and the Hessenberg matrix with F.H (of type UpperHessenberg), either of which may be converted to a regular matrix with Matrix(F.H) or Matrix(F.Q).\n\nIf A is Hermitian or real-Symmetric, then the Hessenberg decomposition produces a real-symmetric tridiagonal matrix and F.H is of type SymTridiagonal.\n\nNote that the shifted factorization A+μI = Q (H+μI) Q' can be constructed efficiently by F + μ*I using the UniformScaling object I, which creates a new Hessenberg object with shared storage and a modified shift. The shift of a given F is obtained by F.μ. This is useful because multiple shifted solves (F + μ*I) \\ b (for different μ and/or b) can be performed efficiently once F is created.\n\nIterating the decomposition produces the factors F.Q, F.H, F.μ.\n\nExamples\n\njulia> A = [4. 9. 7.; 4. 4. 1.; 4. 3. 2.]\n3×3 Matrix{Float64}:\n 4.0 9.0 7.0\n 4.0 4.0 1.0\n 4.0 3.0 2.0\n\njulia> F = hessenberg(A)\nHessenberg{Float64, UpperHessenberg{Float64, Matrix{Float64}}, Matrix{Float64}, Vector{Float64}, Bool}\nQ factor: 3×3 LinearAlgebra.HessenbergQ{Float64, Matrix{Float64}, Vector{Float64}, false}\nH factor:\n3×3 UpperHessenberg{Float64, Matrix{Float64}}:\n 4.0 -11.3137 -1.41421\n -5.65685 5.0 2.0\n ⋅ -8.88178e-16 1.0\n\njulia> F.Q * F.H * F.Q'\n3×3 Matrix{Float64}:\n 4.0 9.0 7.0\n 4.0 4.0 1.0\n 4.0 3.0 2.0\n\njulia> q, h = F; # destructuring via iteration\n\njulia> q == F.Q && h == F.H\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.hessenberg!","page":"Linear Algebra","title":"LinearAlgebra.hessenberg!","text":"hessenberg!(A) -> Hessenberg\n\nhessenberg! is the same as hessenberg, but saves space by overwriting the input A, instead of creating a copy.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Schur","page":"Linear Algebra","title":"LinearAlgebra.Schur","text":"Schur <: Factorization\n\nMatrix factorization type of the Schur factorization of a matrix A. This is the return type of schur(_), the corresponding matrix factorization function.\n\nIf F::Schur is the factorization object, the (quasi) triangular Schur factor can be obtained via either F.Schur or F.T and the orthogonal/unitary Schur vectors via F.vectors or F.Z such that A = F.vectors * F.Schur * F.vectors'. The eigenvalues of A can be obtained with F.values.\n\nIterating the decomposition produces the components F.T, F.Z, and F.values.\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> F = schur(A)\nSchur{Float64, Matrix{Float64}, Vector{Float64}}\nT factor:\n2×2 Matrix{Float64}:\n 3.0 9.0\n 0.0 -2.0\nZ factor:\n2×2 Matrix{Float64}:\n 0.961524 0.274721\n -0.274721 0.961524\neigenvalues:\n2-element Vector{Float64}:\n 3.0\n -2.0\n\njulia> F.vectors * F.Schur * F.vectors'\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> t, z, vals = F; # destructuring via iteration\n\njulia> t == F.T && z == F.Z && vals == F.values\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.GeneralizedSchur","page":"Linear Algebra","title":"LinearAlgebra.GeneralizedSchur","text":"GeneralizedSchur <: Factorization\n\nMatrix factorization type of the generalized Schur factorization of two matrices A and B. This is the return type of schur(_, _), the corresponding matrix factorization function.\n\nIf F::GeneralizedSchur is the factorization object, the (quasi) triangular Schur factors can be obtained via F.S and F.T, the left unitary/orthogonal Schur vectors via F.left or F.Q, and the right unitary/orthogonal Schur vectors can be obtained with F.right or F.Z such that A=F.left*F.S*F.right' and B=F.left*F.T*F.right'. The generalized eigenvalues of A and B can be obtained with F.α./F.β.\n\nIterating the decomposition produces the components F.S, F.T, F.Q, F.Z, F.α, and F.β.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.schur","page":"Linear Algebra","title":"LinearAlgebra.schur","text":"schur(A) -> F::Schur\n\nComputes the Schur factorization of the matrix A. The (quasi) triangular Schur factor can be obtained from the Schur object F with either F.Schur or F.T and the orthogonal/unitary Schur vectors can be obtained with F.vectors or F.Z such that A = F.vectors * F.Schur * F.vectors'. The eigenvalues of A can be obtained with F.values.\n\nFor real A, the Schur factorization is \"quasitriangular\", which means that it is upper-triangular except with 2×2 diagonal blocks for any conjugate pair of complex eigenvalues; this allows the factorization to be purely real even when there are complex eigenvalues. To obtain the (complex) purely upper-triangular Schur factorization from a real quasitriangular factorization, you can use Schur{Complex}(schur(A)).\n\nIterating the decomposition produces the components F.T, F.Z, and F.values.\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> F = schur(A)\nSchur{Float64, Matrix{Float64}, Vector{Float64}}\nT factor:\n2×2 Matrix{Float64}:\n 3.0 9.0\n 0.0 -2.0\nZ factor:\n2×2 Matrix{Float64}:\n 0.961524 0.274721\n -0.274721 0.961524\neigenvalues:\n2-element Vector{Float64}:\n 3.0\n -2.0\n\njulia> F.vectors * F.Schur * F.vectors'\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> t, z, vals = F; # destructuring via iteration\n\njulia> t == F.T && z == F.Z && vals == F.values\ntrue\n\n\n\n\n\nschur(A, B) -> F::GeneralizedSchur\n\nComputes the Generalized Schur (or QZ) factorization of the matrices A and B. The (quasi) triangular Schur factors can be obtained from the Schur object F with F.S and F.T, the left unitary/orthogonal Schur vectors can be obtained with F.left or F.Q and the right unitary/orthogonal Schur vectors can be obtained with F.right or F.Z such that A=F.left*F.S*F.right' and B=F.left*F.T*F.right'. The generalized eigenvalues of A and B can be obtained with F.α./F.β.\n\nIterating the decomposition produces the components F.S, F.T, F.Q, F.Z, F.α, and F.β.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.schur!","page":"Linear Algebra","title":"LinearAlgebra.schur!","text":"schur!(A) -> F::Schur\n\nSame as schur but uses the input argument A as workspace.\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> F = schur!(A)\nSchur{Float64, Matrix{Float64}, Vector{Float64}}\nT factor:\n2×2 Matrix{Float64}:\n 3.0 9.0\n 0.0 -2.0\nZ factor:\n2×2 Matrix{Float64}:\n 0.961524 0.274721\n -0.274721 0.961524\neigenvalues:\n2-element Vector{Float64}:\n 3.0\n -2.0\n\njulia> A\n2×2 Matrix{Float64}:\n 3.0 9.0\n 0.0 -2.0\n\n\n\n\n\nschur!(A::StridedMatrix, B::StridedMatrix) -> F::GeneralizedSchur\n\nSame as schur but uses the input matrices A and B as workspace.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ordschur","page":"Linear Algebra","title":"LinearAlgebra.ordschur","text":"ordschur(F::Schur, select::Union{Vector{Bool},BitVector}) -> F::Schur\n\nReorders the Schur factorization F of a matrix A = Z*T*Z' according to the logical array select returning the reordered factorization F object. The selected eigenvalues appear in the leading diagonal of F.Schur and the corresponding leading columns of F.vectors form an orthogonal/unitary basis of the corresponding right invariant subspace. In the real case, a complex conjugate pair of eigenvalues must be either both included or both excluded via select.\n\n\n\n\n\nordschur(F::GeneralizedSchur, select::Union{Vector{Bool},BitVector}) -> F::GeneralizedSchur\n\nReorders the Generalized Schur factorization F of a matrix pair (A, B) = (Q*S*Z', Q*T*Z') according to the logical array select and returns a GeneralizedSchur object F. The selected eigenvalues appear in the leading diagonal of both F.S and F.T, and the left and right orthogonal/unitary Schur vectors are also reordered such that (A, B) = F.Q*(F.S, F.T)*F.Z' still holds and the generalized eigenvalues of A and B can still be obtained with F.α./F.β.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ordschur!","page":"Linear Algebra","title":"LinearAlgebra.ordschur!","text":"ordschur!(F::Schur, select::Union{Vector{Bool},BitVector}) -> F::Schur\n\nSame as ordschur but overwrites the factorization F.\n\n\n\n\n\nordschur!(F::GeneralizedSchur, select::Union{Vector{Bool},BitVector}) -> F::GeneralizedSchur\n\nSame as ordschur but overwrites the factorization F.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.SVD","page":"Linear Algebra","title":"LinearAlgebra.SVD","text":"SVD <: Factorization\n\nMatrix factorization type of the singular value decomposition (SVD) of a matrix A. This is the return type of svd(_), the corresponding matrix factorization function.\n\nIf F::SVD is the factorization object, U, S, V and Vt can be obtained via F.U, F.S, F.V and F.Vt, such that A = U * Diagonal(S) * Vt. The singular values in S are sorted in descending order.\n\nIterating the decomposition produces the components U, S, and V.\n\nExamples\n\njulia> A = [1. 0. 0. 0. 2.; 0. 0. 3. 0. 0.; 0. 0. 0. 0. 0.; 0. 2. 0. 0. 0.]\n4×5 Matrix{Float64}:\n 1.0 0.0 0.0 0.0 2.0\n 0.0 0.0 3.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 2.0 0.0 0.0 0.0\n\njulia> F = svd(A)\nSVD{Float64, Float64, Matrix{Float64}, Vector{Float64}}\nU factor:\n4×4 Matrix{Float64}:\n 0.0 1.0 0.0 0.0\n 1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0\n 0.0 0.0 -1.0 0.0\nsingular values:\n4-element Vector{Float64}:\n 3.0\n 2.23606797749979\n 2.0\n 0.0\nVt factor:\n4×5 Matrix{Float64}:\n -0.0 0.0 1.0 -0.0 0.0\n 0.447214 0.0 0.0 0.0 0.894427\n 0.0 -1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0 0.0\n\njulia> F.U * Diagonal(F.S) * F.Vt\n4×5 Matrix{Float64}:\n 1.0 0.0 0.0 0.0 2.0\n 0.0 0.0 3.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 2.0 0.0 0.0 0.0\n\njulia> u, s, v = F; # destructuring via iteration\n\njulia> u == F.U && s == F.S && v == F.V\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.GeneralizedSVD","page":"Linear Algebra","title":"LinearAlgebra.GeneralizedSVD","text":"GeneralizedSVD <: Factorization\n\nMatrix factorization type of the generalized singular value decomposition (SVD) of two matrices A and B, such that A = F.U*F.D1*F.R0*F.Q' and B = F.V*F.D2*F.R0*F.Q'. This is the return type of svd(_, _), the corresponding matrix factorization function.\n\nFor an M-by-N matrix A and P-by-N matrix B,\n\nU is a M-by-M orthogonal matrix,\nV is a P-by-P orthogonal matrix,\nQ is a N-by-N orthogonal matrix,\nD1 is a M-by-(K+L) diagonal matrix with 1s in the first K entries,\nD2 is a P-by-(K+L) matrix whose top right L-by-L block is diagonal,\nR0 is a (K+L)-by-N matrix whose rightmost (K+L)-by-(K+L) block is nonsingular upper block triangular,\n\nK+L is the effective numerical rank of the matrix [A; B].\n\nIterating the decomposition produces the components U, V, Q, D1, D2, and R0.\n\nThe entries of F.D1 and F.D2 are related, as explained in the LAPACK documentation for the generalized SVD and the xGGSVD3 routine which is called underneath (in LAPACK 3.6.0 and newer).\n\nExamples\n\njulia> A = [1. 0.; 0. -1.]\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 -1.0\n\njulia> B = [0. 1.; 1. 0.]\n2×2 Matrix{Float64}:\n 0.0 1.0\n 1.0 0.0\n\njulia> F = svd(A, B)\nGeneralizedSVD{Float64, Matrix{Float64}, Float64, Vector{Float64}}\nU factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\nV factor:\n2×2 Matrix{Float64}:\n -0.0 -1.0\n 1.0 0.0\nQ factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\nD1 factor:\n2×2 Matrix{Float64}:\n 0.707107 0.0\n 0.0 0.707107\nD2 factor:\n2×2 Matrix{Float64}:\n 0.707107 0.0\n 0.0 0.707107\nR0 factor:\n2×2 Matrix{Float64}:\n 1.41421 0.0\n 0.0 -1.41421\n\njulia> F.U*F.D1*F.R0*F.Q'\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 -1.0\n\njulia> F.V*F.D2*F.R0*F.Q'\n2×2 Matrix{Float64}:\n -0.0 1.0\n 1.0 0.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.svd","page":"Linear Algebra","title":"LinearAlgebra.svd","text":"svd(A; full::Bool = false, alg::Algorithm = default_svd_alg(A)) -> SVD\n\nCompute the singular value decomposition (SVD) of A and return an SVD object.\n\nU, S, V and Vt can be obtained from the factorization F with F.U, F.S, F.V and F.Vt, such that A = U * Diagonal(S) * Vt. The algorithm produces Vt and hence Vt is more efficient to extract than V. The singular values in S are sorted in descending order.\n\nIterating the decomposition produces the components U, S, and V.\n\nIf full = false (default), a \"thin\" SVD is returned. For an M times N matrix A, in the full factorization U is M times M and V is N times N, while in the thin factorization U is M times K and V is N times K, where K = min(MN) is the number of singular values.\n\nIf alg = DivideAndConquer() a divide-and-conquer algorithm is used to calculate the SVD. Another (typically slower but more accurate) option is alg = QRIteration().\n\ncompat: Julia 1.3\nThe alg keyword argument requires Julia 1.3 or later.\n\nExamples\n\njulia> A = rand(4,3);\n\njulia> F = svd(A); # Store the Factorization Object\n\njulia> A ≈ F.U * Diagonal(F.S) * F.Vt\ntrue\n\njulia> U, S, V = F; # destructuring via iteration\n\njulia> A ≈ U * Diagonal(S) * V'\ntrue\n\njulia> Uonly, = svd(A); # Store U only\n\njulia> Uonly == U\ntrue\n\n\n\n\n\nsvd(A, B) -> GeneralizedSVD\n\nCompute the generalized SVD of A and B, returning a GeneralizedSVD factorization object F such that [A;B] = [F.U * F.D1; F.V * F.D2] * F.R0 * F.Q'\n\nU is a M-by-M orthogonal matrix,\nV is a P-by-P orthogonal matrix,\nQ is a N-by-N orthogonal matrix,\nD1 is a M-by-(K+L) diagonal matrix with 1s in the first K entries,\nD2 is a P-by-(K+L) matrix whose top right L-by-L block is diagonal,\nR0 is a (K+L)-by-N matrix whose rightmost (K+L)-by-(K+L) block is nonsingular upper block triangular,\n\nK+L is the effective numerical rank of the matrix [A; B].\n\nIterating the decomposition produces the components U, V, Q, D1, D2, and R0.\n\nThe generalized SVD is used in applications such as when one wants to compare how much belongs to A vs. how much belongs to B, as in human vs yeast genome, or signal vs noise, or between clusters vs within clusters. (See Edelman and Wang for discussion: https://arxiv.org/abs/1901.00485)\n\nIt decomposes [A; B] into [UC; VS]H, where [UC; VS] is a natural orthogonal basis for the column space of [A; B], and H = RQ' is a natural non-orthogonal basis for the rowspace of [A;B], where the top rows are most closely attributed to the A matrix, and the bottom to the B matrix. The multi-cosine/sine matrices C and S provide a multi-measure of how much A vs how much B, and U and V provide directions in which these are measured.\n\nExamples\n\njulia> A = randn(3,2); B=randn(4,2);\n\njulia> F = svd(A, B);\n\njulia> U,V,Q,C,S,R = F;\n\njulia> H = R*Q';\n\njulia> [A; B] ≈ [U*C; V*S]*H\ntrue\n\njulia> [A; B] ≈ [F.U*F.D1; F.V*F.D2]*F.R0*F.Q'\ntrue\n\njulia> Uonly, = svd(A,B);\n\njulia> U == Uonly\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.svd!","page":"Linear Algebra","title":"LinearAlgebra.svd!","text":"svd!(A; full::Bool = false, alg::Algorithm = default_svd_alg(A)) -> SVD\n\nsvd! is the same as svd, but saves space by overwriting the input A, instead of creating a copy. See documentation of svd for details.\n\n\n\n\n\nsvd!(A, B) -> GeneralizedSVD\n\nsvd! is the same as svd, but modifies the arguments A and B in-place, instead of making copies. See documentation of svd for details.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.svdvals","page":"Linear Algebra","title":"LinearAlgebra.svdvals","text":"svdvals(A)\n\nReturn the singular values of A in descending order.\n\nExamples\n\njulia> A = [1. 0. 0. 0. 2.; 0. 0. 3. 0. 0.; 0. 0. 0. 0. 0.; 0. 2. 0. 0. 0.]\n4×5 Matrix{Float64}:\n 1.0 0.0 0.0 0.0 2.0\n 0.0 0.0 3.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 2.0 0.0 0.0 0.0\n\njulia> svdvals(A)\n4-element Vector{Float64}:\n 3.0\n 2.23606797749979\n 2.0\n 0.0\n\n\n\n\n\nsvdvals(A, B)\n\nReturn the generalized singular values from the generalized singular value decomposition of A and B. See also svd.\n\nExamples\n\njulia> A = [1. 0.; 0. -1.]\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 -1.0\n\njulia> B = [0. 1.; 1. 0.]\n2×2 Matrix{Float64}:\n 0.0 1.0\n 1.0 0.0\n\njulia> svdvals(A, B)\n2-element Vector{Float64}:\n 1.0\n 1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.svdvals!","page":"Linear Algebra","title":"LinearAlgebra.svdvals!","text":"svdvals!(A)\n\nReturn the singular values of A, saving space by overwriting the input. See also svdvals and svd.\n\n\n\n\n\nsvdvals!(A, B)\n\nReturn the generalized singular values from the generalized singular value decomposition of A and B, saving space by overwriting A and B. See also svd and svdvals.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Givens","page":"Linear Algebra","title":"LinearAlgebra.Givens","text":"LinearAlgebra.Givens(i1,i2,c,s) -> G\n\nA Givens rotation linear operator. The fields c and s represent the cosine and sine of the rotation angle, respectively. The Givens type supports left multiplication G*A and conjugated transpose right multiplication A*G'. The type doesn't have a size and can therefore be multiplied with matrices of arbitrary size as long as i2<=size(A,2) for G*A or i2<=size(A,1) for A*G'.\n\nSee also givens.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.givens","page":"Linear Algebra","title":"LinearAlgebra.givens","text":"givens(f::T, g::T, i1::Integer, i2::Integer) where {T} -> (G::Givens, r::T)\n\nComputes the Givens rotation G and scalar r such that for any vector x where\n\nx[i1] = f\nx[i2] = g\n\nthe result of the multiplication\n\ny = G*x\n\nhas the property that\n\ny[i1] = r\ny[i2] = 0\n\nSee also LinearAlgebra.Givens.\n\n\n\n\n\ngivens(A::AbstractArray, i1::Integer, i2::Integer, j::Integer) -> (G::Givens, r)\n\nComputes the Givens rotation G and scalar r such that the result of the multiplication\n\nB = G*A\n\nhas the property that\n\nB[i1,j] = r\nB[i2,j] = 0\n\nSee also LinearAlgebra.Givens.\n\n\n\n\n\ngivens(x::AbstractVector, i1::Integer, i2::Integer) -> (G::Givens, r)\n\nComputes the Givens rotation G and scalar r such that the result of the multiplication\n\nB = G*x\n\nhas the property that\n\nB[i1] = r\nB[i2] = 0\n\nSee also LinearAlgebra.Givens.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.triu","page":"Linear Algebra","title":"LinearAlgebra.triu","text":"triu(M)\n\nUpper triangle of a matrix.\n\nExamples\n\njulia> a = fill(1.0, (4,4))\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> triu(a)\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 0.0 1.0 1.0 1.0\n 0.0 0.0 1.0 1.0\n 0.0 0.0 0.0 1.0\n\n\n\n\n\ntriu(M, k::Integer)\n\nReturn the upper triangle of M starting from the kth superdiagonal.\n\nExamples\n\njulia> a = fill(1.0, (4,4))\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> triu(a,3)\n4×4 Matrix{Float64}:\n 0.0 0.0 0.0 1.0\n 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0\n\njulia> triu(a,-3)\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.triu!","page":"Linear Algebra","title":"LinearAlgebra.triu!","text":"triu!(M)\n\nUpper triangle of a matrix, overwriting M in the process. See also triu.\n\n\n\n\n\ntriu!(M, k::Integer)\n\nReturn the upper triangle of M starting from the kth superdiagonal, overwriting M in the process.\n\nExamples\n\njulia> M = [1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5]\n5×5 Matrix{Int64}:\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n\njulia> triu!(M, 1)\n5×5 Matrix{Int64}:\n 0 2 3 4 5\n 0 0 3 4 5\n 0 0 0 4 5\n 0 0 0 0 5\n 0 0 0 0 0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.tril","page":"Linear Algebra","title":"LinearAlgebra.tril","text":"tril(M)\n\nLower triangle of a matrix.\n\nExamples\n\njulia> a = fill(1.0, (4,4))\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> tril(a)\n4×4 Matrix{Float64}:\n 1.0 0.0 0.0 0.0\n 1.0 1.0 0.0 0.0\n 1.0 1.0 1.0 0.0\n 1.0 1.0 1.0 1.0\n\n\n\n\n\ntril(M, k::Integer)\n\nReturn the lower triangle of M starting from the kth superdiagonal.\n\nExamples\n\njulia> a = fill(1.0, (4,4))\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> tril(a,3)\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> tril(a,-3)\n4×4 Matrix{Float64}:\n 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0\n 1.0 0.0 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.tril!","page":"Linear Algebra","title":"LinearAlgebra.tril!","text":"tril!(M)\n\nLower triangle of a matrix, overwriting M in the process. See also tril.\n\n\n\n\n\ntril!(M, k::Integer)\n\nReturn the lower triangle of M starting from the kth superdiagonal, overwriting M in the process.\n\nExamples\n\njulia> M = [1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5]\n5×5 Matrix{Int64}:\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n\njulia> tril!(M, 2)\n5×5 Matrix{Int64}:\n 1 2 3 0 0\n 1 2 3 4 0\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.diagind","page":"Linear Algebra","title":"LinearAlgebra.diagind","text":"diagind(M::AbstractMatrix, k::Integer = 0, indstyle::IndexStyle = IndexLinear())\ndiagind(M::AbstractMatrix, indstyle::IndexStyle = IndexLinear())\n\nAn AbstractRange giving the indices of the kth diagonal of the matrix M. Optionally, an index style may be specified which determines the type of the range returned. If indstyle isa IndexLinear (default), this returns an AbstractRange{Integer}. On the other hand, if indstyle isa IndexCartesian, this returns an AbstractRange{CartesianIndex{2}}.\n\nIf k is not provided, it is assumed to be 0 (corresponding to the main diagonal).\n\nSee also: diag, diagm, Diagonal.\n\nExamples\n\njulia> A = [1 2 3; 4 5 6; 7 8 9]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n 7 8 9\n\njulia> diagind(A, -1)\n2:4:6\n\njulia> diagind(A, IndexCartesian())\nStepRangeLen(CartesianIndex(1, 1), CartesianIndex(1, 1), 3)\n\ncompat: Julia 1.11\nSpecifying an IndexStyle requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.diag","page":"Linear Algebra","title":"LinearAlgebra.diag","text":"diag(M, k::Integer=0)\n\nThe kth diagonal of a matrix, as a vector.\n\nSee also diagm, diagind, Diagonal, isdiag.\n\nExamples\n\njulia> A = [1 2 3; 4 5 6; 7 8 9]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n 7 8 9\n\njulia> diag(A,1)\n2-element Vector{Int64}:\n 2\n 6\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.diagm","page":"Linear Algebra","title":"LinearAlgebra.diagm","text":"diagm(kv::Pair{<:Integer,<:AbstractVector}...)\ndiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)\n\nConstruct a matrix from Pairs of diagonals and vectors. Vector kv.second will be placed on the kv.first diagonal. By default the matrix is square and its size is inferred from kv, but a non-square size m×n (padded with zeros as needed) can be specified by passing m,n as the first arguments. For repeated diagonal indices kv.first the values in the corresponding vectors kv.second will be added.\n\ndiagm constructs a full matrix; if you want storage-efficient versions with fast arithmetic, see Diagonal, Bidiagonal Tridiagonal and SymTridiagonal.\n\nExamples\n\njulia> diagm(1 => [1,2,3])\n4×4 Matrix{Int64}:\n 0 1 0 0\n 0 0 2 0\n 0 0 0 3\n 0 0 0 0\n\njulia> diagm(1 => [1,2,3], -1 => [4,5])\n4×4 Matrix{Int64}:\n 0 1 0 0\n 4 0 2 0\n 0 5 0 3\n 0 0 0 0\n\njulia> diagm(1 => [1,2,3], 1 => [1,2,3])\n4×4 Matrix{Int64}:\n 0 2 0 0\n 0 0 4 0\n 0 0 0 6\n 0 0 0 0\n\n\n\n\n\ndiagm(v::AbstractVector)\ndiagm(m::Integer, n::Integer, v::AbstractVector)\n\nConstruct a matrix with elements of the vector as diagonal elements. By default, the matrix is square and its size is given by length(v), but a non-square size m×n can be specified by passing m,n as the first arguments.\n\nExamples\n\njulia> diagm([1,2,3])\n3×3 Matrix{Int64}:\n 1 0 0\n 0 2 0\n 0 0 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.rank","page":"Linear Algebra","title":"LinearAlgebra.rank","text":"rank(::QRSparse{Tv,Ti}) -> Ti\n\nReturn the rank of the QR factorization\n\n\n\n\n\nrank(S::SparseMatrixCSC{Tv,Ti}; [tol::Real]) -> Ti\n\nCalculate rank of S by calculating its QR factorization. Values smaller than tol are considered as zero. See SPQR's manual.\n\n\n\n\n\nrank(A::AbstractMatrix; atol::Real=0, rtol::Real=atol>0 ? 0 : n*ϵ)\nrank(A::AbstractMatrix, rtol::Real)\n\nCompute the numerical rank of a matrix by counting how many outputs of svdvals(A) are greater than max(atol, rtol*σ₁) where σ₁ is A's largest calculated singular value. atol and rtol are the absolute and relative tolerances, respectively. The default relative tolerance is n*ϵ, where n is the size of the smallest dimension of A, and ϵ is the eps of the element type of A.\n\nnote: Note\nNumerical rank can be a sensitive and imprecise characterization of ill-conditioned matrices with singular values that are close to the threshold tolerance max(atol, rtol*σ₁). In such cases, slight perturbations to the singular-value computation or to the matrix can change the result of rank by pushing one or more singular values across the threshold. These variations can even occur due to changes in floating-point errors between different Julia versions, architectures, compilers, or operating systems.\n\ncompat: Julia 1.1\nThe atol and rtol keyword arguments requires at least Julia 1.1. In Julia 1.0 rtol is available as a positional argument, but this will be deprecated in Julia 2.0.\n\nExamples\n\njulia> rank(Matrix(I, 3, 3))\n3\n\njulia> rank(diagm(0 => [1, 0, 2]))\n2\n\njulia> rank(diagm(0 => [1, 0.001, 2]), rtol=0.1)\n2\n\njulia> rank(diagm(0 => [1, 0.001, 2]), rtol=0.00001)\n3\n\njulia> rank(diagm(0 => [1, 0.001, 2]), atol=1.5)\n1\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.norm","page":"Linear Algebra","title":"LinearAlgebra.norm","text":"norm(A, p::Real=2)\n\nFor any iterable container A (including arrays of any dimension) of numbers (or any element type for which norm is defined), compute the p-norm (defaulting to p=2) as if A were a vector of the corresponding length.\n\nThe p-norm is defined as\n\nA_p = left( sum_i=1^n a_i ^p right)^1p\n\nwith a_i the entries of A, a_i the norm of a_i, and n the length of A. Since the p-norm is computed using the norms of the entries of A, the p-norm of a vector of vectors is not compatible with the interpretation of it as a block vector in general if p != 2.\n\np can assume any numeric value (even though not all values produce a mathematically valid vector norm). In particular, norm(A, Inf) returns the largest value in abs.(A), whereas norm(A, -Inf) returns the smallest. If A is a matrix and p=2, then this is equivalent to the Frobenius norm.\n\nThe second argument p is not necessarily a part of the interface for norm, i.e. a custom type may only implement norm(A) without second argument.\n\nUse opnorm to compute the operator norm of a matrix.\n\nExamples\n\njulia> v = [3, -2, 6]\n3-element Vector{Int64}:\n 3\n -2\n 6\n\njulia> norm(v)\n7.0\n\njulia> norm(v, 1)\n11.0\n\njulia> norm(v, Inf)\n6.0\n\njulia> norm([1 2 3; 4 5 6; 7 8 9])\n16.881943016134134\n\njulia> norm([1 2 3 4 5 6 7 8 9])\n16.881943016134134\n\njulia> norm(1:9)\n16.881943016134134\n\njulia> norm(hcat(v,v), 1) == norm(vcat(v,v), 1) != norm([v,v], 1)\ntrue\n\njulia> norm(hcat(v,v), 2) == norm(vcat(v,v), 2) == norm([v,v], 2)\ntrue\n\njulia> norm(hcat(v,v), Inf) == norm(vcat(v,v), Inf) != norm([v,v], Inf)\ntrue\n\n\n\n\n\nnorm(x::Number, p::Real=2)\n\nFor numbers, return left( x^p right)^1p.\n\nExamples\n\njulia> norm(2, 1)\n2.0\n\njulia> norm(-2, 1)\n2.0\n\njulia> norm(2, 2)\n2.0\n\njulia> norm(-2, 2)\n2.0\n\njulia> norm(2, Inf)\n2.0\n\njulia> norm(-2, Inf)\n2.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.opnorm","page":"Linear Algebra","title":"LinearAlgebra.opnorm","text":"opnorm(A::AbstractMatrix, p::Real=2)\n\nCompute the operator norm (or matrix norm) induced by the vector p-norm, where valid values of p are 1, 2, or Inf. (Note that for sparse matrices, p=2 is currently not implemented.) Use norm to compute the Frobenius norm.\n\nWhen p=1, the operator norm is the maximum absolute column sum of A:\n\nA_1 = max_1 j n sum_i=1^m a_ij \n\nwith a_ij the entries of A, and m and n its dimensions.\n\nWhen p=2, the operator norm is the spectral norm, equal to the largest singular value of A.\n\nWhen p=Inf, the operator norm is the maximum absolute row sum of A:\n\nA_infty = max_1 i m sum _j=1^n a_ij \n\nExamples\n\njulia> A = [1 -2 -3; 2 3 -1]\n2×3 Matrix{Int64}:\n 1 -2 -3\n 2 3 -1\n\njulia> opnorm(A, Inf)\n6.0\n\njulia> opnorm(A, 1)\n5.0\n\n\n\n\n\nopnorm(x::Number, p::Real=2)\n\nFor numbers, return left( x^p right)^1p. This is equivalent to norm.\n\n\n\n\n\nopnorm(A::Adjoint{<:Any,<:AbstractVector}, q::Real=2)\nopnorm(A::Transpose{<:Any,<:AbstractVector}, q::Real=2)\n\nFor Adjoint/Transpose-wrapped vectors, return the operator q-norm of A, which is equivalent to the p-norm with value p = q/(q-1). They coincide at p = q = 2. Use norm to compute the p norm of A as a vector.\n\nThe difference in norm between a vector space and its dual arises to preserve the relationship between duality and the dot product, and the result is consistent with the operator p-norm of a 1 × n matrix.\n\nExamples\n\njulia> v = [1; im];\n\njulia> vc = v';\n\njulia> opnorm(vc, 1)\n1.0\n\njulia> norm(vc, 1)\n2.0\n\njulia> norm(v, 1)\n2.0\n\njulia> opnorm(vc, 2)\n1.4142135623730951\n\njulia> norm(vc, 2)\n1.4142135623730951\n\njulia> norm(v, 2)\n1.4142135623730951\n\njulia> opnorm(vc, Inf)\n2.0\n\njulia> norm(vc, Inf)\n1.0\n\njulia> norm(v, Inf)\n1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.normalize!","page":"Linear Algebra","title":"LinearAlgebra.normalize!","text":"normalize!(a::AbstractArray, p::Real=2)\n\nNormalize the array a in-place so that its p-norm equals unity, i.e. norm(a, p) == 1. See also normalize and norm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.normalize","page":"Linear Algebra","title":"LinearAlgebra.normalize","text":"normalize(a, p::Real=2)\n\nNormalize a so that its p-norm equals unity, i.e. norm(a, p) == 1. For scalars, this is similar to sign(a), except normalize(0) = NaN. See also normalize!, norm, and sign.\n\nExamples\n\njulia> a = [1,2,4];\n\njulia> b = normalize(a)\n3-element Vector{Float64}:\n 0.2182178902359924\n 0.4364357804719848\n 0.8728715609439696\n\njulia> norm(b)\n1.0\n\njulia> c = normalize(a, 1)\n3-element Vector{Float64}:\n 0.14285714285714285\n 0.2857142857142857\n 0.5714285714285714\n\njulia> norm(c, 1)\n1.0\n\njulia> a = [1 2 4 ; 1 2 4]\n2×3 Matrix{Int64}:\n 1 2 4\n 1 2 4\n\njulia> norm(a)\n6.48074069840786\n\njulia> normalize(a)\n2×3 Matrix{Float64}:\n 0.154303 0.308607 0.617213\n 0.154303 0.308607 0.617213\n\njulia> normalize(3, 1)\n1.0\n\njulia> normalize(-8, 1)\n-1.0\n\njulia> normalize(0, 1)\nNaN\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.cond","page":"Linear Algebra","title":"LinearAlgebra.cond","text":"cond(M, p::Real=2)\n\nCondition number of the matrix M, computed using the operator p-norm. Valid values for p are 1, 2 (default), or Inf.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.condskeel","page":"Linear Algebra","title":"LinearAlgebra.condskeel","text":"condskeel(M, [x, p::Real=Inf])\n\nkappa_S(M p) = leftVert leftvert M rightvert leftvert M^-1 rightvert rightVert_p \nkappa_S(M x p) = fracleftVert leftvert M rightvert leftvert M^-1 rightvert leftvert x rightvert rightVert_pleft Vert x right Vert_p\n\nSkeel condition number kappa_S of the matrix M, optionally with respect to the vector x, as computed using the operator p-norm. leftvert M rightvert denotes the matrix of (entry wise) absolute values of M; leftvert M rightvert_ij = leftvert M_ij rightvert. Valid values for p are 1, 2 and Inf (default).\n\nThis quantity is also known in the literature as the Bauer condition number, relative condition number, or componentwise relative condition number.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.tr","page":"Linear Algebra","title":"LinearAlgebra.tr","text":"tr(M)\n\nMatrix trace. Sums the diagonal elements of M.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> tr(A)\n5\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.det","page":"Linear Algebra","title":"LinearAlgebra.det","text":"det(M)\n\nMatrix determinant.\n\nSee also: logdet and logabsdet.\n\nExamples\n\njulia> M = [1 0; 2 2]\n2×2 Matrix{Int64}:\n 1 0\n 2 2\n\njulia> det(M)\n2.0\n\nNote that, in general, det computes a floating-point approximation of the determinant, even for integer matrices, typically via Gaussian elimination. Julia includes an exact algorithm for integer determinants (the Bareiss algorithm), but only uses it by default for BigInt matrices (since determinants quickly overflow any fixed integer precision):\n\njulia> det(BigInt[1 0; 2 2]) # exact integer determinant\n2\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.logdet","page":"Linear Algebra","title":"LinearAlgebra.logdet","text":"logdet(M)\n\nLogarithm of matrix determinant. Equivalent to log(det(M)), but may provide increased accuracy and avoids overflow/underflow.\n\nExamples\n\njulia> M = [1 0; 2 2]\n2×2 Matrix{Int64}:\n 1 0\n 2 2\n\njulia> logdet(M)\n0.6931471805599453\n\njulia> logdet(Matrix(I, 3, 3))\n0.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.logabsdet","page":"Linear Algebra","title":"LinearAlgebra.logabsdet","text":"logabsdet(M)\n\nLog of absolute value of matrix determinant. Equivalent to (log(abs(det(M))), sign(det(M))), but may provide increased accuracy and/or speed.\n\nExamples\n\njulia> A = [-1. 0.; 0. 1.]\n2×2 Matrix{Float64}:\n -1.0 0.0\n 0.0 1.0\n\njulia> det(A)\n-1.0\n\njulia> logabsdet(A)\n(0.0, -1.0)\n\njulia> B = [2. 0.; 0. 1.]\n2×2 Matrix{Float64}:\n 2.0 0.0\n 0.0 1.0\n\njulia> det(B)\n2.0\n\njulia> logabsdet(B)\n(0.6931471805599453, 1.0)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.inv-Tuple{AbstractMatrix}","page":"Linear Algebra","title":"Base.inv","text":"inv(M)\n\nMatrix inverse. Computes matrix N such that M * N = I, where I is the identity matrix. Computed by solving the left-division N = M \\ I.\n\nExamples\n\njulia> M = [2 5; 1 3]\n2×2 Matrix{Int64}:\n 2 5\n 1 3\n\njulia> N = inv(M)\n2×2 Matrix{Float64}:\n 3.0 -5.0\n -1.0 2.0\n\njulia> M*N == N*M == Matrix(I, 2, 2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.pinv","page":"Linear Algebra","title":"LinearAlgebra.pinv","text":"pinv(M; atol::Real=0, rtol::Real=atol>0 ? 0 : n*ϵ)\npinv(M, rtol::Real) = pinv(M; rtol=rtol) # to be deprecated in Julia 2.0\n\nComputes the Moore-Penrose pseudoinverse.\n\nFor matrices M with floating point elements, it is convenient to compute the pseudoinverse by inverting only singular values greater than max(atol, rtol*σ₁) where σ₁ is the largest singular value of M.\n\nThe optimal choice of absolute (atol) and relative tolerance (rtol) varies both with the value of M and the intended application of the pseudoinverse. The default relative tolerance is n*ϵ, where n is the size of the smallest dimension of M, and ϵ is the eps of the element type of M.\n\nFor inverting dense ill-conditioned matrices in a least-squares sense, rtol = sqrt(eps(real(float(oneunit(eltype(M)))))) is recommended.\n\nFor more information, see [issue8859], [B96], [S84], [KY88].\n\nExamples\n\njulia> M = [1.5 1.3; 1.2 1.9]\n2×2 Matrix{Float64}:\n 1.5 1.3\n 1.2 1.9\n\njulia> N = pinv(M)\n2×2 Matrix{Float64}:\n 1.47287 -1.00775\n -0.930233 1.16279\n\njulia> M * N\n2×2 Matrix{Float64}:\n 1.0 -2.22045e-16\n 4.44089e-16 1.0\n\n[issue8859]: Issue 8859, \"Fix least squares\", https://github.com/JuliaLang/julia/pull/8859\n\n[B96]: Åke Björck, \"Numerical Methods for Least Squares Problems\", SIAM Press, Philadelphia, 1996, \"Other Titles in Applied Mathematics\", Vol. 51. doi:10.1137/1.9781611971484\n\n[S84]: G. W. Stewart, \"Rank Degeneracy\", SIAM Journal on Scientific and Statistical Computing, 5(2), 1984, 403-413. doi:10.1137/0905030\n\n[KY88]: Konstantinos Konstantinides and Kung Yao, \"Statistical analysis of effective singular values in matrix rank determination\", IEEE Transactions on Acoustics, Speech and Signal Processing, 36(5), 1988, 757-763. doi:10.1109/29.1585\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.nullspace","page":"Linear Algebra","title":"LinearAlgebra.nullspace","text":"nullspace(M; atol::Real=0, rtol::Real=atol>0 ? 0 : n*ϵ)\nnullspace(M, rtol::Real) = nullspace(M; rtol=rtol) # to be deprecated in Julia 2.0\n\nComputes a basis for the nullspace of M by including the singular vectors of M whose singular values have magnitudes smaller than max(atol, rtol*σ₁), where σ₁ is M's largest singular value.\n\nBy default, the relative tolerance rtol is n*ϵ, where n is the size of the smallest dimension of M, and ϵ is the eps of the element type of M.\n\nExamples\n\njulia> M = [1 0 0; 0 1 0; 0 0 0]\n3×3 Matrix{Int64}:\n 1 0 0\n 0 1 0\n 0 0 0\n\njulia> nullspace(M)\n3×1 Matrix{Float64}:\n 0.0\n 0.0\n 1.0\n\njulia> nullspace(M, rtol=3)\n3×3 Matrix{Float64}:\n 0.0 1.0 0.0\n 1.0 0.0 0.0\n 0.0 0.0 1.0\n\njulia> nullspace(M, atol=0.95)\n3×1 Matrix{Float64}:\n 0.0\n 0.0\n 1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.kron","page":"Linear Algebra","title":"Base.kron","text":"kron(A, B)\n\nComputes the Kronecker product of two vectors, matrices or numbers.\n\nFor real vectors v and w, the Kronecker product is related to the outer product by kron(v,w) == vec(w * transpose(v)) or w * transpose(v) == reshape(kron(v,w), (length(w), length(v))). Note how the ordering of v and w differs on the left and right of these expressions (due to column-major storage). For complex vectors, the outer product w * v' also differs by conjugation of v.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> B = [im 1; 1 -im]\n2×2 Matrix{Complex{Int64}}:\n 0+1im 1+0im\n 1+0im 0-1im\n\njulia> kron(A, B)\n4×4 Matrix{Complex{Int64}}:\n 0+1im 1+0im 0+2im 2+0im\n 1+0im 0-1im 2+0im 0-2im\n 0+3im 3+0im 0+4im 4+0im\n 3+0im 0-3im 4+0im 0-4im\n\njulia> v = [1, 2]; w = [3, 4, 5];\n\njulia> w*transpose(v)\n3×2 Matrix{Int64}:\n 3 6\n 4 8\n 5 10\n\njulia> reshape(kron(v,w), (length(w), length(v)))\n3×2 Matrix{Int64}:\n 3 6\n 4 8\n 5 10\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.kron!","page":"Linear Algebra","title":"Base.kron!","text":"kron!(C, A, B)\n\nComputes the Kronecker product of A and B and stores the result in C, overwriting the existing content of C. This is the in-place version of kron.\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.exp-Tuple{StridedMatrix{var\"#s9708\"} where var\"#s9708\"<:Union{Float32, Float64, ComplexF64, ComplexF32}}","page":"Linear Algebra","title":"Base.exp","text":"exp(A::AbstractMatrix)\n\nCompute the matrix exponential of A, defined by\n\ne^A = sum_n=0^infty fracA^nn\n\nFor symmetric or Hermitian A, an eigendecomposition (eigen) is used, otherwise the scaling and squaring algorithm (see [H05]) is chosen.\n\n[H05]: Nicholas J. Higham, \"The squaring and scaling method for the matrix exponential revisited\", SIAM Journal on Matrix Analysis and Applications, 26(4), 2005, 1179-1193. doi:10.1137/090768539\n\nExamples\n\njulia> A = Matrix(1.0I, 2, 2)\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\n\njulia> exp(A)\n2×2 Matrix{Float64}:\n 2.71828 0.0\n 0.0 2.71828\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.cis-Tuple{AbstractMatrix}","page":"Linear Algebra","title":"Base.cis","text":"cis(A::AbstractMatrix)\n\nMore efficient method for exp(im*A) of square matrix A (especially if A is Hermitian or real-Symmetric).\n\nSee also cispi, sincos, exp.\n\ncompat: Julia 1.7\nSupport for using cis with matrices was added in Julia 1.7.\n\nExamples\n\njulia> cis([π 0; 0 π]) ≈ -I\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:^-Tuple{AbstractMatrix, Number}","page":"Linear Algebra","title":"Base.:^","text":"^(A::AbstractMatrix, p::Number)\n\nMatrix power, equivalent to exp(plog(A))\n\nExamples\n\njulia> [1 2; 0 3]^3\n2×2 Matrix{Int64}:\n 1 26\n 0 27\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:^-Tuple{Number, AbstractMatrix}","page":"Linear Algebra","title":"Base.:^","text":"^(b::Number, A::AbstractMatrix)\n\nMatrix exponential, equivalent to exp(log(b)A).\n\ncompat: Julia 1.1\nSupport for raising Irrational numbers (like ℯ) to a matrix was added in Julia 1.1.\n\nExamples\n\njulia> 2^[1 2; 0 3]\n2×2 Matrix{Float64}:\n 2.0 6.0\n 0.0 8.0\n\njulia> ℯ^[1 2; 0 3]\n2×2 Matrix{Float64}:\n 2.71828 17.3673\n 0.0 20.0855\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.log-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.log","text":"log(A::AbstractMatrix)\n\nIf A has no negative real eigenvalue, compute the principal matrix logarithm of A, i.e. the unique matrix X such that e^X = A and -pi Im(lambda) pi for all the eigenvalues lambda of X. If A has nonpositive eigenvalues, a nonprincipal matrix function is returned whenever possible.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used, if A is triangular an improved version of the inverse scaling and squaring method is employed (see [AH12] and [AHR13]). If A is real with no negative eigenvalues, then the real Schur form is computed. Otherwise, the complex Schur form is computed. Then the upper (quasi-)triangular algorithm in [AHR13] is used on the upper (quasi-)triangular factor.\n\n[AH12]: Awad H. Al-Mohy and Nicholas J. Higham, \"Improved inverse scaling and squaring algorithms for the matrix logarithm\", SIAM Journal on Scientific Computing, 34(4), 2012, C153-C169. doi:10.1137/110852553\n\n[AHR13]: Awad H. Al-Mohy, Nicholas J. Higham and Samuel D. Relton, \"Computing the Fréchet derivative of the matrix logarithm and estimating the condition number\", SIAM Journal on Scientific Computing, 35(4), 2013, C394-C410. doi:10.1137/120885991\n\nExamples\n\njulia> A = Matrix(2.7182818*I, 2, 2)\n2×2 Matrix{Float64}:\n 2.71828 0.0\n 0.0 2.71828\n\njulia> log(A)\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.sqrt-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.sqrt","text":"sqrt(x)\n\nReturn sqrtx.\n\nThrow a DomainError for negative Real arguments. Use Complex negative arguments instead to obtain a Complex result.\n\nThe prefix operator √ is equivalent to sqrt.\n\nnote: Branch cut\nsqrt has a branch cut along the negative real axis; -0.0im is taken to be below the axis.\n\nSee also: hypot.\n\nExamples\n\njulia> sqrt(big(81))\n9.0\n\njulia> sqrt(big(-81))\nERROR: DomainError with -81.0:\nNaN result for non-NaN input.\nStacktrace:\n [1] sqrt(::BigFloat) at ./mpfr.jl:501\n[...]\n\njulia> sqrt(big(complex(-81)))\n0.0 + 9.0im\n\njulia> sqrt(-81 - 0.0im) # -0.0im is below the branch cut\n0.0 - 9.0im\n\njulia> .√(1:4)\n4-element Vector{Float64}:\n 1.0\n 1.4142135623730951\n 1.7320508075688772\n 2.0\n\n\n\n\n\nsqrt(A::AbstractMatrix)\n\nIf A has no negative real eigenvalues, compute the principal matrix square root of A, that is the unique matrix X with eigenvalues having positive real part such that X^2 = A. Otherwise, a nonprincipal square root is returned.\n\nIf A is real-symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the square root. For such matrices, eigenvalues λ that appear to be slightly negative due to roundoff errors are treated as if they were zero. More precisely, matrices with all eigenvalues ≥ -rtol*(max |λ|) are treated as semidefinite (yielding a Hermitian square root), with negative eigenvalues taken to be zero. rtol is a keyword argument to sqrt (in the Hermitian/real-symmetric case only) that defaults to machine precision scaled by size(A,1).\n\nOtherwise, the square root is determined by means of the Björck-Hammarling method [BH83], which computes the complex Schur form (schur) and then the complex square root of the triangular factor. If a real square root exists, then an extension of this method [H87] that computes the real Schur form and then the real square root of the quasi-triangular factor is instead used.\n\n[BH83]: Åke Björck and Sven Hammarling, \"A Schur method for the square root of a matrix\", Linear Algebra and its Applications, 52-53, 1983, 127-140. doi:10.1016/0024-3795(83)80010-X\n\n[H87]: Nicholas J. Higham, \"Computing real square roots of a real matrix\", Linear Algebra and its Applications, 88-89, 1987, 405-430. doi:10.1016/0024-3795(87)90118-2\n\nExamples\n\njulia> A = [4 0; 0 4]\n2×2 Matrix{Int64}:\n 4 0\n 0 4\n\njulia> sqrt(A)\n2×2 Matrix{Float64}:\n 2.0 0.0\n 0.0 2.0\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.cbrt-Tuple{AbstractMatrix{<:Real}}","page":"Linear Algebra","title":"Base.Math.cbrt","text":"cbrt(A::AbstractMatrix{<:Real})\n\nComputes the real-valued cube root of a real-valued matrix A. If T = cbrt(A), then we have T*T*T ≈ A, see example given below.\n\nIf A is symmetric, i.e., of type HermOrSym{<:Real}, then (eigen) is used to find the cube root. Otherwise, a specialized version of the p-th root algorithm [S03] is utilized, which exploits the real-valued Schur decomposition (schur) to compute the cube root.\n\n[S03]: Matthew I. Smith, \"A Schur Algorithm for Computing Matrix pth Roots\", SIAM Journal on Matrix Analysis and Applications, vol. 24, 2003, pp. 971–989. doi:10.1137/S0895479801392697\n\nExamples\n\njulia> A = [0.927524 -0.15857; -1.3677 -1.01172]\n2×2 Matrix{Float64}:\n 0.927524 -0.15857\n -1.3677 -1.01172\n\njulia> T = cbrt(A)\n2×2 Matrix{Float64}:\n 0.910077 -0.151019\n -1.30257 -0.936818\n\njulia> T*T*T ≈ A\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.cos-Tuple{StridedMatrix{var\"#s9710\"} where var\"#s9710\"<:Real}","page":"Linear Algebra","title":"Base.cos","text":"cos(A::AbstractMatrix)\n\nCompute the matrix cosine of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the cosine. Otherwise, the cosine is determined by calling exp.\n\nExamples\n\njulia> cos(fill(1.0, (2,2)))\n2×2 Matrix{Float64}:\n 0.291927 -0.708073\n -0.708073 0.291927\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.sin-Tuple{StridedMatrix{var\"#s9711\"} where var\"#s9711\"<:Real}","page":"Linear Algebra","title":"Base.sin","text":"sin(A::AbstractMatrix)\n\nCompute the matrix sine of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the sine. Otherwise, the sine is determined by calling exp.\n\nExamples\n\njulia> sin(fill(1.0, (2,2)))\n2×2 Matrix{Float64}:\n 0.454649 0.454649\n 0.454649 0.454649\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.sincos-Tuple{StridedMatrix{var\"#s9712\"} where var\"#s9712\"<:Real}","page":"Linear Algebra","title":"Base.Math.sincos","text":"sincos(A::AbstractMatrix)\n\nCompute the matrix sine and cosine of a square matrix A.\n\nExamples\n\njulia> S, C = sincos(fill(1.0, (2,2)));\n\njulia> S\n2×2 Matrix{Float64}:\n 0.454649 0.454649\n 0.454649 0.454649\n\njulia> C\n2×2 Matrix{Float64}:\n 0.291927 -0.708073\n -0.708073 0.291927\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.tan-Tuple{StridedMatrix{var\"#s9713\"} where var\"#s9713\"<:Real}","page":"Linear Algebra","title":"Base.tan","text":"tan(A::AbstractMatrix)\n\nCompute the matrix tangent of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\nExamples\n\njulia> tan(fill(1.0, (2,2)))\n2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.sec-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.sec","text":"sec(A::AbstractMatrix)\n\nCompute the matrix secant of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.csc-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.csc","text":"csc(A::AbstractMatrix)\n\nCompute the matrix cosecant of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.cot-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.cot","text":"cot(A::AbstractMatrix)\n\nCompute the matrix cotangent of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.cosh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.cosh","text":"cosh(A::AbstractMatrix)\n\nCompute the matrix hyperbolic cosine of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.sinh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.sinh","text":"sinh(A::AbstractMatrix)\n\nCompute the matrix hyperbolic sine of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.tanh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.tanh","text":"tanh(A::AbstractMatrix)\n\nCompute the matrix hyperbolic tangent of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.sech-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.sech","text":"sech(A::AbstractMatrix)\n\nCompute the matrix hyperbolic secant of square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.csch-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.csch","text":"csch(A::AbstractMatrix)\n\nCompute the matrix hyperbolic cosecant of square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.coth-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.coth","text":"coth(A::AbstractMatrix)\n\nCompute the matrix hyperbolic cotangent of square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.acos-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.acos","text":"acos(A::AbstractMatrix)\n\nCompute the inverse matrix cosine of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the inverse cosine. Otherwise, the inverse cosine is determined by using log and sqrt. For the theory and logarithmic formulas used to compute this function, see [AH16_1].\n\n[AH16_1]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\nExamples\n\njulia> acos(cos([0.5 0.1; -0.2 0.3]))\n2×2 Matrix{ComplexF64}:\n 0.5-8.32667e-17im 0.1+0.0im\n -0.2+2.63678e-16im 0.3-3.46945e-16im\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.asin-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.asin","text":"asin(A::AbstractMatrix)\n\nCompute the inverse matrix sine of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the inverse sine. Otherwise, the inverse sine is determined by using log and sqrt. For the theory and logarithmic formulas used to compute this function, see [AH16_2].\n\n[AH16_2]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\nExamples\n\njulia> asin(sin([0.5 0.1; -0.2 0.3]))\n2×2 Matrix{ComplexF64}:\n 0.5-4.16334e-17im 0.1-5.55112e-17im\n -0.2+9.71445e-17im 0.3-1.249e-16im\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.atan-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.atan","text":"atan(A::AbstractMatrix)\n\nCompute the inverse matrix tangent of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the inverse tangent. Otherwise, the inverse tangent is determined by using log. For the theory and logarithmic formulas used to compute this function, see [AH16_3].\n\n[AH16_3]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\nExamples\n\njulia> atan(tan([0.5 0.1; -0.2 0.3]))\n2×2 Matrix{ComplexF64}:\n 0.5+1.38778e-17im 0.1-2.77556e-17im\n -0.2+6.93889e-17im 0.3-4.16334e-17im\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.asec-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.asec","text":"asec(A::AbstractMatrix)\n\nCompute the inverse matrix secant of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.acsc-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.acsc","text":"acsc(A::AbstractMatrix)\n\nCompute the inverse matrix cosecant of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.acot-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.acot","text":"acot(A::AbstractMatrix)\n\nCompute the inverse matrix cotangent of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.acosh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.acosh","text":"acosh(A::AbstractMatrix)\n\nCompute the inverse hyperbolic matrix cosine of a square matrix A. For the theory and logarithmic formulas used to compute this function, see [AH16_4].\n\n[AH16_4]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.asinh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.asinh","text":"asinh(A::AbstractMatrix)\n\nCompute the inverse hyperbolic matrix sine of a square matrix A. For the theory and logarithmic formulas used to compute this function, see [AH16_5].\n\n[AH16_5]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.atanh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.atanh","text":"atanh(A::AbstractMatrix)\n\nCompute the inverse hyperbolic matrix tangent of a square matrix A. For the theory and logarithmic formulas used to compute this function, see [AH16_6].\n\n[AH16_6]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.asech-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.asech","text":"asech(A::AbstractMatrix)\n\nCompute the inverse matrix hyperbolic secant of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.acsch-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.acsch","text":"acsch(A::AbstractMatrix)\n\nCompute the inverse matrix hyperbolic cosecant of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.acoth-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.acoth","text":"acoth(A::AbstractMatrix)\n\nCompute the inverse matrix hyperbolic cotangent of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lyap","page":"Linear Algebra","title":"LinearAlgebra.lyap","text":"lyap(A, C)\n\nComputes the solution X to the continuous Lyapunov equation AX + XA' + C = 0, where no eigenvalue of A has a zero real part and no two eigenvalues are negative complex conjugates of each other.\n\nExamples\n\njulia> A = [3. 4.; 5. 6]\n2×2 Matrix{Float64}:\n 3.0 4.0\n 5.0 6.0\n\njulia> B = [1. 1.; 1. 2.]\n2×2 Matrix{Float64}:\n 1.0 1.0\n 1.0 2.0\n\njulia> X = lyap(A, B)\n2×2 Matrix{Float64}:\n 0.5 -0.5\n -0.5 0.25\n\njulia> A*X + X*A' ≈ -B\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.sylvester","page":"Linear Algebra","title":"LinearAlgebra.sylvester","text":"sylvester(A, B, C)\n\nComputes the solution X to the Sylvester equation AX + XB + C = 0, where A, B and C have compatible dimensions and A and -B have no eigenvalues with equal real part.\n\nExamples\n\njulia> A = [3. 4.; 5. 6]\n2×2 Matrix{Float64}:\n 3.0 4.0\n 5.0 6.0\n\njulia> B = [1. 1.; 1. 2.]\n2×2 Matrix{Float64}:\n 1.0 1.0\n 1.0 2.0\n\njulia> C = [1. 2.; -2. 1]\n2×2 Matrix{Float64}:\n 1.0 2.0\n -2.0 1.0\n\njulia> X = sylvester(A, B, C)\n2×2 Matrix{Float64}:\n -4.46667 1.93333\n 3.73333 -1.8\n\njulia> A*X + X*B ≈ -C\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.issuccess","page":"Linear Algebra","title":"LinearAlgebra.issuccess","text":"issuccess(F::Factorization)\n\nTest that a factorization of a matrix succeeded.\n\ncompat: Julia 1.6\nissuccess(::CholeskyPivoted) requires Julia 1.6 or later.\n\nExamples\n\njulia> F = cholesky([1 0; 0 1]);\n\njulia> issuccess(F)\ntrue\n\n\n\n\n\nissuccess(F::LU; allowsingular = false)\n\nTest that the LU factorization of a matrix succeeded. By default a factorization that produces a valid but rank-deficient U factor is considered a failure. This can be changed by passing allowsingular = true.\n\ncompat: Julia 1.11\nThe allowsingular keyword argument was added in Julia 1.11.\n\nExamples\n\njulia> F = lu([1 2; 1 2], check = false);\n\njulia> issuccess(F)\nfalse\n\njulia> issuccess(F, allowsingular = true)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.issymmetric","page":"Linear Algebra","title":"LinearAlgebra.issymmetric","text":"issymmetric(A) -> Bool\n\nTest whether a matrix is symmetric.\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> issymmetric(a)\ntrue\n\njulia> b = [1 im; -im 1]\n2×2 Matrix{Complex{Int64}}:\n 1+0im 0+1im\n 0-1im 1+0im\n\njulia> issymmetric(b)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.isposdef","page":"Linear Algebra","title":"LinearAlgebra.isposdef","text":"isposdef(A) -> Bool\n\nTest whether a matrix is positive definite (and Hermitian) by trying to perform a Cholesky factorization of A.\n\nSee also isposdef!, cholesky.\n\nExamples\n\njulia> A = [1 2; 2 50]\n2×2 Matrix{Int64}:\n 1 2\n 2 50\n\njulia> isposdef(A)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.isposdef!","page":"Linear Algebra","title":"LinearAlgebra.isposdef!","text":"isposdef!(A) -> Bool\n\nTest whether a matrix is positive definite (and Hermitian) by trying to perform a Cholesky factorization of A, overwriting A in the process. See also isposdef.\n\nExamples\n\njulia> A = [1. 2.; 2. 50.];\n\njulia> isposdef!(A)\ntrue\n\njulia> A\n2×2 Matrix{Float64}:\n 1.0 2.0\n 2.0 6.78233\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.istril","page":"Linear Algebra","title":"LinearAlgebra.istril","text":"istril(A::AbstractMatrix, k::Integer = 0) -> Bool\n\nTest whether A is lower triangular starting from the kth superdiagonal.\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> istril(a)\nfalse\n\njulia> istril(a, 1)\ntrue\n\njulia> c = [1 1 0; 1 1 1; 1 1 1]\n3×3 Matrix{Int64}:\n 1 1 0\n 1 1 1\n 1 1 1\n\njulia> istril(c)\nfalse\n\njulia> istril(c, 1)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.istriu","page":"Linear Algebra","title":"LinearAlgebra.istriu","text":"istriu(A::AbstractMatrix, k::Integer = 0) -> Bool\n\nTest whether A is upper triangular starting from the kth superdiagonal.\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> istriu(a)\nfalse\n\njulia> istriu(a, -1)\ntrue\n\njulia> c = [1 1 1; 1 1 1; 0 1 1]\n3×3 Matrix{Int64}:\n 1 1 1\n 1 1 1\n 0 1 1\n\njulia> istriu(c)\nfalse\n\njulia> istriu(c, -1)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.isdiag","page":"Linear Algebra","title":"LinearAlgebra.isdiag","text":"isdiag(A) -> Bool\n\nTest whether a matrix is diagonal in the sense that iszero(A[i,j]) is true unless i == j. Note that it is not necessary for A to be square; if you would also like to check that, you need to check that size(A, 1) == size(A, 2).\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> isdiag(a)\nfalse\n\njulia> b = [im 0; 0 -im]\n2×2 Matrix{Complex{Int64}}:\n 0+1im 0+0im\n 0+0im 0-1im\n\njulia> isdiag(b)\ntrue\n\njulia> c = [1 0 0; 0 2 0]\n2×3 Matrix{Int64}:\n 1 0 0\n 0 2 0\n\njulia> isdiag(c)\ntrue\n\njulia> d = [1 0 0; 0 2 3]\n2×3 Matrix{Int64}:\n 1 0 0\n 0 2 3\n\njulia> isdiag(d)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ishermitian","page":"Linear Algebra","title":"LinearAlgebra.ishermitian","text":"ishermitian(A) -> Bool\n\nTest whether a matrix is Hermitian.\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> ishermitian(a)\ntrue\n\njulia> b = [1 im; -im 1]\n2×2 Matrix{Complex{Int64}}:\n 1+0im 0+1im\n 0-1im 1+0im\n\njulia> ishermitian(b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.transpose","page":"Linear Algebra","title":"Base.transpose","text":"transpose(A)\n\nLazy transpose. Mutating the returned object should appropriately mutate A. Often, but not always, yields Transpose(A), where Transpose is a lazy transpose wrapper. Note that this operation is recursive.\n\nThis operation is intended for linear algebra usage - for general data manipulation see permutedims, which is non-recursive.\n\nExamples\n\njulia> A = [3 2; 0 0]\n2×2 Matrix{Int64}:\n 3 2\n 0 0\n\njulia> B = transpose(A)\n2×2 transpose(::Matrix{Int64}) with eltype Int64:\n 3 0\n 2 0\n\njulia> B isa Transpose\ntrue\n\njulia> transpose(B) === A # the transpose of a transpose unwraps the parent\ntrue\n\njulia> Transpose(B) # however, the constructor always wraps its argument\n2×2 transpose(transpose(::Matrix{Int64})) with eltype Int64:\n 3 2\n 0 0\n\njulia> B[1,2] = 4; # modifying B will modify A automatically\n\njulia> A\n2×2 Matrix{Int64}:\n 3 2\n 4 0\n\nFor complex matrices, the adjoint operation is equivalent to a conjugate-transpose.\n\njulia> A = reshape([Complex(x, x) for x in 1:4], 2, 2)\n2×2 Matrix{Complex{Int64}}:\n 1+1im 3+3im\n 2+2im 4+4im\n\njulia> adjoint(A) == conj(transpose(A))\ntrue\n\nThe transpose of an AbstractVector is a row-vector:\n\njulia> v = [1,2,3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> transpose(v) # returns a row-vector\n1×3 transpose(::Vector{Int64}) with eltype Int64:\n 1 2 3\n\njulia> transpose(v) * v # compute the dot product\n14\n\nFor a matrix of matrices, the individual blocks are recursively operated on:\n\njulia> C = [1 3; 2 4]\n2×2 Matrix{Int64}:\n 1 3\n 2 4\n\njulia> D = reshape([C, 2C, 3C, 4C], 2, 2) # construct a block matrix\n2×2 Matrix{Matrix{Int64}}:\n [1 3; 2 4] [3 9; 6 12]\n [2 6; 4 8] [4 12; 8 16]\n\njulia> transpose(D) # blocks are recursively transposed\n2×2 transpose(::Matrix{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:\n [1 2; 3 4] [2 4; 6 8]\n [3 6; 9 12] [4 8; 12 16]\n\n\n\n\n\ntranspose(F::Factorization)\n\nLazy transpose of the factorization F. By default, returns a TransposeFactorization, except for Factorizations with real eltype, in which case returns an AdjointFactorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.transpose!","page":"Linear Algebra","title":"LinearAlgebra.transpose!","text":"transpose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}) where {Tv,Ti}\n\nTranspose the matrix A and stores it in the matrix X. size(X) must be equal to size(transpose(A)). No additional memory is allocated other than resizing the rowval and nzval of X, if needed.\n\nSee halfperm!\n\n\n\n\n\ntranspose!(dest,src)\n\nTranspose array src and store the result in the preallocated array dest, which should have a size corresponding to (size(src,2),size(src,1)). No in-place transposition is supported and unexpected results will happen if src and dest have overlapping memory regions.\n\nExamples\n\njulia> A = [3+2im 9+2im; 8+7im 4+6im]\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 8+7im 4+6im\n\njulia> B = zeros(Complex{Int64}, 2, 2)\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+0im\n 0+0im 0+0im\n\njulia> transpose!(B, A);\n\njulia> B\n2×2 Matrix{Complex{Int64}}:\n 3+2im 8+7im\n 9+2im 4+6im\n\njulia> A\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 8+7im 4+6im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Transpose","page":"Linear Algebra","title":"LinearAlgebra.Transpose","text":"Transpose\n\nLazy wrapper type for a transpose view of the underlying linear algebra object, usually an AbstractVector/AbstractMatrix. Usually, the Transpose constructor should not be called directly, use transpose instead. To materialize the view use copy.\n\nThis type is intended for linear algebra usage - for general data manipulation see permutedims.\n\nExamples\n\njulia> A = [2 3; 0 0]\n2×2 Matrix{Int64}:\n 2 3\n 0 0\n\njulia> Transpose(A)\n2×2 transpose(::Matrix{Int64}) with eltype Int64:\n 2 0\n 3 0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.TransposeFactorization","page":"Linear Algebra","title":"LinearAlgebra.TransposeFactorization","text":"TransposeFactorization\n\nLazy wrapper type for the transpose of the underlying Factorization object. Usually, the TransposeFactorization constructor should not be called directly, use transpose(:: Factorization) instead.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#Base.adjoint","page":"Linear Algebra","title":"Base.adjoint","text":"A'\nadjoint(A)\n\nLazy adjoint (conjugate transposition). Note that adjoint is applied recursively to elements.\n\nFor number types, adjoint returns the complex conjugate, and therefore it is equivalent to the identity function for real numbers.\n\nThis operation is intended for linear algebra usage - for general data manipulation see permutedims.\n\nExamples\n\njulia> A = [3+2im 9+2im; 0 0]\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 0+0im 0+0im\n\njulia> B = A' # equivalently adjoint(A)\n2×2 adjoint(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:\n 3-2im 0+0im\n 9-2im 0+0im\n\njulia> B isa Adjoint\ntrue\n\njulia> adjoint(B) === A # the adjoint of an adjoint unwraps the parent\ntrue\n\njulia> Adjoint(B) # however, the constructor always wraps its argument\n2×2 adjoint(adjoint(::Matrix{Complex{Int64}})) with eltype Complex{Int64}:\n 3+2im 9+2im\n 0+0im 0+0im\n\njulia> B[1,2] = 4 + 5im; # modifying B will modify A automatically\n\njulia> A\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 4-5im 0+0im\n\nFor real matrices, the adjoint operation is equivalent to a transpose.\n\njulia> A = reshape([x for x in 1:4], 2, 2)\n2×2 Matrix{Int64}:\n 1 3\n 2 4\n\njulia> A'\n2×2 adjoint(::Matrix{Int64}) with eltype Int64:\n 1 2\n 3 4\n\njulia> adjoint(A) == transpose(A)\ntrue\n\nThe adjoint of an AbstractVector is a row-vector:\n\njulia> x = [3, 4im]\n2-element Vector{Complex{Int64}}:\n 3 + 0im\n 0 + 4im\n\njulia> x'\n1×2 adjoint(::Vector{Complex{Int64}}) with eltype Complex{Int64}:\n 3+0im 0-4im\n\njulia> x'x # compute the dot product, equivalently x' * x\n25 + 0im\n\nFor a matrix of matrices, the individual blocks are recursively operated on:\n\njulia> A = reshape([x + im*x for x in 1:4], 2, 2)\n2×2 Matrix{Complex{Int64}}:\n 1+1im 3+3im\n 2+2im 4+4im\n\njulia> C = reshape([A, 2A, 3A, 4A], 2, 2)\n2×2 Matrix{Matrix{Complex{Int64}}}:\n [1+1im 3+3im; 2+2im 4+4im] [3+3im 9+9im; 6+6im 12+12im]\n [2+2im 6+6im; 4+4im 8+8im] [4+4im 12+12im; 8+8im 16+16im]\n\njulia> C'\n2×2 adjoint(::Matrix{Matrix{Complex{Int64}}}) with eltype Adjoint{Complex{Int64}, Matrix{Complex{Int64}}}:\n [1-1im 2-2im; 3-3im 4-4im] [2-2im 4-4im; 6-6im 8-8im]\n [3-3im 6-6im; 9-9im 12-12im] [4-4im 8-8im; 12-12im 16-16im]\n\n\n\n\n\nadjoint(F::Factorization)\n\nLazy adjoint of the factorization F. By default, returns an AdjointFactorization wrapper.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.adjoint!","page":"Linear Algebra","title":"LinearAlgebra.adjoint!","text":"adjoint!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}) where {Tv,Ti}\n\nTranspose the matrix A and stores the adjoint of the elements in the matrix X. size(X) must be equal to size(transpose(A)). No additional memory is allocated other than resizing the rowval and nzval of X, if needed.\n\nSee halfperm!\n\n\n\n\n\nadjoint!(dest,src)\n\nConjugate transpose array src and store the result in the preallocated array dest, which should have a size corresponding to (size(src,2),size(src,1)). No in-place transposition is supported and unexpected results will happen if src and dest have overlapping memory regions.\n\nExamples\n\njulia> A = [3+2im 9+2im; 8+7im 4+6im]\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 8+7im 4+6im\n\njulia> B = zeros(Complex{Int64}, 2, 2)\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+0im\n 0+0im 0+0im\n\njulia> adjoint!(B, A);\n\njulia> B\n2×2 Matrix{Complex{Int64}}:\n 3-2im 8-7im\n 9-2im 4-6im\n\njulia> A\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 8+7im 4+6im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Adjoint","page":"Linear Algebra","title":"LinearAlgebra.Adjoint","text":"Adjoint\n\nLazy wrapper type for an adjoint view of the underlying linear algebra object, usually an AbstractVector/AbstractMatrix. Usually, the Adjoint constructor should not be called directly, use adjoint instead. To materialize the view use copy.\n\nThis type is intended for linear algebra usage - for general data manipulation see permutedims.\n\nExamples\n\njulia> A = [3+2im 9+2im; 0 0]\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 0+0im 0+0im\n\njulia> Adjoint(A)\n2×2 adjoint(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:\n 3-2im 0+0im\n 9-2im 0+0im\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.AdjointFactorization","page":"Linear Algebra","title":"LinearAlgebra.AdjointFactorization","text":"AdjointFactorization\n\nLazy wrapper type for the adjoint of the underlying Factorization object. Usually, the AdjointFactorization constructor should not be called directly, use adjoint(:: Factorization) instead.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#Base.copy-Tuple{Union{Adjoint, Transpose}}","page":"Linear Algebra","title":"Base.copy","text":"copy(A::Transpose)\ncopy(A::Adjoint)\n\nEagerly evaluate the lazy matrix transpose/adjoint. Note that the transposition is applied recursively to elements.\n\nThis operation is intended for linear algebra usage - for general data manipulation see permutedims, which is non-recursive.\n\nExamples\n\njulia> A = [1 2im; -3im 4]\n2×2 Matrix{Complex{Int64}}:\n 1+0im 0+2im\n 0-3im 4+0im\n\njulia> T = transpose(A)\n2×2 transpose(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:\n 1+0im 0-3im\n 0+2im 4+0im\n\njulia> copy(T)\n2×2 Matrix{Complex{Int64}}:\n 1+0im 0-3im\n 0+2im 4+0im\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.stride1","page":"Linear Algebra","title":"LinearAlgebra.stride1","text":"stride1(A) -> Int\n\nReturn the distance between successive array elements in dimension 1 in units of element size.\n\nExamples\n\njulia> A = [1,2,3,4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> LinearAlgebra.stride1(A)\n1\n\njulia> B = view(A, 2:2:4)\n2-element view(::Vector{Int64}, 2:2:4) with eltype Int64:\n 2\n 4\n\njulia> LinearAlgebra.stride1(B)\n2\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.checksquare","page":"Linear Algebra","title":"LinearAlgebra.checksquare","text":"LinearAlgebra.checksquare(A)\n\nCheck that a matrix is square, then return its common dimension. For multiple arguments, return a vector.\n\nExamples\n\njulia> A = fill(1, (4,4)); B = fill(1, (5,5));\n\njulia> LinearAlgebra.checksquare(A, B)\n2-element Vector{Int64}:\n 4\n 5\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.peakflops","page":"Linear Algebra","title":"LinearAlgebra.peakflops","text":"LinearAlgebra.peakflops(n::Integer=4096; eltype::DataType=Float64, ntrials::Integer=3, parallel::Bool=false)\n\npeakflops computes the peak flop rate of the computer by using double precision gemm!. By default, if no arguments are specified, it multiplies two Float64 matrices of size n x n, where n = 4096. If the underlying BLAS is using multiple threads, higher flop rates are realized. The number of BLAS threads can be set with BLAS.set_num_threads(n).\n\nIf the keyword argument eltype is provided, peakflops will construct matrices with elements of type eltype for calculating the peak flop rate.\n\nBy default, peakflops will use the best timing from 3 trials. If the ntrials keyword argument is provided, peakflops will use those many trials for picking the best timing.\n\nIf the keyword argument parallel is set to true, peakflops is run in parallel on all the worker processors. The flop rate of the entire parallel computer is returned. When running in parallel, only 1 BLAS thread is used. The argument n still refers to the size of the problem that is solved on each processor.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1. In Julia 1.0 it is available from the standard library InteractiveUtils.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.hermitianpart","page":"Linear Algebra","title":"LinearAlgebra.hermitianpart","text":"hermitianpart(A, uplo=:U) -> Hermitian\n\nReturn the Hermitian part of the square matrix A, defined as (A + A') / 2, as a Hermitian matrix. For real matrices A, this is also known as the symmetric part of A; it is also sometimes called the \"operator real part\". The optional argument uplo controls the corresponding argument of the Hermitian view. For real matrices, the latter is equivalent to a Symmetric view.\n\nSee also hermitianpart! for the corresponding in-place operation.\n\ncompat: Julia 1.10\nThis function requires Julia 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.hermitianpart!","page":"Linear Algebra","title":"LinearAlgebra.hermitianpart!","text":"hermitianpart!(A, uplo=:U) -> Hermitian\n\nOverwrite the square matrix A in-place with its Hermitian part (A + A') / 2, and return Hermitian(A, uplo). For real matrices A, this is also known as the symmetric part of A.\n\nSee also hermitianpart for the corresponding out-of-place operation.\n\ncompat: Julia 1.10\nThis function requires Julia 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.copy_adjoint!","page":"Linear Algebra","title":"LinearAlgebra.copy_adjoint!","text":"copy_adjoint!(B::AbstractVecOrMat, ir_dest::AbstractRange{Int}, jr_dest::AbstractRange{Int},\n A::AbstractVecOrMat, ir_src::AbstractRange{Int}, jr_src::AbstractRange{Int}) -> B\n\nEfficiently copy elements of matrix A to B with adjunction as follows:\n\nB[ir_dest, jr_dest] = adjoint(A)[jr_src, ir_src]\n\nThe elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(jr_src) and length(jr_dest) == length(ir_src).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.copy_transpose!","page":"Linear Algebra","title":"LinearAlgebra.copy_transpose!","text":"copy_transpose!(B::AbstractVecOrMat, ir_dest::AbstractRange{Int}, jr_dest::AbstractRange{Int},\n A::AbstractVecOrMat, ir_src::AbstractRange{Int}, jr_src::AbstractRange{Int}) -> B\n\nEfficiently copy elements of matrix A to B with transposition as follows:\n\nB[ir_dest, jr_dest] = transpose(A)[jr_src, ir_src]\n\nThe elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(jr_src) and length(jr_dest) == length(ir_src).\n\n\n\n\n\ncopy_transpose!(B::AbstractMatrix, ir_dest::AbstractUnitRange, jr_dest::AbstractUnitRange,\n tM::AbstractChar,\n M::AbstractVecOrMat, ir_src::AbstractUnitRange, jr_src::AbstractUnitRange) -> B\n\nEfficiently copy elements of matrix M to B conditioned on the character parameter tM as follows:\n\ntM Destination Source\n'N' B[ir_dest, jr_dest] transpose(M)[jr_src, ir_src]\n'T' B[ir_dest, jr_dest] M[jr_src, ir_src]\n'C' B[ir_dest, jr_dest] conj(M)[jr_src, ir_src]\n\nThe elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(jr_src) and length(jr_dest) == length(ir_src).\n\nSee also copyto! and copy_adjoint!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Low-level-matrix-operations","page":"Linear Algebra","title":"Low-level matrix operations","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In many cases there are in-place versions of matrix operations that allow you to supply a pre-allocated output vector or matrix. This is useful when optimizing critical code in order to avoid the overhead of repeated allocations. These in-place operations are suffixed with ! below (e.g. mul!) according to the usual Julia convention.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.mul!\nLinearAlgebra.lmul!\nLinearAlgebra.rmul!\nLinearAlgebra.ldiv!\nLinearAlgebra.rdiv!","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.mul!","page":"Linear Algebra","title":"LinearAlgebra.mul!","text":"mul!(Y, A, B) -> Y\n\nCalculates the matrix-matrix or matrix-vector product A B and stores the result in Y, overwriting the existing value of Y. Note that Y must not be aliased with either A or B.\n\nExamples\n\njulia> A = [1.0 2.0; 3.0 4.0]; B = [1.0 1.0; 1.0 1.0]; Y = similar(B);\n\njulia> mul!(Y, A, B) === Y\ntrue\n\njulia> Y\n2×2 Matrix{Float64}:\n 3.0 3.0\n 7.0 7.0\n\njulia> Y == A * B\ntrue\n\nImplementation\n\nFor custom matrix and vector types, it is recommended to implement 5-argument mul! rather than implementing 3-argument mul! directly if possible.\n\n\n\n\n\nmul!(C, A, B, α, β) -> C\n\nCombined inplace matrix-matrix or matrix-vector multiply-add A B α + C β. The result is stored in C by overwriting it. Note that C must not be aliased with either A or B.\n\ncompat: Julia 1.3\nFive-argument mul! requires at least Julia 1.3.\n\nExamples\n\njulia> A = [1.0 2.0; 3.0 4.0]; B = [1.0 1.0; 1.0 1.0]; C = [1.0 2.0; 3.0 4.0];\n\njulia> α, β = 100.0, 10.0;\n\njulia> mul!(C, A, B, α, β) === C\ntrue\n\njulia> C\n2×2 Matrix{Float64}:\n 310.0 320.0\n 730.0 740.0\n\njulia> C_original = [1.0 2.0; 3.0 4.0]; # A copy of the original value of C\n\njulia> C == A * B * α + C_original * β\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lmul!","page":"Linear Algebra","title":"LinearAlgebra.lmul!","text":"lmul!(a::Number, B::AbstractArray)\n\nScale an array B by a scalar a overwriting B in-place. Use rmul! to multiply scalar from right. The scaling operation respects the semantics of the multiplication * between a and an element of B. In particular, this also applies to multiplication involving non-finite numbers such as NaN and ±Inf.\n\ncompat: Julia 1.1\nPrior to Julia 1.1, NaN and ±Inf entries in B were treated inconsistently.\n\nExamples\n\njulia> B = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> lmul!(2, B)\n2×2 Matrix{Int64}:\n 2 4\n 6 8\n\njulia> lmul!(0.0, [Inf])\n1-element Vector{Float64}:\n NaN\n\n\n\n\n\nlmul!(A, B)\n\nCalculate the matrix-matrix product AB, overwriting B, and return the result. Here, A must be of special matrix type, like, e.g., Diagonal, UpperTriangular or LowerTriangular, or of some orthogonal type, see QR.\n\nExamples\n\njulia> B = [0 1; 1 0];\n\njulia> A = UpperTriangular([1 2; 0 3]);\n\njulia> lmul!(A, B);\n\njulia> B\n2×2 Matrix{Int64}:\n 2 1\n 3 0\n\njulia> B = [1.0 2.0; 3.0 4.0];\n\njulia> F = qr([0 1; -1 0]);\n\njulia> lmul!(F.Q, B)\n2×2 Matrix{Float64}:\n 3.0 4.0\n 1.0 2.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.rmul!","page":"Linear Algebra","title":"LinearAlgebra.rmul!","text":"rmul!(A::AbstractArray, b::Number)\n\nScale an array A by a scalar b overwriting A in-place. Use lmul! to multiply scalar from left. The scaling operation respects the semantics of the multiplication * between an element of A and b. In particular, this also applies to multiplication involving non-finite numbers such as NaN and ±Inf.\n\ncompat: Julia 1.1\nPrior to Julia 1.1, NaN and ±Inf entries in A were treated inconsistently.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rmul!(A, 2)\n2×2 Matrix{Int64}:\n 2 4\n 6 8\n\njulia> rmul!([NaN], 0.0)\n1-element Vector{Float64}:\n NaN\n\n\n\n\n\nrmul!(A, B)\n\nCalculate the matrix-matrix product AB, overwriting A, and return the result. Here, B must be of special matrix type, like, e.g., Diagonal, UpperTriangular or LowerTriangular, or of some orthogonal type, see QR.\n\nExamples\n\njulia> A = [0 1; 1 0];\n\njulia> B = UpperTriangular([1 2; 0 3]);\n\njulia> rmul!(A, B);\n\njulia> A\n2×2 Matrix{Int64}:\n 0 3\n 1 2\n\njulia> A = [1.0 2.0; 3.0 4.0];\n\njulia> F = qr([0 1; -1 0]);\n\njulia> rmul!(A, F.Q)\n2×2 Matrix{Float64}:\n 2.0 1.0\n 4.0 3.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ldiv!","page":"Linear Algebra","title":"LinearAlgebra.ldiv!","text":"ldiv!(Y, A, B) -> Y\n\nCompute A \\ B in-place and store the result in Y, returning the result.\n\nThe argument A should not be a matrix. Rather, instead of matrices it should be a factorization object (e.g. produced by factorize or cholesky). The reason for this is that factorization itself is both expensive and typically allocates memory (although it can also be done in-place via, e.g., lu!), and performance-critical situations requiring ldiv! usually also require fine-grained control over the factorization of A.\n\nnote: Note\nCertain structured matrix types, such as Diagonal and UpperTriangular, are permitted, as these are already in a factorized form\n\nExamples\n\njulia> A = [1 2.2 4; 3.1 0.2 3; 4 1 2];\n\njulia> X = [1; 2.5; 3];\n\njulia> Y = zero(X);\n\njulia> ldiv!(Y, qr(A), X);\n\njulia> Y\n3-element Vector{Float64}:\n 0.7128099173553719\n -0.051652892561983674\n 0.10020661157024757\n\njulia> A\\X\n3-element Vector{Float64}:\n 0.7128099173553719\n -0.05165289256198333\n 0.10020661157024785\n\n\n\n\n\nldiv!(A, B)\n\nCompute A \\ B in-place and overwriting B to store the result.\n\nThe argument A should not be a matrix. Rather, instead of matrices it should be a factorization object (e.g. produced by factorize or cholesky). The reason for this is that factorization itself is both expensive and typically allocates memory (although it can also be done in-place via, e.g., lu!), and performance-critical situations requiring ldiv! usually also require fine-grained control over the factorization of A.\n\nnote: Note\nCertain structured matrix types, such as Diagonal and UpperTriangular, are permitted, as these are already in a factorized form\n\nExamples\n\njulia> A = [1 2.2 4; 3.1 0.2 3; 4 1 2];\n\njulia> X = [1; 2.5; 3];\n\njulia> Y = copy(X);\n\njulia> ldiv!(qr(A), X);\n\njulia> X\n3-element Vector{Float64}:\n 0.7128099173553719\n -0.051652892561983674\n 0.10020661157024757\n\njulia> A\\Y\n3-element Vector{Float64}:\n 0.7128099173553719\n -0.05165289256198333\n 0.10020661157024785\n\n\n\n\n\nldiv!(a::Number, B::AbstractArray)\n\nDivide each entry in an array B by a scalar a overwriting B in-place. Use rdiv! to divide scalar from right.\n\nExamples\n\njulia> B = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> ldiv!(2.0, B)\n2×2 Matrix{Float64}:\n 0.5 1.0\n 1.5 2.0\n\n\n\n\n\nldiv!(A::Tridiagonal, B::AbstractVecOrMat) -> B\n\nCompute A \\ B in-place by Gaussian elimination with partial pivoting and store the result in B, returning the result. In the process, the diagonals of A are overwritten as well.\n\ncompat: Julia 1.11\nldiv! for Tridiagonal left-hand sides requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.rdiv!","page":"Linear Algebra","title":"LinearAlgebra.rdiv!","text":"rdiv!(A, B)\n\nCompute A / B in-place and overwriting A to store the result.\n\nThe argument B should not be a matrix. Rather, instead of matrices it should be a factorization object (e.g. produced by factorize or cholesky). The reason for this is that factorization itself is both expensive and typically allocates memory (although it can also be done in-place via, e.g., lu!), and performance-critical situations requiring rdiv! usually also require fine-grained control over the factorization of B.\n\nnote: Note\nCertain structured matrix types, such as Diagonal and UpperTriangular, are permitted, as these are already in a factorized form\n\n\n\n\n\nrdiv!(A::AbstractArray, b::Number)\n\nDivide each entry in an array A by a scalar b overwriting A in-place. Use ldiv! to divide scalar from left.\n\nExamples\n\njulia> A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> rdiv!(A, 2.0)\n2×2 Matrix{Float64}:\n 0.5 1.0\n 1.5 2.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#BLAS-functions","page":"Linear Algebra","title":"BLAS functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In Julia (as in much of scientific computation), dense linear-algebra operations are based on the LAPACK library, which in turn is built on top of basic linear-algebra building-blocks known as the BLAS. There are highly optimized implementations of BLAS available for every computer architecture, and sometimes in high-performance linear algebra routines it is useful to call the BLAS functions directly.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS provides wrappers for some of the BLAS functions. Those BLAS functions that overwrite one of the input arrays have names ending in '!'. Usually, a BLAS function has four methods defined, for Float32, Float64, ComplexF32, and ComplexF64 arrays.","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-chars","page":"Linear Algebra","title":"BLAS character arguments","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Many BLAS functions accept arguments that determine whether to transpose an argument (trans), which triangle of a matrix to reference (uplo or ul), whether the diagonal of a triangular matrix can be assumed to be all ones (dA) or which side of a matrix multiplication the input argument belongs on (side). The possibilities are:","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-side","page":"Linear Algebra","title":"Multiplication order","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"side Meaning\n'L' The argument goes on the left side of a matrix-matrix operation.\n'R' The argument goes on the right side of a matrix-matrix operation.","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-uplo","page":"Linear Algebra","title":"Triangle referencing","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"uplo/ul Meaning\n'U' Only the upper triangle of the matrix will be used.\n'L' Only the lower triangle of the matrix will be used.","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-trans","page":"Linear Algebra","title":"Transposition operation","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"trans/tX Meaning\n'N' The input matrix X is not transposed or conjugated.\n'T' The input matrix X will be transposed.\n'C' The input matrix X will be conjugated and transposed.","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-diag","page":"Linear Algebra","title":"Unit diagonal","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"diag/dX Meaning\n'N' The diagonal values of the matrix X will be read.\n'U' The diagonal of the matrix X is assumed to be all ones.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS\nLinearAlgebra.BLAS.set_num_threads\nLinearAlgebra.BLAS.get_num_threads","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS","page":"Linear Algebra","title":"LinearAlgebra.BLAS","text":"Interface to BLAS subroutines.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.set_num_threads","page":"Linear Algebra","title":"LinearAlgebra.BLAS.set_num_threads","text":"set_num_threads(n::Integer)\nset_num_threads(::Nothing)\n\nSet the number of threads the BLAS library should use equal to n::Integer.\n\nAlso accepts nothing, in which case julia tries to guess the default number of threads. Passing nothing is discouraged and mainly exists for historical reasons.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.get_num_threads","page":"Linear Algebra","title":"LinearAlgebra.BLAS.get_num_threads","text":"get_num_threads()\n\nGet the number of threads the BLAS library is using.\n\ncompat: Julia 1.6\nget_num_threads requires at least Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"BLAS functions can be divided into three groups, also called three levels, depending on when they were first proposed, the type of input parameters, and the complexity of the operation.","category":"page"},{"location":"stdlib/LinearAlgebra/#Level-1-BLAS-functions","page":"Linear Algebra","title":"Level 1 BLAS functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The level 1 BLAS functions were first proposed in [(Lawson, 1979)][Lawson-1979] and define operations between scalars and vectors.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"[Lawson-1979]: https://dl.acm.org/doi/10.1145/355841.355847","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"# xROTG\n# xROTMG\nLinearAlgebra.BLAS.rot!\n# xROTM\n# xSWAP\nLinearAlgebra.BLAS.scal!\nLinearAlgebra.BLAS.scal\nLinearAlgebra.BLAS.blascopy!\n# xAXPY!\n# xAXPBY!\nLinearAlgebra.BLAS.dot\nLinearAlgebra.BLAS.dotu\nLinearAlgebra.BLAS.dotc\n# xxDOT\nLinearAlgebra.BLAS.nrm2\nLinearAlgebra.BLAS.asum\nLinearAlgebra.BLAS.iamax","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.rot!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.rot!","text":"rot!(n, X, incx, Y, incy, c, s)\n\nOverwrite X with c*X + s*Y and Y with -conj(s)*X + c*Y for the first n elements of array X with stride incx and first n elements of array Y with stride incy. Returns X and Y.\n\ncompat: Julia 1.5\nrot! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.scal!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.scal!","text":"scal!(n, a, X, incx)\nscal!(a, X)\n\nOverwrite X with a*X for the first n elements of array X with stride incx. Returns X.\n\nIf n and incx are not provided, length(X) and stride(X,1) are used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.scal","page":"Linear Algebra","title":"LinearAlgebra.BLAS.scal","text":"scal(n, a, X, incx)\nscal(a, X)\n\nReturn X scaled by a for the first n elements of array X with stride incx.\n\nIf n and incx are not provided, length(X) and stride(X,1) are used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.blascopy!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.blascopy!","text":"blascopy!(n, X, incx, Y, incy)\n\nCopy n elements of array X with stride incx to array Y with stride incy. Returns Y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.dot","page":"Linear Algebra","title":"LinearAlgebra.BLAS.dot","text":"dot(n, X, incx, Y, incy)\n\nDot product of two vectors consisting of n elements of array X with stride incx and n elements of array Y with stride incy.\n\nExamples\n\njulia> BLAS.dot(10, fill(1.0, 10), 1, fill(1.0, 20), 2)\n10.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.dotu","page":"Linear Algebra","title":"LinearAlgebra.BLAS.dotu","text":"dotu(n, X, incx, Y, incy)\n\nDot function for two complex vectors consisting of n elements of array X with stride incx and n elements of array Y with stride incy.\n\nExamples\n\njulia> BLAS.dotu(10, fill(1.0im, 10), 1, fill(1.0+im, 20), 2)\n-10.0 + 10.0im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.dotc","page":"Linear Algebra","title":"LinearAlgebra.BLAS.dotc","text":"dotc(n, X, incx, U, incy)\n\nDot function for two complex vectors, consisting of n elements of array X with stride incx and n elements of array U with stride incy, conjugating the first vector.\n\nExamples\n\njulia> BLAS.dotc(10, fill(1.0im, 10), 1, fill(1.0+im, 20), 2)\n10.0 - 10.0im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.nrm2","page":"Linear Algebra","title":"LinearAlgebra.BLAS.nrm2","text":"nrm2(n, X, incx)\n\n2-norm of a vector consisting of n elements of array X with stride incx.\n\nExamples\n\njulia> BLAS.nrm2(4, fill(1.0, 8), 2)\n2.0\n\njulia> BLAS.nrm2(1, fill(1.0, 8), 2)\n1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.asum","page":"Linear Algebra","title":"LinearAlgebra.BLAS.asum","text":"asum(n, X, incx)\n\nSum of the magnitudes of the first n elements of array X with stride incx.\n\nFor a real array, the magnitude is the absolute value. For a complex array, the magnitude is the sum of the absolute value of the real part and the absolute value of the imaginary part.\n\nExamples\n\njulia> BLAS.asum(5, fill(1.0im, 10), 2)\n5.0\n\njulia> BLAS.asum(2, fill(1.0im, 10), 5)\n2.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.iamax","page":"Linear Algebra","title":"LinearAlgebra.BLAS.iamax","text":"iamax(n, dx, incx)\niamax(dx)\n\nFind the index of the element of dx with the maximum absolute value. n is the length of dx, and incx is the stride. If n and incx are not provided, they assume default values of n=length(dx) and incx=stride1(dx).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Level-2-BLAS-functions","page":"Linear Algebra","title":"Level 2 BLAS functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The level 2 BLAS functions were published in [(Dongarra, 1988)][Dongarra-1988], and define matrix-vector operations.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"[Dongarra-1988]: https://dl.acm.org/doi/10.1145/42288.42291","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"return a vector","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS.gemv!\nLinearAlgebra.BLAS.gemv(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gemv(::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gbmv!\nLinearAlgebra.BLAS.gbmv\nLinearAlgebra.BLAS.hemv!\nLinearAlgebra.BLAS.hemv(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.hemv(::Any, ::Any, ::Any)\n# hbmv!, hbmv\nLinearAlgebra.BLAS.hpmv!\nLinearAlgebra.BLAS.symv!\nLinearAlgebra.BLAS.symv(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.symv(::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.sbmv!\nLinearAlgebra.BLAS.sbmv(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.sbmv(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.spmv!\nLinearAlgebra.BLAS.trmv!\nLinearAlgebra.BLAS.trmv\n# xTBMV\n# xTPMV\nLinearAlgebra.BLAS.trsv!\nLinearAlgebra.BLAS.trsv\n# xTBSV\n# xTPSV","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemv!","text":"gemv!(tA, alpha, A, x, beta, y)\n\nUpdate the vector y as alpha*A*x + beta*y or alpha*A'x + beta*y according to tA. alpha and beta are scalars. Return the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemv-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemv","text":"gemv(tA, alpha, A, x)\n\nReturn alpha*A*x or alpha*A'x according to tA. alpha is a scalar.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemv-Tuple{Any, Any, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemv","text":"gemv(tA, A, x)\n\nReturn A*x or A'x according to tA.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gbmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gbmv!","text":"gbmv!(trans, m, kl, ku, alpha, A, x, beta, y)\n\nUpdate vector y as alpha*A*x + beta*y or alpha*A'*x + beta*y according to trans. The matrix A is a general band matrix of dimension m by size(A,2) with kl sub-diagonals and ku super-diagonals. alpha and beta are scalars. Return the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gbmv","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gbmv","text":"gbmv(trans, m, kl, ku, alpha, A, x)\n\nReturn alpha*A*x or alpha*A'*x according to trans. The matrix A is a general band matrix of dimension m by size(A,2) with kl sub-diagonals and ku super-diagonals, and alpha is a scalar.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemv!","text":"hemv!(ul, alpha, A, x, beta, y)\n\nUpdate the vector y as alpha*A*x + beta*y. A is assumed to be Hermitian. Only the ul triangle of A is used. alpha and beta are scalars. Return the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemv-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemv","text":"hemv(ul, alpha, A, x)\n\nReturn alpha*A*x. A is assumed to be Hermitian. Only the ul triangle of A is used. alpha is a scalar.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemv-Tuple{Any, Any, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemv","text":"hemv(ul, A, x)\n\nReturn A*x. A is assumed to be Hermitian. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hpmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hpmv!","text":"hpmv!(uplo, α, AP, x, β, y)\n\nUpdate vector y as α*A*x + β*y, where A is a Hermitian matrix provided in packed format AP.\n\nWith uplo = 'U', the array AP must contain the upper triangular part of the Hermitian matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.\n\nWith uplo = 'L', the array AP must contain the lower triangular part of the Hermitian matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.\n\nThe scalar inputs α and β must be complex or real numbers.\n\nThe array inputs x, y and AP must all be of ComplexF32 or ComplexF64 type.\n\nReturn the updated y.\n\ncompat: Julia 1.5\nhpmv! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symv!","text":"symv!(ul, alpha, A, x, beta, y)\n\nUpdate the vector y as alpha*A*x + beta*y. A is assumed to be symmetric. Only the ul triangle of A is used. alpha and beta are scalars. Return the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symv-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symv","text":"symv(ul, alpha, A, x)\n\nReturn alpha*A*x. A is assumed to be symmetric. Only the ul triangle of A is used. alpha is a scalar.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symv-Tuple{Any, Any, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symv","text":"symv(ul, A, x)\n\nReturn A*x. A is assumed to be symmetric. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.sbmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.sbmv!","text":"sbmv!(uplo, k, alpha, A, x, beta, y)\n\nUpdate vector y as alpha*A*x + beta*y where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. The storage layout for A is described the reference BLAS module, level-2 BLAS at https://www.netlib.org/lapack/explore-html/. Only the uplo triangle of A is used.\n\nReturn the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.sbmv-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.sbmv","text":"sbmv(uplo, k, alpha, A, x)\n\nReturn alpha*A*x where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. Only the uplo triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.sbmv-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.sbmv","text":"sbmv(uplo, k, A, x)\n\nReturn A*x where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. Only the uplo triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.spmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.spmv!","text":"spmv!(uplo, α, AP, x, β, y)\n\nUpdate vector y as α*A*x + β*y, where A is a symmetric matrix provided in packed format AP.\n\nWith uplo = 'U', the array AP must contain the upper triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.\n\nWith uplo = 'L', the array AP must contain the lower triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.\n\nThe scalar inputs α and β must be real.\n\nThe array inputs x, y and AP must all be of Float32 or Float64 type.\n\nReturn the updated y.\n\ncompat: Julia 1.5\nspmv! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trmv!","text":"trmv!(ul, tA, dA, A, b)\n\nReturn op(A)*b, where op is determined by tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. The multiplication occurs in-place on b.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trmv","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trmv","text":"trmv(ul, tA, dA, A, b)\n\nReturn op(A)*b, where op is determined by tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trsv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trsv!","text":"trsv!(ul, tA, dA, A, b)\n\nOverwrite b with the solution to A*x = b or one of the other two variants determined by tA and ul. dA determines if the diagonal values are read or are assumed to be all ones. Return the updated b.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trsv","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trsv","text":"trsv(ul, tA, dA, A, b)\n\nReturn the solution to A*x = b or one of the other two variants determined by tA and ul. dA determines if the diagonal values are read or are assumed to be all ones.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"return a matrix","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS.ger!\n# xGERU\n# xGERC\nLinearAlgebra.BLAS.her!\n# xHPR\n# xHER2\n# xHPR2\nLinearAlgebra.BLAS.syr!\nLinearAlgebra.BLAS.spr!\n# xSYR2\n# xSPR2","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.ger!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.ger!","text":"ger!(alpha, x, y, A)\n\nRank-1 update of the matrix A with vectors x and y as alpha*x*y' + A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.her!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.her!","text":"her!(uplo, alpha, x, A)\n\nMethods for complex arrays only. Rank-1 update of the Hermitian matrix A with vector x as alpha*x*x' + A. uplo controls which triangle of A is updated. Returns A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syr!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syr!","text":"syr!(uplo, alpha, x, A)\n\nRank-1 update of the symmetric matrix A with vector x as alpha*x*transpose(x) + A. uplo controls which triangle of A is updated. Returns A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.spr!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.spr!","text":"spr!(uplo, α, x, AP)\n\nUpdate matrix A as A+α*x*x', where A is a symmetric matrix provided in packed format AP and x is a vector.\n\nWith uplo = 'U', the array AP must contain the upper triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.\n\nWith uplo = 'L', the array AP must contain the lower triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.\n\nThe scalar input α must be real.\n\nThe array inputs x and AP must all be of Float32 or Float64 type. Return the updated AP.\n\ncompat: Julia 1.8\nspr! requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Level-3-BLAS-functions","page":"Linear Algebra","title":"Level 3 BLAS functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The level 3 BLAS functions were published in [(Dongarra, 1990)][Dongarra-1990], and define matrix-matrix operations.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"[Dongarra-1990]: https://dl.acm.org/doi/10.1145/77626.79170","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS.gemmt!\nLinearAlgebra.BLAS.gemmt(::Any, ::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gemmt(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gemm!\nLinearAlgebra.BLAS.gemm(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gemm(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.symm!\nLinearAlgebra.BLAS.symm(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.symm(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.hemm!\nLinearAlgebra.BLAS.hemm(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.hemm(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.syrk!\nLinearAlgebra.BLAS.syrk\nLinearAlgebra.BLAS.herk!\nLinearAlgebra.BLAS.herk\nLinearAlgebra.BLAS.syr2k!\nLinearAlgebra.BLAS.syr2k\nLinearAlgebra.BLAS.her2k!\nLinearAlgebra.BLAS.her2k\nLinearAlgebra.BLAS.trmm!\nLinearAlgebra.BLAS.trmm\nLinearAlgebra.BLAS.trsm!\nLinearAlgebra.BLAS.trsm","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemmt!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemmt!","text":"gemmt!(uplo, tA, tB, alpha, A, B, beta, C)\n\nUpdate the lower or upper triangular part specified by uplo of C as alpha*A*B + beta*C or the other variants according to tA and tB. Return the updated C.\n\ncompat: Julia 1.11\ngemmt! requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemmt-NTuple{6, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemmt","text":"gemmt(uplo, tA, tB, alpha, A, B)\n\nReturn the lower or upper triangular part specified by uplo of A*B or the other three variants according to tA and tB.\n\ncompat: Julia 1.11\ngemmt requires at least Julia 1.11.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemmt-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemmt","text":"gemmt(uplo, tA, tB, A, B)\n\nReturn the lower or upper triangular part specified by uplo of A*B or the other three variants according to tA and tB.\n\ncompat: Julia 1.11\ngemmt requires at least Julia 1.11.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemm!","text":"gemm!(tA, tB, alpha, A, B, beta, C)\n\nUpdate C as alpha*A*B + beta*C or the other three variants according to tA and tB. Return the updated C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemm-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemm","text":"gemm(tA, tB, alpha, A, B)\n\nReturn alpha*A*B or the other three variants according to tA and tB.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemm-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemm","text":"gemm(tA, tB, A, B)\n\nReturn A*B or the other three variants according to tA and tB.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symm!","text":"symm!(side, ul, alpha, A, B, beta, C)\n\nUpdate C as alpha*A*B + beta*C or alpha*B*A + beta*C according to side. A is assumed to be symmetric. Only the ul triangle of A is used. Return the updated C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symm-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symm","text":"symm(side, ul, alpha, A, B)\n\nReturn alpha*A*B or alpha*B*A according to side. A is assumed to be symmetric. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symm-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symm","text":"symm(side, ul, A, B)\n\nReturn A*B or B*A according to side. A is assumed to be symmetric. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemm!","text":"hemm!(side, ul, alpha, A, B, beta, C)\n\nUpdate C as alpha*A*B + beta*C or alpha*B*A + beta*C according to side. A is assumed to be Hermitian. Only the ul triangle of A is used. Return the updated C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemm-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemm","text":"hemm(side, ul, alpha, A, B)\n\nReturn alpha*A*B or alpha*B*A according to side. A is assumed to be Hermitian. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemm-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemm","text":"hemm(side, ul, A, B)\n\nReturn A*B or B*A according to side. A is assumed to be Hermitian. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syrk!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syrk!","text":"syrk!(uplo, trans, alpha, A, beta, C)\n\nRank-k update of the symmetric matrix C as alpha*A*transpose(A) + beta*C or alpha*transpose(A)*A + beta*C according to trans. Only the uplo triangle of C is used. Return C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syrk","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syrk","text":"syrk(uplo, trans, alpha, A)\n\nReturn either the upper triangle or the lower triangle of A, according to uplo, of alpha*A*transpose(A) or alpha*transpose(A)*A, according to trans.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.herk!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.herk!","text":"herk!(uplo, trans, alpha, A, beta, C)\n\nMethods for complex arrays only. Rank-k update of the Hermitian matrix C as alpha*A*A' + beta*C or alpha*A'*A + beta*C according to trans. Only the uplo triangle of C is updated. Returns C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.herk","page":"Linear Algebra","title":"LinearAlgebra.BLAS.herk","text":"herk(uplo, trans, alpha, A)\n\nMethods for complex arrays only. Returns the uplo triangle of alpha*A*A' or alpha*A'*A, according to trans.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syr2k!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syr2k!","text":"syr2k!(uplo, trans, alpha, A, B, beta, C)\n\nRank-2k update of the symmetric matrix C as alpha*A*transpose(B) + alpha*B*transpose(A) + beta*C or alpha*transpose(A)*B + alpha*transpose(B)*A + beta*C according to trans. Only the uplo triangle of C is used. Returns C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syr2k","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syr2k","text":"syr2k(uplo, trans, alpha, A, B)\n\nReturns the uplo triangle of alpha*A*transpose(B) + alpha*B*transpose(A) or alpha*transpose(A)*B + alpha*transpose(B)*A, according to trans.\n\n\n\n\n\nsyr2k(uplo, trans, A, B)\n\nReturn the uplo triangle of A*transpose(B) + B*transpose(A) or transpose(A)*B + transpose(B)*A, according to trans.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.her2k!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.her2k!","text":"her2k!(uplo, trans, alpha, A, B, beta, C)\n\nRank-2k update of the Hermitian matrix C as alpha*A*B' + alpha*B*A' + beta*C or alpha*A'*B + alpha*B'*A + beta*C according to trans. The scalar beta has to be real. Only the uplo triangle of C is used. Return C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.her2k","page":"Linear Algebra","title":"LinearAlgebra.BLAS.her2k","text":"her2k(uplo, trans, alpha, A, B)\n\nReturn the uplo triangle of alpha*A*B' + alpha*B*A' or alpha*A'*B + alpha*B'*A, according to trans.\n\n\n\n\n\nher2k(uplo, trans, A, B)\n\nReturn the uplo triangle of A*B' + B*A' or A'*B + B'*A, according to trans.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trmm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trmm!","text":"trmm!(side, ul, tA, dA, alpha, A, B)\n\nUpdate B as alpha*A*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. Return the updated B.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trmm","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trmm","text":"trmm(side, ul, tA, dA, alpha, A, B)\n\nReturn alpha*A*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trsm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trsm!","text":"trsm!(side, ul, tA, dA, alpha, A, B)\n\nOverwrite B with the solution to A*X = alpha*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. Returns the updated B.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trsm","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trsm","text":"trsm(side, ul, tA, dA, alpha, A, B)\n\nReturn the solution to A*X = alpha*B or one of the other three variants determined by determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#man-linalg-lapack-functions","page":"Linear Algebra","title":"LAPACK functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.LAPACK provides wrappers for some of the LAPACK functions for linear algebra. Those functions that overwrite one of the input arrays have names ending in '!'.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Usually a function has 4 methods defined, one each for Float64, Float32, ComplexF64 and ComplexF32 arrays.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Note that the LAPACK API provided by Julia can and will change in the future. Since this API is not user-facing, there is no commitment to support/deprecate this specific set of functions in future releases.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.LAPACK\nLinearAlgebra.LAPACK.gbtrf!\nLinearAlgebra.LAPACK.gbtrs!\nLinearAlgebra.LAPACK.gebal!\nLinearAlgebra.LAPACK.gebak!\nLinearAlgebra.LAPACK.gebrd!\nLinearAlgebra.LAPACK.gelqf!\nLinearAlgebra.LAPACK.geqlf!\nLinearAlgebra.LAPACK.geqrf!\nLinearAlgebra.LAPACK.geqp3!\nLinearAlgebra.LAPACK.gerqf!\nLinearAlgebra.LAPACK.geqrt!\nLinearAlgebra.LAPACK.geqrt3!\nLinearAlgebra.LAPACK.getrf!\nLinearAlgebra.LAPACK.tzrzf!\nLinearAlgebra.LAPACK.ormrz!\nLinearAlgebra.LAPACK.gels!\nLinearAlgebra.LAPACK.gesv!\nLinearAlgebra.LAPACK.getrs!\nLinearAlgebra.LAPACK.getri!\nLinearAlgebra.LAPACK.gesvx!\nLinearAlgebra.LAPACK.gelsd!\nLinearAlgebra.LAPACK.gelsy!\nLinearAlgebra.LAPACK.gglse!\nLinearAlgebra.LAPACK.geev!\nLinearAlgebra.LAPACK.gesdd!\nLinearAlgebra.LAPACK.gesvd!\nLinearAlgebra.LAPACK.ggsvd!\nLinearAlgebra.LAPACK.ggsvd3!\nLinearAlgebra.LAPACK.geevx!\nLinearAlgebra.LAPACK.ggev!\nLinearAlgebra.LAPACK.ggev3!\nLinearAlgebra.LAPACK.gtsv!\nLinearAlgebra.LAPACK.gttrf!\nLinearAlgebra.LAPACK.gttrs!\nLinearAlgebra.LAPACK.orglq!\nLinearAlgebra.LAPACK.orgqr!\nLinearAlgebra.LAPACK.orgql!\nLinearAlgebra.LAPACK.orgrq!\nLinearAlgebra.LAPACK.ormlq!\nLinearAlgebra.LAPACK.ormqr!\nLinearAlgebra.LAPACK.ormql!\nLinearAlgebra.LAPACK.ormrq!\nLinearAlgebra.LAPACK.gemqrt!\nLinearAlgebra.LAPACK.posv!\nLinearAlgebra.LAPACK.potrf!\nLinearAlgebra.LAPACK.potri!\nLinearAlgebra.LAPACK.potrs!\nLinearAlgebra.LAPACK.pstrf!\nLinearAlgebra.LAPACK.ptsv!\nLinearAlgebra.LAPACK.pttrf!\nLinearAlgebra.LAPACK.pttrs!\nLinearAlgebra.LAPACK.trtri!\nLinearAlgebra.LAPACK.trtrs!\nLinearAlgebra.LAPACK.trcon!\nLinearAlgebra.LAPACK.trevc!\nLinearAlgebra.LAPACK.trrfs!\nLinearAlgebra.LAPACK.stev!\nLinearAlgebra.LAPACK.stebz!\nLinearAlgebra.LAPACK.stegr!\nLinearAlgebra.LAPACK.stein!\nLinearAlgebra.LAPACK.syconv!\nLinearAlgebra.LAPACK.sysv!\nLinearAlgebra.LAPACK.sytrf!\nLinearAlgebra.LAPACK.sytri!\nLinearAlgebra.LAPACK.sytrs!\nLinearAlgebra.LAPACK.hesv!\nLinearAlgebra.LAPACK.hetrf!\nLinearAlgebra.LAPACK.hetri!\nLinearAlgebra.LAPACK.hetrs!\nLinearAlgebra.LAPACK.syev!\nLinearAlgebra.LAPACK.syevr!\nLinearAlgebra.LAPACK.syevd!\nLinearAlgebra.LAPACK.sygvd!\nLinearAlgebra.LAPACK.bdsqr!\nLinearAlgebra.LAPACK.bdsdc!\nLinearAlgebra.LAPACK.gecon!\nLinearAlgebra.LAPACK.gehrd!\nLinearAlgebra.LAPACK.orghr!\nLinearAlgebra.LAPACK.gees!\nLinearAlgebra.LAPACK.gges!\nLinearAlgebra.LAPACK.gges3!\nLinearAlgebra.LAPACK.trexc!\nLinearAlgebra.LAPACK.trsen!\nLinearAlgebra.LAPACK.tgsen!\nLinearAlgebra.LAPACK.trsyl!\nLinearAlgebra.LAPACK.hseqr!","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK","page":"Linear Algebra","title":"LinearAlgebra.LAPACK","text":"Interfaces to LAPACK subroutines.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gbtrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gbtrf!","text":"gbtrf!(kl, ku, m, AB) -> (AB, ipiv)\n\nCompute the LU factorization of a banded matrix AB. kl is the first subdiagonal containing a nonzero band, ku is the last superdiagonal containing one, and m is the first dimension of the matrix AB. Returns the LU factorization in-place and ipiv, the vector of pivots used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gbtrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gbtrs!","text":"gbtrs!(trans, kl, ku, m, AB, ipiv, B)\n\nSolve the equation AB * X = B. trans determines the orientation of AB. It may be N (no transpose), T (transpose), or C (conjugate transpose). kl is the first subdiagonal containing a nonzero band, ku is the last superdiagonal containing one, and m is the first dimension of the matrix AB. ipiv is the vector of pivots returned from gbtrf!. Returns the vector or matrix X, overwriting B in-place.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gebal!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gebal!","text":"gebal!(job, A) -> (ilo, ihi, scale)\n\nBalance the matrix A before computing its eigensystem or Schur factorization. job can be one of N (A will not be permuted or scaled), P (A will only be permuted), S (A will only be scaled), or B (A will be both permuted and scaled). Modifies A in-place and returns ilo, ihi, and scale. If permuting was turned on, A[i,j] = 0 if j > i and 1 < j < ilo or j > ihi. scale contains information about the scaling/permutations performed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gebak!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gebak!","text":"gebak!(job, side, ilo, ihi, scale, V)\n\nTransform the eigenvectors V of a matrix balanced using gebal! to the unscaled/unpermuted eigenvectors of the original matrix. Modifies V in-place. side can be L (left eigenvectors are transformed) or R (right eigenvectors are transformed).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gebrd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gebrd!","text":"gebrd!(A) -> (A, d, e, tauq, taup)\n\nReduce A in-place to bidiagonal form A = QBP'. Returns A, containing the bidiagonal matrix B; d, containing the diagonal elements of B; e, containing the off-diagonal elements of B; tauq, containing the elementary reflectors representing Q; and taup, containing the elementary reflectors representing P.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gelqf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gelqf!","text":"gelqf!(A, tau)\n\nCompute the LQ factorization of A, A = LQ. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.\n\nReturns A and tau modified in-place.\n\n\n\n\n\ngelqf!(A) -> (A, tau)\n\nCompute the LQ factorization of A, A = LQ.\n\nReturns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqlf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqlf!","text":"geqlf!(A, tau)\n\nCompute the QL factorization of A, A = QL. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.\n\nReturns A and tau modified in-place.\n\n\n\n\n\ngeqlf!(A) -> (A, tau)\n\nCompute the QL factorization of A, A = QL.\n\nReturns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqrf!","text":"geqrf!(A, tau)\n\nCompute the QR factorization of A, A = QR. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.\n\nReturns A and tau modified in-place.\n\n\n\n\n\ngeqrf!(A) -> (A, tau)\n\nCompute the QR factorization of A, A = QR.\n\nReturns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqp3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqp3!","text":"geqp3!(A, [jpvt, tau]) -> (A, tau, jpvt)\n\nCompute the pivoted QR factorization of A, AP = QR using BLAS level 3. P is a pivoting matrix, represented by jpvt. tau stores the elementary reflectors. The arguments jpvt and tau are optional and allow for passing preallocated arrays. When passed, jpvt must have length greater than or equal to n if A is an (m x n) matrix and tau must have length greater than or equal to the smallest dimension of A. On entry, if jpvt[j] does not equal zero then the jth column of A is permuted to the front of AP.\n\nA, jpvt, and tau are modified in-place.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gerqf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gerqf!","text":"gerqf!(A, tau)\n\nCompute the RQ factorization of A, A = RQ. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.\n\nReturns A and tau modified in-place.\n\n\n\n\n\ngerqf!(A) -> (A, tau)\n\nCompute the RQ factorization of A, A = RQ.\n\nReturns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqrt!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqrt!","text":"geqrt!(A, T)\n\nCompute the blocked QR factorization of A, A = QR. T contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization. The first dimension of T sets the block size and it must be between 1 and n. The second dimension of T must equal the smallest dimension of A.\n\nReturns A and T modified in-place.\n\n\n\n\n\ngeqrt!(A, nb) -> (A, T)\n\nCompute the blocked QR factorization of A, A = QR. nb sets the block size and it must be between 1 and n, the second dimension of A.\n\nReturns A, modified in-place, and T, which contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqrt3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqrt3!","text":"geqrt3!(A, T)\n\nRecursively computes the blocked QR factorization of A, A = QR. T contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization. The first dimension of T sets the block size and it must be between 1 and n. The second dimension of T must equal the smallest dimension of A.\n\nReturns A and T modified in-place.\n\n\n\n\n\ngeqrt3!(A) -> (A, T)\n\nRecursively computes the blocked QR factorization of A, A = QR.\n\nReturns A, modified in-place, and T, which contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.getrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.getrf!","text":"getrf!(A, ipiv) -> (A, ipiv, info)\n\nCompute the pivoted LU factorization of A, A = LU. ipiv contains the pivoting information and info a code which indicates success (info = 0), a singular value in U (info = i, in which case U[i,i] is singular), or an error code (info < 0).\n\n\n\n\n\ngetrf!(A) -> (A, ipiv, info)\n\nCompute the pivoted LU factorization of A, A = LU.\n\nReturns A, modified in-place, ipiv, the pivoting information, and an info code which indicates success (info = 0), a singular value in U (info = i, in which case U[i,i] is singular), or an error code (info < 0).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.tzrzf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.tzrzf!","text":"tzrzf!(A) -> (A, tau)\n\nTransforms the upper trapezoidal matrix A to upper triangular form in-place. Returns A and tau, the scalar parameters for the elementary reflectors of the transformation.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormrz!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormrz!","text":"ormrz!(side, trans, A, tau, C)\n\nMultiplies the matrix C by Q from the transformation supplied by tzrzf!. Depending on side or trans the multiplication can be left-sided (side = L, Q*C) or right-sided (side = R, C*Q) and Q can be unmodified (trans = N), transposed (trans = T), or conjugate transposed (trans = C). Returns matrix C which is modified in-place with the result of the multiplication.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gels!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gels!","text":"gels!(trans, A, B) -> (F, B, ssr)\n\nSolves the linear equation A * X = B, transpose(A) * X = B, or adjoint(A) * X = B using a QR or LQ factorization. Modifies the matrix/vector B in place with the solution. A is overwritten with its QR or LQ factorization. trans may be one of N (no modification), T (transpose), or C (conjugate transpose). gels! searches for the minimum norm/least squares solution. A may be under or over determined. The solution is returned in B.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gesv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gesv!","text":"gesv!(A, B) -> (B, A, ipiv)\n\nSolves the linear equation A * X = B where A is a square matrix using the LU factorization of A. A is overwritten with its LU factorization and B is overwritten with the solution X. ipiv contains the pivoting information for the LU factorization of A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.getrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.getrs!","text":"getrs!(trans, A, ipiv, B)\n\nSolves the linear equation A * X = B, transpose(A) * X = B, or adjoint(A) * X = B for square A. Modifies the matrix/vector B in place with the solution. A is the LU factorization from getrf!, with ipiv the pivoting information. trans may be one of N (no modification), T (transpose), or C (conjugate transpose).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.getri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.getri!","text":"getri!(A, ipiv)\n\nComputes the inverse of A, using its LU factorization found by getrf!. ipiv is the pivot information output and A contains the LU factorization of getrf!. A is overwritten with its inverse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gesvx!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gesvx!","text":"gesvx!(fact, trans, A, AF, ipiv, equed, R, C, B) -> (X, equed, R, C, B, rcond, ferr, berr, work)\n\nSolves the linear equation A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) using the LU factorization of A. fact may be E, in which case A will be equilibrated and copied to AF; F, in which case AF and ipiv from a previous LU factorization are inputs; or N, in which case A will be copied to AF and then factored. If fact = F, equed may be N, meaning A has not been equilibrated; R, meaning A was multiplied by Diagonal(R) from the left; C, meaning A was multiplied by Diagonal(C) from the right; or B, meaning A was multiplied by Diagonal(R) from the left and Diagonal(C) from the right. If fact = F and equed = R or B the elements of R must all be positive. If fact = F and equed = C or B the elements of C must all be positive.\n\nReturns the solution X; equed, which is an output if fact is not N, and describes the equilibration that was performed; R, the row equilibration diagonal; C, the column equilibration diagonal; B, which may be overwritten with its equilibrated form Diagonal(R)*B (if trans = N and equed = R,B) or Diagonal(C)*B (if trans = T,C and equed = C,B); rcond, the reciprocal condition number of A after equilbrating; ferr, the forward error bound for each solution vector in X; berr, the forward error bound for each solution vector in X; and work, the reciprocal pivot growth factor.\n\n\n\n\n\ngesvx!(A, B)\n\nThe no-equilibration, no-transpose simplification of gesvx!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gelsd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gelsd!","text":"gelsd!(A, B, rcond) -> (B, rnk)\n\nComputes the least norm solution of A * X = B by finding the SVD factorization of A, then dividing-and-conquering the problem. B is overwritten with the solution X. Singular values below rcond will be treated as zero. Returns the solution in B and the effective rank of A in rnk.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gelsy!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gelsy!","text":"gelsy!(A, B, rcond) -> (B, rnk)\n\nComputes the least norm solution of A * X = B by finding the full QR factorization of A, then dividing-and-conquering the problem. B is overwritten with the solution X. Singular values below rcond will be treated as zero. Returns the solution in B and the effective rank of A in rnk.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gglse!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gglse!","text":"gglse!(A, c, B, d) -> (X,res)\n\nSolves the equation A * x = c where x is subject to the equality constraint B * x = d. Uses the formula ||c - A*x||^2 = 0 to solve. Returns X and the residual sum-of-squares.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geev!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geev!","text":"geev!(jobvl, jobvr, A) -> (W, VL, VR)\n\nFinds the eigensystem of A. If jobvl = N, the left eigenvectors of A aren't computed. If jobvr = N, the right eigenvectors of A aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. Returns the eigenvalues in W, the right eigenvectors in VR, and the left eigenvectors in VL.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gesdd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gesdd!","text":"gesdd!(job, A) -> (U, S, VT)\n\nFinds the singular value decomposition of A, A = U * S * V', using a divide and conquer approach. If job = A, all the columns of U and the rows of V' are computed. If job = N, no columns of U or rows of V' are computed. If job = O, A is overwritten with the columns of (thin) U and the rows of (thin) V'. If job = S, the columns of (thin) U and the rows of (thin) V' are computed and returned separately.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gesvd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gesvd!","text":"gesvd!(jobu, jobvt, A) -> (U, S, VT)\n\nFinds the singular value decomposition of A, A = U * S * V'. If jobu = A, all the columns of U are computed. If jobvt = A all the rows of V' are computed. If jobu = N, no columns of U are computed. If jobvt = N no rows of V' are computed. If jobu = O, A is overwritten with the columns of (thin) U. If jobvt = O, A is overwritten with the rows of (thin) V'. If jobu = S, the columns of (thin) U are computed and returned separately. If jobvt = S the rows of (thin) V' are computed and returned separately. jobu and jobvt can't both be O.\n\nReturns U, S, and Vt, where S are the singular values of A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ggsvd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ggsvd!","text":"ggsvd!(jobu, jobv, jobq, A, B) -> (U, V, Q, alpha, beta, k, l, R)\n\nFinds the generalized singular value decomposition of A and B, U'*A*Q = D1*R and V'*B*Q = D2*R. D1 has alpha on its diagonal and D2 has beta on its diagonal. If jobu = U, the orthogonal/unitary matrix U is computed. If jobv = V the orthogonal/unitary matrix V is computed. If jobq = Q, the orthogonal/unitary matrix Q is computed. If jobu, jobv or jobq is N, that matrix is not computed. This function is only available in LAPACK versions prior to 3.6.0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ggsvd3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ggsvd3!","text":"ggsvd3!(jobu, jobv, jobq, A, B) -> (U, V, Q, alpha, beta, k, l, R)\n\nFinds the generalized singular value decomposition of A and B, U'*A*Q = D1*R and V'*B*Q = D2*R. D1 has alpha on its diagonal and D2 has beta on its diagonal. If jobu = U, the orthogonal/unitary matrix U is computed. If jobv = V the orthogonal/unitary matrix V is computed. If jobq = Q, the orthogonal/unitary matrix Q is computed. If jobu, jobv, or jobq is N, that matrix is not computed. This function requires LAPACK 3.6.0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geevx!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geevx!","text":"geevx!(balanc, jobvl, jobvr, sense, A) -> (A, w, VL, VR, ilo, ihi, scale, abnrm, rconde, rcondv)\n\nFinds the eigensystem of A with matrix balancing. If jobvl = N, the left eigenvectors of A aren't computed. If jobvr = N, the right eigenvectors of A aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. If balanc = N, no balancing is performed. If balanc = P, A is permuted but not scaled. If balanc = S, A is scaled but not permuted. If balanc = B, A is permuted and scaled. If sense = N, no reciprocal condition numbers are computed. If sense = E, reciprocal condition numbers are computed for the eigenvalues only. If sense = V, reciprocal condition numbers are computed for the right eigenvectors only. If sense = B, reciprocal condition numbers are computed for the right eigenvectors and the eigenvectors. If sense = E,B, the right and left eigenvectors must be computed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ggev!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ggev!","text":"ggev!(jobvl, jobvr, A, B) -> (alpha, beta, vl, vr)\n\nFinds the generalized eigendecomposition of A and B. If jobvl = N, the left eigenvectors aren't computed. If jobvr = N, the right eigenvectors aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ggev3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ggev3!","text":"ggev3!(jobvl, jobvr, A, B) -> (alpha, beta, vl, vr)\n\nFinds the generalized eigendecomposition of A and B using a blocked algorithm. If jobvl = N, the left eigenvectors aren't computed. If jobvr = N, the right eigenvectors aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. This function requires LAPACK 3.6.0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gtsv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gtsv!","text":"gtsv!(dl, d, du, B)\n\nSolves the equation A * X = B where A is a tridiagonal matrix with dl on the subdiagonal, d on the diagonal, and du on the superdiagonal.\n\nOverwrites B with the solution X and returns it.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gttrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gttrf!","text":"gttrf!(dl, d, du) -> (dl, d, du, du2, ipiv)\n\nFinds the LU factorization of a tridiagonal matrix with dl on the subdiagonal, d on the diagonal, and du on the superdiagonal.\n\nModifies dl, d, and du in-place and returns them and the second superdiagonal du2 and the pivoting vector ipiv.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gttrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gttrs!","text":"gttrs!(trans, dl, d, du, du2, ipiv, B)\n\nSolves the equation A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) using the LU factorization computed by gttrf!. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orglq!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orglq!","text":"orglq!(A, tau, k = length(tau))\n\nExplicitly finds the matrix Q of a LQ factorization after calling gelqf! on A. Uses the output of gelqf!. A is overwritten by Q.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orgqr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orgqr!","text":"orgqr!(A, tau, k = length(tau))\n\nExplicitly finds the matrix Q of a QR factorization after calling geqrf! on A. Uses the output of geqrf!. A is overwritten by Q.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orgql!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orgql!","text":"orgql!(A, tau, k = length(tau))\n\nExplicitly finds the matrix Q of a QL factorization after calling geqlf! on A. Uses the output of geqlf!. A is overwritten by Q.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orgrq!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orgrq!","text":"orgrq!(A, tau, k = length(tau))\n\nExplicitly finds the matrix Q of a RQ factorization after calling gerqf! on A. Uses the output of gerqf!. A is overwritten by Q.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormlq!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormlq!","text":"ormlq!(side, trans, A, tau, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a LQ factorization of A computed using gelqf!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormqr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormqr!","text":"ormqr!(side, trans, A, tau, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QR factorization of A computed using geqrf!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormql!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormql!","text":"ormql!(side, trans, A, tau, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QL factorization of A computed using geqlf!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormrq!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormrq!","text":"ormrq!(side, trans, A, tau, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a RQ factorization of A computed using gerqf!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gemqrt!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gemqrt!","text":"gemqrt!(side, trans, V, T, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QR factorization of A computed using geqrt!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.posv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.posv!","text":"posv!(uplo, A, B) -> (A, B)\n\nFinds the solution to A * X = B where A is a symmetric or Hermitian positive definite matrix. If uplo = U the upper Cholesky decomposition of A is computed. If uplo = L the lower Cholesky decomposition of A is computed. A is overwritten by its Cholesky decomposition. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.potrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.potrf!","text":"potrf!(uplo, A)\n\nComputes the Cholesky (upper if uplo = U, lower if uplo = L) decomposition of positive-definite matrix A. A is overwritten and returned with an info code.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.potri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.potri!","text":"potri!(uplo, A)\n\nComputes the inverse of positive-definite matrix A after calling potrf! to find its (upper if uplo = U, lower if uplo = L) Cholesky decomposition.\n\nA is overwritten by its inverse and returned.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.potrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.potrs!","text":"potrs!(uplo, A, B)\n\nFinds the solution to A * X = B where A is a symmetric or Hermitian positive definite matrix whose Cholesky decomposition was computed by potrf!. If uplo = U the upper Cholesky decomposition of A was computed. If uplo = L the lower Cholesky decomposition of A was computed. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.pstrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.pstrf!","text":"pstrf!(uplo, A, tol) -> (A, piv, rank, info)\n\nComputes the (upper if uplo = U, lower if uplo = L) pivoted Cholesky decomposition of positive-definite matrix A with a user-set tolerance tol. A is overwritten by its Cholesky decomposition.\n\nReturns A, the pivots piv, the rank of A, and an info code. If info = 0, the factorization succeeded. If info = i > 0, then A is indefinite or rank-deficient.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ptsv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ptsv!","text":"ptsv!(D, E, B)\n\nSolves A * X = B for positive-definite tridiagonal A. D is the diagonal of A and E is the off-diagonal. B is overwritten with the solution X and returned.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.pttrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.pttrf!","text":"pttrf!(D, E)\n\nComputes the LDLt factorization of a positive-definite tridiagonal matrix with D as diagonal and E as off-diagonal. D and E are overwritten and returned.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.pttrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.pttrs!","text":"pttrs!(D, E, B)\n\nSolves A * X = B for positive-definite tridiagonal A with diagonal D and off-diagonal E after computing A's LDLt factorization using pttrf!. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trtri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trtri!","text":"trtri!(uplo, diag, A)\n\nFinds the inverse of (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. A is overwritten with its inverse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trtrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trtrs!","text":"trtrs!(uplo, trans, diag, A, B)\n\nSolves A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) for (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trcon!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trcon!","text":"trcon!(norm, uplo, diag, A)\n\nFinds the reciprocal condition number of (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. If norm = I, the condition number is found in the infinity norm. If norm = O or 1, the condition number is found in the one norm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trevc!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trevc!","text":"trevc!(side, howmny, select, T, VL = similar(T), VR = similar(T))\n\nFinds the eigensystem of an upper triangular matrix T. If side = R, the right eigenvectors are computed. If side = L, the left eigenvectors are computed. If side = B, both sets are computed. If howmny = A, all eigenvectors are found. If howmny = B, all eigenvectors are found and backtransformed using VL and VR. If howmny = S, only the eigenvectors corresponding to the values in select are computed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trrfs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trrfs!","text":"trrfs!(uplo, trans, diag, A, B, X, Ferr, Berr) -> (Ferr, Berr)\n\nEstimates the error in the solution to A * X = B (trans = N), transpose(A) * X = B (trans = T), adjoint(A) * X = B (trans = C) for side = L, or the equivalent equations a right-handed side = R X * A after computing X using trtrs!. If uplo = U, A is upper triangular. If uplo = L, A is lower triangular. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. Ferr and Berr are optional inputs. Ferr is the forward error and Berr is the backward error, each component-wise.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.stev!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.stev!","text":"stev!(job, dv, ev) -> (dv, Zmat)\n\nComputes the eigensystem for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If job = N only the eigenvalues are found and returned in dv. If job = V then the eigenvectors are also found and returned in Zmat.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.stebz!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.stebz!","text":"stebz!(range, order, vl, vu, il, iu, abstol, dv, ev) -> (dv, iblock, isplit)\n\nComputes the eigenvalues for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. If order = B, eigvalues are ordered within a block. If order = E, they are ordered across all the blocks. abstol can be set as a tolerance for convergence.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.stegr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.stegr!","text":"stegr!(jobz, range, dv, ev, vl, vu, il, iu) -> (w, Z)\n\nComputes the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. The eigenvalues are returned in w and the eigenvectors in Z.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.stein!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.stein!","text":"stein!(dv, ev_in, w_in, iblock_in, isplit_in)\n\nComputes the eigenvectors for a symmetric tridiagonal matrix with dv as diagonal and ev_in as off-diagonal. w_in specifies the input eigenvalues for which to find corresponding eigenvectors. iblock_in specifies the submatrices corresponding to the eigenvalues in w_in. isplit_in specifies the splitting points between the submatrix blocks.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.syconv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.syconv!","text":"syconv!(uplo, A, ipiv) -> (A, work)\n\nConverts a symmetric matrix A (which has been factorized into a triangular matrix) into two matrices L and D. If uplo = U, A is upper triangular. If uplo = L, it is lower triangular. ipiv is the pivot vector from the triangular factorization. A is overwritten by L and D.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sysv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sysv!","text":"sysv!(uplo, A, B) -> (B, A, ipiv)\n\nFinds the solution to A * X = B for symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X. A is overwritten by its Bunch-Kaufman factorization. ipiv contains pivoting information about the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sytrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sytrf!","text":"sytrf!(uplo, A) -> (A, ipiv, info)\n\nComputes the Bunch-Kaufman factorization of a symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.\n\nReturns A, overwritten by the factorization, a pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.\n\n\n\n\n\nsytrf!(uplo, A, ipiv) -> (A, ipiv, info)\n\nComputes the Bunch-Kaufman factorization of a symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.\n\nReturns A, overwritten by the factorization, the pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sytri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sytri!","text":"sytri!(uplo, A, ipiv)\n\nComputes the inverse of a symmetric matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. A is overwritten by its inverse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sytrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sytrs!","text":"sytrs!(uplo, A, ipiv, B)\n\nSolves the equation A * X = B for a symmetric matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hesv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hesv!","text":"hesv!(uplo, A, B) -> (B, A, ipiv)\n\nFinds the solution to A * X = B for Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X. A is overwritten by its Bunch-Kaufman factorization. ipiv contains pivoting information about the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hetrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hetrf!","text":"hetrf!(uplo, A) -> (A, ipiv, info)\n\nComputes the Bunch-Kaufman factorization of a Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.\n\nReturns A, overwritten by the factorization, a pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.\n\n\n\n\n\nhetrf!(uplo, A, ipiv) -> (A, ipiv, info)\n\nComputes the Bunch-Kaufman factorization of a Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.\n\nReturns A, overwritten by the factorization, the pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hetri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hetri!","text":"hetri!(uplo, A, ipiv)\n\nComputes the inverse of a Hermitian matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. A is overwritten by its inverse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hetrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hetrs!","text":"hetrs!(uplo, A, ipiv, B)\n\nSolves the equation A * X = B for a Hermitian matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.syev!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.syev!","text":"syev!(jobz, uplo, A)\n\nFinds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.syevr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.syevr!","text":"syevr!(jobz, range, uplo, A, vl, vu, il, iu, abstol) -> (W, Z)\n\nFinds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. abstol can be set as a tolerance for convergence.\n\nThe eigenvalues are returned in W and the eigenvectors in Z.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.syevd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.syevd!","text":"syevd!(jobz, uplo, A)\n\nFinds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used.\n\nUse the divide-and-conquer method, instead of the QR iteration used by syev! or multiple relatively robust representations used by syevr!. See James W. Demmel et al, SIAM J. Sci. Comput. 30, 3, 1508 (2008) for a comparison of the accuracy and performatce of different methods.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sygvd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sygvd!","text":"sygvd!(itype, jobz, uplo, A, B) -> (w, A, B)\n\nFinds the generalized eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A and symmetric positive-definite matrix B. If uplo = U, the upper triangles of A and B are used. If uplo = L, the lower triangles of A and B are used. If itype = 1, the problem to solve is A * x = lambda * B * x. If itype = 2, the problem to solve is A * B * x = lambda * x. If itype = 3, the problem to solve is B * A * x = lambda * x.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.bdsqr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.bdsqr!","text":"bdsqr!(uplo, d, e_, Vt, U, C) -> (d, Vt, U, C)\n\nComputes the singular value decomposition of a bidiagonal matrix with d on the diagonal and e_ on the off-diagonal. If uplo = U, e_ is the superdiagonal. If uplo = L, e_ is the subdiagonal. Can optionally also compute the product Q' * C.\n\nReturns the singular values in d, and the matrix C overwritten with Q' * C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.bdsdc!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.bdsdc!","text":"bdsdc!(uplo, compq, d, e_) -> (d, e, u, vt, q, iq)\n\nComputes the singular value decomposition of a bidiagonal matrix with d on the diagonal and e_ on the off-diagonal using a divide and conqueq method. If uplo = U, e_ is the superdiagonal. If uplo = L, e_ is the subdiagonal. If compq = N, only the singular values are found. If compq = I, the singular values and vectors are found. If compq = P, the singular values and vectors are found in compact form. Only works for real types.\n\nReturns the singular values in d, and if compq = P, the compact singular vectors in iq.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gecon!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gecon!","text":"gecon!(normtype, A, anorm)\n\nFinds the reciprocal condition number of matrix A. If normtype = I, the condition number is found in the infinity norm. If normtype = O or 1, the condition number is found in the one norm. A must be the result of getrf! and anorm is the norm of A in the relevant norm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gehrd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gehrd!","text":"gehrd!(ilo, ihi, A) -> (A, tau)\n\nConverts a matrix A to Hessenberg form. If A is balanced with gebal! then ilo and ihi are the outputs of gebal!. Otherwise they should be ilo = 1 and ihi = size(A,2). tau contains the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orghr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orghr!","text":"orghr!(ilo, ihi, A, tau)\n\nExplicitly finds Q, the orthogonal/unitary matrix from gehrd!. ilo, ihi, A, and tau must correspond to the input/output to gehrd!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gees!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gees!","text":"gees!(jobvs, A) -> (A, vs, w)\n\nComputes the eigenvalues (jobvs = N) or the eigenvalues and Schur vectors (jobvs = V) of matrix A. A is overwritten by its Schur form.\n\nReturns A, vs containing the Schur vectors, and w, containing the eigenvalues.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gges!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gges!","text":"gges!(jobvsl, jobvsr, A, B) -> (A, B, alpha, beta, vsl, vsr)\n\nComputes the generalized eigenvalues, generalized Schur form, left Schur vectors (jobsvl = V), or right Schur vectors (jobvsr = V) of A and B.\n\nThe generalized eigenvalues are returned in alpha and beta. The left Schur vectors are returned in vsl and the right Schur vectors are returned in vsr.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gges3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gges3!","text":"gges3!(jobvsl, jobvsr, A, B) -> (A, B, alpha, beta, vsl, vsr)\n\nComputes the generalized eigenvalues, generalized Schur form, left Schur vectors (jobsvl = V), or right Schur vectors (jobvsr = V) of A and B using a blocked algorithm. This function requires LAPACK 3.6.0.\n\nThe generalized eigenvalues are returned in alpha and beta. The left Schur vectors are returned in vsl and the right Schur vectors are returned in vsr.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trexc!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trexc!","text":"trexc!(compq, ifst, ilst, T, Q) -> (T, Q)\ntrexc!(ifst, ilst, T, Q) -> (T, Q)\n\nReorder the Schur factorization T of a matrix, such that the diagonal block of T with row index ifst is moved to row index ilst. If compq = V, the Schur vectors Q are reordered. If compq = N they are not modified. The 4-arg method calls the 5-arg method with compq = V.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trsen!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trsen!","text":"trsen!(job, compq, select, T, Q) -> (T, Q, w, s, sep)\ntrsen!(select, T, Q) -> (T, Q, w, s, sep)\n\nReorder the Schur factorization of a matrix and optionally finds reciprocal condition numbers. If job = N, no condition numbers are found. If job = E, only the condition number for this cluster of eigenvalues is found. If job = V, only the condition number for the invariant subspace is found. If job = B then the condition numbers for the cluster and subspace are found. If compq = V the Schur vectors Q are updated. If compq = N the Schur vectors are not modified. select determines which eigenvalues are in the cluster. The 3-arg method calls the 5-arg method with job = N and compq = V.\n\nReturns T, Q, reordered eigenvalues in w, the condition number of the cluster of eigenvalues s, and the condition number of the invariant subspace sep.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.tgsen!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.tgsen!","text":"tgsen!(select, S, T, Q, Z) -> (S, T, alpha, beta, Q, Z)\n\nReorders the vectors of a generalized Schur decomposition. select specifies the eigenvalues in each cluster.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trsyl!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trsyl!","text":"trsyl!(transa, transb, A, B, C, isgn=1) -> (C, scale)\n\nSolves the Sylvester matrix equation A * X +/- X * B = scale*C where A and B are both quasi-upper triangular. If transa = N, A is not modified. If transa = T, A is transposed. If transa = C, A is conjugate transposed. Similarly for transb and B. If isgn = 1, the equation A * X + X * B = scale * C is solved. If isgn = -1, the equation A * X - X * B = scale * C is solved.\n\nReturns X (overwriting C) and scale.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hseqr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hseqr!","text":"hseqr!(job, compz, ilo, ihi, H, Z) -> (H, Z, w)\n\nComputes all eigenvalues and (optionally) the Schur factorization of a matrix reduced to Hessenberg form. If H is balanced with gebal! then ilo and ihi are the outputs of gebal!. Otherwise they should be ilo = 1 and ihi = size(H,2). tau contains the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/Sockets/","page":"Sockets","title":"Sockets","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Sockets/docs/src/index.md\"","category":"page"},{"location":"stdlib/Sockets/#Sockets","page":"Sockets","title":"Sockets","text":"","category":"section"},{"location":"stdlib/Sockets/","page":"Sockets","title":"Sockets","text":"Sockets.Sockets\nSockets.connect(::TCPSocket, ::Integer)\nSockets.connect(::AbstractString)\nSockets.listen(::Any)\nSockets.listen(::AbstractString)\nSockets.getaddrinfo\nSockets.getipaddr\nSockets.getipaddrs\nSockets.islinklocaladdr\nSockets.getalladdrinfo\nSockets.DNSError\nSockets.getnameinfo\nSockets.getsockname\nSockets.getpeername\nSockets.IPAddr\nSockets.IPv4\nSockets.IPv6\nSockets.@ip_str\nSockets.TCPSocket\nSockets.UDPSocket\nSockets.accept\nSockets.listenany\nSockets.bind\nSockets.send\nSockets.recv\nSockets.recvfrom\nSockets.setopt\nSockets.nagle\nSockets.quickack","category":"page"},{"location":"stdlib/Sockets/#Sockets.Sockets","page":"Sockets","title":"Sockets.Sockets","text":"Support for sockets. Provides IPAddr and subtypes, TCPSocket, and UDPSocket.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Sockets/#Sockets.connect-Tuple{TCPSocket, Integer}","page":"Sockets","title":"Sockets.connect","text":"connect([host], port::Integer) -> TCPSocket\n\nConnect to the host host on port port.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Sockets/#Sockets.connect-Tuple{AbstractString}","page":"Sockets","title":"Sockets.connect","text":"connect(path::AbstractString) -> PipeEndpoint\n\nConnect to the named pipe / UNIX domain socket at path.\n\nnote: Note\nPath length on Unix is limited to somewhere between 92 and 108 bytes (cf. man unix).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Sockets/#Sockets.listen-Tuple{Any}","page":"Sockets","title":"Sockets.listen","text":"listen([addr, ]port::Integer; backlog::Integer=BACKLOG_DEFAULT) -> TCPServer\n\nListen on port on the address specified by addr. By default this listens on localhost only. To listen on all interfaces pass IPv4(0) or IPv6(0) as appropriate. backlog determines how many connections can be pending (not having called accept) before the server will begin to reject them. The default value of backlog is 511.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Sockets/#Sockets.listen-Tuple{AbstractString}","page":"Sockets","title":"Sockets.listen","text":"listen(path::AbstractString) -> PipeServer\n\nCreate and listen on a named pipe / UNIX domain socket.\n\nnote: Note\nPath length on Unix is limited to somewhere between 92 and 108 bytes (cf. man unix).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Sockets/#Sockets.getaddrinfo","page":"Sockets","title":"Sockets.getaddrinfo","text":"getaddrinfo(host::AbstractString, IPAddr) -> IPAddr\n\nGets the first IP address of the host of the specified IPAddr type. Uses the operating system's underlying getaddrinfo implementation, which may do a DNS lookup.\n\nExamples\n\njulia> getaddrinfo(\"localhost\", IPv6)\nip\"::1\"\n\njulia> getaddrinfo(\"localhost\", IPv4)\nip\"127.0.0.1\"\n\n\n\n\n\ngetaddrinfo(host::AbstractString) -> IPAddr\n\nGets the first available IP address of host, which may be either an IPv4 or IPv6 address. Uses the operating system's underlying getaddrinfo implementation, which may do a DNS lookup.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getipaddr","page":"Sockets","title":"Sockets.getipaddr","text":"getipaddr() -> IPAddr\n\nGet an IP address of the local machine, preferring IPv4 over IPv6. Throws if no addresses are available.\n\ngetipaddr(addr_type::Type{T}) where T<:IPAddr -> T\n\nGet an IP address of the local machine of the specified type. Throws if no addresses of the specified type are available.\n\nThis function is a backwards-compatibility wrapper around getipaddrs. New applications should use getipaddrs instead.\n\nExamples\n\njulia> getipaddr()\nip\"192.168.1.28\"\n\njulia> getipaddr(IPv6)\nip\"fe80::9731:35af:e1c5:6e49\"\n\nSee also getipaddrs.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getipaddrs","page":"Sockets","title":"Sockets.getipaddrs","text":"getipaddrs(addr_type::Type{T}=IPAddr; loopback::Bool=false) where T<:IPAddr -> Vector{T}\n\nGet the IP addresses of the local machine.\n\nSetting the optional addr_type parameter to IPv4 or IPv6 causes only addresses of that type to be returned.\n\nThe loopback keyword argument dictates whether loopback addresses (e.g. ip\"127.0.0.1\", ip\"::1\") are included.\n\ncompat: Julia 1.2\nThis function is available as of Julia 1.2.\n\nExamples\n\njulia> getipaddrs()\n5-element Array{IPAddr,1}:\n ip\"198.51.100.17\"\n ip\"203.0.113.2\"\n ip\"2001:db8:8:4:445e:5fff:fe5d:5500\"\n ip\"2001:db8:8:4:c164:402e:7e3c:3668\"\n ip\"fe80::445e:5fff:fe5d:5500\"\n\njulia> getipaddrs(IPv6)\n3-element Array{IPv6,1}:\n ip\"2001:db8:8:4:445e:5fff:fe5d:5500\"\n ip\"2001:db8:8:4:c164:402e:7e3c:3668\"\n ip\"fe80::445e:5fff:fe5d:5500\"\n\nSee also islinklocaladdr.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.islinklocaladdr","page":"Sockets","title":"Sockets.islinklocaladdr","text":"islinklocaladdr(addr::IPAddr)\n\nTests if an IP address is a link-local address. Link-local addresses are not guaranteed to be unique beyond their network segment, therefore routers do not forward them. Link-local addresses are from the address blocks 169.254.0.0/16 or fe80::/10.\n\nExamples\n\nfilter(!islinklocaladdr, getipaddrs())\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getalladdrinfo","page":"Sockets","title":"Sockets.getalladdrinfo","text":"getalladdrinfo(host::AbstractString) -> Vector{IPAddr}\n\nGets all of the IP addresses of the host. Uses the operating system's underlying getaddrinfo implementation, which may do a DNS lookup.\n\nExamples\n\njulia> getalladdrinfo(\"google.com\")\n2-element Array{IPAddr,1}:\n ip\"172.217.6.174\"\n ip\"2607:f8b0:4000:804::200e\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.DNSError","page":"Sockets","title":"Sockets.DNSError","text":"DNSError\n\nThe type of exception thrown when an error occurs in DNS lookup. The host field indicates the host URL string. The code field indicates the error code based on libuv.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.getnameinfo","page":"Sockets","title":"Sockets.getnameinfo","text":"getnameinfo(host::IPAddr) -> String\n\nPerforms a reverse-lookup for IP address to return a hostname and service using the operating system's underlying getnameinfo implementation.\n\nExamples\n\njulia> getnameinfo(IPv4(\"8.8.8.8\"))\n\"google-public-dns-a.google.com\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getsockname","page":"Sockets","title":"Sockets.getsockname","text":"getsockname(sock::Union{TCPServer, TCPSocket}) -> (IPAddr, UInt16)\n\nGet the IP address and port that the given socket is bound to.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getpeername","page":"Sockets","title":"Sockets.getpeername","text":"getpeername(sock::TCPSocket) -> (IPAddr, UInt16)\n\nGet the IP address and port of the remote endpoint that the given socket is connected to. Valid only for connected TCP sockets.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.IPAddr","page":"Sockets","title":"Sockets.IPAddr","text":"IPAddr\n\nAbstract supertype for IP addresses. IPv4 and IPv6 are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.IPv4","page":"Sockets","title":"Sockets.IPv4","text":"IPv4(host::Integer) -> IPv4\n\nReturn an IPv4 object from IP address host formatted as an Integer.\n\nExamples\n\njulia> IPv4(3223256218)\nip\"192.30.252.154\"\n\n\n\n\n\nIPv4(str::AbstractString) -> IPv4\n\nParse an IPv4 address string into an IPv4 object.\n\nExamples\n\njulia> IPv4(\"127.0.0.1\")\nip\"127.0.0.1\"\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.IPv6","page":"Sockets","title":"Sockets.IPv6","text":"IPv6(host::Integer) -> IPv6\n\nReturn an IPv6 object from IP address host formatted as an Integer.\n\nExamples\n\njulia> IPv6(3223256218)\nip\"::c01e:fc9a\"\n\n\n\n\n\nIPv6(str::AbstractString) -> IPv6\n\nParse an IPv6 address string into an IPv6 object.\n\nExamples\n\njulia> IPv6(\"::1\")\nip\"::1\"\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.@ip_str","page":"Sockets","title":"Sockets.@ip_str","text":"@ip_str str -> IPAddr\n\nParse str as an IP address.\n\nExamples\n\njulia> ip\"127.0.0.1\"\nip\"127.0.0.1\"\n\njulia> @ip_str \"2001:db8:0:0:0:0:2:1\"\nip\"2001:db8::2:1\"\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Sockets/#Sockets.TCPSocket","page":"Sockets","title":"Sockets.TCPSocket","text":"TCPSocket(; delay=true)\n\nOpen a TCP socket using libuv. If delay is true, libuv delays creation of the socket's file descriptor till the first bind call. TCPSocket has various fields to denote the state of the socket as well as its send/receive buffers.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.UDPSocket","page":"Sockets","title":"Sockets.UDPSocket","text":"UDPSocket()\n\nOpen a UDP socket using libuv. UDPSocket has various fields to denote the state of the socket.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.accept","page":"Sockets","title":"Sockets.accept","text":"accept(server[, client])\n\nAccepts a connection on the given server and returns a connection to the client. An uninitialized client stream may be provided, in which case it will be used instead of creating a new stream.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.listenany","page":"Sockets","title":"Sockets.listenany","text":"listenany([host::IPAddr,] port_hint; backlog::Integer=BACKLOG_DEFAULT) -> (UInt16, TCPServer)\n\nCreate a TCPServer on any port, using hint as a starting point. Returns a tuple of the actual port that the server was created on and the server itself. The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Base.bind","page":"Sockets","title":"Base.bind","text":"bind(socket::Union{TCPServer, UDPSocket, TCPSocket}, host::IPAddr, port::Integer; ipv6only=false, reuseaddr=false, kws...)\n\nBind socket to the given host:port. Note that 0.0.0.0 will listen on all devices.\n\nThe ipv6only parameter disables dual stack mode. If ipv6only=true, only an IPv6 stack is created.\nIf reuseaddr=true, multiple threads or processes can bind to the same address without error if they all set reuseaddr=true, but only the last to bind will receive any traffic.\n\n\n\n\n\nbind(chnl::Channel, task::Task)\n\nAssociate the lifetime of chnl with a task. Channel chnl is automatically closed when the task terminates. Any uncaught exception in the task is propagated to all waiters on chnl.\n\nThe chnl object can be explicitly closed independent of task termination. Terminating tasks have no effect on already closed Channel objects.\n\nWhen a channel is bound to multiple tasks, the first task to terminate will close the channel. When multiple channels are bound to the same task, termination of the task will close all of the bound channels.\n\nExamples\n\njulia> c = Channel(0);\n\njulia> task = @async foreach(i->put!(c, i), 1:4);\n\njulia> bind(c,task);\n\njulia> for i in c\n @show i\n end;\ni = 1\ni = 2\ni = 3\ni = 4\n\njulia> isopen(c)\nfalse\n\njulia> c = Channel(0);\n\njulia> task = @async (put!(c, 1); error(\"foo\"));\n\njulia> bind(c, task);\n\njulia> take!(c)\n1\n\njulia> put!(c, 1);\nERROR: TaskFailedException\nStacktrace:\n[...]\n nested task error: foo\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.send","page":"Sockets","title":"Sockets.send","text":"send(socket::UDPSocket, host::IPAddr, port::Integer, msg)\n\nSend msg over socket to host:port.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.recv","page":"Sockets","title":"Sockets.recv","text":"recv(socket::UDPSocket)\n\nRead a UDP packet from the specified socket, and return the bytes received. This call blocks.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.recvfrom","page":"Sockets","title":"Sockets.recvfrom","text":"recvfrom(socket::UDPSocket) -> (host_port, data)\n\nRead a UDP packet from the specified socket, returning a tuple of (host_port, data), where host_port will be an InetAddr{IPv4} or InetAddr{IPv6}, as appropriate.\n\ncompat: Julia 1.3\nPrior to Julia version 1.3, the first returned value was an address (IPAddr). In version 1.3 it was changed to an InetAddr.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.setopt","page":"Sockets","title":"Sockets.setopt","text":"setopt(sock::UDPSocket; multicast_loop=nothing, multicast_ttl=nothing, enable_broadcast=nothing, ttl=nothing)\n\nSet UDP socket options.\n\nmulticast_loop: loopback for multicast packets (default: true).\nmulticast_ttl: TTL for multicast packets (default: nothing).\nenable_broadcast: flag must be set to true if socket will be used for broadcast messages, or else the UDP system will return an access error (default: false).\nttl: Time-to-live of packets sent on the socket (default: nothing).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.nagle","page":"Sockets","title":"Sockets.nagle","text":"nagle(socket::Union{TCPServer, TCPSocket}, enable::Bool)\n\nNagle's algorithm batches multiple small TCP packets into larger ones. This can improve throughput but worsen latency. Nagle's algorithm is enabled by default. This function sets whether Nagle's algorithm is active on a given TCP server or socket. The opposite option is called TCP_NODELAY in other languages.\n\ncompat: Julia 1.3\nThis function requires Julia 1.3 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.quickack","page":"Sockets","title":"Sockets.quickack","text":"quickack(socket::Union{TCPServer, TCPSocket}, enable::Bool)\n\nOn Linux systems, the TCP_QUICKACK is disabled or enabled on socket.\n\n\n\n\n\n","category":"function"},{"location":"manual/distributed-computing/#Multi-processing-and-Distributed-Computing","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"An implementation of distributed memory parallel computing is provided by module Distributed as part of the standard library shipped with Julia.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Most modern computers possess more than one CPU, and several computers can be combined together in a cluster. Harnessing the power of these multiple CPUs allows many computations to be completed more quickly. There are two major factors that influence performance: the speed of the CPUs themselves, and the speed of their access to memory. In a cluster, it's fairly obvious that a given CPU will have fastest access to the RAM within the same computer (node). Perhaps more surprisingly, similar issues are relevant on a typical multicore laptop, due to differences in the speed of main memory and the cache. Consequently, a good multiprocessing environment should allow control over the \"ownership\" of a chunk of memory by a particular CPU. Julia provides a multiprocessing environment based on message passing to allow programs to run on multiple processes in separate memory domains at once.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia's implementation of message passing is different from other environments such as MPI[1]. Communication in Julia is generally \"one-sided\", meaning that the programmer needs to explicitly manage only one process in a two-process operation. Furthermore, these operations typically do not look like \"message send\" and \"message receive\" but rather resemble higher-level operations like calls to user functions.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Distributed programming in Julia is built on two primitives: remote references and remote calls. A remote reference is an object that can be used from any process to refer to an object stored on a particular process. A remote call is a request by one process to call a certain function on certain arguments on another (possibly the same) process.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Remote references come in two flavors: Future and RemoteChannel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A remote call returns a Future to its result. Remote calls return immediately; the process that made the call proceeds to its next operation while the remote call happens somewhere else. You can wait for a remote call to finish by calling wait on the returned Future, and you can obtain the full value of the result using fetch.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"On the other hand, RemoteChannel s are rewritable. For example, multiple processes can coordinate their processing by referencing the same remote Channel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Each process has an associated identifier. The process providing the interactive Julia prompt always has an id equal to 1. The processes used by default for parallel operations are referred to as \"workers\". When there is only one process, process 1 is considered a worker. Otherwise, workers are considered to be all processes other than process 1. As a result, adding 2 or more processes is required to gain benefits from parallel processing methods like pmap. Adding a single process is beneficial if you just wish to do other things in the main process while a long computation is running on the worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Let's try this out. Starting with julia -p n provides n worker processes on the local machine. Generally it makes sense for n to equal the number of CPU threads (logical cores) on the machine. Note that the -p argument implicitly loads module Distributed.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"$ julia -p 2\n\njulia> r = remotecall(rand, 2, 2, 2)\nFuture(2, 1, 4, nothing)\n\njulia> s = @spawnat 2 1 .+ fetch(r)\nFuture(2, 1, 5, nothing)\n\njulia> fetch(s)\n2×2 Array{Float64,2}:\n 1.18526 1.50912\n 1.16296 1.60607","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The first argument to remotecall is the function to call. Most parallel programming in Julia does not reference specific processes or the number of processes available, but remotecall is considered a low-level interface providing finer control. The second argument to remotecall is the id of the process that will do the work, and the remaining arguments will be passed to the function being called.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As you can see, in the first line we asked process 2 to construct a 2-by-2 random matrix, and in the second line we asked it to add 1 to it. The result of both calculations is available in the two futures, r and s. The @spawnat macro evaluates the expression in the second argument on the process specified by the first argument.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Occasionally you might want a remotely-computed value immediately. This typically happens when you read from a remote object to obtain data needed by the next local operation. The function remotecall_fetch exists for this purpose. It is equivalent to fetch(remotecall(...)) but is more efficient.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> remotecall_fetch(r-> fetch(r)[1, 1], 2, r)\n0.18526337335308085","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This fetches the array on worker 2 and returns the first value. Note, that fetch doesn't move any data in this case, since it's executed on the worker that owns the array. One can also write:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> remotecall_fetch(getindex, 2, r, 1, 1)\n0.10824216411304866","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Remember that getindex(r,1,1) is equivalent to r[1,1], so this call fetches the first element of the future r.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"To make things easier, the symbol :any can be passed to @spawnat, which picks where to do the operation for you:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> r = @spawnat :any rand(2,2)\nFuture(2, 1, 4, nothing)\n\njulia> s = @spawnat :any 1 .+ fetch(r)\nFuture(3, 1, 5, nothing)\n\njulia> fetch(s)\n2×2 Array{Float64,2}:\n 1.38854 1.9098\n 1.20939 1.57158","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Note that we used 1 .+ fetch(r) instead of 1 .+ r. This is because we do not know where the code will run, so in general a fetch might be required to move r to the process doing the addition. In this case, @spawnat is smart enough to perform the computation on the process that owns r, so the fetch will be a no-op (no work is done).","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"(It is worth noting that @spawnat is not built-in but defined in Julia as a macro. It is possible to define your own such constructs.)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"An important thing to remember is that, once fetched, a Future will cache its value locally. Further fetch calls do not entail a network hop. Once all referencing Futures have fetched, the remote stored value is deleted.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"@async is similar to @spawnat, but only runs tasks on the local process. We use it to create a \"feeder\" task for each process. Each task picks the next index that needs to be computed, then waits for its process to finish, then repeats until we run out of indices. Note that the feeder tasks do not begin to execute until the main task reaches the end of the @sync block, at which point it surrenders control and waits for all the local tasks to complete before returning from the function. As for v0.7 and beyond, the feeder tasks are able to share state via nextidx because they all run on the same process. Even if Tasks are scheduled cooperatively, locking may still be required in some contexts, as in asynchronous I/O. This means context switches only occur at well-defined points: in this case, when remotecall_fetch is called. This is the current state of implementation and it may change for future Julia versions, as it is intended to make it possible to run up to N Tasks on M Process, aka M:N Threading. Then a lock acquiring\\releasing model for nextidx will be needed, as it is not safe to let multiple processes read-write a resource at the same time.","category":"page"},{"location":"manual/distributed-computing/#code-availability","page":"Multi-processing and Distributed Computing","title":"Code Availability and Loading Packages","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Your code must be available on any process that runs it. For example, type the following into the Julia prompt:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> function rand2(dims...)\n return 2*rand(dims...)\n end\n\njulia> rand2(2,2)\n2×2 Array{Float64,2}:\n 0.153756 0.368514\n 1.15119 0.918912\n\njulia> fetch(@spawnat :any rand2(2,2))\nERROR: RemoteException(2, CapturedException(UndefVarError(Symbol(\"#rand2\"))))\nStacktrace:\n[...]","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Process 1 knew about the function rand2, but process 2 did not.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Most commonly you'll be loading code from files or packages, and you have a considerable amount of flexibility in controlling which processes load code. Consider a file, DummyModule.jl, containing the following code:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"module DummyModule\n\nexport MyType, f\n\nmutable struct MyType\n a::Int\nend\n\nf(x) = x^2+1\n\nprintln(\"loaded\")\n\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In order to refer to MyType across all processes, DummyModule.jl needs to be loaded on every process. Calling include(\"DummyModule.jl\") loads it only on a single process. To load it on every process, use the @everywhere macro (starting Julia with julia -p 2):","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere include(\"DummyModule.jl\")\nloaded\n From worker 3: loaded\n From worker 2: loaded","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As usual, this does not bring DummyModule into scope on any of the process, which requires using or import. Moreover, when DummyModule is brought into scope on one process, it is not on any other:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using .DummyModule\n\njulia> MyType(7)\nMyType(7)\n\njulia> fetch(@spawnat 2 MyType(7))\nERROR: On worker 2:\nUndefVarError: `MyType` not defined in `Main`\n⋮\n\njulia> fetch(@spawnat 2 DummyModule.MyType(7))\nMyType(7)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"However, it's still possible, for instance, to send a MyType to a process which has loaded DummyModule even if it's not in scope:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> put!(RemoteChannel(2), MyType(7))\nRemoteChannel{Channel{Any}}(2, 1, 13)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A file can also be preloaded on multiple processes at startup with the -L flag, and a driver script can be used to drive the computation:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia -p -L file1.jl -L file2.jl driver.jl","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The Julia process running the driver script in the example above has an id equal to 1, just like a process providing an interactive prompt.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Finally, if DummyModule.jl is not a standalone file but a package, then using DummyModule will load DummyModule.jl on all processes, but only bring it into scope on the process where using was called.","category":"page"},{"location":"manual/distributed-computing/#Starting-and-managing-worker-processes","page":"Multi-processing and Distributed Computing","title":"Starting and managing worker processes","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The base Julia installation has in-built support for two types of clusters:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A local cluster specified with the -p option as shown above.\nA cluster spanning machines using the --machine-file option. This uses a passwordless ssh login to start Julia worker processes (from the same path as the current host) on the specified machines. Each machine definition takes the form [count*][user@]host[:port] [bind_addr[:port]]. user defaults to current user, port to the standard ssh port. count is the number of workers to spawn on the node, and defaults to 1. The optional bind-to bind_addr[:port] specifies the IP address and port that other workers should use to connect to this worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"note: Note\nWhile Julia generally strives for backward compatibility, distribution of code to worker processes relies on Serialization.serialize. As pointed out in the corresponding documentation, this can not be guaranteed to work across different Julia versions, so it is advised that all workers on all machines use the same version.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Functions addprocs, rmprocs, workers, and others are available as a programmatic means of adding, removing and querying the processes in a cluster.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using Distributed\n\njulia> addprocs(2)\n2-element Array{Int64,1}:\n 2\n 3","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Module Distributed must be explicitly loaded on the master process before invoking addprocs. It is automatically made available on the worker processes.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"note: Note\nNote that workers do not run a ~/.julia/config/startup.jl startup script, nor do they synchronize their global state (such as command-line switches, global variables, new method definitions, and loaded modules) with any of the other running processes. You may use addprocs(exeflags=\"--project\") to initialize a worker with a particular environment, and then @everywhere using or @everywhere include(\"file.jl\").","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Other types of clusters can be supported by writing your own custom ClusterManager, as described below in the ClusterManagers section.","category":"page"},{"location":"manual/distributed-computing/#Data-Movement","page":"Multi-processing and Distributed Computing","title":"Data Movement","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Sending messages and moving data constitute most of the overhead in a distributed program. Reducing the number of messages and the amount of data sent is critical to achieving performance and scalability. To this end, it is important to understand the data movement performed by Julia's various distributed programming constructs.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"fetch can be considered an explicit data movement operation, since it directly asks that an object be moved to the local machine. @spawnat (and a few related constructs) also moves data, but this is not as obvious, hence it can be called an implicit data movement operation. Consider these two approaches to constructing and squaring a random matrix:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Method 1:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> A = rand(1000,1000);\n\njulia> Bref = @spawnat :any A^2;\n\n[...]\n\njulia> fetch(Bref);","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Method 2:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> Bref = @spawnat :any rand(1000,1000)^2;\n\n[...]\n\njulia> fetch(Bref);","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The difference seems trivial, but in fact is quite significant due to the behavior of @spawnat. In the first method, a random matrix is constructed locally, then sent to another process where it is squared. In the second method, a random matrix is both constructed and squared on another process. Therefore the second method sends much less data than the first.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In this toy example, the two methods are easy to distinguish and choose from. However, in a real program designing data movement might require more thought and likely some measurement. For example, if the first process needs matrix A then the first method might be better. Or, if computing A is expensive and only the current process has it, then moving it to another process might be unavoidable. Or, if the current process has very little to do between the @spawnat and fetch(Bref), it might be better to eliminate the parallelism altogether. Or imagine rand(1000,1000) is replaced with a more expensive operation. Then it might make sense to add another @spawnat statement just for this step.","category":"page"},{"location":"manual/distributed-computing/#Global-variables","page":"Multi-processing and Distributed Computing","title":"Global variables","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Expressions executed remotely via @spawnat, or closures specified for remote execution using remotecall may refer to global variables. Global bindings under module Main are treated a little differently compared to global bindings in other modules. Consider the following code snippet:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A = rand(10,10)\nremotecall_fetch(()->sum(A), 2)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In this case sum MUST be defined in the remote process. Note that A is a global variable defined in the local workspace. Worker 2 does not have a variable called A under Main. The act of shipping the closure ()->sum(A) to worker 2 results in Main.A being defined on 2. Main.A continues to exist on worker 2 even after the call remotecall_fetch returns. Remote calls with embedded global references (under Main module only) manage globals as follows:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"New global bindings are created on destination workers if they are referenced as part of a remote call.\nGlobal constants are declared as constants on remote nodes too.\nGlobals are re-sent to a destination worker only in the context of a remote call, and then only if its value has changed. Also, the cluster does not synchronize global bindings across nodes. For example:\nA = rand(10,10)\nremotecall_fetch(()->sum(A), 2) # worker 2\nA = rand(10,10)\nremotecall_fetch(()->sum(A), 3) # worker 3\nA = nothing\nExecuting the above snippet results in Main.A on worker 2 having a different value from Main.A on worker 3, while the value of Main.A on node 1 is set to nothing.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As you may have realized, while memory associated with globals may be collected when they are reassigned on the master, no such action is taken on the workers as the bindings continue to be valid. clear! can be used to manually reassign specific globals on remote nodes to nothing once they are no longer required. This will release any memory associated with them as part of a regular garbage collection cycle.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Thus programs should be careful referencing globals in remote calls. In fact, it is preferable to avoid them altogether if possible. If you must reference globals, consider using let blocks to localize global variables.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"For example:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> A = rand(10,10);\n\njulia> remotecall_fetch(()->A, 2);\n\njulia> B = rand(10,10);\n\njulia> let B = B\n remotecall_fetch(()->B, 2)\n end;\n\njulia> @fetchfrom 2 InteractiveUtils.varinfo()\nname size summary\n––––––––– ––––––––– ––––––––––––––––––––––\nA 800 bytes 10×10 Array{Float64,2}\nBase Module\nCore Module\nMain Module","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As can be seen, global variable A is defined on worker 2, but B is captured as a local variable and hence a binding for B does not exist on worker 2.","category":"page"},{"location":"manual/distributed-computing/#Parallel-Map-and-Loops","page":"Multi-processing and Distributed Computing","title":"Parallel Map and Loops","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Fortunately, many useful parallel computations do not require data movement. A common example is a Monte Carlo simulation, where multiple processes can handle independent simulation trials simultaneously. We can use @spawnat to flip coins on two processes. First, write the following function in count_heads.jl:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"function count_heads(n)\n c::Int = 0\n for i = 1:n\n c += rand(Bool)\n end\n c\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The function count_heads simply adds together n random bits. Here is how we can perform some trials on two machines, and add together the results:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere include_string(Main, $(read(\"count_heads.jl\", String)), \"count_heads.jl\")\n\njulia> a = @spawnat :any count_heads(100000000)\nFuture(2, 1, 6, nothing)\n\njulia> b = @spawnat :any count_heads(100000000)\nFuture(3, 1, 7, nothing)\n\njulia> fetch(a)+fetch(b)\n100001564","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This example demonstrates a powerful and often-used parallel programming pattern. Many iterations run independently over several processes, and then their results are combined using some function. The combination process is called a reduction, since it is generally tensor-rank-reducing: a vector of numbers is reduced to a single number, or a matrix is reduced to a single row or column, etc. In code, this typically looks like the pattern x = f(x,v[i]), where x is the accumulator, f is the reduction function, and the v[i] are the elements being reduced. It is desirable for f to be associative, so that it does not matter what order the operations are performed in.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Notice that our use of this pattern with count_heads can be generalized. We used two explicit @spawnat statements, which limits the parallelism to two processes. To run on any number of processes, we can use a parallel for loop, running in distributed memory, which can be written in Julia using @distributed like this:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"nheads = @distributed (+) for i = 1:200000000\n Int(rand(Bool))\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This construct implements the pattern of assigning iterations to multiple processes, and combining them with a specified reduction (in this case (+)). The result of each iteration is taken as the value of the last expression inside the loop. The whole parallel loop expression itself evaluates to the final answer.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Note that although parallel for loops look like serial for loops, their behavior is dramatically different. In particular, the iterations do not happen in a specified order, and writes to variables or arrays will not be globally visible since iterations run on different processes. Any variables used inside the parallel loop will be copied and broadcast to each process.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"For example, the following code will not work as intended:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"a = zeros(100000)\n@distributed for i = 1:100000\n a[i] = i\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This code will not initialize all of a, since each process will have a separate copy of it. Parallel for loops like these must be avoided. Fortunately, Shared Arrays can be used to get around this limitation:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"using SharedArrays\n\na = SharedArray{Float64}(10)\n@distributed for i = 1:10\n a[i] = i\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Using \"outside\" variables in parallel loops is perfectly reasonable if the variables are read-only:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"a = randn(1000)\n@distributed (+) for i = 1:100000\n f(a[rand(1:end)])\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Here each iteration applies f to a randomly-chosen sample from a vector a shared by all processes.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As you could see, the reduction operator can be omitted if it is not needed. In that case, the loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns an array of Future immediately without waiting for completion. The caller can wait for the Future completions at a later point by calling fetch on them, or wait for completion at the end of the loop by prefixing it with @sync, like @sync @distributed for.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In some cases no reduction operator is needed, and we merely wish to apply a function to all integers in some range (or, more generally, to all elements in some collection). This is another useful operation called parallel map, implemented in Julia as the pmap function. For example, we could compute the singular values of several large random matrices in parallel as follows:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10];\n\njulia> pmap(svdvals, M);","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia's pmap is designed for the case where each function call does a large amount of work. In contrast, @distributed for can handle situations where each iteration is tiny, perhaps merely summing two numbers. Only worker processes are used by both pmap and @distributed for for the parallel computation. In case of @distributed for, the final reduction is done on the calling process.","category":"page"},{"location":"manual/distributed-computing/#Remote-References-and-AbstractChannels","page":"Multi-processing and Distributed Computing","title":"Remote References and AbstractChannels","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Remote references always refer to an implementation of an AbstractChannel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A concrete implementation of an AbstractChannel (like Channel), is required to implement put!, take!, fetch, isready and wait. The remote object referred to by a Future is stored in a Channel{Any}(1), i.e., a Channel of size 1 capable of holding objects of Any type.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"RemoteChannel, which is rewritable, can point to any type and size of channels, or any other implementation of an AbstractChannel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The constructor RemoteChannel(f::Function, pid)() allows us to construct references to channels holding more than one value of a specific type. f is a function executed on pid and it must return an AbstractChannel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"For example, RemoteChannel(()->Channel{Int}(10), pid), will return a reference to a channel of type Int and size 10. The channel exists on worker pid.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Methods put!, take!, fetch, isready and wait on a RemoteChannel are proxied onto the backing store on the remote process.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"RemoteChannel can thus be used to refer to user implemented AbstractChannel objects. A simple example of this is the following DictChannel which uses a dictionary as its remote store:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> struct DictChannel{T} <: AbstractChannel{T}\n d::Dict\n cond_take::Threads.Condition # waiting for data to become available\n DictChannel{T}() where {T} = new(Dict(), Threads.Condition())\n DictChannel() = DictChannel{Any}()\n end\n\njulia> begin\n function Base.put!(D::DictChannel, k, v)\n @lock D.cond_take begin\n D.d[k] = v\n notify(D.cond_take)\n end\n return D\n end\n function Base.take!(D::DictChannel, k)\n @lock D.cond_take begin\n v = fetch(D, k)\n delete!(D.d, k)\n return v\n end\n end\n Base.isready(D::DictChannel) = @lock D.cond_take !isempty(D.d)\n Base.isready(D::DictChannel, k) = @lock D.cond_take haskey(D.d, k)\n function Base.fetch(D::DictChannel, k)\n @lock D.cond_take begin\n wait(D, k)\n return D.d[k]\n end\n end\n function Base.wait(D::DictChannel, k)\n @lock D.cond_take begin\n while !isready(D, k)\n wait(D.cond_take)\n end\n end\n end\n end;\n\njulia> d = DictChannel();\n\njulia> isready(d)\nfalse\n\njulia> put!(d, :k, :v);\n\njulia> isready(d, :k)\ntrue\n\njulia> fetch(d, :k)\n:v\n\njulia> wait(d, :k)\n\njulia> take!(d, :k)\n:v\n\njulia> isready(d, :k)\nfalse","category":"page"},{"location":"manual/distributed-computing/#Channels-and-RemoteChannels","page":"Multi-processing and Distributed Computing","title":"Channels and RemoteChannels","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A Channel is local to a process. Worker 2 cannot directly refer to a Channel on worker 3 and vice-versa. A RemoteChannel, however, can put and take values across workers.\nA RemoteChannel can be thought of as a handle to a Channel.\nThe process id, pid, associated with a RemoteChannel identifies the process where the backing store, i.e., the backing Channel exists.\nAny process with a reference to a RemoteChannel can put and take items from the channel. Data is automatically sent to (or retrieved from) the process a RemoteChannel is associated with.\nSerializing a Channel also serializes any data present in the channel. Deserializing it therefore effectively makes a copy of the original object.\nOn the other hand, serializing a RemoteChannel only involves the serialization of an identifier that identifies the location and instance of Channel referred to by the handle. A deserialized RemoteChannel object (on any worker), therefore also points to the same backing store as the original.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The channels example from above can be modified for interprocess communication, as shown below.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"We start 4 workers to process a single jobs remote channel. Jobs, identified by an id (job_id), are written to the channel. Each remotely executing task in this simulation reads a job_id, waits for a random amount of time and writes back a tuple of job_id, time taken and its own pid to the results channel. Finally all the results are printed out on the master process.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> addprocs(4); # add worker processes\n\njulia> const jobs = RemoteChannel(()->Channel{Int}(32));\n\njulia> const results = RemoteChannel(()->Channel{Tuple}(32));\n\njulia> @everywhere function do_work(jobs, results) # define work function everywhere\n while true\n job_id = take!(jobs)\n exec_time = rand()\n sleep(exec_time) # simulates elapsed time doing actual work\n put!(results, (job_id, exec_time, myid()))\n end\n end\n\njulia> function make_jobs(n)\n for i in 1:n\n put!(jobs, i)\n end\n end;\n\njulia> n = 12;\n\njulia> errormonitor(@async make_jobs(n)); # feed the jobs channel with \"n\" jobs\n\njulia> for p in workers() # start tasks on the workers to process requests in parallel\n remote_do(do_work, p, jobs, results)\n end\n\njulia> @elapsed while n > 0 # print out results\n job_id, exec_time, where = take!(results)\n println(\"$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where\")\n global n = n - 1\n end\n1 finished in 0.18 seconds on worker 4\n2 finished in 0.26 seconds on worker 5\n6 finished in 0.12 seconds on worker 4\n7 finished in 0.18 seconds on worker 4\n5 finished in 0.35 seconds on worker 5\n4 finished in 0.68 seconds on worker 2\n3 finished in 0.73 seconds on worker 3\n11 finished in 0.01 seconds on worker 3\n12 finished in 0.02 seconds on worker 3\n9 finished in 0.26 seconds on worker 5\n8 finished in 0.57 seconds on worker 4\n10 finished in 0.58 seconds on worker 2\n0.055971741","category":"page"},{"location":"manual/distributed-computing/#Remote-References-and-Distributed-Garbage-Collection","page":"Multi-processing and Distributed Computing","title":"Remote References and Distributed Garbage Collection","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Objects referred to by remote references can be freed only when all held references in the cluster are deleted.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The node where the value is stored keeps track of which of the workers have a reference to it. Every time a RemoteChannel or a (unfetched) Future is serialized to a worker, the node pointed to by the reference is notified. And every time a RemoteChannel or a (unfetched) Future is garbage collected locally, the node owning the value is again notified. This is implemented in an internal cluster aware serializer. Remote references are only valid in the context of a running cluster. Serializing and deserializing references to and from regular IO objects is not supported.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The notifications are done via sending of \"tracking\" messages–an \"add reference\" message when a reference is serialized to a different process and a \"delete reference\" message when a reference is locally garbage collected.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Since Futures are write-once and cached locally, the act of fetching a Future also updates reference tracking information on the node owning the value.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The node which owns the value frees it once all references to it are cleared.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"With Futures, serializing an already fetched Future to a different node also sends the value since the original remote store may have collected the value by this time.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"It is important to note that when an object is locally garbage collected depends on the size of the object and the current memory pressure in the system.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In case of remote references, the size of the local reference object is quite small, while the value stored on the remote node may be quite large. Since the local object may not be collected immediately, it is a good practice to explicitly call finalize on local instances of a RemoteChannel, or on unfetched Futures. Since calling fetch on a Future also removes its reference from the remote store, this is not required on fetched Futures. Explicitly calling finalize results in an immediate message sent to the remote node to go ahead and remove its reference to the value.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Once finalized, a reference becomes invalid and cannot be used in any further calls.","category":"page"},{"location":"manual/distributed-computing/#Local-invocations","page":"Multi-processing and Distributed Computing","title":"Local invocations","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Data is necessarily copied over to the remote node for execution. This is the case for both remotecalls and when data is stored to a RemoteChannel / Future on a different node. As expected, this results in a copy of the serialized objects on the remote node. However, when the destination node is the local node, i.e. the calling process id is the same as the remote node id, it is executed as a local call. It is usually (not always) executed in a different task - but there is no serialization/deserialization of data. Consequently, the call refers to the same object instances as passed - no copies are created. This behavior is highlighted below:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using Distributed;\n\njulia> rc = RemoteChannel(()->Channel(3)); # RemoteChannel created on local node\n\njulia> v = [0];\n\njulia> for i in 1:3\n v[1] = i # Reusing `v`\n put!(rc, v)\n end;\n\njulia> result = [take!(rc) for _ in 1:3];\n\njulia> println(result);\nArray{Int64,1}[[3], [3], [3]]\n\njulia> println(\"Num Unique objects : \", length(unique(map(objectid, result))));\nNum Unique objects : 1\n\njulia> addprocs(1);\n\njulia> rc = RemoteChannel(()->Channel(3), workers()[1]); # RemoteChannel created on remote node\n\njulia> v = [0];\n\njulia> for i in 1:3\n v[1] = i\n put!(rc, v)\n end;\n\njulia> result = [take!(rc) for _ in 1:3];\n\njulia> println(result);\nArray{Int64,1}[[1], [2], [3]]\n\njulia> println(\"Num Unique objects : \", length(unique(map(objectid, result))));\nNum Unique objects : 3","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As can be seen, put! on a locally owned RemoteChannel with the same object v modified between calls results in the same single object instance stored. As opposed to copies of v being created when the node owning rc is a different node.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"It is to be noted that this is generally not an issue. It is something to be factored in only if the object is both being stored locally and modified post the call. In such cases it may be appropriate to store a deepcopy of the object.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This is also true for remotecalls on the local node as seen in the following example:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using Distributed; addprocs(1);\n\njulia> v = [0];\n\njulia> v2 = remotecall_fetch(x->(x[1] = 1; x), myid(), v); # Executed on local node\n\njulia> println(\"v=$v, v2=$v2, \", v === v2);\nv=[1], v2=[1], true\n\njulia> v = [0];\n\njulia> v2 = remotecall_fetch(x->(x[1] = 1; x), workers()[1], v); # Executed on remote node\n\njulia> println(\"v=$v, v2=$v2, \", v === v2);\nv=[0], v2=[1], false","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As can be seen once again, a remote call onto the local node behaves just like a direct invocation. The call modifies local objects passed as arguments. In the remote invocation, it operates on a copy of the arguments.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"To repeat, in general this is not an issue. If the local node is also being used as a compute node, and the arguments used post the call, this behavior needs to be factored in and if required deep copies of arguments must be passed to the call invoked on the local node. Calls on remote nodes will always operate on copies of arguments.","category":"page"},{"location":"manual/distributed-computing/#man-shared-arrays","page":"Multi-processing and Distributed Computing","title":"Shared Arrays","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Shared Arrays use system shared memory to map the same array across many processes. A SharedArray is a good choice when you want to have a large amount of data jointly accessible to two or more processes on the same machine. Shared Array support is available via the module SharedArrays, which must be explicitly loaded on all participating workers.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A complementary data structure is provided by the external package DistributedArrays.jl in the form of a DArray. While there are some similarities to a SharedArray, the behavior of a DArray is quite different. In a SharedArray, each \"participating\" process has access to the entire array; in contrast, in a DArray, each process has local access to just a chunk of the data, and no two processes share the same chunk.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"SharedArray indexing (assignment and accessing values) works just as with regular arrays, and is efficient because the underlying memory is available to the local process. Therefore, most algorithms work naturally on SharedArrays, albeit in single-process mode. In cases where an algorithm insists on an Array input, the underlying array can be retrieved from a SharedArray by calling sdata. For other AbstractArray types, sdata just returns the object itself, so it's safe to use sdata on any Array-type object.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The constructor for a shared array is of the form:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"SharedArray{T,N}(dims::NTuple; init=false, pids=Int[])","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"which creates an N-dimensional shared array of a bits type T and size dims across the processes specified by pids. Unlike distributed arrays, a shared array is accessible only from those participating workers specified by the pids named argument (and the creating process too, if it is on the same host). Note that only elements that are isbits are supported in a SharedArray.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"If an init function, of signature initfn(S::SharedArray), is specified, it is called on all the participating workers. You can specify that each worker runs the init function on a distinct portion of the array, thereby parallelizing initialization.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Here's a brief example:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using Distributed\n\njulia> addprocs(3)\n3-element Array{Int64,1}:\n 2\n 3\n 4\n\njulia> @everywhere using SharedArrays\n\njulia> S = SharedArray{Int,2}((3,4), init = S -> S[localindices(S)] = repeat([myid()], length(localindices(S))))\n3×4 SharedArray{Int64,2}:\n 2 2 3 4\n 2 3 3 4\n 2 3 4 4\n\njulia> S[3,2] = 7\n7\n\njulia> S\n3×4 SharedArray{Int64,2}:\n 2 2 3 4\n 2 3 3 4\n 2 7 4 4","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"SharedArrays.localindices provides disjoint one-dimensional ranges of indices, and is sometimes convenient for splitting up tasks among processes. You can, of course, divide the work any way you wish:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> S = SharedArray{Int,2}((3,4), init = S -> S[indexpids(S):length(procs(S)):length(S)] = repeat([myid()], length( indexpids(S):length(procs(S)):length(S))))\n3×4 SharedArray{Int64,2}:\n 2 2 2 2\n 3 3 3 3\n 4 4 4 4","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Since all processes have access to the underlying data, you do have to be careful not to set up conflicts. For example:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"@sync begin\n for p in procs(S)\n @async begin\n remotecall_wait(fill!, p, S, p)\n end\n end\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"would result in undefined behavior. Because each process fills the entire array with its own pid, whichever process is the last to execute (for any particular element of S) will have its pid retained.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As a more extended and complex example, consider running the following \"kernel\" in parallel:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"q[i,j,t+1] = q[i,j,t] + u[i,j,t]","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In this case, if we try to split up the work using a one-dimensional index, we are likely to run into trouble: if q[i,j,t] is near the end of the block assigned to one worker and q[i,j,t+1] is near the beginning of the block assigned to another, it's very likely that q[i,j,t] will not be ready at the time it's needed for computing q[i,j,t+1]. In such cases, one is better off chunking the array manually. Let's split along the second dimension. Define a function that returns the (irange, jrange) indices assigned to this worker:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere function myrange(q::SharedArray)\n idx = indexpids(q)\n if idx == 0 # This worker is not assigned a piece\n return 1:0, 1:0\n end\n nchunks = length(procs(q))\n splits = [round(Int, s) for s in range(0, stop=size(q,2), length=nchunks+1)]\n 1:size(q,1), splits[idx]+1:splits[idx+1]\n end","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Next, define the kernel:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere function advection_chunk!(q, u, irange, jrange, trange)\n @show (irange, jrange, trange) # display so we can see what's happening\n for t in trange, j in jrange, i in irange\n q[i,j,t+1] = q[i,j,t] + u[i,j,t]\n end\n q\n end","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"We also define a convenience wrapper for a SharedArray implementation","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere advection_shared_chunk!(q, u) =\n advection_chunk!(q, u, myrange(q)..., 1:size(q,3)-1)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Now let's compare three different versions, one that runs in a single process:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> advection_serial!(q, u) = advection_chunk!(q, u, 1:size(q,1), 1:size(q,2), 1:size(q,3)-1);","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"one that uses @distributed:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> function advection_parallel!(q, u)\n for t = 1:size(q,3)-1\n @sync @distributed for j = 1:size(q,2)\n for i = 1:size(q,1)\n q[i,j,t+1]= q[i,j,t] + u[i,j,t]\n end\n end\n end\n q\n end;","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"and one that delegates in chunks:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> function advection_shared!(q, u)\n @sync begin\n for p in procs(q)\n @async remotecall_wait(advection_shared_chunk!, p, q, u)\n end\n end\n q\n end;","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"If we create SharedArrays and time these functions, we get the following results (with julia -p 4):","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> q = SharedArray{Float64,3}((500,500,500));\n\njulia> u = SharedArray{Float64,3}((500,500,500));","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Run the functions once to JIT-compile and @time them on the second run:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @time advection_serial!(q, u);\n(irange,jrange,trange) = (1:500,1:500,1:499)\n 830.220 milliseconds (216 allocations: 13820 bytes)\n\njulia> @time advection_parallel!(q, u);\n 2.495 seconds (3999 k allocations: 289 MB, 2.09% gc time)\n\njulia> @time advection_shared!(q,u);\n From worker 2: (irange,jrange,trange) = (1:500,1:125,1:499)\n From worker 4: (irange,jrange,trange) = (1:500,251:375,1:499)\n From worker 3: (irange,jrange,trange) = (1:500,126:250,1:499)\n From worker 5: (irange,jrange,trange) = (1:500,376:500,1:499)\n 238.119 milliseconds (2264 allocations: 169 KB)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The biggest advantage of advection_shared! is that it minimizes traffic among the workers, allowing each to compute for an extended time on the assigned piece.","category":"page"},{"location":"manual/distributed-computing/#Shared-Arrays-and-Distributed-Garbage-Collection","page":"Multi-processing and Distributed Computing","title":"Shared Arrays and Distributed Garbage Collection","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Like remote references, shared arrays are also dependent on garbage collection on the creating node to release references from all participating workers. Code which creates many short lived shared array objects would benefit from explicitly finalizing these objects as soon as possible. This results in both memory and file handles mapping the shared segment being released sooner.","category":"page"},{"location":"manual/distributed-computing/#ClusterManagers","page":"Multi-processing and Distributed Computing","title":"ClusterManagers","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The launching, management and networking of Julia processes into a logical cluster is done via cluster managers. A ClusterManager is responsible for","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"launching worker processes in a cluster environment\nmanaging events during the lifetime of each worker\noptionally, providing data transport","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A Julia cluster has the following characteristics:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The initial Julia process, also called the master, is special and has an id of 1.\nOnly the master process can add or remove worker processes.\nAll processes can directly communicate with each other.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Connections between workers (using the in-built TCP/IP transport) is established in the following manner:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"addprocs is called on the master process with a ClusterManager object.\naddprocs calls the appropriate launch method which spawns required number of worker processes on appropriate machines.\nEach worker starts listening on a free port and writes out its host and port information to stdout.\nThe cluster manager captures the stdout of each worker and makes it available to the master process.\nThe master process parses this information and sets up TCP/IP connections to each worker.\nEvery worker is also notified of other workers in the cluster.\nEach worker connects to all workers whose id is less than the worker's own id.\nIn this way a mesh network is established, wherein every worker is directly connected with every other worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"While the default transport layer uses plain TCPSocket, it is possible for a Julia cluster to provide its own transport.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia provides two in-built cluster managers:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"LocalManager, used when addprocs() or addprocs(np::Integer) are called\nSSHManager, used when addprocs(hostnames::Array) is called with a list of hostnames","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"LocalManager is used to launch additional workers on the same host, thereby leveraging multi-core and multi-processor hardware.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Thus, a minimal cluster manager would need to:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"be a subtype of the abstract ClusterManager\nimplement launch, a method responsible for launching new workers\nimplement manage, which is called at various events during a worker's lifetime (for example, sending an interrupt signal)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"addprocs(manager::FooManager) requires FooManager to implement:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"function launch(manager::FooManager, params::Dict, launched::Array, c::Condition)\n [...]\nend\n\nfunction manage(manager::FooManager, id::Integer, config::WorkerConfig, op::Symbol)\n [...]\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As an example let us see how the LocalManager, the manager responsible for starting workers on the same host, is implemented:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"struct LocalManager <: ClusterManager\n np::Integer\nend\n\nfunction launch(manager::LocalManager, params::Dict, launched::Array, c::Condition)\n [...]\nend\n\nfunction manage(manager::LocalManager, id::Integer, config::WorkerConfig, op::Symbol)\n [...]\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The launch method takes the following arguments:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"manager::ClusterManager: the cluster manager that addprocs is called with\nparams::Dict: all the keyword arguments passed to addprocs\nlaunched::Array: the array to append one or more WorkerConfig objects to\nc::Condition: the condition variable to be notified as and when workers are launched","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The launch method is called asynchronously in a separate task. The termination of this task signals that all requested workers have been launched. Hence the launch function MUST exit as soon as all the requested workers have been launched.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Newly launched workers are connected to each other and the master process in an all-to-all manner. Specifying the command line argument --worker[=] results in the launched processes initializing themselves as workers and connections being set up via TCP/IP sockets.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"All workers in a cluster share the same cookie as the master. When the cookie is unspecified, i.e, with the --worker option, the worker tries to read it from its standard input. LocalManager and SSHManager both pass the cookie to newly launched workers via their standard inputs.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"By default a worker will listen on a free port at the address returned by a call to getipaddr(). A specific address to listen on may be specified by optional argument --bind-to bind_addr[:port]. This is useful for multi-homed hosts.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As an example of a non-TCP/IP transport, an implementation may choose to use MPI, in which case --worker must NOT be specified. Instead, newly launched workers should call init_worker(cookie) before using any of the parallel constructs.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"For every worker launched, the launch method must add a WorkerConfig object (with appropriate fields initialized) to launched","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"mutable struct WorkerConfig\n # Common fields relevant to all cluster managers\n io::Union{IO, Nothing}\n host::Union{AbstractString, Nothing}\n port::Union{Integer, Nothing}\n\n # Used when launching additional workers at a host\n count::Union{Int, Symbol, Nothing}\n exename::Union{AbstractString, Cmd, Nothing}\n exeflags::Union{Cmd, Nothing}\n\n # External cluster managers can use this to store information at a per-worker level\n # Can be a dict if multiple fields need to be stored.\n userdata::Any\n\n # SSHManager / SSH tunnel connections to workers\n tunnel::Union{Bool, Nothing}\n bind_addr::Union{AbstractString, Nothing}\n sshflags::Union{Cmd, Nothing}\n max_parallel::Union{Integer, Nothing}\n\n # Used by Local/SSH managers\n connect_at::Any\n\n [...]\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Most of the fields in WorkerConfig are used by the inbuilt managers. Custom cluster managers would typically specify only io or host / port:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"If io is specified, it is used to read host/port information. A Julia worker prints out its bind address and port at startup. This allows Julia workers to listen on any free port available instead of requiring worker ports to be configured manually.\nIf io is not specified, host and port are used to connect.\ncount, exename and exeflags are relevant for launching additional workers from a worker. For example, a cluster manager may launch a single worker per node, and use that to launch additional workers.\ncount with an integer value n will launch a total of n workers.\ncount with a value of :auto will launch as many workers as the number of CPU threads (logical cores) on that machine.\nexename is the name of the julia executable including the full path.\nexeflags should be set to the required command line arguments for new workers.\ntunnel, bind_addr, sshflags and max_parallel are used when a ssh tunnel is required to connect to the workers from the master process.\nuserdata is provided for custom cluster managers to store their own worker-specific information.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"manage(manager::FooManager, id::Integer, config::WorkerConfig, op::Symbol) is called at different times during the worker's lifetime with appropriate op values:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"with :register/:deregister when a worker is added / removed from the Julia worker pool.\nwith :interrupt when interrupt(workers) is called. The ClusterManager should signal the appropriate worker with an interrupt signal.\nwith :finalize for cleanup purposes.","category":"page"},{"location":"manual/distributed-computing/#Cluster-Managers-with-Custom-Transports","page":"Multi-processing and Distributed Computing","title":"Cluster Managers with Custom Transports","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Replacing the default TCP/IP all-to-all socket connections with a custom transport layer is a little more involved. Each Julia process has as many communication tasks as the workers it is connected to. For example, consider a Julia cluster of 32 processes in an all-to-all mesh network:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Each Julia process thus has 31 communication tasks.\nEach task handles all incoming messages from a single remote worker in a message-processing loop.\nThe message-processing loop waits on an IO object (for example, a TCPSocket in the default implementation), reads an entire message, processes it and waits for the next one.\nSending messages to a process is done directly from any Julia task–not just communication tasks–again, via the appropriate IO object.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Replacing the default transport requires the new implementation to set up connections to remote workers and to provide appropriate IO objects that the message-processing loops can wait on. The manager-specific callbacks to be implemented are:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"connect(manager::FooManager, pid::Integer, config::WorkerConfig)\nkill(manager::FooManager, pid::Int, config::WorkerConfig)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The default implementation (which uses TCP/IP sockets) is implemented as connect(manager::ClusterManager, pid::Integer, config::WorkerConfig).","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"connect should return a pair of IO objects, one for reading data sent from worker pid, and the other to write data that needs to be sent to worker pid. Custom cluster managers can use an in-memory BufferStream as the plumbing to proxy data between the custom, possibly non-IO transport and Julia's in-built parallel infrastructure.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A BufferStream is an in-memory IOBuffer which behaves like an IO–it is a stream which can be handled asynchronously.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The folder clustermanager/0mq in the Examples repository contains an example of using ZeroMQ to connect Julia workers in a star topology with a 0MQ broker in the middle. Note: The Julia processes are still all logically connected to each other–any worker can message any other worker directly without any awareness of 0MQ being used as the transport layer.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"When using custom transports:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia workers must NOT be started with --worker. Starting with --worker will result in the newly launched workers defaulting to the TCP/IP socket transport implementation.\nFor every incoming logical connection with a worker, Base.process_messages(rd::IO, wr::IO)() must be called. This launches a new task that handles reading and writing of messages from/to the worker represented by the IO objects.\ninit_worker(cookie, manager::FooManager) must be called as part of worker process initialization.\nField connect_at::Any in WorkerConfig can be set by the cluster manager when launch is called. The value of this field is passed in all connect callbacks. Typically, it carries information on how to connect to a worker. For example, the TCP/IP socket transport uses this field to specify the (host, port) tuple at which to connect to a worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"kill(manager, pid, config) is called to remove a worker from the cluster. On the master process, the corresponding IO objects must be closed by the implementation to ensure proper cleanup. The default implementation simply executes an exit() call on the specified remote worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The Examples folder clustermanager/simple is an example that shows a simple implementation using UNIX domain sockets for cluster setup.","category":"page"},{"location":"manual/distributed-computing/#Network-Requirements-for-LocalManager-and-SSHManager","page":"Multi-processing and Distributed Computing","title":"Network Requirements for LocalManager and SSHManager","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia clusters are designed to be executed on already secured environments on infrastructure such as local laptops, departmental clusters, or even the cloud. This section covers network security requirements for the inbuilt LocalManager and SSHManager:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The master process does not listen on any port. It only connects out to the workers.\nEach worker binds to only one of the local interfaces and listens on an ephemeral port number assigned by the OS.\nLocalManager, used by addprocs(N), by default binds only to the loopback interface. This means that workers started later on remote hosts (or by anyone with malicious intentions) are unable to connect to the cluster. An addprocs(4) followed by an addprocs([\"remote_host\"]) will fail. Some users may need to create a cluster comprising their local system and a few remote systems. This can be done by explicitly requesting LocalManager to bind to an external network interface via the restrict keyword argument: addprocs(4; restrict=false).\nSSHManager, used by addprocs(list_of_remote_hosts), launches workers on remote hosts via SSH. By default SSH is only used to launch Julia workers. Subsequent master-worker and worker-worker connections use plain, unencrypted TCP/IP sockets. The remote hosts must have passwordless login enabled. Additional SSH flags or credentials may be specified via keyword argument sshflags.\naddprocs(list_of_remote_hosts; tunnel=true, sshflags=) is useful when we wish to use SSH connections for master-worker too. A typical scenario for this is a local laptop running the Julia REPL (i.e., the master) with the rest of the cluster on the cloud, say on Amazon EC2. In this case only port 22 needs to be opened at the remote cluster coupled with SSH client authenticated via public key infrastructure (PKI). Authentication credentials can be supplied via sshflags, for example sshflags=`-i `.\nIn an all-to-all topology (the default), all workers connect to each other via plain TCP sockets. The security policy on the cluster nodes must thus ensure free connectivity between workers for the ephemeral port range (varies by OS).\nSecuring and encrypting all worker-worker traffic (via SSH) or encrypting individual messages can be done via a custom ClusterManager.\nIf you specify multiplex=true as an option to addprocs, SSH multiplexing is used to create a tunnel between the master and workers. If you have configured SSH multiplexing on your own and the connection has already been established, SSH multiplexing is used regardless of multiplex option. If multiplexing is enabled, forwarding is set by using the existing connection (-O forward option in ssh). This is beneficial if your servers require password authentication; you can avoid authentication in Julia by logging in to the server ahead of addprocs. The control socket will be located at ~/.ssh/julia-%r@%h:%p during the session unless the existing multiplexing connection is used. Note that bandwidth may be limited if you create multiple processes on a node and enable multiplexing, because in that case processes share a single multiplexing TCP connection.","category":"page"},{"location":"manual/distributed-computing/#man-cluster-cookie","page":"Multi-processing and Distributed Computing","title":"Cluster Cookie","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"All processes in a cluster share the same cookie which, by default, is a randomly generated string on the master process:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"cluster_cookie() returns the cookie, while cluster_cookie(cookie)() sets it and returns the new cookie.\nAll connections are authenticated on both sides to ensure that only workers started by the master are allowed to connect to each other.\nThe cookie may be passed to the workers at startup via argument --worker=. If argument --worker is specified without the cookie, the worker tries to read the cookie from its standard input (stdin). The stdin is closed immediately after the cookie is retrieved.\nClusterManagers can retrieve the cookie on the master by calling cluster_cookie(). Cluster managers not using the default TCP/IP transport (and hence not specifying --worker) must call init_worker(cookie, manager) with the same cookie as on the master.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Note that environments requiring higher levels of security can implement this via a custom ClusterManager. For example, cookies can be pre-shared and hence not specified as a startup argument.","category":"page"},{"location":"manual/distributed-computing/#Specifying-Network-Topology-(Experimental)","page":"Multi-processing and Distributed Computing","title":"Specifying Network Topology (Experimental)","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The keyword argument topology passed to addprocs is used to specify how the workers must be connected to each other:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":":all_to_all, the default: all workers are connected to each other.\n:master_worker: only the driver process, i.e. pid 1, has connections to the workers.\n:custom: the launch method of the cluster manager specifies the connection topology via the fields ident and connect_idents in WorkerConfig. A worker with a cluster-manager-provided identity ident will connect to all workers specified in connect_idents.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Keyword argument lazy=true|false only affects topology option :all_to_all. If true, the cluster starts off with the master connected to all workers. Specific worker-worker connections are established at the first remote invocation between two workers. This helps in reducing initial resources allocated for intra-cluster communication. Connections are setup depending on the runtime requirements of a parallel program. Default value for lazy is true.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Currently, sending a message between unconnected workers results in an error. This behaviour, as with the functionality and interface, should be considered experimental in nature and may change in future releases.","category":"page"},{"location":"manual/distributed-computing/#Noteworthy-external-packages","page":"Multi-processing and Distributed Computing","title":"Noteworthy external packages","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Outside of Julia parallelism there are plenty of external packages that should be mentioned. For example, MPI.jl is a Julia wrapper for the MPI protocol, Dagger.jl provides functionality similar to Python's Dask, and DistributedArrays.jl provides array operations distributed across workers, as outlined above.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A mention must be made of Julia's GPU programming ecosystem, which includes:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"CUDA.jl wraps the various CUDA libraries and supports compiling Julia kernels for Nvidia GPUs.\noneAPI.jl wraps the oneAPI unified programming model, and supports executing Julia kernels on supported accelerators. Currently only Linux is supported.\nAMDGPU.jl wraps the AMD ROCm libraries and supports compiling Julia kernels for AMD GPUs. Currently only Linux is supported.\nHigh-level libraries like KernelAbstractions.jl, Tullio.jl and ArrayFire.jl.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In the following example we will use both DistributedArrays.jl and CUDA.jl to distribute an array across multiple processes by first casting it through distribute() and CuArray().","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Remember when importing DistributedArrays.jl to import it across all processes using @everywhere","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"$ ./julia -p 4\n\njulia> addprocs()\n\njulia> @everywhere using DistributedArrays\n\njulia> using CUDA\n\njulia> B = ones(10_000) ./ 2;\n\njulia> A = ones(10_000) .* π;\n\njulia> C = 2 .* A ./ B;\n\njulia> all(C .≈ 4*π)\ntrue\n\njulia> typeof(C)\nArray{Float64,1}\n\njulia> dB = distribute(B);\n\njulia> dA = distribute(A);\n\njulia> dC = 2 .* dA ./ dB;\n\njulia> all(dC .≈ 4*π)\ntrue\n\njulia> typeof(dC)\nDistributedArrays.DArray{Float64,1,Array{Float64,1}}\n\njulia> cuB = CuArray(B);\n\njulia> cuA = CuArray(A);\n\njulia> cuC = 2 .* cuA ./ cuB;\n\njulia> all(cuC .≈ 4*π);\ntrue\n\njulia> typeof(cuC)\nCuArray{Float64,1}","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In the following example we will use both DistributedArrays.jl and CUDA.jl to distribute an array across multiple processes and call a generic function on it.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"function power_method(M, v)\n for i in 1:100\n v = M*v\n v /= norm(v)\n end\n\n return v, norm(M*v) / norm(v) # or (M*v) ./ v\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"power_method repeatedly creates a new vector and normalizes it. We have not specified any type signature in function declaration, let's see if it works with the aforementioned datatypes:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> M = [2. 1; 1 1];\n\njulia> v = rand(2)\n2-element Array{Float64,1}:\n0.40395\n0.445877\n\njulia> power_method(M,v)\n([0.850651, 0.525731], 2.618033988749895)\n\njulia> cuM = CuArray(M);\n\njulia> cuv = CuArray(v);\n\njulia> curesult = power_method(cuM, cuv);\n\njulia> typeof(curesult)\nCuArray{Float64,1}\n\njulia> dM = distribute(M);\n\njulia> dv = distribute(v);\n\njulia> dC = power_method(dM, dv);\n\njulia> typeof(dC)\nTuple{DistributedArrays.DArray{Float64,1,Array{Float64,1}},Float64}","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"To end this short exposure to external packages, we can consider MPI.jl, a Julia wrapper of the MPI protocol. As it would take too long to consider every inner function, it would be better to simply appreciate the approach used to implement the protocol.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Consider this toy script which simply calls each subprocess, instantiate its rank and when the master process is reached, performs the ranks' sum","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"import MPI\n\nMPI.Init()\n\ncomm = MPI.COMM_WORLD\nMPI.Barrier(comm)\n\nroot = 0\nr = MPI.Comm_rank(comm)\n\nsr = MPI.Reduce(r, MPI.SUM, root, comm)\n\nif(MPI.Comm_rank(comm) == root)\n @printf(\"sum of ranks: %s\\n\", sr)\nend\n\nMPI.Finalize()","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"mpirun -np 4 ./julia example.jl","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"[1]: In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication patterns. For additional information on the latest MPI standard, see https://mpi-forum.org/docs.","category":"page"},{"location":"manual/running-external-programs/#Running-External-Programs","page":"Running External Programs","title":"Running External Programs","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Julia borrows backtick notation for commands from the shell, Perl, and Ruby. However, in Julia, writing","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> `echo hello`\n`echo hello`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"differs in several aspects from the behavior in various shells, Perl, or Ruby:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Instead of immediately running the command, backticks create a Cmd object to represent the command. You can use this object to connect the command to others via pipes, run it, and read or write to it.\nWhen the command is run, Julia does not capture its output unless you specifically arrange for it to. Instead, the output of the command by default goes to stdout as it would using libc's system call.\nThe command is never run with a shell. Instead, Julia parses the command syntax directly, appropriately interpolating variables and splitting on words as the shell would, respecting shell quoting syntax. The command is run as julia's immediate child process, using fork and exec calls.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"note: Note\nThe following assumes a Posix environment as on Linux or MacOS. On Windows, many similar commands, such as echo and dir, are not external programs and instead are built into the shell cmd.exe itself. One option to run these commands is to invoke cmd.exe, for example cmd /C echo hello. Alternatively Julia can be run inside a Posix environment such as Cygwin.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Here's a simple example of running an external program:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> mycommand = `echo hello`\n`echo hello`\n\njulia> typeof(mycommand)\nCmd\n\njulia> run(mycommand);\nhello","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The hello is the output of the echo command, sent to stdout. If the external command fails to run successfully, the run method throws an ProcessFailedException.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"If you want to read the output of the external command, read or readchomp can be used instead:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> read(`echo hello`, String)\n\"hello\\n\"\n\njulia> readchomp(`echo hello`)\n\"hello\"","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"More generally, you can use open to read from or write to an external command.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> open(`less`, \"w\", stdout) do io\n for i = 1:3\n println(io, i)\n end\n end\n1\n2\n3","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The program name and the individual arguments in a command can be accessed and iterated over as if the command were an array of strings:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> collect(`echo \"foo bar\"`)\n2-element Vector{String}:\n \"echo\"\n \"foo bar\"\n\njulia> `echo \"foo bar\"`[2]\n\"foo bar\"","category":"page"},{"location":"manual/running-external-programs/#command-interpolation","page":"Running External Programs","title":"Interpolation","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Suppose you want to do something a bit more complicated and use the name of a file in the variable file as an argument to a command. You can use $ for interpolation much as you would in a string literal (see Strings):","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> file = \"/etc/passwd\"\n\"/etc/passwd\"\n\njulia> `sort $file`\n`sort /etc/passwd`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"A common pitfall when running external programs via a shell is that if a file name contains characters that are special to the shell, they may cause undesirable behavior. Suppose, for example, rather than /etc/passwd, we wanted to sort the contents of the file /Volumes/External HD/data.csv. Let's try it:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> file = \"/Volumes/External HD/data.csv\"\n\"/Volumes/External HD/data.csv\"\n\njulia> `sort $file`\n`sort '/Volumes/External HD/data.csv'`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"How did the file name get quoted? Julia knows that file is meant to be interpolated as a single argument, so it quotes the word for you. Actually, that is not quite accurate: the value of file is never interpreted by a shell, so there's no need for actual quoting; the quotes are inserted only for presentation to the user. This will even work if you interpolate a value as part of a shell word:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> path = \"/Volumes/External HD\"\n\"/Volumes/External HD\"\n\njulia> name = \"data\"\n\"data\"\n\njulia> ext = \"csv\"\n\"csv\"\n\njulia> `sort $path/$name.$ext`\n`sort '/Volumes/External HD/data.csv'`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"As you can see, the space in the path variable is appropriately escaped. But what if you want to interpolate multiple words? In that case, just use an array (or any other iterable container):","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> files = [\"/etc/passwd\",\"/Volumes/External HD/data.csv\"]\n2-element Vector{String}:\n \"/etc/passwd\"\n \"/Volumes/External HD/data.csv\"\n\njulia> `grep foo $files`\n`grep foo /etc/passwd '/Volumes/External HD/data.csv'`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"If you interpolate an array as part of a shell word, Julia emulates the shell's {a,b,c} argument generation:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> names = [\"foo\",\"bar\",\"baz\"]\n3-element Vector{String}:\n \"foo\"\n \"bar\"\n \"baz\"\n\njulia> `grep xylophone $names.txt`\n`grep xylophone foo.txt bar.txt baz.txt`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Moreover, if you interpolate multiple arrays into the same word, the shell's Cartesian product generation behavior is emulated:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> names = [\"foo\",\"bar\",\"baz\"]\n3-element Vector{String}:\n \"foo\"\n \"bar\"\n \"baz\"\n\njulia> exts = [\"aux\",\"log\"]\n2-element Vector{String}:\n \"aux\"\n \"log\"\n\njulia> `rm -f $names.$exts`\n`rm -f foo.aux foo.log bar.aux bar.log baz.aux baz.log`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Since you can interpolate literal arrays, you can use this generative functionality without needing to create temporary array objects first:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> `rm -rf $[\"foo\",\"bar\",\"baz\",\"qux\"].$[\"aux\",\"log\",\"pdf\"]`\n`rm -rf foo.aux foo.log foo.pdf bar.aux bar.log bar.pdf baz.aux baz.log baz.pdf qux.aux qux.log qux.pdf`","category":"page"},{"location":"manual/running-external-programs/#Quoting","page":"Running External Programs","title":"Quoting","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Inevitably, one wants to write commands that aren't quite so simple, and it becomes necessary to use quotes. Here's a simple example of a Perl one-liner at a shell prompt:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"sh$ perl -le '$|=1; for (0..3) { print }'\n0\n1\n2\n3","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The Perl expression needs to be in single quotes for two reasons: so that spaces don't break the expression into multiple shell words, and so that uses of Perl variables like $| (yes, that's the name of a variable in Perl), don't cause interpolation. In other instances, you may want to use double quotes so that interpolation does occur:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"sh$ first=\"A\"\nsh$ second=\"B\"\nsh$ perl -le '$|=1; print for @ARGV' \"1: $first\" \"2: $second\"\n1: A\n2: B","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"In general, the Julia backtick syntax is carefully designed so that you can just cut-and-paste shell commands as is into backticks and they will work: the escaping, quoting, and interpolation behaviors are the same as the shell's. The only difference is that the interpolation is integrated and aware of Julia's notion of what is a single string value, and what is a container for multiple values. Let's try the above two examples in Julia:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> A = `perl -le '$|=1; for (0..3) { print }'`\n`perl -le '$|=1; for (0..3) { print }'`\n\njulia> run(A);\n0\n1\n2\n3\n\njulia> first = \"A\"; second = \"B\";\n\njulia> B = `perl -le 'print for @ARGV' \"1: $first\" \"2: $second\"`\n`perl -le 'print for @ARGV' '1: A' '2: B'`\n\njulia> run(B);\n1: A\n2: B","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The results are identical, and Julia's interpolation behavior mimics the shell's with some improvements due to the fact that Julia supports first-class iterable objects while most shells use strings split on spaces for this, which introduces ambiguities. When trying to port shell commands to Julia, try cut and pasting first. Since Julia shows commands to you before running them, you can easily and safely just examine its interpretation without doing any damage.","category":"page"},{"location":"manual/running-external-programs/#Pipelines","page":"Running External Programs","title":"Pipelines","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Shell metacharacters, such as |, &, and >, need to be quoted (or escaped) inside of Julia's backticks:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(`echo hello '|' sort`);\nhello | sort\n\njulia> run(`echo hello \\| sort`);\nhello | sort","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This expression invokes the echo command with three words as arguments: hello, |, and sort. The result is that a single line is printed: hello | sort. How, then, does one construct a pipeline? Instead of using '|' inside of backticks, one uses pipeline:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(pipeline(`echo hello`, `sort`));\nhello","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This pipes the output of the echo command to the sort command. Of course, this isn't terribly interesting since there's only one line to sort, but we can certainly do much more interesting things:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(pipeline(`cut -d: -f3 /etc/passwd`, `sort -n`, `tail -n5`))\n210\n211\n212\n213\n214","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This prints the highest five user IDs on a UNIX system. The cut, sort and tail commands are all spawned as immediate children of the current julia process, with no intervening shell process. Julia itself does the work to setup pipes and connect file descriptors that is normally done by the shell. Since Julia does this itself, it retains better control and can do some things that shells cannot.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Julia can run multiple commands in parallel:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(`echo hello` & `echo world`);\nworld\nhello","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The order of the output here is non-deterministic because the two echo processes are started nearly simultaneously, and race to make the first write to the stdout descriptor they share with each other and the julia parent process. Julia lets you pipe the output from both of these processes to another program:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(pipeline(`echo world` & `echo hello`, `sort`));\nhello\nworld","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"In terms of UNIX plumbing, what's happening here is that a single UNIX pipe object is created and written to by both echo processes, and the other end of the pipe is read from by the sort command.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"IO redirection can be accomplished by passing keyword arguments stdin, stdout, and stderr to the pipeline function:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"pipeline(`do_work`, stdout=pipeline(`sort`, \"out.txt\"), stderr=\"errs.txt\")","category":"page"},{"location":"manual/running-external-programs/#Avoiding-Deadlock-in-Pipelines","page":"Running External Programs","title":"Avoiding Deadlock in Pipelines","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"When reading and writing to both ends of a pipeline from a single process, it is important to avoid forcing the kernel to buffer all of the data.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"For example, when reading all of the output from a command, call read(out, String), not wait(process), since the former will actively consume all of the data written by the process, whereas the latter will attempt to store the data in the kernel's buffers while waiting for a reader to be connected.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Another common solution is to separate the reader and writer of the pipeline into separate Tasks:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"writer = @async write(process, \"data\")\nreader = @async do_compute(read(process, String))\nwait(writer)\nfetch(reader)","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"(commonly also, reader is not a separate task, since we immediately fetch it anyways).","category":"page"},{"location":"manual/running-external-programs/#Complex-Example","page":"Running External Programs","title":"Complex Example","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The combination of a high-level programming language, a first-class command abstraction, and automatic setup of pipes between processes is a powerful one. To give some sense of the complex pipelines that can be created easily, here are some more sophisticated examples, with apologies for the excessive use of Perl one-liners:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> prefixer(prefix, sleep) = `perl -nle '$|=1; print \"'$prefix' \", $_; sleep '$sleep';'`;\n\njulia> run(pipeline(`perl -le '$|=1; for(0..5){ print; sleep 1 }'`, prefixer(\"A\",2) & prefixer(\"B\",2)));\nB 0\nA 1\nB 2\nA 3\nB 4\nA 5","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This is a classic example of a single producer feeding two concurrent consumers: one perl process generates lines with the numbers 0 through 5 on them, while two parallel processes consume that output, one prefixing lines with the letter \"A\", the other with the letter \"B\". Which consumer gets the first line is non-deterministic, but once that race has been won, the lines are consumed alternately by one process and then the other. (Setting $|=1 in Perl causes each print statement to flush the stdout handle, which is necessary for this example to work. Otherwise all the output is buffered and printed to the pipe at once, to be read by just one consumer process.)","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Here is an even more complex multi-stage producer-consumer example:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(pipeline(`perl -le '$|=1; for(0..5){ print; sleep 1 }'`,\n prefixer(\"X\",3) & prefixer(\"Y\",3) & prefixer(\"Z\",3),\n prefixer(\"A\",2) & prefixer(\"B\",2)));\nA X 0\nB Y 1\nA Z 2\nB X 3\nA Y 4\nB Z 5","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This example is similar to the previous one, except there are two stages of consumers, and the stages have different latency so they use a different number of parallel workers, to maintain saturated throughput.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"We strongly encourage you to try all these examples to see how they work.","category":"page"},{"location":"manual/running-external-programs/#Cmd-Objects","page":"Running External Programs","title":"Cmd Objects","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The backtick syntax create an object of type Cmd. Such object may also be constructed directly from an existing Cmd or list of arguments:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"run(Cmd(`pwd`, dir=\"..\"))\nrun(Cmd([\"pwd\"], detach=true, ignorestatus=true))","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This allows you to specify several aspects of the Cmd's execution environment via keyword arguments. For example, the dir keyword provides control over the Cmd's working directory:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(Cmd(`pwd`, dir=\"/\"));\n/","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"And the env keyword allows you to set execution environment variables:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(Cmd(`sh -c \"echo foo \\$HOWLONG\"`, env=(\"HOWLONG\" => \"ever!\",)));\nfoo ever!","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"See Cmd for additional keyword arguments. The setenv and addenv commands provide another means for replacing or adding to the Cmd execution environment variables, respectively:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(setenv(`sh -c \"echo foo \\$HOWLONG\"`, (\"HOWLONG\" => \"ever!\",)));\nfoo ever!\n\njulia> run(addenv(`sh -c \"echo foo \\$HOWLONG\"`, \"HOWLONG\" => \"ever!\"));\nfoo ever!","category":"page"},{"location":"manual/networking-and-streams/#Networking-and-Streams","page":"Networking and Streams","title":"Networking and Streams","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Julia provides a rich interface to deal with streaming I/O objects such as terminals, pipes and TCP sockets. These objects allow data to be sent and received in a stream-like fashion, which means that data is processed sequentially as it becomes available. This interface, though asynchronous at the system level, is presented in a synchronous manner to the programmer. This is achieved by making heavy use of Julia cooperative threading (coroutine) functionality.","category":"page"},{"location":"manual/networking-and-streams/#Basic-Stream-I/O","page":"Networking and Streams","title":"Basic Stream I/O","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"All Julia streams expose at least a read and a write method, taking the stream as their first argument, e.g.:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> write(stdout, \"Hello World\"); # suppress return value 11 with ;\nHello World\njulia> read(stdin, Char)\n\n'\\n': ASCII/Unicode U+000a (category Cc: Other, control)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that write returns 11, the number of bytes (in \"Hello World\") written to stdout, but this return value is suppressed with the ;.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Here Enter was pressed again so that Julia would read the newline. Now, as you can see from this example, write takes the data to write as its second argument, while read takes the type of the data to be read as the second argument.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"For example, to read a simple byte array, we could do:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> x = zeros(UInt8, 4)\n4-element Array{UInt8,1}:\n 0x00\n 0x00\n 0x00\n 0x00\n\njulia> read!(stdin, x)\nabcd\n4-element Array{UInt8,1}:\n 0x61\n 0x62\n 0x63\n 0x64","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"However, since this is slightly cumbersome, there are several convenience methods provided. For example, we could have written the above as:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> read(stdin, 4)\nabcd\n4-element Array{UInt8,1}:\n 0x61\n 0x62\n 0x63\n 0x64","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"or if we had wanted to read the entire line instead:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> readline(stdin)\nabcd\n\"abcd\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that depending on your terminal settings, your TTY (\"teletype terminal\") may be line buffered and might thus require an additional enter before stdin data is sent to Julia. When running Julia from the command line in a TTY, output is sent to the console by default, and standard input is read from the keyboard.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To read every line from stdin you can use eachline:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"for line in eachline(stdin)\n print(\"Found $line\")\nend","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"or read if you wanted to read by character instead:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"while !eof(stdin)\n x = read(stdin, Char)\n println(\"Found: $x\")\nend","category":"page"},{"location":"manual/networking-and-streams/#Text-I/O","page":"Networking and Streams","title":"Text I/O","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that the write method mentioned above operates on binary streams. In particular, values do not get converted to any canonical text representation but are written out as is:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> write(stdout, 0x61); # suppress return value 1 with ;\na","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that a is written to stdout by the write function and that the returned value is 1 (since 0x61 is one byte).","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"For text I/O, use the print or show methods, depending on your needs (see the documentation for these two methods for a detailed discussion of the difference between them):","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> print(stdout, 0x61)\n97","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"See Custom pretty-printing for more information on how to implement display methods for custom types.","category":"page"},{"location":"manual/networking-and-streams/#IO-Output-Contextual-Properties","page":"Networking and Streams","title":"IO Output Contextual Properties","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Sometimes IO output can benefit from the ability to pass contextual information into show methods. The IOContext object provides this framework for associating arbitrary metadata with an IO object. For example, :compact => true adds a hinting parameter to the IO object that the invoked show method should print a shorter output (if applicable). See the IOContext documentation for a list of common properties.","category":"page"},{"location":"manual/networking-and-streams/#Working-with-Files","page":"Networking and Streams","title":"Working with Files","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"You can write content to a file with the write(filename::String, content) method:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> write(\"hello.txt\", \"Hello, World!\")\n13","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"(13 is the number of bytes written.)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"You can read the contents of a file with the read(filename::String) method, or read(filename::String, String) to the contents as a string:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> read(\"hello.txt\", String)\n\"Hello, World!\"","category":"page"},{"location":"manual/networking-and-streams/#Advanced:-streaming-files","page":"Networking and Streams","title":"Advanced: streaming files","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"The read and write methods above allow you to read and write file contents. Like many other environments, Julia also has an open function, which takes a filename and returns an IOStream object that you can use to read and write things from the file. For example, if we have a file, hello.txt, whose contents are Hello, World!:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> f = open(\"hello.txt\")\nIOStream()\n\njulia> readlines(f)\n1-element Array{String,1}:\n \"Hello, World!\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"If you want to write to a file, you can open it with the write (\"w\") flag:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> f = open(\"hello.txt\",\"w\")\nIOStream()\n\njulia> write(f,\"Hello again.\")\n12","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"If you examine the contents of hello.txt at this point, you will notice that it is empty; nothing has actually been written to disk yet. This is because the IOStream must be closed before the write is actually flushed to disk:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> close(f)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Examining hello.txt again will show its contents have been changed.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Opening a file, doing something to its contents, and closing it again is a very common pattern. To make this easier, there exists another invocation of open which takes a function as its first argument and filename as its second, opens the file, calls the function with the file as an argument, and then closes it again. For example, given a function:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"function read_and_capitalize(f::IOStream)\n return uppercase(read(f, String))\nend","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"You can call:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> open(read_and_capitalize, \"hello.txt\")\n\"HELLO AGAIN.\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"to open hello.txt, call read_and_capitalize on it, close hello.txt and return the capitalized contents.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To avoid even having to define a named function, you can use the do syntax, which creates an anonymous function on the fly:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> open(\"hello.txt\") do f\n uppercase(read(f, String))\n end\n\"HELLO AGAIN.\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"If you want to redirect stdout to a file","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"out_file = open(\"output.txt\", \"w\")\n\n# Redirect stdout to file\nredirect_stdout(out_file) do\n # Your code here\n println(\"This output goes to `out_file` via the `stdout` variable.\")\nend\n\n# Close file\nclose(out_file)\n","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Redirecting stdout to a file can help you save and analyze program output, automate processes, and meet compliance requirements.","category":"page"},{"location":"manual/networking-and-streams/#A-simple-TCP-example","page":"Networking and Streams","title":"A simple TCP example","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Let's jump right in with a simple example involving TCP sockets. This functionality is in a standard library package called Sockets. Let's first create a simple server:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> using Sockets\n\njulia> errormonitor(@async begin\n server = listen(2000)\n while true\n sock = accept(server)\n println(\"Hello World\\n\")\n end\n end)\nTask (runnable) @0x00007fd31dc11ae0","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To those familiar with the Unix socket API, the method names will feel familiar, though their usage is somewhat simpler than the raw Unix socket API. The first call to listen will create a server waiting for incoming connections on the specified port (2000) in this case. The same function may also be used to create various other kinds of servers:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> listen(2000) # Listens on localhost:2000 (IPv4)\nSockets.TCPServer(active)\n\njulia> listen(ip\"127.0.0.1\",2000) # Equivalent to the first\nSockets.TCPServer(active)\n\njulia> listen(ip\"::1\",2000) # Listens on localhost:2000 (IPv6)\nSockets.TCPServer(active)\n\njulia> listen(IPv4(0),2001) # Listens on port 2001 on all IPv4 interfaces\nSockets.TCPServer(active)\n\njulia> listen(IPv6(0),2001) # Listens on port 2001 on all IPv6 interfaces\nSockets.TCPServer(active)\n\njulia> listen(\"testsocket\") # Listens on a UNIX domain socket\nSockets.PipeServer(active)\n\njulia> listen(\"\\\\\\\\.\\\\pipe\\\\testsocket\") # Listens on a Windows named pipe\nSockets.PipeServer(active)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that the return type of the last invocation is different. This is because this server does not listen on TCP, but rather on a named pipe (Windows) or UNIX domain socket. Also note that Windows named pipe format has to be a specific pattern such that the name prefix (\\\\.\\pipe\\) uniquely identifies the file type. The difference between TCP and named pipes or UNIX domain sockets is subtle and has to do with the accept and connect methods. The accept method retrieves a connection to the client that is connecting on the server we just created, while the connect function connects to a server using the specified method. The connect function takes the same arguments as listen, so, assuming the environment (i.e. host, cwd, etc.) is the same you should be able to pass the same arguments to connect as you did to listen to establish the connection. So let's try that out (after having created the server above):","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> connect(2000)\nTCPSocket(open, 0 bytes waiting)\n\njulia> Hello World","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"As expected we saw \"Hello World\" printed. So, let's actually analyze what happened behind the scenes. When we called connect, we connect to the server we had just created. Meanwhile, the accept function returns a server-side connection to the newly created socket and prints \"Hello World\" to indicate that the connection was successful.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"A great strength of Julia is that since the API is exposed synchronously even though the I/O is actually happening asynchronously, we didn't have to worry about callbacks or even making sure that the server gets to run. When we called connect the current task waited for the connection to be established and only continued executing after that was done. In this pause, the server task resumed execution (because a connection request was now available), accepted the connection, printed the message and waited for the next client. Reading and writing works in the same way. To see this, consider the following simple echo server:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> errormonitor(@async begin\n server = listen(2001)\n while true\n sock = accept(server)\n @async while isopen(sock)\n write(sock, readline(sock, keep=true))\n end\n end\n end)\nTask (runnable) @0x00007fd31dc12e60\n\njulia> clientside = connect(2001)\nTCPSocket(RawFD(28) open, 0 bytes waiting)\n\njulia> errormonitor(@async while isopen(clientside)\n write(stdout, readline(clientside, keep=true))\n end)\nTask (runnable) @0x00007fd31dc11870\n\njulia> println(clientside,\"Hello World from the Echo Server\")\nHello World from the Echo Server","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"As with other streams, use close to disconnect the socket:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> close(clientside)","category":"page"},{"location":"manual/networking-and-streams/#Resolving-IP-Addresses","page":"Networking and Streams","title":"Resolving IP Addresses","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"One of the connect methods that does not follow the listen methods is connect(host::String,port), which will attempt to connect to the host given by the host parameter on the port given by the port parameter. It allows you to do things like:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> connect(\"google.com\", 80)\nTCPSocket(RawFD(30) open, 0 bytes waiting)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"At the base of this functionality is getaddrinfo, which will do the appropriate address resolution:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> getaddrinfo(\"google.com\")\nip\"74.125.226.225\"","category":"page"},{"location":"manual/networking-and-streams/#Asynchronous-I/O","page":"Networking and Streams","title":"Asynchronous I/O","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"All I/O operations exposed by Base.read and Base.write can be performed asynchronously through the use of coroutines. You can create a new coroutine to read from or write to a stream using the @async macro:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> task = @async open(\"foo.txt\", \"w\") do io\n write(io, \"Hello, World!\")\n end;\n\njulia> wait(task)\n\njulia> readlines(\"foo.txt\")\n1-element Array{String,1}:\n \"Hello, World!\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"It's common to run into situations where you want to perform multiple asynchronous operations concurrently and wait until they've all completed. You can use the @sync macro to cause your program to block until all of the coroutines it wraps around have exited:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> using Sockets\n\njulia> @sync for hostname in (\"google.com\", \"github.com\", \"julialang.org\")\n @async begin\n conn = connect(hostname, 80)\n write(conn, \"GET / HTTP/1.1\\r\\nHost:$(hostname)\\r\\n\\r\\n\")\n readline(conn, keep=true)\n println(\"Finished connection to $(hostname)\")\n end\n end\nFinished connection to google.com\nFinished connection to julialang.org\nFinished connection to github.com","category":"page"},{"location":"manual/networking-and-streams/#Multicast","page":"Networking and Streams","title":"Multicast","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Julia supports multicast over IPv4 and IPv6 using the User Datagram Protocol (UDP) as transport.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Unlike the Transmission Control Protocol (TCP), UDP makes almost no assumptions about the needs of the application. TCP provides flow control (it accelerates and decelerates to maximize throughput), reliability (lost or corrupt packets are automatically retransmitted), sequencing (packets are ordered by the operating system before they are given to the application), segment size, and session setup and teardown. UDP provides no such features.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"A common use for UDP is in multicast applications. TCP is a stateful protocol for communication between exactly two devices. UDP can use special multicast addresses to allow simultaneous communication between many devices.","category":"page"},{"location":"manual/networking-and-streams/#Receiving-IP-Multicast-Packets","page":"Networking and Streams","title":"Receiving IP Multicast Packets","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To transmit data over UDP multicast, simply recv on the socket, and the first packet received will be returned. Note that it may not be the first packet that you sent however!","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"using Sockets\ngroup = ip\"228.5.6.7\"\nsocket = Sockets.UDPSocket()\nbind(socket, ip\"0.0.0.0\", 6789)\njoin_multicast_group(socket, group)\nprintln(String(recv(socket)))\nleave_multicast_group(socket, group)\nclose(socket)","category":"page"},{"location":"manual/networking-and-streams/#Sending-IP-Multicast-Packets","page":"Networking and Streams","title":"Sending IP Multicast Packets","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To transmit data over UDP multicast, simply send to the socket. Notice that it is not necessary for a sender to join the multicast group.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"using Sockets\ngroup = ip\"228.5.6.7\"\nsocket = Sockets.UDPSocket()\nsend(socket, group, 6789, \"Hello over IPv4\")\nclose(socket)","category":"page"},{"location":"manual/networking-and-streams/#IPv6-Example","page":"Networking and Streams","title":"IPv6 Example","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"This example gives the same functionality as the previous program, but uses IPv6 as the network-layer protocol.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Listener:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"using Sockets\ngroup = Sockets.IPv6(\"ff05::5:6:7\")\nsocket = Sockets.UDPSocket()\nbind(socket, Sockets.IPv6(\"::\"), 6789)\njoin_multicast_group(socket, group)\nprintln(String(recv(socket)))\nleave_multicast_group(socket, group)\nclose(socket)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Sender:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"using Sockets\ngroup = Sockets.IPv6(\"ff05::5:6:7\")\nsocket = Sockets.UDPSocket()\nsend(socket, group, 6789, \"Hello over IPv6\")\nclose(socket)","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/REPL/docs/src/index.md\"","category":"page"},{"location":"stdlib/REPL/#The-Julia-REPL","page":"The Julia REPL","title":"The Julia REPL","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Julia comes with a full-featured interactive command-line REPL (read-eval-print loop) built into the julia executable. In addition to allowing quick and easy evaluation of Julia statements, it has a searchable history, tab-completion, many helpful keybindings, and dedicated help and shell modes. The REPL can be started by simply calling julia with no arguments or double-clicking on the executable:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"using REPL\nio = IOBuffer()\nREPL.banner(io)\nbanner = String(take!(io))\nimport Markdown\nMarkdown.parse(\"```\\n\\$ julia\\n\\n$(banner)\\njulia>\\n```\")","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"To exit the interactive session, type ^D – the control key together with the d key on a blank line – or type exit() followed by the return or enter key. The REPL greets you with a banner and a julia> prompt.","category":"page"},{"location":"stdlib/REPL/#The-different-prompt-modes","page":"The Julia REPL","title":"The different prompt modes","text":"","category":"section"},{"location":"stdlib/REPL/#The-Julian-mode","page":"The Julia REPL","title":"The Julian mode","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The REPL has five main modes of operation. The first and most common is the Julian prompt. It is the default mode of operation; each new line initially starts with julia>. It is here that you can enter Julia expressions. Hitting return or enter after a complete expression has been entered will evaluate the entry and show the result of the last expression.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> string(1 + 2)\n\"3\"","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"There are a number of useful features unique to interactive work. In addition to showing the result, the REPL also binds the result to the variable ans. A trailing semicolon on the line can be used as a flag to suppress showing the result.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> string(3 * 4);\n\njulia> ans\n\"12\"","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In Julia mode, the REPL supports something called prompt pasting. This activates when pasting text that starts with julia> into the REPL. In that case, only expressions starting with julia> (as well as the other REPL mode prompts: shell>, help?>, pkg> ) are parsed, but others are removed. This makes it possible to paste a chunk of text that has been copied from a REPL session without having to scrub away prompts and outputs. This feature is enabled by default but can be disabled or enabled at will with REPL.enable_promptpaste(::Bool). If it is enabled, you can try it out by pasting the code block above this paragraph straight into the REPL. This feature does not work on the standard Windows command prompt due to its limitation at detecting when a paste occurs.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Objects are printed at the REPL using the show function with a specific IOContext. In particular, the :limit attribute is set to true. Other attributes can receive in certain show methods a default value if it's not already set, like :compact. It's possible, as an experimental feature, to specify the attributes used by the REPL via the Base.active_repl.options.iocontext dictionary (associating values to attributes). For example:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> rand(2, 2)\n2×2 Array{Float64,2}:\n 0.8833 0.329197\n 0.719708 0.59114\n\njulia> show(IOContext(stdout, :compact => false), \"text/plain\", rand(2, 2))\n 0.43540323669187075 0.15759787870609387\n 0.2540832269192739 0.4597637838786053\njulia> Base.active_repl.options.iocontext[:compact] = false;\n\njulia> rand(2, 2)\n2×2 Array{Float64,2}:\n 0.2083967319174056 0.13330606013126012\n 0.6244375177790158 0.9777957560761545","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In order to define automatically the values of this dictionary at startup time, one can use the atreplinit function in the ~/.julia/config/startup.jl file, for example:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"atreplinit() do repl\n repl.options.iocontext[:compact] = false\nend","category":"page"},{"location":"stdlib/REPL/#Help-mode","page":"The Julia REPL","title":"Help mode","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"When the cursor is at the beginning of the line, the prompt can be changed to a help mode by typing ?. Julia will attempt to print help or documentation for anything entered in help mode:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ? # upon typing ?, the prompt changes (in place) to: help?>\n\nhelp?> string\nsearch: string String Cstring Cwstring RevString randstring bytestring SubString\n\n string(xs...)\n\n Create a string from any values using the print function.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Macros, types and variables can also be queried:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"help?> @time\n @time\n\n A macro to execute an expression, printing the time it took to execute, the number of allocations,\n and the total number of bytes its execution caused to be allocated, before returning the value of the\n expression.\n\n See also @timev, @timed, @elapsed, and @allocated.\n\nhelp?> Int32\nsearch: Int32 UInt32\n\n Int32 <: Signed\n\n 32-bit signed integer type.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"A string or regex literal searches all docstrings using apropos:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"help?> \"aprop\"\nREPL.stripmd\nBase.Docs.apropos\n\nhelp?> r\"ap..p\"\nBase.:∘\nBase.shell_escape_posixly\nDistributed.CachingPool\nREPL.stripmd\nBase.Docs.apropos","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Another feature of help mode is the ability to access extended docstrings. You can do this by typing something like ??Print rather than ?Print which will display the # Extended help section from the source codes documentation.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Help mode can be exited by pressing backspace at the beginning of the line.","category":"page"},{"location":"stdlib/REPL/#man-shell-mode","page":"The Julia REPL","title":"Shell mode","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Just as help mode is useful for quick access to documentation, another common task is to use the system shell to execute system commands. Just as ? entered help mode when at the beginning of the line, a semicolon (;) will enter the shell mode. And it can be exited by pressing backspace at the beginning of the line.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ; # upon typing ;, the prompt changes (in place) to: shell>\n\nshell> echo hello\nhello","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"note: Note\nFor Windows users, Julia's shell mode does not expose windows shell commands. Hence, this will fail:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ; # upon typing ;, the prompt changes (in place) to: shell>\n\nshell> dir\nERROR: IOError: could not spawn `dir`: no such file or directory (ENOENT)\nStacktrace!\n.......","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"However, you can get access to PowerShell like this:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ; # upon typing ;, the prompt changes (in place) to: shell>\n\nshell> powershell\nWindows PowerShell\nCopyright (C) Microsoft Corporation. All rights reserved.\nPS C:\\Users\\elm>","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"... and to cmd.exe like that (see the dir command):","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ; # upon typing ;, the prompt changes (in place) to: shell>\n\nshell> cmd\nMicrosoft Windows [version 10.0.17763.973]\n(c) 2018 Microsoft Corporation. All rights reserved.\nC:\\Users\\elm>dir\n Volume in drive C has no label\n Volume Serial Number is 1643-0CD7\n Directory of C:\\Users\\elm\n\n29/01/2020 22:15 .\n29/01/2020 22:15 ..\n02/02/2020 08:06 .atom","category":"page"},{"location":"stdlib/REPL/#Pkg-mode","page":"The Julia REPL","title":"Pkg mode","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The Package manager mode accepts specialized commands for loading and updating packages. It is entered by pressing the ] key at the Julian REPL prompt and exited by pressing CTRL-C or pressing the backspace key at the beginning of the line. The prompt for this mode is pkg>. It supports its own help-mode, which is entered by pressing ? at the beginning of the line of the pkg> prompt. The Package manager mode is documented in the Pkg manual, available at https://julialang.github.io/Pkg.jl/v1/.","category":"page"},{"location":"stdlib/REPL/#Search-modes","page":"The Julia REPL","title":"Search modes","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In all of the above modes, the executed lines get saved to a history file, which can be searched. To initiate an incremental search through the previous history, type ^R – the control key together with the r key. The prompt will change to (reverse-i-search)`':, and as you type the search query will appear in the quotes. The most recent result that matches the query will dynamically update to the right of the colon as more is typed. To find an older result using the same query, simply type ^R again.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Just as ^R is a reverse search, ^S is a forward search, with the prompt (i-search)`':. The two may be used in conjunction with each other to move through the previous or next matching results, respectively.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"All executed commands in the Julia REPL are logged into ~/.julia/logs/repl_history.jl along with a timestamp of when it was executed and the current REPL mode you were in. Search mode queries this log file in order to find the commands which you previously ran. This can be disabled at startup by passing the --history-file=no flag to Julia.","category":"page"},{"location":"stdlib/REPL/#Key-bindings","page":"The Julia REPL","title":"Key bindings","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The Julia REPL makes great use of key bindings. Several control-key bindings were already introduced above (^D to exit, ^R and ^S for searching), but there are many more. In addition to the control-key, there are also meta-key bindings. These vary more by platform, but most terminals default to using alt- or option- held down with a key to send the meta-key (or can be configured to do so), or pressing Esc and then the key.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Keybinding Description\nProgram control \n^D Exit (when buffer is empty)\n^C Interrupt or cancel\n^L Clear console screen\nReturn/Enter, ^J New line, executing if it is complete\nmeta-Return/Enter Insert new line without executing it\n? or ; Enter help or shell mode (when at start of a line)\n^R, ^S Incremental history search, described above\nCursor movement \nRight arrow, ^F Move right one character\nLeft arrow, ^B Move left one character\nctrl-Right, meta-F Move right one word\nctrl-Left, meta-B Move left one word\nHome, ^A Move to beginning of line\nEnd, ^E Move to end of line\nUp arrow, ^P Move up one line (or change to the previous history entry that matches the text before the cursor)\nDown arrow, ^N Move down one line (or change to the next history entry that matches the text before the cursor)\nShift-Arrow Key Move cursor according to the direction of the Arrow key, while activating the region (\"shift selection\")\nPage-up, meta-P Change to the previous history entry\nPage-down, meta-N Change to the next history entry\nmeta-< Change to the first history entry (of the current session if it is before the current position in history)\nmeta-> Change to the last history entry\n^-Space Set the \"mark\" in the editing region (and de-activate the region if it's active)\n^-Space ^-Space Set the \"mark\" in the editing region and make the region \"active\", i.e. highlighted\n^G De-activate the region (i.e. make it not highlighted)\n^X^X Exchange the current position with the mark\nEditing \nBackspace, ^H Delete the previous character, or the whole region when it's active\nDelete, ^D Forward delete one character (when buffer has text)\nmeta-Backspace Delete the previous word\nmeta-d Forward delete the next word\n^W Delete previous text up to the nearest whitespace\nmeta-w Copy the current region in the kill ring\nmeta-W \"Kill\" the current region, placing the text in the kill ring\n^U \"Kill\" to beginning of line, placing the text in the kill ring\n^K \"Kill\" to end of line, placing the text in the kill ring\n^Y \"Yank\" insert the text from the kill ring\nmeta-y Replace a previously yanked text with an older entry from the kill ring\n^T Transpose the characters about the cursor\nmeta-Up arrow Transpose current line with line above\nmeta-Down arrow Transpose current line with line below\nmeta-u Change the next word to uppercase\nmeta-c Change the next word to titlecase\nmeta-l Change the next word to lowercase\n^/, ^_ Undo previous editing action\n^Q Write a number in REPL and press ^Q to open editor at corresponding stackframe or method\nmeta-Left Arrow Indent the current line on the left\nmeta-Right Arrow Indent the current line on the right\nmeta-. Insert last word from previous history entry\nmeta-e Edit the current input in an editor","category":"page"},{"location":"stdlib/REPL/#Customizing-keybindings","page":"The Julia REPL","title":"Customizing keybindings","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Julia's REPL keybindings may be fully customized to a user's preferences by passing a dictionary to REPL.setup_interface. The keys of this dictionary may be characters or strings. The key '*' refers to the default action. Control plus character x bindings are indicated with \"^x\". Meta plus x can be written \"\\\\M-x\" or \"\\ex\", and Control plus x can be written \"\\\\C-x\" or \"^x\". The values of the custom keymap must be nothing (indicating that the input should be ignored) or functions that accept the signature (PromptState, AbstractREPL, Char). The REPL.setup_interface function must be called before the REPL is initialized, by registering the operation with atreplinit . For example, to bind the up and down arrow keys to move through history without prefix search, one could put the following code in ~/.julia/config/startup.jl:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"import REPL\nimport REPL.LineEdit\n\nconst mykeys = Dict{Any,Any}(\n # Up Arrow\n \"\\e[A\" => (s,o...)->(LineEdit.edit_move_up(s) || LineEdit.history_prev(s, LineEdit.mode(s).hist)),\n # Down Arrow\n \"\\e[B\" => (s,o...)->(LineEdit.edit_move_down(s) || LineEdit.history_next(s, LineEdit.mode(s).hist))\n)\n\nfunction customize_keys(repl)\n repl.interface = REPL.setup_interface(repl; extra_repl_keymap = mykeys)\nend\n\natreplinit(customize_keys)","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Users should refer to LineEdit.jl to discover the available actions on key input.","category":"page"},{"location":"stdlib/REPL/#Tab-completion","page":"The Julia REPL","title":"Tab completion","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In the Julian, pkg and help modes of the REPL, one can enter the first few characters of a function or type and then press the tab key to get a list all matches:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> x[TAB]\njulia> xor","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In some cases it only completes part of the name, up to the next ambiguity:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> mapf[TAB]\njulia> mapfold","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"If you hit tab again, then you get the list of things that might complete this:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> mapfold[TAB]\nmapfoldl mapfoldr","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"When a single complete tab-complete result is available at the end of an input line and 2 or more characters have been typed, a hint of the completion will show in a lighter color. This can be disabled via Base.active_repl.options.hint_tab_completes = false.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"compat: Julia 1.11\nTab-complete hinting was added in Julia 1.11","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Like other components of the REPL, the search is case-sensitive:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> stri[TAB]\nstride strides string strip\n\njulia> Stri[TAB]\nStridedArray StridedMatrix StridedVecOrMat StridedVector String","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The tab key can also be used to substitute LaTeX math symbols with their Unicode equivalents, and get a list of LaTeX matches as well:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> \\pi[TAB]\njulia> π\nπ = 3.1415926535897...\n\njulia> e\\_1[TAB] = [1,0]\njulia> e₁ = [1,0]\n2-element Array{Int64,1}:\n 1\n 0\n\njulia> e\\^1[TAB] = [1 0]\njulia> e¹ = [1 0]\n1×2 Array{Int64,2}:\n 1 0\n\njulia> \\sqrt[TAB]2 # √ is equivalent to the sqrt function\njulia> √2\n1.4142135623730951\n\njulia> \\hbar[TAB](h) = h / 2\\pi[TAB]\njulia> ħ(h) = h / 2π\nħ (generic function with 1 method)\n\njulia> \\h[TAB]\n\\hat \\hermitconjmatrix \\hkswarow \\hrectangle\n\\hatapprox \\hexagon \\hookleftarrow \\hrectangleblack\n\\hbar \\hexagonblack \\hookrightarrow \\hslash\n\\heartsuit \\hksearow \\house \\hspace\n\njulia> α=\"\\alpha[TAB]\" # LaTeX completion also works in strings\njulia> α=\"α\"","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"A full list of tab-completions can be found in the Unicode Input section of the manual.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Completion of paths works for strings and julia's shell mode:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> path=\"/[TAB]\"\n.dockerenv .juliabox/ boot/ etc/ lib/ media/ opt/ root/ sbin/ sys/ usr/\n.dockerinit bin/ dev/ home/ lib64/ mnt/ proc/ run/ srv/ tmp/ var/\nshell> /[TAB]\n.dockerenv .juliabox/ boot/ etc/ lib/ media/ opt/ root/ sbin/ sys/ usr/\n.dockerinit bin/ dev/ home/ lib64/ mnt/ proc/ run/ srv/ tmp/ var/","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Dictionary keys can also be tab completed:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> foo = Dict(\"qwer1\"=>1, \"qwer2\"=>2, \"asdf\"=>3)\nDict{String,Int64} with 3 entries:\n \"qwer2\" => 2\n \"asdf\" => 3\n \"qwer1\" => 1\n\njulia> foo[\"q[TAB]\n\n\"qwer1\" \"qwer2\"\njulia> foo[\"qwer","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Tab completion can also help completing fields:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> x = 3 + 4im;\n\njulia> x.[TAB][TAB]\nim re\n\njulia> import UUIDs\n\njulia> UUIDs.uuid[TAB][TAB]\nuuid1 uuid4 uuid5 uuid_version","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Fields for output from functions can also be completed:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> split(\"\",\"\")[1].[TAB]\nlastindex offset string","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The completion of fields for output from functions uses type inference, and it can only suggest fields if the function is type stable.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Tab completion can help with investigation of the available methods matching the input arguments:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> max([TAB] # All methods are displayed, not shown here due to size of the list\n\njulia> max([1, 2], [TAB] # All methods where `Vector{Int}` matches as first argument\nmax(x, y) in Base at operators.jl:215\nmax(a, b, c, xs...) in Base at operators.jl:281\n\njulia> max([1, 2], max(1, 2), [TAB] # All methods matching the arguments.\nmax(x, y) in Base at operators.jl:215\nmax(a, b, c, xs...) in Base at operators.jl:281","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Keywords are also displayed in the suggested methods after ;, see below line where limit and keepempty are keyword arguments:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> split(\"1 1 1\", [TAB]\nsplit(str::AbstractString; limit, keepempty) in Base at strings/util.jl:302\nsplit(str::T, splitter; limit, keepempty) where T<:AbstractString in Base at strings/util.jl:277","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The completion of the methods uses type inference and can therefore see if the arguments match even if the arguments are output from functions. The function needs to be type stable for the completion to be able to remove non-matching methods.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"If you wonder which methods can be used with particular argument types, use ? as the function name. This shows an example of looking for functions in InteractiveUtils that accept a single string:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> InteractiveUtils.?(\"somefile\")[TAB]\nedit(path::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:197\nless(file::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:266","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"This listed methods in the InteractiveUtils module that can be called on a string. By default, this excludes methods where all arguments are typed as Any, but you can see those too by holding down SHIFT-TAB instead of TAB:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> InteractiveUtils.?(\"somefile\")[SHIFT-TAB]\napropos(string) in REPL at REPL/src/docview.jl:796\nclipboard(x) in InteractiveUtils at InteractiveUtils/src/clipboard.jl:64\ncode_llvm(f) in InteractiveUtils at InteractiveUtils/src/codeview.jl:221\ncode_native(f) in InteractiveUtils at InteractiveUtils/src/codeview.jl:243\nedit(path::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:197\nedit(f) in InteractiveUtils at InteractiveUtils/src/editless.jl:225\neval(x) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:3\ninclude(x) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:3\nless(file::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:266\nless(f) in InteractiveUtils at InteractiveUtils/src/editless.jl:274\nreport_bug(kind) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:391\nseparate_kwargs(args...; kwargs...) in InteractiveUtils at InteractiveUtils/src/macros.jl:7","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"You can also use ?(\"somefile\")[TAB] and look across all modules, but the method lists can be long.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"By omitting the closing parenthesis, you can include functions that might require additional arguments:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> using Mmap\n\nhelp?> Mmap.?(\"file\",[TAB]\nMmap.Anonymous(name::String, readonly::Bool, create::Bool) in Mmap at Mmap/src/Mmap.jl:16\nmmap(file::AbstractString) in Mmap at Mmap/src/Mmap.jl:245\nmmap(file::AbstractString, ::Type{T}) where T<:Array in Mmap at Mmap/src/Mmap.jl:245\nmmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}) where {T<:Array, N} in Mmap at Mmap/src/Mmap.jl:245\nmmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}, offset::Integer; grow, shared) where {T<:Array, N} in Mmap at Mmap/src/Mmap.jl:245\nmmap(file::AbstractString, ::Type{T}, len::Integer) where T<:Array in Mmap at Mmap/src/Mmap.jl:251\nmmap(file::AbstractString, ::Type{T}, len::Integer, offset::Integer; grow, shared) where T<:Array in Mmap at Mmap/src/Mmap.jl:251\nmmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}) where {T<:BitArray, N} in Mmap at Mmap/src/Mmap.jl:316\nmmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}, offset::Integer; grow, shared) where {T<:BitArray, N} in Mmap at Mmap/src/Mmap.jl:316\nmmap(file::AbstractString, ::Type{T}, len::Integer) where T<:BitArray in Mmap at Mmap/src/Mmap.jl:322\nmmap(file::AbstractString, ::Type{T}, len::Integer, offset::Integer; grow, shared) where T<:BitArray in Mmap at Mmap/src/Mmap.jl:322","category":"page"},{"location":"stdlib/REPL/#Customizing-Colors","page":"The Julia REPL","title":"Customizing Colors","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The colors used by Julia and the REPL can be customized, as well. To change the color of the Julia prompt you can add something like the following to your ~/.julia/config/startup.jl file, which is to be placed inside your home directory:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"function customize_colors(repl)\n repl.prompt_color = Base.text_colors[:cyan]\nend\n\natreplinit(customize_colors)","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The available color keys can be seen by typing Base.text_colors in the help mode of the REPL. In addition, the integers 0 to 255 can be used as color keys for terminals with 256 color support.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"You can also change the colors for the help and shell prompts and input and answer text by setting the appropriate field of repl in the customize_colors function above (respectively, help_color, shell_color, input_color, and answer_color). For the latter two, be sure that the envcolors field is also set to false.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"It is also possible to apply boldface formatting by using Base.text_colors[:bold] as a color. For instance, to print answers in boldface font, one can use the following as a ~/.julia/config/startup.jl:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"function customize_colors(repl)\n repl.envcolors = false\n repl.answer_color = Base.text_colors[:bold]\nend\n\natreplinit(customize_colors)","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"You can also customize the color used to render warning and informational messages by setting the appropriate environment variables. For instance, to render error, warning, and informational messages respectively in magenta, yellow, and cyan you can add the following to your ~/.julia/config/startup.jl file:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"ENV[\"JULIA_ERROR_COLOR\"] = :magenta\nENV[\"JULIA_WARN_COLOR\"] = :yellow\nENV[\"JULIA_INFO_COLOR\"] = :cyan","category":"page"},{"location":"stdlib/REPL/#Changing-the-contextual-module-which-is-active-at-the-REPL","page":"The Julia REPL","title":"Changing the contextual module which is active at the REPL","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"When entering expressions at the REPL, they are by default evaluated in the Main module;","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> @__MODULE__\nMain","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"It is possible to change this contextual module via the function REPL.activate(m) where m is a Module or by typing the module in the REPL and pressing the keybinding Alt-m with the cursor on the module name (Esc-m on MacOS). Pressing the keybinding on an empty prompt toggles the context between the previously active non-Main module and Main. The active module is shown in the prompt (unless it is Main):","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> using REPL\n\njulia> REPL.activate(Base)\n\n(Base) julia> @__MODULE__\nBase\n\n(Base) julia> using REPL # Need to load REPL into Base module to use it\n\n(Base) julia> REPL.activate(Main)\n\njulia>\n\njulia> Core # using the keybinding to change module\n\n(Core) julia>\n\n(Core) julia> # going back to Main via keybinding\n\njulia>\n\njulia> # going back to previously-active Core via keybinding\n\n(Core) julia>","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Functions that take an optional module argument often defaults to the REPL context module. As an example, calling varinfo() will show the variables of the current active module:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> module CustomMod\n export var, f\n var = 1\n f(x) = x^2\n end;\n\njulia> REPL.activate(CustomMod)\n\n(Main.CustomMod) julia> varinfo()\n name size summary\n ––––––––– ––––––– ––––––––––––––––––––––––––––––––––\n CustomMod Module\n f 0 bytes f (generic function with 1 method)\n var 8 bytes Int64","category":"page"},{"location":"stdlib/REPL/#Numbered-prompt","page":"The Julia REPL","title":"Numbered prompt","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"It is possible to get an interface which is similar to the IPython REPL and the Mathematica notebook with numbered input prompts and output prefixes. This is done by calling REPL.numbered_prompt!(). If you want to have this enabled on startup, add","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"atreplinit() do repl\n @eval import REPL\n if !isdefined(repl, :interface)\n repl.interface = REPL.setup_interface(repl)\n end\n REPL.numbered_prompt!(repl)\nend","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"to your startup.jl file. In numbered prompt the variable Out[n] (where n is an integer) can be used to refer to earlier results:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In [1]: 5 + 3\nOut[1]: 8\n\nIn [2]: Out[1] + 5\nOut[2]: 13\n\nIn [3]: Out\nOut[3]: Dict{Int64, Any} with 2 entries:\n 2 => 13\n 1 => 8","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"note: Note\nSince all outputs from previous REPL evaluations are saved in the Out variable, one should be careful if they are returning many large in-memory objects like arrays, since they will be protected from garbage collection so long as a reference to them remains in Out. If you need to remove references to objects in Out, you can clear the entire history it stores with empty!(Out), or clear an individual entry with Out[n] = nothing.","category":"page"},{"location":"stdlib/REPL/#TerminalMenus","page":"The Julia REPL","title":"TerminalMenus","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"TerminalMenus is a submodule of the Julia REPL and enables small, low-profile interactive menus in the terminal.","category":"page"},{"location":"stdlib/REPL/#Examples","page":"The Julia REPL","title":"Examples","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"import REPL\nusing REPL.TerminalMenus\n\noptions = [\"apple\", \"orange\", \"grape\", \"strawberry\",\n \"blueberry\", \"peach\", \"lemon\", \"lime\"]\n","category":"page"},{"location":"stdlib/REPL/#RadioMenu","page":"The Julia REPL","title":"RadioMenu","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The RadioMenu allows the user to select one option from the list. The request function displays the interactive menu and returns the index of the selected choice. If a user presses 'q' or ctrl-c, request will return a -1.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"# `pagesize` is the number of items to be displayed at a time.\n# The UI will scroll if the number of options is greater\n# than the `pagesize`\nmenu = RadioMenu(options, pagesize=4)\n\n# `request` displays the menu and returns the index after the\n# user has selected a choice\nchoice = request(\"Choose your favorite fruit:\", menu)\n\nif choice != -1\n println(\"Your favorite fruit is \", options[choice], \"!\")\nelse\n println(\"Menu canceled.\")\nend\n","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Output:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Choose your favorite fruit:\n^ grape\n strawberry\n > blueberry\nv peach\nYour favorite fruit is blueberry!","category":"page"},{"location":"stdlib/REPL/#MultiSelectMenu","page":"The Julia REPL","title":"MultiSelectMenu","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The MultiSelectMenu allows users to select many choices from a list.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"# here we use the default `pagesize` 10\nmenu = MultiSelectMenu(options)\n\n# `request` returns a `Set` of selected indices\n# if the menu us canceled (ctrl-c or q), return an empty set\nchoices = request(\"Select the fruits you like:\", menu)\n\nif length(choices) > 0\n println(\"You like the following fruits:\")\n for i in choices\n println(\" - \", options[i])\n end\nelse\n println(\"Menu canceled.\")\nend","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Output:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Select the fruits you like:\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n [ ] apple\n > [X] orange\n [X] grape\n [ ] strawberry\n [ ] blueberry\n [X] peach\n [ ] lemon\n [ ] lime\nYou like the following fruits:\n - orange\n - grape\n - peach","category":"page"},{"location":"stdlib/REPL/#Customization-/-Configuration","page":"The Julia REPL","title":"Customization / Configuration","text":"","category":"section"},{"location":"stdlib/REPL/#ConfiguredMenu-subtypes","page":"The Julia REPL","title":"ConfiguredMenu subtypes","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Starting with Julia 1.6, the recommended way to configure menus is via the constructor. For instance, the default multiple-selection menu","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> menu = MultiSelectMenu(options, pagesize=5);\n\njulia> request(menu) # ASCII is used by default\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n [ ] apple\n [X] orange\n [ ] grape\n > [X] strawberry\nv [ ] blueberry","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"can instead be rendered with Unicode selection and navigation characters with","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> menu = MultiSelectMenu(options, pagesize=5, charset=:unicode);\n\njulia> request(menu)\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n ⬚ apple\n ✓ orange\n ⬚ grape\n → ✓ strawberry\n↓ ⬚ blueberry","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"More fine-grained configuration is also possible:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> menu = MultiSelectMenu(options, pagesize=5, charset=:unicode, checked=\"YEP!\", unchecked=\"NOPE\", cursor='⧐');\n\njulia> request(menu)\njulia> request(menu)\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n NOPE apple\n YEP! orange\n NOPE grape\n ⧐ YEP! strawberry\n↓ NOPE blueberry","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Aside from the overall charset option, for RadioMenu the configurable options are:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"cursor::Char='>'|'→': character to use for cursor\nup_arrow::Char='^'|'↑': character to use for up arrow\ndown_arrow::Char='v'|'↓': character to use for down arrow\nupdown_arrow::Char='I'|'↕': character to use for up/down arrow in one-line page\nscroll_wrap::Bool=false: optionally wrap-around at the beginning/end of a menu\nctrl_c_interrupt::Bool=true: If false, return empty on ^C, if true throw InterruptException() on ^C","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"MultiSelectMenu adds:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"checked::String=\"[X]\"|\"✓\": string to use for checked\nunchecked::String=\"[ ]\"|\"⬚\"): string to use for unchecked","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"You can create new menu types of your own. Types that are derived from TerminalMenus.ConfiguredMenu configure the menu options at construction time.","category":"page"},{"location":"stdlib/REPL/#Legacy-interface","page":"The Julia REPL","title":"Legacy interface","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Prior to Julia 1.6, and still supported throughout Julia 1.x, one can also configure menus by calling TerminalMenus.config().","category":"page"},{"location":"stdlib/REPL/#References","page":"The Julia REPL","title":"References","text":"","category":"section"},{"location":"stdlib/REPL/#REPL","page":"The Julia REPL","title":"REPL","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Base.atreplinit","category":"page"},{"location":"stdlib/REPL/#Base.atreplinit","page":"The Julia REPL","title":"Base.atreplinit","text":"atreplinit(f)\n\nRegister a one-argument function to be called before the REPL interface is initialized in interactive sessions; this is useful to customize the interface. The argument of f is the REPL object. This function should be called from within the .julia/config/startup.jl initialization file.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#TerminalMenus-2","page":"The Julia REPL","title":"TerminalMenus","text":"","category":"section"},{"location":"stdlib/REPL/#Menus","page":"The Julia REPL","title":"Menus","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.RadioMenu\nREPL.TerminalMenus.MultiSelectMenu","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.RadioMenu","page":"The Julia REPL","title":"REPL.TerminalMenus.RadioMenu","text":"RadioMenu\n\nA menu that allows a user to select a single option from a list.\n\nSample Output\n\njulia> request(RadioMenu(options, pagesize=4))\nChoose your favorite fruit:\n^ grape\n strawberry\n > blueberry\nv peach\nYour favorite fruit is blueberry!\n\n\n\n\n\n","category":"type"},{"location":"stdlib/REPL/#REPL.TerminalMenus.MultiSelectMenu","page":"The Julia REPL","title":"REPL.TerminalMenus.MultiSelectMenu","text":"MultiSelectMenu\n\nA menu that allows a user to select a multiple options from a list.\n\nSample Output\n\njulia> request(MultiSelectMenu(options))\nSelect the fruits you like:\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n [ ] apple\n > [X] orange\n [X] grape\n [ ] strawberry\n [ ] blueberry\n [X] peach\n [ ] lemon\n [ ] lime\nYou like the following fruits:\n - orange\n - grape\n - peach\n\n\n\n\n\n","category":"type"},{"location":"stdlib/REPL/#Configuration","page":"The Julia REPL","title":"Configuration","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.Config\nREPL.TerminalMenus.MultiSelectConfig\nREPL.TerminalMenus.config","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.Config","page":"The Julia REPL","title":"REPL.TerminalMenus.Config","text":"Config(; scroll_wrap=false, ctrl_c_interrupt=true, charset=:ascii, cursor::Char, up_arrow::Char, down_arrow::Char)\n\nConfigure behavior for selection menus via keyword arguments:\n\nscroll_wrap, if true, causes the menu to wrap around when scrolling above the first or below the last entry\nctrl_c_interrupt, if true, throws an InterruptException if the user hits Ctrl-C during menu selection. If false, TerminalMenus.request will return the default result from TerminalMenus.selected.\ncharset affects the default values for cursor, up_arrow, and down_arrow, and can be :ascii or :unicode\ncursor is the character printed to indicate the option that will be chosen by hitting \"Enter.\" Defaults are '>' or '→', depending on charset.\nup_arrow is the character printed when the display does not include the first entry. Defaults are '^' or '↑', depending on charset.\ndown_arrow is the character printed when the display does not include the last entry. Defaults are 'v' or '↓', depending on charset.\n\nSubtypes of ConfiguredMenu will print cursor, up_arrow, and down_arrow automatically as needed, your writeline method should not print them.\n\ncompat: Julia 1.6\nConfig is available as of Julia 1.6. On older releases use the global CONFIG.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/REPL/#REPL.TerminalMenus.MultiSelectConfig","page":"The Julia REPL","title":"REPL.TerminalMenus.MultiSelectConfig","text":"MultiSelectConfig(; charset=:ascii, checked::String, unchecked::String, kwargs...)\n\nConfigure behavior for a multiple-selection menu via keyword arguments:\n\nchecked is the string to print when an option has been selected. Defaults are \"[X]\" or \"✓\", depending on charset.\nunchecked is the string to print when an option has not been selected. Defaults are \"[ ]\" or \"⬚\", depending on charset.\n\nAll other keyword arguments are as described for TerminalMenus.Config. checked and unchecked are not printed automatically, and should be printed by your writeline method.\n\ncompat: Julia 1.6\nMultiSelectConfig is available as of Julia 1.6. On older releases use the global CONFIG.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/REPL/#REPL.TerminalMenus.config","page":"The Julia REPL","title":"REPL.TerminalMenus.config","text":"config( )\n\nKeyword-only function to configure global menu parameters\n\nArguments\n\ncharset::Symbol=:na: ui characters to use (:ascii or :unicode); overridden by other arguments\ncursor::Char='>'|'→': character to use for cursor\nup_arrow::Char='^'|'↑': character to use for up arrow\ndown_arrow::Char='v'|'↓': character to use for down arrow\nchecked::String=\"[X]\"|\"✓\": string to use for checked\nunchecked::String=\"[ ]\"|\"⬚\"): string to use for unchecked\nscroll::Symbol=:nowrap: If :wrap wrap cursor around top and bottom, if :nowrap do not wrap cursor\nsupress_output::Bool=false: Ignored legacy argument, pass suppress_output as a keyword argument to request instead.\nctrl_c_interrupt::Bool=true: If false, return empty on ^C, if true throw InterruptException() on ^C\n\ncompat: Julia 1.6\nAs of Julia 1.6, config is deprecated. Use Config or MultiSelectConfig instead.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#User-interaction","page":"The Julia REPL","title":"User interaction","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.request","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.request","page":"The Julia REPL","title":"REPL.TerminalMenus.request","text":"request(m::AbstractMenu; cursor=1)\n\nDisplay the menu and enter interactive mode. cursor indicates the item number used for the initial cursor position. cursor can be either an Int or a RefValue{Int}. The latter is useful for observation and control of the cursor position from the outside.\n\nReturns selected(m).\n\ncompat: Julia 1.6\nThe cursor argument requires Julia 1.6 or later.\n\n\n\n\n\nrequest([term,] msg::AbstractString, m::AbstractMenu)\n\nShorthand for println(msg); request(m).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#AbstractMenu-extension-interface","page":"The Julia REPL","title":"AbstractMenu extension interface","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Any subtype of AbstractMenu must be mutable, and must contain the fields pagesize::Int and pageoffset::Int. Any subtype must also implement the following functions:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.pick\nREPL.TerminalMenus.cancel\nREPL.TerminalMenus.writeline","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.pick","page":"The Julia REPL","title":"REPL.TerminalMenus.pick","text":"pick(m::AbstractMenu, cursor::Int)\n\nDefines what happens when a user presses the Enter key while the menu is open. If true is returned, request() will exit. cursor indexes the position of the selection.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#REPL.TerminalMenus.cancel","page":"The Julia REPL","title":"REPL.TerminalMenus.cancel","text":"cancel(m::AbstractMenu)\n\nDefine what happens when a user cancels ('q' or ctrl-c) a menu. request() will always exit after calling this function.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#REPL.TerminalMenus.writeline","page":"The Julia REPL","title":"REPL.TerminalMenus.writeline","text":"writeline(buf::IO, m::AbstractMenu, idx::Int, iscursor::Bool)\n\nWrite the option at index idx to buf. iscursor, if true, indicates that this item is at the current cursor position (the one that will be selected by hitting \"Enter\").\n\nIf m is a ConfiguredMenu, TerminalMenus will print the cursor indicator. Otherwise the callee is expected to handle such printing.\n\ncompat: Julia 1.6\nwriteline requires Julia 1.6 or higher.On older versions of Julia, this was writeLine(buf::IO, m::AbstractMenu, idx, iscursor::Bool) and m is assumed to be unconfigured. The selection and cursor indicators can be obtained from TerminalMenus.CONFIG.This older function is supported on all Julia 1.x versions but will be dropped in Julia 2.0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"It must also implement either options or numoptions:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.options\nREPL.TerminalMenus.numoptions","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.options","page":"The Julia REPL","title":"REPL.TerminalMenus.options","text":"options(m::AbstractMenu)\n\nReturn a list of strings to be displayed as options in the current page.\n\nAlternatively, implement numoptions, in which case options is not needed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#REPL.TerminalMenus.numoptions","page":"The Julia REPL","title":"REPL.TerminalMenus.numoptions","text":"numoptions(m::AbstractMenu) -> Int\n\nReturn the number of options in menu m. Defaults to length(options(m)).\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"If the subtype does not have a field named selected, it must also implement","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.selected","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.selected","page":"The Julia REPL","title":"REPL.TerminalMenus.selected","text":"selected(m::AbstractMenu)\n\nReturn information about the user-selected option. By default it returns m.selected.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The following are optional but can allow additional customization:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.header\nREPL.TerminalMenus.keypress","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.header","page":"The Julia REPL","title":"REPL.TerminalMenus.header","text":"header(m::AbstractMenu) -> String\n\nReturn a header string to be printed above the menu. Defaults to \"\".\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#REPL.TerminalMenus.keypress","page":"The Julia REPL","title":"REPL.TerminalMenus.keypress","text":"keypress(m::AbstractMenu, i::UInt32) -> Bool\n\nHandle any non-standard keypress event. If true is returned, TerminalMenus.request will exit. Defaults to false.\n\n\n\n\n\n","category":"function"},{"location":"base/stacktraces/#StackTraces","page":"StackTraces","title":"StackTraces","text":"","category":"section"},{"location":"base/stacktraces/","page":"StackTraces","title":"StackTraces","text":"Base.StackTraces.StackFrame\nBase.StackTraces.StackTrace\nBase.StackTraces.stacktrace","category":"page"},{"location":"base/stacktraces/#Base.StackTraces.StackFrame","page":"StackTraces","title":"Base.StackTraces.StackFrame","text":"StackFrame\n\nStack information representing execution context, with the following fields:\n\nfunc::Symbol\nThe name of the function containing the execution context.\nlinfo::Union{Method, Core.MethodInstance, Core.CodeInfo, Nothing}\nThe Method, MethodInstance, or CodeInfo containing the execution context (if it could be found), or nothing (for example, if the inlining was a result of macro expansion).\nfile::Symbol\nThe path to the file containing the execution context.\nline::Int\nThe line number in the file containing the execution context.\nfrom_c::Bool\nTrue if the code is from C.\ninlined::Bool\nTrue if the code is from an inlined frame.\npointer::UInt64\nRepresentation of the pointer to the execution context as returned by backtrace.\n\n\n\n\n\n","category":"type"},{"location":"base/stacktraces/#Base.StackTraces.StackTrace","page":"StackTraces","title":"Base.StackTraces.StackTrace","text":"StackTrace\n\nAn alias for Vector{StackFrame} provided for convenience; returned by calls to stacktrace.\n\n\n\n\n\n","category":"type"},{"location":"base/stacktraces/#Base.StackTraces.stacktrace","page":"StackTraces","title":"Base.StackTraces.stacktrace","text":"stacktrace([trace::Vector{Ptr{Cvoid}},] [c_funcs::Bool=false]) -> StackTrace\n\nReturn a stack trace in the form of a vector of StackFrames. (By default stacktrace doesn't return C functions, but this can be enabled.) When called without specifying a trace, stacktrace first calls backtrace.\n\n\n\n\n\n","category":"function"},{"location":"base/stacktraces/","page":"StackTraces","title":"StackTraces","text":"The following methods and types in Base.StackTraces are not exported and need to be called e.g. as StackTraces.lookup(ptr).","category":"page"},{"location":"base/stacktraces/","page":"StackTraces","title":"StackTraces","text":"Base.StackTraces.lookup\nBase.StackTraces.remove_frames!","category":"page"},{"location":"base/stacktraces/#Base.StackTraces.lookup","page":"StackTraces","title":"Base.StackTraces.lookup","text":"lookup(pointer::Ptr{Cvoid}) -> Vector{StackFrame}\n\nGiven a pointer to an execution context (usually generated by a call to backtrace), looks up stack frame context information. Returns an array of frame information for all functions inlined at that point, innermost function first.\n\n\n\n\n\n","category":"function"},{"location":"base/stacktraces/#Base.StackTraces.remove_frames!","page":"StackTraces","title":"Base.StackTraces.remove_frames!","text":"remove_frames!(stack::StackTrace, name::Symbol)\n\nTakes a StackTrace (a vector of StackFrames) and a function name (a Symbol) and removes the StackFrame specified by the function name from the StackTrace (also removing all frames above the specified function). Primarily used to remove StackTraces functions from the StackTrace prior to returning it.\n\n\n\n\n\nremove_frames!(stack::StackTrace, m::Module)\n\nReturn the StackTrace with all StackFrames from the provided Module removed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Pkg/","page":"Pkg","title":"Pkg","text":"EditURL = \"https://github.com/JuliaLang/Pkg.jl/blob/master/docs/src/basedocs.md\"","category":"page"},{"location":"stdlib/Pkg/#Pkg","page":"Pkg","title":"Pkg","text":"","category":"section"},{"location":"stdlib/Pkg/","page":"Pkg","title":"Pkg","text":"Pkg is Julia's builtin package manager, and handles operations such as installing, updating and removing packages.","category":"page"},{"location":"stdlib/Pkg/","page":"Pkg","title":"Pkg","text":"note: Note\nWhat follows is a very brief introduction to Pkg. For more information on Project.toml files, Manifest.toml files, package version compatibility ([compat]), environments, registries, etc., it is highly recommended to read the full manual, which is available here: https://pkgdocs.julialang.org. For a tutorial on creating packages, see Creating Packages.","category":"page"},{"location":"stdlib/Pkg/","page":"Pkg","title":"Pkg","text":"import Markdown\nfile = joinpath(Sys.STDLIB, \"Pkg\", \"docs\", \"src\", \"getting-started.md\")\nstr = read(file, String)\nstr = replace(str, r\"^#.*$\"m => \"\")\nstr = replace(str, \"[API Reference](@ref)\" => \"[API Reference](https://pkgdocs.julialang.org/v1/api/)\")\nstr = replace(str, \"(@ref Working-with-Environments)\" => \"(https://pkgdocs.julialang.org/v1/environments/)\")\nstr = replace(str, \"(@ref Managing-Packages)\" => \"(https://pkgdocs.julialang.org/v1/managing-packages/)\")\nMarkdown.parse(str)","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"EditURL = \"https://github.com/JuliaSparse/SparseArrays.jl/blob/master/docs/src/index.md\"","category":"page"},{"location":"stdlib/SparseArrays/#Sparse-Arrays","page":"Sparse Arrays","title":"Sparse Arrays","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"DocTestSetup = :(using SparseArrays, LinearAlgebra)","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Julia has support for sparse vectors and sparse matrices in the SparseArrays stdlib module. Sparse arrays are arrays that contain enough zeros that storing them in a special data structure leads to savings in space and execution time, compared to dense arrays.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"External packages which implement different sparse storage types, multidimensional sparse arrays, and more can be found in Noteworthy External Sparse Packages","category":"page"},{"location":"stdlib/SparseArrays/#man-csc","page":"Sparse Arrays","title":"Compressed Sparse Column (CSC) Sparse Matrix Storage","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"In Julia, sparse matrices are stored in the Compressed Sparse Column (CSC) format. Julia sparse matrices have the type SparseMatrixCSC{Tv,Ti}, where Tv is the type of the stored values, and Ti is the integer type for storing column pointers and row indices. The internal representation of SparseMatrixCSC is as follows:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}\n m::Int # Number of rows\n n::Int # Number of columns\n colptr::Vector{Ti} # Column j is in colptr[j]:(colptr[j+1]-1)\n rowval::Vector{Ti} # Row indices of stored values\n nzval::Vector{Tv} # Stored values, typically nonzeros\nend","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The compressed sparse column storage makes it easy and quick to access the elements in the column of a sparse matrix, whereas accessing the sparse matrix by rows is considerably slower. Operations such as insertion of previously unstored entries one at a time in the CSC structure tend to be slow. This is because all elements of the sparse matrix that are beyond the point of insertion have to be moved one place over.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"All operations on sparse matrices are carefully implemented to exploit the CSC data structure for performance, and to avoid expensive operations.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"If you have data in CSC format from a different application or library, and wish to import it in Julia, make sure that you use 1-based indexing. The row indices in every column need to be sorted, and if they are not, the matrix will display incorrectly. If your SparseMatrixCSC object contains unsorted row indices, one quick way to sort them is by doing a double transpose. Since the transpose operation is lazy, make a copy to materialize each transpose.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"In some applications, it is convenient to store explicit zero values in a SparseMatrixCSC. These are accepted by functions in Base (but there is no guarantee that they will be preserved in mutating operations). Such explicitly stored zeros are treated as structural nonzeros by many routines. The nnz function returns the number of elements explicitly stored in the sparse data structure, including non-structural zeros. In order to count the exact number of numerical nonzeros, use count(!iszero, x), which inspects every stored element of a sparse matrix. dropzeros, and the in-place dropzeros!, can be used to remove stored zeros from the sparse matrix.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> A = sparse([1, 1, 2, 3], [1, 3, 2, 3], [0, 1, 2, 0])\n3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:\n 0 ⋅ 1\n ⋅ 2 ⋅\n ⋅ ⋅ 0\n\njulia> dropzeros(A)\n3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:\n ⋅ ⋅ 1\n ⋅ 2 ⋅\n ⋅ ⋅ ⋅","category":"page"},{"location":"stdlib/SparseArrays/#Sparse-Vector-Storage","page":"Sparse Arrays","title":"Sparse Vector Storage","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Sparse vectors are stored in a close analog to compressed sparse column format for sparse matrices. In Julia, sparse vectors have the type SparseVector{Tv,Ti} where Tv is the type of the stored values and Ti the integer type for the indices. The internal representation is as follows:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}\n n::Int # Length of the sparse vector\n nzind::Vector{Ti} # Indices of stored values\n nzval::Vector{Tv} # Stored values, typically nonzeros\nend","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"As for SparseMatrixCSC, the SparseVector type can also contain explicitly stored zeros. (See Sparse Matrix Storage.).","category":"page"},{"location":"stdlib/SparseArrays/#Sparse-Vector-and-Matrix-Constructors","page":"Sparse Arrays","title":"Sparse Vector and Matrix Constructors","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The simplest way to create a sparse array is to use a function equivalent to the zeros function that Julia provides for working with dense arrays. To produce a sparse array instead, you can use the same name with an sp prefix:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> spzeros(3)\n3-element SparseVector{Float64, Int64} with 0 stored entries","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The sparse function is often a handy way to construct sparse arrays. For example, to construct a sparse matrix we can input a vector I of row indices, a vector J of column indices, and a vector V of stored values (this is also known as the COO (coordinate) format). sparse(I,J,V) then constructs a sparse matrix such that S[I[k], J[k]] = V[k]. The equivalent sparse vector constructor is sparsevec, which takes the (row) index vector I and the vector V with the stored values and constructs a sparse vector R such that R[I[k]] = V[k].","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3];\n\njulia> S = sparse(I,J,V)\n5×18 SparseMatrixCSC{Int64, Int64} with 4 stored entries:\n⎡⠀⠈⠀⠀⠀⠀⠀⠀⢀⎤\n⎣⠀⠀⠀⠂⡀⠀⠀⠀⠀⎦\n\njulia> R = sparsevec(I,V)\n5-element SparseVector{Int64, Int64} with 4 stored entries:\n [1] = 1\n [3] = -5\n [4] = 2\n [5] = 3","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The inverse of the sparse and sparsevec functions is findnz, which retrieves the inputs used to create the sparse array (including stored entries equal to zero). findall(!iszero, x) returns the Cartesian indices of non-zero entries in x (not including stored entries equal to zero).","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> findnz(S)\n([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5])\n\njulia> findall(!iszero, S)\n4-element Vector{CartesianIndex{2}}:\n CartesianIndex(1, 4)\n CartesianIndex(4, 7)\n CartesianIndex(5, 9)\n CartesianIndex(3, 18)\n\njulia> findnz(R)\n([1, 3, 4, 5], [1, -5, 2, 3])\n\njulia> findall(!iszero, R)\n4-element Vector{Int64}:\n 1\n 3\n 4\n 5","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Another way to create a sparse array is to convert a dense array into a sparse array using the sparse function:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> sparse(Matrix(1.0I, 5, 5))\n5×5 SparseMatrixCSC{Float64, Int64} with 5 stored entries:\n 1.0 ⋅ ⋅ ⋅ ⋅\n ⋅ 1.0 ⋅ ⋅ ⋅\n ⋅ ⋅ 1.0 ⋅ ⋅\n ⋅ ⋅ ⋅ 1.0 ⋅\n ⋅ ⋅ ⋅ ⋅ 1.0\n\njulia> sparse([1.0, 0.0, 1.0])\n3-element SparseVector{Float64, Int64} with 2 stored entries:\n [1] = 1.0\n [3] = 1.0","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"You can go in the other direction using the Array constructor. The issparse function can be used to query if a matrix is sparse.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> issparse(spzeros(5))\ntrue","category":"page"},{"location":"stdlib/SparseArrays/#Sparse-matrix-operations","page":"Sparse Arrays","title":"Sparse matrix operations","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Arithmetic operations on sparse matrices also work as they do on dense matrices. Indexing of, assignment into, and concatenation of sparse matrices work in the same way as dense matrices. Indexing operations, especially assignment, are expensive, when carried out one element at a time. In many cases it may be better to convert the sparse matrix into (I,J,V) format using findnz, manipulate the values or the structure in the dense vectors (I,J,V), and then reconstruct the sparse matrix.","category":"page"},{"location":"stdlib/SparseArrays/#Correspondence-of-dense-and-sparse-methods","page":"Sparse Arrays","title":"Correspondence of dense and sparse methods","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The following table gives a correspondence between built-in methods on sparse matrices and their corresponding methods on dense matrix types. In general, methods that generate sparse matrices differ from their dense counterparts in that the resulting matrix follows the same sparsity pattern as a given sparse matrix S, or that the resulting sparse matrix has density d, i.e. each matrix element has a probability d of being non-zero.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Details can be found in the Sparse Vectors and Matrices section of the standard library reference.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Sparse Dense Description\nspzeros(m,n) zeros(m,n) Creates a m-by-n matrix of zeros. (spzeros(m,n) is empty.)\nsparse(I,n,n) Matrix(I,n,n) Creates a n-by-n identity matrix.\nsparse(A) Array(S) Interconverts between dense and sparse formats.\nsprand(m,n,d) rand(m,n) Creates a m-by-n random matrix (of density d) with iid non-zero elements distributed uniformly on the half-open interval 0 1).\nsprandn(m,n,d) randn(m,n) Creates a m-by-n random matrix (of density d) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution.\nsprandn(rng,m,n,d) randn(rng,m,n) Creates a m-by-n random matrix (of density d) with iid non-zero elements generated with the rng random number generator","category":"page"},{"location":"stdlib/SparseArrays/#stdlib-sparse-arrays","page":"Sparse Arrays","title":"SparseArrays API","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"SparseArrays.AbstractSparseArray\nSparseArrays.AbstractSparseVector\nSparseArrays.AbstractSparseMatrix\nSparseArrays.SparseVector\nSparseArrays.SparseMatrixCSC\nSparseArrays.sparse\nSparseArrays.sparse!\nSparseArrays.sparsevec\nBase.similar(::SparseArrays.AbstractSparseMatrixCSC, ::Type)\nSparseArrays.issparse\nSparseArrays.nnz\nSparseArrays.findnz\nSparseArrays.spzeros\nSparseArrays.spzeros!\nSparseArrays.spdiagm\nSparseArrays.sparse_hcat\nSparseArrays.sparse_vcat\nSparseArrays.sparse_hvcat\nSparseArrays.blockdiag\nSparseArrays.sprand\nSparseArrays.sprandn\nSparseArrays.nonzeros\nSparseArrays.rowvals\nSparseArrays.nzrange\nSparseArrays.droptol!\nSparseArrays.dropzeros!\nSparseArrays.dropzeros\nSparseArrays.permute\npermute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1})\nSparseArrays.halfperm!\nSparseArrays.ftranspose!","category":"page"},{"location":"stdlib/SparseArrays/#SparseArrays.AbstractSparseArray","page":"Sparse Arrays","title":"SparseArrays.AbstractSparseArray","text":"AbstractSparseArray{Tv,Ti,N}\n\nSupertype for N-dimensional sparse arrays (or array-like types) with elements of type Tv and index type Ti. SparseMatrixCSC, SparseVector and SuiteSparse.CHOLMOD.Sparse are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.AbstractSparseVector","page":"Sparse Arrays","title":"SparseArrays.AbstractSparseVector","text":"AbstractSparseVector{Tv,Ti}\n\nSupertype for one-dimensional sparse arrays (or array-like types) with elements of type Tv and index type Ti. Alias for AbstractSparseArray{Tv,Ti,1}.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.AbstractSparseMatrix","page":"Sparse Arrays","title":"SparseArrays.AbstractSparseMatrix","text":"AbstractSparseMatrix{Tv,Ti}\n\nSupertype for two-dimensional sparse arrays (or array-like types) with elements of type Tv and index type Ti. Alias for AbstractSparseArray{Tv,Ti,2}.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.SparseVector","page":"Sparse Arrays","title":"SparseArrays.SparseVector","text":"SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}\n\nVector type for storing sparse vectors. Can be created by passing the length of the vector, a sorted vector of non-zero indices, and a vector of non-zero values.\n\nFor instance, the vector [5, 6, 0, 7] can be represented as\n\nSparseVector(4, [1, 2, 4], [5, 6, 7])\n\nThis indicates that the element at index 1 is 5, at index 2 is 6, at index 3 is zero(Int), and at index 4 is 7.\n\nIt may be more convenient to create sparse vectors directly from dense vectors using sparse as\n\nsparse([5, 6, 0, 7])\n\nyields the same sparse vector.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.SparseMatrixCSC","page":"Sparse Arrays","title":"SparseArrays.SparseMatrixCSC","text":"SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}\n\nMatrix type for storing sparse matrices in the Compressed Sparse Column format. The standard way of constructing SparseMatrixCSC is through the sparse function. See also spzeros, spdiagm and sprand.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse","page":"Sparse Arrays","title":"SparseArrays.sparse","text":"sparse(A)\n\nConvert an AbstractMatrix A into a sparse matrix.\n\nExamples\n\njulia> A = Matrix(1.0I, 3, 3)\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> sparse(A)\n3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:\n 1.0 ⋅ ⋅\n ⋅ 1.0 ⋅\n ⋅ ⋅ 1.0\n\n\n\n\n\nsparse(I, J, V,[ m, n, combine])\n\nCreate a sparse matrix S of dimensions m x n such that S[I[k], J[k]] = V[k]. The combine function is used to combine duplicates. If m and n are not specified, they are set to maximum(I) and maximum(J) respectively. If the combine function is not supplied, combine defaults to + unless the elements of V are Booleans in which case combine defaults to |. All elements of I must satisfy 1 <= I[k] <= m, and all elements of J must satisfy 1 <= J[k] <= n. Numerical zeros in (I, J, V) are retained as structural nonzeros; to drop numerical zeros, use dropzeros!.\n\nFor additional documentation and an expert driver, see SparseArrays.sparse!.\n\nExamples\n\njulia> Is = [1; 2; 3];\n\njulia> Js = [1; 2; 3];\n\njulia> Vs = [1; 2; 3];\n\njulia> sparse(Is, Js, Vs)\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 1 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse!","page":"Sparse Arrays","title":"SparseArrays.sparse!","text":"sparse!(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{Tv},\n m::Integer, n::Integer, combine, klasttouch::Vector{Ti},\n csrrowptr::Vector{Ti}, csrcolval::Vector{Ti}, csrnzval::Vector{Tv},\n [csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}] ) where {Tv,Ti<:Integer}\n\nParent of and expert driver for sparse; see sparse for basic usage. This method allows the user to provide preallocated storage for sparse's intermediate objects and result as described below. This capability enables more efficient successive construction of SparseMatrixCSCs from coordinate representations, and also enables extraction of an unsorted-column representation of the result's transpose at no additional cost.\n\nThis method consists of three major steps: (1) Counting-sort the provided coordinate representation into an unsorted-row CSR form including repeated entries. (2) Sweep through the CSR form, simultaneously calculating the desired CSC form's column-pointer array, detecting repeated entries, and repacking the CSR form with repeated entries combined; this stage yields an unsorted-row CSR form with no repeated entries. (3) Counting-sort the preceding CSR form into a fully-sorted CSC form with no repeated entries.\n\nInput arrays csrrowptr, csrcolval, and csrnzval constitute storage for the intermediate CSR forms and require length(csrrowptr) >= m + 1, length(csrcolval) >= length(I), and length(csrnzval >= length(I)). Input array klasttouch, workspace for the second stage, requires length(klasttouch) >= n. Optional input arrays csccolptr, cscrowval, and cscnzval constitute storage for the returned CSC form S. If necessary, these are resized automatically to satisfy length(csccolptr) = n + 1, length(cscrowval) = nnz(S) and length(cscnzval) = nnz(S); hence, if nnz(S) is unknown at the outset, passing in empty vectors of the appropriate type (Vector{Ti}() and Vector{Tv}() respectively) suffices, or calling the sparse! method neglecting cscrowval and cscnzval.\n\nOn return, csrrowptr, csrcolval, and csrnzval contain an unsorted-column representation of the result's transpose.\n\nYou may reuse the input arrays' storage (I, J, V) for the output arrays (csccolptr, cscrowval, cscnzval). For example, you may call sparse!(I, J, V, csrrowptr, csrcolval, csrnzval, I, J, V). Note that they will be resized to satisfy the conditions above.\n\nFor the sake of efficiency, this method performs no argument checking beyond 1 <= I[k] <= m and 1 <= J[k] <= n. Use with care. Testing with --check-bounds=yes is wise.\n\nThis method runs in O(m, n, length(I)) time. The HALFPERM algorithm described in F. Gustavson, \"Two fast algorithms for sparse matrices: multiplication and permuted transposition,\" ACM TOMS 4(3), 250-269 (1978) inspired this method's use of a pair of counting sorts.\n\n\n\n\n\nSparseArrays.sparse!(I, J, V, [m, n, combine]) -> SparseMatrixCSC\n\nVariant of sparse! that re-uses the input vectors (I, J, V) for the final matrix storage. After construction the input vectors will alias the matrix buffers; S.colptr === I, S.rowval === J, and S.nzval === V holds, and they will be resize!d as necessary.\n\nNote that some work buffers will still be allocated. Specifically, this method is a convenience wrapper around sparse!(I, J, V, m, n, combine, klasttouch, csrrowptr, csrcolval, csrnzval, csccolptr, cscrowval, cscnzval) where this method allocates klasttouch, csrrowptr, csrcolval, and csrnzval of appropriate size, but reuses I, J, and V for csccolptr, cscrowval, and cscnzval.\n\nArguments m, n, and combine defaults to maximum(I), maximum(J), and +, respectively.\n\ncompat: Julia 1.10\nThis method requires Julia version 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparsevec","page":"Sparse Arrays","title":"SparseArrays.sparsevec","text":"sparsevec(I, V, [m, combine])\n\nCreate a sparse vector S of length m such that S[I[k]] = V[k]. Duplicates are combined using the combine function, which defaults to + if no combine argument is provided, unless the elements of V are Booleans in which case combine defaults to |.\n\nExamples\n\njulia> II = [1, 3, 3, 5]; V = [0.1, 0.2, 0.3, 0.2];\n\njulia> sparsevec(II, V)\n5-element SparseVector{Float64, Int64} with 3 stored entries:\n [1] = 0.1\n [3] = 0.5\n [5] = 0.2\n\njulia> sparsevec(II, V, 8, -)\n8-element SparseVector{Float64, Int64} with 3 stored entries:\n [1] = 0.1\n [3] = -0.1\n [5] = 0.2\n\njulia> sparsevec([1, 3, 1, 2, 2], [true, true, false, false, false])\n3-element SparseVector{Bool, Int64} with 3 stored entries:\n [1] = 1\n [2] = 0\n [3] = 1\n\n\n\n\n\nsparsevec(d::Dict, [m])\n\nCreate a sparse vector of length m where the nonzero indices are keys from the dictionary, and the nonzero values are the values from the dictionary.\n\nExamples\n\njulia> sparsevec(Dict(1 => 3, 2 => 2))\n2-element SparseVector{Int64, Int64} with 2 stored entries:\n [1] = 3\n [2] = 2\n\n\n\n\n\nsparsevec(A)\n\nConvert a vector A into a sparse vector of length m.\n\nExamples\n\njulia> sparsevec([1.0, 2.0, 0.0, 0.0, 3.0, 0.0])\n6-element SparseVector{Float64, Int64} with 3 stored entries:\n [1] = 1.0\n [2] = 2.0\n [5] = 3.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#Base.similar-Tuple{SparseArrays.AbstractSparseMatrixCSC, Type}","page":"Sparse Arrays","title":"Base.similar","text":"similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}\n\nCreate an uninitialized mutable array with the given element type, index type, and size, based upon the given source SparseMatrixCSC. The new sparse matrix maintains the structure of the original sparse matrix, except in the case where dimensions of the output matrix are different from the output.\n\nThe output matrix has zeros in the same locations as the input, but uninitialized values for the nonzero locations.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/SparseArrays/#SparseArrays.issparse","page":"Sparse Arrays","title":"SparseArrays.issparse","text":"issparse(S)\n\nReturns true if S is sparse, and false otherwise.\n\nExamples\n\njulia> sv = sparsevec([1, 4], [2.3, 2.2], 10)\n10-element SparseVector{Float64, Int64} with 2 stored entries:\n [1] = 2.3\n [4] = 2.2\n\njulia> issparse(sv)\ntrue\n\njulia> issparse(Array(sv))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.nnz","page":"Sparse Arrays","title":"SparseArrays.nnz","text":"nnz(A)\n\nReturns the number of stored (filled) elements in a sparse array.\n\nExamples\n\njulia> A = sparse(2I, 3, 3)\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 2 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 2\n\njulia> nnz(A)\n3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.findnz","page":"Sparse Arrays","title":"SparseArrays.findnz","text":"findnz(A::SparseMatrixCSC)\n\nReturn a tuple (I, J, V) where I and J are the row and column indices of the stored (\"structurally non-zero\") values in sparse matrix A, and V is a vector of the values.\n\nExamples\n\njulia> A = sparse([1 2 0; 0 0 3; 0 4 0])\n3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:\n 1 2 ⋅\n ⋅ ⋅ 3\n ⋅ 4 ⋅\n\njulia> findnz(A)\n([1, 1, 3, 2], [1, 2, 2, 3], [1, 2, 4, 3])\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.spzeros","page":"Sparse Arrays","title":"SparseArrays.spzeros","text":"spzeros([type,]m[,n])\n\nCreate a sparse vector of length m or sparse matrix of size m x n. This sparse array will not contain any nonzero values. No storage will be allocated for nonzero values during construction. The type defaults to Float64 if not specified.\n\nExamples\n\njulia> spzeros(3, 3)\n3×3 SparseMatrixCSC{Float64, Int64} with 0 stored entries:\n ⋅ ⋅ ⋅\n ⋅ ⋅ ⋅\n ⋅ ⋅ ⋅\n\njulia> spzeros(Float32, 4)\n4-element SparseVector{Float32, Int64} with 0 stored entries\n\n\n\n\n\nspzeros([type], I::AbstractVector, J::AbstractVector, [m, n])\n\nCreate a sparse matrix S of dimensions m x n with structural zeros at S[I[k], J[k]].\n\nThis method can be used to construct the sparsity pattern of the matrix, and is more efficient than using e.g. sparse(I, J, zeros(length(I))).\n\nFor additional documentation and an expert driver, see SparseArrays.spzeros!.\n\ncompat: Julia 1.10\nThis methods requires Julia version 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.spzeros!","page":"Sparse Arrays","title":"SparseArrays.spzeros!","text":"spzeros!(::Type{Tv}, I::AbstractVector{Ti}, J::AbstractVector{Ti}, m::Integer, n::Integer,\n klasttouch::Vector{Ti}, csrrowptr::Vector{Ti}, csrcolval::Vector{Ti},\n [csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}]) where {Tv,Ti<:Integer}\n\nParent of and expert driver for spzeros(I, J) allowing user to provide preallocated storage for intermediate objects. This method is to spzeros what SparseArrays.sparse! is to sparse. See documentation for SparseArrays.sparse! for details and required buffer lengths.\n\ncompat: Julia 1.10\nThis methods requires Julia version 1.10 or later.\n\n\n\n\n\nSparseArrays.spzeros!(::Type{Tv}, I, J, [m, n]) -> SparseMatrixCSC{Tv}\n\nVariant of spzeros! that re-uses the input vectors I and J for the final matrix storage. After construction the input vectors will alias the matrix buffers; S.colptr === I and S.rowval === J holds, and they will be resize!d as necessary.\n\nNote that some work buffers will still be allocated. Specifically, this method is a convenience wrapper around spzeros!(Tv, I, J, m, n, klasttouch, csrrowptr, csrcolval, csccolptr, cscrowval) where this method allocates klasttouch, csrrowptr, and csrcolval of appropriate size, but reuses I and J for csccolptr and cscrowval.\n\nArguments m and n defaults to maximum(I) and maximum(J).\n\ncompat: Julia 1.10\nThis method requires Julia version 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.spdiagm","page":"Sparse Arrays","title":"SparseArrays.spdiagm","text":"spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)\nspdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)\n\nConstruct a sparse diagonal matrix from Pairs of vectors and diagonals. Each vector kv.second will be placed on the kv.first diagonal. By default, the matrix is square and its size is inferred from kv, but a non-square size m×n (padded with zeros as needed) can be specified by passing m,n as the first arguments.\n\nExamples\n\njulia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1])\n5×5 SparseMatrixCSC{Int64, Int64} with 8 stored entries:\n ⋅ 4 ⋅ ⋅ ⋅\n 1 ⋅ 3 ⋅ ⋅\n ⋅ 2 ⋅ 2 ⋅\n ⋅ ⋅ 3 ⋅ 1\n ⋅ ⋅ ⋅ 4 ⋅\n\n\n\n\n\nspdiagm(v::AbstractVector)\nspdiagm(m::Integer, n::Integer, v::AbstractVector)\n\nConstruct a sparse matrix with elements of the vector as diagonal elements. By default (no given m and n), the matrix is square and its size is given by length(v), but a non-square size m×n can be specified by passing m and n as the first arguments.\n\ncompat: Julia 1.6\nThese functions require at least Julia 1.6.\n\nExamples\n\njulia> spdiagm([1,2,3])\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 1 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 3\n\njulia> spdiagm(sparse([1,0,3]))\n3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:\n 1 ⋅ ⋅\n ⋅ ⋅ ⋅\n ⋅ ⋅ 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse_hcat","page":"Sparse Arrays","title":"SparseArrays.sparse_hcat","text":"sparse_hcat(A...)\n\nConcatenate along dimension 2. Return a SparseMatrixCSC object.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized \"sparse\" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse_vcat","page":"Sparse Arrays","title":"SparseArrays.sparse_vcat","text":"sparse_vcat(A...)\n\nConcatenate along dimension 1. Return a SparseMatrixCSC object.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized \"sparse\" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse_hvcat","page":"Sparse Arrays","title":"SparseArrays.sparse_hvcat","text":"sparse_hvcat(rows::Tuple{Vararg{Int}}, values...)\n\nSparse horizontal and vertical concatenation in one call. This function is called for block matrix syntax. The first argument specifies the number of arguments to concatenate in each block row.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized \"sparse\" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.blockdiag","page":"Sparse Arrays","title":"SparseArrays.blockdiag","text":"blockdiag(A...)\n\nConcatenate matrices block-diagonally. Currently only implemented for sparse matrices.\n\nExamples\n\njulia> blockdiag(sparse(2I, 3, 3), sparse(4I, 2, 2))\n5×5 SparseMatrixCSC{Int64, Int64} with 5 stored entries:\n 2 ⋅ ⋅ ⋅ ⋅\n ⋅ 2 ⋅ ⋅ ⋅\n ⋅ ⋅ 2 ⋅ ⋅\n ⋅ ⋅ ⋅ 4 ⋅\n ⋅ ⋅ ⋅ ⋅ 4\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sprand","page":"Sparse Arrays","title":"SparseArrays.sprand","text":"sprand([rng],[T::Type],m,[n],p::AbstractFloat)\nsprand([rng],m,[n],p::AbstractFloat,[rfn=rand])\n\nCreate a random length m sparse vector or m by n sparse matrix, in which the probability of any element being nonzero is independently given by p (and hence the mean density of nonzeros is also exactly p). The optional rng argument specifies a random number generator, see Random Numbers. The optional T argument specifies the element type, which defaults to Float64.\n\nBy default, nonzero values are sampled from a uniform distribution using the rand function, i.e. by rand(T), or rand(rng, T) if rng is supplied; for the default T=Float64, this corresponds to nonzero values sampled uniformly in [0,1).\n\nYou can sample nonzero values from a different distribution by passing a custom rfn function instead of rand. This should be a function rfn(k) that returns an array of k random numbers sampled from the desired distribution; alternatively, if rng is supplied, it should instead be a function rfn(rng, k).\n\nExamples\n\njulia> sprand(Bool, 2, 2, 0.5)\n2×2 SparseMatrixCSC{Bool, Int64} with 2 stored entries:\n 1 1\n ⋅ ⋅\n\njulia> sprand(Float64, 3, 0.75)\n3-element SparseVector{Float64, Int64} with 2 stored entries:\n [1] = 0.795547\n [2] = 0.49425\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sprandn","page":"Sparse Arrays","title":"SparseArrays.sprandn","text":"sprandn([rng][,Type],m[,n],p::AbstractFloat)\n\nCreate a random sparse vector of length m or sparse matrix of size m by n with the specified (independent) probability p of any entry being nonzero, where nonzero values are sampled from the normal distribution. The optional rng argument specifies a random number generator, see Random Numbers.\n\ncompat: Julia 1.1\nSpecifying the output element type Type requires at least Julia 1.1.\n\nExamples\n\njulia> sprandn(2, 2, 0.75)\n2×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries:\n -1.20577 ⋅\n 0.311817 -0.234641\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.nonzeros","page":"Sparse Arrays","title":"SparseArrays.nonzeros","text":"nonzeros(A)\n\nReturn a vector of the structural nonzero values in sparse array A. This includes zeros that are explicitly stored in the sparse array. The returned vector points directly to the internal nonzero storage of A, and any modifications to the returned vector will mutate A as well. See rowvals and nzrange.\n\nExamples\n\njulia> A = sparse(2I, 3, 3)\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 2 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 2\n\njulia> nonzeros(A)\n3-element Vector{Int64}:\n 2\n 2\n 2\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.rowvals","page":"Sparse Arrays","title":"SparseArrays.rowvals","text":"rowvals(A::AbstractSparseMatrixCSC)\n\nReturn a vector of the row indices of A. Any modifications to the returned vector will mutate A as well. Providing access to how the row indices are stored internally can be useful in conjunction with iterating over structural nonzero values. See also nonzeros and nzrange.\n\nExamples\n\njulia> A = sparse(2I, 3, 3)\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 2 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 2\n\njulia> rowvals(A)\n3-element Vector{Int64}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.nzrange","page":"Sparse Arrays","title":"SparseArrays.nzrange","text":"nzrange(A::AbstractSparseMatrixCSC, col::Integer)\n\nReturn the range of indices to the structural nonzero values of a sparse matrix column. In conjunction with nonzeros and rowvals, this allows for convenient iterating over a sparse matrix :\n\nA = sparse(I,J,V)\nrows = rowvals(A)\nvals = nonzeros(A)\nm, n = size(A)\nfor j = 1:n\n for i in nzrange(A, j)\n row = rows[i]\n val = vals[i]\n # perform sparse wizardry...\n end\nend\n\nwarning: Warning\nAdding or removing nonzero elements to the matrix may invalidate the nzrange, one should not mutate the matrix while iterating.\n\n\n\n\n\nnzrange(x::SparseVectorUnion, col)\n\nGive the range of indices to the structural nonzero values of a sparse vector. The column index col is ignored (assumed to be 1).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.droptol!","page":"Sparse Arrays","title":"SparseArrays.droptol!","text":"droptol!(A::AbstractSparseMatrixCSC, tol)\n\nRemoves stored values from A whose absolute value is less than or equal to tol.\n\n\n\n\n\ndroptol!(x::AbstractCompressedVector, tol)\n\nRemoves stored values from x whose absolute value is less than or equal to tol.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.dropzeros!","page":"Sparse Arrays","title":"SparseArrays.dropzeros!","text":"dropzeros!(x::AbstractCompressedVector)\n\nRemoves stored numerical zeros from x.\n\nFor an out-of-place version, see dropzeros. For algorithmic information, see fkeep!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.dropzeros","page":"Sparse Arrays","title":"SparseArrays.dropzeros","text":"dropzeros(A::AbstractSparseMatrixCSC;)\n\nGenerates a copy of A and removes stored numerical zeros from that copy.\n\nFor an in-place version and algorithmic information, see dropzeros!.\n\nExamples\n\njulia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0])\n3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:\n 1.0 ⋅ ⋅\n ⋅ 0.0 ⋅\n ⋅ ⋅ 1.0\n\njulia> dropzeros(A)\n3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries:\n 1.0 ⋅ ⋅\n ⋅ ⋅ ⋅\n ⋅ ⋅ 1.0\n\n\n\n\n\ndropzeros(x::AbstractCompressedVector)\n\nGenerates a copy of x and removes numerical zeros from that copy.\n\nFor an in-place version and algorithmic information, see dropzeros!.\n\nExamples\n\njulia> A = sparsevec([1, 2, 3], [1.0, 0.0, 1.0])\n3-element SparseVector{Float64, Int64} with 3 stored entries:\n [1] = 1.0\n [2] = 0.0\n [3] = 1.0\n\njulia> dropzeros(A)\n3-element SparseVector{Float64, Int64} with 2 stored entries:\n [1] = 1.0\n [3] = 1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.permute","page":"Sparse Arrays","title":"SparseArrays.permute","text":"permute(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},\n q::AbstractVector{<:Integer}) where {Tv,Ti}\n\nBilaterally permute A, returning PAQ (A[p,q]). Column-permutation q's length must match A's column count (length(q) == size(A, 2)). Row-permutation p's length must match A's row count (length(p) == size(A, 1)).\n\nFor expert drivers and additional information, see permute!.\n\nExamples\n\njulia> A = spdiagm(0 => [1, 2, 3, 4], 1 => [5, 6, 7])\n4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:\n 1 5 ⋅ ⋅\n ⋅ 2 6 ⋅\n ⋅ ⋅ 3 7\n ⋅ ⋅ ⋅ 4\n\njulia> permute(A, [4, 3, 2, 1], [1, 2, 3, 4])\n4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:\n ⋅ ⋅ ⋅ 4\n ⋅ ⋅ 3 7\n ⋅ 2 6 ⋅\n 1 5 ⋅ ⋅\n\njulia> permute(A, [1, 2, 3, 4], [4, 3, 2, 1])\n4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:\n ⋅ ⋅ 5 1\n ⋅ 6 2 ⋅\n 7 3 ⋅ ⋅\n 4 ⋅ ⋅ ⋅\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#Base.permute!-Union{Tuple{Tq}, Tuple{Tp}, Tuple{Ti}, Tuple{Tv}, Tuple{SparseMatrixCSC{Tv, Ti}, SparseMatrixCSC{Tv, Ti}, AbstractVector{Tp}, AbstractVector{Tq}}} where {Tv, Ti, Tp<:Integer, Tq<:Integer}","page":"Sparse Arrays","title":"Base.permute!","text":"permute!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti},\n p::AbstractVector{<:Integer}, q::AbstractVector{<:Integer},\n [C::AbstractSparseMatrixCSC{Tv,Ti}]) where {Tv,Ti}\n\nBilaterally permute A, storing result PAQ (A[p,q]) in X. Stores intermediate result (AQ)^T (transpose(A[:,q])) in optional argument C if present. Requires that none of X, A, and, if present, C alias each other; to store result PAQ back into A, use the following method lacking X:\n\npermute!(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},\n q::AbstractVector{<:Integer}[, C::AbstractSparseMatrixCSC{Tv,Ti},\n [workcolptr::Vector{Ti}]]) where {Tv,Ti}\n\nX's dimensions must match those of A (size(X, 1) == size(A, 1) and size(X, 2) == size(A, 2)), and X must have enough storage to accommodate all allocated entries in A (length(rowvals(X)) >= nnz(A) and length(nonzeros(X)) >= nnz(A)). Column-permutation q's length must match A's column count (length(q) == size(A, 2)). Row-permutation p's length must match A's row count (length(p) == size(A, 1)).\n\nC's dimensions must match those of transpose(A) (size(C, 1) == size(A, 2) and size(C, 2) == size(A, 1)), and C must have enough storage to accommodate all allocated entries in A (length(rowvals(C)) >= nnz(A) and length(nonzeros(C)) >= nnz(A)).\n\nFor additional (algorithmic) information, and for versions of these methods that forgo argument checking, see (unexported) parent methods unchecked_noalias_permute! and unchecked_aliasing_permute!.\n\nSee also permute.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/SparseArrays/#SparseArrays.halfperm!","page":"Sparse Arrays","title":"SparseArrays.halfperm!","text":"halfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},\n q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}\n\nColumn-permute and transpose A, simultaneously applying f to each entry of A, storing the result (f(A)Q)^T (map(f, transpose(A[:,q]))) in X.\n\nElement type Tv of X must match f(::TvA), where TvA is the element type of A. X's dimensions must match those of transpose(A) (size(X, 1) == size(A, 2) and size(X, 2) == size(A, 1)), and X must have enough storage to accommodate all allocated entries in A (length(rowvals(X)) >= nnz(A) and length(nonzeros(X)) >= nnz(A)). Column-permutation q's length must match A's column count (length(q) == size(A, 2)).\n\nThis method is the parent of several methods performing transposition and permutation operations on SparseMatrixCSCs. As this method performs no argument checking, prefer the safer child methods ([c]transpose[!], permute[!]) to direct use.\n\nThis method implements the HALFPERM algorithm described in F. Gustavson, \"Two fast algorithms for sparse matrices: multiplication and permuted transposition,\" ACM TOMS 4(3), 250-269 (1978). The algorithm runs in O(size(A, 1), size(A, 2), nnz(A)) time and requires no space beyond that passed in.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.ftranspose!","page":"Sparse Arrays","title":"SparseArrays.ftranspose!","text":"ftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}\n\nTranspose A and store it in X while applying the function f to the non-zero elements. Does not remove the zeros created by f. size(X) must be equal to size(transpose(A)). No additional memory is allocated other than resizing the rowval and nzval of X, if needed.\n\nSee halfperm!\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/SparseArrays/#Noteworthy-External-Sparse-Packages","page":"Sparse Arrays","title":"Noteworthy External Sparse Packages","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Several other Julia packages provide sparse matrix implementations that should be mentioned:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"SuiteSparseGraphBLAS.jl is a wrapper over the fast, multithreaded SuiteSparse:GraphBLAS C library. On CPU this is typically the fastest option, often significantly outperforming MKLSparse.\nCUDA.jl exposes the CUSPARSE library for GPU sparse matrix operations.\nSparseMatricesCSR.jl provides a Julia native implementation of the Compressed Sparse Rows (CSR) format.\nMKLSparse.jl accelerates SparseArrays sparse-dense matrix operations using Intel's MKL library.\nSparseArrayKit.jl available for multidimensional sparse arrays.\nLuxurySparse.jl provides static sparse array formats, as well as a coordinate format.\nExtendableSparse.jl enables fast insertion into sparse matrices using a lazy approach to new stored indices.\nFinch.jl supports extensive multidimensional sparse array formats and operations through a mini tensor language and compiler, all in native Julia. Support for COO, CSF, CSR, CSC and more, as well as operations like broadcast, reduce, etc. and custom operations.","category":"page"},{"location":"devdocs/jit/#JIT-Design-and-Implementation","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"This document explains the design and implementation of Julia's JIT, after codegen has finished and unoptimized LLVM IR has been produced. The JIT is responsible for optimizing and compiling this IR to machine code, and for linking it into the current process and making the code available for execution.","category":"page"},{"location":"devdocs/jit/#Introduction","page":"JIT Design and Implementation","title":"Introduction","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"The JIT is responsible for managing compilation resources, looking up previously compiled code, and compiling new code. It is primarily built on LLVM's On-Request-Compilation (ORCv2) technology, which provides support for a number of useful features such as concurrent compilation, lazy compilation, and the ability to compile code in a separate process. Though LLVM provides a basic JIT compiler in the form of LLJIT, Julia uses many ORCv2 APIs directly to create its own custom JIT compiler.","category":"page"},{"location":"devdocs/jit/#Overview","page":"JIT Design and Implementation","title":"Overview","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"(Image: Diagram of the compiler flow)","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Codegen produces an LLVM module containing IR for one or more Julia functions from the original Julia SSA IR produced by type inference (labeled as translate on the compiler diagram above). It also produces a mapping of code-instance to LLVM function name. However, though some optimizations have been applied by the Julia-based compiler on Julia IR, the LLVM IR produced by codegen still contains many opportunities for optimization. Thus, the first step the JIT takes is to run a target-independent optimization pipeline[tdp] on the LLVM module. Then, the JIT runs a target-dependent optimization pipeline, which includes target-specific optimizations and code generation, and outputs an object file. Finally, the JIT links the resulting object file into the current process and makes the code available for execution. All of this is controlled by code in src/jitlayers.cpp.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"[tdp]: This is not a totally-target independent pipeline, as transformations such as vectorization rely upon target information such as vector register width and cost modeling. Additionally, codegen itself makes a few target-dependent assumptions, and the optimization pipeline will take advantage of that knowledge.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Currently, only one thread at a time is permitted to enter the optimize-compile-link pipeline at a time, due to restrictions imposed by one of our linkers (RuntimeDyld). However, the JIT is designed to support concurrent optimization and compilation, and the linker restriction is expected to be lifted in the future when RuntimeDyld has been fully superseded on all platforms.","category":"page"},{"location":"devdocs/jit/#Optimization-Pipeline","page":"JIT Design and Implementation","title":"Optimization Pipeline","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"The optimization pipeline is based off LLVM's new pass manager, but the pipeline is customized for Julia's needs. The pipeline is defined in src/pipeline.cpp, and broadly proceeds through a number of stages as detailed below.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Early Simplification\nThese passes are mainly used to simplify the IR and canonicalize patterns so that later passes can identify those patterns more easily. Additionally, various intrinsic calls such as branch prediction hints and annotations are lowered into other metadata or other IR features. SimplifyCFG (simplify control flow graph), DCE (dead code elimination), and SROA (scalar replacement of aggregates) are some of the key players here.\nEarly Optimization\nThese passes are typically cheap and are primarily focused around reducing the number of instructions in the IR and propagating knowledge to other instructions. For example, EarlyCSE is used to perform common subexpression elimination, and InstCombine and InstSimplify perform a number of small peephole optimizations to make operations less expensive.\nLoop Optimization\nThese passes canonicalize and simplify loops. Loops are often hot code, which makes loop optimization extremely important for performance. Key players here include LoopRotate, LICM, and LoopFullUnroll. Some bounds check elimination also happens here, as a result of the IRCE pass which can prove certain bounds are never exceeded.\nScalar Optimization\nThe scalar optimization pipeline contains a number of more expensive, but more powerful passes such as GVN (global value numbering), SCCP (sparse conditional constant propagation), and another round of bounds check elimination. These passes are expensive, but they can often remove large amounts of code and make vectorization much more successful and effective. Several other simplification and optimization passes intersperse the more expensive ones to reduce the amount of work they have to do.\nVectorization\nAutomatic vectorization is an extremely powerful transformation for CPU-intensive code. Briefly, vectorization allows execution of a single instruction on multiple data (SIMD), e.g. performing 8 addition operations at the same time. However, proving code to be both capable of vectorization and profitable to vectorize is difficult, and this relies heavily on the prior optimization passes to massage the IR into a state where vectorization is worth it.\nIntrinsic Lowering\nJulia inserts a number of custom intrinsics, for reasons such as object allocation, garbage collection, and exception handling. These intrinsics were originally placed to make optimization opportunities more obvious, but they are now lowered into LLVM IR to enable the IR to be emitted as machine code.\nCleanup\nThese passes are last-chance optimizations, and perform small optimizations such as fused multiply-add propagation and division-remainder simplification. Additionally, targets that do not support half-precision floating point numbers will have their half-precision instructions lowered into single-precision instructions here, and passes are added to provide sanitizer support.","category":"page"},{"location":"devdocs/jit/#Target-Dependent-Optimization-and-Code-Generation","page":"JIT Design and Implementation","title":"Target-Dependent Optimization and Code Generation","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"LLVM provides target-dependent optimization and machine code generation in the same pipeline, located in the TargetMachine for a given platform. These passes include instruction selection, instruction scheduling, register allocation, and machine code emission. The LLVM documentation provides a good overview of the process, and the LLVM source code is the best place to look for details on the pipeline and passes.","category":"page"},{"location":"devdocs/jit/#Linking","page":"JIT Design and Implementation","title":"Linking","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Currently, Julia is transitioning between two linkers: the older RuntimeDyld linker, and the newer JITLink linker. JITLink contains a number of features that RuntimeDyld does not have, such as concurrent and reentrant linking, but currently lacks good support for profiling integrations and does not yet support all of the platforms that RuntimeDyld supports. Over time, JITLink is expected to replace RuntimeDyld entirely. Further details on JITLink can be found in the LLVM documentation.","category":"page"},{"location":"devdocs/jit/#Execution","page":"JIT Design and Implementation","title":"Execution","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Once the code has been linked into the current process, it is available for execution. This fact is made known to the generating codeinst by updating the invoke, specsigflags, and specptr fields appropriately. Codeinsts support upgrading invoke, specsigflags, and specptr fields, so long as every combination of these fields that exists at any given point in time is valid to be called. This allows the JIT to update these fields without invalidating existing codeinsts, supporting a potential future concurrent JIT. Specifically, the following states may be valid:","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"invoke is NULL, specsigflags is 0b00, specptr is NULL\nThis is the initial state of a codeinst, and indicates that the codeinst has not yet been compiled.\ninvoke is non-null, specsigflags is 0b00, specptr is NULL\nThis indicates that the codeinst was not compiled with any specialization, and that the codeinst should be invoked directly. Note that in this instance, invoke does not read either the specsigflags or specptr fields, and therefore they may be modified without invalidating the invoke pointer.\ninvoke is non-null, specsigflags is 0b10, specptr is non-null\nThis indicates that the codeinst was compiled, but a specialized function signature was deemed unnecessary by codegen.\ninvoke is non-null, specsigflags is 0b11, specptr is non-null\nThis indicates that the codeinst was compiled, and a specialized function signature was deemed necessary by codegen. The specptr field contains a pointer to the specialized function signature. The invoke pointer is permitted to read both specsigflags and specptr fields.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"In addition, there are a number of different transitional states that occur during the update process. To account for these potential situations, the following write and read patterns should be used when dealing with these codeinst fields.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"When writing invoke, specsigflags, and specptr:\nPerform an atomic compare-exchange operation of specptr assuming the old value was NULL. This compare-exchange operation should have at least acquire-release ordering, to provide ordering guarantees of the remaining memory operations in the write.\nIf specptr was non-null, cease the write operation and wait for bit 0b10 of specsigflags to be written.\nWrite the new low bit of specsigflags to its final value. This may be a relaxed write.\nWrite the new invoke pointer to its final value. This must have at least a release memory ordering to synchronize with reads of invoke.\nSet the second bit of specsigflags to 1. This must be at least a release memory ordering to synchronize with reads of specsigflags. This step completes the write operation and announces to all other threads that all fields have been set.\nWhen reading all of invoke, specsigflags, and specptr:\nRead the invoke field with at least an acquire memory ordering. This load will be referred to as initial_invoke.\nIf initial_invoke is NULL, the codeinst is not yet executable. invoke is NULL, specsigflags may be treated as 0b00, specptr may be treated as NULL.\nRead the specptr field with at least an acquire memory ordering.\nIf specptr is NULL, then the initial_invoke pointer must not be relying on specptr to guarantee correct execution. Therefore, invoke is non-null, specsigflags may be treated as 0b00, specptr may be treated as NULL.\nIf specptr is non-null, then initial_invoke might not be the final invoke field that uses specptr. This can occur if specptr has been written, but invoke has not yet been written. Therefore, spin on the second bit of specsigflags until it is set to 1 with at least acquire memory ordering.\nRe-read the invoke field with at least an acquire memory ordering. This load will be referred to as final_invoke.\nRead the specsigflags field with any memory ordering.\ninvoke is final_invoke, specsigflags is the value read in step 7, specptr is the value read in step 3.\nWhen updating a specptr to a different but equivalent function pointer:\nPerform a release store of the new function pointer to specptr. Races here must be benign, as the old function pointer is required to still be valid, and any new ones are also required to be valid as well. Once a pointer has been written to specptr, it must always be callable whether or not it is later overwritten.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Although these write, read, and update steps are complicated, they ensure that the JIT can update codeinsts without invalidating existing codeinsts, and that the JIT can update codeinsts without invalidating existing invoke pointers. This allows the JIT to potentially reoptimize functions at higher optimization levels in the future, and also will allow the JIT to support concurrent compilation of functions in the future.","category":"page"},{"location":"devdocs/gc/#Garbage-Collection-in-Julia","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"","category":"section"},{"location":"devdocs/gc/#Introduction","page":"Garbage Collection in Julia","title":"Introduction","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia has a non-moving, partially concurrent, parallel, generational and mostly precise mark-sweep collector (an interface for conservative stack scanning is provided as an option for users who wish to call Julia from C).","category":"page"},{"location":"devdocs/gc/#Allocation","page":"Garbage Collection in Julia","title":"Allocation","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia uses two types of allocators, the size of the allocation request determining which one is used. Objects up to 2k bytes are allocated on a per-thread free-list pool allocator, while objects larger than 2k bytes are allocated through libc malloc.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia’s pool allocator partitions objects on different size classes, so that a memory page managed by the pool allocator (which spans 4 operating system pages on 64bit platforms) only contains objects of the same size class. Each memory page from the pool allocator is paired with some page metadata stored on per-thread lock-free lists. The page metadata contains information such as whether the page has live objects at all, number of free slots, and offsets to the first and last objects in the free-list contained in that page. These metadata are used to optimize the collection phase: a page which has no live objects at all may be returned to the operating system without any need of scanning it, for example.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"While a page that has no objects may be returned to the operating system, its associated metadata is permanently allocated and may outlive the given page. As mentioned above, metadata for allocated pages are stored on per-thread lock-free lists. Metadata for free pages, however, may be stored into three separate lock-free lists depending on whether the page has been mapped but never accessed (page_pool_clean), or whether the page has been lazily sweeped and it's waiting to be madvised by a background GC thread (page_pool_lazily_freed), or whether the page has been madvised (page_pool_freed).","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia's pool allocator follows a \"tiered\" allocation discipline. When requesting a memory page for the pool allocator, Julia will:","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Try to claim a page from page_pool_lazily_freed, which contains pages which were empty on the last stop-the-world phase, but not yet madivsed by a concurrent sweeper GC thread.\nIf it failed claiming a page from page_pool_lazily_freed, it will try to claim a page from the page_pool_clean, which contains pages which were mmaped on a previous page allocation request but never accessed.\nIf it failed claiming a page from pool_page_clean and from page_pool_lazily_freed, it will try to claim a page from page_pool_freed, which contains pages which have already been madvised by a concurrent sweeper GC thread and whose underlying virtual address can be recycled.\nIf it failed in all of the attempts mentioned above, it will mmap a batch of pages, claim one page for itself, and insert the remaining pages into page_pool_clean.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"(Image: Diagram of tiered pool allocation)","category":"page"},{"location":"devdocs/gc/#Marking-and-Generational-Collection","page":"Garbage Collection in Julia","title":"Marking and Generational Collection","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia’s mark phase is implemented through a parallel iterative depth-first-search over the object graph. Julia’s collector is non-moving, so object age information can’t be determined through the memory region in which the object resides alone, but has to be somehow encoded in the object header or on a side table. The lowest two bits of an object’s header are used to store, respectively, a mark bit that is set when an object is scanned during the mark phase and an age bit for the generational collection.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Generational collection is implemented through sticky bits: objects are only pushed to the mark-stack, and therefore traced, if their mark-bits are not set. When objects reach the oldest generation, their mark-bits are not reset during the so-called \"quick-sweep\", which leads to these objects not being traced in a subsequent mark phase. A \"full-sweep\", however, causes the mark-bits of all objects to be reset, leading to all objects being traced in a subsequent mark phase. Objects are promoted to the next generation during every sweep phase they survive. On the mutator side, field writes are intercepted through a write barrier that pushes an object’s address into a per-thread remembered set if the object is in the last generation, and if the object at the field being written is not. Objects in this remembered set are then traced during the mark phase.","category":"page"},{"location":"devdocs/gc/#Sweeping","page":"Garbage Collection in Julia","title":"Sweeping","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Sweeping of object pools for Julia may fall into two categories: if a given page managed by the pool allocator contains at least one live object, then a free-list must be threaded through its dead objects; if a given page contains no live objects at all, then its underlying physical memory may be returned to the operating system through, for instance, the use of madvise system calls on Linux.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"The first category of sweeping is parallelized through work-stealing. For the second category of sweeping, if concurrent page sweeping is enabled through the flag --gcthreads=X,1 we perform the madvise system calls in a background sweeper thread, concurrently with the mutator threads. During the stop-the-world phase of the collector, pool allocated pages which contain no live objects are initially pushed into the pool_page_lazily_freed. The background sweeping thread is then woken up and is responsible for removing pages from pool_page_lazily_freed, calling madvise on them, and inserting them into pool_page_freed. As described above, pool_page_lazily_freed is also shared with mutator threads. This implies that on allocation-heavy multithreaded workloads, mutator threads would often avoid a page fault on allocation (coming from accessing a fresh mmaped page or accessing a madvised page) by directly allocating from a page in pool_page_lazily_freed, while the background sweeper thread needs to madvise a reduce number of pages given some of them were already claimed by the mutators.","category":"page"},{"location":"devdocs/gc/#Heuristics","page":"Garbage Collection in Julia","title":"Heuristics","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"GC heuristics tune the GC by changing the size of the allocation interval between garbage collections.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"The GC heuristics measure how big the heap size is after a collection and set the next collection according to the algorithm described by https://dl.acm.org/doi/10.1145/3563323, in summary, it argues that the heap target should have a square root relationship with the live heap, and that it should also be scaled by how fast the GC is freeing objects and how fast the mutators are allocating. The heuristics measure the heap size by counting the number of pages that are in use and the objects that use malloc. Previously we measured the heap size by counting the alive objects, but that doesn't take into account fragmentation which could lead to bad decisions, that also meant that we used thread local information (allocations) to make decisions about a process wide (when to GC), measuring pages means the decision is global.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"The GC will do full collections when the heap size reaches 80% of the maximum allowed size.","category":"page"},{"location":"manual/constructors/#man-constructors","page":"Constructors","title":"Constructors","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Constructors [1] are functions that create new objects – specifically, instances of Composite Types. In Julia, type objects also serve as constructor functions: they create new instances of themselves when applied to an argument tuple as a function. This much was already mentioned briefly when composite types were introduced. For example:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct Foo\n bar\n baz\n end\n\njulia> foo = Foo(1, 2)\nFoo(1, 2)\n\njulia> foo.bar\n1\n\njulia> foo.baz\n2","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"For many types, forming new objects by binding their field values together is all that is ever needed to create instances. However, in some cases more functionality is required when creating composite objects. Sometimes invariants must be enforced, either by checking arguments or by transforming them. Recursive data structures, especially those that may be self-referential, often cannot be constructed cleanly without first being created in an incomplete state and then altered programmatically to be made whole, as a separate step from object creation. Sometimes, it's just convenient to be able to construct objects with fewer or different types of parameters than they have fields. Julia's system for object construction addresses all of these cases and more.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"[1]: Nomenclature: while the term \"constructor\" generally refers to the entire function which constructs objects of a type, it is common to abuse terminology slightly and refer to specific constructor methods as \"constructors\". In such situations, it is generally clear from the context that the term is used to mean \"constructor method\" rather than \"constructor function\", especially as it is often used in the sense of singling out a particular method of the constructor from all of the others.","category":"page"},{"location":"manual/constructors/#man-outer-constructor-methods","page":"Constructors","title":"Outer Constructor Methods","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"A constructor is just like any other function in Julia in that its overall behavior is defined by the combined behavior of its methods. Accordingly, you can add functionality to a constructor by simply defining new methods. For example, let's say you want to add a constructor method for Foo objects that takes only one argument and uses the given value for both the bar and baz fields. This is simple:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Foo(x) = Foo(x,x)\nFoo\n\njulia> Foo(1)\nFoo(1, 1)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"You could also add a zero-argument Foo constructor method that supplies default values for both of the bar and baz fields:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Foo() = Foo(0)\nFoo\n\njulia> Foo()\nFoo(0, 0)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Here the zero-argument constructor method calls the single-argument constructor method, which in turn calls the automatically provided two-argument constructor method. For reasons that will become clear very shortly, additional constructor methods declared as normal methods like this are called outer constructor methods. Outer constructor methods can only ever create a new instance by calling another constructor method, such as the automatically provided default ones.","category":"page"},{"location":"manual/constructors/#man-inner-constructor-methods","page":"Constructors","title":"Inner Constructor Methods","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"While outer constructor methods succeed in addressing the problem of providing additional convenience methods for constructing objects, they fail to address the other two use cases mentioned in the introduction of this chapter: enforcing invariants, and allowing construction of self-referential objects. For these problems, one needs inner constructor methods. An inner constructor method is like an outer constructor method, except for two differences:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"It is declared inside the block of a type declaration, rather than outside of it like normal methods.\nIt has access to a special locally existent function called new that creates objects of the block's type.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"For example, suppose one wants to declare a type that holds a pair of real numbers, subject to the constraint that the first number is not greater than the second one. One could declare it like this:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct OrderedPair\n x::Real\n y::Real\n OrderedPair(x,y) = x > y ? error(\"out of order\") : new(x,y)\n end","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Now OrderedPair objects can only be constructed such that x <= y:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> OrderedPair(1, 2)\nOrderedPair(1, 2)\n\njulia> OrderedPair(2,1)\nERROR: out of order\nStacktrace:\n [1] error at ./error.jl:33 [inlined]\n [2] OrderedPair(::Int64, ::Int64) at ./none:4\n [3] top-level scope","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"If the type were declared mutable, you could reach in and directly change the field values to violate this invariant. Of course, messing around with an object's internals uninvited is bad practice. You (or someone else) can also provide additional outer constructor methods at any later point, but once a type is declared, there is no way to add more inner constructor methods. Since outer constructor methods can only create objects by calling other constructor methods, ultimately, some inner constructor must be called to create an object. This guarantees that all objects of the declared type must come into existence by a call to one of the inner constructor methods provided with the type, thereby giving some degree of enforcement of a type's invariants.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"If any inner constructor method is defined, no default constructor method is provided: it is presumed that you have supplied yourself with all the inner constructors you need. The default constructor is equivalent to writing your own inner constructor method that takes all of the object's fields as parameters (constrained to be of the correct type, if the corresponding field has a type), and passes them to new, returning the resulting object:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct Foo\n bar\n baz\n Foo(bar,baz) = new(bar,baz)\n end\n","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This declaration has the same effect as the earlier definition of the Foo type without an explicit inner constructor method. The following two types are equivalent – one with a default constructor, the other with an explicit constructor:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct T1\n x::Int64\n end\n\njulia> struct T2\n x::Int64\n T2(x) = new(x)\n end\n\njulia> T1(1)\nT1(1)\n\njulia> T2(1)\nT2(1)\n\njulia> T1(1.0)\nT1(1)\n\njulia> T2(1.0)\nT2(1)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"It is good practice to provide as few inner constructor methods as possible: only those taking all arguments explicitly and enforcing essential error checking and transformation. Additional convenience constructor methods, supplying default values or auxiliary transformations, should be provided as outer constructors that call the inner constructors to do the heavy lifting. This separation is typically quite natural.","category":"page"},{"location":"manual/constructors/#Incomplete-Initialization","page":"Constructors","title":"Incomplete Initialization","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The final problem which has still not been addressed is construction of self-referential objects, or more generally, recursive data structures. Since the fundamental difficulty may not be immediately obvious, let us briefly explain it. Consider the following recursive type declaration:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> mutable struct SelfReferential\n obj::SelfReferential\n end\n","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This type may appear innocuous enough, until one considers how to construct an instance of it. If a is an instance of SelfReferential, then a second instance can be created by the call:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> b = SelfReferential(a)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"But how does one construct the first instance when no instance exists to provide as a valid value for its obj field? The only solution is to allow creating an incompletely initialized instance of SelfReferential with an unassigned obj field, and using that incomplete instance as a valid value for the obj field of another instance, such as, for example, itself.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"To allow for the creation of incompletely initialized objects, Julia allows the new function to be called with fewer than the number of fields that the type has, returning an object with the unspecified fields uninitialized. The inner constructor method can then use the incomplete object, finishing its initialization before returning it. Here, for example, is another attempt at defining the SelfReferential type, this time using a zero-argument inner constructor returning instances having obj fields pointing to themselves:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> mutable struct SelfReferential\n obj::SelfReferential\n SelfReferential() = (x = new(); x.obj = x)\n end\n","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"We can verify that this constructor works and constructs objects that are, in fact, self-referential:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> x = SelfReferential();\n\njulia> x === x\ntrue\n\njulia> x === x.obj\ntrue\n\njulia> x === x.obj.obj\ntrue","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Although it is generally a good idea to return a fully initialized object from an inner constructor, it is possible to return incompletely initialized objects:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> mutable struct Incomplete\n data\n Incomplete() = new()\n end\n\njulia> z = Incomplete();","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"While you are allowed to create objects with uninitialized fields, any access to an uninitialized reference is an immediate error:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> z.data\nERROR: UndefRefError: access to undefined reference","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This avoids the need to continually check for null values. However, not all object fields are references. Julia considers some types to be \"plain data\", meaning all of their data is self-contained and does not reference other objects. The plain data types consist of primitive types (e.g. Int) and immutable structs of other plain data types (see also: isbits, isbitstype). The initial contents of a plain data type is undefined:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct HasPlain\n n::Int\n HasPlain() = new()\n end\n\njulia> HasPlain()\nHasPlain(438103441441)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Arrays of plain data types exhibit the same behavior.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"You can pass incomplete objects to other functions from inner constructors to delegate their completion:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> mutable struct Lazy\n data\n Lazy(v) = complete_me(new(), v)\n end","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"As with incomplete objects returned from constructors, if complete_me or any of its callees try to access the data field of the Lazy object before it has been initialized, an error will be thrown immediately.","category":"page"},{"location":"manual/constructors/#Parametric-Constructors","page":"Constructors","title":"Parametric Constructors","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Parametric types add a few wrinkles to the constructor story. Recall from Parametric Types that, by default, instances of parametric composite types can be constructed either with explicitly given type parameters or with type parameters implied by the types of the arguments given to the constructor. Here are some examples:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct Point{T<:Real}\n x::T\n y::T\n end\n\njulia> Point(1,2) ## implicit T ##\nPoint{Int64}(1, 2)\n\njulia> Point(1.0,2.5) ## implicit T ##\nPoint{Float64}(1.0, 2.5)\n\njulia> Point(1,2.5) ## implicit T ##\nERROR: MethodError: no method matching Point(::Int64, ::Float64)\nThe type `Point` exists, but no method is defined for this combination of argument types when trying to construct it.\n\nClosest candidates are:\n Point(::T, ::T) where T<:Real at none:2\n\njulia> Point{Int64}(1, 2) ## explicit T ##\nPoint{Int64}(1, 2)\n\njulia> Point{Int64}(1.0,2.5) ## explicit T ##\nERROR: InexactError: Int64(2.5)\nStacktrace:\n[...]\n\njulia> Point{Float64}(1.0, 2.5) ## explicit T ##\nPoint{Float64}(1.0, 2.5)\n\njulia> Point{Float64}(1,2) ## explicit T ##\nPoint{Float64}(1.0, 2.0)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"As you can see, for constructor calls with explicit type parameters, the arguments are converted to the implied field types: Point{Int64}(1,2) works, but Point{Int64}(1.0,2.5) raises an InexactError when converting 2.5 to Int64. When the type is implied by the arguments to the constructor call, as in Point(1,2), then the types of the arguments must agree – otherwise the T cannot be determined – but any pair of real arguments with matching type may be given to the generic Point constructor.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"What's really going on here is that Point, Point{Float64} and Point{Int64} are all different constructor functions. In fact, Point{T} is a distinct constructor function for each type T. Without any explicitly provided inner constructors, the declaration of the composite type Point{T<:Real} automatically provides an inner constructor, Point{T}, for each possible type T<:Real, that behaves just like non-parametric default inner constructors do. It also provides a single general outer Point constructor that takes pairs of real arguments, which must be of the same type. This automatic provision of constructors is equivalent to the following explicit declaration:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct Point{T<:Real}\n x::T\n y::T\n Point{T}(x,y) where {T<:Real} = new(x,y)\n end\n\njulia> Point(x::T, y::T) where {T<:Real} = Point{T}(x,y);","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Notice that each definition looks like the form of constructor call that it handles. The call Point{Int64}(1,2) will invoke the definition Point{T}(x,y) inside the struct block. The outer constructor declaration, on the other hand, defines a method for the general Point constructor which only applies to pairs of values of the same real type. This declaration makes constructor calls without explicit type parameters, like Point(1,2) and Point(1.0,2.5), work. Since the method declaration restricts the arguments to being of the same type, calls like Point(1,2.5), with arguments of different types, result in \"no method\" errors.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Suppose we wanted to make the constructor call Point(1,2.5) work by \"promoting\" the integer value 1 to the floating-point value 1.0. The simplest way to achieve this is to define the following additional outer constructor method:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Point(x::Int64, y::Float64) = Point(convert(Float64,x),y);","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This method uses the convert function to explicitly convert x to Float64 and then delegates construction to the general constructor for the case where both arguments are Float64. With this method definition what was previously a MethodError now successfully creates a point of type Point{Float64}:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> p = Point(1,2.5)\nPoint{Float64}(1.0, 2.5)\n\njulia> typeof(p)\nPoint{Float64}","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"However, other similar calls still don't work:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Point(1.5,2)\nERROR: MethodError: no method matching Point(::Float64, ::Int64)\nThe type `Point` exists, but no method is defined for this combination of argument types when trying to construct it.\n\nClosest candidates are:\n Point(::T, !Matched::T) where T<:Real\n @ Main none:1\n Point(!Matched::Int64, !Matched::Float64)\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"For a more general way to make all such calls work sensibly, see Conversion and Promotion. At the risk of spoiling the suspense, we can reveal here that all it takes is the following outer method definition to make all calls to the general Point constructor work as one would expect:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Point(x::Real, y::Real) = Point(promote(x,y)...);","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The promote function converts all its arguments to a common type – in this case Float64. With this method definition, the Point constructor promotes its arguments the same way that numeric operators like + do, and works for all kinds of real numbers:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Point(1.5,2)\nPoint{Float64}(1.5, 2.0)\n\njulia> Point(1,1//2)\nPoint{Rational{Int64}}(1//1, 1//2)\n\njulia> Point(1.0,1//2)\nPoint{Float64}(1.0, 0.5)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Thus, while the implicit type parameter constructors provided by default in Julia are fairly strict, it is possible to make them behave in a more relaxed but sensible manner quite easily. Moreover, since constructors can leverage all of the power of the type system, methods, and multiple dispatch, defining sophisticated behavior is typically quite simple.","category":"page"},{"location":"manual/constructors/#Case-Study:-Rational","page":"Constructors","title":"Case Study: Rational","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Perhaps the best way to tie all these pieces together is to present a real world example of a parametric composite type and its constructor methods. To that end, we implement our own rational number type OurRational, similar to Julia's built-in Rational type, defined in rational.jl:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct OurRational{T<:Integer} <: Real\n num::T\n den::T\n function OurRational{T}(num::T, den::T) where T<:Integer\n if num == 0 && den == 0\n error(\"invalid rational: 0//0\")\n end\n num = flipsign(num, den)\n den = flipsign(den, den)\n g = gcd(num, den)\n num = div(num, g)\n den = div(den, g)\n new(num, den)\n end\n end\n\njulia> OurRational(n::T, d::T) where {T<:Integer} = OurRational{T}(n,d)\nOurRational\n\njulia> OurRational(n::Integer, d::Integer) = OurRational(promote(n,d)...)\nOurRational\n\njulia> OurRational(n::Integer) = OurRational(n,one(n))\nOurRational\n\njulia> ⊘(n::Integer, d::Integer) = OurRational(n,d)\n⊘ (generic function with 1 method)\n\njulia> ⊘(x::OurRational, y::Integer) = x.num ⊘ (x.den*y)\n⊘ (generic function with 2 methods)\n\njulia> ⊘(x::Integer, y::OurRational) = (x*y.den) ⊘ y.num\n⊘ (generic function with 3 methods)\n\njulia> ⊘(x::Complex, y::Real) = complex(real(x) ⊘ y, imag(x) ⊘ y)\n⊘ (generic function with 4 methods)\n\njulia> ⊘(x::Real, y::Complex) = (x*y') ⊘ real(y*y')\n⊘ (generic function with 5 methods)\n\njulia> function ⊘(x::Complex, y::Complex)\n xy = x*y'\n yy = real(y*y')\n complex(real(xy) ⊘ yy, imag(xy) ⊘ yy)\n end\n⊘ (generic function with 6 methods)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The first line – struct OurRational{T<:Integer} <: Real – declares that OurRational takes one type parameter of an integer type, and is itself a real type. The field declarations num::T and den::T indicate that the data held in a OurRational{T} object are a pair of integers of type T, one representing the rational value's numerator and the other representing its denominator.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Now things get interesting. OurRational has a single inner constructor method which checks that num and den aren't both zero and ensures that every rational is constructed in \"lowest terms\" with a non-negative denominator. This is accomplished by first flipping the signs of numerator and denominator if the denominator is negative. Then, both are divided by their greatest common divisor (gcd always returns a non-negative number, regardless of the sign of its arguments). Because this is the only inner constructor for OurRational, we can be certain that OurRational objects are always constructed in this normalized form.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"OurRational also provides several outer constructor methods for convenience. The first is the \"standard\" general constructor that infers the type parameter T from the type of the numerator and denominator when they have the same type. The second applies when the given numerator and denominator values have different types: it promotes them to a common type and then delegates construction to the outer constructor for arguments of matching type. The third outer constructor turns integer values into rationals by supplying a value of 1 as the denominator.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Following the outer constructor definitions, we defined a number of methods for the ⊘ operator, which provides a syntax for writing rationals (e.g. 1 ⊘ 2). Julia's Rational type uses the // operator for this purpose. Before these definitions, ⊘ is a completely undefined operator with only syntax and no meaning. Afterwards, it behaves just as described in Rational Numbers – its entire behavior is defined in these few lines. Note that the infix use of ⊘ works because Julia has a set of symbols that are recognized to be infix operators. The first and most basic definition just makes a ⊘ b construct a OurRational by applying the OurRational constructor to a and b when they are integers. When one of the operands of ⊘ is already a rational number, we construct a new rational for the resulting ratio slightly differently; this behavior is actually identical to division of a rational with an integer. Finally, applying ⊘ to complex integral values creates an instance of Complex{<:OurRational} – a complex number whose real and imaginary parts are rationals:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> z = (1 + 2im) ⊘ (1 - 2im);\n\njulia> typeof(z)\nComplex{OurRational{Int64}}\n\njulia> typeof(z) <: Complex{<:OurRational}\ntrue","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Thus, although the ⊘ operator usually returns an instance of OurRational, if either of its arguments are complex integers, it will return an instance of Complex{<:OurRational} instead. The interested reader should consider perusing the rest of rational.jl: it is short, self-contained, and implements an entire basic Julia type.","category":"page"},{"location":"manual/constructors/#Outer-only-constructors","page":"Constructors","title":"Outer-only constructors","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"As we have seen, a typical parametric type has inner constructors that are called when type parameters are known; e.g. they apply to Point{Int} but not to Point. Optionally, outer constructors that determine type parameters automatically can be added, for example constructing a Point{Int} from the call Point(1,2). Outer constructors call inner constructors to actually make instances. However, in some cases one would rather not provide inner constructors, so that specific type parameters cannot be requested manually.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"For example, say we define a type that stores a vector along with an accurate representation of its sum:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct SummedArray{T<:Number,S<:Number}\n data::Vector{T}\n sum::S\n end\n\njulia> SummedArray(Int32[1; 2; 3], Int32(6))\nSummedArray{Int32, Int32}(Int32[1, 2, 3], 6)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The problem is that we want S to be a larger type than T, so that we can sum many elements with less information loss. For example, when T is Int32, we would like S to be Int64. Therefore we want to avoid an interface that allows the user to construct instances of the type SummedArray{Int32,Int32}. One way to do this is to provide a constructor only for SummedArray, but inside the struct definition block to suppress generation of default constructors:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct SummedArray{T<:Number,S<:Number}\n data::Vector{T}\n sum::S\n function SummedArray(a::Vector{T}) where T\n S = widen(T)\n new{T,S}(a, sum(S, a))\n end\n end\n\njulia> SummedArray(Int32[1; 2; 3], Int32(6))\nERROR: MethodError: no method matching SummedArray(::Vector{Int32}, ::Int32)\nThe type `SummedArray` exists, but no method is defined for this combination of argument types when trying to construct it.\n\nClosest candidates are:\n SummedArray(::Vector{T}) where T\n @ Main none:4\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This constructor will be invoked by the syntax SummedArray(a). The syntax new{T,S} allows specifying parameters for the type to be constructed, i.e. this call will return a SummedArray{T,S}. new{T,S} can be used in any constructor definition, but for convenience the parameters to new{} are automatically derived from the type being constructed when possible.","category":"page"},{"location":"manual/constructors/#Constructors-are-just-callable-objects","page":"Constructors","title":"Constructors are just callable objects","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"An object of any type may be made callable by defining a method. This includes types, i.e., objects of type Type; and constructors may, in fact, be viewed as just callable type objects. For example, there are many methods defined on Bool and various supertypes of it:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> methods(Bool)\n# 10 methods for type constructor:\n [1] Bool(x::BigFloat)\n @ Base.MPFR mpfr.jl:393\n [2] Bool(x::Float16)\n @ Base float.jl:338\n [3] Bool(x::Rational)\n @ Base rational.jl:138\n [4] Bool(x::Real)\n @ Base float.jl:233\n [5] (dt::Type{<:Integer})(ip::Sockets.IPAddr)\n @ Sockets ~/tmp/jl/jl/julia-nightly-assert/share/julia/stdlib/v1.11/Sockets/src/IPAddr.jl:11\n [6] (::Type{T})(x::Enum{T2}) where {T<:Integer, T2<:Integer}\n @ Base.Enums Enums.jl:19\n [7] (::Type{T})(z::Complex) where T<:Real\n @ Base complex.jl:44\n [8] (::Type{T})(x::Base.TwicePrecision) where T<:Number\n @ Base twiceprecision.jl:265\n [9] (::Type{T})(x::T) where T<:Number\n @ boot.jl:894\n [10] (::Type{T})(x::AbstractChar) where T<:Union{AbstractChar, Number}\n @ char.jl:50","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The usual constructor syntax is exactly equivalent to the function-like object syntax, so trying to define a method with each syntax will cause the first method to be overwritten by the next one:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct S\n f::Int\n end\n\njulia> S() = S(7)\nS\n\njulia> (::Type{S})() = S(8) # overwrites the previous constructor method\n\njulia> S()\nS(8)","category":"page"},{"location":"devdocs/builtins/#lib-builtins","page":"Core.Builtins","title":"Core.Builtins","text":"","category":"section"},{"location":"devdocs/builtins/#Builtin-Function-APIs","page":"Core.Builtins","title":"Builtin Function APIs","text":"","category":"section"},{"location":"devdocs/builtins/","page":"Core.Builtins","title":"Core.Builtins","text":"The following Builtin function APIs are considered unstable, but provide the basic definitions for what defines the abilities and behaviors of a Julia program. They are typically accessed through a higher level generic API.","category":"page"},{"location":"devdocs/builtins/","page":"Core.Builtins","title":"Core.Builtins","text":"Core.memoryref\nCore.memoryrefoffset\nCore.memoryrefget\nCore.memoryrefset!\nCore.memoryref_isassigned\nCore.memoryrefswap!\nCore.memoryrefmodify!\nCore.memoryrefreplace!\nCore.memoryrefsetonce!\nCore.Intrinsics.atomic_pointerref\nCore.Intrinsics.atomic_pointerset\nCore.Intrinsics.atomic_pointerswap\nCore.Intrinsics.atomic_pointermodify\nCore.Intrinsics.atomic_pointerreplace\nCore.get_binding_type\nCore.set_binding_type!\nCore.IntrinsicFunction\nCore.Intrinsics\nCore.IR","category":"page"},{"location":"devdocs/builtins/#Core.memoryref","page":"Core.Builtins","title":"Core.memoryref","text":"Core.memoryref(::GenericMemory)\nCore.memoryref(::GenericMemoryRef, index::Int, [boundscheck::Bool])\n\nReturn a GenericMemoryRef for a GenericMemory. See MemoryRef.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefoffset","page":"Core.Builtins","title":"Core.memoryrefoffset","text":"Core..memoryrefoffset(::GenericMemoryRef)\n\nReturn the offset index that was used to construct the MemoryRef. See Core.memoryref.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefget","page":"Core.Builtins","title":"Core.memoryrefget","text":"Core.memoryrefget(::GenericMemoryRef, ordering::Symbol, boundscheck::Bool)\n\nReturn the value stored at the MemoryRef, throwing a BoundsError if the Memory is empty. See ref[]. The memory ordering specified must be compatible with the isatomic parameter.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefset!","page":"Core.Builtins","title":"Core.memoryrefset!","text":"Core.memoryrefset!(::GenericMemoryRef, value, ordering::Symbol, boundscheck::Bool)\n\nStore the value to the MemoryRef, throwing a BoundsError if the Memory is empty. See ref[] = value. The memory ordering specified must be compatible with the isatomic parameter.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryref_isassigned","page":"Core.Builtins","title":"Core.memoryref_isassigned","text":"Core.memoryref_isassigned(::GenericMemoryRef, ordering::Symbol, boundscheck::Bool)\n\nReturn whether there is a value stored at the MemoryRef, returning false if the Memory is empty. See isassigned(::Base.RefValue), Core.memoryrefget. The memory ordering specified must be compatible with the isatomic parameter.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefswap!","page":"Core.Builtins","title":"Core.memoryrefswap!","text":"Core.memoryrefswap!(::GenericMemoryRef, value, ordering::Symbol, boundscheck::Bool)\n\nAtomically perform the operations to simultaneously get and set a MemoryRef value.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also swapproperty! and Core.memoryrefset!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefmodify!","page":"Core.Builtins","title":"Core.memoryrefmodify!","text":"Core.memoryrefmodify!(::GenericMemoryRef, op, value, ordering::Symbol, boundscheck::Bool) -> Pair\n\nAtomically perform the operations to get and set a MemoryRef value after applying the function op.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also modifyproperty! and Core.memoryrefset!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefreplace!","page":"Core.Builtins","title":"Core.memoryrefreplace!","text":"Core.memoryrefreplace!(::GenericMemoryRef, expected, desired,\n success_order::Symbol, fail_order::Symbol=success_order, boundscheck::Bool) -> (; old, success::Bool)\n\nAtomically perform the operations to get and conditionally set a MemoryRef value.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also replaceproperty! and Core.memoryrefset!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefsetonce!","page":"Core.Builtins","title":"Core.memoryrefsetonce!","text":"Core.memoryrefsetonce!(::GenericMemoryRef, value,\n success_order::Symbol, fail_order::Symbol=success_order, boundscheck::Bool) -> success::Bool\n\nAtomically perform the operations to set a MemoryRef to a given value, only if it was previously not set.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also setpropertyonce! and Core.memoryrefset!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointerref","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointerref","text":"Core.Intrinsics.atomic_pointerref(pointer::Ptr{T}, order::Symbol) --> T\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_load.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointerset","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointerset","text":"Core.Intrinsics.atomic_pointerset(pointer::Ptr{T}, new::T, order::Symbol) --> pointer\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_store!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointerswap","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointerswap","text":"Core.Intrinsics.atomic_pointerswap(pointer::Ptr{T}, new::T, order::Symbol) --> old\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_swap!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointermodify","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointermodify","text":"Core.Intrinsics.atomic_pointermodify(pointer::Ptr{T}, function::(old::T,arg::S)->T, arg::S, order::Symbol) --> old\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_modify!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointerreplace","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointerreplace","text":"Core.Intrinsics.atomic_pointerreplace(pointer::Ptr{T}, expected::Any, new::T, success_order::Symbol, failure_order::Symbol) --> (old, cmp)\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_replace!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.get_binding_type","page":"Core.Builtins","title":"Core.get_binding_type","text":"Core.get_binding_type(module::Module, name::Symbol)\n\nRetrieve the declared type of the binding name from the module module.\n\ncompat: Julia 1.9\nThis function requires Julia 1.9 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.set_binding_type!","page":"Core.Builtins","title":"Core.set_binding_type!","text":"Core.set_binding_type!(module::Module, name::Symbol, [type::Type])\n\nSet the declared type of the binding name in the module module to type. Error if the binding already has a type that is not equivalent to type. If the type argument is absent, set the binding type to Any if unset, but do not error.\n\ncompat: Julia 1.9\nThis function requires Julia 1.9 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.IntrinsicFunction","page":"Core.Builtins","title":"Core.IntrinsicFunction","text":"Core.IntrinsicFunction <: Core.Builtin <: Function\n\nThe Core.IntrinsicFunction function define some basic primitives for what defines the abilities and behaviors of a Julia program\n\n\n\n\n\n","category":"type"},{"location":"devdocs/builtins/#Core.Intrinsics","page":"Core.Builtins","title":"Core.Intrinsics","text":"Core.Intrinsics\n\nThe Core.Intrinsics module holds the Core.IntrinsicFunction objects.\n\n\n\n\n\n","category":"module"},{"location":"devdocs/builtins/#Core.IR","page":"Core.Builtins","title":"Core.IR","text":"Core.IR\n\nThe Core.IR module exports the IR object model.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/SHA/#SHA","page":"SHA","title":"SHA","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"DocTestSetup = quote\n using SHA\n using InteractiveUtils\nend","category":"page"},{"location":"stdlib/SHA/#SHA-functions","page":"SHA","title":"SHA functions","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Usage is very straightforward:","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"julia> using SHA\n\njulia> bytes2hex(sha256(\"test\"))\n\"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08\"","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Each exported function (at the time of this writing, SHA-1, SHA-2 224, 256, 384 and 512, and SHA-3 224, 256, 384 and 512 functions are implemented) takes in either an AbstractVector{UInt8}, an AbstractString or an IO object. This makes it trivial to checksum a file:","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"shell> cat /tmp/test.txt\ntest\njulia> using SHA\n\njulia> open(\"/tmp/test.txt\") do f\n sha2_256(f)\n end\n32-element Array{UInt8,1}:\n 0x9f\n 0x86\n 0xd0\n 0x81\n 0x88\n 0x4c\n 0x7d\n 0x65\n ⋮\n 0x5d\n 0x6c\n 0x15\n 0xb0\n 0xf0\n 0x0a\n 0x08","category":"page"},{"location":"stdlib/SHA/#All-SHA-functions","page":"SHA","title":"All SHA functions","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Due to the colloquial usage of sha256 to refer to sha2_256, convenience functions are provided, mapping shaxxx() function calls to sha2_xxx(). For SHA-3, no such colloquialisms exist and the user must use the full sha3_xxx() names.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"shaxxx() takes AbstractString and array-like objects (NTuple and Array) with elements of type UInt8.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-1","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"sha1","category":"page"},{"location":"stdlib/SHA/#SHA.sha1","page":"SHA","title":"SHA.sha1","text":"sha1(data)\n\nHash data using the sha1 algorithm and return the resulting digest. See also SHA1_CTX.\n\n\n\n\n\nsha1(io::IO)\n\nHash data from io using sha1 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-2","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"sha224\nsha256\nsha384\nsha512\nsha2_224\nsha2_256\nsha2_384\nsha2_512","category":"page"},{"location":"stdlib/SHA/#SHA.sha224","page":"SHA","title":"SHA.sha224","text":"sha224(data)\n\nHash data using the sha224 algorithm and return the resulting digest. See also SHA2_224_CTX.\n\n\n\n\n\nsha224(io::IO)\n\nHash data from io using sha224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha256","page":"SHA","title":"SHA.sha256","text":"sha256(data)\n\nHash data using the sha256 algorithm and return the resulting digest. See also SHA2_256_CTX.\n\n\n\n\n\nsha256(io::IO)\n\nHash data from io using sha256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha384","page":"SHA","title":"SHA.sha384","text":"sha384(data)\n\nHash data using the sha384 algorithm and return the resulting digest. See also SHA2_384_CTX.\n\n\n\n\n\nsha384(io::IO)\n\nHash data from io using sha384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha512","page":"SHA","title":"SHA.sha512","text":"sha512(data)\n\nHash data using the sha512 algorithm and return the resulting digest. See also SHA2_512_CTX.\n\n\n\n\n\nsha512(io::IO)\n\nHash data from io using sha512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha2_224","page":"SHA","title":"SHA.sha2_224","text":"sha2_224(data)\n\nHash data using the sha2_224 algorithm and return the resulting digest. See also SHA2_224_CTX.\n\n\n\n\n\nsha2_224(io::IO)\n\nHash data from io using sha2_224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha2_256","page":"SHA","title":"SHA.sha2_256","text":"sha2_256(data)\n\nHash data using the sha2_256 algorithm and return the resulting digest. See also SHA2_256_CTX.\n\n\n\n\n\nsha2_256(io::IO)\n\nHash data from io using sha2_256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha2_384","page":"SHA","title":"SHA.sha2_384","text":"sha2_384(data)\n\nHash data using the sha2_384 algorithm and return the resulting digest. See also SHA2_384_CTX.\n\n\n\n\n\nsha2_384(io::IO)\n\nHash data from io using sha2_384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha2_512","page":"SHA","title":"SHA.sha2_512","text":"sha2_512(data)\n\nHash data using the sha2_512 algorithm and return the resulting digest. See also SHA2_512_CTX.\n\n\n\n\n\nsha2_512(io::IO)\n\nHash data from io using sha2_512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-3","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"sha3_224\nsha3_256\nsha3_384\nsha3_512","category":"page"},{"location":"stdlib/SHA/#SHA.sha3_224","page":"SHA","title":"SHA.sha3_224","text":"sha3_224(data)\n\nHash data using the sha3_224 algorithm and return the resulting digest. See also SHA3_224_CTX.\n\n\n\n\n\nsha3_224(io::IO)\n\nHash data from io using sha3_224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha3_256","page":"SHA","title":"SHA.sha3_256","text":"sha3_256(data)\n\nHash data using the sha3_256 algorithm and return the resulting digest. See also SHA3_256_CTX.\n\n\n\n\n\nsha3_256(io::IO)\n\nHash data from io using sha3_256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha3_384","page":"SHA","title":"SHA.sha3_384","text":"sha3_384(data)\n\nHash data using the sha3_384 algorithm and return the resulting digest. See also SHA3_384_CTX.\n\n\n\n\n\nsha3_384(io::IO)\n\nHash data from io using sha3_384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha3_512","page":"SHA","title":"SHA.sha3_512","text":"sha3_512(data)\n\nHash data using the sha3_512 algorithm and return the resulting digest. See also SHA3_512_CTX.\n\n\n\n\n\nsha3_512(io::IO)\n\nHash data from io using sha3_512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#Working-with-context","page":"SHA","title":"Working with context","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"To create a hash from multiple items the SHAX_XXX_CTX() types can be used to create a stateful hash object that is updated with update! and finalized with digest!","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"julia> using SHA\n\njulia> ctx = SHA2_256_CTX()\nSHA2 256-bit hash state\n\njulia> update!(ctx, b\"some data\")\n0x0000000000000009\n\njulia> update!(ctx, b\"some more data\")\n0x0000000000000017\n\njulia> digest!(ctx)\n32-element Vector{UInt8}:\n 0xbe\n 0xcf\n 0x23\n 0xda\n 0xaf\n 0x02\n 0xf7\n 0xa3\n 0x57\n 0x92\n ⋮\n 0x89\n 0x4f\n 0x59\n 0xd8\n 0xb3\n 0xb4\n 0x81\n 0x8b\n 0xc5","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Note that, at the time of this writing, the SHA3 code is not optimized, and as such is roughly an order of magnitude slower than SHA2.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"update!\ndigest!","category":"page"},{"location":"stdlib/SHA/#SHA.update!","page":"SHA","title":"SHA.update!","text":"update!(context, data[, datalen])\n\nUpdate the SHA context with the bytes in data. See also digest! for finalizing the hash.\n\nExamples\n\njulia> ctx = SHA1_CTX()\nSHA1 hash state\n\njulia> update!(ctx, b\"data to to be hashed\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.digest!","page":"SHA","title":"SHA.digest!","text":"digest!(context)\n\nFinalize the SHA context and return the hash as array of bytes (Array{Uint8, 1}). Updating the context after calling digest! on it will error.\n\nExamples\n\njulia> ctx = SHA1_CTX()\nSHA1 hash state\n\njulia> update!(ctx, b\"data to to be hashed\")\n\njulia> digest!(ctx)\n20-element Array{UInt8,1}:\n 0x83\n 0xe4\n ⋮\n 0x89\n 0xf5\n\njulia> update!(ctx, b\"more data\")\nERROR: Cannot update CTX after `digest!` has been called on it\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#All-SHA-context-types","page":"SHA","title":"All SHA context types","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-1","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA1_CTX","category":"page"},{"location":"stdlib/SHA/#SHA.SHA1_CTX","page":"SHA","title":"SHA.SHA1_CTX","text":"SHA1_CTX()\n\nConstruct an empty SHA1 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-2","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Convenience types are also provided, where SHAXXX_CTX is a type alias for SHA2_XXX_CTX.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA224_CTX\nSHA256_CTX\nSHA384_CTX\nSHA512_CTX\nSHA2_224_CTX\nSHA2_256_CTX\nSHA2_384_CTX\nSHA2_512_CTX","category":"page"},{"location":"stdlib/SHA/#SHA.SHA224_CTX","page":"SHA","title":"SHA.SHA224_CTX","text":"SHA2_224_CTX()\n\nConstruct an empty SHA2_224 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA256_CTX","page":"SHA","title":"SHA.SHA256_CTX","text":"SHA2_256_CTX()\n\nConstruct an empty SHA2_256 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA384_CTX","page":"SHA","title":"SHA.SHA384_CTX","text":"SHA2_384()\n\nConstruct an empty SHA2_384 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA512_CTX","page":"SHA","title":"SHA.SHA512_CTX","text":"SHA2_512_CTX()\n\nConstruct an empty SHA2_512 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA2_224_CTX","page":"SHA","title":"SHA.SHA2_224_CTX","text":"SHA2_224_CTX()\n\nConstruct an empty SHA2_224 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA2_256_CTX","page":"SHA","title":"SHA.SHA2_256_CTX","text":"SHA2_256_CTX()\n\nConstruct an empty SHA2_256 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA2_384_CTX","page":"SHA","title":"SHA.SHA2_384_CTX","text":"SHA2_384()\n\nConstruct an empty SHA2_384 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA2_512_CTX","page":"SHA","title":"SHA.SHA2_512_CTX","text":"SHA2_512_CTX()\n\nConstruct an empty SHA2_512 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-3","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA3_224_CTX\nSHA3_256_CTX\nSHA3_384_CTX\nSHA3_512_CTX","category":"page"},{"location":"stdlib/SHA/#SHA.SHA3_224_CTX","page":"SHA","title":"SHA.SHA3_224_CTX","text":"SHA3_224_CTX()\n\nConstruct an empty SHA3_224 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA3_256_CTX","page":"SHA","title":"SHA.SHA3_256_CTX","text":"SHA3_256_CTX()\n\nConstruct an empty SHA3_256 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA3_384_CTX","page":"SHA","title":"SHA.SHA3_384_CTX","text":"SHA3_384_CTX()\n\nConstruct an empty SHA3_384 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA3_512_CTX","page":"SHA","title":"SHA.SHA3_512_CTX","text":"SHA3_512_CTX()\n\nConstruct an empty SHA3_512 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#HMAC-functions","page":"SHA","title":"HMAC functions","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"julia> using SHA\n\njulia> key = collect(codeunits(\"key_string\"))\n10-element Vector{UInt8}:\n 0x6b\n 0x65\n 0x79\n 0x5f\n 0x73\n 0x74\n 0x72\n 0x69\n 0x6e\n 0x67\n\njulia> bytes2hex(hmac_sha3_256(key, \"test-message\"))\n\"bc49a6f2aa29b27ee5ed1e944edd7f3d153e8a01535d98b5e24dac9a589a6248\"","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"To create a hash from multiple items, the HMAC_CTX() types can be used to create a stateful hash object that is updated with update! and finalized with digest!.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"julia> using SHA\n\njulia> key = collect(codeunits(\"key_string\"))\n10-element Vector{UInt8}:\n 0x6b\n 0x65\n 0x79\n 0x5f\n 0x73\n 0x74\n 0x72\n 0x69\n 0x6e\n 0x67\n\njulia> ctx = HMAC_CTX(SHA3_256_CTX(), key);\n\njulia> update!(ctx, b\"test-\")\n0x0000000000000000000000000000008d\n\njulia> update!(ctx, b\"message\")\n0x00000000000000000000000000000094\n\njulia> bytes2hex(digest!(ctx))\n\"bc49a6f2aa29b27ee5ed1e944edd7f3d153e8a01535d98b5e24dac9a589a6248\"","category":"page"},{"location":"stdlib/SHA/#All-HMAC-functions","page":"SHA","title":"All HMAC functions","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"HMAC context type","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"HMAC_CTX","category":"page"},{"location":"stdlib/SHA/#SHA.HMAC_CTX","page":"SHA","title":"SHA.HMAC_CTX","text":"HMAC_CTX(ctx::CTX, key::Vector{UInt8}) where {CTX<:SHA_CTX}\n\nConstruct an empty HMAC_CTX context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-1","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"hmac_sha1","category":"page"},{"location":"stdlib/SHA/#SHA.hmac_sha1","page":"SHA","title":"SHA.hmac_sha1","text":"hmac_sha1(key, data)\n\nHash data using the sha1 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha1(key, io::IO)\n\nHash data from io with the passed key using sha1 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-2","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"hmac_sha224\nhmac_sha256\nhmac_sha384\nhmac_sha512\nhmac_sha2_224\nhmac_sha2_256\nhmac_sha2_384\nhmac_sha2_512","category":"page"},{"location":"stdlib/SHA/#SHA.hmac_sha224","page":"SHA","title":"SHA.hmac_sha224","text":"hmac_sha224(key, data)\n\nHash data using the sha224 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha224(key, io::IO)\n\nHash data from io with the passed key using sha224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha256","page":"SHA","title":"SHA.hmac_sha256","text":"hmac_sha256(key, data)\n\nHash data using the sha256 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha256(key, io::IO)\n\nHash data from io with the passed key using sha256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha384","page":"SHA","title":"SHA.hmac_sha384","text":"hmac_sha384(key, data)\n\nHash data using the sha384 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha384(key, io::IO)\n\nHash data from io with the passed key using sha384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha512","page":"SHA","title":"SHA.hmac_sha512","text":"hmac_sha512(key, data)\n\nHash data using the sha512 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha512(key, io::IO)\n\nHash data from io with the passed key using sha512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha2_224","page":"SHA","title":"SHA.hmac_sha2_224","text":"hmac_sha2_224(key, data)\n\nHash data using the sha2_224 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha2_224(key, io::IO)\n\nHash data from io with the passed key using sha2_224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha2_256","page":"SHA","title":"SHA.hmac_sha2_256","text":"hmac_sha2_256(key, data)\n\nHash data using the sha2_256 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha2_256(key, io::IO)\n\nHash data from io with the passed key using sha2_256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha2_384","page":"SHA","title":"SHA.hmac_sha2_384","text":"hmac_sha2_384(key, data)\n\nHash data using the sha2_384 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha2_384(key, io::IO)\n\nHash data from io with the passed key using sha2_384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha2_512","page":"SHA","title":"SHA.hmac_sha2_512","text":"hmac_sha2_512(key, data)\n\nHash data using the sha2_512 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha2_512(key, io::IO)\n\nHash data from io with the passed key using sha2_512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-3","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"hmac_sha3_224\nhmac_sha3_256\nhmac_sha3_384\nhmac_sha3_512","category":"page"},{"location":"stdlib/SHA/#SHA.hmac_sha3_224","page":"SHA","title":"SHA.hmac_sha3_224","text":"hmac_sha3_224(key, data)\n\nHash data using the sha3_224 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha3_224(key, io::IO)\n\nHash data from io with the passed key using sha3_224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha3_256","page":"SHA","title":"SHA.hmac_sha3_256","text":"hmac_sha3_256(key, data)\n\nHash data using the sha3_256 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha3_256(key, io::IO)\n\nHash data from io with the passed key using sha3_256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha3_384","page":"SHA","title":"SHA.hmac_sha3_384","text":"hmac_sha3_384(key, data)\n\nHash data using the sha3_384 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha3_384(key, io::IO)\n\nHash data from io with the passed key using sha3_384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha3_512","page":"SHA","title":"SHA.hmac_sha3_512","text":"hmac_sha3_512(key, data)\n\nHash data using the sha3_512 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha3_512(key, io::IO)\n\nHash data from io with the passed key using sha3_512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar","page":"Tar","title":"Tar","text":"","category":"section"},{"location":"stdlib/Tar/","page":"Tar","title":"Tar","text":"Tar.create\nTar.extract\nTar.list\nTar.rewrite\nTar.tree_hash\nTar.Header","category":"page"},{"location":"stdlib/Tar/#Tar.create","page":"Tar","title":"Tar.create","text":"create(\n [ predicate, ] dir, [ tarball ];\n [ skeleton, ] [ portable = false ]\n) -> tarball\n\n predicate :: String --> Bool\n dir :: AbstractString\n tarball :: Union{AbstractString, AbstractCmd, IO}\n skeleton :: Union{AbstractString, AbstractCmd, IO}\n portable :: Bool\n\nCreate a tar archive (\"tarball\") of the directory dir. The resulting archive is written to the path tarball or if no path is specified, a temporary path is created and returned by the function call. If tarball is an IO object then the tarball content is written to that handle instead (the handle is left open).\n\nIf a predicate function is passed, it is called on each system path that is encountered while recursively searching dir and path is only included in the tarball if predicate(path) is true. If predicate(path) returns false for a directory, then the directory is excluded entirely: nothing under that directory will be included in the archive.\n\nIf the skeleton keyword is passed then the file or IO handle given is used as a \"skeleton\" to generate the tarball. You create a skeleton file by passing the skeleton keyword to the extract command. If create is called with that skeleton file and the extracted files haven't changed, an identical tarball is recreated. The skeleton and predicate arguments cannot be used together.\n\nIf the portable flag is true then path names are checked for validity on Windows, which ensures that they don't contain illegal characters or have names that are reserved. See https://stackoverflow.com/a/31976060/659248 for details.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.extract","page":"Tar","title":"Tar.extract","text":"extract(\n [ predicate, ] tarball, [ dir ];\n [ skeleton = , ]\n [ copy_symlinks = , ]\n [ set_permissions = true, ]\n) -> dir\n\n predicate :: Header --> Bool\n tarball :: Union{AbstractString, AbstractCmd, IO}\n dir :: AbstractString\n skeleton :: Union{AbstractString, AbstractCmd, IO}\n copy_symlinks :: Bool\n set_permissions :: Bool\n\nExtract a tar archive (\"tarball\") located at the path tarball into the directory dir. If tarball is an IO object instead of a path, then the archive contents will be read from that IO stream. The archive is extracted to dir which must either be an existing empty directory or a non-existent path which can be created as a new directory. If dir is not specified, the archive is extracted into a temporary directory which is returned by extract.\n\nIf a predicate function is passed, it is called on each Header object that is encountered while extracting tarball and the entry is only extracted if the predicate(hdr) is true. This can be used to selectively extract only parts of an archive, to skip entries that cause extract to throw an error, or to record what is extracted during the extraction process.\n\nBefore it is passed to the predicate function, the Header object is somewhat modified from the raw header in the tarball: the path field is normalized to remove . entries and replace multiple consecutive slashes with a single slash. If the entry has type :hardlink, the link target path is normalized the same way so that it will match the path of the target entry; the size field is set to the size of the target path (which must be an already-seen file).\n\nIf the skeleton keyword is passed then a \"skeleton\" of the extracted tarball is written to the file or IO handle given. This skeleton file can be used to recreate an identical tarball by passing the skeleton keyword to the create function. The skeleton and predicate arguments cannot be used together.\n\nIf copy_symlinks is true then instead of extracting symbolic links as such, they will be extracted as copies of what they link to if they are internal to the tarball and if it is possible to do so. Non-internal symlinks, such as a link to /etc/passwd will not be copied. Symlinks which are in any way cyclic will also not be copied and will instead be skipped. By default, extract will detect whether symlinks can be created in dir or not and will automatically copy symlinks if they cannot be created.\n\nIf set_permissions is false, no permissions are set on the extracted files.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.list","page":"Tar","title":"Tar.list","text":"list(tarball; [ strict = true ]) -> Vector{Header}\nlist(callback, tarball; [ strict = true ])\n\n callback :: Header, [ ] --> Any\n tarball :: Union{AbstractString, AbstractCmd, IO}\n strict :: Bool\n\nList the contents of a tar archive (\"tarball\") located at the path tarball. If tarball is an IO handle, read the tar contents from that stream. Returns a vector of Header structs. See Header for details.\n\nIf a callback is provided then instead of returning a vector of headers, the callback is called on each Header. This can be useful if the number of items in the tarball is large or if you want examine items prior to an error in the tarball. If the callback function can accept a second argument of either type Vector{UInt8} or Vector{Pair{Symbol, String}} then it will be called with a representation of the raw header data either as a single byte vector or as a vector of pairs mapping field names to the raw data for that field (if these fields are concatenated together, the result is the raw data of the header).\n\nBy default list will error if it encounters any tarball contents which the extract function would refuse to extract. With strict=false it will skip these checks and list all the the contents of the tar file whether extract would extract them or not. Beware that malicious tarballs can do all sorts of crafty and unexpected things to try to trick you into doing something bad.\n\nIf the tarball argument is a skeleton file (see extract and create) then list will detect that from the file header and appropriately list or iterate the headers of the skeleton file.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.rewrite","page":"Tar","title":"Tar.rewrite","text":"rewrite(\n [ predicate, ] old_tarball, [ new_tarball ];\n [ portable = false, ]\n) -> new_tarball\n\n predicate :: Header --> Bool\n old_tarball :: Union{AbstractString, AbstractCmd, IO}\n new_tarball :: Union{AbstractString, AbstractCmd, IO}\n portable :: Bool\n\nRewrite old_tarball to the standard format that create generates, while also checking that it doesn't contain anything that would cause extract to raise an error. This is functionally equivalent to doing\n\nTar.create(Tar.extract(predicate, old_tarball), new_tarball)\n\nHowever, it never extracts anything to disk and instead uses the seek function to navigate the old tarball's data. If no new_tarball argument is passed, the new tarball is written to a temporary file whose path is returned.\n\nIf a predicate function is passed, it is called on each Header object that is encountered while extracting old_tarball and the entry is skipped unless predicate(hdr) is true. This can be used to selectively rewrite only parts of an archive, to skip entries that would cause extract to throw an error, or to record what content is encountered during the rewrite process.\n\nBefore it is passed to the predicate function, the Header object is somewhat modified from the raw header in the tarball: the path field is normalized to remove . entries and replace multiple consecutive slashes with a single slash. If the entry has type :hardlink, the link target path is normalized the same way so that it will match the path of the target entry; the size field is set to the size of the target path (which must be an already-seen file).\n\nIf the portable flag is true then path names are checked for validity on Windows, which ensures that they don't contain illegal characters or have names that are reserved. See https://stackoverflow.com/a/31976060/659248 for details.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.tree_hash","page":"Tar","title":"Tar.tree_hash","text":"tree_hash([ predicate, ] tarball;\n [ algorithm = \"git-sha1\", ]\n [ skip_empty = false ]) -> hash::String\n\n predicate :: Header --> Bool\n tarball :: Union{AbstractString, AbstractCmd, IO}\n algorithm :: AbstractString\n skip_empty :: Bool\n\nCompute a tree hash value for the file tree that the tarball contains. By default, this uses git's tree hashing algorithm with the SHA1 secure hash function (like current versions of git). This means that for any tarball whose file tree git can represent—i.e. one with only files, symlinks and non-empty directories—the hash value computed by this function will be the same as the hash value git would compute for that file tree. Note that tarballs can represent file trees with empty directories, which git cannot store, and this function can generate hashes for those, which will, by default (see skip_empty below for how to change this behavior), differ from the hash of a tarball which omits those empty directories. In short, the hash function agrees with git on all trees which git can represent, but extends (in a consistent way) the domain of hashable trees to other trees which git cannot represent.\n\nIf a predicate function is passed, it is called on each Header object that is encountered while processing tarball and an entry is only hashed if predicate(hdr) is true. This can be used to selectively hash only parts of an archive, to skip entries that cause extract to throw an error, or to record what is extracted during the hashing process.\n\nBefore it is passed to the predicate function, the Header object is somewhat modified from the raw header in the tarball: the path field is normalized to remove . entries and replace multiple consecutive slashes with a single slash. If the entry has type :hardlink, the link target path is normalized the same way so that it will match the path of the target entry; the size field is set to the size of the target path (which must be an already-seen file).\n\nCurrently supported values for algorithm are git-sha1 (the default) and git-sha256, which uses the same basic algorithm as git-sha1 but replaces the SHA1 hash function with SHA2-256, the hash function that git will transition to using in the future (due to known attacks on SHA1). Support for other file tree hashing algorithms may be added in the future.\n\nThe skip_empty option controls whether directories in the tarball which recursively contain no files or symlinks are included in the hash or ignored. In general, if you are hashing the content of a tarball or a file tree, you care about all directories, not just non-empty ones, so including these in the computed hash is the default. So why does this function even provide the option to skip empty directories? Because git refuses to store empty directories and will ignore them if you try to add them to a repo. So if you compute a reference tree hash by by adding files to a git repo and then asking git for the tree hash, the hash value that you get will match the hash value computed by tree_hash with skip_empty=true. In other words, this option allows tree_hash to emulate how git would hash a tree with empty directories. If you are hashing trees that may contain empty directories (i.e. do not come from a git repo), however, it is recommended that you hash them using a tool (such as this one) that does not ignore empty directories.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.Header","page":"Tar","title":"Tar.Header","text":"The Header type is a struct representing the essential metadata for a single record in a tar file with this definition:\n\nstruct Header\n path :: String # path relative to the root\n type :: Symbol # type indicator (see below)\n mode :: UInt16 # mode/permissions (best viewed in octal)\n size :: Int64 # size of record data in bytes\n link :: String # target path of a symlink\nend\n\nTypes are represented with the following symbols: file, hardlink, symlink, chardev, blockdev, directory, fifo, or for unknown types, the typeflag character as a symbol. Note that extract refuses to extract records types other than file, symlink and directory; list will only list other kinds of records if called with strict=false.\n\nThe tar format includes various other metadata about records, including user and group IDs, user and group names, and timestamps. The Tar package, by design, completely ignores these. When creating tar files, these fields are always set to zero/empty. When reading tar files, these fields are ignored aside from verifying header checksums for each header record for all fields.\n\n\n\n\n\n","category":"type"},{"location":"devdocs/ssair/#Julia-SSA-form-IR","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Julia uses a static single assignment intermediate representation (SSA IR) to perform optimization. This IR is different from LLVM IR, and unique to Julia. It allows for Julia specific optimizations.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Basic blocks (regions with no control flow) are explicitly annotated.\nif/else and loops are turned into goto statements.\nlines with multiple operations are split into multiple lines by introducing variables.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"For example the following Julia code:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"function foo(x)\n y = sin(x)\n if x > 5.0\n y = y + cos(x)\n end\n return exp(2) + y\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"when called with a Float64 argument is translated into:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"using InteractiveUtils\n@code_typed foo(1.0)","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"CodeInfo(\n1 ─ %1 = invoke Main.sin(x::Float64)::Float64\n│ %2 = Base.lt_float(x, 5.0)::Bool\n└── goto #3 if not %2\n2 ─ %4 = invoke Main.cos(x::Float64)::Float64\n└── %5 = Base.add_float(%1, %4)::Float64\n3 ┄ %6 = φ (#2 => %5, #1 => %1)::Float64\n│ %7 = Base.add_float(7.38905609893065, %6)::Float64\n└── return %7\n) => Float64","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"In this example, we can see all of these changes.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The first basic block is everything in","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"1 ─ %1 = invoke Main.sin(x::Float64)::Float64\n│ %2 = Base.lt_float(x, 5.0)::Bool\n└── goto #3 if not %2","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The if statement is translated into goto #3 if not %2 which goes to the 3rd basic block if x>5 isn't met and otherwise goes to the second basic block.\n%2 is an SSA value introduced to represent x > 5.","category":"page"},{"location":"devdocs/ssair/#Background","page":"Julia SSA-form IR","title":"Background","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Beginning in Julia 0.7, parts of the compiler use a new SSA-form intermediate representation (IR). Historically, the compiler would directly generate LLVM IR from a lowered form of the Julia AST. This form had most syntactic abstractions removed, but still looked a lot like an abstract syntax tree. Over time, in order to facilitate optimizations, SSA values were introduced to this IR and the IR was linearized (i.e. turned into a form where function arguments could only be SSA values or constants). However, non-SSA values (slots) remained in the IR due to the lack of Phi nodes in the IR (necessary for back-edges and re-merging of conditional control flow). This negated much of the usefulness of SSA form representation when performing middle end optimizations. Some heroic effort was put into making these optimizations work without a complete SSA form representation, but the lack of such a representation ultimately proved prohibitive.","category":"page"},{"location":"devdocs/ssair/#Categories-of-IR-nodes","page":"Julia SSA-form IR","title":"Categories of IR nodes","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The SSA IR representation has four categories of IR nodes: Phi, Pi, PhiC, and Upsilon nodes (the latter two are only used for exception handling).","category":"page"},{"location":"devdocs/ssair/#Phi-nodes-and-Pi-nodes","page":"Julia SSA-form IR","title":"Phi nodes and Pi nodes","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Phi nodes are part of generic SSA abstraction (see the link above if you're not familiar with the concept). In the Julia IR, these nodes are represented as:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"struct PhiNode\n edges::Vector{Int32}\n values::Vector{Any}\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"where we ensure that both vectors always have the same length. In the canonical representation (the one handled by codegen and the interpreter), the edge values indicate come-from statement numbers (i.e. if edge has an entry of 15, there must be a goto, gotoifnot or implicit fall through from statement 15 that targets this phi node). Values are either SSA values or constants. It is also possible for a value to be unassigned if the variable was not defined on this path. However, undefinedness checks get explicitly inserted and represented as booleans after middle end optimizations, so code generators may assume that any use of a Phi node will have an assigned value in the corresponding slot. It is also legal for the mapping to be incomplete, i.e. for a Phi node to have missing incoming edges. In that case, it must be dynamically guaranteed that the corresponding value will not be used.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Note that SSA uses semantically occur after the terminator of the corresponding predecessor (\"on the edge\"). Consequently, if multiple Phi nodes appear at the start of a basic block, they are run simultaneously. This means that in the following IR snippet, if we came from block 23, %46 will take the value associated to %45 before we entered this block.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"%45 = φ (#18 => %23, #23 => %50)\n%46 = φ (#18 => 1.0, #23 => %45)","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"PiNodes encode statically proven information that may be implicitly assumed in basic blocks dominated by a given pi node. They are conceptually equivalent to the technique introduced in the paper ABCD: Eliminating Array Bounds Checks on Demand or the predicate info nodes in LLVM. To see how they work, consider, e.g.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"%x::Union{Int, Float64} # %x is some Union{Int, Float64} typed ssa value\nif isa(x, Int)\n # use x\nelse\n # use x\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"We can perform predicate insertion and turn this into:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"%x::Union{Int, Float64} # %x is some Union{Int, Float64} typed ssa value\nif isa(x, Int)\n %x_int = PiNode(x, Int)\n # use %x_int\nelse\n %x_float = PiNode(x, Float64)\n # use %x_float\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Pi nodes are generally ignored in the interpreter, since they don't have any effect on the values, but they may sometimes lead to code generation in the compiler (e.g. to change from an implicitly union split representation to a plain unboxed representation). The main usefulness of PiNodes stems from the fact that path conditions of the values can be accumulated simply by def-use chain walking that is generally done for most optimizations that care about these conditions anyway.","category":"page"},{"location":"devdocs/ssair/#PhiC-nodes-and-Upsilon-nodes","page":"Julia SSA-form IR","title":"PhiC nodes and Upsilon nodes","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Exception handling complicates the SSA story moderately, because exception handling introduces additional control flow edges into the IR across which values must be tracked. One approach to do so, which is followed by LLVM, is to make calls which may throw exceptions into basic block terminators and add an explicit control flow edge to the catch handler:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"invoke @function_that_may_throw() to label %regular unwind to %catch\n\nregular:\n# Control flow continues here\n\ncatch:\n# Exceptions go here","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"However, this is problematic in a language like Julia, where at the start of the optimization pipeline, we do not know which calls throw. We would have to conservatively assume that every call (which in Julia is every statement) throws. This would have several negative effects. On the one hand, it would essentially reduce the scope of every basic block to a single call, defeating the purpose of having operations be performed at the basic block level. On the other hand, every catch basic block would have n*m phi node arguments (n, the number of statements in the critical region, m the number of live values through the catch block).","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"To work around this, we use a combination of Upsilon and PhiC nodes (the C standing for catch, written φᶜ in the IR pretty printer, because unicode subscript c is not available). There are several ways to think of these nodes, but perhaps the easiest is to think of each PhiC as a load from a unique store-many, read-once slot, with Upsilon being the corresponding store operation. The PhiC has an operand list of all the upsilon nodes that store to its implicit slot. The Upsilon nodes however, do not record which PhiC node they store to. This is done for more natural integration with the rest of the SSA IR. E.g. if there are no more uses of a PhiC node, it is safe to delete it, and the same is true of an Upsilon node. In most IR passes, PhiC nodes can be treated like Phi nodes. One can follow use-def chains through them, and they can be lifted to new PhiC nodes and new Upsilon nodes (in the same places as the original Upsilon nodes). The result of this scheme is that the number of Upsilon nodes (and PhiC arguments) is proportional to the number of assigned values to a particular variable (before SSA conversion), rather than the number of statements in the critical region.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"To see this scheme in action, consider the function","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"@noinline opaque() = invokelatest(identity, nothing) # Something opaque\nfunction foo()\n local y\n x = 1\n try\n y = 2\n opaque()\n y = 3\n error()\n catch\n end\n (x, y)\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The corresponding IR (with irrelevant types stripped) is:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"1 ─ nothing::Nothing\n2 ─ %2 = $(Expr(:enter, #4))\n3 ─ %3 = ϒ (false)\n│ %4 = ϒ (#undef)\n│ %5 = ϒ (1)\n│ %6 = ϒ (true)\n│ %7 = ϒ (2)\n│ invoke Main.opaque()::Any\n│ %9 = ϒ (true)\n│ %10 = ϒ (3)\n│ invoke Main.error()::Union{}\n└── $(Expr(:unreachable))::Union{}\n4 ┄ %13 = φᶜ (%3, %6, %9)::Bool\n│ %14 = φᶜ (%4, %7, %10)::Core.Compiler.MaybeUndef(Int64)\n│ %15 = φᶜ (%5)::Core.Const(1)\n└── $(Expr(:leave, Core.SSAValue(2)))\n5 ─ $(Expr(:pop_exception, :(%2)))::Any\n│ $(Expr(:throw_undef_if_not, :y, :(%13)))::Any\n│ %19 = Core.tuple(%15, %14)\n└── return %19","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Note in particular that every value live into the critical region gets an upsilon node at the top of the critical region. This is because catch blocks are considered to have an invisible control flow edge from outside the function. As a result, no SSA value dominates the catch blocks, and all incoming values have to come through a φᶜ node.","category":"page"},{"location":"devdocs/ssair/#Main-SSA-data-structure","page":"Julia SSA-form IR","title":"Main SSA data structure","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The main SSAIR data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. The core of the data structure is a flat vector of statements. Each statement is implicitly assigned an SSA value based on its position in the vector (i.e. the result of the statement at idx 1 can be accessed using SSAValue(1) etc). For each SSA value, we additionally maintain its type. Since, SSA values are definitionally assigned only once, this type is also the result type of the expression at the corresponding index. However, while this representation is rather efficient (since the assignments don't need to be explicitly encoded), it of course carries the drawback that order is semantically significant, so reorderings and insertions change statement numbers. Additionally, we do not keep use lists (i.e. it is impossible to walk from a def to all its uses without explicitly computing this map–def lists however are trivial since you can look up the corresponding statement from the index), so the LLVM-style RAUW (replace-all-uses-with) operation is unavailable.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Instead, we do the following:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"We keep a separate buffer of nodes to insert (including the position to insert them at, the type of the corresponding value and the node itself). These nodes are numbered by their occurrence in the insertion buffer, allowing their values to be immediately used elsewhere in the IR (i.e. if there are 12 statements in the original statement list, the first new statement will be accessible as SSAValue(13)).\nRAUW style operations are performed by setting the corresponding statement index to the replacement value.\nStatements are erased by setting the corresponding statement to nothing (this is essentially just a special-case convention of the above).\nIf there are any uses of the statement being erased, they will be set to nothing.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"There is a compact! function that compacts the above data structure by performing the insertion of nodes in the appropriate place, trivial copy propagation, and renaming of uses to any changed SSA values. However, the clever part of this scheme is that this compaction can be done lazily as part of the subsequent pass. Most optimization passes need to walk over the entire list of statements, performing analysis or modifications along the way. We provide an IncrementalCompact iterator that can be used to iterate over the statement list. It will perform any necessary compaction and return the new index of the node, as well as the node itself. It is legal at this point to walk def-use chains, as well as make any modifications or deletions to the IR (insertions are disallowed however).","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The idea behind this arrangement is that, since the optimization passes need to touch the corresponding memory anyway and incur the corresponding memory access penalty, performing the extra housekeeping should have comparatively little overhead (and save the overhead of maintaining these data structures during IR modification).","category":"page"},{"location":"devdocs/EscapeAnalysis/#EscapeAnalysis","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Core.Compiler.EscapeAnalysis is a compiler utility module that aims to analyze escape information of Julia's SSA-form IR a.k.a. IRCode.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"This escape analysis aims to:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"leverage Julia's high-level semantics, especially reason about escapes and aliasing via inter-procedural calls\nbe versatile enough to be used for various optimizations including alias-aware SROA, early finalize insertion, copy-free ImmutableArray construction, stack allocation of mutable objects, and so on.\nachieve a simple implementation based on a fully backward data-flow analysis implementation as well as a new lattice design that combines orthogonal lattice properties","category":"page"},{"location":"devdocs/EscapeAnalysis/#Try-it-out!","page":"EscapeAnalysis","title":"Try it out!","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"You can give a try to the escape analysis by loading the EAUtils.jl utility script that defines the convenience entries code_escapes and @code_escapes for testing and debugging purposes:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"let JULIA_DIR = normpath(Sys.BINDIR, \"..\", \"share\", \"julia\")\n # load `EscapeAnalysis` module to define the core analysis code\n include(normpath(JULIA_DIR, \"base\", \"compiler\", \"ssair\", \"EscapeAnalysis\", \"EscapeAnalysis.jl\"))\n using .EscapeAnalysis\n # load `EAUtils` module to define the utilities\n include(normpath(JULIA_DIR, \"test\", \"compiler\", \"EscapeAnalysis\", \"EAUtils.jl\"))\n using .EAUtils\nend\n\nmutable struct SafeRef{T}\n x::T\nend\nBase.getindex(x::SafeRef) = x.x;\nBase.setindex!(x::SafeRef, v) = x.x = v;\nBase.isassigned(x::SafeRef) = true;\nget′(x) = isassigned(x) ? x[] : throw(x);\n\nresult = code_escapes((String,String,String,String)) do s1, s2, s3, s4\n r1 = Ref(s1)\n r2 = Ref(s2)\n r3 = SafeRef(s3)\n try\n s1 = get′(r1)\n ret = sizeof(s1)\n catch err\n global GV = err # will definitely escape `r1`\n end\n s2 = get′(r2) # still `r2` doesn't escape fully\n s3 = get′(r3) # still `r3` doesn't escape fully\n s4 = sizeof(s4) # the argument `s4` doesn't escape here\n return s2, s3, s4\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"The symbols on the side of each call argument and SSA statements represent the following meaning:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"◌ (plain): this value is not analyzed because escape information of it won't be used anyway (when the object is isbitstype for example)\n✓ (green or cyan): this value never escapes (has_no_escape(result.state[x]) holds), colored blue if it has arg escape also (has_arg_escape(result.state[x]) holds)\n↑ (blue or yellow): this value can escape to the caller via return (has_return_escape(result.state[x]) holds), colored yellow if it has unhandled thrown escape also (has_thrown_escape(result.state[x]) holds)\nX (red): this value can escape to somewhere the escape analysis can't reason about like escapes to a global memory (has_all_escape(result.state[x]) holds)\n* (bold): this value's escape state is between the ReturnEscape and AllEscape in the partial order of EscapeInfo, colored yellow if it has unhandled thrown escape also (has_thrown_escape(result.state[x]) holds)\n′: this value has additional object field / array element information in its AliasInfo property","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Escape information of each call argument and SSA value can be inspected programmatically as like:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"result.state[Core.Argument(3)] # get EscapeInfo of `s2`\n\nresult.state[Core.SSAValue(3)] # get EscapeInfo of `r3`","category":"page"},{"location":"devdocs/EscapeAnalysis/#Analysis-Design","page":"EscapeAnalysis","title":"Analysis Design","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/#Lattice-Design","page":"EscapeAnalysis","title":"Lattice Design","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"EscapeAnalysis is implemented as a data-flow analysis that works on a lattice of x::EscapeInfo, which is composed of the following properties:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"x.Analyzed::Bool: not formally part of the lattice, only indicates x has not been analyzed or not\nx.ReturnEscape::BitSet: records SSA statements where x can escape to the caller via return\nx.ThrownEscape::BitSet: records SSA statements where x can be thrown as exception (used for the exception handling described below)\nx.AliasInfo: maintains all possible values that can be aliased to fields or array elements of x (used for the alias analysis described below)\nx.ArgEscape::Int (not implemented yet): indicates it will escape to the caller through setfield! on argument(s)","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"These attributes can be combined to create a partial lattice that has a finite height, given the invariant that an input program has a finite number of statements, which is assured by Julia's semantics. The clever part of this lattice design is that it enables a simpler implementation of lattice operations by allowing them to handle each lattice property separately[LatticeDesign].","category":"page"},{"location":"devdocs/EscapeAnalysis/#Backward-Escape-Propagation","page":"EscapeAnalysis","title":"Backward Escape Propagation","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"This escape analysis implementation is based on the data-flow algorithm described in the paper[MM02]. The analysis works on the lattice of EscapeInfo and transitions lattice elements from the bottom to the top until every lattice element gets converged to a fixed point by maintaining a (conceptual) working set that contains program counters corresponding to remaining SSA statements to be analyzed. The analysis manages a single global state that tracks EscapeInfo of each argument and SSA statement, but also note that some flow-sensitivity is encoded as program counters recorded in EscapeInfo's ReturnEscape property, which can be combined with domination analysis later to reason about flow-sensitivity if necessary.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"One distinctive design of this escape analysis is that it is fully backward, i.e. escape information flows from usages to definitions. For example, in the code snippet below, EA first analyzes the statement return %1 and imposes ReturnEscape on %1 (corresponding to obj), and then it analyzes %1 = %new(Base.RefValue{String, _2})) and propagates the ReturnEscape imposed on %1 to the call argument _2 (corresponding to s):","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,)) do s\n obj = Ref(s)\n return obj\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"The key observation here is that this backward analysis allows escape information to flow naturally along the use-def chain rather than control-flow[BackandForth]. As a result this scheme enables a simple implementation of escape analysis, e.g. PhiNode for example can be handled simply by propagating escape information imposed on a PhiNode to its predecessor values:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((Bool, String, String)) do cnd, s, t\n if cnd\n obj = Ref(s)\n else\n obj = Ref(t)\n end\n return obj\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/#EA-Alias-Analysis","page":"EscapeAnalysis","title":"Alias Analysis","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"EscapeAnalysis implements a backward field analysis in order to reason about escapes imposed on object fields with certain accuracy, and x::EscapeInfo's x.AliasInfo property exists for this purpose. It records all possible values that can be aliased to fields of x at \"usage\" sites, and then the escape information of that recorded values are propagated to the actual field values later at \"definition\" sites. More specifically, the analysis records a value that may be aliased to a field of object by analyzing getfield call, and then it propagates its escape information to the field when analyzing %new(...) expression or setfield! call[Dynamism].","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,)) do s\n obj = SafeRef(\"init\")\n obj[] = s\n v = obj[]\n return v\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"In the example above, ReturnEscape imposed on %3 (corresponding to v) is not directly propagated to %1 (corresponding to obj) but rather that ReturnEscape is only propagated to _2 (corresponding to s). Here %3 is recorded in %1's AliasInfo property as it can be aliased to the first field of %1, and then when analyzing Base.setfield!(%1, :x, _2)::String, that escape information is propagated to _2 but not to %1.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"So EscapeAnalysis tracks which IR elements can be aliased across a getfield-%new/setfield! chain in order to analyze escapes of object fields, but actually this alias analysis needs to be generalized to handle other IR elements as well. This is because in Julia IR the same object is sometimes represented by different IR elements and so we should make sure that those different IR elements that actually can represent the same object share the same escape information. IR elements that return the same object as their operand(s), such as PiNode and typeassert, can cause that IR-level aliasing and thus requires escape information imposed on any of such aliased values to be shared between them. More interestingly, it is also needed for correctly reasoning about mutations on PhiNode. Let's consider the following example:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((Bool, String,)) do cond, x\n if cond\n ϕ2 = ϕ1 = SafeRef(\"foo\")\n else\n ϕ2 = ϕ1 = SafeRef(\"bar\")\n end\n ϕ2[] = x\n y = ϕ1[]\n return y\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"ϕ1 = %5 and ϕ2 = %6 are aliased and thus ReturnEscape imposed on %8 = Base.getfield(%6, :x)::String (corresponding to y = ϕ1[]) needs to be propagated to Base.setfield!(%5, :x, _3)::String (corresponding to ϕ2[] = x). In order for such escape information to be propagated correctly, the analysis should recognize that the predecessors of ϕ1 and ϕ2 can be aliased as well and equalize their escape information.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"One interesting property of such aliasing information is that it is not known at \"usage\" site but can only be derived at \"definition\" site (as aliasing is conceptually equivalent to assignment), and thus it doesn't naturally fit in a backward analysis. In order to efficiently propagate escape information between related values, EscapeAnalysis.jl uses an approach inspired by the escape analysis algorithm explained in an old JVM paper[JVM05]. That is, in addition to managing escape lattice elements, the analysis also maintains an \"equi\"-alias set, a disjoint set of aliased arguments and SSA statements. The alias set manages values that can be aliased to each other and allows escape information imposed on any of such aliased values to be equalized between them.","category":"page"},{"location":"devdocs/EscapeAnalysis/#EA-Array-Analysis","page":"EscapeAnalysis","title":"Array Analysis","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"The alias analysis for object fields described above can also be generalized to analyze array operations. EscapeAnalysis implements handlings for various primitive array operations so that it can propagate escapes via arrayref-arrayset use-def chain and does not escape allocated arrays too conservatively:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,)) do s\n ary = Any[]\n push!(ary, SafeRef(s))\n return ary[1], length(ary)\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"In the above example EscapeAnalysis understands that %20 and %2 (corresponding to the allocated object SafeRef(s)) are aliased via the arrayset-arrayref chain and imposes ReturnEscape on them, but not impose it on the allocated array %1 (corresponding to ary). EscapeAnalysis still imposes ThrownEscape on ary since it also needs to account for potential escapes via BoundsError, but also note that such unhandled ThrownEscape can often be ignored when optimizing the ary allocation.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Furthermore, in cases when array index information as well as array dimensions can be known precisely, EscapeAnalysis is able to even reason about \"per-element\" aliasing via arrayref-arrayset chain, as EscapeAnalysis does \"per-field\" alias analysis for objects:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,String)) do s, t\n ary = Vector{Any}(undef, 2)\n ary[1] = SafeRef(s)\n ary[2] = SafeRef(t)\n return ary[1], length(ary)\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Note that ReturnEscape is only imposed on %2 (corresponding to SafeRef(s)) but not on %4 (corresponding to SafeRef(t)). This is because the allocated array's dimension and indices involved with all arrayref/arrayset operations are available as constant information and EscapeAnalysis can understand that %6 is aliased to %2 but never be aliased to %4. In this kind of case, the succeeding optimization passes will be able to replace Base.arrayref(true, %1, 1)::Any with %2 (a.k.a. \"load-forwarding\") and eventually eliminate the allocation of array %1 entirely (a.k.a. \"scalar-replacement\").","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"When compared to object field analysis, where an access to object field can be analyzed trivially using type information derived by inference, array dimension isn't encoded as type information and so we need an additional analysis to derive that information. EscapeAnalysis at this moment first does an additional simple linear scan to analyze dimensions of allocated arrays before firing up the main analysis routine so that the succeeding escape analysis can precisely analyze operations on those arrays.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"However, such precise \"per-element\" alias analysis is often hard. Essentially, the main difficulty inherit to array is that array dimension and index are often non-constant:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"loop often produces loop-variant, non-constant array indices\n(specific to vectors) array resizing changes array dimension and invalidates its constant-ness","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Let's discuss those difficulties with concrete examples.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"In the following example, EscapeAnalysis fails the precise alias analysis since the index at the Base.arrayset(false, %4, %8, %6)::Vector{Any} is not (trivially) constant. Especially Any[nothing, nothing] forms a loop and calls that arrayset operation in a loop, where %6 is represented as a ϕ-node value (whose value is control-flow dependent). As a result, ReturnEscape ends up imposed on both %23 (corresponding to SafeRef(s)) and %25 (corresponding to SafeRef(t)), although ideally we want it to be imposed only on %23 but not on %25:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,String)) do s, t\n ary = Any[nothing, nothing]\n ary[1] = SafeRef(s)\n ary[2] = SafeRef(t)\n return ary[1], length(ary)\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"The next example illustrates how vector resizing makes precise alias analysis hard. The essential difficulty is that the dimension of allocated array %1 is first initialized as 0, but it changes by the two :jl_array_grow_end calls afterwards. EscapeAnalysis currently simply gives up precise alias analysis whenever it encounters any array resizing operations and so ReturnEscape is imposed on both %2 (corresponding to SafeRef(s)) and %20 (corresponding to SafeRef(t)):","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,String)) do s, t\n ary = Any[]\n push!(ary, SafeRef(s))\n push!(ary, SafeRef(t))\n ary[1], length(ary)\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"In order to address these difficulties, we need inference to be aware of array dimensions and propagate array dimensions in a flow-sensitive way[ArrayDimension], as well as come up with nice representation of loop-variant values.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"EscapeAnalysis at this moment quickly switches to the more imprecise analysis that doesn't track precise index information in cases when array dimensions or indices are trivially non constant. The switch can naturally be implemented as a lattice join operation of EscapeInfo.AliasInfo property in the data-flow analysis framework.","category":"page"},{"location":"devdocs/EscapeAnalysis/#EA-Exception-Handling","page":"EscapeAnalysis","title":"Exception Handling","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"It would be also worth noting how EscapeAnalysis handles possible escapes via exceptions. Naively it seems enough to propagate escape information imposed on :the_exception object to all values that may be thrown in a corresponding try block. But there are actually several other ways to access to the exception object in Julia, such as Base.current_exceptions and rethrow. For example, escape analysis needs to account for potential escape of r in the example below:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"const GR = Ref{Any}();\n@noinline function rethrow_escape!()\n try\n rethrow()\n catch err\n GR[] = err\n end\nend;\nget′(x) = isassigned(x) ? x[] : throw(x);\n\ncode_escapes() do\n r = Ref{String}()\n local t\n try\n t = get′(r)\n catch err\n t = typeof(err) # `err` (which `r` aliases to) doesn't escape here\n rethrow_escape!() # but `r` escapes here\n end\n return t\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"It requires a global analysis in order to correctly reason about all possible escapes via existing exception interfaces. For now we always propagate the topmost escape information to all potentially thrown objects conservatively, since such an additional analysis might not be worthwhile to do given that exception handling and error path usually don't need to be very performance sensitive, and also optimizations of error paths might be very ineffective anyway since they are often even \"unoptimized\" intentionally for latency reasons.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"x::EscapeInfo's x.ThrownEscape property records SSA statements where x can be thrown as an exception. Using this information EscapeAnalysis can propagate possible escapes via exceptions limitedly to only those may be thrown in each try region:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"result = code_escapes((String,String)) do s1, s2\n r1 = Ref(s1)\n r2 = Ref(s2)\n local ret\n try\n s1 = get′(r1)\n ret = sizeof(s1)\n catch err\n global GV = err # will definitely escape `r1`\n end\n s2 = get′(r2) # still `r2` doesn't escape fully\n return s2\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/#Analysis-Usage","page":"EscapeAnalysis","title":"Analysis Usage","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"analyze_escapes is the entry point to analyze escape information of SSA-IR elements.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Most optimizations like SROA (sroa_pass!) are more effective when applied to an optimized source that the inlining pass (ssa_inlining_pass!) has simplified by resolving inter-procedural calls and expanding callee sources. Accordingly, analyze_escapes is also able to analyze post-inlining IR and collect escape information that is useful for certain memory-related optimizations.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"However, since certain optimization passes like inlining can change control flows and eliminate dead code, they can break the inter-procedural validity of escape information. In particularity, in order to collect inter-procedurally valid escape information, we need to analyze a pre-inlining IR.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Because of this reason, analyze_escapes can analyze IRCode at any Julia-level optimization stage, and especially, it is supposed to be used at the following two stages:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"IPO EA: analyze pre-inlining IR to generate IPO-valid escape information cache\nLocal EA: analyze post-inlining IR to collect locally-valid escape information","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Escape information derived by IPO EA is transformed to the ArgEscapeCache data structure and cached globally. By passing an appropriate get_escape_cache callback to analyze_escapes, the escape analysis can improve analysis accuracy by utilizing cached inter-procedural information of non-inlined callees that has been derived by previous IPO EA. More interestingly, it is also valid to use IPO EA escape information for type inference, e.g., inference accuracy can be improved by forming Const/PartialStruct/MustAlias of mutable object.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Core.Compiler.EscapeAnalysis.analyze_escapes\nCore.Compiler.EscapeAnalysis.EscapeState\nCore.Compiler.EscapeAnalysis.EscapeInfo","category":"page"},{"location":"devdocs/EscapeAnalysis/#Core.Compiler.EscapeAnalysis.analyze_escapes","page":"EscapeAnalysis","title":"Core.Compiler.EscapeAnalysis.analyze_escapes","text":"analyze_escapes(ir::IRCode, nargs::Int, get_escape_cache) -> estate::EscapeState\n\nAnalyzes escape information in ir:\n\nnargs: the number of actual arguments of the analyzed call\nget_escape_cache(::MethodInstance) -> Union{Bool,ArgEscapeCache}: retrieves cached argument escape information\n\n\n\n\n\n","category":"function"},{"location":"devdocs/EscapeAnalysis/#Core.Compiler.EscapeAnalysis.EscapeState","page":"EscapeAnalysis","title":"Core.Compiler.EscapeAnalysis.EscapeState","text":"estate::EscapeState\n\nExtended lattice that maps arguments and SSA values to escape information represented as EscapeInfo. Escape information imposed on SSA IR element x can be retrieved by estate[x].\n\n\n\n\n\n","category":"type"},{"location":"devdocs/EscapeAnalysis/#Core.Compiler.EscapeAnalysis.EscapeInfo","page":"EscapeAnalysis","title":"Core.Compiler.EscapeAnalysis.EscapeInfo","text":"x::EscapeInfo\n\nA lattice for escape information, which holds the following properties:\n\nx.Analyzed::Bool: not formally part of the lattice, only indicates whether x has been analyzed\nx.ReturnEscape::Bool: indicates x can escape to the caller via return\nx.ThrownEscape::BitSet: records SSA statement numbers where x can be thrown as exception:\nisempty(x.ThrownEscape): x will never be thrown in this call frame (the bottom)\npc ∈ x.ThrownEscape: x may be thrown at the SSA statement at pc\n-1 ∈ x.ThrownEscape: x may be thrown at arbitrary points of this call frame (the top)\nThis information will be used by escape_exception! to propagate potential escapes via exception.\nx.AliasInfo::Union{Bool,IndexableFields,IndexableElements,Unindexable}: maintains all possible values that can be aliased to fields or array elements of x:\nx.AliasInfo === false indicates the fields/elements of x aren't analyzed yet\nx.AliasInfo === true indicates the fields/elements of x can't be analyzed, e.g. the type of x is not known or is not concrete and thus its fields/elements can't be known precisely\nx.AliasInfo::IndexableFields records all the possible values that can be aliased to fields of object x with precise index information\nx.AliasInfo::IndexableElements records all the possible values that can be aliased to elements of array x with precise index information\nx.AliasInfo::Unindexable records all the possible values that can be aliased to fields/elements of x without precise index information\nx.Liveness::BitSet: records SSA statement numbers where x should be live, e.g. to be used as a call argument, to be returned to a caller, or preserved for :foreigncall:\nisempty(x.Liveness): x is never be used in this call frame (the bottom)\n0 ∈ x.Liveness also has the special meaning that it's a call argument of the currently analyzed call frame (and thus it's visible from the caller immediately).\npc ∈ x.Liveness: x may be used at the SSA statement at pc\n-1 ∈ x.Liveness: x may be used at arbitrary points of this call frame (the top)\n\nThere are utility constructors to create common EscapeInfos, e.g.,\n\nNoEscape(): the bottom(-like) element of this lattice, meaning it won't escape to anywhere\nAllEscape(): the topmost element of this lattice, meaning it will escape to everywhere\n\nanalyze_escapes will transition these elements from the bottom to the top, in the same direction as Julia's native type inference routine. An abstract state will be initialized with the bottom(-like) elements:\n\nthe call arguments are initialized as ArgEscape(), whose Liveness property includes 0 to indicate that it is passed as a call argument and visible from a caller immediately\nthe other states are initialized as NotAnalyzed(), which is a special lattice element that is slightly lower than NoEscape, but at the same time doesn't represent any meaning other than it's not analyzed yet (thus it's not formally part of the lattice)\n\n\n\n\n\n","category":"type"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[LatticeDesign]: Our type inference implementation takes the alternative approach, where each lattice property is represented by a special lattice element type object. It turns out that it started to complicate implementations of the lattice operations mainly because it often requires conversion rules between each lattice element type object. And we are working on overhauling our type inference lattice implementation with EscapeInfo-like lattice design.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[MM02]: A Graph-Free approach to Data-Flow Analysis. Markas Mohnen, 2002, April. https://api.semanticscholar.org/CorpusID:28519618.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[BackandForth]: Our type inference algorithm in contrast is implemented as a forward analysis, because type information usually flows from \"definition\" to \"usage\" and it is more natural and effective to propagate such information in a forward way.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[Dynamism]: In some cases, however, object fields can't be analyzed precisely. For example, object may escape to somewhere EscapeAnalysis can't account for possible memory effects on it, or fields of the objects simply can't be known because of the lack of type information. In such cases AliasInfo property is raised to the topmost element within its own lattice order, and it causes succeeding field analysis to be conservative and escape information imposed on fields of an unanalyzable object to be propagated to the object itself.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[JVM05]: Escape Analysis in the Context of Dynamic Compilation and Deoptimization. Thomas Kotzmann and Hanspeter Mössenböck, 2005, June. https://dl.acm.org/doi/10.1145/1064979.1064996.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[ArrayDimension]: Otherwise we will need yet another forward data-flow analysis on top of the escape analysis.","category":"page"},{"location":"devdocs/aot/#Ahead-of-Time-Compilation","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"This document describes the design and structure of the ahead-of-time (AOT) compilation system in Julia. This system is used when generating system images and package images. Much of the implementation described here is located in aotcompile.cpp, staticdata.c, and processor.cpp","category":"page"},{"location":"devdocs/aot/#Introduction","page":"Ahead of Time Compilation","title":"Introduction","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Though Julia normally compiles code just-in-time (JIT), it is possible to compile code ahead of time and save the resulting code to a file. This can be useful for a number of reasons:","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"To reduce the time it takes to start a Julia process.\nTo reduce the time spent in the JIT compiler instead of executing code (time to first execution, TTFX).\nTo reduce the amount of memory used by the JIT compiler.","category":"page"},{"location":"devdocs/aot/#High-Level-Overview","page":"Ahead of Time Compilation","title":"High-Level Overview","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The following descriptions are a snapshot of the current implementation details of the end-to-end pipeline that happens internally when the user compiles a new AOT module, such as occurs when they type using Foo. These details are likely to change over time as we implement better ways to handle them, so current implementations may not exactly match the dataflow and functions described below.","category":"page"},{"location":"devdocs/aot/#Compiling-Code-Images","page":"Ahead of Time Compilation","title":"Compiling Code Images","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Firstly, the methods that need to be compiled to native code must be identified. This can only be done by actually executing the code to be compiled, as the set of methods that need to be compiled depends on the types of the arguments passed to the methods, and method invocations with certain combinations of types may not be known until runtime. During this process, the exact methods that the compiler sees are tracked for later compilation, producing a compilation trace.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"note: Note\nCurrently when compiling images, Julia runs the trace generation in a different process than the process performing the AOT compilation. This can have impacts when attempting to use a debugger during precompilation. The best way to debug precompilation with a debugger is to use the rr debugger, record the entire process tree, use rr ps to identify the relevant failing process, and then use rr replay -p PID to replay just the failing process.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Once the methods to be compiled have been identified, they are passed to the jl_create_system_image function. This function sets up a number of data structures that will be used when serializing native code to a file, and then calls jl_create_native with the array of methods. jl_create_native runs codegen on the methods produces one or more LLVM modules. jl_create_system_image then records some useful information about what codegen produced from the module(s).","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The module(s) are then passed to jl_dump_native, along with the information recorded by jl_create_system_image. jl_dump_native contains the code necessary to serialize the module(s) to bitcode, object, or assembly files depending on the command-line options passed to Julia. The serialized code and information are then written to a file as an archive.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The final step is to run a system linker on the object files in the archive produced by jl_dump_native. Once this step is complete, a shared library containing the compiled code is produced.","category":"page"},{"location":"devdocs/aot/#Loading-Code-Images","page":"Ahead of Time Compilation","title":"Loading Code Images","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"When loading a code image, the shared library produced by the linker is loaded into memory. The system image data is then loaded from the shared library. This data contains information about the types, methods, and code instances that were compiled into the shared library. This data is used to restore the state of the runtime to what it was when the code image was compiled.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"If the code image was compiled with multiversioning, the loader will pick the appropriate version of each function to use based on the CPU features available on the current machine.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"For system images, since no other code has been loaded, the state of the runtime is now the same as it was when the code image was compiled. For package images, the environment may have changed compared to when the code was compiled, so each method must be checked against the global method table to determine if it is still valid code.","category":"page"},{"location":"devdocs/aot/#Compiling-Methods","page":"Ahead of Time Compilation","title":"Compiling Methods","text":"","category":"section"},{"location":"devdocs/aot/#Tracing-Compiled-Methods","page":"Ahead of Time Compilation","title":"Tracing Compiled Methods","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Julia has a command-line flag to record all of the methods that are compiled by the JIT compiler, --trace-compile=filename. When a function is compiled and this flag has a filename, Julia will print out a precompile statement to that file with the method and argument types it was called with. This therefore generates a precompile script that can be used later in the AOT compilation process. The PrecompileTools package has tooling that can make taking advantage of this functionality easier for package developers.","category":"page"},{"location":"devdocs/aot/#jl_create_system_image","page":"Ahead of Time Compilation","title":"jl_create_system_image","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"jl_create_system_image saves all of the Julia-specific metadata necessary to later restore the state of the runtime. This includes data such as code instances, method instances, method tables, and type information. This function also sets up the data structures necessary to serialize the native code to a file. Finally, it calls jl_create_native to create one or more LLVM modules containing the native code for the methods passed to it. jl_create_native is responsible for running codegen on the methods passed to it.","category":"page"},{"location":"devdocs/aot/#jl_dump_native","page":"Ahead of Time Compilation","title":"jl_dump_native","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"jl_dump_native is responsible for serializing the LLVM module containing the native code to a file. In addition to the module, the system image data produced by jl_create_system_image is compiled as a global variable. The output of this method is bitcode, object, and/or assembly archives containing the code and system image data.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"jl_dump_native is typically one of the larger time sinks when emitting native code, with much of the time spent in optimizing LLVM IR and emitting machine code. Therefore, this function is capable of multithreading the optimization and machine code emission steps. This multithreading is parameterized on the size of the module, but can be explicitly overridden by setting the JULIA_IMAGE_THREADS environment variable. The default maximum number of threads is half the number of available threads, but setting it to be lower can reduce peak memory usage during compilation.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"jl_dump_native can also produce native code optimized for multiple architectures, when integrated with the Julia loader. This is triggered by setting the JULIA_CPU_TARGET environment variable and mediated by the multiversioning pass in the optimization pipeline. To make this work with multithreading, an annotation step is added before the module is split into submodules that are emitted on their own threads, and this annotation step uses information available throughout the entire module to decide what functions are cloned for different architectures. Once the annotation has happened, individual threads can emit code for different architectures in parallel, knowing that a different submodule is guaranteed to produce the necessary functions that will be called by a cloned function.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Some other metadata about how the module was serialized is also stored in the archive, such as the number of threads used to serialize the module and the number of functions that were compiled.","category":"page"},{"location":"devdocs/aot/#Static-Linking","page":"Ahead of Time Compilation","title":"Static Linking","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The final step in the AOT compilation process is to run a linker on the object files in the archive produced by jl_dump_native. This produces a shared library containing the compiled code. This shared library can then be loaded by Julia to restore the state of the runtime. When compiling a system image, the native linker used by a C compiler is used to produce the final shared library. For package images, the LLVM linker LLD is used to provide a more consistent linking interface.","category":"page"},{"location":"devdocs/aot/#Loading-Code-Images-2","page":"Ahead of Time Compilation","title":"Loading Code Images","text":"","category":"section"},{"location":"devdocs/aot/#Loading-the-Shared-Library","page":"Ahead of Time Compilation","title":"Loading the Shared Library","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The first step in loading a code image is to load the shared library produced by the linker. This is done by calling jl_dlopen on the path to the shared library. This function is responsible for loading the shared library and resolving all of the symbols in the library.","category":"page"},{"location":"devdocs/aot/#Loading-Native-Code","page":"Ahead of Time Compilation","title":"Loading Native Code","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The loader first needs to identify whether the native code that was compiled is valid for the architecture that the loader is running on. This is necessary to avoid executing instructions that older CPUs do not recognize. This is done by checking the CPU features available on the current machine against the CPU features that the code was compiled for. When multiversioning is enabled, the loader will pick the appropriate version of each function to use based on the CPU features available on the current machine. If none of the feature sets that were multiversioned, the loader will throw an error.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Part of the multiversioning pass creates a number of global arrays of all of the functions in the module. When this process is multithreaded, an array of arrays is created, which the loader reorganizes into one large array with all of the functions that were compiled for this architecture. A similar process occurs for the global variables in the module.","category":"page"},{"location":"devdocs/aot/#Setting-Up-Julia-State","page":"Ahead of Time Compilation","title":"Setting Up Julia State","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The loader then uses the global variables and functions produced from loading native code to set up Julia runtime core data structures in the current process. This setup involves adding types and methods to the Julia runtime, and making the cached native code available for use by other Julia functions and the interpreter. For package images, each method must be validated, in that the global method table's state must match the state that the package image was compiled for. In particular, if a different set of methods exists at the load time compared to compile time of the package image, the method must be invalidated and recompiled on first use. This is necessary to ensure that execution semantics remain the same regardless of if a package was precompiled or if the code was directly executed. System images do not need to perform this validation, since the global method table is empty at load time. Thus, system images have faster load times than package images.","category":"page"},{"location":"manual/control-flow/#Control-Flow","page":"Control Flow","title":"Control Flow","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Julia provides a variety of control flow constructs:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Compound Expressions: begin and ;.\nConditional Evaluation: if-elseif-else and ?: (ternary operator).\nShort-Circuit Evaluation: logical operators && (“and”) and || (“or”), and also chained comparisons.\nRepeated Evaluation: Loops: while and for.\nException Handling: try-catch, error and throw.\nTasks (aka Coroutines): yieldto.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The first five control flow mechanisms are standard to high-level programming languages. Tasks are not so standard: they provide non-local control flow, making it possible to switch between temporarily-suspended computations. This is a powerful construct: both exception handling and cooperative multitasking are implemented in Julia using tasks. Everyday programming requires no direct usage of tasks, but certain problems can be solved much more easily by using tasks.","category":"page"},{"location":"manual/control-flow/#man-compound-expressions","page":"Control Flow","title":"Compound Expressions","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Sometimes it is convenient to have a single expression which evaluates several subexpressions in order, returning the value of the last subexpression as its value. There are two Julia constructs that accomplish this: begin blocks and ; chains. The value of both compound expression constructs is that of the last subexpression. Here's an example of a begin block:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> z = begin\n x = 1\n y = 2\n x + y\n end\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Since these are fairly small, simple expressions, they could easily be placed onto a single line, which is where the ; chain syntax comes in handy:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> z = (x = 1; y = 2; x + y)\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This syntax is particularly useful with the terse single-line function definition form introduced in Functions. Although it is typical, there is no requirement that begin blocks be multiline or that ; chains be single-line:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> begin x = 1; y = 2; x + y end\n3\n\njulia> (x = 1;\n y = 2;\n x + y)\n3","category":"page"},{"location":"manual/control-flow/#man-conditional-evaluation","page":"Control Flow","title":"Conditional Evaluation","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Conditional evaluation allows portions of code to be evaluated or not evaluated depending on the value of a boolean expression. Here is the anatomy of the if-elseif-else conditional syntax:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"if x < y\n println(\"x is less than y\")\nelseif x > y\n println(\"x is greater than y\")\nelse\n println(\"x is equal to y\")\nend","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"If the condition expression x < y is true, then the corresponding block is evaluated; otherwise the condition expression x > y is evaluated, and if it is true, the corresponding block is evaluated; if neither expression is true, the else block is evaluated. Here it is in action:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function test(x, y)\n if x < y\n println(\"x is less than y\")\n elseif x > y\n println(\"x is greater than y\")\n else\n println(\"x is equal to y\")\n end\n end\ntest (generic function with 1 method)\n\njulia> test(1, 2)\nx is less than y\n\njulia> test(2, 1)\nx is greater than y\n\njulia> test(1, 1)\nx is equal to y","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The elseif and else blocks are optional, and as many elseif blocks as desired can be used. The condition expressions in the if-elseif-else construct are evaluated until the first one evaluates to true, after which the associated block is evaluated, and no further condition expressions or blocks are evaluated.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"if blocks are \"leaky\", i.e. they do not introduce a local scope. This means that new variables defined inside the if clauses can be used after the if block, even if they weren't defined before. So, we could have defined the test function above as","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function test(x,y)\n if x < y\n relation = \"less than\"\n elseif x == y\n relation = \"equal to\"\n else\n relation = \"greater than\"\n end\n println(\"x is \", relation, \" y.\")\n end\ntest (generic function with 1 method)\n\njulia> test(2, 1)\nx is greater than y.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The variable relation is declared inside the if block, but used outside. However, when depending on this behavior, make sure all possible code paths define a value for the variable. The following change to the above function results in a runtime error","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function test(x,y)\n if x < y\n relation = \"less than\"\n elseif x == y\n relation = \"equal to\"\n end\n println(\"x is \", relation, \" y.\")\n end\ntest (generic function with 1 method)\n\njulia> test(1,2)\nx is less than y.\n\njulia> test(2,1)\nERROR: UndefVarError: `relation` not defined in local scope\nStacktrace:\n [1] test(::Int64, ::Int64) at ./none:7","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"if blocks also return a value, which may seem unintuitive to users coming from many other languages. This value is simply the return value of the last executed statement in the branch that was chosen, so","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> x = 3\n3\n\njulia> if x > 0\n \"positive!\"\n else\n \"negative...\"\n end\n\"positive!\"","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Note that very short conditional statements (one-liners) are frequently expressed using Short-Circuit Evaluation in Julia, as outlined in the next section.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Unlike C, MATLAB, Perl, Python, and Ruby – but like Java, and a few other stricter, typed languages – it is an error if the value of a conditional expression is anything but true or false:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> if 1\n println(\"true\")\n end\nERROR: TypeError: non-boolean (Int64) used in boolean context","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This error indicates that the conditional was of the wrong type: Int64 rather than the required Bool.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The so-called \"ternary operator\", ?:, is closely related to the if-elseif-else syntax, but is used where a conditional choice between single expression values is required, as opposed to conditional execution of longer blocks of code. It gets its name from being the only operator in most languages taking three operands:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"a ? b : c","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The expression a, before the ?, is a condition expression, and the ternary operation evaluates the expression b, before the :, if the condition a is true or the expression c, after the :, if it is false. Note that the spaces around ? and : are mandatory: an expression like a?b:c is not a valid ternary expression (but a newline is acceptable after both the ? and the :).","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The easiest way to understand this behavior is to see an example. In the previous example, the println call is shared by all three branches: the only real choice is which literal string to print. This could be written more concisely using the ternary operator. For the sake of clarity, let's try a two-way version first:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> x = 1; y = 2;\n\njulia> println(x < y ? \"less than\" : \"not less than\")\nless than\n\njulia> x = 1; y = 0;\n\njulia> println(x < y ? \"less than\" : \"not less than\")\nnot less than","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"If the expression x < y is true, the entire ternary operator expression evaluates to the string \"less than\" and otherwise it evaluates to the string \"not less than\". The original three-way example requires chaining multiple uses of the ternary operator together:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> test(x, y) = println(x < y ? \"x is less than y\" :\n x > y ? \"x is greater than y\" : \"x is equal to y\")\ntest (generic function with 1 method)\n\njulia> test(1, 2)\nx is less than y\n\njulia> test(2, 1)\nx is greater than y\n\njulia> test(1, 1)\nx is equal to y","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"To facilitate chaining, the operator associates from right to left.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"It is significant that like if-elseif-else, the expressions before and after the : are only evaluated if the condition expression evaluates to true or false, respectively:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> v(x) = (println(x); x)\nv (generic function with 1 method)\n\njulia> 1 < 2 ? v(\"yes\") : v(\"no\")\nyes\n\"yes\"\n\njulia> 1 > 2 ? v(\"yes\") : v(\"no\")\nno\n\"no\"","category":"page"},{"location":"manual/control-flow/#Short-Circuit-Evaluation","page":"Control Flow","title":"Short-Circuit Evaluation","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The && and || operators in Julia correspond to logical “and” and “or” operations, respectively, and are typically used for this purpose. However, they have an additional property of short-circuit evaluation: they don't necessarily evaluate their second argument, as explained below. (There are also bitwise & and | operators that can be used as logical “and” and “or” without short-circuit behavior, but beware that & and | have higher precedence than && and || for evaluation order.)","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Short-circuit evaluation is quite similar to conditional evaluation. The behavior is found in most imperative programming languages having the && and || boolean operators: in a series of boolean expressions connected by these operators, only the minimum number of expressions are evaluated as are necessary to determine the final boolean value of the entire chain. Some languages (like Python) refer to them as and (&&) and or (||). Explicitly, this means that:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"In the expression a && b, the subexpression b is only evaluated if a evaluates to true.\nIn the expression a || b, the subexpression b is only evaluated if a evaluates to false.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The reasoning is that a && b must be false if a is false, regardless of the value of b, and likewise, the value of a || b must be true if a is true, regardless of the value of b. Both && and || associate to the right, but && has higher precedence than || does. It's easy to experiment with this behavior:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> t(x) = (println(x); true)\nt (generic function with 1 method)\n\njulia> f(x) = (println(x); false)\nf (generic function with 1 method)\n\njulia> t(1) && t(2)\n1\n2\ntrue\n\njulia> t(1) && f(2)\n1\n2\nfalse\n\njulia> f(1) && t(2)\n1\nfalse\n\njulia> f(1) && f(2)\n1\nfalse\n\njulia> t(1) || t(2)\n1\ntrue\n\njulia> t(1) || f(2)\n1\ntrue\n\njulia> f(1) || t(2)\n1\n2\ntrue\n\njulia> f(1) || f(2)\n1\n2\nfalse","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"You can easily experiment in the same way with the associativity and precedence of various combinations of && and || operators.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This behavior is frequently used in Julia to form an alternative to very short if statements. Instead of if end, one can write && (which could be read as: and then ). Similarly, instead of if ! end, one can write || (which could be read as: or else ).","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"For example, a recursive factorial routine could be defined like this:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function fact(n::Int)\n n >= 0 || error(\"n must be non-negative\")\n n == 0 && return 1\n n * fact(n-1)\n end\nfact (generic function with 1 method)\n\njulia> fact(5)\n120\n\njulia> fact(0)\n1\n\njulia> fact(-1)\nERROR: n must be non-negative\nStacktrace:\n [1] error at ./error.jl:33 [inlined]\n [2] fact(::Int64) at ./none:2\n [3] top-level scope","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Boolean operations without short-circuit evaluation can be done with the bitwise boolean operators introduced in Mathematical Operations and Elementary Functions: & and |. These are normal functions, which happen to support infix operator syntax, but always evaluate their arguments:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> f(1) & t(2)\n1\n2\nfalse\n\njulia> t(1) | t(2)\n1\n2\ntrue","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Just like condition expressions used in if, elseif or the ternary operator, the operands of && or || must be boolean values (true or false). Using a non-boolean value anywhere except for the last entry in a conditional chain is an error:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> 1 && true\nERROR: TypeError: non-boolean (Int64) used in boolean context","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"On the other hand, any type of expression can be used at the end of a conditional chain. It will be evaluated and returned depending on the preceding conditionals:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> true && (x = (1, 2, 3))\n(1, 2, 3)\n\njulia> false && (x = (1, 2, 3))\nfalse","category":"page"},{"location":"manual/control-flow/#man-loops","page":"Control Flow","title":"Repeated Evaluation: Loops","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"There are two constructs for repeated evaluation of expressions: the while loop and the for loop. Here is an example of a while loop:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> i = 1;\n\njulia> while i <= 3\n println(i)\n global i += 1\n end\n1\n2\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The while loop evaluates the condition expression (i <= 3 in this case), and as long it remains true, keeps also evaluating the body of the while loop. If the condition expression is false when the while loop is first reached, the body is never evaluated.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The for loop makes common repeated evaluation idioms easier to write. Since counting up and down like the above while loop does is so common, it can be expressed more concisely with a for loop:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i = 1:3\n println(i)\n end\n1\n2\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Here the 1:3 is a range object, representing the sequence of numbers 1, 2, 3. The for loop iterates through these values, assigning each one in turn to the variable i. In general, the for construct can loop over any \"iterable\" object (or \"container\"), from a range like 1:3 or 1:3:13 (a StepRange indicating every 3rd integer 1, 4, 7, …, 13) to more generic containers like arrays, including iterators defined by user code or external packages. For containers other than ranges, the alternative (but fully equivalent) keyword in or ∈ is typically used instead of =, since it makes the code read more clearly:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i in [1,4,0]\n println(i)\n end\n1\n4\n0\n\njulia> for s ∈ [\"foo\",\"bar\",\"baz\"]\n println(s)\n end\nfoo\nbar\nbaz","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Various types of iterable containers will be introduced and discussed in later sections of the manual (see, e.g., Multi-dimensional Arrays).","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"One rather important distinction between the previous while loop form and the for loop form is the scope during which the variable is visible. A for loop always introduces a new iteration variable in its body, regardless of whether a variable of the same name exists in the enclosing scope. This implies that on the one hand i need not be declared before the loop. On the other hand it will not be visible outside the loop, nor will an outside variable of the same name be affected. You'll either need a new interactive session instance or a different variable name to test this:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for j = 1:3\n println(j)\n end\n1\n2\n3\n\njulia> j\nERROR: UndefVarError: `j` not defined in `Main`","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> j = 0;\n\njulia> for j = 1:3\n println(j)\n end\n1\n2\n3\n\njulia> j\n0","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Use for outer to modify the latter behavior and reuse an existing local variable.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"See Scope of Variables for a detailed explanation of variable scope, outer, and how it works in Julia.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"It is sometimes convenient to terminate the repetition of a while before the test condition is falsified or stop iterating in a for loop before the end of the iterable object is reached. This can be accomplished with the break keyword:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> i = 1;\n\njulia> while true\n println(i)\n if i >= 3\n break\n end\n global i += 1\n end\n1\n2\n3\n\njulia> for j = 1:1000\n println(j)\n if j >= 3\n break\n end\n end\n1\n2\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Without the break keyword, the above while loop would never terminate on its own, and the for loop would iterate up to 1000. These loops are both exited early by using break.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"In other circumstances, it is handy to be able to stop an iteration and move on to the next one immediately. The continue keyword accomplishes this:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i = 1:10\n if i % 3 != 0\n continue\n end\n println(i)\n end\n3\n6\n9","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This is a somewhat contrived example since we could produce the same behavior more clearly by negating the condition and placing the println call inside the if block. In realistic usage there is more code to be evaluated after the continue, and often there are multiple points from which one calls continue.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Multiple nested for loops can be combined into a single outer loop, forming the cartesian product of its iterables:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i = 1:2, j = 3:4\n println((i, j))\n end\n(1, 3)\n(1, 4)\n(2, 3)\n(2, 4)","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"With this syntax, iterables may still refer to outer loop variables; e.g. for i = 1:n, j = 1:i is valid. However a break statement inside such a loop exits the entire nest of loops, not just the inner one. Both variables (i and j) are set to their current iteration values each time the inner loop runs. Therefore, assignments to i will not be visible to subsequent iterations:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i = 1:2, j = 3:4\n println((i, j))\n i = 0\n end\n(1, 3)\n(1, 4)\n(2, 3)\n(2, 4)","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"If this example were rewritten to use a for keyword for each variable, then the output would be different: the second and fourth values would contain 0.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Multiple containers can be iterated over at the same time in a single for loop using zip:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for (j, k) in zip([1 2 3], [4 5 6 7])\n println((j,k))\n end\n(1, 4)\n(2, 5)\n(3, 6)","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Using zip will create an iterator that is a tuple containing the subiterators for the containers passed to it. The zip iterator will iterate over all subiterators in order, choosing the ith element of each subiterator in the ith iteration of the for loop. Once any of the subiterators run out, the for loop will stop.","category":"page"},{"location":"manual/control-flow/#Exception-Handling","page":"Control Flow","title":"Exception Handling","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"When an unexpected condition occurs, a function may be unable to return a reasonable value to its caller. In such cases, it may be best for the exceptional condition to either terminate the program while printing a diagnostic error message, or if the programmer has provided code to handle such exceptional circumstances then allow that code to take the appropriate action.","category":"page"},{"location":"manual/control-flow/#Built-in-Exceptions","page":"Control Flow","title":"Built-in Exceptions","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Exceptions are thrown when an unexpected condition has occurred. The built-in Exceptions listed below all interrupt the normal flow of control.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Exception\nArgumentError\nBoundsError\nCompositeException\nDimensionMismatch\nDivideError\nDomainError\nEOFError\nErrorException\nInexactError\nInitError\nInterruptException\nInvalidStateException\nKeyError\nLoadError\nOutOfMemoryError\nReadOnlyMemoryError\nRemoteException\nMethodError\nOverflowError\nMeta.ParseError\nSystemError\nTypeError\nUndefRefError\nUndefVarError\nStringIndexError","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"For example, the sqrt function throws a DomainError if applied to a negative real value:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> sqrt(-1)\nERROR: DomainError with -1.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"You may define your own exceptions in the following way:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> struct MyCustomException <: Exception end","category":"page"},{"location":"manual/control-flow/#The-[throw](@ref)-function","page":"Control Flow","title":"The throw function","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Exceptions can be created explicitly with throw. For example, a function defined only for non-negative numbers could be written to throw a DomainError if the argument is negative:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> f(x) = x>=0 ? exp(-x) : throw(DomainError(x, \"argument must be non-negative\"))\nf (generic function with 1 method)\n\njulia> f(1)\n0.36787944117144233\n\njulia> f(-1)\nERROR: DomainError with -1:\nargument must be non-negative\nStacktrace:\n [1] f(::Int64) at ./none:1","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Note that DomainError without parentheses is not an exception, but a type of exception. It needs to be called to obtain an Exception object:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> typeof(DomainError(nothing)) <: Exception\ntrue\n\njulia> typeof(DomainError) <: Exception\nfalse","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Additionally, some exception types take one or more arguments that are used for error reporting:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> throw(UndefVarError(:x))\nERROR: UndefVarError: `x` not defined","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This mechanism can be implemented easily by custom exception types following the way UndefVarError is written:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> struct MyUndefVarError <: Exception\n var::Symbol\n end\n\njulia> Base.showerror(io::IO, e::MyUndefVarError) = print(io, e.var, \" not defined\")","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"note: Note\nWhen writing an error message, it is preferred to make the first word lowercase. For example,size(A) == size(B) || throw(DimensionMismatch(\"size of A not equal to size of B\"))is preferred oversize(A) == size(B) || throw(DimensionMismatch(\"Size of A not equal to size of B\")).However, sometimes it makes sense to keep the uppercase first letter, for instance if an argument to a function is a capital letter:size(A,1) == size(B,2) || throw(DimensionMismatch(\"A has first dimension...\")).","category":"page"},{"location":"manual/control-flow/#Errors","page":"Control Flow","title":"Errors","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The error function is used to produce an ErrorException that interrupts the normal flow of control.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Suppose we want to stop execution immediately if the square root of a negative number is taken. To do this, we can define a fussy version of the sqrt function that raises an error if its argument is negative:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> fussy_sqrt(x) = x >= 0 ? sqrt(x) : error(\"negative x not allowed\")\nfussy_sqrt (generic function with 1 method)\n\njulia> fussy_sqrt(2)\n1.4142135623730951\n\njulia> fussy_sqrt(-1)\nERROR: negative x not allowed\nStacktrace:\n [1] error at ./error.jl:33 [inlined]\n [2] fussy_sqrt(::Int64) at ./none:1\n [3] top-level scope","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"If fussy_sqrt is called with a negative value from another function, instead of trying to continue execution of the calling function, it returns immediately, displaying the error message in the interactive session:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function verbose_fussy_sqrt(x)\n println(\"before fussy_sqrt\")\n r = fussy_sqrt(x)\n println(\"after fussy_sqrt\")\n return r\n end\nverbose_fussy_sqrt (generic function with 1 method)\n\njulia> verbose_fussy_sqrt(2)\nbefore fussy_sqrt\nafter fussy_sqrt\n1.4142135623730951\n\njulia> verbose_fussy_sqrt(-1)\nbefore fussy_sqrt\nERROR: negative x not allowed\nStacktrace:\n [1] error at ./error.jl:33 [inlined]\n [2] fussy_sqrt at ./none:1 [inlined]\n [3] verbose_fussy_sqrt(::Int64) at ./none:3\n [4] top-level scope","category":"page"},{"location":"manual/control-flow/#The-try/catch-statement","page":"Control Flow","title":"The try/catch statement","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The try/catch statement allows for Exceptions to be tested for, and for the graceful handling of things that may ordinarily break your application. For example, in the below code the function for square root would normally throw an exception. By placing a try/catch block around it we can mitigate that here. You may choose how you wish to handle this exception, whether logging it, return a placeholder value or as in the case below where we just printed out a statement. One thing to think about when deciding how to handle unexpected situations is that using a try/catch block is much slower than using conditional branching to handle those situations. Below there are more examples of handling exceptions with a try/catch block:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> try\n sqrt(\"ten\")\n catch e\n println(\"You should have entered a numeric value\")\n end\nYou should have entered a numeric value","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"try/catch statements also allow the Exception to be saved in a variable. The following contrived example calculates the square root of the second element of x if x is indexable, otherwise assumes x is a real number and returns its square root:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> sqrt_second(x) = try\n sqrt(x[2])\n catch y\n if isa(y, DomainError)\n sqrt(complex(x[2], 0))\n elseif isa(y, BoundsError)\n sqrt(x)\n end\n end\nsqrt_second (generic function with 1 method)\n\njulia> sqrt_second([1 4])\n2.0\n\njulia> sqrt_second([1 -4])\n0.0 + 2.0im\n\njulia> sqrt_second(9)\n3.0\n\njulia> sqrt_second(-9)\nERROR: DomainError with -9.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Note that the symbol following catch will always be interpreted as a name for the exception, so care is needed when writing try/catch expressions on a single line. The following code will not work to return the value of x in case of an error:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"try bad() catch x end","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Instead, use a semicolon or insert a line break after catch:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"try bad() catch; x end\n\ntry bad()\ncatch\n x\nend","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The power of the try/catch construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions. There are situations where no error has occurred, but the ability to unwind the stack and pass a value to a higher level is desirable. Julia provides the rethrow, backtrace, catch_backtrace and current_exceptions functions for more advanced error handling.","category":"page"},{"location":"manual/control-flow/#else-Clauses","page":"Control Flow","title":"else Clauses","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"compat: Julia 1.8\nThis functionality requires at least Julia 1.8.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"In some cases, one may not only want to appropriately handle the error case, but also want to run some code only if the try block succeeds. For this, an else clause can be specified after the catch block that is run whenever no error was thrown previously. The advantage over including this code in the try block instead is that any further errors don't get silently caught by the catch clause.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"local x\ntry\n x = read(\"file\", String)\ncatch\n # handle read errors\nelse\n # do something with x\nend","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"note: Note\nThe try, catch, else, and finally clauses each introduce their own scope blocks, so if a variable is only defined in the try block, it can not be accessed by the else or finally clause:julia> try\n foo = 1\n catch\n else\n foo\n end\nERROR: UndefVarError: `foo` not defined in `Main`\nSuggestion: check for spelling errors or missing imports.Use the local keyword outside the try block to make the variable accessible from anywhere within the outer scope.","category":"page"},{"location":"manual/control-flow/#finally-Clauses","page":"Control Flow","title":"finally Clauses","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"In code that performs state changes or uses resources like files, there is typically clean-up work (such as closing files) that needs to be done when the code is finished. Exceptions potentially complicate this task, since they can cause a block of code to exit before reaching its normal end. The finally keyword provides a way to run some code when a given block of code exits, regardless of how it exits.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"For example, here is how we can guarantee that an opened file is closed:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"f = open(\"file\")\ntry\n # operate on file f\nfinally\n close(f)\nend","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"When control leaves the try block (for example due to a return, or just finishing normally), close(f) will be executed. If the try block exits due to an exception, the exception will continue propagating. A catch block may be combined with try and finally as well. In this case the finally block will run after catch has handled the error.","category":"page"},{"location":"manual/control-flow/#man-tasks","page":"Control Flow","title":"Tasks (aka Coroutines)","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Tasks are a control flow feature that allows computations to be suspended and resumed in a flexible manner. We mention them here only for completeness; for a full discussion see Asynchronous Programming.","category":"page"},{"location":"devdocs/meta/#Talking-to-the-compiler-(the-:meta-mechanism)","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"","category":"section"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"In some circumstances, one might wish to provide hints or instructions that a given block of code has special properties: you might always want to inline it, or you might want to turn on special compiler optimization passes. Starting with version 0.4, Julia has a convention that these instructions can be placed inside a :meta expression, which is typically (but not necessarily) the first expression in the body of a function.","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":":meta expressions are created with macros. As an example, consider the implementation of the @inline macro:","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"macro inline(ex)\n esc(isa(ex, Expr) ? pushmeta!(ex, :inline) : ex)\nend","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"Here, ex is expected to be an expression defining a function. A statement like this:","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"@inline function myfunction(x)\n x*(x+3)\nend","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"gets turned into an expression like this:","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"quote\n function myfunction(x)\n Expr(:meta, :inline)\n x*(x+3)\n end\nend","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"Base.pushmeta!(ex, tag::Union{Symbol,Expr}) appends :tag to the end of the :meta expression, creating a new :meta expression if necessary.","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"To use the metadata, you have to parse these :meta expressions. If your implementation can be performed within Julia, Base.popmeta! is very handy: Base.popmeta!(body, :symbol) will scan a function body expression (one without the function signature) for the first :meta expression containing :symbol, extract any arguments, and return a tuple (found::Bool, args::Array{Any}). If the metadata did not have any arguments, or :symbol was not found, the args array will be empty.","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"Not yet provided is a convenient infrastructure for parsing :meta expressions from C++.","category":"page"},{"location":"devdocs/stdio/#printf()-and-stdio-in-the-Julia-runtime","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"","category":"section"},{"location":"devdocs/stdio/#Libuv-wrappers-for-stdio","page":"printf() and stdio in the Julia runtime","title":"Libuv wrappers for stdio","text":"","category":"section"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"julia.h defines libuv wrappers for the stdio.h streams:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"uv_stream_t *JL_STDIN;\nuv_stream_t *JL_STDOUT;\nuv_stream_t *JL_STDERR;","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"... and corresponding output functions:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"int jl_printf(uv_stream_t *s, const char *format, ...);\nint jl_vprintf(uv_stream_t *s, const char *format, va_list args);","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"These printf functions are used by the .c files in the src/ and cli/ directories wherever stdio is needed to ensure that output buffering is handled in a unified way.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"In special cases, like signal handlers, where the full libuv infrastructure is too heavy, jl_safe_printf() can be used to write(2) directly to STDERR_FILENO:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"void jl_safe_printf(const char *str, ...);","category":"page"},{"location":"devdocs/stdio/#Interface-between-JL_STD*-and-Julia-code","page":"printf() and stdio in the Julia runtime","title":"Interface between JL_STD* and Julia code","text":"","category":"section"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"Base.stdin, Base.stdout and Base.stderr are bound to the JL_STD* libuv streams defined in the runtime.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"Julia's __init__() function (in base/sysimg.jl) calls reinit_stdio() (in base/stream.jl) to create Julia objects for Base.stdin, Base.stdout and Base.stderr.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"reinit_stdio() uses ccall to retrieve pointers to JL_STD* and calls jl_uv_handle_type() to inspect the type of each stream. It then creates a Julia Base.IOStream, Base.TTY or Base.PipeEndpoint object to represent each stream, e.g.:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"$ julia -e 'println(typeof((stdin, stdout, stderr)))'\nTuple{Base.TTY,Base.TTY,Base.TTY}\n\n$ julia -e 'println(typeof((stdin, stdout, stderr)))' < /dev/null 2>/dev/null\nTuple{IOStream,Base.TTY,IOStream}\n\n$ echo hello | julia -e 'println(typeof((stdin, stdout, stderr)))' | cat\nTuple{Base.PipeEndpoint,Base.PipeEndpoint,Base.TTY}","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"The Base.read and Base.write methods for these streams use ccall to call libuv wrappers in src/jl_uv.c, e.g.:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"stream.jl: function write(s::IO, p::Ptr, nb::Integer)\n -> ccall(:jl_uv_write, ...)\n jl_uv.c: -> int jl_uv_write(uv_stream_t *stream, ...)\n -> uv_write(uvw, stream, buf, ...)","category":"page"},{"location":"devdocs/stdio/#printf()-during-initialization","page":"printf() and stdio in the Julia runtime","title":"printf() during initialization","text":"","category":"section"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"The libuv streams relied upon by jl_printf() etc., are not available until midway through initialization of the runtime (see init.c, init_stdio()). Error messages or warnings that need to be printed before this are routed to the standard C library fwrite() function by the following mechanism:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"In sys.c, the JL_STD* stream pointers are statically initialized to integer constants: STD*_FILENO (0, 1 and 2). In jl_uv.c the jl_uv_puts() function checks its uv_stream_t* stream argument and calls fwrite() if stream is set to STDOUT_FILENO or STDERR_FILENO.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"This allows for uniform use of jl_printf() throughout the runtime regardless of whether or not any particular piece of code is reachable before initialization is complete.","category":"page"},{"location":"devdocs/stdio/#Legacy-ios.c-library","page":"printf() and stdio in the Julia runtime","title":"Legacy ios.c library","text":"","category":"section"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"The src/support/ios.c library is inherited from femtolisp. It provides cross-platform buffered file IO and in-memory temporary buffers.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"ios.c is still used by:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"src/flisp/*.c\nsrc/dump.c – for serialization file IO and for memory buffers.\nsrc/staticdata.c – for serialization file IO and for memory buffers.\nbase/iostream.jl – for file IO (see base/fs.jl for libuv equivalent).","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"Use of ios.c in these modules is mostly self-contained and separated from the libuv I/O system. However, there is one place where femtolisp calls through to jl_printf() with a legacy ios_t stream.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"There is a hack in ios.h that makes the ios_t.bm field line up with the uv_stream_t.type and ensures that the values used for ios_t.bm to not overlap with valid UV_HANDLE_TYPE values. This allows uv_stream_t pointers to point to ios_t streams.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"This is needed because jl_printf() caller jl_static_show() is passed an ios_t stream by femtolisp's fl_print() function. Julia's jl_uv_puts() function has special handling for this:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"if (stream->type > UV_HANDLE_TYPE_MAX) {\n return ios_write((ios_t*)stream, str, n);\n}","category":"page"},{"location":"manual/getting-started/#man-getting-started","page":"Getting Started","title":"Getting Started","text":"","category":"section"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"Julia installation is straightforward, whether using precompiled binaries or compiling from source. Download and install Julia by following the instructions at https://julialang.org/downloads/.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"If you are coming to Julia from one of the following languages, then you should start by reading the section on noteworthy differences from MATLAB, R, Python, C/C++ or Common Lisp. This will help you avoid some common pitfalls since Julia differs from those languages in many subtle ways.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"The easiest way to learn and experiment with Julia is by starting an interactive session (also known as a read-eval-print loop or \"REPL\") by double-clicking the Julia executable or running julia from the command line:","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"using REPL\nio = IOBuffer()\nREPL.banner(io)\nbanner = String(take!(io))\nimport Markdown\nMarkdown.parse(\"```\\n\\$ julia\\n\\n$(banner)\\njulia> 1 + 2\\n3\\n\\njulia> ans\\n3\\n```\")","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"To exit the interactive session, type CTRL-D (press the Control/^ key together with the d key), or type exit(). When run in interactive mode, julia displays a banner and prompts the user for input. Once the user has entered a complete expression, such as 1 + 2, and hits enter, the interactive session evaluates the expression and shows its value. If an expression is entered into an interactive session with a trailing semicolon, its value is not shown. The variable ans is bound to the value of the last evaluated expression whether it is shown or not. The ans variable is only bound in interactive sessions, not when Julia code is run in other ways.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"To evaluate expressions written in a source file file.jl, write include(\"file.jl\").","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"To run code in a file non-interactively, you can give it as the first argument to the julia command:","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"$ julia script.jl","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"You can pass additional arguments to Julia, and to your program script.jl. A detailed list of all the available options can be found under Command-line Interface.","category":"page"},{"location":"manual/getting-started/#Resources","page":"Getting Started","title":"Resources","text":"","category":"section"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"A curated list of useful learning resources to help new users get started can be found on the learning page of the main Julia website.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"You can use the REPL as a learning resource by switching into the help mode. Switch to help mode by pressing ? at an empty julia> prompt, before typing anything else. Typing a keyword in help mode will fetch the documentation for it, along with examples. Similarly for most functions or other objects you might encounter!","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"help?> begin\nsearch: begin disable_sigint reenable_sigint\n\n begin\n\n begin...end denotes a block of code.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"If you already know Julia a bit, you might want to peek ahead at Performance Tips and Workflow Tips.","category":"page"},{"location":"devdocs/build/macos/#macOS","page":"macOS","title":"macOS","text":"","category":"section"},{"location":"devdocs/build/macos/","page":"macOS","title":"macOS","text":"You need to have the current Xcode command line utilities installed: run xcode-select --install in the terminal. You will need to rerun this terminal command after each macOS update, otherwise you may run into errors involving missing libraries or headers.","category":"page"},{"location":"devdocs/build/macos/","page":"macOS","title":"macOS","text":"The dependent libraries are now built with BinaryBuilder and will be automatically downloaded. This is the preferred way to build Julia source. In case you want to build them all on your own, you will need a 64-bit gfortran to compile Julia dependencies.","category":"page"},{"location":"devdocs/build/macos/","page":"macOS","title":"macOS","text":"brew install gcc","category":"page"},{"location":"devdocs/build/macos/","page":"macOS","title":"macOS","text":"If you have set LD_LIBRARY_PATH or DYLD_LIBRARY_PATH in your .bashrc or equivalent, Julia may be unable to find various libraries that come bundled with it. These environment variables need to be unset for Julia to work.","category":"page"},{"location":"manual/types/#man-types","page":"Types","title":"Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type systems have traditionally fallen into two quite different camps: static type systems, where every program expression must have a type computable before the execution of the program, and dynamic type systems, where nothing is known about types until run time, when the actual values manipulated by the program are available. Object orientation allows some flexibility in statically typed languages by letting code be written without the precise types of values being known at compile time. The ability to write code that can operate on different types is called polymorphism. All code in classic dynamically typed languages is polymorphic: only by explicitly checking types, or when objects fail to support operations at run-time, are the types of any values ever restricted.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Julia's type system is dynamic, but gains some of the advantages of static type systems by making it possible to indicate that certain values are of specific types. This can be of great assistance in generating efficient code, but even more significantly, it allows method dispatch on the types of function arguments to be deeply integrated with the language. Method dispatch is explored in detail in Methods, but is rooted in the type system presented here.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The default behavior in Julia when types are omitted is to allow values to be of any type. Thus, one can write many useful Julia functions without ever explicitly using types. When additional expressiveness is needed, however, it is easy to gradually introduce explicit type annotations into previously \"untyped\" code. Adding annotations serves three primary purposes: to take advantage of Julia's powerful multiple-dispatch mechanism, to improve human readability, and to catch programmer errors.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Describing Julia in the lingo of type systems, it is: dynamic, nominative and parametric. Generic types can be parameterized, and the hierarchical relationships between types are explicitly declared, rather than implied by compatible structure. One particularly distinctive feature of Julia's type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes. While this might at first seem unduly restrictive, it has many beneficial consequences with surprisingly few drawbacks. It turns out that being able to inherit behavior is much more important than being able to inherit structure, and inheriting both causes significant difficulties in traditional object-oriented languages. Other high-level aspects of Julia's type system that should be mentioned up front are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There is no division between object and non-object values: all values in Julia are true objects having a type that belongs to a single, fully connected type graph, all nodes of which are equally first-class as types.\nThere is no meaningful concept of a \"compile-time type\": the only type a value has is its actual type when the program is running. This is called a \"run-time type\" in object-oriented languages where the combination of static compilation with polymorphism makes this distinction significant.\nOnly values, not variables, have types – variables are simply names bound to values, although for simplicity we may say \"type of a variable\" as shorthand for \"type of the value to which a variable refers\".\nBoth abstract and concrete types can be parameterized by other types. They can also be parameterized by symbols, by values of any type for which isbits returns true (essentially, things like numbers and bools that are stored like C types or structs with no pointers to other objects), and also by tuples thereof. Type parameters may be omitted when they do not need to be referenced or restricted.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Julia's type system is designed to be powerful and expressive, yet clear, intuitive and unobtrusive. Many Julia programmers may never feel the need to write code that explicitly uses types. Some kinds of programming, however, become clearer, simpler, faster and more robust with declared types.","category":"page"},{"location":"manual/types/#Type-Declarations","page":"Types","title":"Type Declarations","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"The :: operator can be used to attach type annotations to expressions and variables in programs. There are two primary reasons to do this:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"As an assertion to help confirm that your program works the way you expect, and\nTo provide extra type information to the compiler, which can then improve performance in some cases.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"When appended to an expression computing a value, the :: operator is read as \"is an instance of\". It can be used anywhere to assert that the value of the expression on the left is an instance of the type on the right. When the type on the right is concrete, the value on the left must have that type as its implementation – recall that all concrete types are final, so no implementation is a subtype of any other. When the type is abstract, it suffices for the value to be implemented by a concrete type that is a subtype of the abstract type. If the type assertion is not true, an exception is thrown, otherwise, the left-hand value is returned:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> (1+2)::AbstractFloat\nERROR: TypeError: in typeassert, expected AbstractFloat, got a value of type Int64\n\njulia> (1+2)::Int\n3","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This allows a type assertion to be attached to any expression in-place.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"When appended to a variable on the left-hand side of an assignment, or as part of a local declaration, the :: operator means something a bit different: it declares the variable to always have the specified type, like a type declaration in a statically-typed language such as C. Every value assigned to the variable will be converted to the declared type using convert:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> function foo()\n x::Int8 = 100\n x\n end\nfoo (generic function with 1 method)\n\njulia> x = foo()\n100\n\njulia> typeof(x)\nInt8","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This feature is useful for avoiding performance \"gotchas\" that could occur if one of the assignments to a variable changed its type unexpectedly.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This \"declaration\" behavior only occurs in specific contexts:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"local x::Int8 # in a local declaration\nx::Int8 = 10 # as the left-hand side of an assignment","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"and applies to the whole current scope, even before the declaration.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"As of Julia 1.8, type declarations can now be used in global scope i.e. type annotations can be added to global variables to make accessing them type stable.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> x::Int = 10\n10\n\njulia> x = 3.5\nERROR: InexactError: Int64(3.5)\n\njulia> function foo(y)\n global x = 15.8 # throws an error when foo is called\n return x + y\n end\nfoo (generic function with 1 method)\n\njulia> foo(10)\nERROR: InexactError: Int64(15.8)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Declarations can also be attached to function definitions:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function sinc(x)::Float64\n if x == 0\n return 1\n end\n return sin(pi*x)/(pi*x)\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Returning from this function behaves just like an assignment to a variable with a declared type: the value is always converted to Float64.","category":"page"},{"location":"manual/types/#man-abstract-types","page":"Types","title":"Abstract Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Abstract types cannot be instantiated, and serve only as nodes in the type graph, thereby describing sets of related concrete types: those concrete types which are their descendants. We begin with abstract types even though they have no instantiation because they are the backbone of the type system: they form the conceptual hierarchy which makes Julia's type system more than just a collection of object implementations.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Recall that in Integers and Floating-Point Numbers, we introduced a variety of concrete types of numeric values: Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, Float16, Float32, and Float64. Although they have different representation sizes, Int8, Int16, Int32, Int64 and Int128 all have in common that they are signed integer types. Likewise UInt8, UInt16, UInt32, UInt64 and UInt128 are all unsigned integer types, while Float16, Float32 and Float64 are distinct in being floating-point types rather than integers. It is common for a piece of code to make sense, for example, only if its arguments are some kind of integer, but not really depend on what particular kind of integer. For example, the greatest common denominator algorithm works for all kinds of integers, but will not work for floating-point numbers. Abstract types allow the construction of a hierarchy of types, providing a context into which concrete types can fit. This allows you, for example, to easily program to any type that is an integer, without restricting an algorithm to a specific type of integer.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Abstract types are declared using the abstract type keyword. The general syntaxes for declaring an abstract type are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"abstract type «name» end\nabstract type «name» <: «supertype» end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The abstract type keyword introduces a new abstract type, whose name is given by «name». This name can be optionally followed by <: and an already-existing type, indicating that the newly declared abstract type is a subtype of this \"parent\" type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"When no supertype is given, the default supertype is Any – a predefined abstract type that all objects are instances of and all types are subtypes of. In type theory, Any is commonly called \"top\" because it is at the apex of the type graph. Julia also has a predefined abstract \"bottom\" type, at the nadir of the type graph, which is written as Union{}. It is the exact opposite of Any: no object is an instance of Union{} and all types are supertypes of Union{}.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Let's consider some of the abstract types that make up Julia's numerical hierarchy:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"abstract type Number end\nabstract type Real <: Number end\nabstract type AbstractFloat <: Real end\nabstract type Integer <: Real end\nabstract type Signed <: Integer end\nabstract type Unsigned <: Integer end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The Number type is a direct child type of Any, and Real is its child. In turn, Real has two children (it has more, but only two are shown here; we'll get to the others later): Integer and AbstractFloat, separating the world into representations of integers and representations of real numbers. Representations of real numbers include floating-point types, but also include other types, such as rationals. AbstractFloat includes only floating-point representations of real numbers. Integers are further subdivided into Signed and Unsigned varieties.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The <: operator in general means \"is a subtype of\", and, used in declarations like those above, declares the right-hand type to be an immediate supertype of the newly declared type. It can also be used in expressions as a subtype operator which returns true when its left operand is a subtype of its right operand:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Integer <: Number\ntrue\n\njulia> Integer <: AbstractFloat\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An important use of abstract types is to provide default implementations for concrete types. To give a simple example, consider:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function myplus(x,y)\n x+y\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The first thing to note is that the above argument declarations are equivalent to x::Any and y::Any. When this function is invoked, say as myplus(2,5), the dispatcher chooses the most specific method named myplus that matches the given arguments. (See Methods for more information on multiple dispatch.)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Assuming no method more specific than the above is found, Julia next internally defines and compiles a method called myplus specifically for two Int arguments based on the generic function given above, i.e., it implicitly defines and compiles:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function myplus(x::Int,y::Int)\n x+y\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"and finally, it invokes this specific method.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Thus, abstract types allow programmers to write generic functions that can later be used as the default method by many combinations of concrete types. Thanks to multiple dispatch, the programmer has full control over whether the default or more specific method is used.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An important point to note is that there is no loss in performance if the programmer relies on a function whose arguments are abstract types, because it is recompiled for each tuple of concrete argument types with which it is invoked. (There may be a performance issue, however, in the case of function arguments that are containers of abstract types; see Performance Tips.)","category":"page"},{"location":"manual/types/#Primitive-Types","page":"Types","title":"Primitive Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"warning: Warning\nIt is almost always preferable to wrap an existing primitive type in a new composite type than to define your own primitive type.This functionality exists to allow Julia to bootstrap the standard primitive types that LLVM supports. Once they are defined, there is very little reason to define more.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A primitive type is a concrete type whose data consists of plain old bits. Classic examples of primitive types are integers and floating-point values. Unlike most languages, Julia lets you declare your own primitive types, rather than providing only a fixed set of built-in ones. In fact, the standard primitive types are all defined in the language itself:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"primitive type Float16 <: AbstractFloat 16 end\nprimitive type Float32 <: AbstractFloat 32 end\nprimitive type Float64 <: AbstractFloat 64 end\n\nprimitive type Bool <: Integer 8 end\nprimitive type Char <: AbstractChar 32 end\n\nprimitive type Int8 <: Signed 8 end\nprimitive type UInt8 <: Unsigned 8 end\nprimitive type Int16 <: Signed 16 end\nprimitive type UInt16 <: Unsigned 16 end\nprimitive type Int32 <: Signed 32 end\nprimitive type UInt32 <: Unsigned 32 end\nprimitive type Int64 <: Signed 64 end\nprimitive type UInt64 <: Unsigned 64 end\nprimitive type Int128 <: Signed 128 end\nprimitive type UInt128 <: Unsigned 128 end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The general syntaxes for declaring a primitive type are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"primitive type «name» «bits» end\nprimitive type «name» <: «supertype» «bits» end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The number of bits indicates how much storage the type requires and the name gives the new type a name. A primitive type can optionally be declared to be a subtype of some supertype. If a supertype is omitted, then the type defaults to having Any as its immediate supertype. The declaration of Bool above therefore means that a boolean value takes eight bits to store, and has Integer as its immediate supertype. Currently, only sizes that are multiples of 8 bits are supported and you are likely to experience LLVM bugs with sizes other than those used above. Therefore, boolean values, although they really need just a single bit, cannot be declared to be any smaller than eight bits.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The types Bool, Int8 and UInt8 all have identical representations: they are eight-bit chunks of memory. Since Julia's type system is nominative, however, they are not interchangeable despite having identical structure. A fundamental difference between them is that they have different supertypes: Bool's direct supertype is Integer, Int8's is Signed, and UInt8's is Unsigned. All other differences between Bool, Int8, and UInt8 are matters of behavior – the way functions are defined to act when given objects of these types as arguments. This is why a nominative type system is necessary: if structure determined type, which in turn dictates behavior, then it would be impossible to make Bool behave any differently than Int8 or UInt8.","category":"page"},{"location":"manual/types/#Composite-Types","page":"Types","title":"Composite Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Composite types are called records, structs, or objects in various languages. A composite type is a collection of named fields, an instance of which can be treated as a single value. In many languages, composite types are the only kind of user-definable type, and they are by far the most commonly used user-defined type in Julia as well.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In mainstream object oriented languages, such as C++, Java, Python and Ruby, composite types also have named functions associated with them, and the combination is called an \"object\". In purer object-oriented languages, such as Ruby or Smalltalk, all values are objects whether they are composites or not. In less pure object oriented languages, including C++ and Java, some values, such as integers and floating-point values, are not objects, while instances of user-defined composite types are true objects with associated methods. In Julia, all values are objects, but functions are not bundled with the objects they operate on. This is necessary since Julia chooses which method of a function to use by multiple dispatch, meaning that the types of all of a function's arguments are considered when selecting a method, rather than just the first one (see Methods for more information on methods and dispatch). Thus, it would be inappropriate for functions to \"belong\" to only their first argument. Organizing methods into function objects rather than having named bags of methods \"inside\" each object ends up being a highly beneficial aspect of the language design.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Composite types are introduced with the struct keyword followed by a block of field names, optionally annotated with types using the :: operator:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Foo\n bar\n baz::Int\n qux::Float64\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Fields with no type annotation default to Any, and can accordingly hold any type of value.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"New objects of type Foo are created by applying the Foo type object like a function to values for its fields:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> foo = Foo(\"Hello, world.\", 23, 1.5)\nFoo(\"Hello, world.\", 23, 1.5)\n\njulia> typeof(foo)\nFoo","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"When a type is applied like a function it is called a constructor. Two constructors are generated automatically (these are called default constructors). One accepts any arguments and calls convert to convert them to the types of the fields, and the other accepts arguments that match the field types exactly. The reason both of these are generated is that this makes it easier to add new definitions without inadvertently replacing a default constructor.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since the bar field is unconstrained in type, any value will do. However, the value for baz must be convertible to Int:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Foo((), 23.5, 1)\nERROR: InexactError: Int64(23.5)\nStacktrace:\n[...]","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"You may find a list of field names using the fieldnames function.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> fieldnames(Foo)\n(:bar, :baz, :qux)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"You can access the field values of a composite object using the traditional foo.bar notation:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> foo.bar\n\"Hello, world.\"\n\njulia> foo.baz\n23\n\njulia> foo.qux\n1.5","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Composite objects declared with struct are immutable; they cannot be modified after construction. This may seem odd at first, but it has several advantages:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"It can be more efficient. Some structs can be packed efficiently into arrays, and in some cases the compiler is able to avoid allocating immutable objects entirely.\nIt is not possible to violate the invariants provided by the type's constructors.\nCode using immutable objects can be easier to reason about.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An immutable object might contain mutable objects, such as arrays, as fields. Those contained objects will remain mutable; only the fields of the immutable object itself cannot be changed to point to different objects.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Where required, mutable composite objects can be declared with the keyword mutable struct, to be discussed in the next section.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"If all the fields of an immutable structure are indistinguishable (===) then two immutable values containing those fields are also indistinguishable:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct X\n a::Int\n b::Float64\n end\n\njulia> X(1, 2) === X(1, 2)\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There is much more to say about how instances of composite types are created, but that discussion depends on both Parametric Types and on Methods, and is sufficiently important to be addressed in its own section: Constructors.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"For many user-defined types X, you may want to define a method Base.broadcastable(x::X) = Ref(x) so that instances of that type act as 0-dimensional \"scalars\" for broadcasting.","category":"page"},{"location":"manual/types/#Mutable-Composite-Types","page":"Types","title":"Mutable Composite Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"If a composite type is declared with mutable struct instead of struct, then instances of it can be modified:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> mutable struct Bar\n baz\n qux::Float64\n end\n\njulia> bar = Bar(\"Hello\", 1.5);\n\njulia> bar.qux = 2.0\n2.0\n\njulia> bar.baz = 1//2\n1//2","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An extra interface between the fields and the user can be provided through Instance Properties. This grants more control on what can be accessed and modified using the bar.baz notation.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In order to support mutation, such objects are generally allocated on the heap, and have stable memory addresses. A mutable object is like a little container that might hold different values over time, and so can only be reliably identified with its address. In contrast, an instance of an immutable type is associated with specific field values –- the field values alone tell you everything about the object. In deciding whether to make a type mutable, ask whether two instances with the same field values would be considered identical, or if they might need to change independently over time. If they would be considered identical, the type should probably be immutable.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"To recap, two essential properties define immutability in Julia:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"It is not permitted to modify the value of an immutable type.\nFor bits types this means that the bit pattern of a value once set will never change and that value is the identity of a bits type.\nFor composite types, this means that the identity of the values of its fields will never change. When the fields are bits types, that means their bits will never change, for fields whose values are mutable types like arrays, that means the fields will always refer to the same mutable value even though that mutable value's content may itself be modified.\nAn object with an immutable type may be copied freely by the compiler since its immutability makes it impossible to programmatically distinguish between the original object and a copy.\nIn particular, this means that small enough immutable values like integers and floats are typically passed to functions in registers (or stack allocated).\nMutable values, on the other hand are heap-allocated and passed to functions as pointers to heap-allocated values except in cases where the compiler is sure that there's no way to tell that this is not what is happening.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In cases where one or more fields of an otherwise mutable struct is known to be immutable, one can declare these fields as such using const as shown below. This enables some, but not all of the optimizations of immutable structs, and can be used to enforce invariants on the particular fields marked as const.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"compat: Julia 1.8\nconst annotating fields of mutable structs requires at least Julia 1.8.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> mutable struct Baz\n a::Int\n const b::Float64\n end\n\njulia> baz = Baz(1, 1.5);\n\njulia> baz.a = 2\n2\n\njulia> baz.b = 2.0\nERROR: setfield!: const field .b of type Baz cannot be changed\n[...]","category":"page"},{"location":"manual/types/#man-declared-types","page":"Types","title":"Declared Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"The three kinds of types (abstract, primitive, composite) discussed in the previous sections are actually all closely related. They share the same key properties:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"They are explicitly declared.\nThey have names.\nThey have explicitly declared supertypes.\nThey may have parameters.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Because of these shared properties, these types are internally represented as instances of the same concept, DataType, which is the type of any of these types:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof(Real)\nDataType\n\njulia> typeof(Int)\nDataType","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A DataType may be abstract or concrete. If it is concrete, it has a specified size, storage layout, and (optionally) field names. Thus a primitive type is a DataType with nonzero size, but no field names. A composite type is a DataType that has field names or is empty (zero size).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Every concrete value in the system is an instance of some DataType.","category":"page"},{"location":"manual/types/#Type-Unions","page":"Types","title":"Type Unions","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"A type union is a special abstract type which includes as objects all instances of any of its argument types, constructed using the special Union keyword:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> IntOrString = Union{Int,AbstractString}\nUnion{Int64, AbstractString}\n\njulia> 1 :: IntOrString\n1\n\njulia> \"Hello!\" :: IntOrString\n\"Hello!\"\n\njulia> 1.0 :: IntOrString\nERROR: TypeError: in typeassert, expected Union{Int64, AbstractString}, got a value of type Float64","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The compilers for many languages have an internal union construct for reasoning about types; Julia simply exposes it to the programmer. The Julia compiler is able to generate efficient code in the presence of Union types with a small number of types [1], by generating specialized code in separate branches for each possible type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A particularly useful case of a Union type is Union{T, Nothing}, where T can be any type and Nothing is the singleton type whose only instance is the object nothing. This pattern is the Julia equivalent of Nullable, Option or Maybe types in other languages. Declaring a function argument or a field as Union{T, Nothing} allows setting it either to a value of type T, or to nothing to indicate that there is no value. See this FAQ entry for more information.","category":"page"},{"location":"manual/types/#Parametric-Types","page":"Types","title":"Parametric Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"An important and powerful feature of Julia's type system is that it is parametric: types can take parameters, so that type declarations actually introduce a whole family of new types – one for each possible combination of parameter values. There are many languages that support some version of generic programming, wherein data structures and algorithms to manipulate them may be specified without specifying the exact types involved. For example, some form of generic programming exists in ML, Haskell, Ada, Eiffel, C++, Java, C#, F#, and Scala, just to name a few. Some of these languages support true parametric polymorphism (e.g. ML, Haskell, Scala), while others support ad-hoc, template-based styles of generic programming (e.g. C++, Java). With so many different varieties of generic programming and parametric types in various languages, we won't even attempt to compare Julia's parametric types to other languages, but will instead focus on explaining Julia's system in its own right. We will note, however, that because Julia is a dynamically typed language and doesn't need to make all type decisions at compile time, many traditional difficulties encountered in static parametric type systems can be relatively easily handled.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"All declared types (the DataType variety) can be parameterized, with the same syntax in each case. We will discuss them in the following order: first, parametric composite types, then parametric abstract types, and finally parametric primitive types.","category":"page"},{"location":"manual/types/#man-parametric-composite-types","page":"Types","title":"Parametric Composite Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type parameters are introduced immediately after the type name, surrounded by curly braces:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Point{T}\n x::T\n y::T\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This declaration defines a new parametric type, Point{T}, holding two \"coordinates\" of type T. What, one may ask, is T? Well, that's precisely the point of parametric types: it can be any type at all (or a value of any bits type, actually, although here it's clearly used as a type). Point{Float64} is a concrete type equivalent to the type defined by replacing T in the definition of Point with Float64. Thus, this single declaration actually declares an unlimited number of types: Point{Float64}, Point{AbstractString}, Point{Int64}, etc. Each of these is now a usable concrete type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64}\nPoint{Float64}\n\njulia> Point{AbstractString}\nPoint{AbstractString}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The type Point{Float64} is a point whose coordinates are 64-bit floating-point values, while the type Point{AbstractString} is a \"point\" whose \"coordinates\" are string objects (see Strings).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Point itself is also a valid type object, containing all instances Point{Float64}, Point{AbstractString}, etc. as subtypes:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64} <: Point\ntrue\n\njulia> Point{AbstractString} <: Point\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Other types, of course, are not subtypes of it:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Float64 <: Point\nfalse\n\njulia> AbstractString <: Point\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Concrete Point types with different values of T are never subtypes of each other:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64} <: Point{Int64}\nfalse\n\njulia> Point{Float64} <: Point{Real}\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"warning: Warning\nThis last point is very important: even though Float64 <: Real we DO NOT have Point{Float64} <: Point{Real}.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In other words, in the parlance of type theory, Julia's type parameters are invariant, rather than being covariant (or even contravariant). This is for practical reasons: while any instance of Point{Float64} may conceptually be like an instance of Point{Real} as well, the two types have different representations in memory:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An instance of Point{Float64} can be represented compactly and efficiently as an immediate pair of 64-bit values;\nAn instance of Point{Real} must be able to hold any pair of instances of Real. Since objects that are instances of Real can be of arbitrary size and structure, in practice an instance of Point{Real} must be represented as a pair of pointers to individually allocated Real objects.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The efficiency gained by being able to store Point{Float64} objects with immediate values is magnified enormously in the case of arrays: an Array{Float64} can be stored as a contiguous memory block of 64-bit floating-point values, whereas an Array{Real} must be an array of pointers to individually allocated Real objects – which may well be boxed 64-bit floating-point values, but also might be arbitrarily large, complex objects, which are declared to be implementations of the Real abstract type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since Point{Float64} is not a subtype of Point{Real}, the following method can't be applied to arguments of type Point{Float64}:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function norm(p::Point{Real})\n sqrt(p.x^2 + p.y^2)\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A correct way to define a method that accepts all arguments of type Point{T} where T is a subtype of Real is:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function norm(p::Point{<:Real})\n sqrt(p.x^2 + p.y^2)\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"(Equivalently, one could define function norm(p::Point{T} where T<:Real) or function norm(p::Point{T}) where T<:Real; see UnionAll Types.)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"More examples will be discussed later in Methods.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"How does one construct a Point object? It is possible to define custom constructors for composite types, which will be discussed in detail in Constructors, but in the absence of any special constructor declarations, there are two default ways of creating new composite objects, one in which the type parameters are explicitly given and the other in which they are implied by the arguments to the object constructor.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since the type Point{Float64} is a concrete type equivalent to Point declared with Float64 in place of T, it can be applied as a constructor accordingly:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> p = Point{Float64}(1.0, 2.0)\nPoint{Float64}(1.0, 2.0)\n\njulia> typeof(p)\nPoint{Float64}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"For the default constructor, exactly one argument must be supplied for each field:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64}(1.0)\nERROR: MethodError: no method matching Point{Float64}(::Float64)\nThe type `Point{Float64}` exists, but no method is defined for this combination of argument types when trying to construct it.\n[...]\n\njulia> Point{Float64}(1.0, 2.0, 3.0)\nERROR: MethodError: no method matching Point{Float64}(::Float64, ::Float64, ::Float64)\nThe type `Point{Float64}` exists, but no method is defined for this combination of argument types when trying to construct it.\n[...]","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Only one default constructor is generated for parametric types, since overriding it is not possible. This constructor accepts any arguments and converts them to the field types.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In many cases, it is redundant to provide the type of Point object one wants to construct, since the types of arguments to the constructor call already implicitly provide type information. For that reason, you can also apply Point itself as a constructor, provided that the implied value of the parameter type T is unambiguous:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> p1 = Point(1.0,2.0)\nPoint{Float64}(1.0, 2.0)\n\njulia> typeof(p1)\nPoint{Float64}\n\njulia> p2 = Point(1,2)\nPoint{Int64}(1, 2)\n\njulia> typeof(p2)\nPoint{Int64}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In the case of Point, the type of T is unambiguously implied if and only if the two arguments to Point have the same type. When this isn't the case, the constructor will fail with a MethodError:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point(1,2.5)\nERROR: MethodError: no method matching Point(::Int64, ::Float64)\nThe type `Point` exists, but no method is defined for this combination of argument types when trying to construct it.\n\nClosest candidates are:\n Point(::T, !Matched::T) where T\n @ Main none:2\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Constructor methods to appropriately handle such mixed cases can be defined, but that will not be discussed until later on in Constructors.","category":"page"},{"location":"manual/types/#Parametric-Abstract-Types","page":"Types","title":"Parametric Abstract Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Parametric abstract type declarations declare a collection of abstract types, in much the same way:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> abstract type Pointy{T} end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"With this declaration, Pointy{T} is a distinct abstract type for each type or integer value of T. As with parametric composite types, each such instance is a subtype of Pointy:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Pointy{Int64} <: Pointy\ntrue\n\njulia> Pointy{1} <: Pointy\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Parametric abstract types are invariant, much as parametric composite types are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Pointy{Float64} <: Pointy{Real}\nfalse\n\njulia> Pointy{Real} <: Pointy{Float64}\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The notation Pointy{<:Real} can be used to express the Julia analogue of a covariant type, while Pointy{>:Int} the analogue of a contravariant type, but technically these represent sets of types (see UnionAll Types).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Pointy{Float64} <: Pointy{<:Real}\ntrue\n\njulia> Pointy{Real} <: Pointy{>:Int}\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Much as plain old abstract types serve to create a useful hierarchy of types over concrete types, parametric abstract types serve the same purpose with respect to parametric composite types. We could, for example, have declared Point{T} to be a subtype of Pointy{T} as follows:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Point{T} <: Pointy{T}\n x::T\n y::T\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Given such a declaration, for each choice of T, we have Point{T} as a subtype of Pointy{T}:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64} <: Pointy{Float64}\ntrue\n\njulia> Point{Real} <: Pointy{Real}\ntrue\n\njulia> Point{AbstractString} <: Pointy{AbstractString}\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This relationship is also invariant:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64} <: Pointy{Real}\nfalse\n\njulia> Point{Float64} <: Pointy{<:Real}\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"What purpose do parametric abstract types like Pointy serve? Consider if we create a point-like implementation that only requires a single coordinate because the point is on the diagonal line x = y:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct DiagPoint{T} <: Pointy{T}\n x::T\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Now both Point{Float64} and DiagPoint{Float64} are implementations of the Pointy{Float64} abstraction, and similarly for every other possible choice of type T. This allows programming to a common interface shared by all Pointy objects, implemented for both Point and DiagPoint. This cannot be fully demonstrated, however, until we have introduced methods and dispatch in the next section, Methods.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There are situations where it may not make sense for type parameters to range freely over all possible types. In such situations, one can constrain the range of T like so:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> abstract type Pointy{T<:Real} end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"With such a declaration, it is acceptable to use any type that is a subtype of Real in place of T, but not types that are not subtypes of Real:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Pointy{Float64}\nPointy{Float64}\n\njulia> Pointy{Real}\nPointy{Real}\n\njulia> Pointy{AbstractString}\nERROR: TypeError: in Pointy, in T, expected T<:Real, got Type{AbstractString}\n\njulia> Pointy{1}\nERROR: TypeError: in Pointy, in T, expected T<:Real, got a value of type Int64","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type parameters for parametric composite types can be restricted in the same manner:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"struct Point{T<:Real} <: Pointy{T}\n x::T\n y::T\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"To give a real-world example of how all this parametric type machinery can be useful, here is the actual definition of Julia's Rational immutable type (except that we omit the constructor here for simplicity), representing an exact ratio of integers:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"struct Rational{T<:Integer} <: Real\n num::T\n den::T\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"It only makes sense to take ratios of integer values, so the parameter type T is restricted to being a subtype of Integer, and a ratio of integers represents a value on the real number line, so any Rational is an instance of the Real abstraction.","category":"page"},{"location":"manual/types/#Tuple-Types","page":"Types","title":"Tuple Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Tuples are an abstraction of the arguments of a function – without the function itself. The salient aspects of a function's arguments are their order and their types. Therefore a tuple type is similar to a parameterized immutable type where each parameter is the type of one field. For example, a 2-element tuple type resembles the following immutable type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"struct Tuple2{A,B}\n a::A\n b::B\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"However, there are three key differences:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Tuple types may have any number of parameters.\nTuple types are covariant in their parameters: Tuple{Int} is a subtype of Tuple{Any}. Therefore Tuple{Any} is considered an abstract type, and tuple types are only concrete if their parameters are.\nTuples do not have field names; fields are only accessed by index.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Tuple values are written with parentheses and commas. When a tuple is constructed, an appropriate tuple type is generated on demand:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof((1,\"foo\",2.5))\nTuple{Int64, String, Float64}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Note the implications of covariance:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Tuple{Int,AbstractString} <: Tuple{Real,Any}\ntrue\n\njulia> Tuple{Int,AbstractString} <: Tuple{Real,Real}\nfalse\n\njulia> Tuple{Int,AbstractString} <: Tuple{Real,}\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Intuitively, this corresponds to the type of a function's arguments being a subtype of the function's signature (when the signature matches).","category":"page"},{"location":"manual/types/#Vararg-Tuple-Types","page":"Types","title":"Vararg Tuple Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"The last parameter of a tuple type can be the special value Vararg, which denotes any number of trailing elements:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> mytupletype = Tuple{AbstractString,Vararg{Int}}\nTuple{AbstractString, Vararg{Int64}}\n\njulia> isa((\"1\",), mytupletype)\ntrue\n\njulia> isa((\"1\",1), mytupletype)\ntrue\n\njulia> isa((\"1\",1,2), mytupletype)\ntrue\n\njulia> isa((\"1\",1,2,3.0), mytupletype)\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Moreover Vararg{T} corresponds to zero or more elements of type T. Vararg tuple types are used to represent the arguments accepted by varargs methods (see Varargs Functions).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The special value Vararg{T,N} (when used as the last parameter of a tuple type) corresponds to exactly N elements of type T. NTuple{N,T} is a convenient alias for Tuple{Vararg{T,N}}, i.e. a tuple type containing exactly N elements of type T.","category":"page"},{"location":"manual/types/#Named-Tuple-Types","page":"Types","title":"Named Tuple Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Named tuples are instances of the NamedTuple type, which has two parameters: a tuple of symbols giving the field names, and a tuple type giving the field types. For convenience, NamedTuple types are printed using the @NamedTuple macro which provides a convenient struct-like syntax for declaring these types via key::Type declarations, where an omitted ::Type corresponds to ::Any.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof((a=1,b=\"hello\")) # prints in macro form\n@NamedTuple{a::Int64, b::String}\n\njulia> NamedTuple{(:a, :b), Tuple{Int64, String}} # long form of the type\n@NamedTuple{a::Int64, b::String}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The begin ... end form of the @NamedTuple macro allows the declarations to be split across multiple lines (similar to a struct declaration), but is otherwise equivalent:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> @NamedTuple begin\n a::Int\n b::String\n end\n@NamedTuple{a::Int64, b::String}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A NamedTuple type can be used as a constructor, accepting a single tuple argument. The constructed NamedTuple type can be either a concrete type, with both parameters specified, or a type that specifies only field names:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> @NamedTuple{a::Float32,b::String}((1, \"\"))\n(a = 1.0f0, b = \"\")\n\njulia> NamedTuple{(:a, :b)}((1, \"\"))\n(a = 1, b = \"\")","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"If field types are specified, the arguments are converted. Otherwise the types of the arguments are used directly.","category":"page"},{"location":"manual/types/#Parametric-Primitive-Types","page":"Types","title":"Parametric Primitive Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Primitive types can also be declared parametrically. For example, pointers are represented as primitive types which would be declared in Julia like this:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"# 32-bit system:\nprimitive type Ptr{T} 32 end\n\n# 64-bit system:\nprimitive type Ptr{T} 64 end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The slightly odd feature of these declarations as compared to typical parametric composite types, is that the type parameter T is not used in the definition of the type itself – it is just an abstract tag, essentially defining an entire family of types with identical structure, differentiated only by their type parameter. Thus, Ptr{Float64} and Ptr{Int64} are distinct types, even though they have identical representations. And of course, all specific pointer types are subtypes of the umbrella Ptr type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Ptr{Float64} <: Ptr\ntrue\n\njulia> Ptr{Int64} <: Ptr\ntrue","category":"page"},{"location":"manual/types/#UnionAll-Types","page":"Types","title":"UnionAll Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"We have said that a parametric type like Ptr acts as a supertype of all its instances (Ptr{Int64} etc.). How does this work? Ptr itself cannot be a normal data type, since without knowing the type of the referenced data the type clearly cannot be used for memory operations. The answer is that Ptr (or other parametric types like Array) is a different kind of type called a UnionAll type. Such a type expresses the iterated union of types for all values of some parameter.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"UnionAll types are usually written using the keyword where. For example Ptr could be more accurately written as Ptr{T} where T, meaning all values whose type is Ptr{T} for some value of T. In this context, the parameter T is also often called a \"type variable\" since it is like a variable that ranges over types. Each where introduces a single type variable, so these expressions are nested for types with multiple parameters, for example Array{T,N} where N where T.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The type application syntax A{B,C} requires A to be a UnionAll type, and first substitutes B for the outermost type variable in A. The result is expected to be another UnionAll type, into which C is then substituted. So A{B,C} is equivalent to A{B}{C}. This explains why it is possible to partially instantiate a type, as in Array{Float64}: the first parameter value has been fixed, but the second still ranges over all possible values. Using explicit where syntax, any subset of parameters can be fixed. For example, the type of all 1-dimensional arrays can be written as Array{T,1} where T.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type variables can be restricted with subtype relations. Array{T} where T<:Integer refers to all arrays whose element type is some kind of Integer. The syntax Array{<:Integer} is a convenient shorthand for Array{T} where T<:Integer. Type variables can have both lower and upper bounds. Array{T} where Int<:T<:Number refers to all arrays of Numbers that are able to contain Ints (since T must be at least as big as Int). The syntax where T>:Int also works to specify only the lower bound of a type variable, and Array{>:Int} is equivalent to Array{T} where T>:Int.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since where expressions nest, type variable bounds can refer to outer type variables. For example Tuple{T,Array{S}} where S<:AbstractArray{T} where T<:Real refers to 2-tuples whose first element is some Real, and whose second element is an Array of any kind of array whose element type contains the type of the first tuple element.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The where keyword itself can be nested inside a more complex declaration. For example, consider the two types created by the following declarations:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> const T1 = Array{Array{T, 1} where T, 1}\nVector{Vector} (alias for Array{Array{T, 1} where T, 1})\n\njulia> const T2 = Array{Array{T, 1}, 1} where T\nArray{Vector{T}, 1} where T","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type T1 defines a 1-dimensional array of 1-dimensional arrays; each of the inner arrays consists of objects of the same type, but this type may vary from one inner array to the next. On the other hand, type T2 defines a 1-dimensional array of 1-dimensional arrays all of whose inner arrays must have the same type. Note that T2 is an abstract type, e.g., Array{Array{Int,1},1} <: T2, whereas T1 is a concrete type. As a consequence, T1 can be constructed with a zero-argument constructor a=T1() but T2 cannot.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There is a convenient syntax for naming such types, similar to the short form of function definition syntax:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Vector{T} = Array{T, 1}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This is equivalent to const Vector = Array{T,1} where T. Writing Vector{Float64} is equivalent to writing Array{Float64,1}, and the umbrella type Vector has as instances all Array objects where the second parameter – the number of array dimensions – is 1, regardless of what the element type is. In languages where parametric types must always be specified in full, this is not especially helpful, but in Julia, this allows one to write just Vector for the abstract type including all one-dimensional dense arrays of any element type.","category":"page"},{"location":"manual/types/#man-singleton-types","page":"Types","title":"Singleton types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Immutable composite types with no fields are called singletons. Formally, if","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"T is an immutable composite type (i.e. defined with struct),\na isa T && b isa T implies a === b,","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"then T is a singleton type.[2] Base.issingletontype can be used to check if a type is a singleton type. Abstract types cannot be singleton types by construction.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"From the definition, it follows that there can be only one instance of such types:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct NoFields\n end\n\njulia> NoFields() === NoFields()\ntrue\n\njulia> Base.issingletontype(NoFields)\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The === function confirms that the constructed instances of NoFields are actually one and the same.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Parametric types can be singleton types when the above condition holds. For example,","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct NoFieldsParam{T}\n end\n\njulia> Base.issingletontype(NoFieldsParam) # Can't be a singleton type ...\nfalse\n\njulia> NoFieldsParam{Int}() isa NoFieldsParam # ... because it has ...\ntrue\n\njulia> NoFieldsParam{Bool}() isa NoFieldsParam # ... multiple instances.\ntrue\n\njulia> Base.issingletontype(NoFieldsParam{Int}) # Parametrized, it is a singleton.\ntrue\n\njulia> NoFieldsParam{Int}() === NoFieldsParam{Int}()\ntrue","category":"page"},{"location":"manual/types/#Types-of-functions","page":"Types","title":"Types of functions","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Each function has its own type, which is a subtype of Function.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> foo41(x) = x + 1\nfoo41 (generic function with 1 method)\n\njulia> typeof(foo41)\ntypeof(foo41) (singleton type of function foo41, subtype of Function)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Note how typeof(foo41) prints as itself. This is merely a convention for printing, as it is a first-class object that can be used like any other value:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> T = typeof(foo41)\ntypeof(foo41) (singleton type of function foo41, subtype of Function)\n\njulia> T <: Function\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Types of functions defined at top-level are singletons. When necessary, you can compare them with ===.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Closures also have their own type, which is usually printed with names that end in #. Names and types for functions defined at different locations are distinct, but not guaranteed to be printed the same way across sessions.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof(x -> x + 1)\nvar\"#9#10\"","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Types of closures are not necessarily singletons.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> addy(y) = x -> x + y\naddy (generic function with 1 method)\n\njulia> typeof(addy(1)) === typeof(addy(2))\ntrue\n\njulia> addy(1) === addy(2)\nfalse\n\njulia> Base.issingletontype(typeof(addy(1)))\nfalse","category":"page"},{"location":"manual/types/#man-typet-type","page":"Types","title":"Type{T} type selectors","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"For each type T, Type{T} is an abstract parametric type whose only instance is the object T. Until we discuss Parametric Methods and conversions, it is difficult to explain the utility of this construct, but in short, it allows one to specialize function behavior on specific types as values. This is useful for writing methods (especially parametric ones) whose behavior depends on a type that is given as an explicit argument rather than implied by the type of one of its arguments.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since the definition is a little difficult to parse, let's look at some examples:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> isa(Float64, Type{Float64})\ntrue\n\njulia> isa(Real, Type{Float64})\nfalse\n\njulia> isa(Real, Type{Real})\ntrue\n\njulia> isa(Float64, Type{Real})\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In other words, isa(A, Type{B}) is true if and only if A and B are the same object and that object is a type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In particular, since parametric types are invariant, we have","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct TypeParamExample{T}\n x::T\n end\n\njulia> TypeParamExample isa Type{TypeParamExample}\ntrue\n\njulia> TypeParamExample{Int} isa Type{TypeParamExample}\nfalse\n\njulia> TypeParamExample{Int} isa Type{TypeParamExample{Int}}\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Without the parameter, Type is simply an abstract type which has all type objects as its instances:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> isa(Type{Float64}, Type)\ntrue\n\njulia> isa(Float64, Type)\ntrue\n\njulia> isa(Real, Type)\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Any object that is not a type is not an instance of Type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> isa(1, Type)\nfalse\n\njulia> isa(\"foo\", Type)\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"While Type is part of Julia's type hierarchy like any other abstract parametric type, it is not commonly used outside method signatures except in some special cases. Another important use case for Type is sharpening field types which would otherwise be captured less precisely, e.g. as DataType in the example below where the default constructor could lead to performance problems in code relying on the precise wrapped type (similarly to abstract type parameters).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct WrapType{T}\n value::T\n end\n\njulia> WrapType(Float64) # default constructor, note DataType\nWrapType{DataType}(Float64)\n\njulia> WrapType(::Type{T}) where T = WrapType{Type{T}}(T)\nWrapType\n\njulia> WrapType(Float64) # sharpened constructor, note more precise Type{Float64}\nWrapType{Type{Float64}}(Float64)","category":"page"},{"location":"manual/types/#Type-Aliases","page":"Types","title":"Type Aliases","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Sometimes it is convenient to introduce a new name for an already expressible type. This can be done with a simple assignment statement. For example, UInt is aliased to either UInt32 or UInt64 as is appropriate for the size of pointers on the system:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"# 32-bit system:\njulia> UInt\nUInt32\n\n# 64-bit system:\njulia> UInt\nUInt64","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This is accomplished via the following code in base/boot.jl:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"if Int === Int64\n const UInt = UInt64\nelse\n const UInt = UInt32\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Of course, this depends on what Int is aliased to – but that is predefined to be the correct type – either Int32 or Int64.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"(Note that unlike Int, Float does not exist as a type alias for a specific sized AbstractFloat. Unlike with integer registers, where the size of Int reflects the size of a native pointer on that machine, the floating point register sizes are specified by the IEEE-754 standard.)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type aliases may be parametrized:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> const Family{T} = Set{T}\nSet\n\njulia> Family{Char} === Set{Char}\ntrue","category":"page"},{"location":"manual/types/#Operations-on-Types","page":"Types","title":"Operations on Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since types in Julia are themselves objects, ordinary functions can operate on them. Some functions that are particularly useful for working with or exploring types have already been introduced, such as the <: operator, which indicates whether its left hand operand is a subtype of its right hand operand.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The isa function tests if an object is of a given type and returns true or false:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> isa(1, Int)\ntrue\n\njulia> isa(1, AbstractFloat)\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The typeof function, already used throughout the manual in examples, returns the type of its argument. Since, as noted above, types are objects, they also have types, and we can ask what their types are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof(Rational{Int})\nDataType\n\njulia> typeof(Union{Real,String})\nUnion","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"What if we repeat the process? What is the type of a type of a type? As it happens, types are all composite values and thus all have a type of DataType:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof(DataType)\nDataType\n\njulia> typeof(Union)\nDataType","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"DataType is its own type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Another operation that applies to some types is supertype, which reveals a type's supertype. Only declared types (DataType) have unambiguous supertypes:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> supertype(Float64)\nAbstractFloat\n\njulia> supertype(Number)\nAny\n\njulia> supertype(AbstractString)\nAny\n\njulia> supertype(Any)\nAny","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"If you apply supertype to other type objects (or non-type objects), a MethodError is raised:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> supertype(Union{Float64,Int64})\nERROR: MethodError: no method matching supertype(::Type{Union{Float64, Int64}})\nThe function `supertype` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n[...]","category":"page"},{"location":"manual/types/#man-custom-pretty-printing","page":"Types","title":"Custom pretty-printing","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Often, one wants to customize how instances of a type are displayed. This is accomplished by overloading the show function. For example, suppose we define a type to represent complex numbers in polar form:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Polar{T<:Real} <: Number\n r::T\n Θ::T\n end\n\njulia> Polar(r::Real,Θ::Real) = Polar(promote(r,Θ)...)\nPolar","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Here, we've added a custom constructor function so that it can take arguments of different Real types and promote them to a common type (see Constructors and Conversion and Promotion). (Of course, we would have to define lots of other methods, too, to make it act like a Number, e.g. +, *, one, zero, promotion rules and so on.) By default, instances of this type display rather simply, with information about the type name and the field values, as e.g. Polar{Float64}(3.0,4.0).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"If we want it to display instead as 3.0 * exp(4.0im), we would define the following method to print the object to a given output object io (representing a file, terminal, buffer, etcetera; see Networking and Streams):","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Base.show(io::IO, z::Polar) = print(io, z.r, \" * exp(\", z.Θ, \"im)\")","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"More fine-grained control over display of Polar objects is possible. In particular, sometimes one wants both a verbose multi-line printing format, used for displaying a single object in the REPL and other interactive environments, and also a more compact single-line format used for print or for displaying the object as part of another object (e.g. in an array). Although by default the show(io, z) function is called in both cases, you can define a different multi-line format for displaying an object by overloading a three-argument form of show that takes the text/plain MIME type as its second argument (see Multimedia I/O), for example:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Base.show(io::IO, ::MIME\"text/plain\", z::Polar{T}) where{T} =\n print(io, \"Polar{$T} complex number:\\n \", z)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"(Note that print(..., z) here will call the 2-argument show(io, z) method.) This results in:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Polar(3, 4.0)\nPolar{Float64} complex number:\n 3.0 * exp(4.0im)\n\njulia> [Polar(3, 4.0), Polar(4.0,5.3)]\n2-element Vector{Polar{Float64}}:\n 3.0 * exp(4.0im)\n 4.0 * exp(5.3im)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"where the single-line show(io, z) form is still used for an array of Polar values. Technically, the REPL calls display(z) to display the result of executing a line, which defaults to show(stdout, MIME(\"text/plain\"), z), which in turn defaults to show(stdout, z), but you should not define new display methods unless you are defining a new multimedia display handler (see Multimedia I/O).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Moreover, you can also define show methods for other MIME types in order to enable richer display (HTML, images, etcetera) of objects in environments that support this (e.g. IJulia). For example, we can define formatted HTML display of Polar objects, with superscripts and italics, via:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Base.show(io::IO, ::MIME\"text/html\", z::Polar{T}) where {T} =\n println(io, \"Polar{$T} complex number: \",\n z.r, \" e\", z.Θ, \" i\")","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A Polar object will then display automatically using HTML in an environment that supports HTML display, but you can call show manually to get HTML output if you want:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> show(stdout, \"text/html\", Polar(3.0,4.0))\nPolar{Float64} complex number: 3.0 e4.0 i","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"

    An HTML renderer would display this as: Polar{Float64} complex number: 3.0 e4.0 i

    ","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"As a rule of thumb, the single-line show method should print a valid Julia expression for creating the shown object. When this show method contains infix operators, such as the multiplication operator (*) in our single-line show method for Polar above, it may not parse correctly when printed as part of another object. To see this, consider the expression object (see Program representation) which takes the square of a specific instance of our Polar type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> a = Polar(3, 4.0)\nPolar{Float64} complex number:\n 3.0 * exp(4.0im)\n\njulia> print(:($a^2))\n3.0 * exp(4.0im) ^ 2","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Because the operator ^ has higher precedence than * (see Operator Precedence and Associativity), this output does not faithfully represent the expression a ^ 2 which should be equal to (3.0 * exp(4.0im)) ^ 2. To solve this issue, we must make a custom method for Base.show_unquoted(io::IO, z::Polar, indent::Int, precedence::Int), which is called internally by the expression object when printing:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> function Base.show_unquoted(io::IO, z::Polar, ::Int, precedence::Int)\n if Base.operator_precedence(:*) <= precedence\n print(io, \"(\")\n show(io, z)\n print(io, \")\")\n else\n show(io, z)\n end\n end\n\njulia> :($a^2)\n:((3.0 * exp(4.0im)) ^ 2)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The method defined above adds parentheses around the call to show when the precedence of the calling operator is higher than or equal to the precedence of multiplication. This check allows expressions which parse correctly without the parentheses (such as :($a + 2) and :($a == 2)) to omit them when printing:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> :($a + 2)\n:(3.0 * exp(4.0im) + 2)\n\njulia> :($a == 2)\n:(3.0 * exp(4.0im) == 2)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In some cases, it is useful to adjust the behavior of show methods depending on the context. This can be achieved via the IOContext type, which allows passing contextual properties together with a wrapped IO stream. For example, we can build a shorter representation in our show method when the :compact property is set to true, falling back to the long representation if the property is false or absent:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> function Base.show(io::IO, z::Polar)\n if get(io, :compact, false)::Bool\n print(io, z.r, \"ℯ\", z.Θ, \"im\")\n else\n print(io, z.r, \" * exp(\", z.Θ, \"im)\")\n end\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This new compact representation will be used when the passed IO stream is an IOContext object with the :compact property set. In particular, this is the case when printing arrays with multiple columns (where horizontal space is limited):","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> show(IOContext(stdout, :compact=>true), Polar(3, 4.0))\n3.0ℯ4.0im\n\njulia> [Polar(3, 4.0) Polar(4.0,5.3)]\n1×2 Matrix{Polar{Float64}}:\n 3.0ℯ4.0im 4.0ℯ5.3im","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"See the IOContext documentation for a list of common properties which can be used to adjust printing.","category":"page"},{"location":"manual/types/#\"Value-types\"","page":"Types","title":"\"Value types\"","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"In Julia, you can't dispatch on a value such as true or false. However, you can dispatch on parametric types, and Julia allows you to include \"plain bits\" values (Types, Symbols, Integers, floating-point numbers, tuples, etc.) as type parameters. A common example is the dimensionality parameter in Array{T,N}, where T is a type (e.g., Float64) but N is just an Int.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"You can create your own custom types that take values as parameters, and use them to control dispatch of custom types. By way of illustration of this idea, let's introduce the parametric type Val{x}, and its constructor Val(x) = Val{x}(), which serves as a customary way to exploit this technique for cases where you don't need a more elaborate hierarchy.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Val is defined as:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Val{x}\n end\n\njulia> Val(x) = Val{x}()\nVal","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There is no more to the implementation of Val than this. Some functions in Julia's standard library accept Val instances as arguments, and you can also use it to write your own functions. For example:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> firstlast(::Val{true}) = \"First\"\nfirstlast (generic function with 1 method)\n\njulia> firstlast(::Val{false}) = \"Last\"\nfirstlast (generic function with 2 methods)\n\njulia> firstlast(Val(true))\n\"First\"\n\njulia> firstlast(Val(false))\n\"Last\"","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"For consistency across Julia, the call site should always pass a Val instance rather than using a type, i.e., use foo(Val(:bar)) rather than foo(Val{:bar}).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"It's worth noting that it's extremely easy to mis-use parametric \"value\" types, including Val; in unfavorable cases, you can easily end up making the performance of your code much worse. In particular, you would never want to write actual code as illustrated above. For more information about the proper (and improper) uses of Val, please read the more extensive discussion in the performance tips.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"[1]: \"Small\" is defined by the max_union_splitting configuration, which currently defaults to 4.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"[2]: A few popular languages have singleton types, including Haskell, Scala and Ruby.","category":"page"},{"location":"stdlib/Unicode/","page":"Unicode","title":"Unicode","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Unicode/docs/src/index.md\"","category":"page"},{"location":"stdlib/Unicode/#Unicode","page":"Unicode","title":"Unicode","text":"","category":"section"},{"location":"stdlib/Unicode/","page":"Unicode","title":"Unicode","text":"The Unicode module provides essential functionality for managing Unicode characters and strings. It includes validation, category determination, normalization, case transformation, and grapheme segmentation, enabling effective Unicode data handling.","category":"page"},{"location":"stdlib/Unicode/","page":"Unicode","title":"Unicode","text":"Unicode\nUnicode.julia_chartransform\nUnicode.isassigned\nUnicode.isequal_normalized\nUnicode.normalize\nUnicode.graphemes","category":"page"},{"location":"stdlib/Unicode/#Unicode","page":"Unicode","title":"Unicode","text":"The Unicode module provides essential functionality for managing Unicode characters and strings. It includes validation, category determination, normalization, case transformation, and grapheme segmentation, enabling effective Unicode data handling.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Unicode/#Unicode.julia_chartransform","page":"Unicode","title":"Unicode.julia_chartransform","text":"Unicode.julia_chartransform(c::Union{Char,Integer})\n\nMap the Unicode character (Char) or codepoint (Integer) c to the corresponding \"equivalent\" character or codepoint, respectively, according to the custom equivalence used within the Julia parser (in addition to NFC normalization).\n\nFor example, 'µ' (U+00B5 micro) is treated as equivalent to 'μ' (U+03BC mu) by Julia's parser, so julia_chartransform performs this transformation while leaving other characters unchanged:\n\njulia> Unicode.julia_chartransform('µ')\n'μ': Unicode U+03BC (category Ll: Letter, lowercase)\n\njulia> Unicode.julia_chartransform('x')\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\njulia_chartransform is mainly useful for passing to the Unicode.normalize function in order to mimic the normalization used by the Julia parser:\n\njulia> s = \"µö\"\n\"µö\"\n\njulia> s2 = Unicode.normalize(s, compose=true, stable=true, chartransform=Unicode.julia_chartransform)\n\"μö\"\n\njulia> collect(s2)\n2-element Vector{Char}:\n 'μ': Unicode U+03BC (category Ll: Letter, lowercase)\n 'ö': Unicode U+00F6 (category Ll: Letter, lowercase)\n\njulia> s2 == string(Meta.parse(s))\ntrue\n\ncompat: Julia 1.8\nThis function was introduced in Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Unicode/#Unicode.isassigned","page":"Unicode","title":"Unicode.isassigned","text":"Unicode.isassigned(c) -> Bool\n\nReturn true if the given char or integer is an assigned Unicode code point.\n\nExamples\n\njulia> Unicode.isassigned(101)\ntrue\n\njulia> Unicode.isassigned('\\x01')\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Unicode/#Unicode.isequal_normalized","page":"Unicode","title":"Unicode.isequal_normalized","text":"isequal_normalized(s1::AbstractString, s2::AbstractString; casefold=false, stripmark=false, chartransform=identity)\n\nReturn whether s1 and s2 are canonically equivalent Unicode strings. If casefold=true, ignores case (performs Unicode case-folding); if stripmark=true, strips diacritical marks and other combining characters.\n\nAs with Unicode.normalize, you can also pass an arbitrary function via the chartransform keyword (mapping Integer codepoints to codepoints) to perform custom normalizations, such as Unicode.julia_chartransform.\n\ncompat: Julia 1.8\nThe isequal_normalized function was added in Julia 1.8.\n\nExamples\n\nFor example, the string \"noël\" can be constructed in two canonically equivalent ways in Unicode, depending on whether \"ë\" is formed from a single codepoint U+00EB or from the ASCII character 'e' followed by the U+0308 combining-diaeresis character.\n\njulia> s1 = \"noël\"\n\"noël\"\n\njulia> s2 = \"noël\"\n\"noël\"\n\njulia> s1 == s2\nfalse\n\njulia> isequal_normalized(s1, s2)\ntrue\n\njulia> isequal_normalized(s1, \"noel\", stripmark=true)\ntrue\n\njulia> isequal_normalized(s1, \"NOËL\", casefold=true)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Unicode/#Unicode.normalize","page":"Unicode","title":"Unicode.normalize","text":"Unicode.normalize(s::AbstractString; keywords...)\nUnicode.normalize(s::AbstractString, normalform::Symbol)\n\nNormalize the string s. By default, canonical composition (compose=true) is performed without ensuring Unicode versioning stability (compat=false), which produces the shortest possible equivalent string but may introduce composition characters not present in earlier Unicode versions.\n\nAlternatively, one of the four \"normal forms\" of the Unicode standard can be specified: normalform can be :NFC, :NFD, :NFKC, or :NFKD. Normal forms C (canonical composition) and D (canonical decomposition) convert different visually identical representations of the same abstract string into a single canonical form, with form C being more compact. Normal forms KC and KD additionally canonicalize \"compatibility equivalents\": they convert characters that are abstractly similar but visually distinct into a single canonical choice (e.g. they expand ligatures into the individual characters), with form KC being more compact.\n\nAlternatively, finer control and additional transformations may be obtained by calling Unicode.normalize(s; keywords...), where any number of the following boolean keywords options (which all default to false except for compose) are specified:\n\ncompose=false: do not perform canonical composition\ndecompose=true: do canonical decomposition instead of canonical composition (compose=true is ignored if present)\ncompat=true: compatibility equivalents are canonicalized\ncasefold=true: perform Unicode case folding, e.g. for case-insensitive string comparison\nnewline2lf=true, newline2ls=true, or newline2ps=true: convert various newline sequences (LF, CRLF, CR, NEL) into a linefeed (LF), line-separation (LS), or paragraph-separation (PS) character, respectively\nstripmark=true: strip diacritical marks (e.g. accents)\nstripignore=true: strip Unicode's \"default ignorable\" characters (e.g. the soft hyphen or the left-to-right marker)\nstripcc=true: strip control characters; horizontal tabs and form feeds are converted to spaces; newlines are also converted to spaces unless a newline-conversion flag was specified\nrejectna=true: throw an error if unassigned code points are found\nstable=true: enforce Unicode versioning stability (never introduce characters missing from earlier Unicode versions)\n\nYou can also use the chartransform keyword (which defaults to identity) to pass an arbitrary function mapping Integer codepoints to codepoints, which is called on each character in s as it is processed, in order to perform arbitrary additional normalizations. For example, by passing chartransform=Unicode.julia_chartransform, you can apply a few Julia-specific character normalizations that are performed by Julia when parsing identifiers (in addition to NFC normalization: compose=true, stable=true).\n\nFor example, NFKC corresponds to the options compose=true, compat=true, stable=true.\n\nExamples\n\njulia> \"é\" == Unicode.normalize(\"é\") #LHS: Unicode U+00e9, RHS: U+0065 & U+0301\ntrue\n\njulia> \"μ\" == Unicode.normalize(\"µ\", compat=true) #LHS: Unicode U+03bc, RHS: Unicode U+00b5\ntrue\n\njulia> Unicode.normalize(\"JuLiA\", casefold=true)\n\"julia\"\n\njulia> Unicode.normalize(\"JúLiA\", stripmark=true)\n\"JuLiA\"\n\ncompat: Julia 1.8\nThe chartransform keyword argument requires Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Unicode/#Unicode.graphemes","page":"Unicode","title":"Unicode.graphemes","text":"graphemes(s::AbstractString) -> GraphemeIterator\n\nReturn an iterator over substrings of s that correspond to the extended graphemes in the string, as defined by Unicode UAX #29. (Roughly, these are what users would perceive as single characters, even though they may contain more than one codepoint; for example a letter combined with an accent mark is a single grapheme.)\n\n\n\n\n\ngraphemes(s::AbstractString, m:n) -> SubString\n\nReturns a SubString of s consisting of the m-th through n-th graphemes of the string s, where the second argument m:n is an integer-valued AbstractUnitRange.\n\nLoosely speaking, this corresponds to the m:n-th user-perceived \"characters\" in the string. For example:\n\njulia> s = graphemes(\"exposé\", 3:6)\n\"posé\"\n\njulia> collect(s)\n5-element Vector{Char}:\n 'p': ASCII/Unicode U+0070 (category Ll: Letter, lowercase)\n 'o': ASCII/Unicode U+006F (category Ll: Letter, lowercase)\n 's': ASCII/Unicode U+0073 (category Ll: Letter, lowercase)\n 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)\n '́': Unicode U+0301 (category Mn: Mark, nonspacing)\n\nThis consists of the 3rd to 7th codepoints (Chars) in \"exposé\", because the grapheme \"é\" is actually two Unicode codepoints (an 'e' followed by an acute-accent combining character U+0301).\n\nBecause finding grapheme boundaries requires iteration over the string contents, the graphemes(s, m:n) function requires time proportional to the length of the string (number of codepoints) before the end of the substring.\n\ncompat: Julia 1.9\nThe m:n argument of graphemes requires Julia 1.9.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/probes/#Instrumenting-Julia-with-DTrace,-and-bpftrace","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"DTrace and bpftrace are tools that enable lightweight instrumentation of processes. You can turn the instrumentation on and off while the process is running, and with instrumentation off the overhead is minimal.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"compat: Julia 1.8\nSupport for probes was added in Julia 1.8","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"note: Note\nThis documentation has been written from a Linux perspective, most of this should hold on Mac OS/Darwin and FreeBSD.","category":"page"},{"location":"devdocs/probes/#Enabling-support","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Enabling support","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"On Linux install the systemtap package that has a version of dtrace and create a Make.user file containing","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"WITH_DTRACE=1","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"to enable USDT probes.","category":"page"},{"location":"devdocs/probes/#Verifying","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Verifying","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"> readelf -n usr/lib/libjulia-internal.so.1\n\nDisplaying notes found in: .note.gnu.build-id\n Owner Data size Description\n GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)\n Build ID: 57161002f35548772a87418d2385c284ceb3ead8\n\nDisplaying notes found in: .note.stapsdt\n Owner Data size Description\n stapsdt 0x00000029 NT_STAPSDT (SystemTap probe descriptors)\n Provider: julia\n Name: gc__begin\n Location: 0x000000000013213e, Base: 0x00000000002bb4da, Semaphore: 0x0000000000346cac\n Arguments:\n stapsdt 0x00000032 NT_STAPSDT (SystemTap probe descriptors)\n Provider: julia\n Name: gc__stop_the_world\n Location: 0x0000000000132144, Base: 0x00000000002bb4da, Semaphore: 0x0000000000346cae\n Arguments:\n stapsdt 0x00000027 NT_STAPSDT (SystemTap probe descriptors)\n Provider: julia\n Name: gc__end\n Location: 0x000000000013214a, Base: 0x00000000002bb4da, Semaphore: 0x0000000000346cb0\n Arguments:\n stapsdt 0x0000002d NT_STAPSDT (SystemTap probe descriptors)\n Provider: julia\n Name: gc__finalizer\n Location: 0x0000000000132150, Base: 0x00000000002bb4da, Semaphore: 0x0000000000346cb2\n Arguments:","category":"page"},{"location":"devdocs/probes/#Adding-probes-in-libjulia","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Adding probes in libjulia","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Probes are declared in dtraces format in the file src/uprobes.d. The generated header file is included in src/julia_internal.h and if you add probes you should provide a noop implementation there.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"The header will contain a semaphore *_ENABLED and the actual call to the probe. If the probe arguments are expensive to compute you should first check if the probe is enabled and then compute the arguments and call the probe.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":" if (JL_PROBE_{PROBE}_ENABLED())\n auto expensive_arg = ...;\n JL_PROBE_{PROBE}(expensive_arg);","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"If your probe has no arguments it is preferred to not include the semaphore check. With USDT probes enabled the cost of a semaphore is a memory load, irrespective of the fact that the probe is enabled or not.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"#define JL_PROBE_GC_BEGIN_ENABLED() __builtin_expect (julia_gc__begin_semaphore, 0)\n__extension__ extern unsigned short julia_gc__begin_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Whereas the probe itself is a noop sled that will be patched to a trampoline to the probe handler.","category":"page"},{"location":"devdocs/probes/#Available-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Available probes","text":"","category":"section"},{"location":"devdocs/probes/#GC-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"GC probes","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"julia:gc__begin: GC begins running on one thread and triggers stop-the-world.\njulia:gc__stop_the_world: All threads have reached a safepoint and GC runs.\njulia:gc__mark__begin: Beginning the mark phase\njulia:gc__mark_end(scanned_bytes, perm_scanned): Mark phase ended\njulia:gc__sweep_begin(full): Starting sweep\njulia:gc__sweep_end: Sweep phase finished\njulia:gc__end: GC is finished, other threads continue work\njulia:gc__finalizer: Initial GC thread has finished running finalizers","category":"page"},{"location":"devdocs/probes/#Task-runtime-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Task runtime probes","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"julia:rt__run__task(task): Switching to task task on current thread.\njulia:rt__pause__task(task): Switching from task task on current thread.\njulia:rt__new__task(parent, child): Task parent created task child on current thread.\njulia:rt__start__task(task): Task task started for the first time with a new stack.\njulia:rt__finish__task(task): Task task finished and will no longer execute.\njulia:rt__start__process__events(task): Task task started processing libuv events.\njulia:rt__finish__process__events(task): Task task finished processing libuv events.","category":"page"},{"location":"devdocs/probes/#Task-queue-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Task queue probes","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"julia:rt__taskq__insert(ptls, task): Thread ptls attempted to insert task into a PARTR multiq.\njulia:rt__taskq__get(ptls, task): Thread ptls popped task from a PARTR multiq.","category":"page"},{"location":"devdocs/probes/#Thread-sleep/wake-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Thread sleep/wake probes","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"julia:rt__sleep__check__wake(ptls, old_state): Thread (PTLS ptls) waking up, previously in state old_state.\njulia:rt__sleep__check__wakeup(ptls): Thread (PTLS ptls) woke itself up.\njulia:rt__sleep__check__sleep(ptls): Thread (PTLS ptls) is attempting to sleep.\njulia:rt__sleep__check__taskq__wake(ptls): Thread (PTLS ptls) fails to sleep due to tasks in PARTR multiq.\njulia:rt__sleep__check__task__wake(ptls): Thread (PTLS ptls) fails to sleep due to tasks in Base workqueue.\njulia:rt__sleep__check__uv__wake(ptls): Thread (PTLS ptls) fails to sleep due to libuv wakeup.","category":"page"},{"location":"devdocs/probes/#Probe-usage-examples","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Probe usage examples","text":"","category":"section"},{"location":"devdocs/probes/#GC-stop-the-world-latency","page":"Instrumenting Julia with DTrace, and bpftrace","title":"GC stop-the-world latency","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"An example bpftrace script is given in contrib/gc_stop_the_world_latency.bt and it creates a histogram of the latency for all threads to reach a safepoint.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Running this Julia code, with julia -t 2","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"using Base.Threads\n\nfib(x) = x <= 1 ? 1 : fib(x-1) + fib(x-2)\n\nbeaver = @spawn begin\n while true\n fib(30)\n # A manual safepoint is necessary since otherwise this loop\n # may never yield to GC.\n GC.safepoint()\n end\nend\n\nallocator = @spawn begin\n while true\n zeros(1024)\n end\nend\n\nwait(allocator)","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"and in a second terminal","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"> sudo contrib/bpftrace/gc_stop_the_world_latency.bt\nAttaching 4 probes...\nTracing Julia GC Stop-The-World Latency... Hit Ctrl-C to end.\n^C\n\n\n@usecs[1743412]:\n[4, 8) 971 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|\n[8, 16) 837 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |\n[16, 32) 129 |@@@@@@ |\n[32, 64) 10 | |\n[64, 128) 1 | |","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"We can see the latency distribution of the stop-the-world phase in the executed Julia process.","category":"page"},{"location":"devdocs/probes/#Task-spawn-monitor","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Task spawn monitor","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"It's sometimes useful to know when a task is spawning other tasks. This is very easy to see with rt__new__task. The first argument to the probe, parent, is the existing task which is creating a new task. This means that if you know the address of the task you want to monitor, you can easily just look at the tasks that that specific task spawned. Let's see how to do this; first let's start a Julia session and get the PID and REPL's task address:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"> julia\n _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.2 (2021-07-14)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\n1> getpid()\n997825\n\n2> current_task()\nTask (runnable) @0x00007f524d088010","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Now we can start bpftrace and have it monitor rt__new__task for only this parent:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"sudo bpftrace -p 997825 -e 'usdt:usr/lib/libjulia-internal.so:julia:rt__new__task /arg0==0x00007f524d088010/{ printf(\"Task: %x\\n\", arg0); }'","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"(Note that in the above, arg0 is the first argument, parent).","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"And if we spawn a single task:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"@async 1+1","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"we see this task being created:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Task: 4d088010","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"However, if we spawn a bunch of tasks from that newly-spawned task:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"@async for i in 1:10\n @async 1+1\nend","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"we still only see one task from bpftrace:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Task: 4d088010","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"and it's still the same task we were monitoring! Of course, we can remove this filter to see all newly-created tasks just as easily:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"sudo bpftrace -p 997825 -e 'usdt:usr/lib/libjulia-internal.so:julia:rt__new__task { printf(\"Task: %x\\n\", arg0); }'","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Task: 4d088010\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"We can see our root task, and the newly-spawned task as the parent of the ten even newer tasks.","category":"page"},{"location":"devdocs/probes/#Thundering-herd-detection","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Thundering herd detection","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Task runtimes can often suffer from the \"thundering herd\" problem: when some work is added to a quiet task runtime, all threads may be woken up from their slumber, even if there isn't enough work for each thread to process. This can cause extra latency and CPU cycles while all threads awaken (and simultaneously go back to sleep, not finding any work to execute).","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"We can see this problem illustrated with bpftrace quite easily. First, in one terminal we start Julia with multiple threads (6 in this example), and get the PID of that process:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"> julia -t 6\n _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.2 (2021-07-14)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\n1> getpid()\n997825","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"And in another terminal we start bpftrace monitoring our process, specifically probing the rt__sleep__check__wake hook:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"sudo bpftrace -p 997825 -e 'usdt:usr/lib/libjulia-internal.so:julia:rt__sleep__check__wake { printf(\"Thread wake up! %x\\n\", arg0); }'","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Now, we create and execute a single task in Julia:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Threads.@spawn 1+1","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"And in bpftrace we see printed out something like:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Thread wake up! 3f926100\nThread wake up! 3ebd5140\nThread wake up! 3f876130\nThread wake up! 3e2711a0\nThread wake up! 3e312190","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Even though we only spawned a single task (which only one thread could process at a time), we woke up all of our other threads! In the future, a smarter task runtime might only wake up a single thread (or none at all; the spawning thread could execute this task!), and we should see this behavior go away.","category":"page"},{"location":"devdocs/probes/#Task-Monitor-with-BPFnative.jl","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Task Monitor with BPFnative.jl","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"BPFnative.jl is able to attach to USDT probe points just like bpftrace. There is a demo available for monitoring the task runtime, GC, and thread sleep/wake transitions here.","category":"page"},{"location":"devdocs/probes/#Notes-on-using-bpftrace","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Notes on using bpftrace","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"An example probe in the bpftrace format looks like:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"usdt:usr/lib/libjulia-internal.so:julia:gc__begin\n{\n @start[pid] = nsecs;\n}","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"The probe declaration takes the kind usdt, then either the path to the library or the PID, the provider name julia and the probe name gc__begin. Note that I am using a relative path to the libjulia-internal.so, but this might need to be an absolute path on a production system.","category":"page"},{"location":"devdocs/probes/#Useful-references:","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Useful references:","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Julia Evans blog on Linux tracing systems\nLWN article on USDT and BPF\nGDB support for probes\nBrendan Gregg – Linux Performance","category":"page"},{"location":"base/constants/#lib-constants","page":"Constants","title":"Constants","text":"","category":"section"},{"location":"base/constants/","page":"Constants","title":"Constants","text":"Core.nothing\nBase.PROGRAM_FILE\nBase.ARGS\nBase.C_NULL\nBase.VERSION\nBase.DEPOT_PATH\nBase.LOAD_PATH\nBase.Sys.BINDIR\nBase.Sys.CPU_THREADS\nBase.Sys.WORD_SIZE\nBase.Sys.KERNEL\nBase.Sys.ARCH\nBase.Sys.MACHINE","category":"page"},{"location":"base/constants/#Core.nothing","page":"Constants","title":"Core.nothing","text":"nothing\n\nThe singleton instance of type Nothing, used by convention when there is no value to return (as in a C void function) or when a variable or field holds no value.\n\nSee also: isnothing, something, missing.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.PROGRAM_FILE","page":"Constants","title":"Base.PROGRAM_FILE","text":"PROGRAM_FILE\n\nA string containing the script name passed to Julia from the command line. Note that the script name remains unchanged from within included files. Alternatively see @__FILE__.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.ARGS","page":"Constants","title":"Base.ARGS","text":"ARGS\n\nAn array of the command line arguments passed to Julia, as strings.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.C_NULL","page":"Constants","title":"Base.C_NULL","text":"C_NULL\n\nThe C null pointer constant, sometimes used when calling external code.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.VERSION","page":"Constants","title":"Base.VERSION","text":"VERSION\n\nA VersionNumber object describing which version of Julia is in use. See also Version Number Literals.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.DEPOT_PATH","page":"Constants","title":"Base.DEPOT_PATH","text":"DEPOT_PATH\n\nA stack of \"depot\" locations where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, and configuration files. By default it includes:\n\n~/.julia where ~ is the user home as appropriate on the system;\nan architecture-specific shared system directory, e.g. /usr/local/share/julia;\nan architecture-independent shared system directory, e.g. /usr/share/julia.\n\nSo DEPOT_PATH might be:\n\n[joinpath(homedir(), \".julia\"), \"/usr/local/share/julia\", \"/usr/share/julia\"]\n\nThe first entry is the \"user depot\" and should be writable by and owned by the current user. The user depot is where: registries are cloned, new package versions are installed, named environments are created and updated, package repos are cloned, newly compiled package image files are saved, log files are written, development packages are checked out by default, and global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and managed by system administrators.\n\nDEPOT_PATH is populated based on the JULIA_DEPOT_PATH environment variable if set.\n\nDEPOT_PATH contents\n\nEach entry in DEPOT_PATH is a path to a directory which contains subdirectories used by Julia for various purposes. Here is an overview of some of the subdirectories that may exist in a depot:\n\nartifacts: Contains content that packages use for which Pkg manages the installation of.\nclones: Contains full clones of package repos. Maintained by Pkg.jl and used as a cache.\nconfig: Contains julia-level configuration such as a startup.jl\ncompiled: Contains precompiled *.ji files for packages. Maintained by Julia.\ndev: Default directory for Pkg.develop. Maintained by Pkg.jl and the user.\nenvironments: Default package environments. For instance the global environment for a specific julia version. Maintained by Pkg.jl.\nlogs: Contains logs of Pkg and REPL operations. Maintained by Pkg.jl and Julia.\npackages: Contains packages, some of which were explicitly installed and some which are implicit dependencies. Maintained by Pkg.jl.\nregistries: Contains package registries. By default only General. Maintained by Pkg.jl.\nscratchspaces: Contains content that a package itself installs via the Scratch.jl package. Pkg.gc() will delete content that is known to be unused.\n\nnote: Note\nPackages that want to store content should use the scratchspaces subdirectory via Scratch.jl instead of creating new subdirectories in the depot root.\n\nSee also JULIA_DEPOT_PATH, and Code Loading.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.LOAD_PATH","page":"Constants","title":"Base.LOAD_PATH","text":"LOAD_PATH\n\nAn array of paths for using and import statements to consider as project environments or package directories when loading code. It is populated based on the JULIA_LOAD_PATH environment variable if set; otherwise it defaults to [\"@\", \"@v#.#\", \"@stdlib\"]. Entries starting with @ have special meanings:\n\n@ refers to the \"current active environment\", the initial value of which is initially determined by the JULIA_PROJECT environment variable or the --project command-line option.\n@stdlib expands to the absolute path of the current Julia installation's standard library directory.\n@name refers to a named environment, which are stored in depots (see JULIA_DEPOT_PATH) under the environments subdirectory. The user's named environments are stored in ~/.julia/environments so @name would refer to the environment in ~/.julia/environments/name if it exists and contains a Project.toml file. If name contains # characters, then they are replaced with the major, minor and patch components of the Julia version number. For example, if you are running Julia 1.2 then @v#.# expands to @v1.2 and will look for an environment by that name, typically at ~/.julia/environments/v1.2.\n\nThe fully expanded value of LOAD_PATH that is searched for projects and packages can be seen by calling the Base.load_path() function.\n\nSee also JULIA_LOAD_PATH, JULIA_PROJECT, JULIA_DEPOT_PATH, and Code Loading.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.BINDIR","page":"Constants","title":"Base.Sys.BINDIR","text":"Sys.BINDIR::String\n\nA string containing the full path to the directory containing the julia executable.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.CPU_THREADS","page":"Constants","title":"Base.Sys.CPU_THREADS","text":"Sys.CPU_THREADS::Int\n\nThe number of logical CPU cores available in the system, i.e. the number of threads that the CPU can run concurrently. Note that this is not necessarily the number of CPU cores, for example, in the presence of hyper-threading.\n\nSee Hwloc.jl or CpuId.jl for extended information, including number of physical cores.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.WORD_SIZE","page":"Constants","title":"Base.Sys.WORD_SIZE","text":"Sys.WORD_SIZE::Int\n\nStandard word size on the current machine, in bits.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.KERNEL","page":"Constants","title":"Base.Sys.KERNEL","text":"Sys.KERNEL::Symbol\n\nA symbol representing the name of the operating system, as returned by uname of the build configuration.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.ARCH","page":"Constants","title":"Base.Sys.ARCH","text":"Sys.ARCH::Symbol\n\nA symbol representing the architecture of the build configuration.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.MACHINE","page":"Constants","title":"Base.Sys.MACHINE","text":"Sys.MACHINE::String\n\nA string containing the build triple.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/","page":"Constants","title":"Constants","text":"See also:","category":"page"},{"location":"base/constants/","page":"Constants","title":"Constants","text":"stdin\nstdout\nstderr\nENV\nENDIAN_BOM","category":"page"},{"location":"tutorials/profile/#Profiling","page":"Profiling","title":"Profiling","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The Profile module provides tools to help developers improve the performance of their code. When used, it takes measurements on running code, and produces output that helps you understand how much time is spent on individual line(s). The most common usage is to identify \"bottlenecks\" as targets for optimization.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Profile implements what is known as a \"sampling\" or statistical profiler. It works by periodically taking a backtrace during the execution of any task. Each backtrace captures the currently-running function and line number, plus the complete chain of function calls that led to this line, and hence is a \"snapshot\" of the current state of execution.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"If much of your run time is spent executing a particular line of code, this line will show up frequently in the set of all backtraces. In other words, the \"cost\" of a given line–or really, the cost of the sequence of function calls up to and including this line–is proportional to how often it appears in the set of all backtraces.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"A sampling profiler does not provide complete line-by-line coverage, because the backtraces occur at intervals (by default, 1 ms on Unix systems and 10 ms on Windows, although the actual scheduling is subject to operating system load). Moreover, as discussed further below, because samples are collected at a sparse subset of all execution points, the data collected by a sampling profiler is subject to statistical noise.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Despite these limitations, sampling profilers have substantial strengths:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"You do not have to make any modifications to your code to take timing measurements.\nIt can profile into Julia's core code and even (optionally) into C and Fortran libraries.\nBy running \"infrequently\" there is very little performance overhead; while profiling, your code can run at nearly native speed.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"For these reasons, it's recommended that you try using the built-in sampling profiler before considering any alternatives.","category":"page"},{"location":"tutorials/profile/#Basic-usage","page":"Profiling","title":"Basic usage","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Let's work with a simple test case:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> function myfunc()\n A = rand(200, 200, 400)\n maximum(A)\n end","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"It's a good idea to first run the code you intend to profile at least once (unless you want to profile Julia's JIT-compiler):","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> myfunc() # run once to force compilation","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Now we're ready to profile this function:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> @profile myfunc()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"To see the profiling results, there are several graphical browsers. One \"family\" of visualizers is based on FlameGraphs.jl, with each family member providing a different user interface:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"VS Code is a full IDE with built-in support for profile visualization\nProfileView.jl is a stand-alone visualizer based on GTK\nProfileVega.jl uses VegaLight and integrates well with Jupyter notebooks\nStatProfilerHTML.jl produces HTML and presents some additional summaries, and also integrates well with Jupyter notebooks\nProfileSVG.jl renders SVG\nPProf.jl serves a local website for inspecting graphs, flamegraphs and more\nProfileCanvas.jl is a HTML canvas based profile viewer UI, used by the Julia VS Code extension, but can also generate interactive HTML files.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"An entirely independent approach to profile visualization is PProf.jl, which uses the external pprof tool.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Here, though, we'll use the text-based display that comes with the standard library:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> Profile.print()\n80 ./event.jl:73; (::Base.REPL.##1#2{Base.REPL.REPLBackend})()\n 80 ./REPL.jl:97; macro expansion\n 80 ./REPL.jl:66; eval_user_input(::Any, ::Base.REPL.REPLBackend)\n 80 ./boot.jl:235; eval(::Module, ::Any)\n 80 ./:?; anonymous\n 80 ./profile.jl:23; macro expansion\n 52 ./REPL[1]:2; myfunc()\n 38 ./random.jl:431; rand!(::MersenneTwister, ::Array{Float64,3}, ::Int64, ::Type{B...\n 38 ./dSFMT.jl:84; dsfmt_fill_array_close_open!(::Base.dSFMT.DSFMT_state, ::Ptr{F...\n 14 ./random.jl:278; rand\n 14 ./random.jl:277; rand\n 14 ./random.jl:366; rand\n 14 ./random.jl:369; rand\n 28 ./REPL[1]:3; myfunc()\n 28 ./reduce.jl:270; _mapreduce(::Base.#identity, ::Base.#scalarmax, ::IndexLinear,...\n 3 ./reduce.jl:426; mapreduce_impl(::Base.#identity, ::Base.#scalarmax, ::Array{F...\n 25 ./reduce.jl:428; mapreduce_impl(::Base.#identity, ::Base.#scalarmax, ::Array{F...","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Each line of this display represents a particular spot (line number) in the code. Indentation is used to indicate the nested sequence of function calls, with more-indented lines being deeper in the sequence of calls. In each line, the first \"field\" is the number of backtraces (samples) taken at this line or in any functions executed by this line. The second field is the file name and line number and the third field is the function name. Note that the specific line numbers may change as Julia's code changes; if you want to follow along, it's best to run this example yourself.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"In this example, we can see that the top level function called is in the file event.jl. This is the function that runs the REPL when you launch Julia. If you examine line 97 of REPL.jl, you'll see this is where the function eval_user_input() is called. This is the function that evaluates what you type at the REPL, and since we're working interactively these functions were invoked when we entered @profile myfunc(). The next line reflects actions taken in the @profile macro.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The first line shows that 80 backtraces were taken at line 73 of event.jl, but it's not that this line was \"expensive\" on its own: the third line reveals that all 80 of these backtraces were actually triggered inside its call to eval_user_input, and so on. To find out which operations are actually taking the time, we need to look deeper in the call chain.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The first \"important\" line in this output is this one:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"52 ./REPL[1]:2; myfunc()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"REPL refers to the fact that we defined myfunc in the REPL, rather than putting it in a file; if we had used a file, this would show the file name. The [1] shows that the function myfunc was the first expression evaluated in this REPL session. Line 2 of myfunc() contains the call to rand, and there were 52 (out of 80) backtraces that occurred at this line. Below that, you can see a call to dsfmt_fill_array_close_open! inside dSFMT.jl.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"A little further down, you see:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"28 ./REPL[1]:3; myfunc()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Line 3 of myfunc contains the call to maximum, and there were 28 (out of 80) backtraces taken here. Below that, you can see the specific places in base/reduce.jl that carry out the time-consuming operations in the maximum function for this type of input data.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Overall, we can tentatively conclude that generating the random numbers is approximately twice as expensive as finding the maximum element. We could increase our confidence in this result by collecting more samples:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> @profile (for i = 1:100; myfunc(); end)\n\njulia> Profile.print()\n[....]\n 3821 ./REPL[1]:2; myfunc()\n 3511 ./random.jl:431; rand!(::MersenneTwister, ::Array{Float64,3}, ::Int64, ::Type...\n 3511 ./dSFMT.jl:84; dsfmt_fill_array_close_open!(::Base.dSFMT.DSFMT_state, ::Ptr...\n 310 ./random.jl:278; rand\n [....]\n 2893 ./REPL[1]:3; myfunc()\n 2893 ./reduce.jl:270; _mapreduce(::Base.#identity, ::Base.#scalarmax, ::IndexLinea...\n [....]","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"In general, if you have N samples collected at a line, you can expect an uncertainty on the order of sqrt(N) (barring other sources of noise, like how busy the computer is with other tasks). The major exception to this rule is garbage collection, which runs infrequently but tends to be quite expensive. (Since Julia's garbage collector is written in C, such events can be detected using the C=true output mode described below, or by using ProfileView.jl.)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"This illustrates the default \"tree\" dump; an alternative is the \"flat\" dump, which accumulates counts independent of their nesting:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> Profile.print(format=:flat)\n Count File Line Function\n 6714 ./ -1 anonymous\n 6714 ./REPL.jl 66 eval_user_input(::Any, ::Base.REPL.REPLBackend)\n 6714 ./REPL.jl 97 macro expansion\n 3821 ./REPL[1] 2 myfunc()\n 2893 ./REPL[1] 3 myfunc()\n 6714 ./REPL[7] 1 macro expansion\n 6714 ./boot.jl 235 eval(::Module, ::Any)\n 3511 ./dSFMT.jl 84 dsfmt_fill_array_close_open!(::Base.dSFMT.DSFMT_s...\n 6714 ./event.jl 73 (::Base.REPL.##1#2{Base.REPL.REPLBackend})()\n 6714 ./profile.jl 23 macro expansion\n 3511 ./random.jl 431 rand!(::MersenneTwister, ::Array{Float64,3}, ::In...\n 310 ./random.jl 277 rand\n 310 ./random.jl 278 rand\n 310 ./random.jl 366 rand\n 310 ./random.jl 369 rand\n 2893 ./reduce.jl 270 _mapreduce(::Base.#identity, ::Base.#scalarmax, :...\n 5 ./reduce.jl 420 mapreduce_impl(::Base.#identity, ::Base.#scalarma...\n 253 ./reduce.jl 426 mapreduce_impl(::Base.#identity, ::Base.#scalarma...\n 2592 ./reduce.jl 428 mapreduce_impl(::Base.#identity, ::Base.#scalarma...\n 43 ./reduce.jl 429 mapreduce_impl(::Base.#identity, ::Base.#scalarma...","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"If your code has recursion, one potentially-confusing point is that a line in a \"child\" function can accumulate more counts than there are total backtraces. Consider the following function definitions:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"dumbsum(n::Integer) = n == 1 ? 1 : 1 + dumbsum(n-1)\ndumbsum3() = dumbsum(3)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"If you were to profile dumbsum3, and a backtrace was taken while it was executing dumbsum(1), the backtrace would look like this:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"dumbsum3\n dumbsum(3)\n dumbsum(2)\n dumbsum(1)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Consequently, this child function gets 3 counts, even though the parent only gets one. The \"tree\" representation makes this much clearer, and for this reason (among others) is probably the most useful way to view the results.","category":"page"},{"location":"tutorials/profile/#Accumulation-and-clearing","page":"Profiling","title":"Accumulation and clearing","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Results from @profile accumulate in a buffer; if you run multiple pieces of code under @profile, then Profile.print() will show you the combined results. This can be very useful, but sometimes you want to start fresh; you can do so with Profile.clear().","category":"page"},{"location":"tutorials/profile/#Options-for-controlling-the-display-of-profile-results","page":"Profiling","title":"Options for controlling the display of profile results","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Profile.print has more options than we've described so far. Let's see the full declaration:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"function print(io::IO = stdout, data = fetch(); kwargs...)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Let's first discuss the two positional arguments, and later the keyword arguments:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"io – Allows you to save the results to a buffer, e.g. a file, but the default is to print to stdout (the console).\ndata – Contains the data you want to analyze; by default that is obtained from Profile.fetch(), which pulls out the backtraces from a pre-allocated buffer. For example, if you want to profile the profiler, you could say:\ndata = copy(Profile.fetch())\nProfile.clear()\n@profile Profile.print(stdout, data) # Prints the previous results\nProfile.print() # Prints results from Profile.print()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The keyword arguments can be any combination of:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"format – Introduced above, determines whether backtraces are printed with (default, :tree) or without (:flat) indentation indicating tree structure.\nC – If true, backtraces from C and Fortran code are shown (normally they are excluded). Try running the introductory example with Profile.print(C = true). This can be extremely helpful in deciding whether it's Julia code or C code that is causing a bottleneck; setting C = true also improves the interpretability of the nesting, at the cost of longer profile dumps.\ncombine – Some lines of code contain multiple operations; for example, s += A[i] contains both an array reference (A[i]) and a sum operation. These correspond to different lines in the generated machine code, and hence there may be two or more different addresses captured during backtraces on this line. combine = true lumps them together, and is probably what you typically want, but you can generate an output separately for each unique instruction pointer with combine = false.\nmaxdepth – Limits frames at a depth higher than maxdepth in the :tree format.\nsortedby – Controls the order in :flat format. :filefuncline (default) sorts by the source line, whereas :count sorts in order of number of collected samples.\nnoisefloor – Limits frames that are below the heuristic noise floor of the sample (only applies to format :tree). A suggested value to try for this is 2.0 (the default is 0). This parameter hides samples for which n <= noisefloor * √N, where n is the number of samples on this line, and N is the number of samples for the callee.\nmincount – Limits frames with less than mincount occurrences.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"File/function names are sometimes truncated (with ...), and indentation is truncated with a +n at the beginning, where n is the number of extra spaces that would have been inserted, had there been room. If you want a complete profile of deeply-nested code, often a good idea is to save to a file using a wide displaysize in an IOContext:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"open(\"/tmp/prof.txt\", \"w\") do s\n Profile.print(IOContext(s, :displaysize => (24, 500)))\nend","category":"page"},{"location":"tutorials/profile/#Configuration","page":"Profiling","title":"Configuration","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"@profile just accumulates backtraces, and the analysis happens when you call Profile.print(). For a long-running computation, it's entirely possible that the pre-allocated buffer for storing backtraces will be filled. If that happens, the backtraces stop but your computation continues. As a consequence, you may miss some important profiling data (you will get a warning when that happens).","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"You can obtain and configure the relevant parameters this way:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Profile.init() # returns the current settings\nProfile.init(n = 10^7, delay = 0.01)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"n is the total number of instruction pointers you can store, with a default value of 10^6. If your typical backtrace is 20 instruction pointers, then you can collect 50000 backtraces, which suggests a statistical uncertainty of less than 1%. This may be good enough for most applications.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Consequently, you are more likely to need to modify delay, expressed in seconds, which sets the amount of time that Julia gets between snapshots to perform the requested computations. A very long-running job might not need frequent backtraces. The default setting is delay = 0.001. Of course, you can decrease the delay as well as increase it; however, the overhead of profiling grows once the delay becomes similar to the amount of time needed to take a backtrace (~30 microseconds on the author's laptop).","category":"page"},{"location":"tutorials/profile/#Memory-allocation-analysis","page":"Profiling","title":"Memory allocation analysis","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"One of the most common techniques to improve performance is to reduce memory allocation. Julia provides several tools to measure this:","category":"page"},{"location":"tutorials/profile/#@time","page":"Profiling","title":"@time","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The total amount of allocation can be measured with @time, @allocated and @allocations, and specific lines triggering allocation can often be inferred from profiling via the cost of garbage collection that these lines incur. However, sometimes it is more efficient to directly measure the amount of memory allocated by each line of code.","category":"page"},{"location":"tutorials/profile/#GC-Logging","page":"Profiling","title":"GC Logging","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"While @time logs high-level stats about memory usage and garbage collection over the course of evaluating an expression, it can be useful to log each garbage collection event, to get an intuitive sense of how often the garbage collector is running, how long it's running each time, and how much garbage it collects each time. This can be enabled with GC.enable_logging(true), which causes Julia to log to stderr every time a garbage collection happens.","category":"page"},{"location":"tutorials/profile/#allocation-profiler","page":"Profiling","title":"Allocation Profiler","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"compat: Julia 1.8\nThis functionality requires at least Julia 1.8.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The allocation profiler records the stack trace, type, and size of each allocation while it is running. It can be invoked with Profile.Allocs.@profile.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"This information about the allocations is returned as an array of Alloc objects, wrapped in an AllocResults object. The best way to visualize these is currently with the PProf.jl and ProfileCanvas.jl packages, which can visualize the call stacks which are making the most allocations.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The allocation profiler does have significant overhead, so a sample_rate argument can be passed to speed it up by making it skip some allocations. Passing sample_rate=1.0 will make it record everything (which is slow); sample_rate=0.1 will record only 10% of the allocations (faster), etc.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"compat: Julia 1.11\nOlder versions of Julia could not capture types in all cases. In older versions of Julia, if you see an allocation of type Profile.Allocs.UnknownType, it means that the profiler doesn't know what type of object was allocated. This mainly happened when the allocation was coming from generated code produced by the compiler. See issue #43688 for more info.Since Julia 1.11, all allocations should have a type reported.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"For more details on how to use this tool, please see the following talk from JuliaCon 2022: https://www.youtube.com/watch?v=BFvpwC8hEWQ","category":"page"},{"location":"tutorials/profile/#Allocation-Profiler-Example","page":"Profiling","title":"Allocation Profiler Example","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"In this simple example, we use PProf to visualize the alloc profile. You could use another visualization tool instead. We collect the profile (specifying a sample rate), then we visualize it.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"using Profile, PProf\nProfile.Allocs.clear()\nProfile.Allocs.@profile sample_rate=0.0001 my_function()\nPProf.Allocs.pprof()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Here is a more in-depth example, showing how we can tune the sample rate. A good number of samples to aim for is around 1 - 10 thousand. Too many, and the profile visualizer can get overwhelmed, and profiling will be slow. Too few, and you don't have a representative sample.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> import Profile\n\njulia> @time my_function() # Estimate allocations from a (second-run) of the function\n 0.110018 seconds (1.50 M allocations: 58.725 MiB, 17.17% gc time)\n500000\n\njulia> Profile.Allocs.clear()\n\njulia> Profile.Allocs.@profile sample_rate=0.001 begin # 1.5 M * 0.001 = ~1.5K allocs.\n my_function()\n end\n500000\n\njulia> prof = Profile.Allocs.fetch(); # If you want, you can also manually inspect the results.\n\njulia> length(prof.allocs) # Confirm we have expected number of allocations.\n1515\n\njulia> using PProf # Now, visualize with an external tool, like PProf or ProfileCanvas.\n\njulia> PProf.Allocs.pprof(prof; from_c=false) # You can optionally pass in a previously fetched profile result.\nAnalyzing 1515 allocation samples... 100%|████████████████████████████████| Time: 0:00:00\nMain binary filename not available.\nServing web UI on http://localhost:62261\n\"alloc-profile.pb.gz\"","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Then you can view the profile by navigating to http://localhost:62261, and the profile is saved to disk. See PProf package for more options.","category":"page"},{"location":"tutorials/profile/#Allocation-Profiling-Tips","page":"Profiling","title":"Allocation Profiling Tips","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"As stated above, aim for around 1-10 thousand samples in your profile.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Note that we are uniformly sampling in the space of all allocations, and are not weighting our samples by the size of the allocation. So a given allocation profile may not give a representative profile of where most bytes are allocated in your program, unless you had set sample_rate=1.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Allocations can come from users directly constructing objects, but can also come from inside the runtime or be inserted into compiled code to handle type instability. Looking at the \"source code\" view can be helpful to isolate them, and then other external tools such as Cthulhu.jl can be useful for identifying the cause of the allocation.","category":"page"},{"location":"tutorials/profile/#Allocation-Profile-Visualization-Tools","page":"Profiling","title":"Allocation Profile Visualization Tools","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"There are several profiling visualization tools now that can all display Allocation Profiles. Here is a small list of some of the main ones we know about:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"PProf.jl\nProfileCanvas.jl\nVSCode's built-in profile visualizer (@profview_allocs) [docs needed]\nViewing the results directly in the REPL\nYou can inspect the results in the REPL via Profile.Allocs.fetch(), to view the stacktrace and type of each allocation.","category":"page"},{"location":"tutorials/profile/#Line-by-Line-Allocation-Tracking","page":"Profiling","title":"Line-by-Line Allocation Tracking","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"An alternative way to measure allocations is to start Julia with the --track-allocation= command-line option, for which you can choose none (the default, do not measure allocation), user (measure memory allocation everywhere except Julia's core code), or all (measure memory allocation at each line of Julia code). Allocation gets measured for each line of compiled code. When you quit Julia, the cumulative results are written to text files with .mem appended after the file name, residing in the same directory as the source file. Each line lists the total number of bytes allocated. The Coverage package contains some elementary analysis tools, for example to sort the lines in order of number of bytes allocated.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"In interpreting the results, there are a few important details. Under the user setting, the first line of any function directly called from the REPL will exhibit allocation due to events that happen in the REPL code itself. More significantly, JIT-compilation also adds to allocation counts, because much of Julia's compiler is written in Julia (and compilation usually requires memory allocation). The recommended procedure is to force compilation by executing all the commands you want to analyze, then call Profile.clear_malloc_data() to reset all allocation counters. Finally, execute the desired commands and quit Julia to trigger the generation of the .mem files.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"note: Note\n--track-allocation changes code generation to log the allocations, and so the allocations may be different than what happens without the option. We recommend using the allocation profiler instead.","category":"page"},{"location":"tutorials/profile/#External-Profiling","page":"Profiling","title":"External Profiling","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Currently Julia supports Intel VTune, OProfile and perf as external profiling tools.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Depending on the tool you choose, compile with USE_INTEL_JITEVENTS, USE_OPROFILE_JITEVENTS and USE_PERF_JITEVENTS set to 1 in Make.user. Multiple flags are supported.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Before running Julia set the environment variable ENABLE_JITPROFILING to 1.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Now you have a multitude of ways to employ those tools! For example with OProfile you can try a simple recording :","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":">ENABLE_JITPROFILING=1 sudo operf -Vdebug ./julia test/fastmath.jl\n>opreport -l `which ./julia`","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Or similarly with perf :","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"$ ENABLE_JITPROFILING=1 perf record -o /tmp/perf.data --call-graph dwarf -k 1 ./julia /test/fastmath.jl\n$ perf inject --jit --input /tmp/perf.data --output /tmp/perf-jit.data\n$ perf report --call-graph -G -i /tmp/perf-jit.data","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"There are many more interesting things that you can measure about your program, to get a comprehensive list please read the Linux perf examples page.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Remember that perf saves for each execution a perf.data file that, even for small programs, can get quite large. Also the perf LLVM module saves temporarily debug objects in ~/.debug/jit, remember to clean that folder frequently.","category":"page"},{"location":"devdocs/cartesian/#Base.Cartesian","page":"Base.Cartesian","title":"Base.Cartesian","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"The (non-exported) Cartesian module provides macros that facilitate writing multidimensional algorithms. Most often you can write such algorithms with straightforward techniques; however, there are a few cases where Base.Cartesian is still useful or necessary.","category":"page"},{"location":"devdocs/cartesian/#Principles-of-usage","page":"Base.Cartesian","title":"Principles of usage","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"A simple example of usage is:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@nloops 3 i A begin\n s += @nref 3 A i\nend","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"which generates the following code:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"for i_3 = axes(A, 3)\n for i_2 = axes(A, 2)\n for i_1 = axes(A, 1)\n s += A[i_1, i_2, i_3]\n end\n end\nend","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"In general, Cartesian allows you to write generic code that contains repetitive elements, like the nested loops in this example. Other applications include repeated expressions (e.g., loop unwinding) or creating function calls with variable numbers of arguments without using the \"splat\" construct (i...).","category":"page"},{"location":"devdocs/cartesian/#Basic-syntax","page":"Base.Cartesian","title":"Basic syntax","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"The (basic) syntax of @nloops is as follows:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"The first argument must be an integer (not a variable) specifying the number of loops.\nThe second argument is the symbol-prefix used for the iterator variable. Here we used i, and variables i_1, i_2, i_3 were generated.\nThe third argument specifies the range for each iterator variable. If you use a variable (symbol) here, it's taken as axes(A, dim). More flexibly, you can use the anonymous-function expression syntax described below.\nThe last argument is the body of the loop. Here, that's what appears between the begin...end.","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"There are some additional features of @nloops described in the reference section.","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@nref follows a similar pattern, generating A[i_1,i_2,i_3] from @nref 3 A i. The general practice is to read from left to right, which is why @nloops is @nloops 3 i A expr (as in for i_2 = axes(A, 2), where i_2 is to the left and the range is to the right) whereas @nref is @nref 3 A i (as in A[i_1,i_2,i_3], where the array comes first).","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"If you're developing code with Cartesian, you may find that debugging is easier when you examine the generated code, using @macroexpand:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"DocTestSetup = quote\n import Base.Cartesian: @nref\nend","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"julia> @macroexpand @nref 2 A i\n:(A[i_1, i_2])","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"DocTestSetup = nothing","category":"page"},{"location":"devdocs/cartesian/#Supplying-the-number-of-expressions","page":"Base.Cartesian","title":"Supplying the number of expressions","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"The first argument to both of these macros is the number of expressions, which must be an integer. When you're writing a function that you intend to work in multiple dimensions, this may not be something you want to hard-code. The recommended approach is to use a @generated function. Here's an example:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@generated function mysum(A::Array{T,N}) where {T,N}\n quote\n s = zero(T)\n @nloops $N i A begin\n s += @nref $N A i\n end\n s\n end\nend","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"Naturally, you can also prepare expressions or perform calculations before the quote block.","category":"page"},{"location":"devdocs/cartesian/#Anonymous-function-expressions-as-macro-arguments","page":"Base.Cartesian","title":"Anonymous-function expressions as macro arguments","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"Perhaps the single most powerful feature in Cartesian is the ability to supply anonymous-function expressions that get evaluated at parsing time. Let's consider a simple example:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@nexprs 2 j->(i_j = 1)","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@nexprs generates n expressions that follow a pattern. This code would generate the following statements:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"i_1 = 1\ni_2 = 1","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"In each generated statement, an \"isolated\" j (the variable of the anonymous function) gets replaced by values in the range 1:2. Generally speaking, Cartesian employs a LaTeX-like syntax. This allows you to do math on the index j. Here's an example computing the strides of an array:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"s_1 = 1\n@nexprs 3 j->(s_{j+1} = s_j * size(A, j))","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"would generate expressions","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"s_1 = 1\ns_2 = s_1 * size(A, 1)\ns_3 = s_2 * size(A, 2)\ns_4 = s_3 * size(A, 3)","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"Anonymous-function expressions have many uses in practice.","category":"page"},{"location":"devdocs/cartesian/#dev-cartesian-reference","page":"Base.Cartesian","title":"Macro reference","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"Base.Cartesian.@nloops\nBase.Cartesian.@nref\nBase.Cartesian.@nextract\nBase.Cartesian.@nexprs\nBase.Cartesian.@ncall\nBase.Cartesian.@ncallkw\nBase.Cartesian.@ntuple\nBase.Cartesian.@nall\nBase.Cartesian.@nany\nBase.Cartesian.@nif","category":"page"},{"location":"devdocs/cartesian/#Base.Cartesian.@nloops","page":"Base.Cartesian","title":"Base.Cartesian.@nloops","text":"@nloops N itersym rangeexpr bodyexpr\n@nloops N itersym rangeexpr preexpr bodyexpr\n@nloops N itersym rangeexpr preexpr postexpr bodyexpr\n\nGenerate N nested loops, using itersym as the prefix for the iteration variables. rangeexpr may be an anonymous-function expression, or a simple symbol var in which case the range is axes(var, d) for dimension d.\n\nOptionally, you can provide \"pre\" and \"post\" expressions. These get executed first and last, respectively, in the body of each loop. For example:\n\n@nloops 2 i A d -> j_d = min(i_d, 5) begin\n s += @nref 2 A j\nend\n\nwould generate:\n\nfor i_2 = axes(A, 2)\n j_2 = min(i_2, 5)\n for i_1 = axes(A, 1)\n j_1 = min(i_1, 5)\n s += A[j_1, j_2]\n end\nend\n\nIf you want just a post-expression, supply nothing for the pre-expression. Using parentheses and semicolons, you can supply multi-statement expressions.\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nref","page":"Base.Cartesian","title":"Base.Cartesian.@nref","text":"@nref N A indexexpr\n\nGenerate expressions like A[i_1, i_2, ...]. indexexpr can either be an iteration-symbol prefix, or an anonymous-function expression.\n\nExamples\n\njulia> @macroexpand Base.Cartesian.@nref 3 A i\n:(A[i_1, i_2, i_3])\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nextract","page":"Base.Cartesian","title":"Base.Cartesian.@nextract","text":"@nextract N esym isym\n\nGenerate N variables esym_1, esym_2, ..., esym_N to extract values from isym. isym can be either a Symbol or anonymous-function expression.\n\n@nextract 2 x y would generate\n\nx_1 = y[1]\nx_2 = y[2]\n\nwhile @nextract 3 x d->y[2d-1] yields\n\nx_1 = y[1]\nx_2 = y[3]\nx_3 = y[5]\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nexprs","page":"Base.Cartesian","title":"Base.Cartesian.@nexprs","text":"@nexprs N expr\n\nGenerate N expressions. expr should be an anonymous-function expression.\n\nExamples\n\njulia> @macroexpand Base.Cartesian.@nexprs 4 i -> y[i] = A[i+j]\nquote\n y[1] = A[1 + j]\n y[2] = A[2 + j]\n y[3] = A[3 + j]\n y[4] = A[4 + j]\nend\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@ncall","page":"Base.Cartesian","title":"Base.Cartesian.@ncall","text":"@ncall N f sym...\n\nGenerate a function call expression. sym represents any number of function arguments, the last of which may be an anonymous-function expression and is expanded into N arguments.\n\nFor example, @ncall 3 func a generates\n\nfunc(a_1, a_2, a_3)\n\nwhile @ncall 2 func a b i->c[i] yields\n\nfunc(a, b, c[1], c[2])\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@ncallkw","page":"Base.Cartesian","title":"Base.Cartesian.@ncallkw","text":"@ncallkw N f kw sym...\n\nGenerate a function call expression with keyword arguments kw.... As in the case of @ncall, sym represents any number of function arguments, the last of which may be an anonymous-function expression and is expanded into N arguments.\n\nExamples\n\njulia> using Base.Cartesian\n\njulia> f(x...; a, b = 1, c = 2, d = 3) = +(x..., a, b, c, d);\n\njulia> x_1, x_2 = (-1, -2); b = 0; kw = (c = 0, d = 0);\n\njulia> @ncallkw 2 f (; a = 0, b, kw...) x\n-3\n\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@ntuple","page":"Base.Cartesian","title":"Base.Cartesian.@ntuple","text":"@ntuple N expr\n\nGenerates an N-tuple. @ntuple 2 i would generate (i_1, i_2), and @ntuple 2 k->k+1 would generate (2,3).\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nall","page":"Base.Cartesian","title":"Base.Cartesian.@nall","text":"@nall N expr\n\nCheck whether all of the expressions generated by the anonymous-function expression expr evaluate to true.\n\n@nall 3 d->(i_d > 1) would generate the expression (i_1 > 1 && i_2 > 1 && i_3 > 1). This can be convenient for bounds-checking.\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nany","page":"Base.Cartesian","title":"Base.Cartesian.@nany","text":"@nany N expr\n\nCheck whether any of the expressions generated by the anonymous-function expression expr evaluate to true.\n\n@nany 3 d->(i_d > 1) would generate the expression (i_1 > 1 || i_2 > 1 || i_3 > 1).\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nif","page":"Base.Cartesian","title":"Base.Cartesian.@nif","text":"@nif N conditionexpr expr\n@nif N conditionexpr expr elseexpr\n\nGenerates a sequence of if ... elseif ... else ... end statements. For example:\n\n@nif 3 d->(i_d >= size(A,d)) d->(error(\"Dimension \", d, \" too big\")) d->println(\"All OK\")\n\nwould generate:\n\nif i_1 > size(A, 1)\n error(\"Dimension \", 1, \" too big\")\nelseif i_2 > size(A, 2)\n error(\"Dimension \", 2, \" too big\")\nelse\n println(\"All OK\")\nend\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/pkgimg/#pkgimages","page":"Package Images","title":"Package Images","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Julia package images provide object (native code) caches for Julia packages. They are similar to Julia's system image and support many of the same features. In fact the underlying serialization format is the same, and the system image is the base image that the package images are build against.","category":"page"},{"location":"devdocs/pkgimg/#High-level-overview","page":"Package Images","title":"High-level overview","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Package images are shared libraries that contain both code and data. Like .ji cache files, they are generated per package. The data section contains both global data (global variables in the package) as well as the necessary metadata about what methods and types are defined by the package. The code section contains native objects that cache the final output of Julia's LLVM-based compiler.","category":"page"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"The command line option --pkgimages=no can be used to turn off object caching for this session. Note that this means that cache files have to likely be regenerated. See JULIA_MAX_NUM_PRECOMPILE_FILES for the upper limit of variants Julia caches per default.","category":"page"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"note: Note\nWhile the package images present themselves as native shared libraries, they are only an approximation thereof. You will not be able to link against them from a native program and they must be loaded from Julia.","category":"page"},{"location":"devdocs/pkgimg/#Linking","page":"Package Images","title":"Linking","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Since the package images contain native code, we must run a linker over them before we can use them. You can set the environment variable JULIA_VERBOSE_LINKING to true to make the package image linking process verbose.","category":"page"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Furthermore, we cannot assume that the user has a working system linker installed. Therefore, Julia ships with LLD, the LLVM linker, to provide a working out of the box experience. In base/linking.jl, we implement a limited interface to be able to link package images on all supported platforms.","category":"page"},{"location":"devdocs/pkgimg/#Quirks","page":"Package Images","title":"Quirks","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Despite LLD being a multi-platform linker, it does not provide a consistent interface across platforms. Furthermore, it is meant to be used from clang or another compiler driver, we therefore reimplement some of the logic from llvm-project/clang/lib/Driver/ToolChains. Thankfully one can use lld -flavor to set lld to the right platform","category":"page"},{"location":"devdocs/pkgimg/#Windows","page":"Package Images","title":"Windows","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"To avoid having to deal with link.exe we use -flavor gnu, effectively turning lld into a cross-linker from a mingw32 environment. Windows DLLs are required to contain a _DllMainCRTStartup function and to minimize our dependence on mingw32 libraries, we inject a stub definition ourselves.","category":"page"},{"location":"devdocs/pkgimg/#MacOS","page":"Package Images","title":"MacOS","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Dynamic libraries on macOS need to link against -lSystem. On recent macOS versions, -lSystem is only available for linking when Xcode is available. To that effect we link with -undefined dynamic_lookup.","category":"page"},{"location":"devdocs/pkgimg/#pkgimgs-multi-versioning","page":"Package Images","title":"Package images optimized for multiple microarchitectures","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Similar to multi-versioning for system images, package images support multi-versioning. If you are in a heterogeneous environment, with a unified cache, you can set the environment variable JULIA_CPU_TARGET=generic to multi-version the object caches.","category":"page"},{"location":"devdocs/pkgimg/#Flags-that-impact-package-image-creation-and-selection","page":"Package Images","title":"Flags that impact package image creation and selection","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"These are the Julia command line flags that impact cache selection. Package images that were created with different flags will be rejected.","category":"page"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"-g, --debug-info: Exact match required since it changes code generation.\n--check-bounds: Exact match required since it changes code generation.\n--inline: Exact match required since it changes code generation.\n--pkgimages: To allow running without object caching enabled.\n-O, --optimize: Reject package images generated for a lower optimization level, but allow for higher optimization levels to be loaded.","category":"page"},{"location":"devdocs/precompile_hang/#Fixing-precompilation-hangs-due-to-open-tasks-or-IO","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"","category":"section"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"On Julia 1.10 or higher, you might see the following message:","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"(Image: Screenshot of precompilation hang)","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"This may repeat. If it continues to repeat with no hints that it will resolve itself, you may have a \"precompilation hang\" that requires fixing. Even if it's transient, you might prefer to resolve it so that users will not be bothered by this warning. This page walks you through how to analyze and fix such issues.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"If you follow the advice and hit Ctrl-C, you might see","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"^C Interrupted: Exiting precompilation...\n\n 1 dependency had warnings during precompilation:\n┌ Test1 [ac89d554-e2ba-40bc-bc5c-de68b658c982]\n│ [pid 2745] waiting for IO to finish:\n│ Handle type uv_handle_t->data\n│ timer 0x55580decd1e0->0x7f94c3a4c340","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"This message conveys two key pieces of information:","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"the hang is occurring during precompilation of Test1, a dependency of Test2 (the package we were trying to load with using Test2)\nduring precompilation of Test1, Julia created a Timer object (use ?Timer if you're unfamiliar with Timers) which is still open; until that closes, the process is hung","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"If this is enough of a hint for you to figure out how timer = Timer(args...) is being created, one good solution is to add wait(timer) if timer eventually finishes on its own, or close(timer) if you need to force-close it, before the final end of the module.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"However, there are cases that may not be that straightforward. Usually the best option is to start by determining whether the hang is due to code in Test1 or whether it is due to one of Test1's dependencies:","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Option 1: Pkg.add(\"Aqua\") and use Aqua.test_persistent_tasks. This should help you identify which package is causing the problem, after which the instructions below should be followed. If needed, you can create a PkgId as Base.PkgId(UUID(\"...\"), \"Test1\"), where ... comes from the uuid entry in Test1/Project.toml.\nOption 2: manually diagnose the source of the hang.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"To manually diagnose:","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Pkg.develop(\"Test1\")\nComment out all the code included or defined in Test1, except the using/import statements.\nTry using Test2 (or even using Test1 assuming that hangs too) again","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Now we arrive at a fork in the road: either","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"the hang persists, indicating it is due to one of your dependencies\nthe hang disappears, indicating that it is due to something in your code.","category":"page"},{"location":"devdocs/precompile_hang/#pchang_deps","page":"Fixing precompilation hangs due to open tasks or IO","title":"Diagnosing and fixing hangs due to a package dependency","text":"","category":"section"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Use a binary search to identify the problematic dependency: start by commenting out half your dependencies, then when you isolate which half is responsible comment out half of that half, etc. (You don't have to remove them from the project, just comment out the using/import statements.)","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Once you've identified a suspect (here we'll call it ThePackageYouThinkIsCausingTheProblem), first try precompiling that package. If it also hangs during precompilation, continue chasing the problem backwards.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"However, most likely ThePackageYouThinkIsCausingTheProblem will precompile fine. This suggests it's in the function ThePackageYouThinkIsCausingTheProblem.__init__, which does not run during precompilation of ThePackageYouThinkIsCausingTheProblem but does in any package that loads ThePackageYouThinkIsCausingTheProblem. To test this theory, set up a minimal working example (MWE), something like","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"(@v1.10) pkg> generate MWE\n Generating project MWE:\n MWE\\Project.toml\n MWE\\src\\MWE.jl","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"where the source code of MWE.jl is","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"module MWE\nusing ThePackageYouThinkIsCausingTheProblem\nend","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"and you've added ThePackageYouThinkIsCausingTheProblem to MWE's dependencies.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"If that MWE reproduces the hang, you've found your culprit: ThePackageYouThinkIsCausingTheProblem.__init__ must be creating the Timer object. If the timer object can be safely closed, that's a good option. Otherwise, the most common solution is to avoid creating the timer while any package is being precompiled: add","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"ccall(:jl_generating_output, Cint, ()) == 1 && return nothing","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"as the first line of ThePackageYouThinkIsCausingTheProblem.__init__, and it will avoid doing any initialization in any Julia process whose purpose is to precompile packages.","category":"page"},{"location":"devdocs/precompile_hang/#pchang_fix","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing package code to avoid hangs","text":"","category":"section"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Search your package for suggestive words (here like \"Timer\") and see if you can identify where the problem is being created. Note that a method definition like","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"maketimer() = Timer(timer -> println(\"hi\"), 0; interval=1)","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"is not problematic in and of itself: it can cause this problem only if maketimer gets called while the module is being defined. This might be happening from a top-level statement such as","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"const GLOBAL_TIMER = maketimer()","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"or it might conceivably occur in a precompile workload.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"If you struggle to identify the causative lines, then consider doing a binary search: comment out sections of your package (or include lines to omit entire files) until you've reduced the problem in scope.","category":"page"},{"location":"stdlib/SharedArrays/","page":"Shared Arrays","title":"Shared Arrays","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/SharedArrays/docs/src/index.md\"","category":"page"},{"location":"stdlib/SharedArrays/#Shared-Arrays","page":"Shared Arrays","title":"Shared Arrays","text":"","category":"section"},{"location":"stdlib/SharedArrays/","page":"Shared Arrays","title":"Shared Arrays","text":"SharedArray represents an array, which is shared across multiple processes, on a single machine.","category":"page"},{"location":"stdlib/SharedArrays/","page":"Shared Arrays","title":"Shared Arrays","text":"SharedArrays.SharedArray\nSharedArrays.SharedVector\nSharedArrays.SharedMatrix\nSharedArrays.procs(::SharedArray)\nSharedArrays.sdata\nSharedArrays.indexpids\nSharedArrays.localindices","category":"page"},{"location":"stdlib/SharedArrays/#SharedArrays.SharedArray","page":"Shared Arrays","title":"SharedArrays.SharedArray","text":"SharedArray{T}(dims::NTuple; init=false, pids=Int[])\nSharedArray{T,N}(...)\n\nConstruct a SharedArray of a bits type T and size dims across the processes specified by pids - all of which have to be on the same host. If N is specified by calling SharedArray{T,N}(dims), then N must match the length of dims.\n\nIf pids is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, localindices and indexpids will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.\n\nIf an init function of the type initfn(S::SharedArray) is specified, it is called on all the participating workers.\n\nThe shared array is valid as long as a reference to the SharedArray object exists on the node which created the mapping.\n\nSharedArray{T}(filename::AbstractString, dims::NTuple, [offset=0]; mode=nothing, init=false, pids=Int[])\nSharedArray{T,N}(...)\n\nConstruct a SharedArray backed by the file filename, with element type T (must be a bits type) and size dims, across the processes specified by pids - all of which have to be on the same host. This file is mmapped into the host memory, with the following consequences:\n\nThe array data must be represented in binary format (e.g., an ASCII format like CSV cannot be supported)\nAny changes you make to the array values (e.g., A[3] = 0) will also change the values on disk\n\nIf pids is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, localindices and indexpids will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.\n\nmode must be one of \"r\", \"r+\", \"w+\", or \"a+\", and defaults to \"r+\" if the file specified by filename already exists, or \"w+\" if not. If an init function of the type initfn(S::SharedArray) is specified, it is called on all the participating workers. You cannot specify an init function if the file is not writable.\n\noffset allows you to skip the specified number of bytes at the beginning of the file.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SharedArrays/#SharedArrays.SharedVector","page":"Shared Arrays","title":"SharedArrays.SharedVector","text":"SharedVector\n\nA one-dimensional SharedArray.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SharedArrays/#SharedArrays.SharedMatrix","page":"Shared Arrays","title":"SharedArrays.SharedMatrix","text":"SharedMatrix\n\nA two-dimensional SharedArray.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SharedArrays/#Distributed.procs-Tuple{SharedArray}","page":"Shared Arrays","title":"Distributed.procs","text":"procs(S::SharedArray)\n\nGet the vector of processes mapping the shared array.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/SharedArrays/#SharedArrays.sdata","page":"Shared Arrays","title":"SharedArrays.sdata","text":"sdata(S::SharedArray)\n\nReturn the actual Array object backing S.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SharedArrays/#SharedArrays.indexpids","page":"Shared Arrays","title":"SharedArrays.indexpids","text":"indexpids(S::SharedArray)\n\nReturn the current worker's index in the list of workers mapping the SharedArray (i.e. in the same list returned by procs(S)), or 0 if the SharedArray is not mapped locally.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SharedArrays/#SharedArrays.localindices","page":"Shared Arrays","title":"SharedArrays.localindices","text":"localindices(S::SharedArray)\n\nReturn a range describing the \"default\" indices to be handled by the current process. This range should be interpreted in the sense of linear indexing, i.e., as a sub-range of 1:length(S). In multi-process contexts, returns an empty range in the parent process (or any process for which indexpids returns 0).\n\nIt's worth emphasizing that localindices exists purely as a convenience, and you can partition work on the array among workers any way you wish. For a SharedArray, all indices should be equally fast for each worker process.\n\n\n\n\n\n","category":"function"},{"location":"manual/modules/#modules","page":"Modules","title":"Modules","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Modules in Julia help organize code into coherent units. They are delimited syntactically inside module NameOfModule ... end, and have the following features:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Modules are separate namespaces, each introducing a new global scope. This is useful, because it allows the same name to be used for different functions or global variables without conflict, as long as they are in separate modules.\nModules have facilities for detailed namespace management: each defines a set of names it exports and marks as public, and can import names from other modules with using and import (we explain these below).\nModules can be precompiled for faster loading, and may contain code for runtime initialization.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Typically, in larger Julia packages you will see module code organized into files, eg","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"module SomeModule\n\n# export, public, using, import statements are usually here; we discuss these below\n\ninclude(\"file1.jl\")\ninclude(\"file2.jl\")\n\nend","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Files and file names are mostly unrelated to modules; modules are associated only with module expressions. One can have multiple files per module, and multiple modules per file. include behaves as if the contents of the source file were evaluated in the global scope of the including module. In this chapter, we use short and simplified examples, so we won't use include.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"The recommended style is not to indent the body of the module, since that would typically lead to whole files being indented. Also, it is common to use UpperCamelCase for module names (just like types), and use the plural form if applicable, especially if the module contains a similarly named identifier, to avoid name clashes. For example,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"module FastThings\n\nstruct FastThing\n ...\nend\n\nend","category":"page"},{"location":"manual/modules/#namespace-management","page":"Modules","title":"Namespace management","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Namespace management refers to the facilities the language offers for making names in a module available in other modules. We discuss the related concepts and functionality below in detail.","category":"page"},{"location":"manual/modules/#Qualified-names","page":"Modules","title":"Qualified names","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Names for functions, variables and types in the global scope like sin, ARGS, and UnitRange always belong to a module, called the parent module, which can be found interactively with parentmodule, for example","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> parentmodule(UnitRange)\nBase","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"One can also refer to these names outside their parent module by prefixing them with their module, eg Base.UnitRange. This is called a qualified name. The parent module may be accessible using a chain of submodules like Base.Math.sin, where Base.Math is called the module path. Due to syntactic ambiguities, qualifying a name that contains only symbols, such as an operator, requires inserting a colon, e.g. Base.:+. A small number of operators additionally require parentheses, e.g. Base.:(==).","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"If a name is qualified, then it is always accessible, and in case of a function, it can also have methods added to it by using the qualified name as the function name.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Within a module, a variable name can be “reserved” without assigning to it by declaring it as global x. This prevents name conflicts for globals initialized after load time. The syntax M.x = y does not work to assign a global in another module; global assignment is always module-local.","category":"page"},{"location":"manual/modules/#Export-lists","page":"Modules","title":"Export lists","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Names (referring to functions, types, global variables, and constants) can be added to the export list of a module with export: these are the symbols that are imported when using the module. Typically, they are at or near the top of the module definition so that readers of the source code can find them easily, as in","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> module NiceStuff\n export nice, DOG\n struct Dog end # singleton type, not exported\n const DOG = Dog() # named instance, exported\n nice(x) = \"nice $x\" # function, exported\n end;\n","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"but this is just a style suggestion — a module can have multiple export statements in arbitrary locations.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"It is common to export names which form part of the API (application programming interface). In the above code, the export list suggests that users should use nice and DOG. However, since qualified names always make identifiers accessible, this is just an option for organizing APIs: unlike other languages, Julia has no facilities for truly hiding module internals.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Also, some modules don't export names at all. This is usually done if they use common words, such as derivative, in their API, which could easily clash with the export lists of other modules. We will see how to manage name clashes below.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"To mark a name as public without exporting it into the namespace of folks who call using NiceStuff, one can use public instead of export. This marks the public name(s) as part of the public API, but does not have any namespace implications. The public keyword is only available in Julia 1.11 and above. To maintain compatibility with Julia 1.10 and below, use the @compat macro from the Compat package.","category":"page"},{"location":"manual/modules/#Standalone-using-and-import","page":"Modules","title":"Standalone using and import","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Possibly the most common way of loading a module is using ModuleName. This loads the code associated with ModuleName, and brings","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"the module name\nand the elements of the export list into the surrounding global namespace.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Technically, the statement using ModuleName means that a module called ModuleName will be available for resolving names as needed. When a global variable is encountered that has no definition in the current module, the system will search for it among variables exported by ModuleName and use it if it is found there. This means that all uses of that global within the current module will resolve to the definition of that variable in ModuleName.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"To load a module from a package, the statement using ModuleName can be used. To load a module from a locally defined module, a dot needs to be added before the module name like using .ModuleName.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"To continue with our example,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"would load the above code, making NiceStuff (the module name), DOG and nice available. Dog is not on the export list, but it can be accessed if the name is qualified with the module path (which here is just the module name) as NiceStuff.Dog.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Importantly, using ModuleName is the only form for which export lists matter at all.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"In contrast,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> import .NiceStuff","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"brings only the module name into scope. Users would need to use NiceStuff.DOG, NiceStuff.Dog, and NiceStuff.nice to access its contents. Usually, import ModuleName is used in contexts when the user wants to keep the namespace clean. As we will see in the next section import .NiceStuff is equivalent to using .NiceStuff: NiceStuff.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"You can combine multiple using and import statements of the same kind in a comma-separated expression, e.g.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using LinearAlgebra, Random","category":"page"},{"location":"manual/modules/#using-and-import-with-specific-identifiers,-and-adding-methods","page":"Modules","title":"using and import with specific identifiers, and adding methods","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"When using ModuleName: or import ModuleName: is followed by a comma-separated list of names, the module is loaded, but only those specific names are brought into the namespace by the statement. For example,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff: nice, DOG","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"will import the names nice and DOG.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Importantly, the module name NiceStuff will not be in the namespace. If you want to make it accessible, you have to list it explicitly, as","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff: nice, DOG, NiceStuff","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Julia has two forms for seemingly the same thing because only import ModuleName: f allows adding methods to f without a module path. That is to say, the following example will give an error:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff: nice\n\njulia> struct Cat end\n\njulia> nice(::Cat) = \"nice 😸\"\nERROR: invalid method definition in Main: function NiceStuff.nice must be explicitly imported to be extended\nStacktrace:\n [1] top-level scope\n @ none:0\n [2] top-level scope\n @ none:1","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"This error prevents accidentally adding methods to functions in other modules that you only intended to use.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"There are two ways to deal with this. You can always qualify function names with a module path:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff\n\njulia> struct Cat end\n\njulia> NiceStuff.nice(::Cat) = \"nice 😸\"","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Alternatively, you can import the specific function name:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> import .NiceStuff: nice\n\njulia> struct Mouse end\n\njulia> nice(::Mouse) = \"nice 🐭\"\nnice (generic function with 3 methods)","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Which one you choose is a matter of style. The first form makes it clear that you are adding a method to a function in another module (remember, that the imports and the method definition may be in separate files), while the second one is shorter, which is especially convenient if you are defining multiple methods.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Once a variable is made visible via using or import, a module may not create its own variable with the same name. Imported variables are read-only; assigning to a global variable always affects a variable owned by the current module, or else raises an error.","category":"page"},{"location":"manual/modules/#Renaming-with-as","page":"Modules","title":"Renaming with as","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"An identifier brought into scope by import or using can be renamed with the keyword as. This is useful for working around name conflicts as well as for shortening names. For example, Base exports the function name read, but the CSV.jl package also provides CSV.read. If we are going to invoke CSV reading many times, it would be convenient to drop the CSV. qualifier. But then it is ambiguous whether we are referring to Base.read or CSV.read:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> read;\n\njulia> import CSV: read\nWARNING: ignoring conflicting import of CSV.read into Main","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Renaming provides a solution:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> import CSV: read as rd","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Imported packages themselves can also be renamed:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"import BenchmarkTools as BT","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"as works with using only when a single identifier is brought into scope. For example using CSV: read as rd works, but using CSV as C does not, since it operates on all of the exported names in CSV.","category":"page"},{"location":"manual/modules/#Mixing-multiple-using-and-import-statements","page":"Modules","title":"Mixing multiple using and import statements","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"When multiple using or import statements of any of the forms above are used, their effect is combined in the order they appear. For example,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff # exported names and the module name\n\njulia> import .NiceStuff: nice # allows adding methods to unqualified functions\n","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"would bring all the exported names of NiceStuff and the module name itself into scope, and also allow adding methods to nice without prefixing it with a module name.","category":"page"},{"location":"manual/modules/#Handling-name-conflicts","page":"Modules","title":"Handling name conflicts","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Consider the situation where two (or more) packages export the same name, as in","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> module A\n export f\n f() = 1\n end\nA\njulia> module B\n export f\n f() = 2\n end\nB","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"The statement using .A, .B works, but when you try to call f, you get a warning","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .A, .B\n\njulia> f\nWARNING: both B and A export \"f\"; uses of it in module Main must be qualified\nERROR: UndefVarError: `f` not defined in `Main`","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Here, Julia cannot decide which f you are referring to, so you have to make a choice. The following solutions are commonly used:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Simply proceed with qualified names like A.f and B.f. This makes the context clear to the reader of your code, especially if f just happens to coincide but has different meaning in various packages. For example, degree has various uses in mathematics, the natural sciences, and in everyday life, and these meanings should be kept separate.\nUse the as keyword above to rename one or both identifiers, eg\njulia> using .A: f as f\n\njulia> using .B: f as g\n\nwould make B.f available as g. Here, we are assuming that you did not use using A before, which would have brought f into the namespace.\nWhen the names in question do share a meaning, it is common for one module to import it from another, or have a lightweight “base” package with the sole function of defining an interface like this, which can be used by other packages. It is conventional to have such package names end in ...Base (which has nothing to do with Julia's Base module).","category":"page"},{"location":"manual/modules/#Default-top-level-definitions-and-bare-modules","page":"Modules","title":"Default top-level definitions and bare modules","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Modules automatically contain using Core, using Base, and definitions of the eval and include functions, which evaluate expressions/files within the global scope of that module.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"If these default definitions are not wanted, modules can be defined using the keyword baremodule instead (note: Core is still imported). In terms of baremodule, a standard module looks like this:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"baremodule Mod\n\nusing Base\n\neval(x) = Core.eval(Mod, x)\ninclude(p) = Base.include(Mod, p)\n\n...\n\nend","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"If even Core is not wanted, a module that imports nothing and defines no names at all can be defined with Module(:YourNameHere, false, false) and code can be evaluated into it with @eval or Core.eval:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> arithmetic = Module(:arithmetic, false, false)\nMain.arithmetic\n\njulia> @eval arithmetic add(x, y) = $(+)(x, y)\nadd (generic function with 1 method)\n\njulia> arithmetic.add(12, 13)\n25","category":"page"},{"location":"manual/modules/#Standard-modules","page":"Modules","title":"Standard modules","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"There are three important standard modules:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Core contains all functionality \"built into\" the language.\nBase contains basic functionality that is useful in almost all cases.\nMain is the top-level module and the current module, when Julia is started.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"note: Standard library modules\nBy default Julia ships with some standard library modules. These behave like regular Julia packages except that you don't need to install them explicitly. For example, if you wanted to perform some unit testing, you could load the Test standard library as follows:using Test","category":"page"},{"location":"manual/modules/#Submodules-and-relative-paths","page":"Modules","title":"Submodules and relative paths","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Modules can contain submodules, nesting the same syntax module ... end. They can be used to introduce separate namespaces, which can be helpful for organizing complex codebases. Note that each module introduces its own scope, so submodules do not automatically “inherit” names from their parent.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"It is recommended that submodules refer to other modules within the enclosing parent module (including the latter) using relative module qualifiers in using and import statements. A relative module qualifier starts with a period (.), which corresponds to the current module, and each successive . leads to the parent of the current module. This should be followed by modules if necessary, and eventually the actual name to access, all separated by .s.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Consider the following example, where the submodule SubA defines a function, which is then extended in its “sibling” module:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> module ParentModule\n module SubA\n export add_D # exported interface\n const D = 3\n add_D(x) = x + D\n end\n using .SubA # brings `add_D` into the namespace\n export add_D # export it from ParentModule too\n module SubB\n import ..SubA: add_D # relative path for a “sibling” module\n struct Infinity end\n add_D(x::Infinity) = x\n end\n end;\n","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"You may see code in packages, which, in a similar situation, uses","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> import .ParentModule.SubA: add_D\n","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"However, this operates through code loading, and thus only works if ParentModule is in a package. It is better to use relative paths.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Note that the order of definitions also matters if you are evaluating values. Consider","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"module TestPackage\n\nexport x, y\n\nx = 0\n\nmodule Sub\nusing ..TestPackage\nz = y # ERROR: UndefVarError: `y` not defined in `Main`\nend\n\ny = 1\n\nend","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"where Sub is trying to use TestPackage.y before it was defined, so it does not have a value.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"For similar reasons, you cannot use a cyclic ordering:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"module A\n\nmodule B\nusing ..C # ERROR: UndefVarError: `C` not defined in `Main.A`\nend\n\nmodule C\nusing ..B\nend\n\nend","category":"page"},{"location":"manual/modules/#Module-initialization-and-precompilation","page":"Modules","title":"Module initialization and precompilation","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Large modules can take several seconds to load because executing all of the statements in a module often involves compiling a large amount of code. Julia creates precompiled caches of the module to reduce this time.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Precompiled module files (sometimes called \"cache files\") are created and used automatically when import or using loads a module. If the cache file(s) do not yet exist, the module will be compiled and saved for future reuse. You can also manually call Base.compilecache(Base.identify_package(\"modulename\")) to create these files without loading the module. The resulting cache files will be stored in the compiled subfolder of DEPOT_PATH[1]. If nothing about your system changes, such cache files will be used when you load the module with import or using.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Precompilation cache files store definitions of modules, types, methods, and constants. They may also store method specializations and the code generated for them, but this typically requires that the developer add explicit precompile directives or execute workloads that force compilation during the package build.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"However, if you update the module's dependencies or change its source code, the module is automatically recompiled upon using or import. Dependencies are modules it imports, the Julia build, files it includes, or explicit dependencies declared by include_dependency(path) in the module file(s).","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"For file dependencies loaded by include, a change is determined by examining whether the file size (fsize) or content (condensed into a hash) is unchanged. For file dependencies loaded by include_dependency a change is determined by examining whether the modification time (mtime) is unchanged, or equal to the modification time truncated to the nearest second (to accommodate systems that can't copy mtime with sub-second accuracy). It also takes into account whether the path to the file chosen by the search logic in require matches the path that had created the precompile file. It also takes into account the set of dependencies already loaded into the current process and won't recompile those modules, even if their files change or disappear, in order to avoid creating incompatibilities between the running system and the precompile cache. Finally, it takes account of changes in any compile-time preferences.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"If you know that a module is not safe to precompile (for example, for one of the reasons described below), you should put __precompile__(false) in the module file (typically placed at the top). This will cause Base.compilecache to throw an error, and will cause using / import to load it directly into the current process and skip the precompile and caching. This also thereby prevents the module from being imported by any other precompiled module.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"You may need to be aware of certain behaviors inherent in the creation of incremental shared libraries which may require care when writing your module. For example, external state is not preserved. To accommodate this, explicitly separate any initialization steps that must occur at runtime from steps that can occur at compile time. For this purpose, Julia allows you to define an __init__() function in your module that executes any initialization steps that must occur at runtime. This function will not be called during compilation (--output-*). Effectively, you can assume it will be run exactly once in the lifetime of the code. You may, of course, call it manually if necessary, but the default is to assume this function deals with computing state for the local machine, which does not need to be – or even should not be – captured in the compiled image. It will be called after the module is loaded into a process, including if it is being loaded into an incremental compile (--output-incremental=yes), but not if it is being loaded into a full-compilation process.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"In particular, if you define a function __init__() in a module, then Julia will call __init__() immediately after the module is loaded (e.g., by import, using, or require) at runtime for the first time (i.e., __init__ is only called once, and only after all statements in the module have been executed). Because it is called after the module is fully imported, any submodules or other imported modules have their __init__ functions called before the __init__ of the enclosing module.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Two typical uses of __init__ are calling runtime initialization functions of external C libraries and initializing global constants that involve pointers returned by external libraries. For example, suppose that we are calling a C library libfoo that requires us to call a foo_init() initialization function at runtime. Suppose that we also want to define a global constant foo_data_ptr that holds the return value of a void *foo_data() function defined by libfoo – this constant must be initialized at runtime (not at compile time) because the pointer address will change from run to run. You could accomplish this by defining the following __init__ function in your module:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"const foo_data_ptr = Ref{Ptr{Cvoid}}(0)\nfunction __init__()\n ccall((:foo_init, :libfoo), Cvoid, ())\n foo_data_ptr[] = ccall((:foo_data, :libfoo), Ptr{Cvoid}, ())\n nothing\nend","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Notice that it is perfectly possible to define a global inside a function like __init__; this is one of the advantages of using a dynamic language. But by making it a constant at global scope, we can ensure that the type is known to the compiler and allow it to generate better optimized code. Obviously, any other globals in your module that depends on foo_data_ptr would also have to be initialized in __init__.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Constants involving most Julia objects that are not produced by ccall do not need to be placed in __init__: their definitions can be precompiled and loaded from the cached module image. This includes complicated heap-allocated objects like arrays. However, any routine that returns a raw pointer value must be called at runtime for precompilation to work (Ptr objects will turn into null pointers unless they are hidden inside an isbits object). This includes the return values of the Julia functions @cfunction and pointer.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Dictionary and set types, or in general anything that depends on the output of a hash(key) method, are a trickier case. In the common case where the keys are numbers, strings, symbols, ranges, Expr, or compositions of these types (via arrays, tuples, sets, pairs, etc.) they are safe to precompile. However, for a few other key types, such as Function or DataType and generic user-defined types where you haven't defined a hash method, the fallback hash method depends on the memory address of the object (via its objectid) and hence may change from run to run. If you have one of these key types, or if you aren't sure, to be safe you can initialize this dictionary from within your __init__ function. Alternatively, you can use the IdDict dictionary type, which is specially handled by precompilation so that it is safe to initialize at compile-time.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"When using precompilation, it is important to keep a clear sense of the distinction between the compilation phase and the execution phase. In this mode, it will often be much more clearly apparent that Julia is a compiler which allows execution of arbitrary Julia code, not a standalone interpreter that also generates compiled code.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Other known potential failure scenarios include:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Global counters (for example, for attempting to uniquely identify objects). Consider the following code snippet:\nmutable struct UniquedById\n myid::Int\n let counter = 0\n UniquedById() = new(counter += 1)\n end\nend\nwhile the intent of this code was to give every instance a unique id, the counter value is recorded at the end of compilation. All subsequent usages of this incrementally compiled module will start from that same counter value.\nNote that objectid (which works by hashing the memory pointer) has similar issues (see notes on Dict usage below).\nOne alternative is to use a macro to capture @__MODULE__ and store it alone with the current counter value, however, it may be better to redesign the code to not depend on this global state.\nAssociative collections (such as Dict and Set) need to be re-hashed in __init__. (In the future, a mechanism may be provided to register an initializer function.)\nDepending on compile-time side-effects persisting through load-time. Example include: modifying arrays or other variables in other Julia modules; maintaining handles to open files or devices; storing pointers to other system resources (including memory);\nCreating accidental \"copies\" of global state from another module, by referencing it directly instead of via its lookup path. For example, (in global scope):\n#mystdout = Base.stdout #= will not work correctly, since this will copy Base.stdout into this module =#\n# instead use accessor functions:\ngetstdout() = Base.stdout #= best option =#\n# or move the assignment into the runtime:\n__init__() = global mystdout = Base.stdout #= also works =#","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Several additional restrictions are placed on the operations that can be done while precompiling code to help the user avoid other wrong-behavior situations:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Calling eval to cause a side-effect in another module. This will also cause a warning to be emitted when the incremental precompile flag is set.\nglobal const statements from local scope after __init__() has been started (see issue #12010 for plans to add an error for this)\nReplacing a module is a runtime error while doing an incremental precompile.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"A few other points to be aware of:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"No code reload / cache invalidation is performed after changes are made to the source files themselves, (including by Pkg.update), and no cleanup is done after Pkg.rm\nThe memory sharing behavior of a reshaped array is disregarded by precompilation (each view gets its own copy)\nExpecting the filesystem to be unchanged between compile-time and runtime e.g. @__FILE__/source_path() to find resources at runtime, or the BinDeps @checked_lib macro. Sometimes this is unavoidable. However, when possible, it can be good practice to copy resources into the module at compile-time so they won't need to be found at runtime.\nWeakRef objects and finalizers are not currently handled properly by the serializer (this will be fixed in an upcoming release).\nIt is usually best to avoid capturing references to instances of internal metadata objects such as Method, MethodInstance, MethodTable, TypeMapLevel, TypeMapEntry and fields of those objects, as this can confuse the serializer and may not lead to the outcome you desire. It is not necessarily an error to do this, but you simply need to be prepared that the system will try to copy some of these and to create a single unique instance of others.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"It is sometimes helpful during module development to turn off incremental precompilation. The command line flag --compiled-modules={yes|no|existing} enables you to toggle module precompilation on and off. When Julia is started with --compiled-modules=no the serialized modules in the compile cache are ignored when loading modules and module dependencies. In some cases, you may want to load existing precompiled modules, but not create new ones. This can be done by starting Julia with --compiled-modules=existing. More fine-grained control is available with --pkgimages={yes|no|existing}, which only affects native-code storage during precompilation. Base.compilecache can still be called manually. The state of this command line flag is passed to Pkg.build to disable automatic precompilation triggering when installing, updating, and explicitly building packages.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"You can also debug some precompilation failures with environment variables. Setting JULIA_VERBOSE_LINKING=true may help resolve failures in linking shared libraries of compiled native code. See the Developer Documentation part of the Julia manual, where you will find further details in the section documenting Julia's internals under \"Package Images\".","category":"page"},{"location":"devdocs/debuggingtips/#gdb-debugging-tips","page":"gdb debugging tips","title":"gdb debugging tips","text":"","category":"section"},{"location":"devdocs/debuggingtips/#Displaying-Julia-variables","page":"gdb debugging tips","title":"Displaying Julia variables","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Within gdb, any jl_value_t* object obj can be displayed using","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) call jl_(obj)","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"The object will be displayed in the julia session, not in the gdb session. This is a useful way to discover the types and values of objects being manipulated by Julia's C code.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Similarly, if you're debugging some of Julia's internals (e.g., compiler.jl), you can print obj using","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"ccall(:jl_, Cvoid, (Any,), obj)","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"This is a good way to circumvent problems that arise from the order in which julia's output streams are initialized.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Julia's flisp interpreter uses value_t objects; these can be displayed with call fl_print(fl_ctx, ios_stdout, obj).","category":"page"},{"location":"devdocs/debuggingtips/#Useful-Julia-variables-for-Inspecting","page":"gdb debugging tips","title":"Useful Julia variables for Inspecting","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"While the addresses of many variables, like singletons, can be useful to print for many failures, there are a number of additional variables (see julia.h for a complete list) that are even more useful.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(when in jl_apply_generic) mfunc and jl_uncompress_ast(mfunc->def, mfunc->code) :: for figuring out a bit about the call-stack\njl_lineno and jl_filename :: for figuring out what line in a test to go start debugging from (or figure out how far into a file has been parsed)\n$1 :: not really a variable, but still a useful shorthand for referring to the result of the last gdb command (such as print)\njl_options :: sometimes useful, since it lists all of the command line options that were successfully parsed\njl_uv_stderr :: because who doesn't like to be able to interact with stdio","category":"page"},{"location":"devdocs/debuggingtips/#Useful-Julia-functions-for-Inspecting-those-variables","page":"gdb debugging tips","title":"Useful Julia functions for Inspecting those variables","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"jl_print_task_backtraces(0) :: Similar to gdb's thread apply all bt or lldb's thread backtrace all. Runs all threads while printing backtraces for all existing tasks.\njl_gdblookup($pc) :: For looking up the current function and line.\njl_gdblookupinfo($pc) :: For looking up the current method instance object.\njl_gdbdumpcode(mi) :: For dumping all of code_typed/code_llvm/code_asm when the REPL is not working right.\njlbacktrace() :: For dumping the current Julia backtrace stack to stderr. Only usable after record_backtrace() has been called.\njl_dump_llvm_value(Value*) :: For invoking Value->dump() in gdb, where it doesn't work natively. For example, f->linfo->functionObject, f->linfo->specFunctionObject, and to_function(f->linfo).\njl_dump_llvm_module(Module*) :: For invoking Module->dump() in gdb, where it doesn't work natively.\nType->dump() :: only works in lldb. Note: add something like ;1 to prevent lldb from printing its prompt over the output\njl_eval_string(\"expr\") :: for invoking side-effects to modify the current state or to lookup symbols\njl_typeof(jl_value_t*) :: for extracting the type tag of a Julia value (in gdb, call macro define jl_typeof jl_typeof first, or pick something short like ty for the first arg to define a shorthand)","category":"page"},{"location":"devdocs/debuggingtips/#Inserting-breakpoints-for-inspection-from-gdb","page":"gdb debugging tips","title":"Inserting breakpoints for inspection from gdb","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"In your gdb session, set a breakpoint in jl_breakpoint like so:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) break jl_breakpoint","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Then within your Julia code, insert a call to jl_breakpoint by adding","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"ccall(:jl_breakpoint, Cvoid, (Any,), obj)","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"where obj can be any variable or tuple you want to be accessible in the breakpoint.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"It's particularly helpful to back up to the jl_apply frame, from which you can display the arguments to a function using, e.g.,","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) call jl_(args[0])","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Another useful frame is to_function(jl_method_instance_t *li, bool cstyle). The jl_method_instance_t* argument is a struct with a reference to the final AST sent into the compiler. However, the AST at this point will usually be compressed; to view the AST, call jl_uncompress_ast and then pass the result to jl_:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"#2 0x00007ffff7928bf7 in to_function (li=0x2812060, cstyle=false) at codegen.cpp:584\n584 abort();\n(gdb) p jl_(jl_uncompress_ast(li, li->ast))","category":"page"},{"location":"devdocs/debuggingtips/#Inserting-breakpoints-upon-certain-conditions","page":"gdb debugging tips","title":"Inserting breakpoints upon certain conditions","text":"","category":"section"},{"location":"devdocs/debuggingtips/#Loading-a-particular-file","page":"gdb debugging tips","title":"Loading a particular file","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Let's say the file is sysimg.jl:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) break jl_load if strcmp(fname, \"sysimg.jl\")==0","category":"page"},{"location":"devdocs/debuggingtips/#Calling-a-particular-method","page":"gdb debugging tips","title":"Calling a particular method","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) break jl_apply_generic if strcmp((char*)(jl_symbol_name)(jl_gf_mtable(F)->name), \"method_to_break\")==0","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Since this function is used for every call, you will make everything 1000x slower if you do this.","category":"page"},{"location":"devdocs/debuggingtips/#Dealing-with-signals","page":"gdb debugging tips","title":"Dealing with signals","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Julia requires a few signals to function properly. The profiler uses SIGUSR2 for sampling and the garbage collector uses SIGSEGV for threads synchronization. If you are debugging some code that uses the profiler or multiple threads, you may want to let the debugger ignore these signals since they can be triggered very often during normal operations. The command to do this in GDB is (replace SIGSEGV with SIGUSR2 or other signals you want to ignore):","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) handle SIGSEGV noprint nostop pass","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"The corresponding LLDB command is (after the process is started):","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(lldb) pro hand -p true -s false -n false SIGSEGV","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"If you are debugging a segfault with threaded code, you can set a breakpoint on jl_critical_error (sigdie_handler should also work on Linux and BSD) in order to only catch the actual segfault rather than the GC synchronization points.","category":"page"},{"location":"devdocs/debuggingtips/#Debugging-during-Julia's-build-process-(bootstrap)","page":"gdb debugging tips","title":"Debugging during Julia's build process (bootstrap)","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Errors that occur during make need special handling. Julia is built in two stages, constructing sys0 and sys.ji. To see what commands are running at the time of failure, use make VERBOSE=1.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"At the time of this writing, you can debug build errors during the sys0 phase from the base directory using:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"julia/base$ gdb --args ../usr/bin/julia-debug -C native --build ../usr/lib/julia/sys0 sysimg.jl","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"You might need to delete all the files in usr/lib/julia/ to get this to work.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"You can debug the sys.ji phase using:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"julia/base$ gdb --args ../usr/bin/julia-debug -C native --build ../usr/lib/julia/sys -J ../usr/lib/julia/sys0.ji sysimg.jl","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"By default, any errors will cause Julia to exit, even under gdb. To catch an error \"in the act\", set a breakpoint in jl_error (there are several other useful spots, for specific kinds of failures, including: jl_too_few_args, jl_too_many_args, and jl_throw).","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Once an error is caught, a useful technique is to walk up the stack and examine the function by inspecting the related call to jl_apply. To take a real-world example:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Breakpoint 1, jl_throw (e=0x7ffdf42de400) at task.c:802\n802 {\n(gdb) p jl_(e)\nErrorException(\"auto_unbox: unable to determine argument type\")\n$2 = void\n(gdb) bt 10\n#0 jl_throw (e=0x7ffdf42de400) at task.c:802\n#1 0x00007ffff65412fe in jl_error (str=0x7ffde56be000 <_j_str267> \"auto_unbox:\n unable to determine argument type\")\n at builtins.c:39\n#2 0x00007ffde56bd01a in julia_convert_16886 ()\n#3 0x00007ffff6541154 in jl_apply (f=0x7ffdf367f630, args=0x7fffffffc2b0, nargs=2) at julia.h:1281\n...","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"The most recent jl_apply is at frame #3, so we can go back there and look at the AST for the function julia_convert_16886. This is the uniqued name for some method of convert. f in this frame is a jl_function_t*, so we can look at the type signature, if any, from the specTypes field:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) f 3\n#3 0x00007ffff6541154 in jl_apply (f=0x7ffdf367f630, args=0x7fffffffc2b0, nargs=2) at julia.h:1281\n1281 return f->fptr((jl_value_t*)f, args, nargs);\n(gdb) p f->linfo->specTypes\n$4 = (jl_tupletype_t *) 0x7ffdf39b1030\n(gdb) p jl_( f->linfo->specTypes )\nTuple{Type{Float32}, Float64} # <-- type signature for julia_convert_16886","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Then, we can look at the AST for this function:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) p jl_( jl_uncompress_ast(f->linfo, f->linfo->ast) )\nExpr(:lambda, Array{Any, 1}[:#s29, :x], Array{Any, 1}[Array{Any, 1}[], Array{Any, 1}[Array{Any, 1}[:#s29, :Any, 0], Array{Any, 1}[:x, :Any, 0]], Array{Any, 1}[], 0], Expr(:body,\nExpr(:line, 90, :float.jl)::Any,\nExpr(:return, Expr(:call, :box, :Float32, Expr(:call, :fptrunc, :Float32, :x)::Any)::Any)::Any)::Any)::Any","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Finally, and perhaps most usefully, we can force the function to be recompiled in order to step through the codegen process. To do this, clear the cached functionObject from the jl_lamdbda_info_t*:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) p f->linfo->functionObject\n$8 = (void *) 0x1289d070\n(gdb) set f->linfo->functionObject = NULL","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Then, set a breakpoint somewhere useful (e.g. emit_function, emit_expr, emit_call, etc.), and run codegen:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) p jl_compile(f)\n... # your breakpoint here","category":"page"},{"location":"devdocs/debuggingtips/#Debugging-precompilation-errors","page":"gdb debugging tips","title":"Debugging precompilation errors","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Module precompilation spawns a separate Julia process to precompile each module. Setting a breakpoint or catching failures in a precompile worker requires attaching a debugger to the worker. The easiest approach is to set the debugger watch for new process launches matching a given name. For example:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) attach -w -n julia-debug","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"or:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(lldb) process attach -w -n julia-debug","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Then run a script/command to start precompilation. As described earlier, use conditional breakpoints in the parent process to catch specific file-loading events and narrow the debugging window. (some operating systems may require alternative approaches, such as following each fork from the parent process)","category":"page"},{"location":"devdocs/debuggingtips/#Mozilla's-Record-and-Replay-Framework-(rr)","page":"gdb debugging tips","title":"Mozilla's Record and Replay Framework (rr)","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Julia now works out of the box with rr, the lightweight recording and deterministic debugging framework from Mozilla. This allows you to replay the trace of an execution deterministically. The replayed execution's address spaces, register contents, syscall data etc are exactly the same in every run.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"A recent version of rr (3.1.0 or higher) is required.","category":"page"},{"location":"devdocs/debuggingtips/#Reproducing-concurrency-bugs-with-rr","page":"gdb debugging tips","title":"Reproducing concurrency bugs with rr","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"rr simulates a single-threaded machine by default. In order to debug concurrent code you can use rr record --chaos which will cause rr to simulate between one to eight cores, chosen randomly. You might therefore want to set JULIA_NUM_THREADS=8 and rerun your code under rr until you have caught your bug.","category":"page"},{"location":"manual/stacktraces/#Stack-Traces","page":"Stack Traces","title":"Stack Traces","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"The StackTraces module provides simple stack traces that are both human readable and easy to use programmatically.","category":"page"},{"location":"manual/stacktraces/#Viewing-a-stack-trace","page":"Stack Traces","title":"Viewing a stack trace","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"The primary function used to obtain a stack trace is stacktrace:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"6-element Array{Base.StackTraces.StackFrame,1}:\n top-level scope\n eval at boot.jl:317 [inlined]\n eval(::Module, ::Expr) at REPL.jl:5\n eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n macro expansion at REPL.jl:116 [inlined]\n (::getfield(REPL, Symbol(\"##28#29\")){REPL.REPLBackend})() at event.jl:92","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Calling stacktrace() returns a vector of StackTraces.StackFrame s. For ease of use, the alias StackTraces.StackTrace can be used in place of Vector{StackFrame}. (Examples with [...] indicate that output may vary depending on how the code is run.)","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> example() = stacktrace()\nexample (generic function with 1 method)\n\njulia> example()\n7-element Array{Base.StackTraces.StackFrame,1}:\n example() at REPL[1]:1\n top-level scope\n eval at boot.jl:317 [inlined]\n[...]\n\njulia> @noinline child() = stacktrace()\nchild (generic function with 1 method)\n\njulia> @noinline parent() = child()\nparent (generic function with 1 method)\n\njulia> grandparent() = parent()\ngrandparent (generic function with 1 method)\n\njulia> grandparent()\n9-element Array{Base.StackTraces.StackFrame,1}:\n child() at REPL[3]:1\n parent() at REPL[4]:1\n grandparent() at REPL[5]:1\n[...]","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Note that when calling stacktrace() you'll typically see a frame with eval at boot.jl. When calling stacktrace() from the REPL you'll also have a few extra frames in the stack from REPL.jl, usually looking something like this:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> example() = stacktrace()\nexample (generic function with 1 method)\n\njulia> example()\n7-element Array{Base.StackTraces.StackFrame,1}:\n example() at REPL[1]:1\n top-level scope\n eval at boot.jl:317 [inlined]\n eval(::Module, ::Expr) at REPL.jl:5\n eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n macro expansion at REPL.jl:116 [inlined]\n (::getfield(REPL, Symbol(\"##28#29\")){REPL.REPLBackend})() at event.jl:92","category":"page"},{"location":"manual/stacktraces/#Extracting-useful-information","page":"Stack Traces","title":"Extracting useful information","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Each StackTraces.StackFrame contains the function name, file name, line number, lambda info, a flag indicating whether the frame has been inlined, a flag indicating whether it is a C function (by default C functions do not appear in the stack trace), and an integer representation of the pointer returned by backtrace:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> frame = stacktrace()[3]\neval(::Module, ::Expr) at REPL.jl:5\n\njulia> frame.func\n:eval\n\njulia> frame.file\nSymbol(\"~/julia/usr/share/julia/stdlib/v0.7/REPL/src/REPL.jl\")\n\njulia> frame.line\n5\n\njulia> frame.linfo\nMethodInstance for eval(::Module, ::Expr)\n\njulia> frame.inlined\nfalse\n\njulia> frame.from_c\nfalse\n\njulia> frame.pointer\n0x00007f92d6293171","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"This makes stack trace information available programmatically for logging, error handling, and more.","category":"page"},{"location":"manual/stacktraces/#Error-handling","page":"Stack Traces","title":"Error handling","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"While having easy access to information about the current state of the callstack can be helpful in many places, the most obvious application is in error handling and debugging.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> @noinline bad_function() = undeclared_variable\nbad_function (generic function with 1 method)\n\njulia> @noinline example() = try\n bad_function()\n catch\n stacktrace()\n end\nexample (generic function with 1 method)\n\njulia> example()\n7-element Array{Base.StackTraces.StackFrame,1}:\n example() at REPL[2]:4\n top-level scope\n eval at boot.jl:317 [inlined]\n[...]","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"You may notice that in the example above the first stack frame points at line 4, where stacktrace is called, rather than line 2, where bad_function is called, and bad_function's frame is missing entirely. This is understandable, given that stacktrace is called from the context of the catch. While in this example it's fairly easy to find the actual source of the error, in complex cases tracking down the source of the error becomes nontrivial.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"This can be remedied by passing the result of catch_backtrace to stacktrace. Instead of returning callstack information for the current context, catch_backtrace returns stack information for the context of the most recent exception:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> @noinline bad_function() = undeclared_variable\nbad_function (generic function with 1 method)\n\njulia> @noinline example() = try\n bad_function()\n catch\n stacktrace(catch_backtrace())\n end\nexample (generic function with 1 method)\n\njulia> example()\n8-element Array{Base.StackTraces.StackFrame,1}:\n bad_function() at REPL[1]:1\n example() at REPL[2]:2\n[...]","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Notice that the stack trace now indicates the appropriate line number and the missing frame.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> @noinline child() = error(\"Whoops!\")\nchild (generic function with 1 method)\n\njulia> @noinline parent() = child()\nparent (generic function with 1 method)\n\njulia> @noinline function grandparent()\n try\n parent()\n catch err\n println(\"ERROR: \", err.msg)\n stacktrace(catch_backtrace())\n end\n end\ngrandparent (generic function with 1 method)\n\njulia> grandparent()\nERROR: Whoops!\n10-element Array{Base.StackTraces.StackFrame,1}:\n error at error.jl:33 [inlined]\n child() at REPL[1]:1\n parent() at REPL[2]:1\n grandparent() at REPL[3]:3\n[...]","category":"page"},{"location":"manual/stacktraces/#Exception-stacks-and-[current_exceptions](@ref)","page":"Stack Traces","title":"Exception stacks and current_exceptions","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"compat: Julia 1.1\nException stacks requires at least Julia 1.1.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"While handling an exception further exceptions may be thrown. It can be useful to inspect all these exceptions to identify the root cause of a problem. The julia runtime supports this by pushing each exception onto an internal exception stack as it occurs. When the code exits a catch normally, any exceptions which were pushed onto the stack in the associated try are considered to be successfully handled and are removed from the stack.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"The stack of current exceptions can be accessed using the current_exceptions function. For example,","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> try\n error(\"(A) The root cause\")\n catch\n try\n error(\"(B) An exception while handling the exception\")\n catch\n for (exc, bt) in current_exceptions()\n showerror(stdout, exc, bt)\n println(stdout)\n end\n end\n end\n(A) The root cause\nStacktrace:\n [1] error(::String) at error.jl:33\n [2] top-level scope at REPL[7]:2\n [3] eval(::Module, ::Any) at boot.jl:319\n [4] eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n [5] macro expansion at REPL.jl:117 [inlined]\n [6] (::getfield(REPL, Symbol(\"##26#27\")){REPL.REPLBackend})() at task.jl:259\n(B) An exception while handling the exception\nStacktrace:\n [1] error(::String) at error.jl:33\n [2] top-level scope at REPL[7]:5\n [3] eval(::Module, ::Any) at boot.jl:319\n [4] eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n [5] macro expansion at REPL.jl:117 [inlined]\n [6] (::getfield(REPL, Symbol(\"##26#27\")){REPL.REPLBackend})() at task.jl:259","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"In this example the root cause exception (A) is first on the stack, with a further exception (B) following it. After exiting both catch blocks normally (i.e., without throwing a further exception) all exceptions are removed from the stack and are no longer accessible.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"The exception stack is stored on the Task where the exceptions occurred. When a task fails with uncaught exceptions, current_exceptions(task) may be used to inspect the exception stack for that task.","category":"page"},{"location":"manual/stacktraces/#Comparison-with-[backtrace](@ref)","page":"Stack Traces","title":"Comparison with backtrace","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"A call to backtrace returns a vector of Union{Ptr{Nothing}, Base.InterpreterIP}, which may then be passed into stacktrace for translation:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> trace = backtrace()\n18-element Array{Union{Ptr{Nothing}, Base.InterpreterIP},1}:\n Ptr{Nothing} @0x00007fd8734c6209\n Ptr{Nothing} @0x00007fd87362b342\n Ptr{Nothing} @0x00007fd87362c136\n Ptr{Nothing} @0x00007fd87362c986\n Ptr{Nothing} @0x00007fd87362d089\n Base.InterpreterIP(CodeInfo(:(begin\n Core.SSAValue(0) = backtrace()\n trace = Core.SSAValue(0)\n return Core.SSAValue(0)\n end)), 0x0000000000000000)\n Ptr{Nothing} @0x00007fd87362e4cf\n[...]\n\njulia> stacktrace(trace)\n6-element Array{Base.StackTraces.StackFrame,1}:\n top-level scope\n eval at boot.jl:317 [inlined]\n eval(::Module, ::Expr) at REPL.jl:5\n eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n macro expansion at REPL.jl:116 [inlined]\n (::getfield(REPL, Symbol(\"##28#29\")){REPL.REPLBackend})() at event.jl:92","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Notice that the vector returned by backtrace had 18 elements, while the vector returned by stacktrace only has 6. This is because, by default, stacktrace removes any lower-level C functions from the stack. If you want to include stack frames from C calls, you can do it like this:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> stacktrace(trace, true)\n21-element Array{Base.StackTraces.StackFrame,1}:\n jl_apply_generic at gf.c:2167\n do_call at interpreter.c:324\n eval_value at interpreter.c:416\n eval_body at interpreter.c:559\n jl_interpret_toplevel_thunk_callback at interpreter.c:798\n top-level scope\n jl_interpret_toplevel_thunk at interpreter.c:807\n jl_toplevel_eval_flex at toplevel.c:856\n jl_toplevel_eval_in at builtins.c:624\n eval at boot.jl:317 [inlined]\n eval(::Module, ::Expr) at REPL.jl:5\n jl_apply_generic at gf.c:2167\n eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n jl_apply_generic at gf.c:2167\n macro expansion at REPL.jl:116 [inlined]\n (::getfield(REPL, Symbol(\"##28#29\")){REPL.REPLBackend})() at event.jl:92\n jl_fptr_trampoline at gf.c:1838\n jl_apply_generic at gf.c:2167\n jl_apply at julia.h:1540 [inlined]\n start_task at task.c:268\n ip:0xffffffffffffffff","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Individual pointers returned by backtrace can be translated into StackTraces.StackFrame s by passing them into StackTraces.lookup:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> pointer = backtrace()[1];\n\njulia> frame = StackTraces.lookup(pointer)\n1-element Array{Base.StackTraces.StackFrame,1}:\n jl_apply_generic at gf.c:2167\n\njulia> println(\"The top frame is from $(frame[1].func)!\")\nThe top frame is from jl_apply_generic!","category":"page"},{"location":"devdocs/external_profilers/#External-Profiler-Support","page":"External Profiler Support","title":"External Profiler Support","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Julia provides explicit support for some external tracing profilers, enabling you to obtain a high-level overview of the runtime's execution behavior.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The currently supported profilers are:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Tracy\nIntel VTune (ITTAPI)","category":"page"},{"location":"devdocs/external_profilers/#Adding-New-Zones","page":"External Profiler Support","title":"Adding New Zones","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To add new zones, use the JL_TIMING macro. You can find numerous examples throughout the codebase by searching for JL_TIMING. To add a new type of zone you add it to JL_TIMING_OWNERS (and possibly JL_TIMING_EVENTS).","category":"page"},{"location":"devdocs/external_profilers/#Dynamically-Enabling-and-Disabling-Zones","page":"External Profiler Support","title":"Dynamically Enabling and Disabling Zones","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The JULIA_TIMING_SUBSYSTEMS environment variable allows you to enable or disable zones for a specific Julia run. For instance, setting the variable to +GC,-INFERENCE will enable the GC zones and disable the INFERENCE zones.","category":"page"},{"location":"devdocs/external_profilers/#Tracy-Profiler","page":"External Profiler Support","title":"Tracy Profiler","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Tracy is a flexible profiler that can be optionally integrated with Julia.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"A typical Tracy session might look like this:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"(Image: Typical Tracy usage)","category":"page"},{"location":"devdocs/external_profilers/#Building-Julia-with-Tracy","page":"External Profiler Support","title":"Building Julia with Tracy","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To enable Tracy integration, build Julia with the extra option WITH_TRACY=1 in the Make.user file.","category":"page"},{"location":"devdocs/external_profilers/#Installing-the-Tracy-Profile-Viewer","page":"External Profiler Support","title":"Installing the Tracy Profile Viewer","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The easiest way to obtain the profile viewer is by adding the TracyProfiler_jll package and launching the profiler with:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"run(TracyProfiler_jll.tracy())","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"note: Note\nOn macOS, you may want to set the TRACY_DPI_SCALE environment variable to 1.0 if the UI elements in the profiler appear excessively large.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To run a \"headless\" instance that saves the trace to disk, use","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"run(`$(TracyProfiler_jll.capture()) -o mytracefile.tracy`)","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"instead.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"For information on using the Tracy UI, refer to the Tracy manual.","category":"page"},{"location":"devdocs/external_profilers/#Profiling-Julia-with-Tracy","page":"External Profiler Support","title":"Profiling Julia with Tracy","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"A typical workflow for profiling Julia with Tracy involves starting Julia using:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"JULIA_WAIT_FOR_TRACY=1 ./julia -e '...'","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The environment variable ensures that Julia waits until it has successfully connected to the Tracy profiler before continuing execution. Afterward, use the Tracy profiler UI, click Connect, and Julia execution should resume and profiling should start.","category":"page"},{"location":"devdocs/external_profilers/#Profiling-package-precompilation-with-Tracy","page":"External Profiler Support","title":"Profiling package precompilation with Tracy","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To profile a package precompilation process it is easiest to explicitly call into Base.compilecache with the package you want to precompile:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"pkg = Base.identify_package(\"SparseArrays\")\nwithenv(\"JULIA_WAIT_FOR_TRACY\" => 1, \"TRACY_PORT\" => 9001) do\n Base.compilecache(pkg)\nend","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Here, we use a custom port for tracy which makes it easier to find the correct client in the Tracy UI to connect to.","category":"page"},{"location":"devdocs/external_profilers/#Adding-metadata-to-zones","page":"External Profiler Support","title":"Adding metadata to zones","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The various jl_timing_show_* and jl_timing_printf functions can be used to attach a string (or strings) to a zone. For example, the trace zone for inference shows the method instance that is being inferred.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The TracyCZoneColor function can be used to set the color of a certain zone. Search through the codebase to see how it is used.","category":"page"},{"location":"devdocs/external_profilers/#Viewing-Tracy-files-in-your-browser","page":"External Profiler Support","title":"Viewing Tracy files in your browser","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Visit https://topolarity.github.io/trace-viewer/ for an (experimental) web viewer for Tracy traces.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"You can open a local .tracy file or provide a URL from the web (e.g. a file in a Github repo). If you load a trace file from the web, you can also share the page URL directly with others, enabling them to view the same trace.","category":"page"},{"location":"devdocs/external_profilers/#Enabling-stack-trace-samples","page":"External Profiler Support","title":"Enabling stack trace samples","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To enable call stack sampling in Tracy, build Julia with these options in your Make.user file:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"WITH_TRACY := 1\nWITH_TRACY_CALLSTACKS := 1\nUSE_BINARYBUILDER_LIBTRACYCLIENT := 0","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"You may also need to run make -C deps clean-libtracyclient to force a re-build of Tracy.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"This feature has a significant impact on trace size and profiling overhead, so it is recommended to leave call stack sampling off when possible, especially if you intend to share your trace files online.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Note that the Julia JIT runtime does not yet have integration for Tracy's symbolification, so Julia functions will typically be unknown in these stack traces.","category":"page"},{"location":"devdocs/external_profilers/#Intel-VTune-(ITTAPI)-Profiler","page":"External Profiler Support","title":"Intel VTune (ITTAPI) Profiler","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"This section is yet to be written.","category":"page"},{"location":"base/collections/#Collections-and-Data-Structures","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"","category":"section"},{"location":"base/collections/#lib-collections-iteration","page":"Collections and Data Structures","title":"Iteration","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Sequential iteration is implemented by the iterate function. The general for loop:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"for i in iter # or \"for i = iter\"\n # body\nend","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"is translated into:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"next = iterate(iter)\nwhile next !== nothing\n (i, state) = next\n # body\n next = iterate(iter, state)\nend","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"The state object may be anything, and should be chosen appropriately for each iterable type. See the manual section on the iteration interface for more details about defining a custom iterable type.","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.iterate\nBase.IteratorSize\nBase.IteratorEltype","category":"page"},{"location":"base/collections/#Base.iterate","page":"Collections and Data Structures","title":"Base.iterate","text":"iterate(iter [, state]) -> Union{Nothing, Tuple{Any, Any}}\n\nAdvance the iterator to obtain the next element. If no elements remain, nothing should be returned. Otherwise, a 2-tuple of the next element and the new iteration state should be returned.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.IteratorSize","page":"Collections and Data Structures","title":"Base.IteratorSize","text":"IteratorSize(itertype::Type) -> IteratorSize\n\nGiven the type of an iterator, return one of the following values:\n\nSizeUnknown() if the length (number of elements) cannot be determined in advance.\nHasLength() if there is a fixed, finite length.\nHasShape{N}() if there is a known length plus a notion of multidimensional shape (as for an array). In this case N should give the number of dimensions, and the axes function is valid for the iterator.\nIsInfinite() if the iterator yields values forever.\n\nThe default value (for iterators that do not define this function) is HasLength(). This means that most iterators are assumed to implement length.\n\nThis trait is generally used to select between algorithms that pre-allocate space for their result, and algorithms that resize their result incrementally.\n\njulia> Base.IteratorSize(1:5)\nBase.HasShape{1}()\n\njulia> Base.IteratorSize((2,3))\nBase.HasLength()\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.IteratorEltype","page":"Collections and Data Structures","title":"Base.IteratorEltype","text":"IteratorEltype(itertype::Type) -> IteratorEltype\n\nGiven the type of an iterator, return one of the following values:\n\nEltypeUnknown() if the type of elements yielded by the iterator is not known in advance.\nHasEltype() if the element type is known, and eltype would return a meaningful value.\n\nHasEltype() is the default, since iterators are assumed to implement eltype.\n\nThis trait is generally used to select between algorithms that pre-allocate a specific type of result, and algorithms that pick a result type based on the types of yielded values.\n\njulia> Base.IteratorEltype(1:5)\nBase.HasEltype()\n\n\n\n\n\n","category":"type"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"AbstractRange\nUnitRange\nTuple\nNumber\nAbstractArray\nBitSet\nIdDict\nDict\nWeakKeyDict\nEachLine\nAbstractString\nSet\nPair\nNamedTuple","category":"page"},{"location":"base/collections/#Constructors-and-Types","page":"Collections and Data Structures","title":"Constructors and Types","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.AbstractRange\nBase.OrdinalRange\nBase.AbstractUnitRange\nBase.StepRange\nBase.UnitRange\nBase.LinRange","category":"page"},{"location":"base/collections/#Base.AbstractRange","page":"Collections and Data Structures","title":"Base.AbstractRange","text":"AbstractRange{T} <: AbstractVector{T}\n\nSupertype for linear ranges with elements of type T. UnitRange, LinRange and other types are subtypes of this.\n\nAll subtypes must define step. Thus LogRange is not a subtype of AbstractRange.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.OrdinalRange","page":"Collections and Data Structures","title":"Base.OrdinalRange","text":"OrdinalRange{T, S} <: AbstractRange{T}\n\nSupertype for ordinal ranges with elements of type T with spacing(s) of type S. The steps should be always-exact multiples of oneunit, and T should be a \"discrete\" type, which cannot have values smaller than oneunit. For example, Integer or Date types would qualify, whereas Float64 would not (since this type can represent values smaller than oneunit(Float64). UnitRange, StepRange, and other types are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.AbstractUnitRange","page":"Collections and Data Structures","title":"Base.AbstractUnitRange","text":"AbstractUnitRange{T} <: OrdinalRange{T, T}\n\nSupertype for ranges with a step size of oneunit(T) with elements of type T. UnitRange and other types are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.StepRange","page":"Collections and Data Structures","title":"Base.StepRange","text":"StepRange{T, S} <: OrdinalRange{T, S}\n\nRanges with elements of type T with spacing of type S. The step between each element is constant, and the range is defined in terms of a start and stop of type T and a step of type S. Neither T nor S should be floating point types. The syntax a:b:c with b != 0 and a, b, and c all integers creates a StepRange.\n\nExamples\n\njulia> collect(StepRange(1, Int8(2), 10))\n5-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n\njulia> typeof(StepRange(1, Int8(2), 10))\nStepRange{Int64, Int8}\n\njulia> typeof(1:3:6)\nStepRange{Int64, Int64}\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.UnitRange","page":"Collections and Data Structures","title":"Base.UnitRange","text":"UnitRange{T<:Real}\n\nA range parameterized by a start and stop of type T, filled with elements spaced by 1 from start until stop is exceeded. The syntax a:b with a and b both Integers creates a UnitRange.\n\nExamples\n\njulia> collect(UnitRange(2.3, 5.2))\n3-element Vector{Float64}:\n 2.3\n 3.3\n 4.3\n\njulia> typeof(1:10)\nUnitRange{Int64}\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.LinRange","page":"Collections and Data Structures","title":"Base.LinRange","text":"LinRange{T,L}\n\nA range with len linearly spaced elements between its start and stop. The size of the spacing is controlled by len, which must be an Integer.\n\nExamples\n\njulia> LinRange(1.5, 5.5, 9)\n9-element LinRange{Float64, Int64}:\n 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5\n\nCompared to using range, directly constructing a LinRange should have less overhead but won't try to correct for floating point errors:\n\njulia> collect(range(-0.1, 0.3, length=5))\n5-element Vector{Float64}:\n -0.1\n 0.0\n 0.1\n 0.2\n 0.3\n\njulia> collect(LinRange(-0.1, 0.3, 5))\n5-element Vector{Float64}:\n -0.1\n -1.3877787807814457e-17\n 0.09999999999999999\n 0.19999999999999998\n 0.3\n\nSee also Logrange for logarithmically spaced points.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#General-Collections","page":"Collections and Data Structures","title":"General Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.isempty\nBase.isdone\nBase.empty!\nBase.length\nBase.checked_length","category":"page"},{"location":"base/collections/#Base.isempty","page":"Collections and Data Structures","title":"Base.isempty","text":"isempty(collection) -> Bool\n\nDetermine whether a collection is empty (has no elements).\n\nwarning: Warning\nisempty(itr) may consume the next element of a stateful iterator itr unless an appropriate Base.isdone(itr) method is defined. Stateful iterators should implement isdone, but you may want to avoid using isempty when writing generic code which should support any iterator type.\n\nExamples\n\njulia> isempty([])\ntrue\n\njulia> isempty([1 2 3])\nfalse\n\n\n\n\n\nisempty(condition)\n\nReturn true if no tasks are waiting on the condition, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.isdone","page":"Collections and Data Structures","title":"Base.isdone","text":"isdone(itr, [state]) -> Union{Bool, Missing}\n\nThis function provides a fast-path hint for iterator completion. This is useful for stateful iterators that want to avoid having elements consumed if they are not going to be exposed to the user (e.g. when checking for done-ness in isempty or zip).\n\nStateful iterators that want to opt into this feature should define an isdone method that returns true/false depending on whether the iterator is done or not. Stateless iterators need not implement this function.\n\nIf the result is missing, callers may go ahead and compute iterate(x, state) === nothing to compute a definite answer.\n\nSee also iterate, isempty\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.empty!","page":"Collections and Data Structures","title":"Base.empty!","text":"empty!(collection) -> collection\n\nRemove all elements from a collection.\n\nExamples\n\njulia> A = Dict(\"a\" => 1, \"b\" => 2)\nDict{String, Int64} with 2 entries:\n \"b\" => 2\n \"a\" => 1\n\njulia> empty!(A);\n\njulia> A\nDict{String, Int64}()\n\n\n\n\n\nempty!(c::Channel)\n\nEmpty a Channel c by calling empty! on the internal buffer. Return the empty channel.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.length","page":"Collections and Data Structures","title":"Base.length","text":"length(collection) -> Integer\n\nReturn the number of elements in the collection.\n\nUse lastindex to get the last valid index of an indexable collection.\n\nSee also: size, ndims, eachindex.\n\nExamples\n\njulia> length(1:5)\n5\n\njulia> length([1, 2, 3, 4])\n4\n\njulia> length([1 2; 3 4])\n4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.checked_length","page":"Collections and Data Structures","title":"Base.checked_length","text":"Base.checked_length(r)\n\nCalculates length(r), but may check for overflow errors where applicable when the result doesn't fit into Union{Integer(eltype(r)),Int}.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"AbstractRange\nUnitRange\nTuple\nNumber\nAbstractArray\nBitSet\nIdDict\nDict\nWeakKeyDict\nAbstractString\nSet\nNamedTuple","category":"page"},{"location":"base/collections/#Iterable-Collections","page":"Collections and Data Structures","title":"Iterable Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.in\nBase.:∉\nBase.hasfastin\nBase.eltype\nBase.indexin\nBase.unique\nBase.unique!\nBase.allunique\nBase.allequal\nBase.reduce(::Any, ::Any)\nBase.reduce(::Any, ::AbstractArray)\nBase.foldl(::Any, ::Any)\nBase.foldr(::Any, ::Any)\nBase.maximum\nBase.maximum!\nBase.minimum\nBase.minimum!\nBase.extrema\nBase.extrema!\nBase.argmax\nBase.argmin\nBase.findmax\nBase.findmin\nBase.findmax!\nBase.findmin!\nBase.sum\nBase.sum!\nBase.prod\nBase.prod!\nBase.any(::Any)\nBase.any(::AbstractArray, ::Any)\nBase.any!\nBase.all(::Any)\nBase.all(::AbstractArray, ::Any)\nBase.all!\nBase.count\nBase.foreach\nBase.map\nBase.map!\nBase.mapreduce(::Any, ::Any, ::Any)\nBase.mapfoldl(::Any, ::Any, ::Any)\nBase.mapfoldr(::Any, ::Any, ::Any)\nBase.first\nBase.last\nBase.front\nBase.tail\nBase.step\nBase.collect(::Any)\nBase.collect(::Type, ::Any)\nBase.filter\nBase.filter!\nBase.replace(::Any, ::Pair...)\nBase.replace(::Base.Callable, ::Any)\nBase.replace!\nBase.rest\nBase.split_rest","category":"page"},{"location":"base/collections/#Base.in","page":"Collections and Data Structures","title":"Base.in","text":"in(item, collection) -> Bool\n∈(item, collection) -> Bool\n\nDetermine whether an item is in the given collection, in the sense that it is == to one of the values generated by iterating over the collection. Return a Bool value, except if item is missing or collection contains missing but not item, in which case missing is returned (three-valued logic, matching the behavior of any and ==).\n\nSome collections follow a slightly different definition. For example, Sets check whether the item isequal to one of the elements; Dicts look for key=>value pairs, and the key is compared using isequal.\n\nTo test for the presence of a key in a dictionary, use haskey or k in keys(dict). For the collections mentioned above, the result is always a Bool.\n\nWhen broadcasting with in.(items, collection) or items .∈ collection, both items and collection are broadcasted over, which is often not what is intended. For example, if both arguments are vectors (and the dimensions match), the result is a vector indicating whether each value in collection items is in the value at the corresponding position in collection. To get a vector indicating whether each value in items is in collection, wrap collection in a tuple or a Ref like this: in.(items, Ref(collection)) or items .∈ Ref(collection).\n\nSee also: ∉, insorted, contains, occursin, issubset.\n\nExamples\n\njulia> a = 1:3:20\n1:3:19\n\njulia> 4 in a\ntrue\n\njulia> 5 in a\nfalse\n\njulia> missing in [1, 2]\nmissing\n\njulia> 1 in [2, missing]\nmissing\n\njulia> 1 in [1, missing]\ntrue\n\njulia> missing in Set([1, 2])\nfalse\n\njulia> (1=>missing) in Dict(1=>10, 2=>20)\nmissing\n\njulia> [1, 2] .∈ [2, 3]\n2-element BitVector:\n 0\n 0\n\njulia> [1, 2] .∈ ([2, 3],)\n2-element BitVector:\n 0\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.:∉","page":"Collections and Data Structures","title":"Base.:∉","text":"∉(item, collection) -> Bool\n∌(collection, item) -> Bool\n\nNegation of ∈ and ∋, i.e. checks that item is not in collection.\n\nWhen broadcasting with items .∉ collection, both items and collection are broadcasted over, which is often not what is intended. For example, if both arguments are vectors (and the dimensions match), the result is a vector indicating whether each value in collection items is not in the value at the corresponding position in collection. To get a vector indicating whether each value in items is not in collection, wrap collection in a tuple or a Ref like this: items .∉ Ref(collection).\n\nExamples\n\njulia> 1 ∉ 2:4\ntrue\n\njulia> 1 ∉ 1:3\nfalse\n\njulia> [1, 2] .∉ [2, 3]\n2-element BitVector:\n 1\n 1\n\njulia> [1, 2] .∉ ([2, 3],)\n2-element BitVector:\n 1\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.hasfastin","page":"Collections and Data Structures","title":"Base.hasfastin","text":"Base.hasfastin(T)\n\nDetermine whether the computation x ∈ collection where collection::T can be considered as a \"fast\" operation (typically constant or logarithmic complexity). The definition hasfastin(x) = hasfastin(typeof(x)) is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.\n\nThe default for hasfastin(T) is true for subtypes of AbstractSet, AbstractDict and AbstractRange and false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.eltype","page":"Collections and Data Structures","title":"Base.eltype","text":"eltype(type)\n\nDetermine the type of the elements generated by iterating a collection of the given type. For dictionary types, this will be a Pair{KeyType,ValType}. The definition eltype(x) = eltype(typeof(x)) is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.\n\nSee also: keytype, typeof.\n\nExamples\n\njulia> eltype(fill(1f0, (2,2)))\nFloat32\n\njulia> eltype(fill(0x1, (2,2)))\nUInt8\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.indexin","page":"Collections and Data Structures","title":"Base.indexin","text":"indexin(a, b)\n\nReturn an array containing the first index in b for each value in a that is a member of b. The output array contains nothing wherever a is not a member of b.\n\nSee also: sortperm, findfirst.\n\nExamples\n\njulia> a = ['a', 'b', 'c', 'b', 'd', 'a'];\n\njulia> b = ['a', 'b', 'c'];\n\njulia> indexin(a, b)\n6-element Vector{Union{Nothing, Int64}}:\n 1\n 2\n 3\n 2\n nothing\n 1\n\njulia> indexin(b, a)\n3-element Vector{Union{Nothing, Int64}}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.unique","page":"Collections and Data Structures","title":"Base.unique","text":"unique(itr)\n\nReturn an array containing only the unique elements of collection itr, as determined by isequal and hash, in the order that the first of each set of equivalent elements originally appears. The element type of the input is preserved.\n\nSee also: unique!, allunique, allequal.\n\nExamples\n\njulia> unique([1, 2, 6, 2])\n3-element Vector{Int64}:\n 1\n 2\n 6\n\njulia> unique(Real[1, 1.0, 2])\n2-element Vector{Real}:\n 1\n 2\n\n\n\n\n\nunique(f, itr)\n\nReturn an array containing one value from itr for each unique value produced by f applied to elements of itr.\n\nExamples\n\njulia> unique(x -> x^2, [1, -1, 3, -3, 4])\n3-element Vector{Int64}:\n 1\n 3\n 4\n\nThis functionality can also be used to extract the indices of the first occurrences of unique elements in an array:\n\njulia> a = [3.1, 4.2, 5.3, 3.1, 3.1, 3.1, 4.2, 1.7];\n\njulia> i = unique(i -> a[i], eachindex(a))\n4-element Vector{Int64}:\n 1\n 2\n 3\n 8\n\njulia> a[i]\n4-element Vector{Float64}:\n 3.1\n 4.2\n 5.3\n 1.7\n\njulia> a[i] == unique(a)\ntrue\n\n\n\n\n\nunique(A::AbstractArray; dims::Int)\n\nReturn unique regions of A along dimension dims.\n\nExamples\n\njulia> A = map(isodd, reshape(Vector(1:8), (2,2,2)))\n2×2×2 Array{Bool, 3}:\n[:, :, 1] =\n 1 1\n 0 0\n\n[:, :, 2] =\n 1 1\n 0 0\n\njulia> unique(A)\n2-element Vector{Bool}:\n 1\n 0\n\njulia> unique(A, dims=2)\n2×1×2 Array{Bool, 3}:\n[:, :, 1] =\n 1\n 0\n\n[:, :, 2] =\n 1\n 0\n\njulia> unique(A, dims=3)\n2×2×1 Array{Bool, 3}:\n[:, :, 1] =\n 1 1\n 0 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.unique!","page":"Collections and Data Structures","title":"Base.unique!","text":"unique!(f, A::AbstractVector)\n\nSelects one value from A for each unique value produced by f applied to elements of A, then return the modified A.\n\ncompat: Julia 1.1\nThis method is available as of Julia 1.1.\n\nExamples\n\njulia> unique!(x -> x^2, [1, -1, 3, -3, 4])\n3-element Vector{Int64}:\n 1\n 3\n 4\n\njulia> unique!(n -> n%3, [5, 1, 8, 9, 3, 4, 10, 7, 2, 6])\n3-element Vector{Int64}:\n 5\n 1\n 9\n\njulia> unique!(iseven, [2, 3, 5, 7, 9])\n2-element Vector{Int64}:\n 2\n 3\n\n\n\n\n\nunique!(A::AbstractVector)\n\nRemove duplicate items as determined by isequal and hash, then return the modified A. unique! will return the elements of A in the order that they occur. If you do not care about the order of the returned data, then calling (sort!(A); unique!(A)) will be much more efficient as long as the elements of A can be sorted.\n\nExamples\n\njulia> unique!([1, 1, 1])\n1-element Vector{Int64}:\n 1\n\njulia> A = [7, 3, 2, 3, 7, 5];\n\njulia> unique!(A)\n4-element Vector{Int64}:\n 7\n 3\n 2\n 5\n\njulia> B = [7, 6, 42, 6, 7, 42];\n\njulia> sort!(B); # unique! is able to process sorted data much more efficiently.\n\njulia> unique!(B)\n3-element Vector{Int64}:\n 6\n 7\n 42\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.allunique","page":"Collections and Data Structures","title":"Base.allunique","text":"allunique(itr) -> Bool\nallunique(f, itr) -> Bool\n\nReturn true if all values from itr are distinct when compared with isequal. Or if all of [f(x) for x in itr] are distinct, for the second method.\n\nNote that allunique(f, itr) may call f fewer than length(itr) times. The precise number of calls is regarded as an implementation detail.\n\nallunique may use a specialized implementation when the input is sorted.\n\nSee also: unique, issorted, allequal.\n\ncompat: Julia 1.11\nThe method allunique(f, itr) requires at least Julia 1.11.\n\nExamples\n\njulia> allunique([1, 2, 3])\ntrue\n\njulia> allunique([1, 2, 1, 2])\nfalse\n\njulia> allunique(Real[1, 1.0, 2])\nfalse\n\njulia> allunique([NaN, 2.0, NaN, 4.0])\nfalse\n\njulia> allunique(abs, [1, -1, 2])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.allequal","page":"Collections and Data Structures","title":"Base.allequal","text":"allequal(itr) -> Bool\nallequal(f, itr) -> Bool\n\nReturn true if all values from itr are equal when compared with isequal. Or if all of [f(x) for x in itr] are equal, for the second method.\n\nNote that allequal(f, itr) may call f fewer than length(itr) times. The precise number of calls is regarded as an implementation detail.\n\nSee also: unique, allunique.\n\ncompat: Julia 1.8\nThe allequal function requires at least Julia 1.8.\n\ncompat: Julia 1.11\nThe method allequal(f, itr) requires at least Julia 1.11.\n\nExamples\n\njulia> allequal([])\ntrue\n\njulia> allequal([1])\ntrue\n\njulia> allequal([1, 1])\ntrue\n\njulia> allequal([1, 2])\nfalse\n\njulia> allequal(Dict(:a => 1, :b => 1))\nfalse\n\njulia> allequal(abs2, [1, -1])\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.reduce-Tuple{Any, Any}","page":"Collections and Data Structures","title":"Base.reduce","text":"reduce(op, itr; [init])\n\nReduce the given collection itr with the given binary operator op. If provided, the initial value init must be a neutral element for op that will be returned for empty collections. It is unspecified whether init is used for non-empty collections.\n\nFor empty collections, providing init will be necessary, except for some special cases (e.g. when op is one of +, *, max, min, &, |) when Julia can determine the neutral element of op.\n\nReductions for certain commonly-used operators may have special implementations, and should be used instead: maximum(itr), minimum(itr), sum(itr), prod(itr), any(itr), all(itr). There are efficient methods for concatenating certain arrays of arrays by calling reduce(vcat, arr) or reduce(hcat, arr).\n\nThe associativity of the reduction is implementation dependent. This means that you can't use non-associative operations like - because it is undefined whether reduce(-,[1,2,3]) should be evaluated as (1-2)-3 or 1-(2-3). Use foldl or foldr instead for guaranteed left or right associativity.\n\nSome operations accumulate error. Parallelism will be easier if the reduction can be executed in groups. Future versions of Julia might change the algorithm. Note that the elements are not reordered if you use an ordered collection.\n\nExamples\n\njulia> reduce(*, [2; 3; 4])\n24\n\njulia> reduce(*, [2; 3; 4]; init=-1)\n-24\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.reduce-Tuple{Any, AbstractArray}","page":"Collections and Data Structures","title":"Base.reduce","text":"reduce(f, A::AbstractArray; dims=:, [init])\n\nReduce 2-argument function f along dimensions of A. dims is a vector specifying the dimensions to reduce, and the keyword argument init is the initial value to use in the reductions. For +, *, max and min the init argument is optional.\n\nThe associativity of the reduction is implementation-dependent; if you need a particular associativity, e.g. left-to-right, you should write your own loop or consider using foldl or foldr. See documentation for reduce.\n\nExamples\n\njulia> a = reshape(Vector(1:16), (4,4))\n4×4 Matrix{Int64}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> reduce(max, a, dims=2)\n4×1 Matrix{Int64}:\n 13\n 14\n 15\n 16\n\njulia> reduce(max, a, dims=1)\n1×4 Matrix{Int64}:\n 4 8 12 16\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.foldl-Tuple{Any, Any}","page":"Collections and Data Structures","title":"Base.foldl","text":"foldl(op, itr; [init])\n\nLike reduce, but with guaranteed left associativity. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.\n\nSee also mapfoldl, foldr, accumulate.\n\nExamples\n\njulia> foldl(=>, 1:4)\n((1 => 2) => 3) => 4\n\njulia> foldl(=>, 1:4; init=0)\n(((0 => 1) => 2) => 3) => 4\n\njulia> accumulate(=>, (1,2,3,4))\n(1, 1 => 2, (1 => 2) => 3, ((1 => 2) => 3) => 4)\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.foldr-Tuple{Any, Any}","page":"Collections and Data Structures","title":"Base.foldr","text":"foldr(op, itr; [init])\n\nLike reduce, but with guaranteed right associativity. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.\n\nExamples\n\njulia> foldr(=>, 1:4)\n1 => (2 => (3 => 4))\n\njulia> foldr(=>, 1:4; init=0)\n1 => (2 => (3 => (4 => 0)))\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.maximum","page":"Collections and Data Structures","title":"Base.maximum","text":"maximum(f, itr; [init])\n\nReturn the largest result of calling function f on each element of itr.\n\nThe value returned for empty itr can be specified by init. It must be a neutral element for max (i.e. which is less than or equal to any other element) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> maximum(length, [\"Julion\", \"Julia\", \"Jule\"])\n6\n\njulia> maximum(length, []; init=-1)\n-1\n\njulia> maximum(sin, Real[]; init=-1.0) # good, since output of sin is >= -1\n-1.0\n\n\n\n\n\nmaximum(itr; [init])\n\nReturn the largest element in a collection.\n\nThe value returned for empty itr can be specified by init. It must be a neutral element for max (i.e. which is less than or equal to any other element) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> maximum(-20.5:10)\n9.5\n\njulia> maximum([1,2,3])\n3\n\njulia> maximum(())\nERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer\nStacktrace:\n[...]\n\njulia> maximum((); init=-Inf)\n-Inf\n\n\n\n\n\nmaximum(A::AbstractArray; dims)\n\nCompute the maximum value of an array over the given dimensions. See also the max(a,b) function to take the maximum of two or more arguments, which can be applied elementwise to arrays via max.(a,b).\n\nSee also: maximum!, extrema, findmax, argmax.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> maximum(A, dims=1)\n1×2 Matrix{Int64}:\n 3 4\n\njulia> maximum(A, dims=2)\n2×1 Matrix{Int64}:\n 2\n 4\n\n\n\n\n\nmaximum(f, A::AbstractArray; dims)\n\nCompute the maximum value by calling the function f on each element of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> maximum(abs2, A, dims=1)\n1×2 Matrix{Int64}:\n 9 16\n\njulia> maximum(abs2, A, dims=2)\n2×1 Matrix{Int64}:\n 4\n 16\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.maximum!","page":"Collections and Data Structures","title":"Base.maximum!","text":"maximum!(r, A)\n\nCompute the maximum value of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> maximum!([1; 1], A)\n2-element Vector{Int64}:\n 2\n 4\n\njulia> maximum!([1 1], A)\n1×2 Matrix{Int64}:\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.minimum","page":"Collections and Data Structures","title":"Base.minimum","text":"minimum(f, itr; [init])\n\nReturn the smallest result of calling function f on each element of itr.\n\nThe value returned for empty itr can be specified by init. It must be a neutral element for min (i.e. which is greater than or equal to any other element) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> minimum(length, [\"Julion\", \"Julia\", \"Jule\"])\n4\n\njulia> minimum(length, []; init=typemax(Int64))\n9223372036854775807\n\njulia> minimum(sin, Real[]; init=1.0) # good, since output of sin is <= 1\n1.0\n\n\n\n\n\nminimum(itr; [init])\n\nReturn the smallest element in a collection.\n\nThe value returned for empty itr can be specified by init. It must be a neutral element for min (i.e. which is greater than or equal to any other element) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> minimum(-20.5:10)\n-20.5\n\njulia> minimum([1,2,3])\n1\n\njulia> minimum([])\nERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer\nStacktrace:\n[...]\n\njulia> minimum([]; init=Inf)\nInf\n\n\n\n\n\nminimum(A::AbstractArray; dims)\n\nCompute the minimum value of an array over the given dimensions. See also the min(a,b) function to take the minimum of two or more arguments, which can be applied elementwise to arrays via min.(a,b).\n\nSee also: minimum!, extrema, findmin, argmin.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> minimum(A, dims=1)\n1×2 Matrix{Int64}:\n 1 2\n\njulia> minimum(A, dims=2)\n2×1 Matrix{Int64}:\n 1\n 3\n\n\n\n\n\nminimum(f, A::AbstractArray; dims)\n\nCompute the minimum value by calling the function f on each element of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> minimum(abs2, A, dims=1)\n1×2 Matrix{Int64}:\n 1 4\n\njulia> minimum(abs2, A, dims=2)\n2×1 Matrix{Int64}:\n 1\n 9\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.minimum!","page":"Collections and Data Structures","title":"Base.minimum!","text":"minimum!(r, A)\n\nCompute the minimum value of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> minimum!([1; 1], A)\n2-element Vector{Int64}:\n 1\n 3\n\njulia> minimum!([1 1], A)\n1×2 Matrix{Int64}:\n 1 2\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.extrema","page":"Collections and Data Structures","title":"Base.extrema","text":"extrema(itr; [init]) -> (mn, mx)\n\nCompute both the minimum mn and maximum mx element in a single pass, and return them as a 2-tuple.\n\nThe value returned for empty itr can be specified by init. It must be a 2-tuple whose first and second elements are neutral elements for min and max respectively (i.e. which are greater/less than or equal to any other element). As a consequence, when itr is empty the returned (mn, mx) tuple will satisfy mn ≥ mx. When init is specified it may be used even for non-empty itr.\n\ncompat: Julia 1.8\nKeyword argument init requires Julia 1.8 or later.\n\nExamples\n\njulia> extrema(2:10)\n(2, 10)\n\njulia> extrema([9,pi,4.5])\n(3.141592653589793, 9.0)\n\njulia> extrema([]; init = (Inf, -Inf))\n(Inf, -Inf)\n\n\n\n\n\nextrema(f, itr; [init]) -> (mn, mx)\n\nCompute both the minimum mn and maximum mx of f applied to each element in itr and return them as a 2-tuple. Only one pass is made over itr.\n\nThe value returned for empty itr can be specified by init. It must be a 2-tuple whose first and second elements are neutral elements for min and max respectively (i.e. which are greater/less than or equal to any other element). It is used for non-empty collections. Note: it implies that, for empty itr, the returned value (mn, mx) satisfies mn ≥ mx even though for non-empty itr it satisfies mn ≤ mx. This is a \"paradoxical\" but yet expected result.\n\ncompat: Julia 1.2\nThis method requires Julia 1.2 or later.\n\ncompat: Julia 1.8\nKeyword argument init requires Julia 1.8 or later.\n\nExamples\n\njulia> extrema(sin, 0:π)\n(0.0, 0.9092974268256817)\n\njulia> extrema(sin, Real[]; init = (1.0, -1.0)) # good, since -1 ≤ sin(::Real) ≤ 1\n(1.0, -1.0)\n\n\n\n\n\nextrema(A::AbstractArray; dims) -> Array{Tuple}\n\nCompute the minimum and maximum elements of an array over the given dimensions.\n\nSee also: minimum, maximum, extrema!.\n\nExamples\n\njulia> A = reshape(Vector(1:2:16), (2,2,2))\n2×2×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 5\n 3 7\n\n[:, :, 2] =\n 9 13\n 11 15\n\njulia> extrema(A, dims = (1,2))\n1×1×2 Array{Tuple{Int64, Int64}, 3}:\n[:, :, 1] =\n (1, 7)\n\n[:, :, 2] =\n (9, 15)\n\n\n\n\n\nextrema(f, A::AbstractArray; dims) -> Array{Tuple}\n\nCompute the minimum and maximum of f applied to each element in the given dimensions of A.\n\ncompat: Julia 1.2\nThis method requires Julia 1.2 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.extrema!","page":"Collections and Data Structures","title":"Base.extrema!","text":"extrema!(r, A)\n\nCompute the minimum and maximum value of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\ncompat: Julia 1.8\nThis method requires Julia 1.8 or later.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> extrema!([(1, 1); (1, 1)], A)\n2-element Vector{Tuple{Int64, Int64}}:\n (1, 2)\n (3, 4)\n\njulia> extrema!([(1, 1);; (1, 1)], A)\n1×2 Matrix{Tuple{Int64, Int64}}:\n (1, 3) (2, 4)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.argmax","page":"Collections and Data Structures","title":"Base.argmax","text":"argmax(r::AbstractRange)\n\nRanges can have multiple maximal elements. In that case argmax will return a maximal index, but not necessarily the first one.\n\n\n\n\n\nargmax(f, domain)\n\nReturn a value x from domain for which f(x) is maximised. If there are multiple maximal values for f(x) then the first one will be found.\n\ndomain must be a non-empty iterable.\n\nValues are compared with isless.\n\ncompat: Julia 1.7\nThis method requires Julia 1.7 or later.\n\nSee also argmin, findmax.\n\nExamples\n\njulia> argmax(abs, -10:5)\n-10\n\njulia> argmax(cos, 0:π/2:2π)\n0.0\n\n\n\n\n\nargmax(itr)\n\nReturn the index or key of the maximal element in a collection. If there are multiple maximal elements, then the first one will be returned.\n\nThe collection must not be empty.\n\nIndices are of the same type as those returned by keys(itr) and pairs(itr).\n\nValues are compared with isless.\n\nSee also: argmin, findmax.\n\nExamples\n\njulia> argmax([8, 0.1, -9, pi])\n1\n\njulia> argmax([1, 7, 7, 6])\n2\n\njulia> argmax([1, 7, 7, NaN])\n4\n\n\n\n\n\nargmax(A; dims) -> indices\n\nFor an array input, return the indices of the maximum elements over the given dimensions. NaN is treated as greater than all other values except missing.\n\nExamples\n\njulia> A = [1.0 2; 3 4]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> argmax(A, dims=1)\n1×2 Matrix{CartesianIndex{2}}:\n CartesianIndex(2, 1) CartesianIndex(2, 2)\n\njulia> argmax(A, dims=2)\n2×1 Matrix{CartesianIndex{2}}:\n CartesianIndex(1, 2)\n CartesianIndex(2, 2)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.argmin","page":"Collections and Data Structures","title":"Base.argmin","text":"argmin(r::AbstractRange)\n\nRanges can have multiple minimal elements. In that case argmin will return a minimal index, but not necessarily the first one.\n\n\n\n\n\nargmin(f, domain)\n\nReturn a value x from domain for which f(x) is minimised. If there are multiple minimal values for f(x) then the first one will be found.\n\ndomain must be a non-empty iterable.\n\nNaN is treated as less than all other values except missing.\n\ncompat: Julia 1.7\nThis method requires Julia 1.7 or later.\n\nSee also argmax, findmin.\n\nExamples\n\njulia> argmin(sign, -10:5)\n-10\n\njulia> argmin(x -> -x^3 + x^2 - 10, -5:5)\n5\n\njulia> argmin(acos, 0:0.1:1)\n1.0\n\n\n\n\n\nargmin(itr)\n\nReturn the index or key of the minimal element in a collection. If there are multiple minimal elements, then the first one will be returned.\n\nThe collection must not be empty.\n\nIndices are of the same type as those returned by keys(itr) and pairs(itr).\n\nNaN is treated as less than all other values except missing.\n\nSee also: argmax, findmin.\n\nExamples\n\njulia> argmin([8, 0.1, -9, pi])\n3\n\njulia> argmin([7, 1, 1, 6])\n2\n\njulia> argmin([7, 1, 1, NaN])\n4\n\n\n\n\n\nargmin(A; dims) -> indices\n\nFor an array input, return the indices of the minimum elements over the given dimensions. NaN is treated as less than all other values except missing.\n\nExamples\n\njulia> A = [1.0 2; 3 4]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> argmin(A, dims=1)\n1×2 Matrix{CartesianIndex{2}}:\n CartesianIndex(1, 1) CartesianIndex(1, 2)\n\njulia> argmin(A, dims=2)\n2×1 Matrix{CartesianIndex{2}}:\n CartesianIndex(1, 1)\n CartesianIndex(2, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.findmax","page":"Collections and Data Structures","title":"Base.findmax","text":"findmax(f, domain) -> (f(x), index)\n\nReturn a pair of a value in the codomain (outputs of f) and the index or key of the corresponding value in the domain (inputs to f) such that f(x) is maximised. If there are multiple maximal points, then the first one will be returned.\n\ndomain must be a non-empty iterable supporting keys. Indices are of the same type as those returned by keys(domain).\n\nValues are compared with isless.\n\ncompat: Julia 1.7\nThis method requires Julia 1.7 or later.\n\nExamples\n\njulia> findmax(identity, 5:9)\n(9, 5)\n\njulia> findmax(-, 1:10)\n(-1, 1)\n\njulia> findmax(first, [(1, :a), (3, :b), (3, :c)])\n(3, 2)\n\njulia> findmax(cos, 0:π/2:2π)\n(1.0, 1)\n\n\n\n\n\nfindmax(itr) -> (x, index)\n\nReturn the maximal element of the collection itr and its index or key. If there are multiple maximal elements, then the first one will be returned. Values are compared with isless.\n\nIndices are of the same type as those returned by keys(itr) and pairs(itr).\n\nSee also: findmin, argmax, maximum.\n\nExamples\n\njulia> findmax([8, 0.1, -9, pi])\n(8.0, 1)\n\njulia> findmax([1, 7, 7, 6])\n(7, 2)\n\njulia> findmax([1, 7, 7, NaN])\n(NaN, 4)\n\n\n\n\n\nfindmax(A; dims) -> (maxval, index)\n\nFor an array input, returns the value and index of the maximum over the given dimensions. NaN is treated as greater than all other values except missing.\n\nExamples\n\njulia> A = [1.0 2; 3 4]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> findmax(A, dims=1)\n([3.0 4.0], CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(2, 2)])\n\njulia> findmax(A, dims=2)\n([2.0; 4.0;;], CartesianIndex{2}[CartesianIndex(1, 2); CartesianIndex(2, 2);;])\n\n\n\n\n\nfindmax(f, A; dims) -> (f(x), index)\n\nFor an array input, returns the value in the codomain and index of the corresponding value which maximize f over the given dimensions.\n\nExamples\n\njulia> A = [-1.0 1; -0.5 2]\n2×2 Matrix{Float64}:\n -1.0 1.0\n -0.5 2.0\n\njulia> findmax(abs2, A, dims=1)\n([1.0 4.0], CartesianIndex{2}[CartesianIndex(1, 1) CartesianIndex(2, 2)])\n\njulia> findmax(abs2, A, dims=2)\n([1.0; 4.0;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 2);;])\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.findmin","page":"Collections and Data Structures","title":"Base.findmin","text":"findmin(f, domain) -> (f(x), index)\n\nReturn a pair of a value in the codomain (outputs of f) and the index or key of the corresponding value in the domain (inputs to f) such that f(x) is minimised. If there are multiple minimal points, then the first one will be returned.\n\ndomain must be a non-empty iterable.\n\nIndices are of the same type as those returned by keys(domain) and pairs(domain).\n\nNaN is treated as less than all other values except missing.\n\ncompat: Julia 1.7\nThis method requires Julia 1.7 or later.\n\nExamples\n\njulia> findmin(identity, 5:9)\n(5, 1)\n\njulia> findmin(-, 1:10)\n(-10, 10)\n\njulia> findmin(first, [(2, :a), (2, :b), (3, :c)])\n(2, 1)\n\njulia> findmin(cos, 0:π/2:2π)\n(-1.0, 3)\n\n\n\n\n\nfindmin(itr) -> (x, index)\n\nReturn the minimal element of the collection itr and its index or key. If there are multiple minimal elements, then the first one will be returned. NaN is treated as less than all other values except missing.\n\nIndices are of the same type as those returned by keys(itr) and pairs(itr).\n\nSee also: findmax, argmin, minimum.\n\nExamples\n\njulia> findmin([8, 0.1, -9, pi])\n(-9.0, 3)\n\njulia> findmin([1, 7, 7, 6])\n(1, 1)\n\njulia> findmin([1, 7, 7, NaN])\n(NaN, 4)\n\n\n\n\n\nfindmin(A; dims) -> (minval, index)\n\nFor an array input, returns the value and index of the minimum over the given dimensions. NaN is treated as less than all other values except missing.\n\nExamples\n\njulia> A = [1.0 2; 3 4]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> findmin(A, dims=1)\n([1.0 2.0], CartesianIndex{2}[CartesianIndex(1, 1) CartesianIndex(1, 2)])\n\njulia> findmin(A, dims=2)\n([1.0; 3.0;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 1);;])\n\n\n\n\n\nfindmin(f, A; dims) -> (f(x), index)\n\nFor an array input, returns the value in the codomain and index of the corresponding value which minimize f over the given dimensions.\n\nExamples\n\njulia> A = [-1.0 1; -0.5 2]\n2×2 Matrix{Float64}:\n -1.0 1.0\n -0.5 2.0\n\njulia> findmin(abs2, A, dims=1)\n([0.25 1.0], CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(1, 2)])\n\njulia> findmin(abs2, A, dims=2)\n([1.0; 0.25;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 1);;])\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.findmax!","page":"Collections and Data Structures","title":"Base.findmax!","text":"findmax!(rval, rind, A) -> (maxval, index)\n\nFind the maximum of A and the corresponding linear index along singleton dimensions of rval and rind, and store the results in rval and rind. NaN is treated as greater than all other values except missing.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.findmin!","page":"Collections and Data Structures","title":"Base.findmin!","text":"findmin!(rval, rind, A) -> (minval, index)\n\nFind the minimum of A and the corresponding linear index along singleton dimensions of rval and rind, and store the results in rval and rind. NaN is treated as less than all other values except missing.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.sum","page":"Collections and Data Structures","title":"Base.sum","text":"sum(f, itr; [init])\n\nSum the results of calling function f on each element of itr.\n\nThe return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.\n\nThe value returned for empty itr can be specified by init. It must be the additive identity (i.e. zero) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> sum(abs2, [2; 3; 4])\n29\n\nNote the important difference between sum(A) and reduce(+, A) for arrays with small integer eltype:\n\njulia> sum(Int8[100, 28])\n128\n\njulia> reduce(+, Int8[100, 28])\n-128\n\nIn the former case, the integers are widened to system word size and therefore the result is 128. In the latter case, no such widening happens and integer overflow results in -128.\n\n\n\n\n\nsum(itr; [init])\n\nReturn the sum of all elements in a collection.\n\nThe return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.\n\nThe value returned for empty itr can be specified by init. It must be the additive identity (i.e. zero) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nSee also: reduce, mapreduce, count, union.\n\nExamples\n\njulia> sum(1:20)\n210\n\njulia> sum(1:20; init = 0.0)\n210.0\n\n\n\n\n\nsum(A::AbstractArray; dims)\n\nSum elements of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> sum(A, dims=1)\n1×2 Matrix{Int64}:\n 4 6\n\njulia> sum(A, dims=2)\n2×1 Matrix{Int64}:\n 3\n 7\n\n\n\n\n\nsum(f, A::AbstractArray; dims)\n\nSum the results of calling function f on each element of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> sum(abs2, A, dims=1)\n1×2 Matrix{Int64}:\n 10 20\n\njulia> sum(abs2, A, dims=2)\n2×1 Matrix{Int64}:\n 5\n 25\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.sum!","page":"Collections and Data Structures","title":"Base.sum!","text":"sum!(r, A)\n\nSum elements of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> sum!([1; 1], A)\n2-element Vector{Int64}:\n 3\n 7\n\njulia> sum!([1 1], A)\n1×2 Matrix{Int64}:\n 4 6\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.prod","page":"Collections and Data Structures","title":"Base.prod","text":"prod(f, itr; [init])\n\nReturn the product of f applied to each element of itr.\n\nThe return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.\n\nThe value returned for empty itr can be specified by init. It must be the multiplicative identity (i.e. one) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> prod(abs2, [2; 3; 4])\n576\n\n\n\n\n\nprod(itr; [init])\n\nReturn the product of all elements of a collection.\n\nThe return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.\n\nThe value returned for empty itr can be specified by init. It must be the multiplicative identity (i.e. one) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nSee also: reduce, cumprod, any.\n\nExamples\n\njulia> prod(1:5)\n120\n\njulia> prod(1:5; init = 1.0)\n120.0\n\n\n\n\n\nprod(A::AbstractArray; dims)\n\nMultiply elements of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> prod(A, dims=1)\n1×2 Matrix{Int64}:\n 3 8\n\njulia> prod(A, dims=2)\n2×1 Matrix{Int64}:\n 2\n 12\n\n\n\n\n\nprod(f, A::AbstractArray; dims)\n\nMultiply the results of calling the function f on each element of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> prod(abs2, A, dims=1)\n1×2 Matrix{Int64}:\n 9 64\n\njulia> prod(abs2, A, dims=2)\n2×1 Matrix{Int64}:\n 4\n 144\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.prod!","page":"Collections and Data Structures","title":"Base.prod!","text":"prod!(r, A)\n\nMultiply elements of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> prod!([1; 1], A)\n2-element Vector{Int64}:\n 2\n 12\n\njulia> prod!([1 1], A)\n1×2 Matrix{Int64}:\n 3 8\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.any-Tuple{Any}","page":"Collections and Data Structures","title":"Base.any","text":"any(itr) -> Bool\n\nTest whether any elements of a boolean collection are true, returning true as soon as the first true value in itr is encountered (short-circuiting). To short-circuit on false, use all.\n\nIf the input contains missing values, return missing if all non-missing values are false (or equivalently, if the input contains no true value), following three-valued logic.\n\nSee also: all, count, sum, |, , ||.\n\nExamples\n\njulia> a = [true,false,false,true]\n4-element Vector{Bool}:\n 1\n 0\n 0\n 1\n\njulia> any(a)\ntrue\n\njulia> any((println(i); v) for (i, v) in enumerate(a))\n1\ntrue\n\njulia> any([missing, true])\ntrue\n\njulia> any([false, missing])\nmissing\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.any-Tuple{AbstractArray, Any}","page":"Collections and Data Structures","title":"Base.any","text":"any(p, itr) -> Bool\n\nDetermine whether predicate p returns true for any elements of itr, returning true as soon as the first item in itr for which p returns true is encountered (short-circuiting). To short-circuit on false, use all.\n\nIf the input contains missing values, return missing if all non-missing values are false (or equivalently, if the input contains no true value), following three-valued logic.\n\nExamples\n\njulia> any(i->(4<=i<=6), [3,5,7])\ntrue\n\njulia> any(i -> (println(i); i > 3), 1:10)\n1\n2\n3\n4\ntrue\n\njulia> any(i -> i > 0, [1, missing])\ntrue\n\njulia> any(i -> i > 0, [-1, missing])\nmissing\n\njulia> any(i -> i > 0, [-1, 0])\nfalse\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.any!","page":"Collections and Data Structures","title":"Base.any!","text":"any!(r, A)\n\nTest whether any values in A along the singleton dimensions of r are true, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [true false; true false]\n2×2 Matrix{Bool}:\n 1 0\n 1 0\n\njulia> any!([1; 1], A)\n2-element Vector{Int64}:\n 1\n 1\n\njulia> any!([1 1], A)\n1×2 Matrix{Int64}:\n 1 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.all-Tuple{Any}","page":"Collections and Data Structures","title":"Base.all","text":"all(itr) -> Bool\n\nTest whether all elements of a boolean collection are true, returning false as soon as the first false value in itr is encountered (short-circuiting). To short-circuit on true, use any.\n\nIf the input contains missing values, return missing if all non-missing values are true (or equivalently, if the input contains no false value), following three-valued logic.\n\nSee also: all!, any, count, &, , &&, allunique.\n\nExamples\n\njulia> a = [true,false,false,true]\n4-element Vector{Bool}:\n 1\n 0\n 0\n 1\n\njulia> all(a)\nfalse\n\njulia> all((println(i); v) for (i, v) in enumerate(a))\n1\n2\nfalse\n\njulia> all([missing, false])\nfalse\n\njulia> all([true, missing])\nmissing\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.all-Tuple{AbstractArray, Any}","page":"Collections and Data Structures","title":"Base.all","text":"all(p, itr) -> Bool\n\nDetermine whether predicate p returns true for all elements of itr, returning false as soon as the first item in itr for which p returns false is encountered (short-circuiting). To short-circuit on true, use any.\n\nIf the input contains missing values, return missing if all non-missing values are true (or equivalently, if the input contains no false value), following three-valued logic.\n\nExamples\n\njulia> all(i->(4<=i<=6), [4,5,6])\ntrue\n\njulia> all(i -> (println(i); i < 3), 1:10)\n1\n2\n3\nfalse\n\njulia> all(i -> i > 0, [1, missing])\nmissing\n\njulia> all(i -> i > 0, [-1, missing])\nfalse\n\njulia> all(i -> i > 0, [1, 2])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.all!","page":"Collections and Data Structures","title":"Base.all!","text":"all!(r, A)\n\nTest whether all values in A along the singleton dimensions of r are true, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [true false; true false]\n2×2 Matrix{Bool}:\n 1 0\n 1 0\n\njulia> all!([1; 1], A)\n2-element Vector{Int64}:\n 0\n 0\n\njulia> all!([1 1], A)\n1×2 Matrix{Int64}:\n 1 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.count","page":"Collections and Data Structures","title":"Base.count","text":"count([f=identity,] itr; init=0) -> Integer\n\nCount the number of elements in itr for which the function f returns true. If f is omitted, count the number of true elements in itr (which should be a collection of boolean values). init optionally specifies the value to start counting from and therefore also determines the output type.\n\ncompat: Julia 1.6\ninit keyword was added in Julia 1.6.\n\nSee also: any, sum.\n\nExamples\n\njulia> count(i->(4<=i<=6), [2,3,4,5,6])\n3\n\njulia> count([true, false, true, true])\n3\n\njulia> count(>(3), 1:7, init=0x03)\n0x07\n\n\n\n\n\ncount(\n pattern::Union{AbstractChar,AbstractString,AbstractPattern},\n string::AbstractString;\n overlap::Bool = false,\n)\n\nReturn the number of matches for pattern in string. This is equivalent to calling length(findall(pattern, string)) but more efficient.\n\nIf overlap=true, the matching sequences are allowed to overlap indices in the original string, otherwise they must be from disjoint character ranges.\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\ncompat: Julia 1.7\nUsing a character as the pattern requires at least Julia 1.7.\n\nExamples\n\njulia> count('a', \"JuliaLang\")\n2\n\njulia> count(r\"a(.)a\", \"cabacabac\", overlap=true)\n3\n\njulia> count(r\"a(.)a\", \"cabacabac\")\n2\n\n\n\n\n\ncount([f=identity,] A::AbstractArray; dims=:)\n\nCount the number of elements in A for which f returns true over the given dimensions.\n\ncompat: Julia 1.5\ndims keyword was added in Julia 1.5.\n\ncompat: Julia 1.6\ninit keyword was added in Julia 1.6.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> count(<=(2), A, dims=1)\n1×2 Matrix{Int64}:\n 1 1\n\njulia> count(<=(2), A, dims=2)\n2×1 Matrix{Int64}:\n 2\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.foreach","page":"Collections and Data Structures","title":"Base.foreach","text":"foreach(f, c...) -> Nothing\n\nCall function f on each element of iterable c. For multiple iterable arguments, f is called elementwise, and iteration stops when any iterator is finished.\n\nforeach should be used instead of map when the results of f are not needed, for example in foreach(println, array).\n\nExamples\n\njulia> tri = 1:3:7; res = Int[];\n\njulia> foreach(x -> push!(res, x^2), tri)\n\njulia> res\n3-element Vector{Int64}:\n 1\n 16\n 49\n\njulia> foreach((x, y) -> println(x, \" with \", y), tri, 'a':'z')\n1 with a\n4 with b\n7 with c\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.map","page":"Collections and Data Structures","title":"Base.map","text":"map(f, c...) -> collection\n\nTransform collection c by applying f to each element. For multiple collection arguments, apply f elementwise, and stop when any of them is exhausted.\n\nSee also map!, foreach, mapreduce, mapslices, zip, Iterators.map.\n\nExamples\n\njulia> map(x -> x * 2, [1, 2, 3])\n3-element Vector{Int64}:\n 2\n 4\n 6\n\njulia> map(+, [1, 2, 3], [10, 20, 30, 400, 5000])\n3-element Vector{Int64}:\n 11\n 22\n 33\n\n\n\n\n\nmap(f, A::AbstractArray...) -> N-array\n\nWhen acting on multi-dimensional arrays of the same ndims, they must all have the same axes, and the answer will too.\n\nSee also broadcast, which allows mismatched sizes.\n\nExamples\n\njulia> map(//, [1 2; 3 4], [4 3; 2 1])\n2×2 Matrix{Rational{Int64}}:\n 1//4 2//3\n 3//2 4//1\n\njulia> map(+, [1 2; 3 4], zeros(2,1))\nERROR: DimensionMismatch\n\njulia> map(+, [1 2; 3 4], [1,10,100,1000], zeros(3,1)) # iterates until 3rd is exhausted\n3-element Vector{Float64}:\n 2.0\n 13.0\n 102.0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.map!","page":"Collections and Data Structures","title":"Base.map!","text":"map!(function, destination, collection...)\n\nLike map, but stores the result in destination rather than a new collection. destination must be at least as large as the smallest collection.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also: map, foreach, zip, copyto!.\n\nExamples\n\njulia> a = zeros(3);\n\njulia> map!(x -> x * 2, a, [1, 2, 3]);\n\njulia> a\n3-element Vector{Float64}:\n 2.0\n 4.0\n 6.0\n\njulia> map!(+, zeros(Int, 5), 100:999, 1:3)\n5-element Vector{Int64}:\n 101\n 103\n 105\n 0\n 0\n\n\n\n\n\nmap!(f, values(dict::AbstractDict))\n\nModifies dict by transforming each value from val to f(val). Note that the type of dict cannot be changed: if f(val) is not an instance of the value type of dict then it will be converted to the value type if possible and otherwise raise an error.\n\ncompat: Julia 1.2\nmap!(f, values(dict::AbstractDict)) requires Julia 1.2 or later.\n\nExamples\n\njulia> d = Dict(:a => 1, :b => 2)\nDict{Symbol, Int64} with 2 entries:\n :a => 1\n :b => 2\n\njulia> map!(v -> v-1, values(d))\nValueIterator for a Dict{Symbol, Int64} with 2 entries. Values:\n 0\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.mapreduce-Tuple{Any, Any, Any}","page":"Collections and Data Structures","title":"Base.mapreduce","text":"mapreduce(f, op, itrs...; [init])\n\nApply function f to each element(s) in itrs, and then reduce the result using the binary function op. If provided, init must be a neutral element for op that will be returned for empty collections. It is unspecified whether init is used for non-empty collections. In general, it will be necessary to provide init to work with empty collections.\n\nmapreduce is functionally equivalent to calling reduce(op, map(f, itr); init=init), but will in general execute faster since no intermediate collection needs to be created. See documentation for reduce and map.\n\ncompat: Julia 1.2\nmapreduce with multiple iterators requires Julia 1.2 or later.\n\nExamples\n\njulia> mapreduce(x->x^2, +, [1:3;]) # == 1 + 4 + 9\n14\n\nThe associativity of the reduction is implementation-dependent. Additionally, some implementations may reuse the return value of f for elements that appear multiple times in itr. Use mapfoldl or mapfoldr instead for guaranteed left or right associativity and invocation of f for every value.\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.mapfoldl-Tuple{Any, Any, Any}","page":"Collections and Data Structures","title":"Base.mapfoldl","text":"mapfoldl(f, op, itr; [init])\n\nLike mapreduce, but with guaranteed left associativity, as in foldl. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.mapfoldr-Tuple{Any, Any, Any}","page":"Collections and Data Structures","title":"Base.mapfoldr","text":"mapfoldr(f, op, itr; [init])\n\nLike mapreduce, but with guaranteed right associativity, as in foldr. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.first","page":"Collections and Data Structures","title":"Base.first","text":"first(coll)\n\nGet the first element of an iterable collection. Return the start point of an AbstractRange even if it is empty.\n\nSee also: only, firstindex, last.\n\nExamples\n\njulia> first(2:2:10)\n2\n\njulia> first([1; 2; 3; 4])\n1\n\n\n\n\n\nfirst(itr, n::Integer)\n\nGet the first n elements of the iterable collection itr, or fewer elements if itr is not long enough.\n\nSee also: startswith, Iterators.take.\n\ncompat: Julia 1.6\nThis method requires at least Julia 1.6.\n\nExamples\n\njulia> first([\"foo\", \"bar\", \"qux\"], 2)\n2-element Vector{String}:\n \"foo\"\n \"bar\"\n\njulia> first(1:6, 10)\n1:6\n\njulia> first(Bool[], 1)\nBool[]\n\n\n\n\n\nfirst(s::AbstractString, n::Integer)\n\nGet a string consisting of the first n characters of s.\n\nExamples\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 0)\n\"\"\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 1)\n\"∀\"\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 3)\n\"∀ϵ≠\"\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.last","page":"Collections and Data Structures","title":"Base.last","text":"last(coll)\n\nGet the last element of an ordered collection, if it can be computed in O(1) time. This is accomplished by calling lastindex to get the last index. Return the end point of an AbstractRange even if it is empty.\n\nSee also first, endswith.\n\nExamples\n\njulia> last(1:2:10)\n9\n\njulia> last([1; 2; 3; 4])\n4\n\n\n\n\n\nlast(itr, n::Integer)\n\nGet the last n elements of the iterable collection itr, or fewer elements if itr is not long enough.\n\ncompat: Julia 1.6\nThis method requires at least Julia 1.6.\n\nExamples\n\njulia> last([\"foo\", \"bar\", \"qux\"], 2)\n2-element Vector{String}:\n \"bar\"\n \"qux\"\n\njulia> last(1:6, 10)\n1:6\n\njulia> last(Float64[], 1)\nFloat64[]\n\n\n\n\n\nlast(s::AbstractString, n::Integer)\n\nGet a string consisting of the last n characters of s.\n\nExamples\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 0)\n\"\"\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 1)\n\"0\"\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 3)\n\"²>0\"\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.front","page":"Collections and Data Structures","title":"Base.front","text":"front(x::Tuple)::Tuple\n\nReturn a Tuple consisting of all but the last component of x.\n\nSee also: first, tail.\n\nExamples\n\njulia> Base.front((1,2,3))\n(1, 2)\n\njulia> Base.front(())\nERROR: ArgumentError: Cannot call front on an empty tuple.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.tail","page":"Collections and Data Structures","title":"Base.tail","text":"tail(x::Tuple)::Tuple\n\nReturn a Tuple consisting of all but the first component of x.\n\nSee also: front, rest, first, Iterators.peel.\n\nExamples\n\njulia> Base.tail((1,2,3))\n(2, 3)\n\njulia> Base.tail(())\nERROR: ArgumentError: Cannot call tail on an empty tuple.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.step","page":"Collections and Data Structures","title":"Base.step","text":"step(r)\n\nGet the step size of an AbstractRange object.\n\nExamples\n\njulia> step(1:10)\n1\n\njulia> step(1:2:10)\n2\n\njulia> step(2.5:0.3:10.9)\n0.3\n\njulia> step(range(2.5, stop=10.9, length=85))\n0.1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.collect-Tuple{Any}","page":"Collections and Data Structures","title":"Base.collect","text":"collect(collection)\n\nReturn an Array of all items in a collection or iterator. For dictionaries, returns a Vector of key=>value Pairs. If the argument is array-like or is an iterator with the HasShape trait, the result will have the same shape and number of dimensions as the argument.\n\nUsed by comprehensions to turn a generator expression into an Array. Thus, on generators, the square-brackets notation may be used instead of calling collect, see second example.\n\nExamples\n\nCollect items from a UnitRange{Int64} collection:\n\njulia> collect(1:3)\n3-element Vector{Int64}:\n 1\n 2\n 3\n\nCollect items from a generator (same output as [x^2 for x in 1:3]):\n\njulia> collect(x^2 for x in 1:3)\n3-element Vector{Int64}:\n 1\n 4\n 9\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.collect-Tuple{Type, Any}","page":"Collections and Data Structures","title":"Base.collect","text":"collect(element_type, collection)\n\nReturn an Array with the given element type of all items in a collection or iterable. The result has the same shape and number of dimensions as collection.\n\nExamples\n\njulia> collect(Float64, 1:2:5)\n3-element Vector{Float64}:\n 1.0\n 3.0\n 5.0\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.filter","page":"Collections and Data Structures","title":"Base.filter","text":"filter(f, a)\n\nReturn a copy of collection a, removing elements for which f is false. The function f is passed one argument.\n\ncompat: Julia 1.4\nSupport for a as a tuple requires at least Julia 1.4.\n\nSee also: filter!, Iterators.filter.\n\nExamples\n\njulia> a = 1:10\n1:10\n\njulia> filter(isodd, a)\n5-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n\n\n\n\n\nfilter(f)\n\nCreate a function that filters its arguments with function f using filter, i.e. a function equivalent to x -> filter(f, x).\n\nThe returned function is of type Base.Fix1{typeof(filter)}, which can be used to implement specialized methods.\n\nExamples\n\njulia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)\n(1, 2, 4, 6)\n\njulia> map(filter(iseven), [1:3, 2:4, 3:5])\n3-element Vector{Vector{Int64}}:\n [2]\n [2, 4]\n [4]\n\ncompat: Julia 1.9\nThis method requires at least Julia 1.9.\n\n\n\n\n\nfilter(f, d::AbstractDict)\n\nReturn a copy of d, removing elements for which f is false. The function f is passed key=>value pairs.\n\nExamples\n\njulia> d = Dict(1=>\"a\", 2=>\"b\")\nDict{Int64, String} with 2 entries:\n 2 => \"b\"\n 1 => \"a\"\n\njulia> filter(p->isodd(p.first), d)\nDict{Int64, String} with 1 entry:\n 1 => \"a\"\n\n\n\n\n\nfilter(f, itr::SkipMissing{<:AbstractArray})\n\nReturn a vector similar to the array wrapped by the given SkipMissing iterator but with all missing elements and those for which f returns false removed.\n\ncompat: Julia 1.2\nThis method requires Julia 1.2 or later.\n\nExamples\n\njulia> x = [1 2; missing 4]\n2×2 Matrix{Union{Missing, Int64}}:\n 1 2\n missing 4\n\njulia> filter(isodd, skipmissing(x))\n1-element Vector{Int64}:\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.filter!","page":"Collections and Data Structures","title":"Base.filter!","text":"filter!(f, a)\n\nUpdate collection a, removing elements for which f is false. The function f is passed one argument.\n\nExamples\n\njulia> filter!(isodd, Vector(1:10))\n5-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n\n\n\n\n\nfilter!(f, d::AbstractDict)\n\nUpdate d, removing elements for which f is false. The function f is passed key=>value pairs.\n\nExamples\n\njulia> d = Dict(1=>\"a\", 2=>\"b\", 3=>\"c\")\nDict{Int64, String} with 3 entries:\n 2 => \"b\"\n 3 => \"c\"\n 1 => \"a\"\n\njulia> filter!(p->isodd(p.first), d)\nDict{Int64, String} with 2 entries:\n 3 => \"c\"\n 1 => \"a\"\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.replace-Tuple{Any, Vararg{Pair}}","page":"Collections and Data Structures","title":"Base.replace","text":"replace(A, old_new::Pair...; [count::Integer])\n\nReturn a copy of collection A where, for each pair old=>new in old_new, all occurrences of old are replaced by new. Equality is determined using isequal. If count is specified, then replace at most count occurrences in total.\n\nThe element type of the result is chosen using promotion (see promote_type) based on the element type of A and on the types of the new values in pairs. If count is omitted and the element type of A is a Union, the element type of the result will not include singleton types which are replaced with values of a different type: for example, Union{T,Missing} will become T if missing is replaced.\n\nSee also replace!, splice!, delete!, insert!.\n\ncompat: Julia 1.7\nVersion 1.7 is required to replace elements of a Tuple.\n\nExamples\n\njulia> replace([1, 2, 1, 3], 1=>0, 2=>4, count=2)\n4-element Vector{Int64}:\n 0\n 4\n 1\n 3\n\njulia> replace([1, missing], missing=>0)\n2-element Vector{Int64}:\n 1\n 0\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.replace-Tuple{Union{Function, Type}, Any}","page":"Collections and Data Structures","title":"Base.replace","text":"replace(new::Union{Function, Type}, A; [count::Integer])\n\nReturn a copy of A where each value x in A is replaced by new(x). If count is specified, then replace at most count values in total (replacements being defined as new(x) !== x).\n\ncompat: Julia 1.7\nVersion 1.7 is required to replace elements of a Tuple.\n\nExamples\n\njulia> replace(x -> isodd(x) ? 2x : x, [1, 2, 3, 4])\n4-element Vector{Int64}:\n 2\n 2\n 6\n 4\n\njulia> replace(Dict(1=>2, 3=>4)) do kv\n first(kv) < 3 ? first(kv)=>3 : kv\n end\nDict{Int64, Int64} with 2 entries:\n 3 => 4\n 1 => 3\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.replace!","page":"Collections and Data Structures","title":"Base.replace!","text":"replace!(A, old_new::Pair...; [count::Integer])\n\nFor each pair old=>new in old_new, replace all occurrences of old in collection A by new. Equality is determined using isequal. If count is specified, then replace at most count occurrences in total. See also replace.\n\nExamples\n\njulia> replace!([1, 2, 1, 3], 1=>0, 2=>4, count=2)\n4-element Vector{Int64}:\n 0\n 4\n 1\n 3\n\njulia> replace!(Set([1, 2, 3]), 1=>0)\nSet{Int64} with 3 elements:\n 0\n 2\n 3\n\n\n\n\n\nreplace!(new::Union{Function, Type}, A; [count::Integer])\n\nReplace each element x in collection A by new(x). If count is specified, then replace at most count values in total (replacements being defined as new(x) !== x).\n\nExamples\n\njulia> replace!(x -> isodd(x) ? 2x : x, [1, 2, 3, 4])\n4-element Vector{Int64}:\n 2\n 2\n 6\n 4\n\njulia> replace!(Dict(1=>2, 3=>4)) do kv\n first(kv) < 3 ? first(kv)=>3 : kv\n end\nDict{Int64, Int64} with 2 entries:\n 3 => 4\n 1 => 3\n\njulia> replace!(x->2x, Set([3, 6]))\nSet{Int64} with 2 elements:\n 6\n 12\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.rest","page":"Collections and Data Structures","title":"Base.rest","text":"Base.rest(collection[, itr_state])\n\nGeneric function for taking the tail of collection, starting from a specific iteration state itr_state. Return a Tuple, if collection itself is a Tuple, a subtype of AbstractVector, if collection is an AbstractArray, a subtype of AbstractString if collection is an AbstractString, and an arbitrary iterator, falling back to Iterators.rest(collection[, itr_state]), otherwise.\n\nCan be overloaded for user-defined collection types to customize the behavior of slurping in assignments in final position, like a, b... = collection.\n\ncompat: Julia 1.6\nBase.rest requires at least Julia 1.6.\n\nSee also: first, Iterators.rest, Base.split_rest.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> first, state = iterate(a)\n(1, 2)\n\njulia> first, Base.rest(a, state)\n(1, [3, 2, 4])\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.split_rest","page":"Collections and Data Structures","title":"Base.split_rest","text":"Base.split_rest(collection, n::Int[, itr_state]) -> (rest_but_n, last_n)\n\nGeneric function for splitting the tail of collection, starting from a specific iteration state itr_state. Returns a tuple of two new collections. The first one contains all elements of the tail but the n last ones, which make up the second collection.\n\nThe type of the first collection generally follows that of Base.rest, except that the fallback case is not lazy, but is collected eagerly into a vector.\n\nCan be overloaded for user-defined collection types to customize the behavior of slurping in assignments in non-final position, like a, b..., c = collection.\n\ncompat: Julia 1.9\nBase.split_rest requires at least Julia 1.9.\n\nSee also: Base.rest.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> first, state = iterate(a)\n(1, 2)\n\njulia> first, Base.split_rest(a, 1, state)\n(1, ([3, 2], [4]))\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Indexable-Collections","page":"Collections and Data Structures","title":"Indexable Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.getindex\nBase.setindex!\nBase.firstindex\nBase.lastindex","category":"page"},{"location":"base/collections/#Base.getindex","page":"Collections and Data Structures","title":"Base.getindex","text":"getindex(collection, key...)\n\nRetrieve the value(s) stored at the given key or index within a collection. The syntax a[i,j,...] is converted by the compiler to getindex(a, i, j, ...).\n\nSee also get, keys, eachindex.\n\nExamples\n\njulia> A = Dict(\"a\" => 1, \"b\" => 2)\nDict{String, Int64} with 2 entries:\n \"b\" => 2\n \"a\" => 1\n\njulia> getindex(A, \"a\")\n1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.setindex!","page":"Collections and Data Structures","title":"Base.setindex!","text":"setindex!(collection, value, key...)\n\nStore the given value at the given key or index within a collection. The syntax a[i,j,...] = x is converted by the compiler to (setindex!(a, x, i, j, ...); x).\n\nExamples\n\njulia> a = Dict(\"a\"=>1)\nDict{String, Int64} with 1 entry:\n \"a\" => 1\n\njulia> setindex!(a, 2, \"b\")\nDict{String, Int64} with 2 entries:\n \"b\" => 2\n \"a\" => 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.firstindex","page":"Collections and Data Structures","title":"Base.firstindex","text":"firstindex(collection) -> Integer\nfirstindex(collection, d) -> Integer\n\nReturn the first index of collection. If d is given, return the first index of collection along dimension d.\n\nThe syntaxes A[begin] and A[1, begin] lower to A[firstindex(A)] and A[1, firstindex(A, 2)], respectively.\n\nSee also: first, axes, lastindex, nextind.\n\nExamples\n\njulia> firstindex([1,2,4])\n1\n\njulia> firstindex(rand(3,4,5), 2)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.lastindex","page":"Collections and Data Structures","title":"Base.lastindex","text":"lastindex(collection) -> Integer\nlastindex(collection, d) -> Integer\n\nReturn the last index of collection. If d is given, return the last index of collection along dimension d.\n\nThe syntaxes A[end] and A[end, end] lower to A[lastindex(A)] and A[lastindex(A, 1), lastindex(A, 2)], respectively.\n\nSee also: axes, firstindex, eachindex, prevind.\n\nExamples\n\njulia> lastindex([1,2,4])\n3\n\njulia> lastindex(rand(3,4,5), 2)\n4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Array\nBitArray\nAbstractArray\nSubArray","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Partially implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"AbstractRange\nUnitRange\nTuple\nAbstractString\nDict\nIdDict\nWeakKeyDict\nNamedTuple","category":"page"},{"location":"base/collections/#Dictionaries","page":"Collections and Data Structures","title":"Dictionaries","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Dict is the standard dictionary. Its implementation uses hash as the hashing function for the key, and isequal to determine equality. Define these two functions for custom types to override how they are stored in a hash table.","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"IdDict is a special hash table where the keys are always object identities.","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"WeakKeyDict is a hash table implementation where the keys are weak references to objects, and thus may be garbage collected even when referenced in a hash table. Like Dict it uses hash for hashing and isequal for equality, unlike Dict it does not convert keys on insertion.","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Dicts can be created by passing pair objects constructed with => to a Dict constructor: Dict(\"A\"=>1, \"B\"=>2). This call will attempt to infer type information from the keys and values (i.e. this example creates a Dict{String, Int64}). To explicitly specify types use the syntax Dict{KeyType,ValueType}(...). For example, Dict{String,Int32}(\"A\"=>1, \"B\"=>2).","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Dictionaries may also be created with generators. For example, Dict(i => f(i) for i = 1:10).","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Given a dictionary D, the syntax D[x] returns the value of key x (if it exists) or throws an error, and D[x] = y stores the key-value pair x => y in D (replacing any existing value for the key x). Multiple arguments to D[...] are converted to tuples; for example, the syntax D[x,y] is equivalent to D[(x,y)], i.e. it refers to the value keyed by the tuple (x,y).","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.AbstractDict\nBase.Dict\nBase.IdDict\nBase.WeakKeyDict\nBase.ImmutableDict\nBase.PersistentDict\nBase.haskey\nBase.get\nBase.get!\nBase.getkey\nBase.delete!\nBase.pop!(::Any, ::Any, ::Any)\nBase.keys\nBase.values\nBase.pairs\nBase.merge\nBase.mergewith\nBase.merge!\nBase.mergewith!\nBase.sizehint!\nBase.keytype\nBase.valtype","category":"page"},{"location":"base/collections/#Base.AbstractDict","page":"Collections and Data Structures","title":"Base.AbstractDict","text":"AbstractDict{K, V}\n\nSupertype for dictionary-like types with keys of type K and values of type V. Dict, IdDict and other types are subtypes of this. An AbstractDict{K, V} should be an iterator of Pair{K, V}.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.Dict","page":"Collections and Data Structures","title":"Base.Dict","text":"Dict([itr])\n\nDict{K,V}() constructs a hash table with keys of type K and values of type V. Keys are compared with isequal and hashed with hash.\n\nGiven a single iterable argument, constructs a Dict whose key-value pairs are taken from 2-tuples (key,value) generated by the argument.\n\nExamples\n\njulia> Dict([(\"A\", 1), (\"B\", 2)])\nDict{String, Int64} with 2 entries:\n \"B\" => 2\n \"A\" => 1\n\nAlternatively, a sequence of pair arguments may be passed.\n\njulia> Dict(\"A\"=>1, \"B\"=>2)\nDict{String, Int64} with 2 entries:\n \"B\" => 2\n \"A\" => 1\n\nwarning: Warning\nKeys are allowed to be mutable, but if you do mutate stored keys, the hash table may become internally inconsistent, in which case the Dict will not work properly. IdDict can be an alternative if you need to mutate keys.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.IdDict","page":"Collections and Data Structures","title":"Base.IdDict","text":"IdDict([itr])\n\nIdDict{K,V}() constructs a hash table using objectid as hash and === as equality with keys of type K and values of type V. See Dict for further help and IdSet for the set version of this.\n\nIn the example below, the Dict keys are all isequal and therefore get hashed the same, so they get overwritten. The IdDict hashes by object-id, and thus preserves the 3 different keys.\n\nExamples\n\njulia> Dict(true => \"yes\", 1 => \"no\", 1.0 => \"maybe\")\nDict{Real, String} with 1 entry:\n 1.0 => \"maybe\"\n\njulia> IdDict(true => \"yes\", 1 => \"no\", 1.0 => \"maybe\")\nIdDict{Any, String} with 3 entries:\n true => \"yes\"\n 1.0 => \"maybe\"\n 1 => \"no\"\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.WeakKeyDict","page":"Collections and Data Structures","title":"Base.WeakKeyDict","text":"WeakKeyDict([itr])\n\nWeakKeyDict() constructs a hash table where the keys are weak references to objects which may be garbage collected even when referenced in a hash table.\n\nSee Dict for further help. Note, unlike Dict, WeakKeyDict does not convert keys on insertion, as this would imply the key object was unreferenced anywhere before insertion.\n\nSee also WeakRef.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.ImmutableDict","page":"Collections and Data Structures","title":"Base.ImmutableDict","text":"ImmutableDict\n\nImmutableDict is a dictionary implemented as an immutable linked list, which is optimal for small dictionaries that are constructed over many individual insertions. Note that it is not possible to remove a value, although it can be partially overridden and hidden by inserting a new value with the same key.\n\nImmutableDict(KV::Pair)\n\nCreate a new entry in the ImmutableDict for a key => value pair\n\nuse (key => value) in dict to see if this particular combination is in the properties set\nuse get(dict, key, default) to retrieve the most recent value for a particular key\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.PersistentDict","page":"Collections and Data Structures","title":"Base.PersistentDict","text":"PersistentDict\n\nPersistentDict is a dictionary implemented as an hash array mapped trie, which is optimal for situations where you need persistence, each operation returns a new dictionary separate from the previous one, but the underlying implementation is space-efficient and may share storage across multiple separate dictionaries.\n\nnote: Note\nIt behaves like an IdDict.\n\nPersistentDict(KV::Pair)\n\nExamples\n\njulia> dict = Base.PersistentDict(:a=>1)\nBase.PersistentDict{Symbol, Int64} with 1 entry:\n :a => 1\n\njulia> dict2 = Base.delete(dict, :a)\nBase.PersistentDict{Symbol, Int64}()\n\njulia> dict3 = Base.PersistentDict(dict, :a=>2)\nBase.PersistentDict{Symbol, Int64} with 1 entry:\n :a => 2\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.haskey","page":"Collections and Data Structures","title":"Base.haskey","text":"haskey(collection, key) -> Bool\n\nDetermine whether a collection has a mapping for a given key.\n\nExamples\n\njulia> D = Dict('a'=>2, 'b'=>3)\nDict{Char, Int64} with 2 entries:\n 'a' => 2\n 'b' => 3\n\njulia> haskey(D, 'a')\ntrue\n\njulia> haskey(D, 'c')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.get","page":"Collections and Data Structures","title":"Base.get","text":"get(collection, key, default)\n\nReturn the value stored for the given key, or the given default value if no mapping for the key is present.\n\ncompat: Julia 1.7\nFor tuples and numbers, this function requires at least Julia 1.7.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2);\n\njulia> get(d, \"a\", 3)\n1\n\njulia> get(d, \"c\", 3)\n3\n\n\n\n\n\nget(f::Union{Function, Type}, collection, key)\n\nReturn the value stored for the given key, or if no mapping for the key is present, return f(). Use get! to also store the default value in the dictionary.\n\nThis is intended to be called using do block syntax\n\nget(dict, key) do\n # default value calculated here\n time()\nend\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.get!","page":"Collections and Data Structures","title":"Base.get!","text":"get!(collection, key, default)\n\nReturn the value stored for the given key, or if no mapping for the key is present, store key => default, and return default.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2, \"c\"=>3);\n\njulia> get!(d, \"a\", 5)\n1\n\njulia> get!(d, \"d\", 4)\n4\n\njulia> d\nDict{String, Int64} with 4 entries:\n \"c\" => 3\n \"b\" => 2\n \"a\" => 1\n \"d\" => 4\n\n\n\n\n\nget!(f::Union{Function, Type}, collection, key)\n\nReturn the value stored for the given key, or if no mapping for the key is present, store key => f(), and return f().\n\nThis is intended to be called using do block syntax.\n\nExamples\n\njulia> squares = Dict{Int, Int}();\n\njulia> function get_square!(d, i)\n get!(d, i) do\n i^2\n end\n end\nget_square! (generic function with 1 method)\n\njulia> get_square!(squares, 2)\n4\n\njulia> squares\nDict{Int64, Int64} with 1 entry:\n 2 => 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.getkey","page":"Collections and Data Structures","title":"Base.getkey","text":"getkey(collection, key, default)\n\nReturn the key matching argument key if one exists in collection, otherwise return default.\n\nExamples\n\njulia> D = Dict('a'=>2, 'b'=>3)\nDict{Char, Int64} with 2 entries:\n 'a' => 2\n 'b' => 3\n\njulia> getkey(D, 'a', 1)\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> getkey(D, 'd', 'a')\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.delete!","page":"Collections and Data Structures","title":"Base.delete!","text":"delete!(collection, key)\n\nDelete the mapping for the given key in a collection, if any, and return the collection.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2)\nDict{String, Int64} with 2 entries:\n \"b\" => 2\n \"a\" => 1\n\njulia> delete!(d, \"b\")\nDict{String, Int64} with 1 entry:\n \"a\" => 1\n\njulia> delete!(d, \"b\") # d is left unchanged\nDict{String, Int64} with 1 entry:\n \"a\" => 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.pop!-Tuple{Any, Any, Any}","page":"Collections and Data Structures","title":"Base.pop!","text":"pop!(collection, key[, default])\n\nDelete and return the mapping for key if it exists in collection, otherwise return default, or throw an error if default is not specified.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2, \"c\"=>3);\n\njulia> pop!(d, \"a\")\n1\n\njulia> pop!(d, \"d\")\nERROR: KeyError: key \"d\" not found\nStacktrace:\n[...]\n\njulia> pop!(d, \"e\", 4)\n4\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.keys","page":"Collections and Data Structures","title":"Base.keys","text":"keys(iterator)\n\nFor an iterator or collection that has keys and values (e.g. arrays and dictionaries), return an iterator over the keys.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.values","page":"Collections and Data Structures","title":"Base.values","text":"values(iterator)\n\nFor an iterator or collection that has keys and values, return an iterator over the values. This function simply returns its argument by default, since the elements of a general iterator are normally considered its \"values\".\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2);\n\njulia> values(d)\nValueIterator for a Dict{String, Int64} with 2 entries. Values:\n 2\n 1\n\njulia> values([2])\n1-element Vector{Int64}:\n 2\n\n\n\n\n\nvalues(a::AbstractDict)\n\nReturn an iterator over all values in a collection. collect(values(a)) returns an array of values. When the values are stored internally in a hash table, as is the case for Dict, the order in which they are returned may vary. But keys(a) and values(a) both iterate a and return the elements in the same order.\n\nExamples\n\njulia> D = Dict('a'=>2, 'b'=>3)\nDict{Char, Int64} with 2 entries:\n 'a' => 2\n 'b' => 3\n\njulia> collect(values(D))\n2-element Vector{Int64}:\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.pairs","page":"Collections and Data Structures","title":"Base.pairs","text":"pairs(IndexLinear(), A)\npairs(IndexCartesian(), A)\npairs(IndexStyle(A), A)\n\nAn iterator that accesses each element of the array A, returning i => x, where i is the index for the element and x = A[i]. Identical to pairs(A), except that the style of index can be selected. Also similar to enumerate(A), except i will be a valid index for A, while enumerate always counts from 1 regardless of the indices of A.\n\nSpecifying IndexLinear() ensures that i will be an integer; specifying IndexCartesian() ensures that i will be a Base.CartesianIndex; specifying IndexStyle(A) chooses whichever has been defined as the native indexing style for array A.\n\nMutation of the bounds of the underlying array will invalidate this iterator.\n\nExamples\n\njulia> A = [\"a\" \"d\"; \"b\" \"e\"; \"c\" \"f\"];\n\njulia> for (index, value) in pairs(IndexStyle(A), A)\n println(\"$index $value\")\n end\n1 a\n2 b\n3 c\n4 d\n5 e\n6 f\n\njulia> S = view(A, 1:2, :);\n\njulia> for (index, value) in pairs(IndexStyle(S), S)\n println(\"$index $value\")\n end\nCartesianIndex(1, 1) a\nCartesianIndex(2, 1) b\nCartesianIndex(1, 2) d\nCartesianIndex(2, 2) e\n\nSee also IndexStyle, axes.\n\n\n\n\n\npairs(collection)\n\nReturn an iterator over key => value pairs for any collection that maps a set of keys to a set of values. This includes arrays, where the keys are the array indices.\n\nExamples\n\njulia> a = Dict(zip([\"a\", \"b\", \"c\"], [1, 2, 3]))\nDict{String, Int64} with 3 entries:\n \"c\" => 3\n \"b\" => 2\n \"a\" => 1\n\njulia> pairs(a)\nDict{String, Int64} with 3 entries:\n \"c\" => 3\n \"b\" => 2\n \"a\" => 1\n\njulia> foreach(println, pairs([\"a\", \"b\", \"c\"]))\n1 => \"a\"\n2 => \"b\"\n3 => \"c\"\n\njulia> (;a=1, b=2, c=3) |> pairs |> collect\n3-element Vector{Pair{Symbol, Int64}}:\n :a => 1\n :b => 2\n :c => 3\n\njulia> (;a=1, b=2, c=3) |> collect\n3-element Vector{Int64}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.merge","page":"Collections and Data Structures","title":"Base.merge","text":"merge(initial::Face, others::Face...)\n\nMerge the properties of the initial face and others, with later faces taking priority.\n\n\n\n\n\nmerge(d::AbstractDict, others::AbstractDict...)\n\nConstruct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of the merged collections. If the same key is present in another collection, the value for that key will be the value it has in the last collection listed. See also mergewith for custom handling of values with the same key.\n\nExamples\n\njulia> a = Dict(\"foo\" => 0.0, \"bar\" => 42.0)\nDict{String, Float64} with 2 entries:\n \"bar\" => 42.0\n \"foo\" => 0.0\n\njulia> b = Dict(\"baz\" => 17, \"bar\" => 4711)\nDict{String, Int64} with 2 entries:\n \"bar\" => 4711\n \"baz\" => 17\n\njulia> merge(a, b)\nDict{String, Float64} with 3 entries:\n \"bar\" => 4711.0\n \"baz\" => 17.0\n \"foo\" => 0.0\n\njulia> merge(b, a)\nDict{String, Float64} with 3 entries:\n \"bar\" => 42.0\n \"baz\" => 17.0\n \"foo\" => 0.0\n\n\n\n\n\nmerge(a::NamedTuple, bs::NamedTuple...)\n\nConstruct a new named tuple by merging two or more existing ones, in a left-associative manner. Merging proceeds left-to-right, between pairs of named tuples, and so the order of fields present in both the leftmost and rightmost named tuples take the same position as they are found in the leftmost named tuple. However, values are taken from matching fields in the rightmost named tuple that contains that field. Fields present in only the rightmost named tuple of a pair are appended at the end. A fallback is implemented for when only a single named tuple is supplied, with signature merge(a::NamedTuple).\n\ncompat: Julia 1.1\nMerging 3 or more NamedTuple requires at least Julia 1.1.\n\nExamples\n\njulia> merge((a=1, b=2, c=3), (b=4, d=5))\n(a = 1, b = 4, c = 3, d = 5)\n\njulia> merge((a=1, b=2), (b=3, c=(d=1,)), (c=(d=2,),))\n(a = 1, b = 3, c = (d = 2,))\n\n\n\n\n\nmerge(a::NamedTuple, iterable)\n\nInterpret an iterable of key-value pairs as a named tuple, and perform a merge.\n\njulia> merge((a=1, b=2, c=3), [:b=>4, :d=>5])\n(a = 1, b = 4, c = 3, d = 5)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.mergewith","page":"Collections and Data Structures","title":"Base.mergewith","text":"mergewith(combine, d::AbstractDict, others::AbstractDict...)\nmergewith(combine)\nmerge(combine, d::AbstractDict, others::AbstractDict...)\n\nConstruct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of the merged collections. Values with the same key will be combined using the combiner function. The curried form mergewith(combine) returns the function (args...) -> mergewith(combine, args...).\n\nMethod merge(combine::Union{Function,Type}, args...) as an alias of mergewith(combine, args...) is still available for backward compatibility.\n\ncompat: Julia 1.5\nmergewith requires Julia 1.5 or later.\n\nExamples\n\njulia> a = Dict(\"foo\" => 0.0, \"bar\" => 42.0)\nDict{String, Float64} with 2 entries:\n \"bar\" => 42.0\n \"foo\" => 0.0\n\njulia> b = Dict(\"baz\" => 17, \"bar\" => 4711)\nDict{String, Int64} with 2 entries:\n \"bar\" => 4711\n \"baz\" => 17\n\njulia> mergewith(+, a, b)\nDict{String, Float64} with 3 entries:\n \"bar\" => 4753.0\n \"baz\" => 17.0\n \"foo\" => 0.0\n\njulia> ans == mergewith(+)(a, b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.merge!","page":"Collections and Data Structures","title":"Base.merge!","text":"merge!(d::AbstractDict, others::AbstractDict...)\n\nUpdate collection with pairs from the other collections. See also merge.\n\nExamples\n\njulia> d1 = Dict(1 => 2, 3 => 4);\n\njulia> d2 = Dict(1 => 4, 4 => 5);\n\njulia> merge!(d1, d2);\n\njulia> d1\nDict{Int64, Int64} with 3 entries:\n 4 => 5\n 3 => 4\n 1 => 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.mergewith!","page":"Collections and Data Structures","title":"Base.mergewith!","text":"mergewith!(combine, d::AbstractDict, others::AbstractDict...) -> d\nmergewith!(combine)\nmerge!(combine, d::AbstractDict, others::AbstractDict...) -> d\n\nUpdate collection with pairs from the other collections. Values with the same key will be combined using the combiner function. The curried form mergewith!(combine) returns the function (args...) -> mergewith!(combine, args...).\n\nMethod merge!(combine::Union{Function,Type}, args...) as an alias of mergewith!(combine, args...) is still available for backward compatibility.\n\ncompat: Julia 1.5\nmergewith! requires Julia 1.5 or later.\n\nExamples\n\njulia> d1 = Dict(1 => 2, 3 => 4);\n\njulia> d2 = Dict(1 => 4, 4 => 5);\n\njulia> mergewith!(+, d1, d2);\n\njulia> d1\nDict{Int64, Int64} with 3 entries:\n 4 => 5\n 3 => 4\n 1 => 6\n\njulia> mergewith!(-, d1, d1);\n\njulia> d1\nDict{Int64, Int64} with 3 entries:\n 4 => 0\n 3 => 0\n 1 => 0\n\njulia> foldl(mergewith!(+), [d1, d2]; init=Dict{Int64, Int64}())\nDict{Int64, Int64} with 3 entries:\n 4 => 5\n 3 => 0\n 1 => 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.sizehint!","page":"Collections and Data Structures","title":"Base.sizehint!","text":"sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s\n\nSuggest that collection s reserve capacity for at least n elements. That is, if you expect that you're going to have to push a lot of values onto s, you can avoid the cost of incremental reallocation by doing it once up front; this can improve performance.\n\nIf first is true, then any additional space is reserved before the start of the collection. This way, subsequent calls to pushfirst! (instead of push!) may become faster. Supplying this keyword may result in an error if the collection is not ordered or if pushfirst! is not supported for this collection.\n\nIf shrink=true (the default), the collection's capacity may be reduced if its current capacity is greater than n.\n\nSee also resize!.\n\nNotes on the performance model\n\nFor types that support sizehint!,\n\npush! and append! methods generally may (but are not required to) preallocate extra storage. For types implemented in Base, they typically do, using a heuristic optimized for a general use case.\nsizehint! may control this preallocation. Again, it typically does this for types in Base.\nempty! is nearly costless (and O(1)) for types that support this kind of preallocation.\n\ncompat: Julia 1.11\nThe shrink and first arguments were added in Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.keytype","page":"Collections and Data Structures","title":"Base.keytype","text":"keytype(T::Type{<:AbstractArray})\nkeytype(A::AbstractArray)\n\nReturn the key type of an array. This is equal to the eltype of the result of keys(...), and is provided mainly for compatibility with the dictionary interface.\n\nExamples\n\njulia> keytype([1, 2, 3]) == Int\ntrue\n\njulia> keytype([1 2; 3 4])\nCartesianIndex{2}\n\ncompat: Julia 1.2\nFor arrays, this function requires at least Julia 1.2.\n\n\n\n\n\nkeytype(type)\n\nGet the key type of a dictionary type. Behaves similarly to eltype.\n\nExamples\n\njulia> keytype(Dict(Int32(1) => \"foo\"))\nInt32\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.valtype","page":"Collections and Data Structures","title":"Base.valtype","text":"valtype(T::Type{<:AbstractArray})\nvaltype(A::AbstractArray)\n\nReturn the value type of an array. This is identical to eltype and is provided mainly for compatibility with the dictionary interface.\n\nExamples\n\njulia> valtype([\"one\", \"two\", \"three\"])\nString\n\ncompat: Julia 1.2\nFor arrays, this function requires at least Julia 1.2.\n\n\n\n\n\nvaltype(type)\n\nGet the value type of a dictionary type. Behaves similarly to eltype.\n\nExamples\n\njulia> valtype(Dict(Int32(1) => \"foo\"))\nString\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Dict\nIdDict\nWeakKeyDict","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Partially implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Set\nBitSet\nIdSet\nEnvDict\nArray\nBitArray\nImmutableDict\nPersistentDict\nIterators.Pairs","category":"page"},{"location":"base/collections/#Set-Like-Collections","page":"Collections and Data Structures","title":"Set-Like Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.AbstractSet\nBase.Set\nBase.BitSet\nBase.IdSet\nBase.union\nBase.union!\nBase.intersect\nBase.setdiff\nBase.setdiff!\nBase.symdiff\nBase.symdiff!\nBase.intersect!\nBase.issubset\nBase.in!\nBase.:⊈\nBase.:⊊\nBase.issetequal\nBase.isdisjoint","category":"page"},{"location":"base/collections/#Base.AbstractSet","page":"Collections and Data Structures","title":"Base.AbstractSet","text":"AbstractSet{T}\n\nSupertype for set-like types whose elements are of type T. Set, BitSet and other types are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.Set","page":"Collections and Data Structures","title":"Base.Set","text":"Set{T} <: AbstractSet{T}\n\nSets are mutable containers that provide fast membership testing.\n\nSets have efficient implementations of set operations such as in, union and intersect. Elements in a Set are unique, as determined by the elements' definition of isequal. The order of elements in a Set is an implementation detail and cannot be relied on.\n\nSee also: AbstractSet, BitSet, Dict, push!, empty!, union!, in, isequal\n\nExamples\n\njulia> s = Set(\"aaBca\")\nSet{Char} with 3 elements:\n 'a'\n 'c'\n 'B'\n\njulia> push!(s, 'b')\nSet{Char} with 4 elements:\n 'a'\n 'b'\n 'B'\n 'c'\n\njulia> s = Set([NaN, 0.0, 1.0, 2.0]);\n\njulia> -0.0 in s # isequal(0.0, -0.0) is false\nfalse\n\njulia> NaN in s # isequal(NaN, NaN) is true\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.BitSet","page":"Collections and Data Structures","title":"Base.BitSet","text":"BitSet([itr])\n\nConstruct a sorted set of Ints generated by the given iterable object, or an empty set. Implemented as a bit string, and therefore designed for dense integer sets. If the set will be sparse (for example, holding a few very large integers), use Set instead.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.IdSet","page":"Collections and Data Structures","title":"Base.IdSet","text":"IdSet{T}([itr])\nIdSet()\n\nIdSet{T}() constructs a set (see Set) using === as equality with values of type V.\n\nIn the example below, the values are all isequal so they get overwritten. The IdSet compares by === so preserves the 3 different keys.\n\nExamples ≡≡≡≡≡≡≡≡\n\njulia> Set(Any[true, 1, 1.0]) Set{Any} with 1 element: 1.0\n\njulia> IdSet{Any}(Any[true, 1, 1.0]) IdSet{Any} with 3 elements: 1.0 1 true\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.union","page":"Collections and Data Structures","title":"Base.union","text":"union(s, itrs...)\n∪(s, itrs...)\n\nConstruct an object containing all distinct elements from all of the arguments.\n\nThe first argument controls what kind of container is returned. If this is an array, it maintains the order in which elements first appear.\n\nUnicode ∪ can be typed by writing \\cup then pressing tab in the Julia REPL, and in many editors. This is an infix operator, allowing s ∪ itr.\n\nSee also unique, intersect, isdisjoint, vcat, Iterators.flatten.\n\nExamples\n\njulia> union([1, 2], [3])\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> union([4 2 3 4 4], 1:3, 3.0)\n4-element Vector{Float64}:\n 4.0\n 2.0\n 3.0\n 1.0\n\njulia> (0, 0.0) ∪ (-0.0, NaN)\n3-element Vector{Real}:\n 0\n -0.0\n NaN\n\njulia> union(Set([1, 2]), 2:3)\nSet{Int64} with 3 elements:\n 2\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.union!","page":"Collections and Data Structures","title":"Base.union!","text":"union!(s::Union{AbstractSet,AbstractVector}, itrs...)\n\nConstruct the union of passed in sets and overwrite s with the result. Maintain order with arrays.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> a = Set([3, 4, 5]);\n\njulia> union!(a, 1:2:7);\n\njulia> a\nSet{Int64} with 5 elements:\n 5\n 4\n 7\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.intersect","page":"Collections and Data Structures","title":"Base.intersect","text":"intersect(s, itrs...)\n∩(s, itrs...)\n\nConstruct the set containing those elements which appear in all of the arguments.\n\nThe first argument controls what kind of container is returned. If this is an array, it maintains the order in which elements first appear.\n\nUnicode ∩ can be typed by writing \\cap then pressing tab in the Julia REPL, and in many editors. This is an infix operator, allowing s ∩ itr.\n\nSee also setdiff, isdisjoint, issubset, issetequal.\n\ncompat: Julia 1.8\nAs of Julia 1.8 intersect returns a result with the eltype of the type-promoted eltypes of the two inputs\n\nExamples\n\njulia> intersect([1, 2, 3], [3, 4, 5])\n1-element Vector{Int64}:\n 3\n\njulia> intersect([1, 4, 4, 5, 6], [6, 4, 6, 7, 8])\n2-element Vector{Int64}:\n 4\n 6\n\njulia> intersect(1:16, 7:99)\n7:16\n\njulia> (0, 0.0) ∩ (-0.0, 0)\n1-element Vector{Real}:\n 0\n\njulia> intersect(Set([1, 2]), BitSet([2, 3]), 1.0:10.0)\nSet{Float64} with 1 element:\n 2.0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.setdiff","page":"Collections and Data Structures","title":"Base.setdiff","text":"setdiff(s, itrs...)\n\nConstruct the set of elements in s but not in any of the iterables in itrs. Maintain order with arrays.\n\nSee also setdiff!, union and intersect.\n\nExamples\n\njulia> setdiff([1,2,3], [3,4,5])\n2-element Vector{Int64}:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.setdiff!","page":"Collections and Data Structures","title":"Base.setdiff!","text":"setdiff!(s, itrs...)\n\nRemove from set s (in-place) each element of each iterable from itrs. Maintain order with arrays.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> a = Set([1, 3, 4, 5]);\n\njulia> setdiff!(a, 1:2:6);\n\njulia> a\nSet{Int64} with 1 element:\n 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.symdiff","page":"Collections and Data Structures","title":"Base.symdiff","text":"symdiff(s, itrs...)\n\nConstruct the symmetric difference of elements in the passed in sets. When s is not an AbstractSet, the order is maintained.\n\nSee also symdiff!, setdiff, union and intersect.\n\nExamples\n\njulia> symdiff([1,2,3], [3,4,5], [4,5,6])\n3-element Vector{Int64}:\n 1\n 2\n 6\n\njulia> symdiff([1,2,1], [2, 1, 2])\nInt64[]\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.symdiff!","page":"Collections and Data Structures","title":"Base.symdiff!","text":"symdiff!(s::Union{AbstractSet,AbstractVector}, itrs...)\n\nConstruct the symmetric difference of the passed in sets, and overwrite s with the result. When s is an array, the order is maintained. Note that in this case the multiplicity of elements matters.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.intersect!","page":"Collections and Data Structures","title":"Base.intersect!","text":"intersect!(s::Union{AbstractSet,AbstractVector}, itrs...)\n\nIntersect all passed in sets and overwrite s with the result. Maintain order with arrays.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.issubset","page":"Collections and Data Structures","title":"Base.issubset","text":"issubset(a, b) -> Bool\n⊆(a, b) -> Bool\n⊇(b, a) -> Bool\n\nDetermine whether every element of a is also in b, using in.\n\nSee also ⊊, ⊈, ∩, ∪, contains.\n\nExamples\n\njulia> issubset([1, 2], [1, 2, 3])\ntrue\n\njulia> [1, 2, 3] ⊆ [1, 2]\nfalse\n\njulia> [1, 2, 3] ⊇ [1, 2]\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.in!","page":"Collections and Data Structures","title":"Base.in!","text":"in!(x, s::AbstractSet) -> Bool\n\nIf x is in s, return true. If not, push x into s and return false. This is equivalent to in(x, s) ? true : (push!(s, x); false), but may have a more efficient implementation.\n\nSee also: in, push!, Set\n\ncompat: Julia 1.11\nThis function requires at least 1.11.\n\nExamples\n\njulia> s = Set{Any}([1, 2, 3]); in!(4, s)\nfalse\n\njulia> length(s)\n4\n\njulia> in!(0x04, s)\ntrue\n\njulia> s\nSet{Any} with 4 elements:\n 4\n 2\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.:⊈","page":"Collections and Data Structures","title":"Base.:⊈","text":"⊈(a, b) -> Bool\n⊉(b, a) -> Bool\n\nNegation of ⊆ and ⊇, i.e. checks that a is not a subset of b.\n\nSee also issubset (⊆), ⊊.\n\nExamples\n\njulia> (1, 2) ⊈ (2, 3)\ntrue\n\njulia> (1, 2) ⊈ (1, 2, 3)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.:⊊","page":"Collections and Data Structures","title":"Base.:⊊","text":"⊊(a, b) -> Bool\n⊋(b, a) -> Bool\n\nDetermines if a is a subset of, but not equal to, b.\n\nSee also issubset (⊆), ⊈.\n\nExamples\n\njulia> (1, 2) ⊊ (1, 2, 3)\ntrue\n\njulia> (1, 2) ⊊ (1, 2)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.issetequal","page":"Collections and Data Structures","title":"Base.issetequal","text":"issetequal(a, b) -> Bool\n\nDetermine whether a and b have the same elements. Equivalent to a ⊆ b && b ⊆ a but more efficient when possible.\n\nSee also: isdisjoint, union.\n\nExamples\n\njulia> issetequal([1, 2], [1, 2, 3])\nfalse\n\njulia> issetequal([1, 2], [2, 1])\ntrue\n\n\n\n\n\nissetequal(x)\n\nCreate a function that compares its argument to x using issetequal, i.e. a function equivalent to y -> issetequal(y, x). The returned function is of type Base.Fix2{typeof(issetequal)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.11\nThis functionality requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.isdisjoint","page":"Collections and Data Structures","title":"Base.isdisjoint","text":"isdisjoint(a, b) -> Bool\n\nDetermine whether the collections a and b are disjoint. Equivalent to isempty(a ∩ b) but more efficient when possible.\n\nSee also: intersect, isempty, issetequal.\n\ncompat: Julia 1.5\nThis function requires at least Julia 1.5.\n\nExamples\n\njulia> isdisjoint([1, 2], [2, 3, 4])\nfalse\n\njulia> isdisjoint([3, 1], [2, 4])\ntrue\n\n\n\n\n\nisdisjoint(x)\n\nCreate a function that compares its argument to x using isdisjoint, i.e. a function equivalent to y -> isdisjoint(y, x). The returned function is of type Base.Fix2{typeof(isdisjoint)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.11\nThis functionality requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Set\nBitSet\nIdSet","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Partially implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Array","category":"page"},{"location":"base/collections/#Dequeues","page":"Collections and Data Structures","title":"Dequeues","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.push!\nBase.pop!\nBase.popat!\nBase.pushfirst!\nBase.popfirst!\nBase.insert!\nBase.deleteat!\nBase.keepat!\nBase.splice!\nBase.resize!\nBase.append!\nBase.prepend!","category":"page"},{"location":"base/collections/#Base.push!","page":"Collections and Data Structures","title":"Base.push!","text":"push!(collection, items...) -> collection\n\nInsert one or more items in collection. If collection is an ordered container, the items are inserted at the end (in the given order).\n\nExamples\n\njulia> push!([1, 2, 3], 4, 5, 6)\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\nIf collection is ordered, use append! to add all the elements of another collection to it. The result of the preceding example is equivalent to append!([1, 2, 3], [4, 5, 6]). For AbstractSet objects, union! can be used instead.\n\nSee sizehint! for notes about the performance model.\n\nSee also pushfirst!.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.pop!","page":"Collections and Data Structures","title":"Base.pop!","text":"pop!(collection) -> item\n\nRemove an item in collection and return it. If collection is an ordered container, the last item is returned; for unordered containers, an arbitrary element is returned.\n\nSee also: popfirst!, popat!, delete!, deleteat!, splice!, and push!.\n\nExamples\n\njulia> A=[1, 2, 3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> pop!(A)\n3\n\njulia> A\n2-element Vector{Int64}:\n 1\n 2\n\njulia> S = Set([1, 2])\nSet{Int64} with 2 elements:\n 2\n 1\n\njulia> pop!(S)\n2\n\njulia> S\nSet{Int64} with 1 element:\n 1\n\njulia> pop!(Dict(1=>2))\n1 => 2\n\n\n\n\n\npop!(collection, key[, default])\n\nDelete and return the mapping for key if it exists in collection, otherwise return default, or throw an error if default is not specified.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2, \"c\"=>3);\n\njulia> pop!(d, \"a\")\n1\n\njulia> pop!(d, \"d\")\nERROR: KeyError: key \"d\" not found\nStacktrace:\n[...]\n\njulia> pop!(d, \"e\", 4)\n4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.popat!","page":"Collections and Data Structures","title":"Base.popat!","text":"popat!(a::Vector, i::Integer, [default])\n\nRemove the item at the given i and return it. Subsequent items are shifted to fill the resulting gap. When i is not a valid index for a, return default, or throw an error if default is not specified.\n\nSee also: pop!, popfirst!, deleteat!, splice!.\n\ncompat: Julia 1.5\nThis function is available as of Julia 1.5.\n\nExamples\n\njulia> a = [4, 3, 2, 1]; popat!(a, 2)\n3\n\njulia> a\n3-element Vector{Int64}:\n 4\n 2\n 1\n\njulia> popat!(a, 4, missing)\nmissing\n\njulia> popat!(a, 4)\nERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.pushfirst!","page":"Collections and Data Structures","title":"Base.pushfirst!","text":"pushfirst!(collection, items...) -> collection\n\nInsert one or more items at the beginning of collection.\n\nThis function is called unshift in many other programming languages.\n\nExamples\n\njulia> pushfirst!([1, 2, 3, 4], 5, 6)\n6-element Vector{Int64}:\n 5\n 6\n 1\n 2\n 3\n 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.popfirst!","page":"Collections and Data Structures","title":"Base.popfirst!","text":"popfirst!(collection) -> item\n\nRemove the first item from collection.\n\nThis function is called shift in many other programming languages.\n\nSee also: pop!, popat!, delete!.\n\nExamples\n\njulia> A = [1, 2, 3, 4, 5, 6]\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\njulia> popfirst!(A)\n1\n\njulia> A\n5-element Vector{Int64}:\n 2\n 3\n 4\n 5\n 6\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.insert!","page":"Collections and Data Structures","title":"Base.insert!","text":"insert!(a::Vector, index::Integer, item)\n\nInsert an item into a at the given index. index is the index of item in the resulting a.\n\nSee also: push!, replace, popat!, splice!.\n\nExamples\n\njulia> insert!(Any[1:6;], 3, \"here\")\n7-element Vector{Any}:\n 1\n 2\n \"here\"\n 3\n 4\n 5\n 6\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.deleteat!","page":"Collections and Data Structures","title":"Base.deleteat!","text":"deleteat!(a::Vector, i::Integer)\n\nRemove the item at the given i and return the modified a. Subsequent items are shifted to fill the resulting gap.\n\nSee also: keepat!, delete!, popat!, splice!.\n\nExamples\n\njulia> deleteat!([6, 5, 4, 3, 2, 1], 2)\n5-element Vector{Int64}:\n 6\n 4\n 3\n 2\n 1\n\n\n\n\n\ndeleteat!(a::Vector, inds)\n\nRemove the items at the indices given by inds, and return the modified a. Subsequent items are shifted to fill the resulting gap.\n\ninds can be either an iterator or a collection of sorted and unique integer indices, or a boolean vector of the same length as a with true indicating entries to delete.\n\nExamples\n\njulia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)\n3-element Vector{Int64}:\n 5\n 3\n 1\n\njulia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])\n3-element Vector{Int64}:\n 5\n 3\n 1\n\njulia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))\nERROR: ArgumentError: indices must be unique and sorted\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.keepat!","page":"Collections and Data Structures","title":"Base.keepat!","text":"keepat!(a::Vector, inds)\nkeepat!(a::BitVector, inds)\n\nRemove the items at all the indices which are not given by inds, and return the modified a. Items which are kept are shifted to fill the resulting gaps.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\ninds must be an iterator of sorted and unique integer indices. See also deleteat!.\n\ncompat: Julia 1.7\nThis function is available as of Julia 1.7.\n\nExamples\n\njulia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)\n3-element Vector{Int64}:\n 6\n 4\n 2\n\n\n\n\n\nkeepat!(a::Vector, m::AbstractVector{Bool})\nkeepat!(a::BitVector, m::AbstractVector{Bool})\n\nThe in-place version of logical indexing a = a[m]. That is, keepat!(a, m) on vectors of equal length a and m will remove all elements from a for which m at the corresponding index is false.\n\nExamples\n\njulia> a = [:a, :b, :c];\n\njulia> keepat!(a, [true, false, true])\n2-element Vector{Symbol}:\n :a\n :c\n\njulia> a\n2-element Vector{Symbol}:\n :a\n :c\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.splice!","page":"Collections and Data Structures","title":"Base.splice!","text":"splice!(a::Vector, index::Integer, [replacement]) -> item\n\nRemove the item at the given index, and return the removed item. Subsequent items are shifted left to fill the resulting gap. If specified, replacement values from an ordered collection will be spliced in place of the removed item.\n\nSee also: replace, delete!, deleteat!, pop!, popat!.\n\nExamples\n\njulia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)\n2\n\njulia> A\n5-element Vector{Int64}:\n 6\n 5\n 4\n 3\n 1\n\njulia> splice!(A, 5, -1)\n1\n\njulia> A\n5-element Vector{Int64}:\n 6\n 5\n 4\n 3\n -1\n\njulia> splice!(A, 1, [-1, -2, -3])\n6\n\njulia> A\n7-element Vector{Int64}:\n -1\n -2\n -3\n 5\n 4\n 3\n -1\n\nTo insert replacement before an index n without removing any items, use splice!(collection, n:n-1, replacement).\n\n\n\n\n\nsplice!(a::Vector, indices, [replacement]) -> items\n\nRemove items at specified indices, and return a collection containing the removed items. Subsequent items are shifted left to fill the resulting gaps. If specified, replacement values from an ordered collection will be spliced in place of the removed items; in this case, indices must be a AbstractUnitRange.\n\nTo insert replacement before an index n without removing any items, use splice!(collection, n:n-1, replacement).\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\ncompat: Julia 1.5\nPrior to Julia 1.5, indices must always be a UnitRange.\n\ncompat: Julia 1.8\nPrior to Julia 1.8, indices must be a UnitRange if splicing in replacement values.\n\nExamples\n\njulia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)\nInt64[]\n\njulia> A\n8-element Vector{Int64}:\n -1\n -2\n -3\n 2\n 5\n 4\n 3\n -1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.resize!","page":"Collections and Data Structures","title":"Base.resize!","text":"resize!(a::Vector, n::Integer) -> Vector\n\nResize a to contain n elements. If n is smaller than the current collection length, the first n elements will be retained. If n is larger, the new elements are not guaranteed to be initialized.\n\nExamples\n\njulia> resize!([6, 5, 4, 3, 2, 1], 3)\n3-element Vector{Int64}:\n 6\n 5\n 4\n\njulia> a = resize!([6, 5, 4, 3, 2, 1], 8);\n\njulia> length(a)\n8\n\njulia> a[1:6]\n6-element Vector{Int64}:\n 6\n 5\n 4\n 3\n 2\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.append!","page":"Collections and Data Structures","title":"Base.append!","text":"append!(collection, collections...) -> collection.\n\nFor an ordered container collection, add the elements of each collections to the end of it.\n\ncompat: Julia 1.6\nSpecifying multiple collections to be appended requires at least Julia 1.6.\n\nExamples\n\njulia> append!([1], [2, 3])\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> append!([1, 2, 3], [4, 5], [6])\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\nUse push! to add individual items to collection which are not already themselves in another collection. The result of the preceding example is equivalent to push!([1, 2, 3], 4, 5, 6).\n\nSee sizehint! for notes about the performance model.\n\nSee also vcat for vectors, union! for sets, and prepend! and pushfirst! for the opposite order.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.prepend!","page":"Collections and Data Structures","title":"Base.prepend!","text":"prepend!(a::Vector, collections...) -> collection\n\nInsert the elements of each collections to the beginning of a.\n\nWhen collections specifies multiple collections, order is maintained: elements of collections[1] will appear leftmost in a, and so on.\n\ncompat: Julia 1.6\nSpecifying multiple collections to be prepended requires at least Julia 1.6.\n\nExamples\n\njulia> prepend!([3], [1, 2])\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> prepend!([6], [1, 2], [3, 4, 5])\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Vector (a.k.a. 1-dimensional Array)\nBitVector (a.k.a. 1-dimensional BitArray)","category":"page"},{"location":"base/collections/#Utility-Collections","page":"Collections and Data Structures","title":"Utility Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.Pair\nIterators.Pairs","category":"page"},{"location":"base/collections/#Core.Pair","page":"Collections and Data Structures","title":"Core.Pair","text":"Pair(x, y)\nx => y\n\nConstruct a Pair object with type Pair{typeof(x), typeof(y)}. The elements are stored in the fields first and second. They can also be accessed via iteration (but a Pair is treated as a single \"scalar\" for broadcasting operations).\n\nSee also Dict.\n\nExamples\n\njulia> p = \"foo\" => 7\n\"foo\" => 7\n\njulia> typeof(p)\nPair{String, Int64}\n\njulia> p.first\n\"foo\"\n\njulia> for x in p\n println(x)\n end\nfoo\n7\n\njulia> replace.([\"xops\", \"oxps\"], \"x\" => \"o\")\n2-element Vector{String}:\n \"oops\"\n \"oops\"\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.Pairs","page":"Collections and Data Structures","title":"Base.Pairs","text":"Base.Pairs(values, keys) <: AbstractDict{eltype(keys), eltype(values)}\n\nTransforms an indexable container into a Dictionary-view of the same data. Modifying the key-space of the underlying data may invalidate this object.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#man-distributed","page":"Distributed Computing","title":"Distributed Computing","text":"","category":"section"},{"location":"stdlib/Distributed/","page":"Distributed Computing","title":"Distributed Computing","text":"Distributed\nDistributed.addprocs\nDistributed.nprocs\nDistributed.nworkers\nDistributed.procs()\nDistributed.procs(::Integer)\nDistributed.workers\nDistributed.rmprocs\nDistributed.interrupt\nDistributed.myid\nDistributed.pmap\nDistributed.RemoteException\nDistributed.ProcessExitedException\nDistributed.Future\nDistributed.RemoteChannel\nDistributed.fetch(::Distributed.Future)\nDistributed.fetch(::RemoteChannel)\nDistributed.remotecall(::Any, ::Integer, ::Any...)\nDistributed.remotecall_wait(::Any, ::Integer, ::Any...)\nDistributed.remotecall_fetch(::Any, ::Integer, ::Any...)\nDistributed.remote_do(::Any, ::Integer, ::Any...)\nDistributed.put!(::RemoteChannel, ::Any...)\nDistributed.put!(::Distributed.Future, ::Any)\nDistributed.take!(::RemoteChannel, ::Any...)\nDistributed.isready(::RemoteChannel, ::Any...)\nDistributed.isready(::Distributed.Future)\nDistributed.AbstractWorkerPool\nDistributed.WorkerPool\nDistributed.CachingPool\nDistributed.default_worker_pool\nDistributed.clear!\nDistributed.remote\nDistributed.remotecall(::Any, ::AbstractWorkerPool, ::Any...)\nDistributed.remotecall_wait(::Any, ::AbstractWorkerPool, ::Any...)\nDistributed.remotecall_fetch(::Any, ::AbstractWorkerPool, ::Any...)\nDistributed.remote_do(::Any, ::AbstractWorkerPool, ::Any...)\nDistributed.@spawn\nDistributed.@spawnat\nDistributed.@fetch\nDistributed.@fetchfrom\nDistributed.@distributed\nDistributed.@everywhere\nDistributed.remoteref_id\nDistributed.channel_from_id\nDistributed.worker_id_from_socket\nDistributed.cluster_cookie()\nDistributed.cluster_cookie(::Any)","category":"page"},{"location":"stdlib/Distributed/#Distributed","page":"Distributed Computing","title":"Distributed","text":"Tools for distributed parallel processing.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Distributed/#Distributed.addprocs","page":"Distributed Computing","title":"Distributed.addprocs","text":"addprocs(manager::ClusterManager; kwargs...) -> List of process identifiers\n\nLaunches worker processes via the specified cluster manager.\n\nFor example, Beowulf clusters are supported via a custom cluster manager implemented in the package ClusterManagers.jl.\n\nThe number of seconds a newly launched worker waits for connection establishment from the master can be specified via variable JULIA_WORKER_TIMEOUT in the worker process's environment. Relevant only when using TCP/IP as transport.\n\nTo launch workers without blocking the REPL, or the containing function if launching workers programmatically, execute addprocs in its own task.\n\nExamples\n\n# On busy clusters, call `addprocs` asynchronously\nt = @async addprocs(...)\n\n# Utilize workers as and when they come online\nif nprocs() > 1 # Ensure at least one new worker is available\n .... # perform distributed execution\nend\n\n# Retrieve newly launched worker IDs, or any error messages\nif istaskdone(t) # Check if `addprocs` has completed to ensure `fetch` doesn't block\n if nworkers() == N\n new_pids = fetch(t)\n else\n fetch(t)\n end\nend\n\n\n\n\n\naddprocs(machines; tunnel=false, sshflags=``, max_parallel=10, kwargs...) -> List of process identifiers\n\nAdd worker processes on remote machines via SSH. Configuration is done with keyword arguments (see below). In particular, the exename keyword can be used to specify the path to the julia binary on the remote machine(s).\n\nmachines is a vector of \"machine specifications\" which are given as strings of the form [user@]host[:port] [bind_addr[:port]]. user defaults to current user and port to the standard SSH port. If [bind_addr[:port]] is specified, other workers will connect to this worker at the specified bind_addr and port.\n\nIt is possible to launch multiple processes on a remote host by using a tuple in the machines vector or the form (machine_spec, count), where count is the number of workers to be launched on the specified host. Passing :auto as the worker count will launch as many workers as the number of CPU threads on the remote host.\n\nExamples:\n\naddprocs([\n \"remote1\", # one worker on 'remote1' logging in with the current username\n \"user@remote2\", # one worker on 'remote2' logging in with the 'user' username\n \"user@remote3:2222\", # specifying SSH port to '2222' for 'remote3'\n (\"user@remote4\", 4), # launch 4 workers on 'remote4'\n (\"user@remote5\", :auto), # launch as many workers as CPU threads on 'remote5'\n])\n\nKeyword arguments:\n\ntunnel: if true then SSH tunneling will be used to connect to the worker from the master process. Default is false.\nmultiplex: if true then SSH multiplexing is used for SSH tunneling. Default is false.\nssh: the name or path of the SSH client executable used to start the workers. Default is \"ssh\".\nsshflags: specifies additional ssh options, e.g. sshflags=`-i /home/foo/bar.pem`\nmax_parallel: specifies the maximum number of workers connected to in parallel at a host. Defaults to 10.\nshell: specifies the type of shell to which ssh connects on the workers.\nshell=:posix: a POSIX-compatible Unix/Linux shell (sh, ksh, bash, dash, zsh, etc.). The default.\nshell=:csh: a Unix C shell (csh, tcsh).\nshell=:wincmd: Microsoft Windows cmd.exe.\ndir: specifies the working directory on the workers. Defaults to the host's current directory (as found by pwd())\nenable_threaded_blas: if true then BLAS will run on multiple threads in added processes. Default is false.\nexename: name of the julia executable. Defaults to \"$(Sys.BINDIR)/julia\" or \"$(Sys.BINDIR)/julia-debug\" as the case may be. It is recommended that a common Julia version is used on all remote machines because serialization and code distribution might fail otherwise.\nexeflags: additional flags passed to the worker processes.\ntopology: Specifies how the workers connect to each other. Sending a message between unconnected workers results in an error.\ntopology=:all_to_all: All processes are connected to each other. The default.\ntopology=:master_worker: Only the driver process, i.e. pid 1 connects to the workers. The workers do not connect to each other.\ntopology=:custom: The launch method of the cluster manager specifies the connection topology via fields ident and connect_idents in WorkerConfig. A worker with a cluster manager identity ident will connect to all workers specified in connect_idents.\nlazy: Applicable only with topology=:all_to_all. If true, worker-worker connections are setup lazily, i.e. they are setup at the first instance of a remote call between workers. Default is true.\nenv: provide an array of string pairs such as env=[\"JULIA_DEPOT_PATH\"=>\"/depot\"] to request that environment variables are set on the remote machine. By default only the environment variable JULIA_WORKER_TIMEOUT is passed automatically from the local to the remote environment.\ncmdline_cookie: pass the authentication cookie via the --worker commandline option. The (more secure) default behaviour of passing the cookie via ssh stdio may hang with Windows workers that use older (pre-ConPTY) Julia or Windows versions, in which case cmdline_cookie=true offers a work-around.\n\ncompat: Julia 1.6\nThe keyword arguments ssh, shell, env and cmdline_cookie were added in Julia 1.6.\n\nEnvironment variables:\n\nIf the master process fails to establish a connection with a newly launched worker within 60.0 seconds, the worker treats it as a fatal situation and terminates. This timeout can be controlled via environment variable JULIA_WORKER_TIMEOUT. The value of JULIA_WORKER_TIMEOUT on the master process specifies the number of seconds a newly launched worker waits for connection establishment.\n\n\n\n\n\naddprocs(np::Integer=Sys.CPU_THREADS; restrict=true, kwargs...) -> List of process identifiers\n\nLaunch np workers on the local host using the in-built LocalManager.\n\nLocal workers inherit the current package environment (i.e., active project, LOAD_PATH, and DEPOT_PATH) from the main process.\n\nwarning: Warning\nNote that workers do not run a ~/.julia/config/startup.jl startup script, nor do they synchronize their global state (such as command-line switches, global variables, new method definitions, and loaded modules) with any of the other running processes.\n\nKeyword arguments:\n\nrestrict::Bool: if true (default) binding is restricted to 127.0.0.1.\ndir, exename, exeflags, env, topology, lazy, enable_threaded_blas: same effect as for SSHManager, see documentation for addprocs(machines::AbstractVector).\n\ncompat: Julia 1.9\nThe inheriting of the package environment and the env keyword argument were added in Julia 1.9.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.nprocs","page":"Distributed Computing","title":"Distributed.nprocs","text":"nprocs()\n\nGet the number of available processes.\n\nExamples\n\njulia> nprocs()\n3\n\njulia> workers()\n2-element Array{Int64,1}:\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.nworkers","page":"Distributed Computing","title":"Distributed.nworkers","text":"nworkers()\n\nGet the number of available worker processes. This is one less than nprocs(). Equal to nprocs() if nprocs() == 1.\n\nExamples\n\n$ julia -p 2\n\njulia> nprocs()\n3\n\njulia> nworkers()\n2\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.procs-Tuple{}","page":"Distributed Computing","title":"Distributed.procs","text":"procs()\n\nReturn a list of all process identifiers, including pid 1 (which is not included by workers()).\n\nExamples\n\n$ julia -p 2\n\njulia> procs()\n3-element Array{Int64,1}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.procs-Tuple{Integer}","page":"Distributed Computing","title":"Distributed.procs","text":"procs(pid::Integer)\n\nReturn a list of all process identifiers on the same physical node. Specifically all workers bound to the same ip-address as pid are returned.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.workers","page":"Distributed Computing","title":"Distributed.workers","text":"workers()\n\nReturn a list of all worker process identifiers.\n\nExamples\n\n$ julia -p 2\n\njulia> workers()\n2-element Array{Int64,1}:\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.rmprocs","page":"Distributed Computing","title":"Distributed.rmprocs","text":"rmprocs(pids...; waitfor=typemax(Int))\n\nRemove the specified workers. Note that only process 1 can add or remove workers.\n\nArgument waitfor specifies how long to wait for the workers to shut down:\n\nIf unspecified, rmprocs will wait until all requested pids are removed.\nAn ErrorException is raised if all workers cannot be terminated before the requested waitfor seconds.\nWith a waitfor value of 0, the call returns immediately with the workers scheduled for removal in a different task. The scheduled Task object is returned. The user should call wait on the task before invoking any other parallel calls.\n\nExamples\n\n$ julia -p 5\n\njulia> t = rmprocs(2, 3, waitfor=0)\nTask (runnable) @0x0000000107c718d0\n\njulia> wait(t)\n\njulia> workers()\n3-element Array{Int64,1}:\n 4\n 5\n 6\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.interrupt","page":"Distributed Computing","title":"Distributed.interrupt","text":"interrupt(pids::Integer...)\n\nInterrupt the current executing task on the specified workers. This is equivalent to pressing Ctrl-C on the local machine. If no arguments are given, all workers are interrupted.\n\n\n\n\n\ninterrupt(pids::AbstractVector=workers())\n\nInterrupt the current executing task on the specified workers. This is equivalent to pressing Ctrl-C on the local machine. If no arguments are given, all workers are interrupted.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.myid","page":"Distributed Computing","title":"Distributed.myid","text":"myid()\n\nGet the id of the current process.\n\nExamples\n\njulia> myid()\n1\n\njulia> remotecall_fetch(() -> myid(), 4)\n4\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.pmap","page":"Distributed Computing","title":"Distributed.pmap","text":"pmap(f, [::AbstractWorkerPool], c...; distributed=true, batch_size=1, on_error=nothing, retry_delays=[], retry_check=nothing) -> collection\n\nTransform collection c by applying f to each element using available workers and tasks.\n\nFor multiple collection arguments, apply f elementwise.\n\nNote that f must be made available to all worker processes; see Code Availability and Loading Packages for details.\n\nIf a worker pool is not specified all available workers will be used via a CachingPool.\n\nBy default, pmap distributes the computation over all specified workers. To use only the local process and distribute over tasks, specify distributed=false. This is equivalent to using asyncmap. For example, pmap(f, c; distributed=false) is equivalent to asyncmap(f,c; ntasks=()->nworkers())\n\npmap can also use a mix of processes and tasks via the batch_size argument. For batch sizes greater than 1, the collection is processed in multiple batches, each of length batch_size or less. A batch is sent as a single request to a free worker, where a local asyncmap processes elements from the batch using multiple concurrent tasks.\n\nAny error stops pmap from processing the remainder of the collection. To override this behavior you can specify an error handling function via argument on_error which takes in a single argument, i.e., the exception. The function can stop the processing by rethrowing the error, or, to continue, return any value which is then returned inline with the results to the caller.\n\nConsider the following two examples. The first one returns the exception object inline, the second a 0 in place of any exception:\n\njulia> pmap(x->iseven(x) ? error(\"foo\") : x, 1:4; on_error=identity)\n4-element Array{Any,1}:\n 1\n ErrorException(\"foo\")\n 3\n ErrorException(\"foo\")\n\njulia> pmap(x->iseven(x) ? error(\"foo\") : x, 1:4; on_error=ex->0)\n4-element Array{Int64,1}:\n 1\n 0\n 3\n 0\n\nErrors can also be handled by retrying failed computations. Keyword arguments retry_delays and retry_check are passed through to retry as keyword arguments delays and check respectively. If batching is specified, and an entire batch fails, all items in the batch are retried.\n\nNote that if both on_error and retry_delays are specified, the on_error hook is called before retrying. If on_error does not throw (or rethrow) an exception, the element will not be retried.\n\nExample: On errors, retry f on an element a maximum of 3 times without any delay between retries.\n\npmap(f, c; retry_delays = zeros(3))\n\nExample: Retry f only if the exception is not of type InexactError, with exponentially increasing delays up to 3 times. Return a NaN in place for all InexactError occurrences.\n\npmap(f, c; on_error = e->(isa(e, InexactError) ? NaN : rethrow()), retry_delays = ExponentialBackOff(n = 3))\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.RemoteException","page":"Distributed Computing","title":"Distributed.RemoteException","text":"RemoteException(captured)\n\nExceptions on remote computations are captured and rethrown locally. A RemoteException wraps the pid of the worker and a captured exception. A CapturedException captures the remote exception and a serializable form of the call stack when the exception was raised.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.ProcessExitedException","page":"Distributed Computing","title":"Distributed.ProcessExitedException","text":"ProcessExitedException(worker_id::Int)\n\nAfter a client Julia process has exited, further attempts to reference the dead child will throw this exception.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.Future","page":"Distributed Computing","title":"Distributed.Future","text":"Future(w::Int, rrid::RRID, v::Union{Some, Nothing}=nothing)\n\nA Future is a placeholder for a single computation of unknown termination status and time. For multiple potential computations, see RemoteChannel. See remoteref_id for identifying an AbstractRemoteRef.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.RemoteChannel","page":"Distributed Computing","title":"Distributed.RemoteChannel","text":"RemoteChannel(pid::Integer=myid())\n\nMake a reference to a Channel{Any}(1) on process pid. The default pid is the current process.\n\nRemoteChannel(f::Function, pid::Integer=myid())\n\nCreate references to remote channels of a specific size and type. f is a function that when executed on pid must return an implementation of an AbstractChannel.\n\nFor example, RemoteChannel(()->Channel{Int}(10), pid), will return a reference to a channel of type Int and size 10 on pid.\n\nThe default pid is the current process.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Base.fetch-Tuple{Distributed.Future}","page":"Distributed Computing","title":"Base.fetch","text":"fetch(x::Future)\n\nWait for and get the value of a Future. The fetched value is cached locally. Further calls to fetch on the same reference return the cached value. If the remote value is an exception, throws a RemoteException which captures the remote exception and backtrace.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.fetch-Tuple{RemoteChannel}","page":"Distributed Computing","title":"Base.fetch","text":"fetch(c::RemoteChannel)\n\nWait for and get a value from a RemoteChannel. Exceptions raised are the same as for a Future. Does not remove the item fetched.\n\n\n\n\n\nfetch(x::Any)\n\nReturn x.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall-Tuple{Any, Integer, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall","text":"remotecall(f, id::Integer, args...; kwargs...) -> Future\n\nCall a function f asynchronously on the given arguments on the specified process. Return a Future. Keyword arguments, if any, are passed through to f.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall_wait-Tuple{Any, Integer, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall_wait","text":"remotecall_wait(f, id::Integer, args...; kwargs...)\n\nPerform a faster wait(remotecall(...)) in one message on the Worker specified by worker id id. Keyword arguments, if any, are passed through to f.\n\nSee also wait and remotecall.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall_fetch-Tuple{Any, Integer, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall_fetch","text":"remotecall_fetch(f, id::Integer, args...; kwargs...)\n\nPerform fetch(remotecall(...)) in one message. Keyword arguments, if any, are passed through to f. Any remote exceptions are captured in a RemoteException and thrown.\n\nSee also fetch and remotecall.\n\nExamples\n\n$ julia -p 2\n\njulia> remotecall_fetch(sqrt, 2, 4)\n2.0\n\njulia> remotecall_fetch(sqrt, 2, -4)\nERROR: On worker 2:\nDomainError with -4.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\n...\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remote_do-Tuple{Any, Integer, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remote_do","text":"remote_do(f, id::Integer, args...; kwargs...) -> nothing\n\nExecutes f on worker id asynchronously. Unlike remotecall, it does not store the result of computation, nor is there a way to wait for its completion.\n\nA successful invocation indicates that the request has been accepted for execution on the remote node.\n\nWhile consecutive remotecalls to the same worker are serialized in the order they are invoked, the order of executions on the remote worker is undetermined. For example, remote_do(f1, 2); remotecall(f2, 2); remote_do(f3, 2) will serialize the call to f1, followed by f2 and f3 in that order. However, it is not guaranteed that f1 is executed before f3 on worker 2.\n\nAny exceptions thrown by f are printed to stderr on the remote worker.\n\nKeyword arguments, if any, are passed through to f.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.put!-Tuple{RemoteChannel, Vararg{Any}}","page":"Distributed Computing","title":"Base.put!","text":"put!(rr::RemoteChannel, args...)\n\nStore a set of values to the RemoteChannel. If the channel is full, blocks until space is available. Return the first argument.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.put!-Tuple{Distributed.Future, Any}","page":"Distributed Computing","title":"Base.put!","text":"put!(rr::Future, v)\n\nStore a value to a Future rr. Futures are write-once remote references. A put! on an already set Future throws an Exception. All asynchronous remote calls return Futures and set the value to the return value of the call upon completion.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.take!-Tuple{RemoteChannel, Vararg{Any}}","page":"Distributed Computing","title":"Base.take!","text":"take!(rr::RemoteChannel, args...)\n\nFetch value(s) from a RemoteChannel rr, removing the value(s) in the process.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.isready-Tuple{RemoteChannel, Vararg{Any}}","page":"Distributed Computing","title":"Base.isready","text":"isready(rr::RemoteChannel, args...)\n\nDetermine whether a RemoteChannel has a value stored to it. Note that this function can cause race conditions, since by the time you receive its result it may no longer be true. However, it can be safely used on a Future since they are assigned only once.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.isready-Tuple{Distributed.Future}","page":"Distributed Computing","title":"Base.isready","text":"isready(rr::Future)\n\nDetermine whether a Future has a value stored to it.\n\nIf the argument Future is owned by a different node, this call will block to wait for the answer. It is recommended to wait for rr in a separate task instead or to use a local Channel as a proxy:\n\np = 1\nf = Future(p)\nerrormonitor(@async put!(f, remotecall_fetch(long_computation, p)))\nisready(f) # will not block\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.AbstractWorkerPool","page":"Distributed Computing","title":"Distributed.AbstractWorkerPool","text":"AbstractWorkerPool\n\nSupertype for worker pools such as WorkerPool and CachingPool. An AbstractWorkerPool should implement:\n\npush! - add a new worker to the overall pool (available + busy)\nput! - put back a worker to the available pool\ntake! - take a worker from the available pool (to be used for remote function execution)\nlength - number of workers available in the overall pool\nisready - return false if a take! on the pool would block, else true\n\nThe default implementations of the above (on a AbstractWorkerPool) require fields\n\nchannel::Channel{Int}\nworkers::Set{Int}\n\nwhere channel contains free worker pids and workers is the set of all workers associated with this pool.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.WorkerPool","page":"Distributed Computing","title":"Distributed.WorkerPool","text":"WorkerPool(workers::Union{Vector{Int},AbstractRange{Int}})\n\nCreate a WorkerPool from a vector or range of worker ids.\n\nExamples\n\n$ julia -p 3\n\njulia> WorkerPool([2, 3])\nWorkerPool(Channel{Int64}(sz_max:9223372036854775807,sz_curr:2), Set([2, 3]), RemoteChannel{Channel{Any}}(1, 1, 6))\n\njulia> WorkerPool(2:4)\nWorkerPool(Channel{Int64}(sz_max:9223372036854775807,sz_curr:2), Set([4, 2, 3]), RemoteChannel{Channel{Any}}(1, 1, 7))\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.CachingPool","page":"Distributed Computing","title":"Distributed.CachingPool","text":"CachingPool(workers::Vector{Int})\n\nAn implementation of an AbstractWorkerPool. remote, remotecall_fetch, pmap (and other remote calls which execute functions remotely) benefit from caching the serialized/deserialized functions on the worker nodes, especially closures (which may capture large amounts of data).\n\nThe remote cache is maintained for the lifetime of the returned CachingPool object. To clear the cache earlier, use clear!(pool).\n\nFor global variables, only the bindings are captured in a closure, not the data. let blocks can be used to capture global data.\n\nExamples\n\nconst foo = rand(10^8);\nwp = CachingPool(workers())\nlet foo = foo\n pmap(i -> sum(foo) + i, wp, 1:100);\nend\n\nThe above would transfer foo only once to each worker.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.default_worker_pool","page":"Distributed Computing","title":"Distributed.default_worker_pool","text":"default_worker_pool()\n\nAbstractWorkerPool containing idle workers - used by remote(f) and pmap (by default). Unless one is explicitly set via default_worker_pool!(pool), the default worker pool is initialized to a WorkerPool.\n\nExamples\n\n$ julia -p 3\n\njulia> default_worker_pool()\nWorkerPool(Channel{Int64}(sz_max:9223372036854775807,sz_curr:3), Set([4, 2, 3]), RemoteChannel{Channel{Any}}(1, 1, 4))\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.clear!","page":"Distributed Computing","title":"Distributed.clear!","text":"clear!(syms, pids=workers(); mod=Main)\n\nClears global bindings in modules by initializing them to nothing. syms should be of type Symbol or a collection of Symbols . pids and mod identify the processes and the module in which global variables are to be reinitialized. Only those names found to be defined under mod are cleared.\n\nAn exception is raised if a global constant is requested to be cleared.\n\n\n\n\n\nclear!(pool::CachingPool) -> pool\n\nRemoves all cached functions from all participating workers.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.remote","page":"Distributed Computing","title":"Distributed.remote","text":"remote([p::AbstractWorkerPool], f) -> Function\n\nReturn an anonymous function that executes function f on an available worker (drawn from WorkerPool p if provided) using remotecall_fetch.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.remotecall-Tuple{Any, AbstractWorkerPool, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall","text":"remotecall(f, pool::AbstractWorkerPool, args...; kwargs...) -> Future\n\nWorkerPool variant of remotecall(f, pid, ....). Wait for and take a free worker from pool and perform a remotecall on it.\n\nExamples\n\n$ julia -p 3\n\njulia> wp = WorkerPool([2, 3]);\n\njulia> A = rand(3000);\n\njulia> f = remotecall(maximum, wp, A)\nFuture(2, 1, 6, nothing)\n\nIn this example, the task ran on pid 2, called from pid 1.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall_wait-Tuple{Any, AbstractWorkerPool, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall_wait","text":"remotecall_wait(f, pool::AbstractWorkerPool, args...; kwargs...) -> Future\n\nWorkerPool variant of remotecall_wait(f, pid, ....). Wait for and take a free worker from pool and perform a remotecall_wait on it.\n\nExamples\n\n$ julia -p 3\n\njulia> wp = WorkerPool([2, 3]);\n\njulia> A = rand(3000);\n\njulia> f = remotecall_wait(maximum, wp, A)\nFuture(3, 1, 9, nothing)\n\njulia> fetch(f)\n0.9995177101692958\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall_fetch-Tuple{Any, AbstractWorkerPool, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall_fetch","text":"remotecall_fetch(f, pool::AbstractWorkerPool, args...; kwargs...) -> result\n\nWorkerPool variant of remotecall_fetch(f, pid, ....). Waits for and takes a free worker from pool and performs a remotecall_fetch on it.\n\nExamples\n\n$ julia -p 3\n\njulia> wp = WorkerPool([2, 3]);\n\njulia> A = rand(3000);\n\njulia> remotecall_fetch(maximum, wp, A)\n0.9995177101692958\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remote_do-Tuple{Any, AbstractWorkerPool, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remote_do","text":"remote_do(f, pool::AbstractWorkerPool, args...; kwargs...) -> nothing\n\nWorkerPool variant of remote_do(f, pid, ....). Wait for and take a free worker from pool and perform a remote_do on it.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.@spawn","page":"Distributed Computing","title":"Distributed.@spawn","text":"@spawn expr\n\nCreate a closure around an expression and run it on an automatically-chosen process, returning a Future to the result. This macro is deprecated; @spawnat :any expr should be used instead.\n\nExamples\n\njulia> addprocs(3);\n\njulia> f = @spawn myid()\nFuture(2, 1, 5, nothing)\n\njulia> fetch(f)\n2\n\njulia> f = @spawn myid()\nFuture(3, 1, 7, nothing)\n\njulia> fetch(f)\n3\n\ncompat: Julia 1.3\nAs of Julia 1.3 this macro is deprecated. Use @spawnat :any instead.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@spawnat","page":"Distributed Computing","title":"Distributed.@spawnat","text":"@spawnat p expr\n\nCreate a closure around an expression and run the closure asynchronously on process p. Return a Future to the result. If p is the quoted literal symbol :any, then the system will pick a processor to use automatically.\n\nExamples\n\njulia> addprocs(3);\n\njulia> f = @spawnat 2 myid()\nFuture(2, 1, 3, nothing)\n\njulia> fetch(f)\n2\n\njulia> f = @spawnat :any myid()\nFuture(3, 1, 7, nothing)\n\njulia> fetch(f)\n3\n\ncompat: Julia 1.3\nThe :any argument is available as of Julia 1.3.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@fetch","page":"Distributed Computing","title":"Distributed.@fetch","text":"@fetch expr\n\nEquivalent to fetch(@spawnat :any expr). See fetch and @spawnat.\n\nExamples\n\njulia> addprocs(3);\n\njulia> @fetch myid()\n2\n\njulia> @fetch myid()\n3\n\njulia> @fetch myid()\n4\n\njulia> @fetch myid()\n2\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@fetchfrom","page":"Distributed Computing","title":"Distributed.@fetchfrom","text":"@fetchfrom\n\nEquivalent to fetch(@spawnat p expr). See fetch and @spawnat.\n\nExamples\n\njulia> addprocs(3);\n\njulia> @fetchfrom 2 myid()\n2\n\njulia> @fetchfrom 4 myid()\n4\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@distributed","page":"Distributed Computing","title":"Distributed.@distributed","text":"@distributed\n\nA distributed memory, parallel for loop of the form :\n\n@distributed [reducer] for var = range\n body\nend\n\nThe specified range is partitioned and locally executed across all workers. In case an optional reducer function is specified, @distributed performs local reductions on each worker with a final reduction on the calling process.\n\nNote that without a reducer function, @distributed executes asynchronously, i.e. it spawns independent tasks on all available workers and returns immediately without waiting for completion. To wait for completion, prefix the call with @sync, like :\n\n@sync @distributed for var = range\n body\nend\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@everywhere","page":"Distributed Computing","title":"Distributed.@everywhere","text":"@everywhere [procs()] expr\n\nExecute an expression under Main on all procs. Errors on any of the processes are collected into a CompositeException and thrown. For example:\n\n@everywhere bar = 1\n\nwill define Main.bar on all current processes. Any processes added later (say with addprocs()) will not have the expression defined.\n\nUnlike @spawnat, @everywhere does not capture any local variables. Instead, local variables can be broadcast using interpolation:\n\nfoo = 1\n@everywhere bar = $foo\n\nThe optional argument procs allows specifying a subset of all processes to have execute the expression.\n\nSimilar to calling remotecall_eval(Main, procs, expr), but with two extra features:\n\n- `using` and `import` statements run on the calling process first, to ensure\n packages are precompiled.\n- The current source file path used by `include` is propagated to other processes.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.remoteref_id","page":"Distributed Computing","title":"Distributed.remoteref_id","text":"remoteref_id(r::AbstractRemoteRef) -> RRID\n\nFutures and RemoteChannels are identified by fields:\n\nwhere - refers to the node where the underlying object/storage referred to by the reference actually exists.\nwhence - refers to the node the remote reference was created from. Note that this is different from the node where the underlying object referred to actually exists. For example calling RemoteChannel(2) from the master process would result in a where value of 2 and a whence value of 1.\nid is unique across all references created from the worker specified by whence.\n\nTaken together, whence and id uniquely identify a reference across all workers.\n\nremoteref_id is a low-level API which returns a RRID object that wraps whence and id values of a remote reference.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.channel_from_id","page":"Distributed Computing","title":"Distributed.channel_from_id","text":"channel_from_id(id) -> c\n\nA low-level API which returns the backing AbstractChannel for an id returned by remoteref_id. The call is valid only on the node where the backing channel exists.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.worker_id_from_socket","page":"Distributed Computing","title":"Distributed.worker_id_from_socket","text":"worker_id_from_socket(s) -> pid\n\nA low-level API which, given a IO connection or a Worker, returns the pid of the worker it is connected to. This is useful when writing custom serialize methods for a type, which optimizes the data written out depending on the receiving process id.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.cluster_cookie-Tuple{}","page":"Distributed Computing","title":"Distributed.cluster_cookie","text":"cluster_cookie() -> cookie\n\nReturn the cluster cookie.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.cluster_cookie-Tuple{Any}","page":"Distributed Computing","title":"Distributed.cluster_cookie","text":"cluster_cookie(cookie) -> cookie\n\nSet the passed cookie as the cluster cookie, then returns it.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Cluster-Manager-Interface","page":"Distributed Computing","title":"Cluster Manager Interface","text":"","category":"section"},{"location":"stdlib/Distributed/","page":"Distributed Computing","title":"Distributed Computing","text":"This interface provides a mechanism to launch and manage Julia workers on different cluster environments. There are two types of managers present in Base: LocalManager, for launching additional workers on the same host, and SSHManager, for launching on remote hosts via ssh. TCP/IP sockets are used to connect and transport messages between processes. It is possible for Cluster Managers to provide a different transport.","category":"page"},{"location":"stdlib/Distributed/","page":"Distributed Computing","title":"Distributed Computing","text":"Distributed.ClusterManager\nDistributed.WorkerConfig\nDistributed.launch\nDistributed.manage\nDistributed.kill(::ClusterManager, ::Int, ::WorkerConfig)\nDistributed.connect(::ClusterManager, ::Int, ::WorkerConfig)\nDistributed.init_worker\nDistributed.start_worker\nDistributed.process_messages\nDistributed.default_addprocs_params","category":"page"},{"location":"stdlib/Distributed/#Distributed.ClusterManager","page":"Distributed Computing","title":"Distributed.ClusterManager","text":"ClusterManager\n\nSupertype for cluster managers, which control workers processes as a cluster. Cluster managers implement how workers can be added, removed and communicated with. SSHManager and LocalManager are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.WorkerConfig","page":"Distributed Computing","title":"Distributed.WorkerConfig","text":"WorkerConfig\n\nType used by ClusterManagers to control workers added to their clusters. Some fields are used by all cluster managers to access a host:\n\nio – the connection used to access the worker (a subtype of IO or Nothing)\nhost – the host address (either a String or Nothing)\nport – the port on the host used to connect to the worker (either an Int or Nothing)\n\nSome are used by the cluster manager to add workers to an already-initialized host:\n\ncount – the number of workers to be launched on the host\nexename – the path to the Julia executable on the host, defaults to \"$(Sys.BINDIR)/julia\" or \"$(Sys.BINDIR)/julia-debug\"\nexeflags – flags to use when launching Julia remotely\n\nThe userdata field is used to store information for each worker by external managers.\n\nSome fields are used by SSHManager and similar managers:\n\ntunnel – true (use tunneling), false (do not use tunneling), or nothing (use default for the manager)\nmultiplex – true (use SSH multiplexing for tunneling) or false\nforward – the forwarding option used for -L option of ssh\nbind_addr – the address on the remote host to bind to\nsshflags – flags to use in establishing the SSH connection\nmax_parallel – the maximum number of workers to connect to in parallel on the host\n\nSome fields are used by both LocalManagers and SSHManagers:\n\nconnect_at – determines whether this is a worker-to-worker or driver-to-worker setup call\nprocess – the process which will be connected (usually the manager will assign this during addprocs)\nospid – the process ID according to the host OS, used to interrupt worker processes\nenviron – private dictionary used to store temporary information by Local/SSH managers\nident – worker as identified by the ClusterManager\nconnect_idents – list of worker ids the worker must connect to if using a custom topology\nenable_threaded_blas – true, false, or nothing, whether to use threaded BLAS or not on the workers\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.launch","page":"Distributed Computing","title":"Distributed.launch","text":"launch(manager::ClusterManager, params::Dict, launched::Array, launch_ntfy::Condition)\n\nImplemented by cluster managers. For every Julia worker launched by this function, it should append a WorkerConfig entry to launched and notify launch_ntfy. The function MUST exit once all workers, requested by manager have been launched. params is a dictionary of all keyword arguments addprocs was called with.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.manage","page":"Distributed Computing","title":"Distributed.manage","text":"manage(manager::ClusterManager, id::Integer, config::WorkerConfig. op::Symbol)\n\nImplemented by cluster managers. It is called on the master process, during a worker's lifetime, with appropriate op values:\n\nwith :register/:deregister when a worker is added / removed from the Julia worker pool.\nwith :interrupt when interrupt(workers) is called. The ClusterManager should signal the appropriate worker with an interrupt signal.\nwith :finalize for cleanup purposes.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Base.kill-Tuple{ClusterManager, Int64, WorkerConfig}","page":"Distributed Computing","title":"Base.kill","text":"kill(manager::ClusterManager, pid::Int, config::WorkerConfig)\n\nImplemented by cluster managers. It is called on the master process, by rmprocs. It should cause the remote worker specified by pid to exit. kill(manager::ClusterManager.....) executes a remote exit() on pid.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Sockets.connect-Tuple{ClusterManager, Int64, WorkerConfig}","page":"Distributed Computing","title":"Sockets.connect","text":"connect(manager::ClusterManager, pid::Int, config::WorkerConfig) -> (instrm::IO, outstrm::IO)\n\nImplemented by cluster managers using custom transports. It should establish a logical connection to worker with id pid, specified by config and return a pair of IO objects. Messages from pid to current process will be read off instrm, while messages to be sent to pid will be written to outstrm. The custom transport implementation must ensure that messages are delivered and received completely and in order. connect(manager::ClusterManager.....) sets up TCP/IP socket connections in-between workers.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.init_worker","page":"Distributed Computing","title":"Distributed.init_worker","text":"init_worker(cookie::AbstractString, manager::ClusterManager=DefaultClusterManager())\n\nCalled by cluster managers implementing custom transports. It initializes a newly launched process as a worker. Command line argument --worker[=] has the effect of initializing a process as a worker using TCP/IP sockets for transport. cookie is a cluster_cookie.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.start_worker","page":"Distributed Computing","title":"Distributed.start_worker","text":"start_worker([out::IO=stdout], cookie::AbstractString=readline(stdin); close_stdin::Bool=true, stderr_to_stdout::Bool=true)\n\nstart_worker is an internal function which is the default entry point for worker processes connecting via TCP/IP. It sets up the process as a Julia cluster worker.\n\nhost:port information is written to stream out (defaults to stdout).\n\nThe function reads the cookie from stdin if required, and listens on a free port (or if specified, the port in the --bind-to command line option) and schedules tasks to process incoming TCP connections and requests. It also (optionally) closes stdin and redirects stderr to stdout.\n\nIt does not return.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.process_messages","page":"Distributed Computing","title":"Distributed.process_messages","text":"process_messages(r_stream::IO, w_stream::IO, incoming::Bool=true)\n\nCalled by cluster managers using custom transports. It should be called when the custom transport implementation receives the first message from a remote worker. The custom transport must manage a logical connection to the remote worker and provide two IO objects, one for incoming messages and the other for messages addressed to the remote worker. If incoming is true, the remote peer initiated the connection. Whichever of the pair initiates the connection sends the cluster cookie and its Julia version number to perform the authentication handshake.\n\nSee also cluster_cookie.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.default_addprocs_params","page":"Distributed Computing","title":"Distributed.default_addprocs_params","text":"default_addprocs_params(mgr::ClusterManager) -> Dict{Symbol, Any}\n\nImplemented by cluster managers. The default keyword parameters passed when calling addprocs(mgr). The minimal set of options is available by calling default_addprocs_params()\n\n\n\n\n\n","category":"function"},{"location":"manual/conversion-and-promotion/#conversion-and-promotion","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Julia has a system for promoting arguments of mathematical operators to a common type, which has been mentioned in various other sections, including Integers and Floating-Point Numbers, Mathematical Operations and Elementary Functions, Types, and Methods. In this section, we explain how this promotion system works, as well as how to extend it to new types and apply it to functions besides built-in mathematical operators. Traditionally, programming languages fall into two camps with respect to promotion of arithmetic arguments:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Automatic promotion for built-in arithmetic types and operators. In most languages, built-in numeric types, when used as operands to arithmetic operators with infix syntax, such as +, -, *, and /, are automatically promoted to a common type to produce the expected results. C, Java, Perl, and Python, to name a few, all correctly compute the sum 1 + 1.5 as the floating-point value 2.5, even though one of the operands to + is an integer. These systems are convenient and designed carefully enough that they are generally all-but-invisible to the programmer: hardly anyone consciously thinks of this promotion taking place when writing such an expression, but compilers and interpreters must perform conversion before addition since integers and floating-point values cannot be added as-is. Complex rules for such automatic conversions are thus inevitably part of specifications and implementations for such languages.\nNo automatic promotion. This camp includes Ada and ML – very \"strict\" statically typed languages. In these languages, every conversion must be explicitly specified by the programmer. Thus, the example expression 1 + 1.5 would be a compilation error in both Ada and ML. Instead one must write real(1) + 1.5, explicitly converting the integer 1 to a floating-point value before performing addition. Explicit conversion everywhere is so inconvenient, however, that even Ada has some degree of automatic conversion: integer literals are promoted to the expected integer type automatically, and floating-point literals are similarly promoted to appropriate floating-point types.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"In a sense, Julia falls into the \"no automatic promotion\" category: mathematical operators are just functions with special syntax, and the arguments of functions are never automatically converted. However, one may observe that applying mathematical operations to a wide variety of mixed argument types is just an extreme case of polymorphic multiple dispatch – something which Julia's dispatch and type systems are particularly well-suited to handle. \"Automatic\" promotion of mathematical operands simply emerges as a special application: Julia comes with pre-defined catch-all dispatch rules for mathematical operators, invoked when no specific implementation exists for some combination of operand types. These catch-all rules first promote all operands to a common type using user-definable promotion rules, and then invoke a specialized implementation of the operator in question for the resulting values, now of the same type. User-defined types can easily participate in this promotion system by defining methods for conversion to and from other types, and providing a handful of promotion rules defining what types they should promote to when mixed with other types.","category":"page"},{"location":"manual/conversion-and-promotion/#Conversion","page":"Conversion and Promotion","title":"Conversion","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The standard way to obtain a value of a certain type T is to call the type's constructor, T(x). However, there are cases where it's convenient to convert a value from one type to another without the programmer asking for it explicitly. One example is assigning a value into an array: if A is a Vector{Float64}, the expression A[1] = 2 should work by automatically converting the 2 from Int to Float64, and storing the result in the array. This is done via the convert function.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The convert function generally takes two arguments: the first is a type object and the second is a value to convert to that type. The returned value is the value converted to an instance of given type. The simplest way to understand this function is to see it in action:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> x = 12\n12\n\njulia> typeof(x)\nInt64\n\njulia> xu = convert(UInt8, x)\n0x0c\n\njulia> typeof(xu)\nUInt8\n\njulia> xf = convert(AbstractFloat, x)\n12.0\n\njulia> typeof(xf)\nFloat64\n\njulia> a = Any[1 2 3; 4 5 6]\n2×3 Matrix{Any}:\n 1 2 3\n 4 5 6\n\njulia> convert(Array{Float64}, a)\n2×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Conversion isn't always possible, in which case a MethodError is thrown indicating that convert doesn't know how to perform the requested conversion:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> convert(AbstractFloat, \"foo\")\nERROR: MethodError: Cannot `convert` an object of type String to an object of type AbstractFloat\n[...]","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Some languages consider parsing strings as numbers or formatting numbers as strings to be conversions (many dynamic languages will even perform conversion for you automatically). This is not the case in Julia. Even though some strings can be parsed as numbers, most strings are not valid representations of numbers, and only a very limited subset of them are. Therefore in Julia the dedicated parse function must be used to perform this operation, making it more explicit.","category":"page"},{"location":"manual/conversion-and-promotion/#When-is-convert-called?","page":"Conversion and Promotion","title":"When is convert called?","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The following language constructs call convert:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Assigning to an array converts to the array's element type.\nAssigning to a field of an object converts to the declared type of the field.\nConstructing an object with new converts to the object's declared field types.\nAssigning to a variable with a declared type (e.g. local x::T) converts to that type.\nA function with a declared return type converts its return value to that type.\nPassing a value to ccall converts it to the corresponding argument type.","category":"page"},{"location":"manual/conversion-and-promotion/#Conversion-vs.-Construction","page":"Conversion and Promotion","title":"Conversion vs. Construction","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Note that the behavior of convert(T, x) appears to be nearly identical to T(x). Indeed, it usually is. However, there is a key semantic difference: since convert can be called implicitly, its methods are restricted to cases that are considered \"safe\" or \"unsurprising\". convert will only convert between types that represent the same basic kind of thing (e.g. different representations of numbers, or different string encodings). It is also usually lossless; converting a value to a different type and back again should result in the exact same value.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"There are four general kinds of cases where constructors differ from convert:","category":"page"},{"location":"manual/conversion-and-promotion/#Constructors-for-types-unrelated-to-their-arguments","page":"Conversion and Promotion","title":"Constructors for types unrelated to their arguments","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Some constructors don't implement the concept of \"conversion\". For example, Timer(2) creates a 2-second timer, which is not really a \"conversion\" from an integer to a timer.","category":"page"},{"location":"manual/conversion-and-promotion/#Mutable-collections","page":"Conversion and Promotion","title":"Mutable collections","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"convert(T, x) is expected to return the original x if x is already of type T. In contrast, if T is a mutable collection type then T(x) should always make a new collection (copying elements from x).","category":"page"},{"location":"manual/conversion-and-promotion/#Wrapper-types","page":"Conversion and Promotion","title":"Wrapper types","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"For some types which \"wrap\" other values, the constructor may wrap its argument inside a new object even if it is already of the requested type. For example Some(x) wraps x to indicate that a value is present (in a context where the result might be a Some or nothing). However, x itself might be the object Some(y), in which case the result is Some(Some(y)), with two levels of wrapping. convert(Some, x), on the other hand, would just return x since it is already a Some.","category":"page"},{"location":"manual/conversion-and-promotion/#Constructors-that-don't-return-instances-of-their-own-type","page":"Conversion and Promotion","title":"Constructors that don't return instances of their own type","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"In very rare cases it might make sense for the constructor T(x) to return an object not of type T. This could happen if a wrapper type is its own inverse (e.g. Flip(Flip(x)) === x), or to support an old calling syntax for backwards compatibility when a library is restructured. But convert(T, x) should always return a value of type T.","category":"page"},{"location":"manual/conversion-and-promotion/#Defining-New-Conversions","page":"Conversion and Promotion","title":"Defining New Conversions","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"When defining a new type, initially all ways of creating it should be defined as constructors. If it becomes clear that implicit conversion would be useful, and that some constructors meet the above \"safety\" criteria, then convert methods can be added. These methods are typically quite simple, as they only need to call the appropriate constructor. Such a definition might look like this:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"import Base: convert\nconvert(::Type{MyType}, x) = MyType(x)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The type of the first argument of this method is Type{MyType}, the only instance of which is MyType. Thus, this method is only invoked when the first argument is the type value MyType. Notice the syntax used for the first argument: the argument name is omitted prior to the :: symbol, and only the type is given. This is the syntax in Julia for a function argument whose type is specified but whose value does not need to be referenced by name.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"All instances of some abstract types are by default considered \"sufficiently similar\" that a universal convert definition is provided in Julia Base. For example, this definition states that it's valid to convert any Number type to any other by calling a 1-argument constructor:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"convert(::Type{T}, x::Number) where {T<:Number} = T(x)::T","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"This means that new Number types only need to define constructors, since this definition will handle convert for them. An identity conversion is also provided to handle the case where the argument is already of the requested type:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"convert(::Type{T}, x::T) where {T<:Number} = x","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Similar definitions exist for AbstractString, AbstractArray, and AbstractDict.","category":"page"},{"location":"manual/conversion-and-promotion/#Promotion","page":"Conversion and Promotion","title":"Promotion","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Promotion refers to converting values of mixed types to a single common type. Although it is not strictly necessary, it is generally implied that the common type to which the values are converted can faithfully represent all of the original values. In this sense, the term \"promotion\" is appropriate since the values are converted to a \"greater\" type – i.e. one which can represent all of the input values in a single common type. It is important, however, not to confuse this with object-oriented (structural) super-typing, or Julia's notion of abstract super-types: promotion has nothing to do with the type hierarchy, and everything to do with converting between alternate representations. For instance, although every Int32 value can also be represented as a Float64 value, Int32 is not a subtype of Float64.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Promotion to a common \"greater\" type is performed in Julia by the promote function, which takes any number of arguments, and returns a tuple of the same number of values, converted to a common type, or throws an exception if promotion is not possible. The most common use case for promotion is to convert numeric arguments to a common type:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> promote(1, 2.5)\n(1.0, 2.5)\n\njulia> promote(1, 2.5, 3)\n(1.0, 2.5, 3.0)\n\njulia> promote(2, 3//4)\n(2//1, 3//4)\n\njulia> promote(1, 2.5, 3, 3//4)\n(1.0, 2.5, 3.0, 0.75)\n\njulia> promote(1.5, im)\n(1.5 + 0.0im, 0.0 + 1.0im)\n\njulia> promote(1 + 2im, 3//4)\n(1//1 + 2//1*im, 3//4 + 0//1*im)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Floating-point values are promoted to the largest of the floating-point argument types. Integer values are promoted to the largest of the integer argument types. If the types are the same size but differ in signedness, the unsigned type is chosen. Mixtures of integers and floating-point values are promoted to a floating-point type big enough to hold all the values. Integers mixed with rationals are promoted to rationals. Rationals mixed with floats are promoted to floats. Complex values mixed with real values are promoted to the appropriate kind of complex value.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"That is really all there is to using promotions. The rest is just a matter of clever application, the most typical \"clever\" application being the definition of catch-all methods for numeric operations like the arithmetic operators +, -, * and /. Here are some of the catch-all method definitions given in promotion.jl:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"+(x::Number, y::Number) = +(promote(x,y)...)\n-(x::Number, y::Number) = -(promote(x,y)...)\n*(x::Number, y::Number) = *(promote(x,y)...)\n/(x::Number, y::Number) = /(promote(x,y)...)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"These method definitions say that in the absence of more specific rules for adding, subtracting, multiplying and dividing pairs of numeric values, promote the values to a common type and then try again. That's all there is to it: nowhere else does one ever need to worry about promotion to a common numeric type for arithmetic operations – it just happens automatically. There are definitions of catch-all promotion methods for a number of other arithmetic and mathematical functions in promotion.jl, but beyond that, there are hardly any calls to promote required in Julia Base. The most common usages of promote occur in outer constructors methods, provided for convenience, to allow constructor calls with mixed types to delegate to an inner type with fields promoted to an appropriate common type. For example, recall that rational.jl provides the following outer constructor method:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Rational(n::Integer, d::Integer) = Rational(promote(n,d)...)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"This allows calls like the following to work:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> x = Rational(Int8(15),Int32(-5))\n-3//1\n\njulia> typeof(x)\nRational{Int32}","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"For most user-defined types, it is better practice to require programmers to supply the expected types to constructor functions explicitly, but sometimes, especially for numeric problems, it can be convenient to do promotion automatically.","category":"page"},{"location":"manual/conversion-and-promotion/#Defining-Promotion-Rules","page":"Conversion and Promotion","title":"Defining Promotion Rules","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Although one could, in principle, define methods for the promote function directly, this would require many redundant definitions for all possible permutations of argument types. Instead, the behavior of promote is defined in terms of an auxiliary function called promote_rule, which one can provide methods for. The promote_rule function takes a pair of type objects and returns another type object, such that instances of the argument types will be promoted to the returned type. Thus, by defining the rule:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"import Base: promote_rule\npromote_rule(::Type{Float64}, ::Type{Float32}) = Float64","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"one declares that when 64-bit and 32-bit floating-point values are promoted together, they should be promoted to 64-bit floating-point. The promotion type does not need to be one of the argument types. For example, the following promotion rules both occur in Julia Base:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"promote_rule(::Type{BigInt}, ::Type{Float64}) = BigFloat\npromote_rule(::Type{BigInt}, ::Type{Int8}) = BigInt","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"In the latter case, the result type is BigInt since BigInt is the only type large enough to hold integers for arbitrary-precision integer arithmetic. Also note that one does not need to define both promote_rule(::Type{A}, ::Type{B}) and promote_rule(::Type{B}, ::Type{A}) – the symmetry is implied by the way promote_rule is used in the promotion process.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The promote_rule function is used as a building block to define a second function called promote_type, which, given any number of type objects, returns the common type to which those values, as arguments to promote should be promoted. Thus, if one wants to know, in absence of actual values, what type a collection of values of certain types would promote to, one can use promote_type:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> promote_type(Int8, Int64)\nInt64","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Note that we do not overload promote_type directly: we overload promote_rule instead. promote_type uses promote_rule, and adds the symmetry. Overloading it directly can cause ambiguity errors. We overload promote_rule to define how things should be promoted, and we use promote_type to query that.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Internally, promote_type is used inside of promote to determine what type argument values should be converted to for promotion. The curious reader can read the code in promotion.jl, which defines the complete promotion mechanism in about 35 lines.","category":"page"},{"location":"manual/conversion-and-promotion/#Case-Study:-Rational-Promotions","page":"Conversion and Promotion","title":"Case Study: Rational Promotions","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Finally, we finish off our ongoing case study of Julia's rational number type, which makes relatively sophisticated use of the promotion mechanism with the following promotion rules:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"import Base: promote_rule\npromote_rule(::Type{Rational{T}}, ::Type{S}) where {T<:Integer,S<:Integer} = Rational{promote_type(T,S)}\npromote_rule(::Type{Rational{T}}, ::Type{Rational{S}}) where {T<:Integer,S<:Integer} = Rational{promote_type(T,S)}\npromote_rule(::Type{Rational{T}}, ::Type{S}) where {T<:Integer,S<:AbstractFloat} = promote_type(T,S)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The first rule says that promoting a rational number with any other integer type promotes to a rational type whose numerator/denominator type is the result of promotion of its numerator/denominator type with the other integer type. The second rule applies the same logic to two different types of rational numbers, resulting in a rational of the promotion of their respective numerator/denominator types. The third and final rule dictates that promoting a rational with a float results in the same type as promoting the numerator/denominator type with the float.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"This small handful of promotion rules, together with the type's constructors and the default convert method for numbers, are sufficient to make rational numbers interoperate completely naturally with all of Julia's other numeric types – integers, floating-point numbers, and complex numbers. By providing appropriate conversion methods and promotion rules in the same manner, any user-defined numeric type can interoperate just as naturally with Julia's predefined numerics.","category":"page"},{"location":"devdocs/ast/#Julia-ASTs","page":"Julia ASTs","title":"Julia ASTs","text":"","category":"section"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Julia has two representations of code. First there is a surface syntax AST returned by the parser (e.g. the Meta.parse function), and manipulated by macros. It is a structured representation of code as it is written, constructed by julia-parser.scm from a character stream. Next there is a lowered form, or IR (intermediate representation), which is used by type inference and code generation. In the lowered form there are fewer types of nodes, all macros are expanded, and all control flow is converted to explicit branches and sequences of statements. The lowered form is constructed by julia-syntax.scm.","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"First we will focus on the AST, since it is needed to write macros.","category":"page"},{"location":"devdocs/ast/#Surface-syntax-AST","page":"Julia ASTs","title":"Surface syntax AST","text":"","category":"section"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Front end ASTs consist almost entirely of Exprs and atoms (e.g. symbols, numbers). There is generally a different expression head for each visually distinct syntactic form. Examples will be given in s-expression syntax. Each parenthesized list corresponds to an Expr, where the first element is the head. For example (call f x) corresponds to Expr(:call, :f, :x) in Julia.","category":"page"},{"location":"devdocs/ast/#Calls","page":"Julia ASTs","title":"Calls","text":"","category":"section"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Input AST\nf(x) (call f x)\nf(x, y=1, z=2) (call f x (kw y 1) (kw z 2))\nf(x; y=1) (call f (parameters (kw y 1)) x)\nf(x...) (call f (... x))","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"do syntax:","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"f(x) do a,b\n body\nend","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"parses as (do (call f x) (-> (tuple a b) (block body))).","category":"page"},{"location":"devdocs/ast/#Operators","page":"Julia ASTs","title":"Operators","text":"","category":"section"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Most uses of operators are just function calls, so they are parsed with the head call. However some operators are special forms (not necessarily function calls), and in those cases the operator itself is the expression head. In julia-parser.scm these are referred to as \"syntactic operators\". Some operators (+ and *) use N-ary parsing; chained calls are parsed as a single N-argument call. Finally, chains of comparisons have their own special expression structure.","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Input AST\nx+y (call + x y)\na+b+c+d (call + a b c d)\n2x (call * 2 x)\na&&b (&& a b)\nx += 1 (+= x 1)\na ? 1 : 2 (if a 1 2)\na,b (tuple a b)\na==b (call == a b)\n1 @printf \"Hello %s\" \"world\"\nHello world\n\njulia> @printf \"Scientific notation %e\" 1.234\nScientific notation 1.234000e+00\n\njulia> @printf \"Scientific notation three digits %.3e\" 1.23456\nScientific notation three digits 1.235e+00\n\njulia> @printf \"Decimal two digits %.2f\" 1.23456\nDecimal two digits 1.23\n\njulia> @printf \"Padded to length 5 %5i\" 123\nPadded to length 5 123\n\njulia> @printf \"Padded with zeros to length 6 %06i\" 123\nPadded with zeros to length 6 000123\n\njulia> @printf \"Use shorter of decimal or scientific %g %g\" 1.23 12300000.0\nUse shorter of decimal or scientific 1.23 1.23e+07\n\njulia> @printf \"Use dynamic width and precision %*.*f\" 10 2 0.12345\nUse dynamic width and precision 0.12\n\nFor a systematic specification of the format, see here. See also @sprintf to get the result as a String instead of it being printed.\n\nCaveats\n\nInf and NaN are printed consistently as Inf and NaN for flags %a, %A, %e, %E, %f, %F, %g, and %G. Furthermore, if a floating point number is equally close to the numeric values of two possible output strings, the output string further away from zero is chosen.\n\nExamples\n\njulia> @printf(\"%f %F %f %F\", Inf, Inf, NaN, NaN)\nInf Inf NaN NaN\n\njulia> @printf \"%.0f %.1f %f\" 0.5 0.025 -0.0078125\n0 0.0 -0.007812\n\ncompat: Julia 1.8\nStarting in Julia 1.8, %s (string) and %c (character) widths are computed using textwidth, which e.g. ignores zero-width characters (such as combining characters for diacritical marks) and treats certain \"wide\" characters (e.g. emoji) as width 2.\n\ncompat: Julia 1.10\nDynamic width specifiers like %*s and %0*.*f require Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Printf/#Printf.@sprintf","page":"Printf","title":"Printf.@sprintf","text":"@sprintf(\"%Fmt\", args...)\n\nReturn @printf formatted output as string.\n\nExamples\n\njulia> @sprintf \"this is a %s %15.1f\" \"test\" 34.567\n\"this is a test 34.6\"\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Printf/#Printf.Format","page":"Printf","title":"Printf.Format","text":"Printf.Format(format_str)\n\nCreate a C printf-compatible format object that can be used for formatting values.\n\nThe input format_str can include any valid format specifier character and modifiers.\n\nA Format object can be passed to Printf.format(f::Format, args...) to produce a formatted string, or Printf.format(io::IO, f::Format, args...) to print the formatted string directly to io.\n\nFor convenience, the Printf.format\"...\" string macro form can be used for building a Printf.Format object at macro-expansion-time.\n\ncompat: Julia 1.6\nPrintf.Format requires Julia 1.6 or later.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Printf/#Printf.format","page":"Printf","title":"Printf.format","text":"Printf.format(f::Printf.Format, args...) => String\nPrintf.format(io::IO, f::Printf.Format, args...)\n\nApply a printf format object f to provided args and return the formatted string (1st method), or print directly to an io object (2nd method). See @printf for more details on C printf support.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Test/docs/src/index.md\"","category":"page"},{"location":"stdlib/Test/#Unit-Testing","page":"Unit Testing","title":"Unit Testing","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"DocTestSetup = :(using Test)","category":"page"},{"location":"stdlib/Test/#Testing-Base-Julia","page":"Unit Testing","title":"Testing Base Julia","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Julia is under rapid development and has an extensive test suite to verify functionality across multiple platforms. If you build Julia from source, you can run this test suite with make test. In a binary install, you can run the test suite using Base.runtests().","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Base.runtests","category":"page"},{"location":"stdlib/Test/#Base.runtests","page":"Unit Testing","title":"Base.runtests","text":"Base.runtests(tests=[\"all\"]; ncores=ceil(Int, Sys.CPU_THREADS / 2),\n exit_on_error=false, revise=false, [seed])\n\nRun the Julia unit tests listed in tests, which can be either a string or an array of strings, using ncores processors. If exit_on_error is false, when one test fails, all remaining tests in other files will still be run; they are otherwise discarded, when exit_on_error == true. If revise is true, the Revise package is used to load any modifications to Base or to the standard libraries before running the tests. If a seed is provided via the keyword argument, it is used to seed the global RNG in the context where the tests are run; otherwise the seed is chosen randomly.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Basic-Unit-Tests","page":"Unit Testing","title":"Basic Unit Tests","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"The Test module provides simple unit testing functionality. Unit testing is a way to see if your code is correct by checking that the results are what you expect. It can be helpful to ensure your code still works after you make changes, and can be used when developing as a way of specifying the behaviors your code should have when complete. You may also want to look at the documentation for adding tests to your Julia Package.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Simple unit testing can be performed with the @test and @test_throws macros:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@test\nTest.@test_throws","category":"page"},{"location":"stdlib/Test/#Test.@test","page":"Unit Testing","title":"Test.@test","text":"@test ex\n@test f(args...) key=val ...\n@test ex broken=true\n@test ex skip=true\n\nTest that the expression ex evaluates to true. If executed inside a @testset, return a Pass Result if it does, a Fail Result if it is false, and an Error Result if it could not be evaluated. If executed outside a @testset, throw an exception instead of returning Fail or Error.\n\nExamples\n\njulia> @test true\nTest Passed\n\njulia> @test [1, 2] + [2, 1] == [3, 3]\nTest Passed\n\nThe @test f(args...) key=val... form is equivalent to writing @test f(args..., key=val...) which can be useful when the expression is a call using infix syntax such as approximate comparisons:\n\njulia> @test π ≈ 3.14 atol=0.01\nTest Passed\n\nThis is equivalent to the uglier test @test ≈(π, 3.14, atol=0.01). It is an error to supply more than one expression unless the first is a call expression and the rest are assignments (k=v).\n\nYou can use any key for the key=val arguments, except for broken and skip, which have special meanings in the context of @test:\n\nbroken=cond indicates a test that should pass but currently consistently fails when cond==true. Tests that the expression ex evaluates to false or causes an exception. Returns a Broken Result if it does, or an Error Result if the expression evaluates to true. Regular @test ex is evaluated when cond==false.\nskip=cond marks a test that should not be executed but should be included in test summary reporting as Broken, when cond==true. This can be useful for tests that intermittently fail, or tests of not-yet-implemented functionality. Regular @test ex is evaluated when cond==false.\n\nExamples\n\njulia> @test 2 + 2 ≈ 6 atol=1 broken=true\nTest Broken\n Expression: ≈(2 + 2, 6, atol = 1)\n\njulia> @test 2 + 2 ≈ 5 atol=1 broken=false\nTest Passed\n\njulia> @test 2 + 2 == 5 skip=true\nTest Broken\n Skipped: 2 + 2 == 5\n\njulia> @test 2 + 2 == 4 skip=false\nTest Passed\n\ncompat: Julia 1.7\nThe broken and skip keyword arguments require at least Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.@test_throws","page":"Unit Testing","title":"Test.@test_throws","text":"@test_throws exception expr\n\nTests that the expression expr throws exception. The exception may specify either a type, a string, regular expression, or list of strings occurring in the displayed error message, a matching function, or a value (which will be tested for equality by comparing fields). Note that @test_throws does not support a trailing keyword form.\n\ncompat: Julia 1.8\nThe ability to specify anything other than a type or a value as exception requires Julia v1.8 or later.\n\nExamples\n\njulia> @test_throws BoundsError [1, 2, 3][4]\nTest Passed\n Thrown: BoundsError\n\njulia> @test_throws DimensionMismatch [1, 2, 3] + [1, 2]\nTest Passed\n Thrown: DimensionMismatch\n\njulia> @test_throws \"Try sqrt(Complex\" sqrt(-1)\nTest Passed\n Message: \"DomainError with -1.0:\\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\"\n\nIn the final example, instead of matching a single string it could alternatively have been performed with:\n\n[\"Try\", \"Complex\"] (a list of strings)\nr\"Try sqrt\\([Cc]omplex\" (a regular expression)\nstr -> occursin(\"complex\", str) (a matching function)\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"For example, suppose we want to check our new function foo(x) works as expected:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> using Test\n\njulia> foo(x) = length(x)^2\nfoo (generic function with 1 method)","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If the condition is true, a Pass is returned:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test foo(\"bar\") == 9\nTest Passed\n\njulia> @test foo(\"fizz\") >= 10\nTest Passed","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If the condition is false, then a Fail is returned and an exception is thrown:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test foo(\"f\") == 20\nTest Failed at none:1\n Expression: foo(\"f\") == 20\n Evaluated: 1 == 20\n\nERROR: There was an error during testing","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If the condition could not be evaluated because an exception was thrown, which occurs in this case because length is not defined for symbols, an Error object is returned and an exception is thrown:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test foo(:cat) == 1\nError During Test\n Test threw an exception of type MethodError\n Expression: foo(:cat) == 1\n MethodError: no method matching length(::Symbol)\n The function `length` exists, but no method is defined for this combination of argument types.\n\n Closest candidates are:\n length(::SimpleVector) at essentials.jl:256\n length(::Base.MethodList) at reflection.jl:521\n length(::MethodTable) at reflection.jl:597\n ...\n Stacktrace:\n [...]\nERROR: There was an error during testing","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If we expect that evaluating an expression should throw an exception, then we can use @test_throws to check that this occurs:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test_throws MethodError foo(:cat)\nTest Passed\n Thrown: MethodError","category":"page"},{"location":"stdlib/Test/#Working-with-Test-Sets","page":"Unit Testing","title":"Working with Test Sets","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Typically a large number of tests are used to make sure functions work correctly over a range of inputs. In the event a test fails, the default behavior is to throw an exception immediately. However, it is normally preferable to run the rest of the tests first to get a better picture of how many errors there are in the code being tested.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"note: Note\nThe @testset will create a local scope of its own when running the tests in it.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"The @testset macro can be used to group tests into sets. All the tests in a test set will be run, and at the end of the test set a summary will be printed. If any of the tests failed, or could not be evaluated due to an error, the test set will then throw a TestSetException.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@testset\nTest.TestSetException","category":"page"},{"location":"stdlib/Test/#Test.@testset","page":"Unit Testing","title":"Test.@testset","text":"@testset [CustomTestSet] [options...] [\"description\"] begin test_ex end\n@testset [CustomTestSet] [options...] [\"description $v\"] for v in itr test_ex end\n@testset [CustomTestSet] [options...] [\"description $v, $w\"] for v in itrv, w in itrw test_ex end\n@testset [CustomTestSet] [options...] [\"description\"] test_func()\n@testset let v = v, w = w; test_ex; end\n\nWith begin/end or function call\n\nWhen @testset is used, with begin/end or a single function call, the macro starts a new test set in which to evaluate the given expression.\n\nIf no custom testset type is given it defaults to creating a DefaultTestSet. DefaultTestSet records all the results and, if there are any Fails or Errors, throws an exception at the end of the top-level (non-nested) test set, along with a summary of the test results.\n\nAny custom testset type (subtype of AbstractTestSet) can be given and it will also be used for any nested @testset invocations. The given options are only applied to the test set where they are given. The default test set type accepts three boolean options:\n\nverbose: if true, the result summary of the nested testsets is shown even when they all pass (the default is false).\nshowtiming: if true, the duration of each displayed testset is shown (the default is true).\nfailfast: if true, any test failure or error will cause the testset and any child testsets to return immediately (the default is false). This can also be set globally via the env var JULIA_TEST_FAILFAST.\n\ncompat: Julia 1.8\n@testset test_func() requires at least Julia 1.8.\n\ncompat: Julia 1.9\nfailfast requires at least Julia 1.9.\n\nThe description string accepts interpolation from the loop indices. If no description is provided, one is constructed based on the variables. If a function call is provided, its name will be used. Explicit description strings override this behavior.\n\nBy default the @testset macro will return the testset object itself, though this behavior can be customized in other testset types. If a for loop is used then the macro collects and returns a list of the return values of the finish method, which by default will return a list of the testset objects used in each iteration.\n\nBefore the execution of the body of a @testset, there is an implicit call to Random.seed!(seed) where seed is the current seed of the global RNG. Moreover, after the execution of the body, the state of the global RNG is restored to what it was before the @testset. This is meant to ease reproducibility in case of failure, and to allow seamless re-arrangements of @testsets regardless of their side-effect on the global RNG state.\n\nExamples\n\njulia> @testset \"trigonometric identities\" begin\n θ = 2/3*π\n @test sin(-θ) ≈ -sin(θ)\n @test cos(-θ) ≈ cos(θ)\n @test sin(2θ) ≈ 2*sin(θ)*cos(θ)\n @test cos(2θ) ≈ cos(θ)^2 - sin(θ)^2\n end;\nTest Summary: | Pass Total Time\ntrigonometric identities | 4 4 0.2s\n\n@testset for\n\nWhen @testset for is used, the macro starts a new test for each iteration of the provided loop. The semantics of each test set are otherwise identical to that of that begin/end case (as if used for each loop iteration).\n\n@testset let\n\nWhen @testset let is used, the macro starts a transparent test set with the given object added as a context object to any failing test contained therein. This is useful when performing a set of related tests on one larger object and it is desirable to print this larger object when any of the individual tests fail. Transparent test sets do not introduce additional levels of nesting in the test set hierarchy and are passed through directly to the parent test set (with the context object appended to any failing tests.)\n\ncompat: Julia 1.9\n@testset let requires at least Julia 1.9.\n\ncompat: Julia 1.10\nMultiple let assignments are supported since Julia 1.10.\n\nExamples\n\njulia> @testset let logi = log(im)\n @test imag(logi) == π/2\n @test !iszero(real(logi))\n end\nTest Failed at none:3\n Expression: !(iszero(real(logi)))\n Context: logi = 0.0 + 1.5707963267948966im\n\nERROR: There was an error during testing\n\njulia> @testset let logi = log(im), op = !iszero\n @test imag(logi) == π/2\n @test op(real(logi))\n end\nTest Failed at none:3\n Expression: op(real(logi))\n Context: logi = 0.0 + 1.5707963267948966im\n op = !iszero\n\nERROR: There was an error during testing\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.TestSetException","page":"Unit Testing","title":"Test.TestSetException","text":"TestSetException\n\nThrown when a test set finishes and not all tests passed.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"We can put our tests for the foo(x) function in a test set:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @testset \"Foo Tests\" begin\n @test foo(\"a\") == 1\n @test foo(\"ab\") == 4\n @test foo(\"abc\") == 9\n end;\nTest Summary: | Pass Total Time\nFoo Tests | 3 3 0.0s","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test sets can also be nested:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @testset \"Foo Tests\" begin\n @testset \"Animals\" begin\n @test foo(\"cat\") == 9\n @test foo(\"dog\") == foo(\"cat\")\n end\n @testset \"Arrays $i\" for i in 1:3\n @test foo(zeros(i)) == i^2\n @test foo(fill(1.0, i)) == i^2\n end\n end;\nTest Summary: | Pass Total Time\nFoo Tests | 8 8 0.0s","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"As well as call functions:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> f(x) = @test isone(x)\nf (generic function with 1 method)\n\njulia> @testset f(1);\nTest Summary: | Pass Total Time\nf | 1 1 0.0s","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"This can be used to allow for factorization of test sets, making it easier to run individual test sets by running the associated functions instead. Note that in the case of functions, the test set will be given the name of the called function. In the event that a nested test set has no failures, as happened here, it will be hidden in the summary, unless the verbose=true option is passed:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @testset verbose = true \"Foo Tests\" begin\n @testset \"Animals\" begin\n @test foo(\"cat\") == 9\n @test foo(\"dog\") == foo(\"cat\")\n end\n @testset \"Arrays $i\" for i in 1:3\n @test foo(zeros(i)) == i^2\n @test foo(fill(1.0, i)) == i^2\n end\n end;\nTest Summary: | Pass Total Time\nFoo Tests | 8 8 0.0s\n Animals | 2 2 0.0s\n Arrays 1 | 2 2 0.0s\n Arrays 2 | 2 2 0.0s\n Arrays 3 | 2 2 0.0s","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If we do have a test failure, only the details for the failed test sets will be shown:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @testset \"Foo Tests\" begin\n @testset \"Animals\" begin\n @testset \"Felines\" begin\n @test foo(\"cat\") == 9\n end\n @testset \"Canines\" begin\n @test foo(\"dog\") == 9\n end\n end\n @testset \"Arrays\" begin\n @test foo(zeros(2)) == 4\n @test foo(fill(1.0, 4)) == 15\n end\n end\n\nArrays: Test Failed\n Expression: foo(fill(1.0, 4)) == 15\n Evaluated: 16 == 15\n[...]\nTest Summary: | Pass Fail Total Time\nFoo Tests | 3 1 4 0.0s\n Animals | 2 2 0.0s\n Arrays | 1 1 2 0.0s\nERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken.","category":"page"},{"location":"stdlib/Test/#Testing-Log-Statements","page":"Unit Testing","title":"Testing Log Statements","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"One can use the @test_logs macro to test log statements, or use a TestLogger.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@test_logs\nTest.TestLogger\nTest.LogRecord","category":"page"},{"location":"stdlib/Test/#Test.@test_logs","page":"Unit Testing","title":"Test.@test_logs","text":"@test_logs [log_patterns...] [keywords] expression\n\nCollect a list of log records generated by expression using collect_test_logs, check that they match the sequence log_patterns, and return the value of expression. The keywords provide some simple filtering of log records: the min_level keyword controls the minimum log level which will be collected for the test, the match_mode keyword defines how matching will be performed (the default :all checks that all logs and patterns match pairwise; use :any to check that the pattern matches at least once somewhere in the sequence.)\n\nThe most useful log pattern is a simple tuple of the form (level,message). A different number of tuple elements may be used to match other log metadata, corresponding to the arguments to passed to AbstractLogger via the handle_message function: (level,message,module,group,id,file,line). Elements which are present will be matched pairwise with the log record fields using == by default, with the special cases that Symbols may be used for the standard log levels, and Regexs in the pattern will match string or Symbol fields using occursin.\n\nExamples\n\nConsider a function which logs a warning, and several debug messages:\n\nfunction foo(n)\n @info \"Doing foo with n=$n\"\n for i=1:n\n @debug \"Iteration $i\"\n end\n 42\nend\n\nWe can test the info message using\n\n@test_logs (:info,\"Doing foo with n=2\") foo(2)\n\nIf we also wanted to test the debug messages, these need to be enabled with the min_level keyword:\n\nusing Logging\n@test_logs (:info,\"Doing foo with n=2\") (:debug,\"Iteration 1\") (:debug,\"Iteration 2\") min_level=Logging.Debug foo(2)\n\nIf you want to test that some particular messages are generated while ignoring the rest, you can set the keyword match_mode=:any:\n\nusing Logging\n@test_logs (:info,) (:debug,\"Iteration 42\") min_level=Logging.Debug match_mode=:any foo(100)\n\nThe macro may be chained with @test to also test the returned value:\n\n@test (@test_logs (:info,\"Doing foo with n=2\") foo(2)) == 42\n\nIf you want to test for the absence of warnings, you can omit specifying log patterns and set the min_level accordingly:\n\n# test that the expression logs no messages when the logger level is warn:\n@test_logs min_level=Logging.Warn @info(\"Some information\") # passes\n@test_logs min_level=Logging.Warn @warn(\"Some information\") # fails\n\nIf you want to test the absence of warnings (or error messages) in stderr which are not generated by @warn, see @test_nowarn.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.TestLogger","page":"Unit Testing","title":"Test.TestLogger","text":"TestLogger(; min_level=Info, catch_exceptions=false)\n\nCreate a TestLogger which captures logged messages in its logs::Vector{LogRecord} field.\n\nSet min_level to control the LogLevel, catch_exceptions for whether or not exceptions thrown as part of log event generation should be caught, and respect_maxlog for whether or not to follow the convention of logging messages with maxlog=n for some integer n at most n times.\n\nSee also: LogRecord.\n\nExamples\n\njulia> using Test, Logging\n\njulia> f() = @info \"Hi\" number=5;\n\njulia> test_logger = TestLogger();\n\njulia> with_logger(test_logger) do\n f()\n @info \"Bye!\"\n end\n\njulia> @test test_logger.logs[1].message == \"Hi\"\nTest Passed\n\njulia> @test test_logger.logs[1].kwargs[:number] == 5\nTest Passed\n\njulia> @test test_logger.logs[2].message == \"Bye!\"\nTest Passed\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.LogRecord","page":"Unit Testing","title":"Test.LogRecord","text":"LogRecord\n\nStores the results of a single log event. Fields:\n\nlevel: the LogLevel of the log message\nmessage: the textual content of the log message\n_module: the module of the log event\ngroup: the logging group (by default, the name of the file containing the log event)\nid: the ID of the log event\nfile: the file containing the log event\nline: the line within the file of the log event\nkwargs: any keyword arguments passed to the log event\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Other-Test-Macros","page":"Unit Testing","title":"Other Test Macros","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"As calculations on floating-point values can be imprecise, you can perform approximate equality checks using either @test a ≈ b (where ≈, typed via tab completion of \\approx, is the isapprox function) or use isapprox directly.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test 1 ≈ 0.999999999\nTest Passed\n\njulia> @test 1 ≈ 0.999999\nTest Failed at none:1\n Expression: 1 ≈ 0.999999\n Evaluated: 1 ≈ 0.999999\n\nERROR: There was an error during testing","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"You can specify relative and absolute tolerances by setting the rtol and atol keyword arguments of isapprox, respectively, after the ≈ comparison:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test 1 ≈ 0.999999 rtol=1e-5\nTest Passed","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Note that this is not a specific feature of the ≈ but rather a general feature of the @test macro: @test a b key=val is transformed by the macro into @test op(a, b, key=val). It is, however, particularly useful for ≈ tests.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@inferred\nTest.@test_deprecated\nTest.@test_warn\nTest.@test_nowarn","category":"page"},{"location":"stdlib/Test/#Test.@inferred","page":"Unit Testing","title":"Test.@inferred","text":"@inferred [AllowedType] f(x)\n\nTests that the call expression f(x) returns a value of the same type inferred by the compiler. It is useful to check for type stability.\n\nf(x) can be any call expression. Returns the result of f(x) if the types match, and an Error Result if it finds different types.\n\nOptionally, AllowedType relaxes the test, by making it pass when either the type of f(x) matches the inferred type modulo AllowedType, or when the return type is a subtype of AllowedType. This is useful when testing type stability of functions returning a small union such as Union{Nothing, T} or Union{Missing, T}.\n\njulia> f(a) = a > 1 ? 1 : 1.0\nf (generic function with 1 method)\n\njulia> typeof(f(2))\nInt64\n\njulia> @code_warntype f(2)\nMethodInstance for f(::Int64)\n from f(a) @ Main none:1\nArguments\n #self#::Core.Const(f)\n a::Int64\nBody::UNION{FLOAT64, INT64}\n1 ─ %1 = (a > 1)::Bool\n└── goto #3 if not %1\n2 ─ return 1\n3 ─ return 1.0\n\njulia> @inferred f(2)\nERROR: return type Int64 does not match inferred return type Union{Float64, Int64}\n[...]\n\njulia> @inferred max(1, 2)\n2\n\njulia> g(a) = a < 10 ? missing : 1.0\ng (generic function with 1 method)\n\njulia> @inferred g(20)\nERROR: return type Float64 does not match inferred return type Union{Missing, Float64}\n[...]\n\njulia> @inferred Missing g(20)\n1.0\n\njulia> h(a) = a < 10 ? missing : f(a)\nh (generic function with 1 method)\n\njulia> @inferred Missing h(20)\nERROR: return type Int64 does not match inferred return type Union{Missing, Float64, Int64}\n[...]\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.@test_deprecated","page":"Unit Testing","title":"Test.@test_deprecated","text":"@test_deprecated [pattern] expression\n\nWhen --depwarn=yes, test that expression emits a deprecation warning and return the value of expression. The log message string will be matched against pattern which defaults to r\"deprecated\"i.\n\nWhen --depwarn=no, simply return the result of executing expression. When --depwarn=error, check that an ErrorException is thrown.\n\nExamples\n\n# Deprecated in julia 0.7\n@test_deprecated num2hex(1)\n\n# The returned value can be tested by chaining with @test:\n@test (@test_deprecated num2hex(1)) == \"0000000000000001\"\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.@test_warn","page":"Unit Testing","title":"Test.@test_warn","text":"@test_warn msg expr\n\nTest whether evaluating expr results in stderr output that contains the msg string or matches the msg regular expression. If msg is a boolean function, tests whether msg(output) returns true. If msg is a tuple or array, checks that the error output contains/matches each item in msg. Returns the result of evaluating expr.\n\nSee also @test_nowarn to check for the absence of error output.\n\nNote: Warnings generated by @warn cannot be tested with this macro. Use @test_logs instead.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.@test_nowarn","page":"Unit Testing","title":"Test.@test_nowarn","text":"@test_nowarn expr\n\nTest whether evaluating expr results in empty stderr output (no warnings or other messages). Returns the result of evaluating expr.\n\nNote: The absence of warnings generated by @warn cannot be tested with this macro. Use @test_logs instead.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Broken-Tests","page":"Unit Testing","title":"Broken Tests","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If a test fails consistently it can be changed to use the @test_broken macro. This will denote the test as Broken if the test continues to fail and alerts the user via an Error if the test succeeds.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@test_broken","category":"page"},{"location":"stdlib/Test/#Test.@test_broken","page":"Unit Testing","title":"Test.@test_broken","text":"@test_broken ex\n@test_broken f(args...) key=val ...\n\nIndicates a test that should pass but currently consistently fails. Tests that the expression ex evaluates to false or causes an exception. Returns a Broken Result if it does, or an Error Result if the expression evaluates to true. This is equivalent to @test ex broken=true.\n\nThe @test_broken f(args...) key=val... form works as for the @test macro.\n\nExamples\n\njulia> @test_broken 1 == 2\nTest Broken\n Expression: 1 == 2\n\njulia> @test_broken 1 == 2 atol=0.1\nTest Broken\n Expression: ==(1, 2, atol = 0.1)\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"@test_skip is also available to skip a test without evaluation, but counting the skipped test in the test set reporting. The test will not run but gives a Broken Result.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@test_skip","category":"page"},{"location":"stdlib/Test/#Test.@test_skip","page":"Unit Testing","title":"Test.@test_skip","text":"@test_skip ex\n@test_skip f(args...) key=val ...\n\nMarks a test that should not be executed but should be included in test summary reporting as Broken. This can be useful for tests that intermittently fail, or tests of not-yet-implemented functionality. This is equivalent to @test ex skip=true.\n\nThe @test_skip f(args...) key=val... form works as for the @test macro.\n\nExamples\n\njulia> @test_skip 1 == 2\nTest Broken\n Skipped: 1 == 2\n\njulia> @test_skip 1 == 2 atol=0.1\nTest Broken\n Skipped: ==(1, 2, atol = 0.1)\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test-result-types","page":"Unit Testing","title":"Test result types","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.Result\nTest.Pass\nTest.Fail\nTest.Error\nTest.Broken","category":"page"},{"location":"stdlib/Test/#Test.Result","page":"Unit Testing","title":"Test.Result","text":"Test.Result\n\nAll tests produce a result object. This object may or may not be stored, depending on whether the test is part of a test set.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.Pass","page":"Unit Testing","title":"Test.Pass","text":"Test.Pass <: Test.Result\n\nThe test condition was true, i.e. the expression evaluated to true or the correct exception was thrown.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.Fail","page":"Unit Testing","title":"Test.Fail","text":"Test.Fail <: Test.Result\n\nThe test condition was false, i.e. the expression evaluated to false or the correct exception was not thrown.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.Error","page":"Unit Testing","title":"Test.Error","text":"Test.Error <: Test.Result\n\nThe test condition couldn't be evaluated due to an exception, or it evaluated to something other than a Bool. In the case of @test_broken it is used to indicate that an unexpected Pass Result occurred.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.Broken","page":"Unit Testing","title":"Test.Broken","text":"Test.Broken <: Test.Result\n\nThe test condition is the expected (failed) result of a broken test, or was explicitly skipped with @test_skip.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Creating-Custom-AbstractTestSet-Types","page":"Unit Testing","title":"Creating Custom AbstractTestSet Types","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Packages can create their own AbstractTestSet subtypes by implementing the record and finish methods. The subtype should have a one-argument constructor taking a description string, with any options passed in as keyword arguments.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.record\nTest.finish","category":"page"},{"location":"stdlib/Test/#Test.record","page":"Unit Testing","title":"Test.record","text":"record(ts::AbstractTestSet, res::Result)\n\nRecord a result to a testset. This function is called by the @testset infrastructure each time a contained @test macro completes, and is given the test result (which could be an Error). This will also be called with an Error if an exception is thrown inside the test block but outside of a @test context.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.finish","page":"Unit Testing","title":"Test.finish","text":"finish(ts::AbstractTestSet)\n\nDo any final processing necessary for the given testset. This is called by the @testset infrastructure after a test block executes.\n\nCustom AbstractTestSet subtypes should call record on their parent (if there is one) to add themselves to the tree of test results. This might be implemented as:\n\nif get_testset_depth() != 0\n # Attach this test set to the parent test set\n parent_ts = get_testset()\n record(parent_ts, self)\n return self\nend\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test takes responsibility for maintaining a stack of nested testsets as they are executed, but any result accumulation is the responsibility of the AbstractTestSet subtype. You can access this stack with the get_testset and get_testset_depth methods. Note that these functions are not exported.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.get_testset\nTest.get_testset_depth","category":"page"},{"location":"stdlib/Test/#Test.get_testset","page":"Unit Testing","title":"Test.get_testset","text":"get_testset()\n\nRetrieve the active test set from the task's local storage. If no test set is active, use the fallback default test set.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.get_testset_depth","page":"Unit Testing","title":"Test.get_testset_depth","text":"get_testset_depth()\n\nReturn the number of active test sets, not including the default test set\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test also makes sure that nested @testset invocations use the same AbstractTestSet subtype as their parent unless it is set explicitly. It does not propagate any properties of the testset. Option inheritance behavior can be implemented by packages using the stack infrastructure that Test provides.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Defining a basic AbstractTestSet subtype might look like:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"import Test: Test, record, finish\nusing Test: AbstractTestSet, Result, Pass, Fail, Error\nusing Test: get_testset_depth, get_testset\nstruct CustomTestSet <: Test.AbstractTestSet\n description::AbstractString\n foo::Int\n results::Vector\n # constructor takes a description string and options keyword arguments\n CustomTestSet(desc; foo=1) = new(desc, foo, [])\nend\n\nrecord(ts::CustomTestSet, child::AbstractTestSet) = push!(ts.results, child)\nrecord(ts::CustomTestSet, res::Result) = push!(ts.results, res)\nfunction finish(ts::CustomTestSet)\n # just record if we're not the top-level parent\n if get_testset_depth() > 0\n record(get_testset(), ts)\n return ts\n end\n\n # so the results are printed if we are at the top level\n Test.print_test_results(ts)\n return ts\nend","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"And using that testset looks like:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"@testset CustomTestSet foo=4 \"custom testset inner 2\" begin\n # this testset should inherit the type, but not the argument.\n @testset \"custom testset inner\" begin\n @test true\n end\nend","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"In order to use a custom testset and have the recorded results printed as part of any outer default testset, also define Test.get_test_counts. This might look like so:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"using Test: AbstractTestSet, Pass, Fail, Error, Broken, get_test_counts, TestCounts, format_duration\n\nfunction Test.get_test_counts(ts::CustomTestSet)\n passes, fails, errors, broken = 0, 0, 0, 0\n # cumulative results\n c_passes, c_fails, c_errors, c_broken = 0, 0, 0, 0\n\n for t in ts.results\n # count up results\n isa(t, Pass) && (passes += 1)\n isa(t, Fail) && (fails += 1)\n isa(t, Error) && (errors += 1)\n isa(t, Broken) && (broken += 1)\n # handle children\n if isa(t, AbstractTestSet)\n tc = get_test_counts(t)::TestCounts\n c_passes += tc.passes + tc.cumulative_passes\n c_fails += tc.fails + tc.cumulative_fails\n c_errors += tc.errors + tc.cumulative_errors\n c_broken += tc.broken + tc.cumulative_broken\n end\n end\n # get a duration, if we have one\n duration = format_duration(ts)\n return TestCounts(true, passes, fails, errors, broken, c_passes, c_fails, c_errors, c_broken, duration)\nend","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.TestCounts\nTest.get_test_counts\nTest.format_duration\nTest.print_test_results","category":"page"},{"location":"stdlib/Test/#Test.TestCounts","page":"Unit Testing","title":"Test.TestCounts","text":"TestCounts\n\nHolds the state for recursively gathering the results of a test set for display purposes.\n\nFields:\n\ncustomized: Whether the function get_test_counts was customized for the AbstractTestSet this counts object is for. If a custom method was defined, always pass true to the constructor.\npasses: The number of passing @test invocations.\nfails: The number of failing @test invocations.\nerrors: The number of erroring @test invocations.\nbroken: The number of broken @test invocations.\npasses: The cumulative number of passing @test invocations.\nfails: The cumulative number of failing @test invocations.\nerrors: The cumulative number of erroring @test invocations.\nbroken: The cumulative number of broken @test invocations.\nduration: The total duration the AbstractTestSet in question ran for, as a formatted String.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.get_test_counts","page":"Unit Testing","title":"Test.get_test_counts","text":"\" gettestcounts(::AbstractTestSet) -> TestCounts\n\nRecursive function that counts the number of test results of each type directly in the testset, and totals across the child testsets.\n\nCustom AbstractTestSet should implement this function to get their totals counted & displayed with DefaultTestSet as well.\n\nIf this is not implemented for a custom TestSet, the printing falls back to reporting x for failures and ?s for the duration.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.format_duration","page":"Unit Testing","title":"Test.format_duration","text":"format_duration(::AbstractTestSet)\n\nReturn a formatted string for printing the duration the testset ran for.\n\nIf not defined, falls back to \"?s\".\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.print_test_results","page":"Unit Testing","title":"Test.print_test_results","text":"print_test_results(ts::AbstractTestSet, depth_pad=0)\n\nPrint the results of an AbstractTestSet as a formatted table.\n\ndepth_pad refers to how much padding should be added in front of all output.\n\nCalled inside of Test.finish, if the finished testset is the topmost testset.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test-utilities","page":"Unit Testing","title":"Test utilities","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.GenericArray\nTest.GenericDict\nTest.GenericOrder\nTest.GenericSet\nTest.GenericString\nTest.detect_ambiguities\nTest.detect_unbound_args","category":"page"},{"location":"stdlib/Test/#Test.GenericArray","page":"Unit Testing","title":"Test.GenericArray","text":"The GenericArray can be used to test generic array APIs that program to the AbstractArray interface, in order to ensure that functions can work with array types besides the standard Array type.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.GenericDict","page":"Unit Testing","title":"Test.GenericDict","text":"The GenericDict can be used to test generic dict APIs that program to the AbstractDict interface, in order to ensure that functions can work with associative types besides the standard Dict type.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.GenericOrder","page":"Unit Testing","title":"Test.GenericOrder","text":"The GenericOrder can be used to test APIs for their support of generic ordered types.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.GenericSet","page":"Unit Testing","title":"Test.GenericSet","text":"The GenericSet can be used to test generic set APIs that program to the AbstractSet interface, in order to ensure that functions can work with set types besides the standard Set and BitSet types.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.GenericString","page":"Unit Testing","title":"Test.GenericString","text":"The GenericString can be used to test generic string APIs that program to the AbstractString interface, in order to ensure that functions can work with string types besides the standard String type.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.detect_ambiguities","page":"Unit Testing","title":"Test.detect_ambiguities","text":"detect_ambiguities(mod1, mod2...; recursive=false,\n ambiguous_bottom=false,\n allowed_undefineds=nothing)\n\nReturn a vector of (Method,Method) pairs of ambiguous methods defined in the specified modules. Use recursive=true to test in all submodules.\n\nambiguous_bottom controls whether ambiguities triggered only by Union{} type parameters are included; in most cases you probably want to set this to false. See Base.isambiguous.\n\nSee Test.detect_unbound_args for an explanation of allowed_undefineds.\n\ncompat: Julia 1.8\nallowed_undefineds requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.detect_unbound_args","page":"Unit Testing","title":"Test.detect_unbound_args","text":"detect_unbound_args(mod1, mod2...; recursive=false, allowed_undefineds=nothing)\n\nReturn a vector of Methods which may have unbound type parameters. Use recursive=true to test in all submodules.\n\nBy default, any undefined symbols trigger a warning. This warning can be suppressed by supplying a collection of GlobalRefs for which the warning can be skipped. For example, setting\n\nallowed_undefineds = Set([GlobalRef(Base, :active_repl),\n GlobalRef(Base, :active_repl_backend)])\n\nwould suppress warnings about Base.active_repl and Base.active_repl_backend.\n\ncompat: Julia 1.8\nallowed_undefineds requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Workflow-for-Testing-Packages","page":"Unit Testing","title":"Workflow for Testing Packages","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Using the tools available to us in the previous sections, here is a potential workflow of creating a package and adding tests to it.","category":"page"},{"location":"stdlib/Test/#Generating-an-Example-Package","page":"Unit Testing","title":"Generating an Example Package","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"For this workflow, we will create a package called Example:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"pkg> generate Example\nshell> cd Example\nshell> mkdir test\npkg> activate .","category":"page"},{"location":"stdlib/Test/#Creating-Sample-Functions","page":"Unit Testing","title":"Creating Sample Functions","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"The number one requirement for testing a package is to have functionality to test. For that, we will add some simple functions to Example that we can test. Add the following to src/Example.jl:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"module Example\n\nfunction greet()\n \"Hello world!\"\nend\n\nfunction simple_add(a, b)\n a + b\nend\n\nfunction type_multiply(a::Float64, b::Float64)\n a * b\nend\n\nexport greet, simple_add, type_multiply\n\nend","category":"page"},{"location":"stdlib/Test/#Creating-a-Test-Environment","page":"Unit Testing","title":"Creating a Test Environment","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"From within the root of the Example package, navigate to the test directory, activate a new environment there, and add the Test package to the environment:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"shell> cd test\npkg> activate .\n(test) pkg> add Test","category":"page"},{"location":"stdlib/Test/#Testing-Our-Package","page":"Unit Testing","title":"Testing Our Package","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Now, we are ready to add tests to Example. It is standard practice to create a file within the test directory called runtests.jl which contains the test sets we want to run. Go ahead and create that file within the test directory and add the following code to it:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"using Example\nusing Test\n\n@testset \"Example tests\" begin\n\n @testset \"Math tests\" begin\n include(\"math_tests.jl\")\n end\n\n @testset \"Greeting tests\" begin\n include(\"greeting_tests.jl\")\n end\nend","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"We will need to create those two included files, math_tests.jl and greeting_tests.jl, and add some tests to them.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Note: Notice how we did not have to specify add Example into the test environment's Project.toml. This is a benefit of Julia's testing system that you could read about more here.","category":"page"},{"location":"stdlib/Test/#Writing-Tests-for-math_tests.jl","page":"Unit Testing","title":"Writing Tests for math_tests.jl","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Using our knowledge of Test.jl, here are some example tests we could add to math_tests.jl:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"@testset \"Testset 1\" begin\n @test 2 == simple_add(1, 1)\n @test 3.5 == simple_add(1, 2.5)\n @test_throws MethodError simple_add(1, \"A\")\n @test_throws MethodError simple_add(1, 2, 3)\nend\n\n@testset \"Testset 2\" begin\n @test 1.0 == type_multiply(1.0, 1.0)\n @test isa(type_multiply(2.0, 2.0), Float64)\n @test_throws MethodError type_multiply(1, 2.5)\nend","category":"page"},{"location":"stdlib/Test/#Writing-Tests-for-greeting_tests.jl","page":"Unit Testing","title":"Writing Tests for greeting_tests.jl","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Using our knowledge of Test.jl, here are some example tests we could add to greeting_tests.jl:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"@testset \"Testset 3\" begin\n @test \"Hello world!\" == greet()\n @test_throws MethodError greet(\"Antonia\")\nend","category":"page"},{"location":"stdlib/Test/#Testing-Our-Package-2","page":"Unit Testing","title":"Testing Our Package","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Now that we have added our tests and our runtests.jl script in test, we can test our Example package by going back to the root of the Example package environment and reactivating the Example environment:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"shell> cd ..\npkg> activate .","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"From there, we can finally run our test suite as follows:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"(Example) pkg> test\n Testing Example\n Status `/tmp/jl_Yngpvy/Project.toml`\n [fa318bd2] Example v0.1.0 `/home/src/Projects/tmp/errata/Example`\n [8dfed614] Test `@stdlib/Test`\n Status `/tmp/jl_Yngpvy/Manifest.toml`\n [fa318bd2] Example v0.1.0 `/home/src/Projects/tmp/errata/Example`\n [2a0f44e3] Base64 `@stdlib/Base64`\n [b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`\n [56ddb016] Logging `@stdlib/Logging`\n [d6f4376e] Markdown `@stdlib/Markdown`\n [9a3f8284] Random `@stdlib/Random`\n [ea8e919c] SHA `@stdlib/SHA`\n [9e88b42a] Serialization `@stdlib/Serialization`\n [8dfed614] Test `@stdlib/Test`\n Testing Running tests...\nTest Summary: | Pass Total\nExample tests | 9 9\n Testing Example tests passed","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"And if all went correctly, you should see a similar output as above. Using Test.jl, more complicated tests can be added for packages but this should ideally point developers in the direction of how to get started with testing their own created packages.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/Test/#Code-Coverage","page":"Unit Testing","title":"Code Coverage","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Code coverage tracking during tests can be enabled using the pkg> test --coverage flag (or at a lower level using the --code-coverage julia arg). This is on by default in the julia-runtest GitHub action.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"To evaluate coverage either manually inspect the .cov files that are generated beside the source files locally, or in CI use the julia-processcoverage GitHub action.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"compat: Julia 1.11\nSince Julia 1.11, coverage is not collected during the package precompilation phase.","category":"page"},{"location":"manual/interfaces/#Interfaces","page":"Interfaces","title":"Interfaces","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"A lot of the power and extensibility in Julia comes from a collection of informal interfaces. By extending a few specific methods to work for a custom type, objects of that type not only receive those functionalities, but they are also able to be used in other methods that are written to generically build upon those behaviors.","category":"page"},{"location":"manual/interfaces/#man-interface-iteration","page":"Interfaces","title":"Iteration","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"There are two methods that are always required:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Required method Brief description\niterate(iter) Returns either a tuple of the first item and initial state or nothing if empty\niterate(iter, state) Returns either a tuple of the next item and next state or nothing if no items remain","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"There are several more methods that should be defined in some circumstances. Please note that you should always define at least one of Base.IteratorSize(IterType) and length(iter) because the default definition of Base.IteratorSize(IterType) is Base.HasLength().","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Method When should this method be defined? Default definition Brief description\nBase.IteratorSize(IterType) If default is not appropriate Base.HasLength() One of Base.HasLength(), Base.HasShape{N}(), Base.IsInfinite(), or Base.SizeUnknown() as appropriate\nlength(iter) If Base.IteratorSize() returns Base.HasLength() or Base.HasShape{N}() (undefined) The number of items, if known\nsize(iter, [dim]) If Base.IteratorSize() returns Base.HasShape{N}() (undefined) The number of items in each dimension, if known\nBase.IteratorEltype(IterType) If default is not appropriate Base.HasEltype() Either Base.EltypeUnknown() or Base.HasEltype() as appropriate\neltype(IterType) If default is not appropriate Any The type of the first entry of the tuple returned by iterate()\nBase.isdone(iter, [state]) Must be defined if iterator is stateful missing Fast-path hint for iterator completion. If not defined for a stateful iterator then functions that check for done-ness, like isempty() and zip(), may mutate the iterator and cause buggy behaviour!","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Sequential iteration is implemented by the iterate function. Instead of mutating objects as they are iterated over, Julia iterators may keep track of the iteration state externally from the object. The return value from iterate is always either a tuple of a value and a state, or nothing if no elements remain. The state object will be passed back to the iterate function on the next iteration and is generally considered an implementation detail private to the iterable object.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Any object that defines this function is iterable and can be used in the many functions that rely upon iteration. It can also be used directly in a for loop since the syntax:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"for item in iter # or \"for item = iter\"\n # body\nend","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"is translated into:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"next = iterate(iter)\nwhile next !== nothing\n (item, state) = next\n # body\n next = iterate(iter, state)\nend","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"A simple example is an iterable sequence of square numbers with a defined length:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> struct Squares\n count::Int\n end\n\njulia> Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"With only iterate definition, the Squares type is already pretty powerful. We can iterate over all the elements:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> for item in Squares(7)\n println(item)\n end\n1\n4\n9\n16\n25\n36\n49","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"We can use many of the builtin methods that work with iterables, like in or sum:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> 25 in Squares(10)\ntrue\n\njulia> sum(Squares(100))\n338350","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"There are a few more methods we can extend to give Julia more information about this iterable collection. We know that the elements in a Squares sequence will always be Int. By extending the eltype method, we can give that information to Julia and help it make more specialized code in the more complicated methods. We also know the number of elements in our sequence, so we can extend length, too:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type\n\njulia> Base.length(S::Squares) = S.count","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Now, when we ask Julia to collect all the elements into an array it can preallocate a Vector{Int} of the right size instead of naively push!ing each element into a Vector{Any}:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> collect(Squares(4))\n4-element Vector{Int64}:\n 1\n 4\n 9\n 16","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"While we can rely upon generic implementations, we can also extend specific methods where we know there is a simpler algorithm. For example, there's a formula to compute the sum of squares, so we can override the generic iterative version with a more performant solution:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.sum(S::Squares) = (n = S.count; return n*(n+1)*(2n+1)÷6)\n\njulia> sum(Squares(1803))\n1955361914","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"This is a very common pattern throughout Julia Base: a small set of required methods define an informal interface that enable many fancier behaviors. In some cases, types will want to additionally specialize those extra behaviors when they know a more efficient algorithm can be used in their specific case.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"It is also often useful to allow iteration over a collection in reverse order by iterating over Iterators.reverse(iterator). To actually support reverse-order iteration, however, an iterator type T needs to implement iterate for Iterators.Reverse{T}. (Given r::Iterators.Reverse{T}, the underling iterator of type T is r.itr.) In our Squares example, we would implement Iterators.Reverse{Squares} methods:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.iterate(rS::Iterators.Reverse{Squares}, state=rS.itr.count) = state < 1 ? nothing : (state*state, state-1)\n\njulia> collect(Iterators.reverse(Squares(4)))\n4-element Vector{Int64}:\n 16\n 9\n 4\n 1","category":"page"},{"location":"manual/interfaces/#Indexing","page":"Interfaces","title":"Indexing","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Brief description\ngetindex(X, i) X[i], indexed access, non-scalar i should allocate a copy\nsetindex!(X, v, i) X[i] = v, indexed assignment\nfirstindex(X) The first index, used in X[begin]\nlastindex(X) The last index, used in X[end]","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For the Squares iterable above, we can easily compute the ith element of the sequence by squaring it. We can expose this as an indexing expression S[i]. To opt into this behavior, Squares simply needs to define getindex:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> function Base.getindex(S::Squares, i::Int)\n 1 <= i <= S.count || throw(BoundsError(S, i))\n return i*i\n end\n\njulia> Squares(100)[23]\n529","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Additionally, to support the syntax S[begin] and S[end], we must define firstindex and lastindex to specify the first and last valid indices, respectively:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.firstindex(S::Squares) = 1\n\njulia> Base.lastindex(S::Squares) = length(S)\n\njulia> Squares(23)[end]\n529","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For multi-dimensional begin/end indexing as in a[3, begin, 7], for example, you should define firstindex(a, dim) and lastindex(a, dim) (which default to calling first and last on axes(a, dim), respectively).","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Note, though, that the above only defines getindex with one integer index. Indexing with anything other than an Int will throw a MethodError saying that there was no matching method. In order to support indexing with ranges or vectors of Ints, separate methods must be written:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.getindex(S::Squares, i::Number) = S[convert(Int, i)]\n\njulia> Base.getindex(S::Squares, I) = [S[i] for i in I]\n\njulia> Squares(10)[[3,4.,5]]\n3-element Vector{Int64}:\n 9\n 16\n 25","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"While this is starting to support more of the indexing operations supported by some of the builtin types, there's still quite a number of behaviors missing. This Squares sequence is starting to look more and more like a vector as we've added behaviors to it. Instead of defining all these behaviors ourselves, we can officially define it as a subtype of an AbstractArray.","category":"page"},{"location":"manual/interfaces/#man-interface-array","page":"Interfaces","title":"Abstract Arrays","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Brief description\nsize(A) Returns a tuple containing the dimensions of A\ngetindex(A, i::Int) (if IndexLinear) Linear scalar indexing\ngetindex(A, I::Vararg{Int, N}) (if IndexCartesian, where N = ndims(A)) N-dimensional scalar indexing\nOptional methods Default definition Brief description\nIndexStyle(::Type) IndexCartesian() Returns either IndexLinear() or IndexCartesian(). See the description below.\nsetindex!(A, v, i::Int) (if IndexLinear) Scalar indexed assignment\nsetindex!(A, v, I::Vararg{Int, N}) (if IndexCartesian, where N = ndims(A)) N-dimensional scalar indexed assignment\ngetindex(A, I...) defined in terms of scalar getindex Multidimensional and nonscalar indexing\nsetindex!(A, X, I...) defined in terms of scalar setindex! Multidimensional and nonscalar indexed assignment\niterate defined in terms of scalar getindex Iteration\nlength(A) prod(size(A)) Number of elements\nsimilar(A) similar(A, eltype(A), size(A)) Return a mutable array with the same shape and element type\nsimilar(A, ::Type{S}) similar(A, S, size(A)) Return a mutable array with the same shape and the specified element type\nsimilar(A, dims::Dims) similar(A, eltype(A), dims) Return a mutable array with the same element type and size dims\nsimilar(A, ::Type{S}, dims::Dims) Array{S}(undef, dims) Return a mutable array with the specified element type and size\nNon-traditional indices Default definition Brief description\naxes(A) map(OneTo, size(A)) Return a tuple of AbstractUnitRange{<:Integer} of valid indices. The axes should be their own axes, that is axes.(axes(A),1) == axes(A) should be satisfied.\nsimilar(A, ::Type{S}, inds) similar(A, S, Base.to_shape(inds)) Return a mutable array with the specified indices inds (see below)\nsimilar(T::Union{Type,Function}, inds) T(Base.to_shape(inds)) Return an array similar to T with the specified indices inds (see below)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If a type is defined as a subtype of AbstractArray, it inherits a very large set of rich behaviors including iteration and multidimensional indexing built on top of single-element access. See the arrays manual page and the Julia Base section for more supported methods.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"A key part in defining an AbstractArray subtype is IndexStyle. Since indexing is such an important part of an array and often occurs in hot loops, it's important to make both indexing and indexed assignment as efficient as possible. Array data structures are typically defined in one of two ways: either it most efficiently accesses its elements using just one index (linear indexing) or it intrinsically accesses the elements with indices specified for every dimension. These two modalities are identified by Julia as IndexLinear() and IndexCartesian(). Converting a linear index to multiple indexing subscripts is typically very expensive, so this provides a traits-based mechanism to enable efficient generic code for all array types.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"This distinction determines which scalar indexing methods the type must define. IndexLinear() arrays are simple: just define getindex(A::ArrayType, i::Int). When the array is subsequently indexed with a multidimensional set of indices, the fallback getindex(A::AbstractArray, I...) efficiently converts the indices into one linear index and then calls the above method. IndexCartesian() arrays, on the other hand, require methods to be defined for each supported dimensionality with ndims(A) Int indices. For example, SparseMatrixCSC from the SparseArrays standard library module, only supports two dimensions, so it just defines getindex(A::SparseMatrixCSC, i::Int, j::Int). The same holds for setindex!.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Returning to the sequence of squares from above, we could instead define it as a subtype of an AbstractArray{Int, 1}:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> struct SquaresVector <: AbstractArray{Int, 1}\n count::Int\n end\n\njulia> Base.size(S::SquaresVector) = (S.count,)\n\njulia> Base.IndexStyle(::Type{<:SquaresVector}) = IndexLinear()\n\njulia> Base.getindex(S::SquaresVector, i::Int) = i*i","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Note that it's very important to specify the two parameters of the AbstractArray; the first defines the eltype, and the second defines the ndims. That supertype and those three methods are all it takes for SquaresVector to be an iterable, indexable, and completely functional array:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> s = SquaresVector(4)\n4-element SquaresVector:\n 1\n 4\n 9\n 16\n\njulia> s[s .> 8]\n2-element Vector{Int64}:\n 9\n 16\n\njulia> s + s\n4-element Vector{Int64}:\n 2\n 8\n 18\n 32\n\njulia> sin.(s)\n4-element Vector{Float64}:\n 0.8414709848078965\n -0.7568024953079282\n 0.4121184852417566\n -0.2879033166650653","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"As a more complicated example, let's define our own toy N-dimensional sparse-like array type built on top of Dict:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> struct SparseArray{T,N} <: AbstractArray{T,N}\n data::Dict{NTuple{N,Int}, T}\n dims::NTuple{N,Int}\n end\n\njulia> SparseArray(::Type{T}, dims::Int...) where {T} = SparseArray(T, dims);\n\njulia> SparseArray(::Type{T}, dims::NTuple{N,Int}) where {T,N} = SparseArray{T,N}(Dict{NTuple{N,Int}, T}(), dims);\n\njulia> Base.size(A::SparseArray) = A.dims\n\njulia> Base.similar(A::SparseArray, ::Type{T}, dims::Dims) where {T} = SparseArray(T, dims)\n\njulia> Base.getindex(A::SparseArray{T,N}, I::Vararg{Int,N}) where {T,N} = get(A.data, I, zero(T))\n\njulia> Base.setindex!(A::SparseArray{T,N}, v, I::Vararg{Int,N}) where {T,N} = (A.data[I] = v)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Notice that this is an IndexCartesian array, so we must manually define getindex and setindex! at the dimensionality of the array. Unlike the SquaresVector, we are able to define setindex!, and so we can mutate the array:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> A = SparseArray(Float64, 3, 3)\n3×3 SparseArray{Float64, 2}:\n 0.0 0.0 0.0\n 0.0 0.0 0.0\n 0.0 0.0 0.0\n\njulia> fill!(A, 2)\n3×3 SparseArray{Float64, 2}:\n 2.0 2.0 2.0\n 2.0 2.0 2.0\n 2.0 2.0 2.0\n\njulia> A[:] = 1:length(A); A\n3×3 SparseArray{Float64, 2}:\n 1.0 4.0 7.0\n 2.0 5.0 8.0\n 3.0 6.0 9.0","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The result of indexing an AbstractArray can itself be an array (for instance when indexing by an AbstractRange). The AbstractArray fallback methods use similar to allocate an Array of the appropriate size and element type, which is filled in using the basic indexing method described above. However, when implementing an array wrapper you often want the result to be wrapped as well:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> A[1:2,:]\n2×3 SparseArray{Float64, 2}:\n 1.0 4.0 7.0\n 2.0 5.0 8.0","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In this example it is accomplished by defining Base.similar(A::SparseArray, ::Type{T}, dims::Dims) where T to create the appropriate wrapped array. (Note that while similar supports 1- and 2-argument forms, in most case you only need to specialize the 3-argument form.) For this to work it's important that SparseArray is mutable (supports setindex!). Defining similar, getindex and setindex! for SparseArray also makes it possible to copy the array:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> copy(A)\n3×3 SparseArray{Float64, 2}:\n 1.0 4.0 7.0\n 2.0 5.0 8.0\n 3.0 6.0 9.0","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In addition to all the iterable and indexable methods from above, these types can also interact with each other and use most of the methods defined in Julia Base for AbstractArrays:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> A[SquaresVector(3)]\n3-element SparseArray{Float64, 1}:\n 1.0\n 4.0\n 9.0\n\njulia> sum(A)\n45.0","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If you are defining an array type that allows non-traditional indexing (indices that start at something other than 1), you should specialize axes. You should also specialize similar so that the dims argument (ordinarily a Dims size-tuple) can accept AbstractUnitRange objects, perhaps range-types Ind of your own design. For more information, see Arrays with custom indices.","category":"page"},{"location":"manual/interfaces/#man-interface-strided-arrays","page":"Interfaces","title":"Strided Arrays","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Brief description\nstrides(A) Return the distance in memory (in number of elements) between adjacent elements in each dimension as a tuple. If A is an AbstractArray{T,0}, this should return an empty tuple.\nBase.unsafe_convert(::Type{Ptr{T}}, A) Return the native address of an array.\nBase.elsize(::Type{<:A}) Return the stride between consecutive elements in the array.\nOptional methods Default definition Brief description\nstride(A, i::Int) strides(A)[i] Return the distance in memory (in number of elements) between adjacent elements in dimension k.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"A strided array is a subtype of AbstractArray whose entries are stored in memory with fixed strides. Provided the element type of the array is compatible with BLAS, a strided array can utilize BLAS and LAPACK routines for more efficient linear algebra routines. A typical example of a user-defined strided array is one that wraps a standard Array with additional structure.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Warning: do not implement these methods if the underlying storage is not actually strided, as it may lead to incorrect results or segmentation faults.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Here are some examples to demonstrate which type of arrays are strided and which are not:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"1:5 # not strided (there is no storage associated with this array.)\nVector(1:5) # is strided with strides (1,)\nA = [1 5; 2 6; 3 7; 4 8] # is strided with strides (1,4)\nV = view(A, 1:2, :) # is strided with strides (1,4)\nV = view(A, 1:2:3, 1:2) # is strided with strides (2,4)\nV = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not fixed.","category":"page"},{"location":"manual/interfaces/#man-interfaces-broadcasting","page":"Interfaces","title":"Customizing broadcasting","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Brief description\nBase.BroadcastStyle(::Type{SrcType}) = SrcStyle() Broadcasting behavior of SrcType\nBase.similar(bc::Broadcasted{DestStyle}, ::Type{ElType}) Allocation of output container\nOptional methods \nBase.BroadcastStyle(::Style1, ::Style2) = Style12() Precedence rules for mixing styles\nBase.axes(x) Declaration of the indices of x, as per axes(x).\nBase.broadcastable(x) Convert x to an object that has axes and supports indexing\nBypassing default machinery \nBase.copy(bc::Broadcasted{DestStyle}) Custom implementation of broadcast\nBase.copyto!(dest, bc::Broadcasted{DestStyle}) Custom implementation of broadcast!, specializing on DestStyle\nBase.copyto!(dest::DestType, bc::Broadcasted{Nothing}) Custom implementation of broadcast!, specializing on DestType\nBase.Broadcast.broadcasted(f, args...) Override the default lazy behavior within a fused expression\nBase.Broadcast.instantiate(bc::Broadcasted{DestStyle}) Override the computation of the lazy broadcast's axes","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Broadcasting is triggered by an explicit call to broadcast or broadcast!, or implicitly by \"dot\" operations like A .+ b or f.(x, y). Any object that has axes and supports indexing can participate as an argument in broadcasting, and by default the result is stored in an Array. This basic framework is extensible in three major ways:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Ensuring that all arguments support broadcast\nSelecting an appropriate output array for the given set of arguments\nSelecting an efficient implementation for the given set of arguments","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Not all types support axes and indexing, but many are convenient to allow in broadcast. The Base.broadcastable function is called on each argument to broadcast, allowing it to return something different that supports axes and indexing. By default, this is the identity function for all AbstractArrays and Numbers — they already support axes and indexing.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If a type is intended to act like a \"0-dimensional scalar\" (a single object) rather than as a container for broadcasting, then the following method should be defined:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.broadcastable(o::MyType) = Ref(o)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"that returns the argument wrapped in a 0-dimensional Ref container. For example, such a wrapper method is defined for types themselves, functions, special singletons like missing and nothing, and dates.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Custom array-like types can specialize Base.broadcastable to define their shape, but they should follow the convention that collect(Base.broadcastable(x)) == collect(x). A notable exception is AbstractString; strings are special-cased to behave as scalars for the purposes of broadcast even though they are iterable collections of their characters (see Strings for more).","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The next two steps (selecting the output array and implementation) are dependent upon determining a single answer for a given set of arguments. Broadcast must take all the varied types of its arguments and collapse them down to just one output array and one implementation. Broadcast calls this single answer a \"style\". Every broadcastable object each has its own preferred style, and a promotion-like system is used to combine these styles into a single answer — the \"destination style\".","category":"page"},{"location":"manual/interfaces/#Broadcast-Styles","page":"Interfaces","title":"Broadcast Styles","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle is the abstract type from which all broadcast styles are derived. When used as a function it has two possible forms, unary (single-argument) and binary. The unary variant states that you intend to implement specific broadcasting behavior and/or output type, and do not wish to rely on the default fallback Broadcast.DefaultArrayStyle.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"To override these defaults, you can define a custom BroadcastStyle for your object:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"struct MyStyle <: Broadcast.BroadcastStyle end\nBase.BroadcastStyle(::Type{<:MyType}) = MyStyle()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In some cases it might be convenient not to have to define MyStyle, in which case you can leverage one of the general broadcast wrappers:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle(::Type{<:MyType}) = Broadcast.Style{MyType}() can be used for arbitrary types.\nBase.BroadcastStyle(::Type{<:MyType}) = Broadcast.ArrayStyle{MyType}() is preferred if MyType is an AbstractArray.\nFor AbstractArrays that only support a certain dimensionality, create a subtype of Broadcast.AbstractArrayStyle{N} (see below).","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"When your broadcast operation involves several arguments, individual argument styles get combined to determine a single DestStyle that controls the type of the output container. For more details, see below.","category":"page"},{"location":"manual/interfaces/#Selecting-an-appropriate-output-array","page":"Interfaces","title":"Selecting an appropriate output array","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The broadcast style is computed for every broadcasting operation to allow for dispatch and specialization. The actual allocation of the result array is handled by similar, using the Broadcasted object as its first argument.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType})","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The fallback definition is","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"similar(bc::Broadcasted{DefaultArrayStyle{N}}, ::Type{ElType}) where {N,ElType} =\n similar(Array{ElType}, axes(bc))","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"However, if needed you can specialize on any or all of these arguments. The final argument bc is a lazy representation of a (potentially fused) broadcast operation, a Broadcasted object. For these purposes, the most important fields of the wrapper are f and args, describing the function and argument list, respectively. Note that the argument list can — and often does — include other nested Broadcasted wrappers.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For a complete example, let's say you have created a type, ArrayAndChar, that stores an array and a single character:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"struct ArrayAndChar{T,N} <: AbstractArray{T,N}\n data::Array{T,N}\n char::Char\nend\nBase.size(A::ArrayAndChar) = size(A.data)\nBase.getindex(A::ArrayAndChar{T,N}, inds::Vararg{Int,N}) where {T,N} = A.data[inds...]\nBase.setindex!(A::ArrayAndChar{T,N}, val, inds::Vararg{Int,N}) where {T,N} = A.data[inds...] = val\nBase.showarg(io::IO, A::ArrayAndChar, toplevel) = print(io, typeof(A), \" with char '\", A.char, \"'\")","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"You might want broadcasting to preserve the char \"metadata\". First we define","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar}()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"This means we must also define a corresponding similar method:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{ArrayAndChar}}, ::Type{ElType}) where ElType\n # Scan the inputs for the ArrayAndChar:\n A = find_aac(bc)\n # Use the char field of A to create the output\n ArrayAndChar(similar(Array{ElType}, axes(bc)), A.char)\nend\n\n\"`A = find_aac(As)` returns the first ArrayAndChar among the arguments.\"\nfind_aac(bc::Base.Broadcast.Broadcasted) = find_aac(bc.args)\nfind_aac(args::Tuple) = find_aac(find_aac(args[1]), Base.tail(args))\nfind_aac(x) = x\nfind_aac(::Tuple{}) = nothing\nfind_aac(a::ArrayAndChar, rest) = a\nfind_aac(::Any, rest) = find_aac(rest)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"From these definitions, one obtains the following behavior:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> a = ArrayAndChar([1 2; 3 4], 'x')\n2×2 ArrayAndChar{Int64, 2} with char 'x':\n 1 2\n 3 4\n\njulia> a .+ 1\n2×2 ArrayAndChar{Int64, 2} with char 'x':\n 2 3\n 4 5\n\njulia> a .+ [5,10]\n2×2 ArrayAndChar{Int64, 2} with char 'x':\n 6 7\n 13 14","category":"page"},{"location":"manual/interfaces/#extending-in-place-broadcast","page":"Interfaces","title":"Extending broadcast with custom implementations","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In general, a broadcast operation is represented by a lazy Broadcasted container that holds onto the function to be applied alongside its arguments. Those arguments may themselves be more nested Broadcasted containers, forming a large expression tree to be evaluated. A nested tree of Broadcasted containers is directly constructed by the implicit dot syntax; 5 .+ 2.*x is transiently represented by Broadcasted(+, 5, Broadcasted(*, 2, x)), for example. This is invisible to users as it is immediately realized through a call to copy, but it is this container that provides the basis for broadcast's extensibility for authors of custom types. The built-in broadcast machinery will then determine the result type and size based upon the arguments, allocate it, and then finally copy the realization of the Broadcasted object into it with a default copyto!(::AbstractArray, ::Broadcasted) method. The built-in fallback broadcast and broadcast! methods similarly construct a transient Broadcasted representation of the operation so they can follow the same codepath. This allows custom array implementations to provide their own copyto! specialization to customize and optimize broadcasting. This is again determined by the computed broadcast style. This is such an important part of the operation that it is stored as the first type parameter of the Broadcasted type, allowing for dispatch and specialization.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For some types, the machinery to \"fuse\" operations across nested levels of broadcasting is not available or could be done more efficiently incrementally. In such cases, you may need or want to evaluate x .* (x .+ 1) as if it had been written broadcast(*, x, broadcast(+, x, 1)), where the inner operation is evaluated before tackling the outer operation. This sort of eager operation is directly supported by a bit of indirection; instead of directly constructing Broadcasted objects, Julia lowers the fused expression x .* (x .+ 1) to Broadcast.broadcasted(*, x, Broadcast.broadcasted(+, x, 1)). Now, by default, broadcasted just calls the Broadcasted constructor to create the lazy representation of the fused expression tree, but you can choose to override it for a particular combination of function and arguments.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"As an example, the builtin AbstractRange objects use this machinery to optimize pieces of broadcasted expressions that can be eagerly evaluated purely in terms of the start, step, and length (or stop) instead of computing every single element. Just like all the other machinery, broadcasted also computes and exposes the combined broadcast style of its arguments, so instead of specializing on broadcasted(f, args...), you can specialize on broadcasted(::DestStyle, f, args...) for any combination of style, function, and arguments.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For example, the following definition supports the negation of ranges:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange) = range(-first(r), step=-step(r), length=length(r))","category":"page"},{"location":"manual/interfaces/#extending-in-place-broadcast-2","page":"Interfaces","title":"Extending in-place broadcasting","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In-place broadcasting can be supported by defining the appropriate copyto!(dest, bc::Broadcasted) method. Because you might want to specialize either on dest or the specific subtype of bc, to avoid ambiguities between packages we recommend the following convention.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If you wish to specialize on a particular style DestStyle, define a method for","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"copyto!(dest, bc::Broadcasted{DestStyle})","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Optionally, with this form you can also specialize on the type of dest.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If instead you want to specialize on the destination type DestType without specializing on DestStyle, then you should define a method with the following signature:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"copyto!(dest::DestType, bc::Broadcasted{Nothing})","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"This leverages a fallback implementation of copyto! that converts the wrapper into a Broadcasted{Nothing}. Consequently, specializing on DestType has lower precedence than methods that specialize on DestStyle.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Similarly, you can completely override out-of-place broadcasting with a copy(::Broadcasted) method.","category":"page"},{"location":"manual/interfaces/#Working-with-Broadcasted-objects","page":"Interfaces","title":"Working with Broadcasted objects","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In order to implement such a copy or copyto!, method, of course, you must work with the Broadcasted wrapper to compute each element. There are two main ways of doing so:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Broadcast.flatten recomputes the potentially nested operation into a single function and flat list of arguments. You are responsible for implementing the broadcasting shape rules yourself, but this may be helpful in limited situations.\nIterating over the CartesianIndices of the axes(::Broadcasted) and using indexing with the resulting CartesianIndex object to compute the result.","category":"page"},{"location":"manual/interfaces/#writing-binary-broadcasting-rules","page":"Interfaces","title":"Writing binary broadcasting rules","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The precedence rules are defined by binary BroadcastStyle calls:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle(::Style1, ::Style2) = Style12()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"where Style12 is the BroadcastStyle you want to choose for outputs involving arguments of Style1 and Style2. For example,","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle(::Broadcast.Style{Tuple}, ::Broadcast.AbstractArrayStyle{0}) = Broadcast.Style{Tuple}()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"indicates that Tuple \"wins\" over zero-dimensional arrays (the output container will be a tuple). It is worth noting that you do not need to (and should not) define both argument orders of this call; defining one is sufficient no matter what order the user supplies the arguments in.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For AbstractArray types, defining a BroadcastStyle supersedes the fallback choice, Broadcast.DefaultArrayStyle. DefaultArrayStyle and the abstract supertype, AbstractArrayStyle, store the dimensionality as a type parameter to support specialized array types that have fixed dimensionality requirements.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"DefaultArrayStyle \"loses\" to any other AbstractArrayStyle that has been defined because of the following methods:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"BroadcastStyle(a::AbstractArrayStyle{Any}, ::DefaultArrayStyle) = a\nBroadcastStyle(a::AbstractArrayStyle{N}, ::DefaultArrayStyle{N}) where N = a\nBroadcastStyle(a::AbstractArrayStyle{M}, ::DefaultArrayStyle{N}) where {M,N} =\n typeof(a)(Val(max(M, N)))","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"You do not need to write binary BroadcastStyle rules unless you want to establish precedence for two or more non-DefaultArrayStyle types.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If your array type does have fixed dimensionality requirements, then you should subtype AbstractArrayStyle. For example, the sparse array code has the following definitions:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"struct SparseVecStyle <: Broadcast.AbstractArrayStyle{1} end\nstruct SparseMatStyle <: Broadcast.AbstractArrayStyle{2} end\nBase.BroadcastStyle(::Type{<:SparseVector}) = SparseVecStyle()\nBase.BroadcastStyle(::Type{<:SparseMatrixCSC}) = SparseMatStyle()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Whenever you subtype AbstractArrayStyle, you also need to define rules for combining dimensionalities, by creating a constructor for your style that takes a Val(N) argument. For example:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"SparseVecStyle(::Val{0}) = SparseVecStyle()\nSparseVecStyle(::Val{1}) = SparseVecStyle()\nSparseVecStyle(::Val{2}) = SparseMatStyle()\nSparseVecStyle(::Val{N}) where N = Broadcast.DefaultArrayStyle{N}()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"These rules indicate that the combination of a SparseVecStyle with 0- or 1-dimensional arrays yields another SparseVecStyle, that its combination with a 2-dimensional array yields a SparseMatStyle, and anything of higher dimensionality falls back to the dense arbitrary-dimensional framework. These rules allow broadcasting to keep the sparse representation for operations that result in one or two dimensional outputs, but produce an Array for any other dimensionality.","category":"page"},{"location":"manual/interfaces/#man-instance-properties","page":"Interfaces","title":"Instance Properties","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Default definition Brief description\npropertynames(x::ObjType, private::Bool=false) fieldnames(typeof(x)) Return a tuple of the properties (x.property) of an object x. If private=true, also return property names intended to be kept as private\ngetproperty(x::ObjType, s::Symbol) getfield(x, s) Return property s of x. x.s calls getproperty(x, :s).\nsetproperty!(x::ObjType, s::Symbol, v) setfield!(x, s, v) Set property s of x to v. x.s = v calls setproperty!(x, :s, v). Should return v.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Sometimes, it is desirable to change how the end-user interacts with the fields of an object. Instead of granting direct access to type fields, an extra layer of abstraction between the user and the code can be provided by overloading object.field. Properties are what the user sees of the object, fields what the object actually is.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"By default, properties and fields are the same. However, this behavior can be changed. For example, take this representation of a point in a plane in polar coordinates:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> mutable struct Point\n r::Float64\n ϕ::Float64\n end\n\njulia> p = Point(7.0, pi/4)\nPoint(7.0, 0.7853981633974483)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"As described in the table above dot access p.r is the same as getproperty(p, :r) which is by default the same as getfield(p, :r):","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> propertynames(p)\n(:r, :ϕ)\n\njulia> getproperty(p, :r), getproperty(p, :ϕ)\n(7.0, 0.7853981633974483)\n\njulia> p.r, p.ϕ\n(7.0, 0.7853981633974483)\n\njulia> getfield(p, :r), getproperty(p, :ϕ)\n(7.0, 0.7853981633974483)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"However, we may want users to be unaware that Point stores the coordinates as r and ϕ (fields), and instead interact with x and y (properties). The methods in the first column can be defined to add new functionality:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.propertynames(::Point, private::Bool=false) = private ? (:x, :y, :r, :ϕ) : (:x, :y)\n\njulia> function Base.getproperty(p::Point, s::Symbol)\n if s === :x\n return getfield(p, :r) * cos(getfield(p, :ϕ))\n elseif s === :y\n return getfield(p, :r) * sin(getfield(p, :ϕ))\n else\n # This allows accessing fields with p.r and p.ϕ\n return getfield(p, s)\n end\n end\n\njulia> function Base.setproperty!(p::Point, s::Symbol, f)\n if s === :x\n y = p.y\n setfield!(p, :r, sqrt(f^2 + y^2))\n setfield!(p, :ϕ, atan(y, f))\n return f\n elseif s === :y\n x = p.x\n setfield!(p, :r, sqrt(x^2 + f^2))\n setfield!(p, :ϕ, atan(f, x))\n return f\n else\n # This allow modifying fields with p.r and p.ϕ\n return setfield!(p, s, f)\n end\n end","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"It is important that getfield and setfield are used inside getproperty and setproperty! instead of the dot syntax, since the dot syntax would make the functions recursive which can lead to type inference issues. We can now try out the new functionality:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> propertynames(p)\n(:x, :y)\n\njulia> p.x\n4.949747468305833\n\njulia> p.y = 4.0\n4.0\n\njulia> p.r\n6.363961030678928","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Finally, it is worth noting that adding instance properties like this is quite rarely done in Julia and should in general only be done if there is a good reason for doing so.","category":"page"},{"location":"manual/interfaces/#man-rounding-interface","page":"Interfaces","title":"Rounding","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Default definition Brief description\nround(x::ObjType, r::RoundingMode) none Round x and return the result. If possible, round should return an object of the same type as x\nround(T::Type, x::ObjType, r::RoundingMode) convert(T, round(x, r)) Round x, returning the result as a T","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"To support rounding on a new type it is typically sufficient to define the single method round(x::ObjType, r::RoundingMode). The passed rounding mode determines in which direction the value should be rounded. The most commonly used rounding modes are RoundNearest, RoundToZero, RoundDown, and RoundUp, as these rounding modes are used in the definitions of the one argument round, method, and trunc, floor, and ceil, respectively.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In some cases, it is possible to define a three-argument round method that is more accurate or performant than the two-argument method followed by conversion. In this case it is acceptable to define the three argument method in addition to the two argument method. If it is impossible to represent the rounded result as an object of the type T, then the three argument method should throw an InexactError.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For example, if we have an Interval type which represents a range of possible values similar to https://github.com/JuliaPhysics/Measurements.jl, we may define rounding on that type with the following","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> struct Interval{T}\n min::T\n max::T\n end\n\njulia> Base.round(x::Interval, r::RoundingMode) = Interval(round(x.min, r), round(x.max, r))\n\njulia> x = Interval(1.7, 2.2)\nInterval{Float64}(1.7, 2.2)\n\njulia> round(x)\nInterval{Float64}(2.0, 2.0)\n\njulia> floor(x)\nInterval{Float64}(1.0, 2.0)\n\njulia> ceil(x)\nInterval{Float64}(2.0, 3.0)\n\njulia> trunc(x)\nInterval{Float64}(1.0, 2.0)","category":"page"}] +[{"location":"stdlib/CRC32c/","page":"CRC32c","title":"CRC32c","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/CRC32c/docs/src/index.md\"","category":"page"},{"location":"stdlib/CRC32c/#CRC32c","page":"CRC32c","title":"CRC32c","text":"","category":"section"},{"location":"stdlib/CRC32c/","page":"CRC32c","title":"CRC32c","text":"Standard library module for computing the CRC-32c checksum.","category":"page"},{"location":"stdlib/CRC32c/","page":"CRC32c","title":"CRC32c","text":"CRC32c.crc32c\nCRC32c.crc32c(::IO, ::Integer, ::UInt32)","category":"page"},{"location":"stdlib/CRC32c/#CRC32c.crc32c","page":"CRC32c","title":"CRC32c.crc32c","text":"crc32c(data, crc::UInt32=0x00000000)\n\nCompute the CRC-32c checksum of the given data, which can be an Array{UInt8}, a contiguous subarray thereof, or a String. Optionally, you can pass a starting crc integer to be mixed in with the checksum. The crc parameter can be used to compute a checksum on data divided into chunks: performing crc32c(data2, crc32c(data1)) is equivalent to the checksum of [data1; data2]. (Technically, a little-endian checksum is computed.)\n\nThere is also a method crc32c(io, nb, crc) to checksum nb bytes from a stream io, or crc32c(io, crc) to checksum all the remaining bytes. Hence you can do open(crc32c, filename) to checksum an entire file, or crc32c(seekstart(buf)) to checksum an IOBuffer without calling take!.\n\nFor a String, note that the result is specific to the UTF-8 encoding (a different checksum would be obtained from a different Unicode encoding). To checksum an a::Array of some other bitstype, you can do crc32c(reinterpret(UInt8,a)), but note that the result may be endian-dependent.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/CRC32c/#CRC32c.crc32c-Tuple{IO, Integer, UInt32}","page":"CRC32c","title":"CRC32c.crc32c","text":"crc32c(io::IO, [nb::Integer,] crc::UInt32=0x00000000)\n\nRead up to nb bytes from io and return the CRC-32c checksum, optionally mixed with a starting crc integer. If nb is not supplied, then io will be read until the end of the stream.\n\n\n\n\n\n","category":"method"},{"location":"manual/installation/#man-installation","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"There are many ways to install Julia. The following sections highlight the recommended method for each of the main supported platforms, and then present alternative ways that might be useful in specialized situations.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"The current installation recommendation is a solution based on Juliaup. If you installed Julia previously with a method that is not based on Juliaup and want to switch your system to an installation that is based on Juliaup, we recommend that you uninstall all previous Julia versions, ensure that you remove anything Julia related from your PATH variable and then install Julia with one of the methods described below.","category":"page"},{"location":"manual/installation/#Windows","page":"Installation","title":"Windows","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"On Windows Julia can be installed directly from the Windows store here. One can also install exactly the same version by executing","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"winget install julia -s msstore","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"in any shell.","category":"page"},{"location":"manual/installation/#Mac-and-Linux","page":"Installation","title":"Mac and Linux","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"Julia can be installed on Linux or Mac by executing","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"curl -fsSL https://install.julialang.org | sh","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"in a shell.","category":"page"},{"location":"manual/installation/#Command-line-arguments","page":"Installation","title":"Command line arguments","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"One can pass various command line arguments to the Julia installer. The syntax for installer arguments is","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"curl -fsSL https://install.julialang.org | sh -s -- ","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"Here should be replaced with one or more of the following arguments:","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--yes (or -y): Run the installer in a non-interactive mode. All","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"configuration values use their default or a value supplied as a command line argument.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--default-channel=: Configure the default Juliaup channel. For","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"example --default-channel lts would install the lts channel and configure it as the default.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--add-to-path=: Configure whether Julia should be added to the PATH","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"environment variable. Valid values are yes (default) and no.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--background-selfupdate=: Configure an optional CRON job that","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"auto-updates Juliaup if has a value larger than 0. The actual value controls how often the CRON job will run to check for a new Juliaup version in seconds. The default value is 0, i.e. no CRON job will be created.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"--startup-selfupdate=: Configure how often Julia will check for new","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"versions of Juliaup when Julia is started. The default is every 1440 minutes.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"-p= (or --path): Configure where the Julia and Juliaup binaries are","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"installed. The default is ~/.juliaup.","category":"page"},{"location":"manual/installation/#Alternative-installation-methods","page":"Installation","title":"Alternative installation methods","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"Note that we recommend the following methods only if none of the installation methods described above work for your system.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"Some of the installation methods described below recommend installing a package called juliaup. Note that this nevertheless installs a fully functional Julia system, not just Juliaup.","category":"page"},{"location":"manual/installation/#App-Installer-(Windows)","page":"Installation","title":"App Installer (Windows)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"If the Windows Store is blocked on a system, we have an alternative MSIX App Installer based setup. To use the App Installer version, download this file and open it by double clicking on it.","category":"page"},{"location":"manual/installation/#MSI-Installer-(Windows)","page":"Installation","title":"MSI Installer (Windows)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"If neither the Windows Store nor the App Installer version work on your Windows system, you can also use a MSI based installer. Note that this installation methods comes with serious limitations and is generally not recommended unless no other method works. For example, there is no automatic update mechanism for Juliaup with this installation method. The 64 bit version of the MSI installer can be downloaded from here and the 32 bit version from here.","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"By default the install will be a per-user install that does not require elevation. You can also do a system install by running the following command from a shell:","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"msiexec /i ALLUSERS=1","category":"page"},{"location":"manual/installation/#[Homebrew](https://brew.sh)-(Mac-and-Linux)","page":"Installation","title":"Homebrew (Mac and Linux)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"On systems with brew, you can install Julia by running","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"brew install juliaup","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"in a shell. Note that you will have to update Juliaup with standard brew commands.","category":"page"},{"location":"manual/installation/#[Arch-Linux-AUR](https://aur.archlinux.org/packages/juliaup/)-(Linux)","page":"Installation","title":"Arch Linux - AUR (Linux)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"On Arch Linux, Juliaup is available in the Arch User Repository (AUR).","category":"page"},{"location":"manual/installation/#[openSUSE-Tumbleweed](https://get.opensuse.org/tumbleweed/)-(Linux)","page":"Installation","title":"openSUSE Tumbleweed (Linux)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"On openSUSE Tumbleweed, you can install Julia by running","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"zypper install juliaup","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"in a shell with root privileges.","category":"page"},{"location":"manual/installation/#[cargo](https://crates.io/crates/juliaup/)-(Windows,-Mac-and-Linux)","page":"Installation","title":"cargo (Windows, Mac and Linux)","text":"","category":"section"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"To install Julia via Rust's cargo, run:","category":"page"},{"location":"manual/installation/","page":"Installation","title":"Installation","text":"cargo install juliaup","category":"page"},{"location":"base/sort/#Sorting-and-Related-Functions","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Julia has an extensive, flexible API for sorting and interacting with already-sorted arrays of values. By default, Julia picks reasonable algorithms and sorts in ascending order:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort([2,3,1])\n3-element Vector{Int64}:\n 1\n 2\n 3","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"You can sort in reverse order as well:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort([2,3,1], rev=true)\n3-element Vector{Int64}:\n 3\n 2\n 1","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"sort constructs a sorted copy leaving its input unchanged. Use the \"bang\" version of the sort function to mutate an existing array:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> a = [2,3,1];\n\njulia> sort!(a);\n\njulia> a\n3-element Vector{Int64}:\n 1\n 2\n 3","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Instead of directly sorting an array, you can compute a permutation of the array's indices that puts the array into sorted order:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> v = randn(5)\n5-element Array{Float64,1}:\n 0.297288\n 0.382396\n -0.597634\n -0.0104452\n -0.839027\n\njulia> p = sortperm(v)\n5-element Array{Int64,1}:\n 5\n 3\n 4\n 1\n 2\n\njulia> v[p]\n5-element Array{Float64,1}:\n -0.839027\n -0.597634\n -0.0104452\n 0.297288\n 0.382396","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Arrays can be sorted according to an arbitrary transformation of their values:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort(v, by=abs)\n5-element Array{Float64,1}:\n -0.0104452\n 0.297288\n 0.382396\n -0.597634\n -0.839027","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Or in reverse order by a transformation:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort(v, by=abs, rev=true)\n5-element Array{Float64,1}:\n -0.839027\n -0.597634\n 0.382396\n 0.297288\n -0.0104452","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"If needed, the sorting algorithm can be chosen:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"julia> sort(v, alg=InsertionSort)\n5-element Array{Float64,1}:\n -0.839027\n -0.597634\n -0.0104452\n 0.297288\n 0.382396","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"All the sorting and order related functions rely on a \"less than\" relation defining a strict weak order on the values to be manipulated. The isless function is invoked by default, but the relation can be specified via the lt keyword, a function that takes two array elements and returns true if and only if the first argument is \"less than\" the second. See sort! and Alternate Orderings for more information.","category":"page"},{"location":"base/sort/#Sorting-Functions","page":"Sorting and Related Functions","title":"Sorting Functions","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Base.sort!\nBase.sort\nBase.sortperm\nBase.InsertionSort\nBase.MergeSort\nBase.QuickSort\nBase.PartialQuickSort\nBase.Sort.sortperm!\nBase.Sort.sortslices","category":"page"},{"location":"base/sort/#Base.sort!","page":"Sorting and Related Functions","title":"Base.sort!","text":"sort!(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nSort the vector v in place. A stable algorithm is used by default: the ordering of elements that compare equal is preserved. A specific algorithm can be selected via the alg keyword (see Sorting Algorithms for available algorithms).\n\nElements are first transformed with the function by and then compared according to either the function lt or the ordering order. Finally, the resulting order is reversed if rev=true (this preserves forward stability: elements that compare equal are not reversed). The current implementation applies the by transformation before each comparison rather than once per element.\n\nPassing an lt other than isless along with an order other than Base.Order.Forward or Base.Order.Reverse is not permitted, otherwise all options are independent and can be used together in all possible combinations. Note that order can also include a \"by\" transformation, in which case it is applied after that defined with the by keyword. For more information on order values see the documentation on Alternate Orderings.\n\nRelations between two elements are defined as follows (with \"less\" and \"greater\" exchanged when rev=true):\n\nx is less than y if lt(by(x), by(y)) (or Base.Order.lt(order, by(x), by(y))) yields true.\nx is greater than y if y is less than x.\nx and y are equivalent if neither is less than the other (\"incomparable\" is sometimes used as a synonym for \"equivalent\").\n\nThe result of sort! is sorted in the sense that every element is greater than or equivalent to the previous one.\n\nThe lt function must define a strict weak order, that is, it must be\n\nirreflexive: lt(x, x) always yields false,\nasymmetric: if lt(x, y) yields true then lt(y, x) yields false,\ntransitive: lt(x, y) && lt(y, z) implies lt(x, z),\ntransitive in equivalence: !lt(x, y) && !lt(y, x) and !lt(y, z) && !lt(z, y) together imply !lt(x, z) && !lt(z, x). In words: if x and y are equivalent and y and z are equivalent then x and z must be equivalent.\n\nFor example < is a valid lt function for Int values but ≤ is not: it violates irreflexivity. For Float64 values even < is invalid as it violates the fourth condition: 1.0 and NaN are equivalent and so are NaN and 2.0 but 1.0 and 2.0 are not equivalent.\n\nSee also sort, sortperm, sortslices, partialsort!, partialsortperm, issorted, searchsorted, insorted, Base.Order.ord.\n\nExamples\n\njulia> v = [3, 1, 2]; sort!(v); v\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> v = [3, 1, 2]; sort!(v, rev = true); v\n3-element Vector{Int64}:\n 3\n 2\n 1\n\njulia> v = [(1, \"c\"), (3, \"a\"), (2, \"b\")]; sort!(v, by = x -> x[1]); v\n3-element Vector{Tuple{Int64, String}}:\n (1, \"c\")\n (2, \"b\")\n (3, \"a\")\n\njulia> v = [(1, \"c\"), (3, \"a\"), (2, \"b\")]; sort!(v, by = x -> x[2]); v\n3-element Vector{Tuple{Int64, String}}:\n (3, \"a\")\n (2, \"b\")\n (1, \"c\")\n\njulia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) # same as sort(0:3, by=abs(x->x-2))\n4-element Vector{Int64}:\n 2\n 1\n 3\n 0\n\njulia> sort([2, NaN, 1, NaN, 3]) # correct sort with default lt=isless\n5-element Vector{Float64}:\n 1.0\n 2.0\n 3.0\n NaN\n NaN\n\njulia> sort([2, NaN, 1, NaN, 3], lt=<) # wrong sort due to invalid lt. This behavior is undefined.\n5-element Vector{Float64}:\n 2.0\n NaN\n 1.0\n NaN\n 3.0\n\n\n\n\n\nsort!(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nSort the multidimensional array A along dimension dims. See the one-dimensional version of sort! for a description of possible keyword arguments.\n\nTo sort slices of an array, refer to sortslices.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nExamples\n\njulia> A = [4 3; 1 2]\n2×2 Matrix{Int64}:\n 4 3\n 1 2\n\njulia> sort!(A, dims = 1); A\n2×2 Matrix{Int64}:\n 1 2\n 4 3\n\njulia> sort!(A, dims = 2); A\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.sort","page":"Sorting and Related Functions","title":"Base.sort","text":"sort(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nVariant of sort! that returns a sorted copy of v leaving v itself unmodified.\n\nExamples\n\njulia> v = [3, 1, 2];\n\njulia> sort(v)\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> v\n3-element Vector{Int64}:\n 3\n 1\n 2\n\n\n\n\n\nsort(A; dims::Integer, alg::Algorithm=defalg(A), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nSort a multidimensional array A along the given dimension. See sort! for a description of possible keyword arguments.\n\nTo sort slices of an array, refer to sortslices.\n\nExamples\n\njulia> A = [4 3; 1 2]\n2×2 Matrix{Int64}:\n 4 3\n 1 2\n\njulia> sort(A, dims = 1)\n2×2 Matrix{Int64}:\n 1 2\n 4 3\n\njulia> sort(A, dims = 2)\n2×2 Matrix{Int64}:\n 3 4\n 1 2\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.sortperm","page":"Sorting and Related Functions","title":"Base.sortperm","text":"sortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])\n\nReturn a permutation vector or array I that puts A[I] in sorted order along the given dimension. If A has more than one dimension, then the dims keyword argument must be specified. The order is specified using the same keywords as sort!. The permutation is guaranteed to be stable even if the sorting algorithm is unstable: the indices of equal elements will appear in ascending order.\n\nSee also sortperm!, partialsortperm, invperm, indexin. To sort slices of an array, refer to sortslices.\n\ncompat: Julia 1.9\nThe method accepting dims requires at least Julia 1.9.\n\nExamples\n\njulia> v = [3, 1, 2];\n\njulia> p = sortperm(v)\n3-element Vector{Int64}:\n 2\n 3\n 1\n\njulia> v[p]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> A = [8 7; 5 6]\n2×2 Matrix{Int64}:\n 8 7\n 5 6\n\njulia> sortperm(A, dims = 1)\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\njulia> sortperm(A, dims = 2)\n2×2 Matrix{Int64}:\n 3 1\n 2 4\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.InsertionSort","page":"Sorting and Related Functions","title":"Base.Sort.InsertionSort","text":"InsertionSort\n\nUse the insertion sort algorithm.\n\nInsertion sort traverses the collection one element at a time, inserting each element into its correct, sorted position in the output vector.\n\nCharacteristics:\n\nstable: preserves the ordering of elements that compare equal\n\n(e.g. \"a\" and \"A\" in a sort of letters that ignores case).\n\nin-place in memory.\nquadratic performance in the number of elements to be sorted:\n\nit is well-suited to small collections but should not be used for large ones.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Sort.MergeSort","page":"Sorting and Related Functions","title":"Base.Sort.MergeSort","text":"MergeSort\n\nIndicate that a sorting function should use the merge sort algorithm. Merge sort divides the collection into subcollections and repeatedly merges them, sorting each subcollection at each step, until the entire collection has been recombined in sorted form.\n\nCharacteristics:\n\nstable: preserves the ordering of elements that compare equal (e.g. \"a\" and \"A\" in a sort of letters that ignores case).\nnot in-place in memory.\ndivide-and-conquer sort strategy.\ngood performance for large collections but typically not quite as fast as QuickSort.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Sort.QuickSort","page":"Sorting and Related Functions","title":"Base.Sort.QuickSort","text":"QuickSort\n\nIndicate that a sorting function should use the quick sort algorithm, which is not stable.\n\nCharacteristics:\n\nnot stable: does not preserve the ordering of elements that compare equal (e.g. \"a\" and \"A\" in a sort of letters that ignores case).\nin-place in memory.\ndivide-and-conquer: sort strategy similar to MergeSort.\ngood performance for large collections.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Sort.PartialQuickSort","page":"Sorting and Related Functions","title":"Base.Sort.PartialQuickSort","text":"PartialQuickSort{T <: Union{Integer,OrdinalRange}}\n\nIndicate that a sorting function should use the partial quick sort algorithm. PartialQuickSort(k) is like QuickSort, but is only required to find and sort the elements that would end up in v[k] were v fully sorted.\n\nCharacteristics:\n\nnot stable: does not preserve the ordering of elements that compare equal (e.g. \"a\" and \"A\" in a sort of letters that ignores case).\nin-place in memory.\ndivide-and-conquer: sort strategy similar to MergeSort.\n\nNote that PartialQuickSort(k) does not necessarily sort the whole array. For example,\n\njulia> x = rand(100);\n\njulia> k = 50:100;\n\njulia> s1 = sort(x; alg=QuickSort);\n\njulia> s2 = sort(x; alg=PartialQuickSort(k));\n\njulia> map(issorted, (s1, s2))\n(true, false)\n\njulia> map(x->issorted(x[k]), (s1, s2))\n(true, true)\n\njulia> s1[k] == s2[k]\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Sort.sortperm!","page":"Sorting and Related Functions","title":"Base.Sort.sortperm!","text":"sortperm!(ix, A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])\n\nLike sortperm, but accepts a preallocated index vector or array ix with the same axes as A. ix is initialized to contain the values LinearIndices(A).\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\ncompat: Julia 1.9\nThe method accepting dims requires at least Julia 1.9.\n\nExamples\n\njulia> v = [3, 1, 2]; p = zeros(Int, 3);\n\njulia> sortperm!(p, v); p\n3-element Vector{Int64}:\n 2\n 3\n 1\n\njulia> v[p]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> A = [8 7; 5 6]; p = zeros(Int,2, 2);\n\njulia> sortperm!(p, A; dims=1); p\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\njulia> sortperm!(p, A; dims=2); p\n2×2 Matrix{Int64}:\n 3 1\n 2 4\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.sortslices","page":"Sorting and Related Functions","title":"Base.sortslices","text":"sortslices(A; dims, alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nSort slices of an array A. The required keyword argument dims must be either an integer or a tuple of integers. It specifies the dimension(s) over which the slices are sorted.\n\nE.g., if A is a matrix, dims=1 will sort rows, dims=2 will sort columns. Note that the default comparison function on one dimensional slices sorts lexicographically.\n\nFor the remaining keyword arguments, see the documentation of sort!.\n\nExamples\n\njulia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1) # Sort rows\n3×3 Matrix{Int64}:\n -1 6 4\n 7 3 5\n 9 -2 8\n\njulia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, lt=(x,y)->isless(x[2],y[2]))\n3×3 Matrix{Int64}:\n 9 -2 8\n 7 3 5\n -1 6 4\n\njulia> sortslices([7 3 5; -1 6 4; 9 -2 8], dims=1, rev=true)\n3×3 Matrix{Int64}:\n 9 -2 8\n 7 3 5\n -1 6 4\n\njulia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2) # Sort columns\n3×3 Matrix{Int64}:\n 3 5 7\n -1 -4 6\n -2 8 9\n\njulia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, alg=InsertionSort, lt=(x,y)->isless(x[2],y[2]))\n3×3 Matrix{Int64}:\n 5 3 7\n -4 -1 6\n 8 -2 9\n\njulia> sortslices([7 3 5; 6 -1 -4; 9 -2 8], dims=2, rev=true)\n3×3 Matrix{Int64}:\n 7 5 3\n 6 -4 -1\n 9 8 -2\n\nHigher dimensions\n\nsortslices extends naturally to higher dimensions. E.g., if A is a a 2x2x2 array, sortslices(A, dims=3) will sort slices within the 3rd dimension, passing the 2x2 slices A[:, :, 1] and A[:, :, 2] to the comparison function. Note that while there is no default order on higher-dimensional slices, you may use the by or lt keyword argument to specify such an order.\n\nIf dims is a tuple, the order of the dimensions in dims is relevant and specifies the linear order of the slices. E.g., if A is three dimensional and dims is (1, 2), the orderings of the first two dimensions are re-arranged such that the slices (of the remaining third dimension) are sorted. If dims is (2, 1) instead, the same slices will be taken, but the result order will be row-major instead.\n\nHigher dimensional examples\n\njulia> A = [4 3; 2 1 ;;; 'A' 'B'; 'C' 'D']\n2×2×2 Array{Any, 3}:\n[:, :, 1] =\n 4 3\n 2 1\n\n[:, :, 2] =\n 'A' 'B'\n 'C' 'D'\n\njulia> sortslices(A, dims=(1,2))\n2×2×2 Array{Any, 3}:\n[:, :, 1] =\n 1 3\n 2 4\n\n[:, :, 2] =\n 'D' 'B'\n 'C' 'A'\n\njulia> sortslices(A, dims=(2,1))\n2×2×2 Array{Any, 3}:\n[:, :, 1] =\n 1 2\n 3 4\n\n[:, :, 2] =\n 'D' 'C'\n 'B' 'A'\n\njulia> sortslices(reshape([5; 4; 3; 2; 1], (1,1,5)), dims=3, by=x->x[1,1])\n1×1×5 Array{Int64, 3}:\n[:, :, 1] =\n 1\n\n[:, :, 2] =\n 2\n\n[:, :, 3] =\n 3\n\n[:, :, 4] =\n 4\n\n[:, :, 5] =\n 5\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Order-Related-Functions","page":"Sorting and Related Functions","title":"Order-Related Functions","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Base.issorted\nBase.Sort.searchsorted\nBase.Sort.searchsortedfirst\nBase.Sort.searchsortedlast\nBase.Sort.insorted\nBase.Sort.partialsort!\nBase.Sort.partialsort\nBase.Sort.partialsortperm\nBase.Sort.partialsortperm!","category":"page"},{"location":"base/sort/#Base.issorted","page":"Sorting and Related Functions","title":"Base.issorted","text":"issorted(v, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)\n\nTest whether a collection is in sorted order. The keywords modify what order is considered sorted, as described in the sort! documentation.\n\nExamples\n\njulia> issorted([1, 2, 3])\ntrue\n\njulia> issorted([(1, \"b\"), (2, \"a\")], by = x -> x[1])\ntrue\n\njulia> issorted([(1, \"b\"), (2, \"a\")], by = x -> x[2])\nfalse\n\njulia> issorted([(1, \"b\"), (2, \"a\")], by = x -> x[2], rev=true)\ntrue\n\njulia> issorted([1, 2, -2, 3], by=abs)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.searchsorted","page":"Sorting and Related Functions","title":"Base.Sort.searchsorted","text":"searchsorted(v, x; by=identity, lt=isless, rev=false)\n\nReturn the range of indices in v where values are equivalent to x, or an empty range located at the insertion point if v does not contain values equivalent to x. The vector v must be sorted according to the order defined by the keywords. Refer to sort! for the meaning of the keywords and the definition of equivalence. Note that the by function is applied to the searched value x as well as the values in v.\n\nThe range is generally found using binary search, but there are optimized implementations for some inputs.\n\nSee also: searchsortedfirst, sort!, insorted, findall.\n\nExamples\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 4) # single match\n3:3\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 5) # multiple matches\n4:5\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 3) # no match, insert in the middle\n3:2\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 9) # no match, insert at end\n7:6\n\njulia> searchsorted([1, 2, 4, 5, 5, 7], 0) # no match, insert at start\n1:0\n\njulia> searchsorted([1=>\"one\", 2=>\"two\", 2=>\"two\", 4=>\"four\"], 2=>\"two\", by=first) # compare the keys of the pairs\n2:3\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.searchsortedfirst","page":"Sorting and Related Functions","title":"Base.Sort.searchsortedfirst","text":"searchsortedfirst(v, x; by=identity, lt=isless, rev=false)\n\nReturn the index of the first value in v that is not ordered before x. If all values in v are ordered before x, return lastindex(v) + 1.\n\nThe vector v must be sorted according to the order defined by the keywords. insert!ing x at the returned index will maintain the sorted order. Refer to sort! for the meaning and use of the keywords. Note that the by function is applied to the searched value x as well as the values in v.\n\nThe index is generally found using binary search, but there are optimized implementations for some inputs.\n\nSee also: searchsortedlast, searchsorted, findfirst.\n\nExamples\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 4) # single match\n3\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 5) # multiple matches\n4\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 3) # no match, insert in the middle\n3\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 9) # no match, insert at end\n7\n\njulia> searchsortedfirst([1, 2, 4, 5, 5, 7], 0) # no match, insert at start\n1\n\njulia> searchsortedfirst([1=>\"one\", 2=>\"two\", 4=>\"four\"], 3=>\"three\", by=first) # compare the keys of the pairs\n3\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.searchsortedlast","page":"Sorting and Related Functions","title":"Base.Sort.searchsortedlast","text":"searchsortedlast(v, x; by=identity, lt=isless, rev=false)\n\nReturn the index of the last value in v that is not ordered after x. If all values in v are ordered after x, return firstindex(v) - 1.\n\nThe vector v must be sorted according to the order defined by the keywords. insert!ing x immediately after the returned index will maintain the sorted order. Refer to sort! for the meaning and use of the keywords. Note that the by function is applied to the searched value x as well as the values in v.\n\nThe index is generally found using binary search, but there are optimized implementations for some inputs\n\nExamples\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 4) # single match\n3\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 5) # multiple matches\n5\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 3) # no match, insert in the middle\n2\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 9) # no match, insert at end\n6\n\njulia> searchsortedlast([1, 2, 4, 5, 5, 7], 0) # no match, insert at start\n0\n\njulia> searchsortedlast([1=>\"one\", 2=>\"two\", 4=>\"four\"], 3=>\"three\", by=first) # compare the keys of the pairs\n2\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.insorted","page":"Sorting and Related Functions","title":"Base.Sort.insorted","text":"insorted(x, v; by=identity, lt=isless, rev=false) -> Bool\n\nDetermine whether a vector v contains any value equivalent to x. The vector v must be sorted according to the order defined by the keywords. Refer to sort! for the meaning of the keywords and the definition of equivalence. Note that the by function is applied to the searched value x as well as the values in v.\n\nThe check is generally done using binary search, but there are optimized implementations for some inputs.\n\nSee also in.\n\nExamples\n\njulia> insorted(4, [1, 2, 4, 5, 5, 7]) # single match\ntrue\n\njulia> insorted(5, [1, 2, 4, 5, 5, 7]) # multiple matches\ntrue\n\njulia> insorted(3, [1, 2, 4, 5, 5, 7]) # no match\nfalse\n\njulia> insorted(9, [1, 2, 4, 5, 5, 7]) # no match\nfalse\n\njulia> insorted(0, [1, 2, 4, 5, 5, 7]) # no match\nfalse\n\njulia> insorted(2=>\"TWO\", [1=>\"one\", 2=>\"two\", 4=>\"four\"], by=first) # compare the keys of the pairs\ntrue\n\ncompat: Julia 1.6\ninsorted was added in Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.partialsort!","page":"Sorting and Related Functions","title":"Base.Sort.partialsort!","text":"partialsort!(v, k; by=identity, lt=isless, rev=false)\n\nPartially sort the vector v in place so that the value at index k (or range of adjacent values if k is a range) occurs at the position where it would appear if the array were fully sorted. If k is a single index, that value is returned; if k is a range, an array of values at those indices is returned. Note that partialsort! may not fully sort the input array.\n\nFor the keyword arguments, see the documentation of sort!.\n\nExamples\n\njulia> a = [1, 2, 4, 3, 4]\n5-element Vector{Int64}:\n 1\n 2\n 4\n 3\n 4\n\njulia> partialsort!(a, 4)\n4\n\njulia> a\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 4\n\njulia> a = [1, 2, 4, 3, 4]\n5-element Vector{Int64}:\n 1\n 2\n 4\n 3\n 4\n\njulia> partialsort!(a, 4, rev=true)\n2\n\njulia> a\n5-element Vector{Int64}:\n 4\n 4\n 3\n 2\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.partialsort","page":"Sorting and Related Functions","title":"Base.Sort.partialsort","text":"partialsort(v, k, by=identity, lt=isless, rev=false)\n\nVariant of partialsort! that copies v before partially sorting it, thereby returning the same thing as partialsort! but leaving v unmodified.\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.partialsortperm","page":"Sorting and Related Functions","title":"Base.Sort.partialsortperm","text":"partialsortperm(v, k; by=ientity, lt=isless, rev=false)\n\nReturn a partial permutation I of the vector v, so that v[I] returns values of a fully sorted version of v at index k. If k is a range, a vector of indices is returned; if k is an integer, a single index is returned. The order is specified using the same keywords as sort!. The permutation is stable: the indices of equal elements will appear in ascending order.\n\nThis function is equivalent to, but more efficient than, calling sortperm(...)[k].\n\nExamples\n\njulia> v = [3, 1, 2, 1];\n\njulia> v[partialsortperm(v, 1)]\n1\n\njulia> p = partialsortperm(v, 1:3)\n3-element view(::Vector{Int64}, 1:3) with eltype Int64:\n 2\n 4\n 3\n\njulia> v[p]\n3-element Vector{Int64}:\n 1\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Sort.partialsortperm!","page":"Sorting and Related Functions","title":"Base.Sort.partialsortperm!","text":"partialsortperm!(ix, v, k; by=identity, lt=isless, rev=false)\n\nLike partialsortperm, but accepts a preallocated index vector ix the same size as v, which is used to store (a permutation of) the indices of v.\n\nix is initialized to contain the indices of v.\n\n(Typically, the indices of v will be 1:length(v), although if v has an alternative array type with non-one-based indices, such as an OffsetArray, ix must share those same indices)\n\nUpon return, ix is guaranteed to have the indices k in their sorted positions, such that\n\npartialsortperm!(ix, v, k);\nv[ix[k]] == partialsort(v, k)\n\nThe return value is the kth element of ix if k is an integer, or view into ix if k is a range.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> v = [3, 1, 2, 1];\n\njulia> ix = Vector{Int}(undef, 4);\n\njulia> partialsortperm!(ix, v, 1)\n2\n\njulia> ix = [1:4;];\n\njulia> partialsortperm!(ix, v, 2:3)\n2-element view(::Vector{Int64}, 2:3) with eltype Int64:\n 4\n 3\n\n\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Sorting-Algorithms","page":"Sorting and Related Functions","title":"Sorting Algorithms","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"There are currently four sorting algorithms publicly available in base Julia:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"InsertionSort\nQuickSort\nPartialQuickSort(k)\nMergeSort","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"By default, the sort family of functions uses stable sorting algorithms that are fast on most inputs. The exact algorithm choice is an implementation detail to allow for future performance improvements. Currently, a hybrid of RadixSort, ScratchQuickSort, InsertionSort, and CountingSort is used based on input type, size, and composition. Implementation details are subject to change but currently available in the extended help of ??Base.DEFAULT_STABLE and the docstrings of internal sorting algorithms listed there.","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"You can explicitly specify your preferred algorithm with the alg keyword (e.g. sort!(v, alg=PartialQuickSort(10:20))) or reconfigure the default sorting algorithm for custom types by adding a specialized method to the Base.Sort.defalg function. For example, InlineStrings.jl defines the following method:","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Base.Sort.defalg(::AbstractArray{<:Union{SmallInlineStrings, Missing}}) = InlineStringSort","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"compat: Julia 1.9\nThe default sorting algorithm (returned by Base.Sort.defalg) is guaranteed to be stable since Julia 1.9. Previous versions had unstable edge cases when sorting numeric arrays.","category":"page"},{"location":"base/sort/#Alternate-Orderings","page":"Sorting and Related Functions","title":"Alternate Orderings","text":"","category":"section"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"By default, sort, searchsorted, and related functions use isless to compare two elements in order to determine which should come first. The Base.Order.Ordering abstract type provides a mechanism for defining alternate orderings on the same set of elements: when calling a sorting function like sort!, an instance of Ordering can be provided with the keyword argument order.","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Instances of Ordering define an order through the Base.Order.lt function, which works as a generalization of isless. This function's behavior on custom Orderings must satisfy all the conditions of a strict weak order. See sort! for details and examples of valid and invalid lt functions.","category":"page"},{"location":"base/sort/","page":"Sorting and Related Functions","title":"Sorting and Related Functions","text":"Base.Order.Ordering\nBase.Order.lt\nBase.Order.ord\nBase.Order.Forward\nBase.Order.ReverseOrdering\nBase.Order.Reverse\nBase.Order.By\nBase.Order.Lt\nBase.Order.Perm","category":"page"},{"location":"base/sort/#Base.Order.Ordering","page":"Sorting and Related Functions","title":"Base.Order.Ordering","text":"Base.Order.Ordering\n\nAbstract type which represents a strict weak order on some set of elements. See sort! for more.\n\nUse Base.Order.lt to compare two elements according to the ordering.\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Order.lt","page":"Sorting and Related Functions","title":"Base.Order.lt","text":"lt(o::Ordering, a, b) -> Bool\n\nTest whether a is less than b according to the ordering o.\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Order.ord","page":"Sorting and Related Functions","title":"Base.Order.ord","text":"ord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)\n\nConstruct an Ordering object from the same arguments used by sort!. Elements are first transformed by the function by (which may be identity) and are then compared according to either the function lt or an existing ordering order. lt should be isless or a function that obeys the same rules as the lt parameter of sort!. Finally, the resulting order is reversed if rev=true.\n\nPassing an lt other than isless along with an order other than Base.Order.Forward or Base.Order.Reverse is not permitted, otherwise all options are independent and can be used together in all possible combinations.\n\n\n\n\n\n","category":"function"},{"location":"base/sort/#Base.Order.Forward","page":"Sorting and Related Functions","title":"Base.Order.Forward","text":"Base.Order.Forward\n\nDefault ordering according to isless.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Order.ReverseOrdering","page":"Sorting and Related Functions","title":"Base.Order.ReverseOrdering","text":"ReverseOrdering(fwd::Ordering=Forward)\n\nA wrapper which reverses an ordering.\n\nFor a given Ordering o, the following holds for all a, b:\n\nlt(ReverseOrdering(o), a, b) == lt(o, b, a)\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Order.Reverse","page":"Sorting and Related Functions","title":"Base.Order.Reverse","text":"Base.Order.Reverse\n\nReverse ordering according to isless.\n\n\n\n\n\n","category":"constant"},{"location":"base/sort/#Base.Order.By","page":"Sorting and Related Functions","title":"Base.Order.By","text":"By(by, order::Ordering=Forward)\n\nOrdering which applies order to elements after they have been transformed by the function by.\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Order.Lt","page":"Sorting and Related Functions","title":"Base.Order.Lt","text":"Lt(lt)\n\nOrdering that calls lt(a, b) to compare elements. lt must obey the same rules as the lt parameter of sort!.\n\n\n\n\n\n","category":"type"},{"location":"base/sort/#Base.Order.Perm","page":"Sorting and Related Functions","title":"Base.Order.Perm","text":"Perm(order::Ordering, data::AbstractVector)\n\nOrdering on the indices of data where i is less than j if data[i] is less than data[j] according to order. In the case that data[i] and data[j] are equal, i and j are compared by numeric value.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Base64/","page":"Base64","title":"Base64","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Base64/docs/src/index.md\"","category":"page"},{"location":"stdlib/Base64/#Base64","page":"Base64","title":"Base64","text":"","category":"section"},{"location":"stdlib/Base64/","page":"Base64","title":"Base64","text":"Base64.Base64\nBase64.Base64EncodePipe\nBase64.base64encode\nBase64.Base64DecodePipe\nBase64.base64decode\nBase64.stringmime","category":"page"},{"location":"stdlib/Base64/#Base64.Base64","page":"Base64","title":"Base64.Base64","text":"Base64\n\nFunctionality for base64 encoding and decoding, a method to represent binary data using text, common on the web.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Base64/#Base64.Base64EncodePipe","page":"Base64","title":"Base64.Base64EncodePipe","text":"Base64EncodePipe(ostream)\n\nReturn a new write-only I/O stream, which converts any bytes written to it into base64-encoded ASCII bytes written to ostream. Calling close on the Base64EncodePipe stream is necessary to complete the encoding (but does not close ostream).\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> iob64_encode = Base64EncodePipe(io);\n\njulia> write(iob64_encode, \"Hello!\")\n6\n\njulia> close(iob64_encode);\n\njulia> str = String(take!(io))\n\"SGVsbG8h\"\n\njulia> String(base64decode(str))\n\"Hello!\"\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Base64/#Base64.base64encode","page":"Base64","title":"Base64.base64encode","text":"base64encode(writefunc, args...; context=nothing)\nbase64encode(args...; context=nothing)\n\nGiven a write-like function writefunc, which takes an I/O stream as its first argument, base64encode(writefunc, args...) calls writefunc to write args... to a base64-encoded string, and returns the string. base64encode(args...) is equivalent to base64encode(write, args...): it converts its arguments into bytes using the standard write functions and returns the base64-encoded string.\n\nThe optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to writefunc or write.\n\nSee also base64decode.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Base64/#Base64.Base64DecodePipe","page":"Base64","title":"Base64.Base64DecodePipe","text":"Base64DecodePipe(istream)\n\nReturn a new read-only I/O stream, which decodes base64-encoded data read from istream.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> iob64_decode = Base64DecodePipe(io);\n\njulia> write(io, \"SGVsbG8h\")\n8\n\njulia> seekstart(io);\n\njulia> String(read(iob64_decode))\n\"Hello!\"\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Base64/#Base64.base64decode","page":"Base64","title":"Base64.base64decode","text":"base64decode(string)\n\nDecode the base64-encoded string and returns a Vector{UInt8} of the decoded bytes.\n\nSee also base64encode.\n\nExamples\n\njulia> b = base64decode(\"SGVsbG8h\")\n6-element Vector{UInt8}:\n 0x48\n 0x65\n 0x6c\n 0x6c\n 0x6f\n 0x21\n\njulia> String(b)\n\"Hello!\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Base64/#Base64.stringmime","page":"Base64","title":"Base64.stringmime","text":"stringmime(mime, x; context=nothing)\n\nReturn an AbstractString containing the representation of x in the requested mime type. This is similar to repr(mime, x) except that binary data is base64-encoded as an ASCII string.\n\nThe optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to show.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/FileWatching/docs/src/index.md\"","category":"page"},{"location":"stdlib/FileWatching/#lib-filewatching","page":"File Events","title":"File Events","text":"","category":"section"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"FileWatching.poll_fd\nFileWatching.poll_file\nFileWatching.watch_file\nFileWatching.watch_folder\nFileWatching.unwatch_folder","category":"page"},{"location":"stdlib/FileWatching/#FileWatching.poll_fd","page":"File Events","title":"FileWatching.poll_fd","text":"poll_fd(fd, timeout_s::Real=-1; readable=false, writable=false)\n\nMonitor a file descriptor fd for changes in the read or write availability, and with a timeout given by timeout_s seconds.\n\nThe keyword arguments determine which of read and/or write status should be monitored; at least one of them must be set to true.\n\nThe returned value is an object with boolean fields readable, writable, and timedout, giving the result of the polling.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.poll_file","page":"File Events","title":"FileWatching.poll_file","text":"poll_file(path::AbstractString, interval_s::Real=5.007, timeout_s::Real=-1) -> (previous::StatStruct, current)\n\nMonitor a file for changes by polling every interval_s seconds until a change occurs or timeout_s seconds have elapsed. The interval_s should be a long period; the default is 5.007 seconds.\n\nReturns a pair of status objects (previous, current) when a change is detected. The previous status is always a StatStruct, but it may have all of the fields zeroed (indicating the file didn't previously exist, or wasn't previously accessible).\n\nThe current status object may be a StatStruct, an EOFError (indicating the timeout elapsed), or some other Exception subtype (if the stat operation failed - for example, if the path does not exist).\n\nTo determine when a file was modified, compare current isa StatStruct && mtime(prev) != mtime(current) to detect notification of changes. However, using watch_file for this operation is preferred, since it is more reliable and efficient, although in some situations it may not be available.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.watch_file","page":"File Events","title":"FileWatching.watch_file","text":"watch_file(path::AbstractString, timeout_s::Real=-1)\n\nWatch file or directory path for changes until a change occurs or timeout_s seconds have elapsed. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.\n\nThe returned value is an object with boolean fields renamed, changed, and timedout, giving the result of watching the file.\n\nThis behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.watch_folder","page":"File Events","title":"FileWatching.watch_folder","text":"watch_folder(path::AbstractString, timeout_s::Real=-1)\n\nWatches a file or directory path for changes until a change has occurred or timeout_s seconds have elapsed. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.\n\nThis will continuing tracking changes for path in the background until unwatch_folder is called on the same path.\n\nThe returned value is an pair where the first field is the name of the changed file (if available) and the second field is an object with boolean fields renamed, changed, and timedout, giving the event.\n\nThis behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.unwatch_folder","page":"File Events","title":"FileWatching.unwatch_folder","text":"unwatch_folder(path::AbstractString)\n\nStop background tracking of changes for path. It is not recommended to do this while another task is waiting for watch_folder to return on the same path, as the result may be unpredictable.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#Pidfile","page":"File Events","title":"Pidfile","text":"","category":"section"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"CurrentModule = FileWatching.Pidfile","category":"page"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"A simple utility tool for creating advisory pidfiles (lock files).","category":"page"},{"location":"stdlib/FileWatching/#Primary-Functions","page":"File Events","title":"Primary Functions","text":"","category":"section"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"mkpidlock\ntrymkpidlock\nclose(lock::LockMonitor)","category":"page"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.mkpidlock","page":"File Events","title":"FileWatching.Pidfile.mkpidlock","text":"mkpidlock([f::Function], at::String, [pid::Cint]; kwopts...)\nmkpidlock(at::String, proc::Process; kwopts...)\n\nCreate a pidfile lock for the path \"at\" for the current process or the process identified by pid or proc. Can take a function to execute once locked, for usage in do blocks, after which the lock will be automatically closed. If the lock fails and wait is false, then an error is thrown.\n\nThe lock will be released by either close, a finalizer, or shortly after proc exits. Make sure the return value is live through the end of the critical section of your program, so the finalizer does not reclaim it early.\n\nOptional keyword arguments:\n\nmode: file access mode (modified by the process umask). Defaults to world-readable.\npoll_interval: Specify the maximum time to between attempts (if watch_file doesn't work)\nstale_age: Delete an existing pidfile (ignoring the lock) if it is older than this many seconds, based on its mtime. The file won't be deleted until 5x longer than this if the pid in the file appears that it may be valid. Or 25x longer if refresh is overridden to 0 to disable lock refreshing. By default this is disabled (stale_age = 0), but a typical recommended value would be about 3-5x an estimated normal completion time.\nrefresh: Keeps a lock from becoming stale by updating the mtime every interval of time that passes. By default, this is set to stale_age/2, which is the recommended value.\nwait: If true, block until we get the lock, if false, raise error if lock fails.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.trymkpidlock","page":"File Events","title":"FileWatching.Pidfile.trymkpidlock","text":"trymkpidlock([f::Function], at::String, [pid::Cint]; kwopts...)\ntrymkpidlock(at::String, proc::Process; kwopts...)\n\nLike mkpidlock except returns false instead of waiting if the file is already locked.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#Base.close-Tuple{FileWatching.Pidfile.LockMonitor}","page":"File Events","title":"Base.close","text":"close(lock::LockMonitor)\n\nRelease a pidfile lock.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/FileWatching/#Helper-Functions","page":"File Events","title":"Helper Functions","text":"","category":"section"},{"location":"stdlib/FileWatching/","page":"File Events","title":"File Events","text":"Pidfile.open_exclusive\nPidfile.tryopen_exclusive\nPidfile.write_pidfile\nPidfile.parse_pidfile\nPidfile.stale_pidfile\nPidfile.isvalidpid\nBase.touch(::Pidfile.LockMonitor)","category":"page"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.open_exclusive","page":"File Events","title":"FileWatching.Pidfile.open_exclusive","text":"open_exclusive(path::String; mode, poll_interval, wait, stale_age, refresh) :: File\n\nCreate a new a file for read-write advisory-exclusive access. If wait is false then error out if the lock files exist otherwise block until we get the lock.\n\nFor a description of the keyword arguments, see mkpidlock.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.tryopen_exclusive","page":"File Events","title":"FileWatching.Pidfile.tryopen_exclusive","text":"tryopen_exclusive(path::String, mode::Integer = 0o444) :: Union{Void, File}\n\nTry to create a new file for read-write advisory-exclusive access, return nothing if it already exists.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.write_pidfile","page":"File Events","title":"FileWatching.Pidfile.write_pidfile","text":"write_pidfile(io, pid)\n\nWrite our pidfile format to an open IO descriptor.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.parse_pidfile","page":"File Events","title":"FileWatching.Pidfile.parse_pidfile","text":"parse_pidfile(file::Union{IO, String}) => (pid, hostname, age)\n\nAttempt to parse our pidfile format, replaced an element with (0, \"\", 0.0), respectively, for any read that failed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.stale_pidfile","page":"File Events","title":"FileWatching.Pidfile.stale_pidfile","text":"stale_pidfile(path::String, stale_age::Real, refresh::Real) :: Bool\n\nHelper function for open_exclusive for deciding if a pidfile is stale.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#FileWatching.Pidfile.isvalidpid","page":"File Events","title":"FileWatching.Pidfile.isvalidpid","text":"isvalidpid(hostname::String, pid::Cuint) :: Bool\n\nAttempt to conservatively estimate whether pid is a valid process id.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/FileWatching/#Base.Filesystem.touch-Tuple{FileWatching.Pidfile.LockMonitor}","page":"File Events","title":"Base.Filesystem.touch","text":"Base.touch(::Pidfile.LockMonitor)\n\nUpdate the mtime on the lock, to indicate it is still fresh.\n\nSee also the refresh keyword in the mkpidlock constructor.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Logging/docs/src/index.md\"","category":"page"},{"location":"stdlib/Logging/#man-logging","page":"Logging","title":"Logging","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The Logging module provides a way to record the history and progress of a computation as a log of events. Events are created by inserting a logging statement into the source code, for example:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"@warn \"Abandon printf debugging, all ye who enter here!\"\n┌ Warning: Abandon printf debugging, all ye who enter here!\n└ @ Main REPL[1]:1","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The system provides several advantages over peppering your source code with calls to println(). First, it allows you to control the visibility and presentation of messages without editing the source code. For example, in contrast to the @warn above","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"@debug \"The sum of some values $(sum(rand(100)))\"","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"will produce no output by default. Furthermore, it's very cheap to leave debug statements like this in the source code because the system avoids evaluating the message if it would later be ignored. In this case sum(rand(100)) and the associated string processing will never be executed unless debug logging is enabled.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Second, the logging tools allow you to attach arbitrary data to each event as a set of key–value pairs. This allows you to capture local variables and other program state for later analysis. For example, to attach the local array variable A and the sum of a vector v as the key s you can use","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"A = ones(Int, 4, 4)\nv = ones(100)\n@info \"Some variables\" A s=sum(v)\n\n# output\n┌ Info: Some variables\n│ A =\n│ 4×4 Matrix{Int64}:\n│ 1 1 1 1\n│ 1 1 1 1\n│ 1 1 1 1\n│ 1 1 1 1\n└ s = 100.0","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"All of the logging macros @debug, @info, @warn and @error share common features that are described in detail in the documentation for the more general macro @logmsg.","category":"page"},{"location":"stdlib/Logging/#Log-event-structure","page":"Logging","title":"Log event structure","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Each event generates several pieces of data, some provided by the user and some automatically extracted. Let's examine the user-defined data first:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The log level is a broad category for the message that is used for early filtering. There are several standard levels of type LogLevel; user-defined levels are also possible. Each is distinct in purpose:\nLogging.Debug (log level -1000) is information intended for the developer of the program. These events are disabled by default.\nLogging.Info (log level 0) is for general information to the user. Think of it as an alternative to using println directly.\nLogging.Warn (log level 1000) means something is wrong and action is likely required but that for now the program is still working.\nLogging.Error (log level 2000) means something is wrong and it is unlikely to be recovered, at least by this part of the code. Often this log-level is unneeded as throwing an exception can convey all the required information.\nThe message is an object describing the event. By convention AbstractStrings passed as messages are assumed to be in markdown format. Other types will be displayed using print(io, obj) or string(obj) for text-based output and possibly show(io,mime,obj) for other multimedia displays used in the installed logger.\nOptional key–value pairs allow arbitrary data to be attached to each event. Some keys have conventional meaning that can affect the way an event is interpreted (see @logmsg).","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The system also generates some standard information for each event:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The module in which the logging macro was expanded.\nThe file and line where the logging macro occurs in the source code.\nA message id that is a unique, fixed identifier for the source code statement where the logging macro appears. This identifier is designed to be fairly stable even if the source code of the file changes, as long as the logging statement itself remains the same.\nA group for the event, which is set to the base name of the file by default, without extension. This can be used to group messages into categories more finely than the log level (for example, all deprecation warnings have group :depwarn), or into logical groupings across or within modules.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Notice that some useful information such as the event time is not included by default. This is because such information can be expensive to extract and is also dynamically available to the current logger. It's simple to define a custom logger to augment event data with the time, backtrace, values of global variables and other useful information as required.","category":"page"},{"location":"stdlib/Logging/#Processing-log-events","page":"Logging","title":"Processing log events","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"As you can see in the examples, logging statements make no mention of where log events go or how they are processed. This is a key design feature that makes the system composable and natural for concurrent use. It does this by separating two different concerns:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Creating log events is the concern of the module author who needs to decide where events are triggered and which information to include.\nProcessing of log events — that is, display, filtering, aggregation and recording — is the concern of the application author who needs to bring multiple modules together into a cooperating application.","category":"page"},{"location":"stdlib/Logging/#Loggers","page":"Logging","title":"Loggers","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Processing of events is performed by a logger, which is the first piece of user configurable code to see the event. All loggers must be subtypes of AbstractLogger.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"When an event is triggered, the appropriate logger is found by looking for a task-local logger with the global logger as fallback. The idea here is that the application code knows how log events should be processed and exists somewhere at the top of the call stack. So we should look up through the call stack to discover the logger — that is, the logger should be dynamically scoped. (This is a point of contrast with logging frameworks where the logger is lexically scoped; provided explicitly by the module author or as a simple global variable. In such a system it's awkward to control logging while composing functionality from multiple modules.)","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The global logger may be set with global_logger, and task-local loggers controlled using with_logger. Newly spawned tasks inherit the logger of the parent task.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"There are three logger types provided by the library. ConsoleLogger is the default logger you see when starting the REPL. It displays events in a readable text format and tries to give simple but user friendly control over formatting and filtering. NullLogger is a convenient way to drop all messages where necessary; it is the logging equivalent of the devnull stream. SimpleLogger is a very simplistic text formatting logger, mainly useful for debugging the logging system itself.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Custom loggers should come with overloads for the functions described in the reference section.","category":"page"},{"location":"stdlib/Logging/#Early-filtering-and-message-handling","page":"Logging","title":"Early filtering and message handling","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"When an event occurs, a few steps of early filtering occur to avoid generating messages that will be discarded:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"The message log level is checked against a global minimum level (set via disable_logging). This is a crude but extremely cheap global setting.\nThe current logger state is looked up and the message level checked against the logger's cached minimum level, as found by calling Logging.min_enabled_level. This behavior can be overridden via environment variables (more on this later).\nThe Logging.shouldlog function is called with the current logger, taking some minimal information (level, module, group, id) which can be computed statically. Most usefully, shouldlog is passed an event id which can be used to discard events early based on a cached predicate.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"If all these checks pass, the message and key–value pairs are evaluated in full and passed to the current logger via the Logging.handle_message function. handle_message() may perform additional filtering as required and display the event to the screen, save it to a file, etc.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Exceptions that occur while generating the log event are captured and logged by default. This prevents individual broken events from crashing the application, which is helpful when enabling little-used debug events in a production system. This behavior can be customized per logger type by extending Logging.catch_exceptions.","category":"page"},{"location":"stdlib/Logging/#Testing-log-events","page":"Logging","title":"Testing log events","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Log events are a side effect of running normal code, but you might find yourself wanting to test particular informational messages and warnings. The Test module provides a @test_logs macro that can be used to pattern match against the log event stream.","category":"page"},{"location":"stdlib/Logging/#Environment-variables","page":"Logging","title":"Environment variables","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Message filtering can be influenced through the JULIA_DEBUG environment variable, and serves as an easy way to enable debug logging for a file or module. Loading julia with JULIA_DEBUG=loading will activate @debug log messages in loading.jl. For example, in Linux shells:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"$ JULIA_DEBUG=loading julia -e 'using OhMyREPL'\n┌ Debug: Rejecting cache file /home/user/.julia/compiled/v0.7/OhMyREPL.ji due to it containing an invalid cache header\n└ @ Base loading.jl:1328\n[ Info: Recompiling stale cache file /home/user/.julia/compiled/v0.7/OhMyREPL.ji for module OhMyREPL\n┌ Debug: Rejecting cache file /home/user/.julia/compiled/v0.7/Tokenize.ji due to it containing an invalid cache header\n└ @ Base loading.jl:1328\n...","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"On windows, the same can be achieved in CMD via first running set JULIA_DEBUG=\"loading\" and in Powershell via $env:JULIA_DEBUG=\"loading\".","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Similarly, the environment variable can be used to enable debug logging of modules, such as Pkg, or module roots (see Base.moduleroot). To enable all debug logging, use the special value all.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"To turn debug logging on from the REPL, set ENV[\"JULIA_DEBUG\"] to the name of the module of interest. Functions defined in the REPL belong to module Main; logging for them can be enabled like this:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"julia> foo() = @debug \"foo\"\nfoo (generic function with 1 method)\n\njulia> foo()\n\njulia> ENV[\"JULIA_DEBUG\"] = Main\nMain\n\njulia> foo()\n┌ Debug: foo\n└ @ Main REPL[1]:1\n","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Use a comma separator to enable debug for multiple modules: JULIA_DEBUG=loading,Main.","category":"page"},{"location":"stdlib/Logging/#Examples","page":"Logging","title":"Examples","text":"","category":"section"},{"location":"stdlib/Logging/#Example:-Writing-log-events-to-a-file","page":"Logging","title":"Example: Writing log events to a file","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Sometimes it can be useful to write log events to a file. Here is an example of how to use a task-local and global logger to write information to a text file:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"# Load the logging module\njulia> using Logging\n\n# Open a textfile for writing\njulia> io = open(\"log.txt\", \"w+\")\nIOStream()\n\n# Create a simple logger\njulia> logger = SimpleLogger(io)\nSimpleLogger(IOStream(), Info, Dict{Any,Int64}())\n\n# Log a task-specific message\njulia> with_logger(logger) do\n @info(\"a context specific log message\")\n end\n\n# Write all buffered messages to the file\njulia> flush(io)\n\n# Set the global logger to logger\njulia> global_logger(logger)\nSimpleLogger(IOStream(), Info, Dict{Any,Int64}())\n\n# This message will now also be written to the file\njulia> @info(\"a global log message\")\n\n# Close the file\njulia> close(io)","category":"page"},{"location":"stdlib/Logging/#Example:-Enable-debug-level-messages","page":"Logging","title":"Example: Enable debug-level messages","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Here is an example of creating a ConsoleLogger that lets through any messages with log level higher than, or equal, to Logging.Debug.","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"julia> using Logging\n\n# Create a ConsoleLogger that prints any log messages with level >= Debug to stderr\njulia> debuglogger = ConsoleLogger(stderr, Logging.Debug)\n\n# Enable debuglogger for a task\njulia> with_logger(debuglogger) do\n @debug \"a context specific log message\"\n end\n\n# Set the global logger\njulia> global_logger(debuglogger)","category":"page"},{"location":"stdlib/Logging/#Reference","page":"Logging","title":"Reference","text":"","category":"section"},{"location":"stdlib/Logging/#Logging-module","page":"Logging","title":"Logging module","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.Logging","category":"page"},{"location":"stdlib/Logging/#Logging.Logging","page":"Logging","title":"Logging.Logging","text":"Utilities for capturing, filtering and presenting streams of log events. Normally you don't need to import Logging to create log events; for this the standard logging macros such as @info are already exported by Base and available by default.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Logging/#Creating-events","page":"Logging","title":"Creating events","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.@logmsg\nLogging.LogLevel\nLogging.Debug\nLogging.Info\nLogging.Warn\nLogging.Error\nLogging.BelowMinLevel\nLogging.AboveMaxLevel","category":"page"},{"location":"stdlib/Logging/#Logging.@logmsg","page":"Logging","title":"Logging.@logmsg","text":"@debug message [key=value | value ...]\n@info message [key=value | value ...]\n@warn message [key=value | value ...]\n@error message [key=value | value ...]\n\n@logmsg level message [key=value | value ...]\n\nCreate a log record with an informational message. For convenience, four logging macros @debug, @info, @warn and @error are defined which log at the standard severity levels Debug, Info, Warn and Error. @logmsg allows level to be set programmatically to any LogLevel or custom log level types.\n\nmessage should be an expression which evaluates to a string which is a human readable description of the log event. By convention, this string will be formatted as markdown when presented.\n\nThe optional list of key=value pairs supports arbitrary user defined metadata which will be passed through to the logging backend as part of the log record. If only a value expression is supplied, a key representing the expression will be generated using Symbol. For example, x becomes x=x, and foo(10) becomes Symbol(\"foo(10)\")=foo(10). For splatting a list of key value pairs, use the normal splatting syntax, @info \"blah\" kws....\n\nThere are some keys which allow automatically generated log data to be overridden:\n\n_module=mod can be used to specify a different originating module from the source location of the message.\n_group=symbol can be used to override the message group (this is normally derived from the base name of the source file).\n_id=symbol can be used to override the automatically generated unique message identifier. This is useful if you need to very closely associate messages generated on different source lines.\n_file=string and _line=integer can be used to override the apparent source location of a log message.\n\nThere's also some key value pairs which have conventional meaning:\n\nmaxlog=integer should be used as a hint to the backend that the message should be displayed no more than maxlog times.\nexception=ex should be used to transport an exception with a log message, often used with @error. An associated backtrace bt may be attached using the tuple exception=(ex,bt).\n\nExamples\n\n@debug \"Verbose debugging information. Invisible by default\"\n@info \"An informational message\"\n@warn \"Something was odd. You should pay attention\"\n@error \"A non fatal error occurred\"\n\nx = 10\n@info \"Some variables attached to the message\" x a=42.0\n\n@debug begin\n sA = sum(A)\n \"sum(A) = $sA is an expensive operation, evaluated only when `shouldlog` returns true\"\nend\n\nfor i=1:10000\n @info \"With the default backend, you will only see (i = $i) ten times\" maxlog=10\n @debug \"Algorithm1\" i progress=i/10000\nend\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Logging/#Logging.LogLevel","page":"Logging","title":"Logging.LogLevel","text":"LogLevel(level)\n\nSeverity/verbosity of a log record.\n\nThe log level provides a key against which potential log records may be filtered, before any other work is done to construct the log record data structure itself.\n\nExamples\n\njulia> Logging.LogLevel(0) == Logging.Info\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Logging/#Logging.Debug","page":"Logging","title":"Logging.Debug","text":"Debug\n\nAlias for LogLevel(-1000).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.Info","page":"Logging","title":"Logging.Info","text":"Info\n\nAlias for LogLevel(0).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.Warn","page":"Logging","title":"Logging.Warn","text":"Warn\n\nAlias for LogLevel(1000).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.Error","page":"Logging","title":"Logging.Error","text":"Error\n\nAlias for LogLevel(2000).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.BelowMinLevel","page":"Logging","title":"Logging.BelowMinLevel","text":"BelowMinLevel\n\nAlias for LogLevel(-1_000_001).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#Logging.AboveMaxLevel","page":"Logging","title":"Logging.AboveMaxLevel","text":"AboveMaxLevel\n\nAlias for LogLevel(1_000_001).\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Logging/#AbstractLogger-interface","page":"Logging","title":"Processing events with AbstractLogger","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Event processing is controlled by overriding functions associated with AbstractLogger:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Methods to implement Brief description\nLogging.handle_message Handle a log event\nLogging.shouldlog Early filtering of events\nLogging.min_enabled_level Lower bound for log level of accepted events\nOptional methods Default definition Brief description\nLogging.catch_exceptions true Catch exceptions during event evaluation","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.AbstractLogger\nLogging.handle_message\nLogging.shouldlog\nLogging.min_enabled_level\nLogging.catch_exceptions\nLogging.disable_logging","category":"page"},{"location":"stdlib/Logging/#Logging.AbstractLogger","page":"Logging","title":"Logging.AbstractLogger","text":"A logger controls how log records are filtered and dispatched. When a log record is generated, the logger is the first piece of user configurable code which gets to inspect the record and decide what to do with it.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Logging/#Logging.handle_message","page":"Logging","title":"Logging.handle_message","text":"handle_message(logger, level, message, _module, group, id, file, line; key1=val1, ...)\n\nLog a message to logger at level. The logical location at which the message was generated is given by module _module and group; the source location by file and line. id is an arbitrary unique value (typically a Symbol) to be used as a key to identify the log statement when filtering.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.shouldlog","page":"Logging","title":"Logging.shouldlog","text":"shouldlog(logger, level, _module, group, id)\n\nReturn true when logger accepts a message at level, generated for _module, group and with unique log identifier id.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.min_enabled_level","page":"Logging","title":"Logging.min_enabled_level","text":"min_enabled_level(logger)\n\nReturn the minimum enabled level for logger for early filtering. That is, the log level below or equal to which all messages are filtered.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.catch_exceptions","page":"Logging","title":"Logging.catch_exceptions","text":"catch_exceptions(logger)\n\nReturn true if the logger should catch exceptions which happen during log record construction. By default, messages are caught\n\nBy default all exceptions are caught to prevent log message generation from crashing the program. This lets users confidently toggle little-used functionality - such as debug logging - in a production system.\n\nIf you want to use logging as an audit trail you should disable this for your logger type.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.disable_logging","page":"Logging","title":"Logging.disable_logging","text":"disable_logging(level)\n\nDisable all log messages at log levels equal to or less than level. This is a global setting, intended to make debug logging extremely cheap when disabled.\n\nExamples\n\nLogging.disable_logging(Logging.Info) # Disable debug and info\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Using-Loggers","page":"Logging","title":"Using Loggers","text":"","category":"section"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logger installation and inspection:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.global_logger\nLogging.with_logger\nLogging.current_logger","category":"page"},{"location":"stdlib/Logging/#Logging.global_logger","page":"Logging","title":"Logging.global_logger","text":"global_logger()\n\nReturn the global logger, used to receive messages when no specific logger exists for the current task.\n\nglobal_logger(logger)\n\nSet the global logger to logger, and return the previous global logger.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.with_logger","page":"Logging","title":"Logging.with_logger","text":"with_logger(function, logger)\n\nExecute function, directing all log messages to logger.\n\nExamples\n\nfunction test(x)\n @info \"x = $x\"\nend\n\nwith_logger(logger) do\n test(1)\n test([1,2])\nend\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/#Logging.current_logger","page":"Logging","title":"Logging.current_logger","text":"current_logger()\n\nReturn the logger for the current task, or the global logger if none is attached to the task.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Loggers that are supplied with the system:","category":"page"},{"location":"stdlib/Logging/","page":"Logging","title":"Logging","text":"Logging.NullLogger\nLogging.ConsoleLogger\nLogging.SimpleLogger","category":"page"},{"location":"stdlib/Logging/#Logging.NullLogger","page":"Logging","title":"Logging.NullLogger","text":"NullLogger()\n\nLogger which disables all messages and produces no output - the logger equivalent of /dev/null.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Logging/#Logging.ConsoleLogger","page":"Logging","title":"Logging.ConsoleLogger","text":"ConsoleLogger([stream,] min_level=Info; meta_formatter=default_metafmt,\n show_limited=true, right_justify=0)\n\nLogger with formatting optimized for readability in a text console, for example interactive work with the Julia REPL.\n\nLog levels less than min_level are filtered out.\n\nMessage formatting can be controlled by setting keyword arguments:\n\nmeta_formatter is a function which takes the log event metadata (level, _module, group, id, file, line) and returns a face name (used in the constructed AnnotatedString), prefix and suffix for the log message. The default is to prefix with the log level and a suffix containing the module, file and line location.\nshow_limited limits the printing of large data structures to something which can fit on the screen by setting the :limit IOContext key during formatting.\nright_justify is the integer column which log metadata is right justified at. The default is zero (metadata goes on its own line).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Logging/#Logging.SimpleLogger","page":"Logging","title":"Logging.SimpleLogger","text":"SimpleLogger([stream,] min_level=Info)\n\nSimplistic logger for logging all messages with level greater than or equal to min_level to stream. If stream is closed then messages with log level greater or equal to Warn will be logged to stderr and below to stdout.\n\n\n\n\n\n","category":"type"},{"location":"tutorials/creating-packages/#creating-packages-tutorial","page":"Creating Packages","title":"Creating Packages","text":"","category":"section"},{"location":"tutorials/creating-packages/#Generating-files-for-a-package","page":"Creating Packages","title":"Generating files for a package","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nThe PkgTemplates package offers an easy, repeatable, and customizable way to generate the files for a new package. It can also generate files needed for Documentation, CI, etc. We recommend that you use PkgTemplates for creating new packages instead of using the minimal pkg> generate functionality described below.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"To generate the bare minimum files for a new package, use pkg> generate.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"(@v1.8) pkg> generate HelloWorld","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"This creates a new project HelloWorld in a subdirectory by the same name, with the following files (visualized with the external tree command):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"shell> tree HelloWorld/\nHelloWorld/\n├── Project.toml\n└── src\n └── HelloWorld.jl\n\n2 directories, 2 files","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The Project.toml file contains the name of the package, its unique UUID, its version, the authors and potential dependencies:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"name = \"HelloWorld\"\nuuid = \"b4cd1eb8-1e24-11e8-3319-93036a3eb9f3\"\nversion = \"0.1.0\"\nauthors = [\"Some One \"]\n\n[deps]","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The content of src/HelloWorld.jl is:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module HelloWorld\n\ngreet() = print(\"Hello World!\")\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We can now activate the project by using the path to the directory where it is installed, and load the package:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"pkg> activate ./HelloWorld\n\njulia> import HelloWorld\n\njulia> HelloWorld.greet()\nHello World!","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"For the rest of the tutorial we enter inside the directory of the project, for convenience:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> cd(\"HelloWorld\")","category":"page"},{"location":"tutorials/creating-packages/#Adding-dependencies-to-the-project","page":"Creating Packages","title":"Adding dependencies to the project","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Let’s say we want to use the standard library package Random and the registered package JSON in our project. We simply add these packages (note how the prompt now shows the name of the newly generated project, since we activated it):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"(HelloWorld) pkg> add Random JSON\n Resolving package versions...\n Updating `~/HelloWorld/Project.toml`\n [682c06a0] + JSON v0.21.3\n [9a3f8284] + Random\n Updating `~/HelloWorld/Manifest.toml`\n [682c06a0] + JSON v0.21.3\n [69de0a69] + Parsers v2.4.0\n [ade2ca70] + Dates\n ...","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Both Random and JSON got added to the project’s Project.toml file, and the resulting dependencies got added to the Manifest.toml file. The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforces on its dependencies.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We can now use both Random and JSON in our project. Changing src/HelloWorld.jl to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module HelloWorld\n\nimport Random\nimport JSON\n\ngreet() = print(\"Hello World!\")\ngreet_alien() = print(\"Hello \", Random.randstring(8))\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"and reloading the package, the new greet_alien function that uses Random can be called:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> HelloWorld.greet_alien()\nHello aT157rHV","category":"page"},{"location":"tutorials/creating-packages/#Defining-a-public-API","page":"Creating Packages","title":"Defining a public API","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"If you want your package to be useful to other packages and you want folks to be able to easily update to newer version of your package when they come out, it is important to document what behavior will stay consistent across updates.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Unless you note otherwise, the public API of your package is defined as all the behavior you describe about public symbols. A public symbol is a symbol that is exported from your package with the export keyword or marked as public with the public keyword. When you change the behavior of something that was previously public so that the new version no longer conforms to the specifications provided in the old version, you should adjust your package version number according to Julia's variant on SemVer. If you would like to include a symbol in your public API without exporting it into the global namespace of folks who call using YourPackage, you should mark that symbol as public with public that_symbol. Symbols marked as public with the public keyword are just as public as those marked as public with the export keyword, but when folks call using YourPackage, they will still have to qualify access to those symbols with YourPackage.that_symbol.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Let's say we would like our greet function to be part of the public API, but not the greet_alien function. We could the write the following and release it as version 1.0.0.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module HelloWorld\n\nexport greet\n\nimport Random\nimport JSON\n\n\"Writes a friendly message.\"\ngreet() = print(\"Hello World!\")\n\n\"Greet an alien by a randomly generated name.\"\ngreet_alien() = print(\"Hello \", Random.randstring(8))\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Then, if we change greet to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"\"Writes a friendly message that is exactly three words long.\"\ngreet() = print(\"Hello Lovely World!\")","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We would release the new version as 1.1.0. This is not breaking because the new implementation conforms to the old documentation, but it does add a new feature, that the message must be three words long.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Later, we may wish to change greet_alien to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"\"Greet an alien by the name of \\\"Zork\\\".\"\ngreet_alien() = print(\"Hello Zork\")","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"And also export it by changing","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"export greet","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"export greet, greet_alien","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We should release this new version as 1.2.0 because it adds a new feature greet_alien to the public API. Even though greet_alien was documented before and the new version does not conform to the old documentation, this is not breaking because the old documentation was not attached to a symbol that was exported at the time so that documentation does not apply across released versions.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"However, if we now wish to change greet to","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"\"Writes a friendly message that is exactly four words long.\"\ngreet() = print(\"Hello very lovely world\")","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"we would need to release the new version as 2.0.0. In version 1.1.0, we specified that the greeting would be three words long, and because greet was exported, that description also applies to all future versions until the next breaking release. Because this new version does not conform to the old specification, it must be tagged as a breaking change.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Please note that version numbers are free and unlimited. It is okay to use lots of them (e.g. version 6.62.8).","category":"page"},{"location":"tutorials/creating-packages/#Adding-a-build-step-to-the-package","page":"Creating Packages","title":"Adding a build step to the package","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The build step is executed the first time a package is installed or when explicitly invoked with build. A package is built by executing the file deps/build.jl.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> mkpath(\"deps\");\n\njulia> write(\"deps/build.jl\",\n \"\"\"\n println(\"I am being built...\")\n \"\"\");\n\n(HelloWorld) pkg> build\n Building HelloWorld → `deps/build.log`\n Resolving package versions...\n\njulia> print(readchomp(\"deps/build.log\"))\nI am being built...","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"If the build step fails, the output of the build step is printed to the console","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> write(\"deps/build.jl\",\n \"\"\"\n error(\"Ooops\")\n \"\"\");\n\n(HelloWorld) pkg> build\n Building HelloWorld → `~/HelloWorld/deps/build.log`\nERROR: Error building `HelloWorld`:\nERROR: LoadError: Ooops\nStacktrace:\n [1] error(s::String)\n @ Base ./error.jl:35\n [2] top-level scope\n @ ~/HelloWorld/deps/build.jl:1\n [3] include(fname::String)\n @ Base.MainInclude ./client.jl:476\n [4] top-level scope\n @ none:5\nin expression starting at /home/kc/HelloWorld/deps/build.jl:1","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"warning: Warning\nA build step should generally not create or modify any files in the package directory. If you need to store some files from the build step, use the Scratch.jl package.","category":"page"},{"location":"tutorials/creating-packages/#adding-tests-to-packages","page":"Creating Packages","title":"Adding tests to the package","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"When a package is tested the file test/runtests.jl is executed:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> mkpath(\"test\");\n\njulia> write(\"test/runtests.jl\",\n \"\"\"\n println(\"Testing...\")\n \"\"\");\n\n(HelloWorld) pkg> test\n Testing HelloWorld\n Resolving package versions...\nTesting...\n Testing HelloWorld tests passed","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Tests are run in a new Julia process, where the package itself, and any test-specific dependencies, are available, see below.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"warning: Warning\nTests should generally not create or modify any files in the package directory. If you need to store some files from the build step, use the Scratch.jl package.","category":"page"},{"location":"tutorials/creating-packages/#Test-specific-dependencies","page":"Creating Packages","title":"Test-specific dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"There are two ways of adding test-specific dependencies (dependencies that are not dependencies of the package but will still be available to load when the package is tested).","category":"page"},{"location":"tutorials/creating-packages/#target-based-test-specific-dependencies","page":"Creating Packages","title":"target based test specific dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Using this method of adding test-specific dependencies, the packages are added under an [extras] section and to a test target, e.g. to add Markdown and Test as test dependencies, add the following to the Project.toml file:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"[extras]\nMarkdown = \"d6f4376e-aef5-505a-96c1-9c027394607a\"\nTest = \"8dfed614-e22c-5e08-85e1-65c5234f0b40\"\n\n[targets]\ntest = [\"Markdown\", \"Test\"]","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Note that the only supported targets are test and build, the latter of which (not recommended) can be used for any deps/build.jl scripts.","category":"page"},{"location":"tutorials/creating-packages/#Alternative-approach:-test/Project.toml-file-test-specific-dependencies","page":"Creating Packages","title":"Alternative approach: test/Project.toml file test specific dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nThe exact interaction between Project.toml, test/Project.toml and their corresponding Manifest.tomls are not fully worked out and may be subject to change in future versions. The older method of adding test-specific dependencies, described in the previous section, will therefore be supported throughout all Julia 1.X releases.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"In Julia 1.2 and later test dependencies can be declared in test/Project.toml. When running tests, Pkg will automatically merge this and the package Projects to create the test environment.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nIf no test/Project.toml exists Pkg will use the target based test specific dependencies.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"To add a test-specific dependency, i.e. a dependency that is available only when testing, it is thus enough to add this dependency to the test/Project.toml project. This can be done from the Pkg REPL by activating this environment, and then use add as one normally does. Let's add the Test standard library as a test dependency:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"(HelloWorld) pkg> activate ./test\n[ Info: activating environment at `~/HelloWorld/test/Project.toml`.\n\n(test) pkg> add Test\n Resolving package versions...\n Updating `~/HelloWorld/test/Project.toml`\n [8dfed614] + Test\n Updating `~/HelloWorld/test/Manifest.toml`\n [...]","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"We can now use Test in the test script and we can see that it gets installed when testing:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"julia> write(\"test/runtests.jl\",\n \"\"\"\n using Test\n @test 1 == 1\n \"\"\");\n\n(test) pkg> activate .\n\n(HelloWorld) pkg> test\n Testing HelloWorld\n Resolving package versions...\n Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Project.toml`\n [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`]\n [8dfed614] + Test\n Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Manifest.toml`\n [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`]\n Testing HelloWorld tests passed```","category":"page"},{"location":"tutorials/creating-packages/#Compatibility-on-dependencies","page":"Creating Packages","title":"Compatibility on dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Every dependency should in general have a compatibility constraint on it. This is an important topic so there is a chapter in the package docs about it: Compatibility.","category":"page"},{"location":"tutorials/creating-packages/#Weak-dependencies","page":"Creating Packages","title":"Weak dependencies","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nThis is a somewhat advanced usage of Pkg which can be skipped for people new to Julia and Julia packages.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"compat: Compat\nThe described feature requires Julia 1.9+.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"A weak dependency is a dependency that will not automatically install when the package is installed but you can still control what versions of that package are allowed to be installed by setting compatibility on it. These are listed in the project file under the [weakdeps] section:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"[weakdeps]\nSomePackage = \"b3785f31-9d33-4cdf-bc73-f646780f1739\"\n\n[compat]\nSomePackage = \"1.2\"","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The current usage of this is almost solely limited to \"extensions\" which is described in the next section.","category":"page"},{"location":"tutorials/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)","page":"Creating Packages","title":"Conditional loading of code in packages (Extensions)","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nThis is a somewhat advanced usage of Pkg which can be skipped for people new to Julia and Julia packages.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"compat: Compat\nThe described feature requires Julia 1.9+.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Sometimes one wants to make two or more packages work well together, but may be reluctant (perhaps due to increased load times) to make one an unconditional dependency of the other. A package extension is a module in a file (similar to a package) that is automatically loaded when some other set of packages are loaded into the Julia session. This is very similar to functionality that the external package Requires.jl provides, but which is now available directly through Julia, and provides added benefits such as being able to precompile the extension.","category":"page"},{"location":"tutorials/creating-packages/#Code-structure","page":"Creating Packages","title":"Code structure","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"A useful application of extensions could be for a plotting package that should be able to plot objects from a wide variety of different Julia packages. Adding all those different Julia packages as dependencies of the plotting package could be expensive since they would end up getting loaded even if they were never used. Instead, the code required to plot objects for specific packages can be put into separate files (extensions) and these are loaded only when the packages that define the type(s) we want to plot are loaded.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Below is an example of how the code can be structured for a use case in which a Plotting package wants to be able to display objects defined in the external package Contour. The file and folder structure shown below is found in the Plotting package.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Project.toml:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"name = \"Plotting\"\nversion = \"0.1.0\"\nuuid = \"...\"\n\n[weakdeps]\nContour = \"d38c429a-6771-53c6-b99e-75d170b6e991\"\n\n[extensions]\n# name of extension to the left\n# extension dependencies required to load the extension to the right\n# use a list for multiple extension dependencies\nPlottingContourExt = \"Contour\"\n\n[compat]\nContour = \"0.6.2\"","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"src/Plotting.jl:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module Plotting\n\nfunction plot(x::Vector)\n # Some functionality for plotting a vector here\nend\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"ext/PlottingContourExt.jl (can also be in ext/PlottingContourExt/PlottingContourExt.jl):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"module PlottingContourExt # Should be same name as the file (just like a normal package)\n\nusing Plotting, Contour\n\nfunction Plotting.plot(c::Contour.ContourCollection)\n # Some functionality for plotting a contour here\nend\n\nend # module","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Extensions can have any arbitrary name (here PlottingContourExt), but using something similar to the format of this example that makes the extended functionality and dependency of the extension clear is likely a good idea.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"compat: Compat\nOften you will put the extension dependencies into the test target so they are loaded when running e.g. Pkg.test(). On earlier Julia versions this requires you to also put the package in the [extras] section. This is unfortunate but the project verifier on older Julia versions will complain if this is not done.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nIf you use a manifest generated by a Julia version that does not know about extensions with a Julia version that does know about them, the extensions will not load. This is because the manifest lacks some information that tells Julia when it should load these packages. So make sure you use a manifest generated at least the Julia version you are using.","category":"page"},{"location":"tutorials/creating-packages/#Behavior-of-extensions","page":"Creating Packages","title":"Behavior of extensions","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"A user that depends only on Plotting will not pay the cost of the \"extension\" inside the PlottingContourExt module. It is only when the Contour package actually gets loaded that the PlottingContourExt extension is loaded too and provides the new functionality.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"In our example, the new functionality is an additional method, which we add to an existing function from the parent package Plotting. Implementing such methods is among the most standard use cases of package extensions. Within the parent package, the function to extend can even be defined with zero methods, as follows:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"function plot end","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"note: Note\nIf one considers PlottingContourExt as a completely separate package, it could be argued that defining Plotting.plot(c::Contour.ContourCollection) is type piracy since PlottingContourExt owns neither the function Plotting.plot nor the type Contour.ContourCollection. However, for extensions, it is ok to assume that the extension owns the functions in its parent package.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"In other situations, one may need to define new symbols in the extension (types, structs, functions, etc.) instead of reusing those from the parent package. Such symbols are created in a separate module corresponding to the extension, namely PlottingContourExt, and thus not in Plotting itself. If extension symbols are needed in the parent package, one must call Base.get_extension to retrieve them. Here is an example showing how a custom type defined in PlottingContourExt can be accessed in Plotting:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"ext = Base.get_extension(@__MODULE__, :PlottingContourExt)\nif !isnothing(ext)\n ContourPlotType = ext.ContourPlotType\nend","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"On the other hand, accessing extension symbols from a third-party package (i.e. not the parent) is not a recommended practice at the moment.","category":"page"},{"location":"tutorials/creating-packages/#Backwards-compatibility","page":"Creating Packages","title":"Backwards compatibility","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"This section discusses various methods for using extensions on Julia versions that support them, while simultaneously providing similar functionality on older Julia versions.","category":"page"},{"location":"tutorials/creating-packages/#Requires.jl","page":"Creating Packages","title":"Requires.jl","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"This section is relevant if you are currently using Requires.jl but want to transition to using extensions (while still having Requires be used on Julia versions that do not support extensions). This is done by making the following changes (using the example above):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Add the following to the package file. This makes it so that Requires.jl loads and inserts the callback only when extensions are not supported\n# This symbol is only defined on Julia versions that support extensions\nif !isdefined(Base, :get_extension)\nusing Requires\nend\n\n@static if !isdefined(Base, :get_extension)\nfunction __init__()\n @require Contour = \"d38c429a-6771-53c6-b99e-75d170b6e991\" include(\"../ext/PlottingContourExt.jl\")\nend\nend\nor if you have other things in your __init__() function:\nif !isdefined(Base, :get_extension)\nusing Requires\nend\n\nfunction __init__()\n # Other init functionality here\n\n @static if !isdefined(Base, :get_extension)\n @require Contour = \"d38c429a-6771-53c6-b99e-75d170b6e991\" include(\"../ext/PlottingContourExt.jl\")\n end\nend\nMake the following change in the conditionally-loaded code:\nisdefined(Base, :get_extension) ? (using Contour) : (using ..Contour)\nAdd Requires to [weakdeps] in your Project.toml file, so that it is listed in both [deps] and [weakdeps]. Julia 1.9+ knows to not install it as a regular dependency, whereas earlier versions will consider it a dependency.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"The package should now work with Requires.jl on Julia versions before extensions were introduced and with extensions on more recent Julia versions.","category":"page"},{"location":"tutorials/creating-packages/#Transition-from-normal-dependency-to-extension","page":"Creating Packages","title":"Transition from normal dependency to extension","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"This section is relevant if you have a normal dependency that you want to transition be an extension (while still having the dependency be a normal dependency on Julia versions that do not support extensions). This is done by making the following changes (using the example above):","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Make sure that the package is both in the [deps] and [weakdeps] section. Newer Julia versions will ignore dependencies in [deps] that are also in [weakdeps].\nAdd the following to your main package file (typically at the bottom):\nif !isdefined(Base, :get_extension)\n include(\"../ext/PlottingContourExt.jl\")\nend","category":"page"},{"location":"tutorials/creating-packages/#Using-an-extension-while-supporting-older-Julia-versions","page":"Creating Packages","title":"Using an extension while supporting older Julia versions","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"In the case where one wants to use an extension (without worrying about the feature of the extension being available on older Julia versions) while still supporting older Julia versions the packages under [weakdeps] should be duplicated into [extras]. This is an unfortunate duplication, but without doing this the project verifier under older Julia versions will throw an error if it finds packages under [compat] that is not listed in [extras].","category":"page"},{"location":"tutorials/creating-packages/#Package-naming-rules","page":"Creating Packages","title":"Package naming rules","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Package names should be sensible to most Julia users, even to those who are not domain experts. The following rules apply to the General registry but may be useful for other package registries as well.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Since the General registry belongs to the entire community, people may have opinions about your package name when you publish it, especially if it's ambiguous or can be confused with something other than what it is. Usually, you will then get suggestions for a new name that may fit your package better.","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Avoid jargon. In particular, avoid acronyms unless there is minimal possibility of confusion.\nIt's ok to say USA if you're talking about the USA.\nIt's not ok to say PMA, even if you're talking about positive mental attitude.\nAvoid using Julia in your package name or prefixing it with Ju.\nIt is usually clear from context and to your users that the package is a Julia package.\nPackage names already have a .jl extension, which communicates to users that Package.jl is a Julia package.\nHaving Julia in the name can imply that the package is connected to, or endorsed by, contributors to the Julia language itself.\nPackages that provide most of their functionality in association with a new type should have pluralized names.\nDataFrames provides the DataFrame type.\nBloomFilters provides the BloomFilter type.\nIn contrast, JuliaParser provides no new type, but instead new functionality in the JuliaParser.parse() function.\nErr on the side of clarity, even if clarity seems long-winded to you.\nRandomMatrices is a less ambiguous name than RndMat or RMT, even though the latter are shorter.\nA less systematic name may suit a package that implements one of several possible approaches to its domain.\nJulia does not have a single comprehensive plotting package. Instead, Gadfly, PyPlot, Winston and other packages each implement a unique approach based on a particular design philosophy.\nIn contrast, SortingAlgorithms provides a consistent interface to use many well-established sorting algorithms.\nPackages that wrap external libraries or programs can be named after those libraries or programs.\nCPLEX.jl wraps the CPLEX library, which can be identified easily in a web search.\nMATLAB.jl provides an interface to call the MATLAB engine from within Julia.\nAvoid naming a package closely to an existing package\nWebsocket is too close to WebSockets and can be confusing to users. Rather use a new name such as SimpleWebsockets.\nAvoid using a distinctive name that is already in use in a well known, unrelated project.\nDon't use the names Tkinter.jl, TkinterGUI.jl, etc. for a package that is unrelated to the popular tkinter python package, even if it provides bindings to Tcl/Tk. A package name of Tkinter.jl would only be appropriate if the package used Python's library to accomplish its work or was spearheaded by the same community of developers.\nIt's okay to name a package HTTP.jl even though it is unrelated to the popular rust crate http because in most usages the name \"http\" refers to the hypertext transfer protocol, not to the http rust crate.\nIt's okay to name a package OpenSSL.jl if it provides an interface to the OpenSSL library, even without explicit affiliation with the creators of the OpenSSL (provided there's no copyright or trademark infringement etc.)","category":"page"},{"location":"tutorials/creating-packages/#Registering-packages","page":"Creating Packages","title":"Registering packages","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Once a package is ready it can be registered with the General Registry (see also the FAQ). Currently, packages are submitted via Registrator. In addition to Registrator, TagBot helps manage the process of tagging releases.","category":"page"},{"location":"tutorials/creating-packages/#Best-Practices","page":"Creating Packages","title":"Best Practices","text":"","category":"section"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Packages should avoid mutating their own state (writing to files within their package directory). Packages should, in general, not assume that they are located in a writable location (e.g. if installed as part of a system-wide depot) or even a stable one (e.g. if they are bundled into a system image by PackageCompiler.jl). To support the various use cases in the Julia package ecosystem, the Pkg developers have created a number of auxiliary packages and techniques to help package authors create self-contained, immutable, and relocatable packages:","category":"page"},{"location":"tutorials/creating-packages/","page":"Creating Packages","title":"Creating Packages","text":"Artifacts can be used to bundle chunks of data alongside your package, or even allow them to be downloaded on-demand. Prefer artifacts over attempting to open a file via a path such as joinpath(@__DIR__, \"data\", \"my_dataset.csv\") as this is non-relocatable. Once your package has been precompiled, the result of @__DIR__ will have been baked into your precompiled package data, and if you attempt to distribute this package, it will attempt to load files at the wrong location. Artifacts can be bundled and accessed easily using the artifact\"name\" string macro.\nScratch.jl provides the notion of \"scratch spaces\", mutable containers of data for packages. Scratch spaces are designed for data caches that are completely managed by a package and should be removed when the package itself is uninstalled. For important user-generated data, packages should continue to write out to a user-specified path that is not managed by Julia or Pkg.\nPreferences.jl allows packages to read and write preferences to the top-level Project.toml. These preferences can be read at runtime or compile-time, to enable or disable different aspects of package behavior. Packages previously would write out files to their own package directories to record options set by the user or environment, but this is highly discouraged now that Preferences is available.","category":"page"},{"location":"devdocs/valgrind/#Using-Valgrind-with-Julia","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Valgrind is a tool for memory debugging, memory leak detection, and profiling. This section describes things to keep in mind when using Valgrind to debug memory issues with Julia.","category":"page"},{"location":"devdocs/valgrind/#General-considerations","page":"Using Valgrind with Julia","title":"General considerations","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"By default, Valgrind assumes that there is no self modifying code in the programs it runs. This assumption works fine in most instances but fails miserably for a just-in-time compiler like julia. For this reason it is crucial to pass --smc-check=all-non-file to valgrind, else code may crash or behave unexpectedly (often in subtle ways).","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"In some cases, to better detect memory errors using Valgrind, it can help to compile julia with memory pools disabled. The compile-time flag MEMDEBUG disables memory pools in Julia, and MEMDEBUG2 disables memory pools in FemtoLisp. To build julia with both flags, add the following line to Make.user:","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"CFLAGS = -DMEMDEBUG -DMEMDEBUG2","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Another thing to note: if your program uses multiple worker processes, it is likely that you want all such worker processes to run under Valgrind, not just the parent process. To do this, pass --trace-children=yes to valgrind.","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Yet another thing to note: if using valgrind errors with Unable to find compatible target in system image, try rebuilding the sysimage with target generic or julia with JULIA_CPU_TARGET=generic.","category":"page"},{"location":"devdocs/valgrind/#Suppressions","page":"Using Valgrind with Julia","title":"Suppressions","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Valgrind will typically display spurious warnings as it runs. To reduce the number of such warnings, it helps to provide a suppressions file to Valgrind. A sample suppressions file is included in the Julia source distribution at contrib/valgrind-julia.supp.","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"The suppressions file can be used from the julia/ source directory as follows:","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"$ valgrind --smc-check=all-non-file --suppressions=contrib/valgrind-julia.supp ./julia progname.jl","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Any memory errors that are displayed should either be reported as bugs or contributed as additional suppressions. Note that some versions of Valgrind are shipped with insufficient default suppressions, so that may be one thing to consider before submitting any bugs.","category":"page"},{"location":"devdocs/valgrind/#Running-the-Julia-test-suite-under-Valgrind","page":"Using Valgrind with Julia","title":"Running the Julia test suite under Valgrind","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"It is possible to run the entire Julia test suite under Valgrind, but it does take quite some time (typically several hours). To do so, run the following command from the julia/test/ directory:","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"valgrind --smc-check=all-non-file --trace-children=yes --suppressions=$PWD/../contrib/valgrind-julia.supp ../julia runtests.jl all","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"If you would like to see a report of \"definite\" memory leaks, pass the flags --leak-check=full --show-leak-kinds=definite to valgrind as well.","category":"page"},{"location":"devdocs/valgrind/#Additional-spurious-warnings","page":"Using Valgrind with Julia","title":"Additional spurious warnings","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"This section covers Valgrind warnings that cannot be added to the suppressions file yet are nonetheless safe to ignore.","category":"page"},{"location":"devdocs/valgrind/#Unhandled-rr-system-calls","page":"Using Valgrind with Julia","title":"Unhandled rr system calls","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Valgrind will emit a warning if it encounters any of the system calls that are specific to rr, the Record and Replay Framework. In particular, a warning about an unhandled 1008 syscall will be shown when julia tries to detect whether it is running under rr:","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"--xxxxxx-- WARNING: unhandled amd64-linux syscall: 1008\n--xxxxxx-- You may be able to write your own handler.\n--xxxxxx-- Read the file README_MISSING_SYSCALL_OR_IOCTL.\n--xxxxxx-- Nevertheless we consider this a bug. Please report\n--xxxxxx-- it at http://valgrind.org/support/bug_reports.html.","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"This issue has been reported to the Valgrind developers as they have requested.","category":"page"},{"location":"devdocs/valgrind/#Caveats","page":"Using Valgrind with Julia","title":"Caveats","text":"","category":"section"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"Valgrind currently does not support multiple rounding modes, so code that adjusts the rounding mode will behave differently when run under Valgrind.","category":"page"},{"location":"devdocs/valgrind/","page":"Using Valgrind with Julia","title":"Using Valgrind with Julia","text":"In general, if after setting --smc-check=all-non-file you find that your program behaves differently when run under Valgrind, it may help to pass --tool=none to valgrind as you investigate further. This will enable the minimal Valgrind machinery but will also run much faster than when the full memory checker is enabled.","category":"page"},{"location":"manual/metaprogramming/#Metaprogramming","page":"Metaprogramming","title":"Metaprogramming","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The strongest legacy of Lisp in the Julia language is its metaprogramming support. Like Lisp, Julia represents its own code as a data structure of the language itself. Since code is represented by objects that can be created and manipulated from within the language, it is possible for a program to transform and generate its own code. This allows sophisticated code generation without extra build steps, and also allows true Lisp-style macros operating at the level of abstract syntax trees. In contrast, preprocessor \"macro\" systems, like that of C and C++, perform textual manipulation and substitution before any actual parsing or interpretation occurs. Because all data types and code in Julia are represented by Julia data structures, powerful reflection capabilities are available to explore the internals of a program and its types just like any other data.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"warning: Warning\nMetaprogramming is a powerful tool, but it introduces complexity that can make code more difficult to understand. For example, it can be surprisingly hard to get scope rules correct. Metaprogramming should typically be used only when other approaches such as higher order functions and closures cannot be applied.eval and defining new macros should be typically used as a last resort. It is almost never a good idea to use Meta.parse or convert an arbitrary string into Julia code. For manipulating Julia code, use the Expr data structure directly to avoid the complexity of how Julia syntax is parsed.The best uses of metaprogramming often implement most of their functionality in runtime helper functions, striving to minimize the amount of code they generate.","category":"page"},{"location":"manual/metaprogramming/#Program-representation","page":"Metaprogramming","title":"Program representation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Every Julia program starts life as a string:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> prog = \"1 + 1\"\n\"1 + 1\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"What happens next?","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The next step is to parse each string into an object called an expression, represented by the Julia type Expr:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1 = Meta.parse(prog)\n:(1 + 1)\n\njulia> typeof(ex1)\nExpr","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Expr objects contain two parts:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"a Symbol identifying the kind of expression. A symbol is an interned string identifier (more discussion below).","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1.head\n:call","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"the expression arguments, which may be symbols, other expressions, or literal values:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1.args\n3-element Vector{Any}:\n :+\n 1\n 1","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Expressions may also be constructed directly in prefix notation:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex2 = Expr(:call, :+, 1, 1)\n:(1 + 1)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The two expressions constructed above – by parsing and by direct construction – are equivalent:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1 == ex2\ntrue","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The key point here is that Julia code is internally represented as a data structure that is accessible from the language itself.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The dump function provides indented and annotated display of Expr objects:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> dump(ex2)\nExpr\n head: Symbol call\n args: Array{Any}((3,))\n 1: Symbol +\n 2: Int64 1\n 3: Int64 1","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Expr objects may also be nested:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex3 = Meta.parse(\"(4 + 4) / 2\")\n:((4 + 4) / 2)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Another way to view expressions is with Meta.show_sexpr, which displays the S-expression form of a given Expr, which may look very familiar to users of Lisp. Here's an example illustrating the display on a nested Expr:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> Meta.show_sexpr(ex3)\n(:call, :/, (:call, :+, 4, 4), 2)","category":"page"},{"location":"manual/metaprogramming/#Symbols","page":"Metaprogramming","title":"Symbols","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The : character has two syntactic purposes in Julia. The first form creates a Symbol, an interned string used as one building-block of expressions, from valid identifiers:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> s = :foo\n:foo\n\njulia> typeof(s)\nSymbol","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The Symbol constructor takes any number of arguments and creates a new symbol by concatenating their string representations together:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> :foo === Symbol(\"foo\")\ntrue\n\njulia> Symbol(\"1foo\") # `:1foo` would not work, as `1foo` is not a valid identifier\nSymbol(\"1foo\")\n\njulia> Symbol(\"func\",10)\n:func10\n\njulia> Symbol(:var,'_',\"sym\")\n:var_sym","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In the context of an expression, symbols are used to indicate access to variables; when an expression is evaluated, a symbol is replaced with the value bound to that symbol in the appropriate scope.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Sometimes extra parentheses around the argument to : are needed to avoid ambiguity in parsing:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> :(:)\n:(:)\n\njulia> :(::)\n:(::)","category":"page"},{"location":"manual/metaprogramming/#Expressions-and-evaluation","page":"Metaprogramming","title":"Expressions and evaluation","text":"","category":"section"},{"location":"manual/metaprogramming/#Quoting","page":"Metaprogramming","title":"Quoting","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The second syntactic purpose of the : character is to create expression objects without using the explicit Expr constructor. This is referred to as quoting. The : character, followed by paired parentheses around a single statement of Julia code, produces an Expr object based on the enclosed code. Here is an example of the short form used to quote an arithmetic expression:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = :(a+b*c+1)\n:(a + b * c + 1)\n\njulia> typeof(ex)\nExpr","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"(to view the structure of this expression, try ex.head and ex.args, or use dump as above or Meta.@dump)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note that equivalent expressions may be constructed using Meta.parse or the direct Expr form:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> :(a + b*c + 1) ==\n Meta.parse(\"a + b*c + 1\") ==\n Expr(:call, :+, :a, Expr(:call, :*, :b, :c), 1)\ntrue","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Expressions provided by the parser generally only have symbols, other expressions, and literal values as their args, whereas expressions constructed by Julia code can have arbitrary run-time values without literal forms as args. In this specific example, + and a are symbols, *(b,c) is a subexpression, and 1 is a literal 64-bit signed integer.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"There is a second syntactic form of quoting for multiple expressions: blocks of code enclosed in quote ... end.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = quote\n x = 1\n y = 2\n x + y\n end\nquote\n #= none:2 =#\n x = 1\n #= none:3 =#\n y = 2\n #= none:4 =#\n x + y\nend\n\njulia> typeof(ex)\nExpr","category":"page"},{"location":"manual/metaprogramming/#man-expression-interpolation","page":"Metaprogramming","title":"Interpolation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Direct construction of Expr objects with value arguments is powerful, but Expr constructors can be tedious compared to \"normal\" Julia syntax. As an alternative, Julia allows interpolation of literals or expressions into quoted expressions. Interpolation is indicated by a prefix $.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In this example, the value of variable a is interpolated:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> a = 1;\n\njulia> ex = :($a + b)\n:(1 + b)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Interpolating into an unquoted expression is not supported and will cause a compile-time error:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> $a + b\nERROR: syntax: \"$\" expression outside quote","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In this example, the tuple (1,2,3) is interpolated as an expression into a conditional test:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = :(a in $:((1,2,3)) )\n:(a in (1, 2, 3))","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The use of $ for expression interpolation is intentionally reminiscent of string interpolation and command interpolation. Expression interpolation allows convenient, readable programmatic construction of complex Julia expressions.","category":"page"},{"location":"manual/metaprogramming/#Splatting-interpolation","page":"Metaprogramming","title":"Splatting interpolation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Notice that the $ interpolation syntax allows inserting only a single expression into an enclosing expression. Occasionally, you have an array of expressions and need them all to become arguments of the surrounding expression. This can be done with the syntax $(xs...). For example, the following code generates a function call where the number of arguments is determined programmatically:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> args = [:x, :y, :z];\n\njulia> :(f(1, $(args...)))\n:(f(1, x, y, z))","category":"page"},{"location":"manual/metaprogramming/#Nested-quote","page":"Metaprogramming","title":"Nested quote","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Naturally, it is possible for quote expressions to contain other quote expressions. Understanding how interpolation works in these cases can be a bit tricky. Consider this example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> x = :(1 + 2);\n\njulia> e = quote quote $x end end\nquote\n #= none:1 =#\n $(Expr(:quote, quote\n #= none:1 =#\n $(Expr(:$, :x))\nend))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Notice that the result contains $x, which means that x has not been evaluated yet. In other words, the $ expression \"belongs to\" the inner quote expression, and so its argument is only evaluated when the inner quote expression is:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> eval(e)\nquote\n #= none:1 =#\n 1 + 2\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"However, the outer quote expression is able to interpolate values inside the $ in the inner quote. This is done with multiple $s:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> e = quote quote $$x end end\nquote\n #= none:1 =#\n $(Expr(:quote, quote\n #= none:1 =#\n $(Expr(:$, :(1 + 2)))\nend))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Notice that (1 + 2) now appears in the result instead of the symbol x. Evaluating this expression yields an interpolated 3:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> eval(e)\nquote\n #= none:1 =#\n 3\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The intuition behind this behavior is that x is evaluated once for each $: one $ works similarly to eval(:x), giving x's value, while two $s do the equivalent of eval(eval(:x)).","category":"page"},{"location":"manual/metaprogramming/#man-quote-node","page":"Metaprogramming","title":"QuoteNode","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The usual representation of a quote form in an AST is an Expr with head :quote:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> dump(Meta.parse(\":(1+2)\"))\nExpr\n head: Symbol quote\n args: Array{Any}((1,))\n 1: Expr\n head: Symbol call\n args: Array{Any}((3,))\n 1: Symbol +\n 2: Int64 1\n 3: Int64 2","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"As we have seen, such expressions support interpolation with $. However, in some situations it is necessary to quote code without performing interpolation. This kind of quoting does not yet have syntax, but is represented internally as an object of type QuoteNode:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> eval(Meta.quot(Expr(:$, :(1+2))))\n3\n\njulia> eval(QuoteNode(Expr(:$, :(1+2))))\n:($(Expr(:$, :(1 + 2))))","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The parser yields QuoteNodes for simple quoted items like symbols:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> dump(Meta.parse(\":x\"))\nQuoteNode\n value: Symbol x","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"QuoteNode can also be used for certain advanced metaprogramming tasks.","category":"page"},{"location":"manual/metaprogramming/#Evaluating-expressions","page":"Metaprogramming","title":"Evaluating expressions","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Given an expression object, one can cause Julia to evaluate (execute) it at global scope using eval:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex1 = :(1 + 2)\n:(1 + 2)\n\njulia> eval(ex1)\n3\n\njulia> ex = :(a + b)\n:(a + b)\n\njulia> eval(ex)\nERROR: UndefVarError: `b` not defined in `Main`\n[...]\n\njulia> a = 1; b = 2;\n\njulia> eval(ex)\n3","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Every module has its own eval function that evaluates expressions in its global scope. Expressions passed to eval are not limited to returning values – they can also have side-effects that alter the state of the enclosing module's environment:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = :(x = 1)\n:(x = 1)\n\njulia> x\nERROR: UndefVarError: `x` not defined in `Main`\n\njulia> eval(ex)\n1\n\njulia> x\n1","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here, the evaluation of an expression object causes a value to be assigned to the global variable x.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Since expressions are just Expr objects which can be constructed programmatically and then evaluated, it is possible to dynamically generate arbitrary code which can then be run using eval. Here is a simple example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> a = 1;\n\njulia> ex = Expr(:call, :+, a, :b)\n:(1 + b)\n\njulia> a = 0; b = 2;\n\njulia> eval(ex)\n3","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The value of a is used to construct the expression ex which applies the + function to the value 1 and the variable b. Note the important distinction between the way a and b are used:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The value of the variable a at expression construction time is used as an immediate value in the expression. Thus, the value of a when the expression is evaluated no longer matters: the value in the expression is already 1, independent of whatever the value of a might be.\nOn the other hand, the symbol :b is used in the expression construction, so the value of the variable b at that time is irrelevant – :b is just a symbol and the variable b need not even be defined. At expression evaluation time, however, the value of the symbol :b is resolved by looking up the value of the variable b.","category":"page"},{"location":"manual/metaprogramming/#Functions-on-Expressions","page":"Metaprogramming","title":"Functions on Expressions","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"As hinted above, one extremely useful feature of Julia is the capability to generate and manipulate Julia code within Julia itself. We have already seen one example of a function returning Expr objects: the Meta.parse function, which takes a string of Julia code and returns the corresponding Expr. A function can also take one or more Expr objects as arguments, and return another Expr. Here is a simple, motivating example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function math_expr(op, op1, op2)\n expr = Expr(:call, op, op1, op2)\n return expr\n end\nmath_expr (generic function with 1 method)\n\njulia> ex = math_expr(:+, 1, Expr(:call, :*, 4, 5))\n:(1 + 4 * 5)\n\njulia> eval(ex)\n21","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"As another example, here is a function that doubles any numeric argument, but leaves expressions alone:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function make_expr2(op, opr1, opr2)\n opr1f, opr2f = map(x -> isa(x, Number) ? 2*x : x, (opr1, opr2))\n retexpr = Expr(:call, op, opr1f, opr2f)\n return retexpr\n end\nmake_expr2 (generic function with 1 method)\n\njulia> make_expr2(:+, 1, 2)\n:(2 + 4)\n\njulia> ex = make_expr2(:+, 1, Expr(:call, :*, 5, 8))\n:(2 + 5 * 8)\n\njulia> eval(ex)\n42","category":"page"},{"location":"manual/metaprogramming/#man-macros","page":"Metaprogramming","title":"Macros","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros provide a mechanism to include generated code in the final body of a program. A macro maps a tuple of arguments to a returned expression, and the resulting expression is compiled directly rather than requiring a runtime eval call. Macro arguments may include expressions, literal values, and symbols.","category":"page"},{"location":"manual/metaprogramming/#Basics","page":"Metaprogramming","title":"Basics","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here is an extraordinarily simple macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro sayhello()\n return :( println(\"Hello, world!\") )\n end\n@sayhello (macro with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros have a dedicated character in Julia's syntax: the @ (at-sign), followed by the unique name declared in a macro NAME ... end block. In this example, the compiler will replace all instances of @sayhello with:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":":( println(\"Hello, world!\") )","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"When @sayhello is entered in the REPL, the expression executes immediately, thus we only see the evaluation result:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @sayhello()\nHello, world!","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Now, consider a slightly more complex macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro sayhello(name)\n return :( println(\"Hello, \", $name) )\n end\n@sayhello (macro with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This macro takes one argument: name. When @sayhello is encountered, the quoted expression is expanded to interpolate the value of the argument into the final expression:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @sayhello(\"human\")\nHello, human","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We can view the quoted return expression using the function macroexpand (important note: this is an extremely useful tool for debugging macros):","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> ex = macroexpand(Main, :(@sayhello(\"human\")) )\n:(Main.println(\"Hello, \", \"human\"))\n\njulia> typeof(ex)\nExpr","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We can see that the \"human\" literal has been interpolated into the expression.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"There also exists a macro @macroexpand that is perhaps a bit more convenient than the macroexpand function:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @macroexpand @sayhello \"human\"\n:(println(\"Hello, \", \"human\"))","category":"page"},{"location":"manual/metaprogramming/#Hold-up:-why-macros?","page":"Metaprogramming","title":"Hold up: why macros?","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We have already seen a function f(::Expr...) -> Expr in a previous section. In fact, macroexpand is also such a function. So, why do macros exist?","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros are necessary because they execute when code is parsed, therefore, macros allow the programmer to generate and include fragments of customized code before the full program is run. To illustrate the difference, consider the following example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro twostep(arg)\n println(\"I execute at parse time. The argument is: \", arg)\n return :(println(\"I execute at runtime. The argument is: \", $arg))\n end\n@twostep (macro with 1 method)\n\njulia> ex = macroexpand(Main, :(@twostep :(1, 2, 3)) );\nI execute at parse time. The argument is: :((1, 2, 3))","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The first call to println is executed when macroexpand is called. The resulting expression contains only the second println:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> typeof(ex)\nExpr\n\njulia> ex\n:(println(\"I execute at runtime. The argument is: \", $(Expr(:copyast, :($(QuoteNode(:((1, 2, 3)))))))))\n\njulia> eval(ex)\nI execute at runtime. The argument is: (1, 2, 3)","category":"page"},{"location":"manual/metaprogramming/#Macro-invocation","page":"Metaprogramming","title":"Macro invocation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros are invoked with the following general syntax:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"@name expr1 expr2 ...\n@name(expr1, expr2, ...)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note the distinguishing @ before the macro name and the lack of commas between the argument expressions in the first form, and the lack of whitespace after @name in the second form. The two styles should not be mixed. For example, the following syntax is different from the examples above; it passes the tuple (expr1, expr2, ...) as one argument to the macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"@name (expr1, expr2, ...)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"An alternative way to invoke a macro over an array literal (or comprehension) is to juxtapose both without using parentheses. In this case, the array will be the only expression fed to the macro. The following syntax is equivalent (and different from @name [a b] * v):","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"@name[a b] * v\n@name([a b]) * v","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"It is important to emphasize that macros receive their arguments as expressions, literals, or symbols. One way to explore macro arguments is to call the show function within the macro body:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro showarg(x)\n show(x)\n # ... remainder of macro, returning an expression\n end\n@showarg (macro with 1 method)\n\njulia> @showarg(a)\n:a\n\njulia> @showarg(1+1)\n:(1 + 1)\n\njulia> @showarg(println(\"Yo!\"))\n:(println(\"Yo!\"))\n\njulia> @showarg(1) # Numeric literal\n1\n\njulia> @showarg(\"Yo!\") # String literal\n\"Yo!\"\n\njulia> @showarg(\"Yo! $(\"hello\")\") # String with interpolation is an Expr rather than a String\n:(\"Yo! $(\"hello\")\")","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In addition to the given argument list, every macro is passed extra arguments named __source__ and __module__.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The argument __source__ provides information (in the form of a LineNumberNode object) about the parser location of the @ sign from the macro invocation. This allows macros to include better error diagnostic information, and is commonly used by logging, string-parser macros, and docs, for example, as well as to implement the @__LINE__, @__FILE__, and @__DIR__ macros.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The location information can be accessed by referencing __source__.line and __source__.file:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro __LOCATION__(); return QuoteNode(__source__); end\n@__LOCATION__ (macro with 1 method)\n\njulia> dump(\n @__LOCATION__(\n ))\nLineNumberNode\n line: Int64 2\n file: Symbol none","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The argument __module__ provides information (in the form of a Module object) about the expansion context of the macro invocation. This allows macros to look up contextual information, such as existing bindings, or to insert the value as an extra argument to a runtime function call doing self-reflection in the current module.","category":"page"},{"location":"manual/metaprogramming/#Building-an-advanced-macro","page":"Metaprogramming","title":"Building an advanced macro","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here is a simplified definition of Julia's @assert macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro assert(ex)\n return :( $ex ? nothing : throw(AssertionError($(string(ex)))) )\n end\n@assert (macro with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This macro can be used like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @assert 1 == 1.0\n\njulia> @assert 1 == 0\nERROR: AssertionError: 1 == 0","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In place of the written syntax, the macro call is expanded at parse time to its returned result. This is equivalent to writing:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"1 == 1.0 ? nothing : throw(AssertionError(\"1 == 1.0\"))\n1 == 0 ? nothing : throw(AssertionError(\"1 == 0\"))","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"That is, in the first call, the expression :(1 == 1.0) is spliced into the test condition slot, while the value of string(:(1 == 1.0)) is spliced into the assertion message slot. The entire expression, thus constructed, is placed into the syntax tree where the @assert macro call occurs. Then at execution time, if the test expression evaluates to true, then nothing is returned, whereas if the test is false, an error is raised indicating the asserted expression that was false. Notice that it would not be possible to write this as a function, since only the value of the condition is available and it would be impossible to display the expression that computed it in the error message.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The actual definition of @assert in Julia Base is more complicated. It allows the user to optionally specify their own error message, instead of just printing the failed expression. Just like in functions with a variable number of arguments (Varargs Functions), this is specified with an ellipses following the last argument:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro assert(ex, msgs...)\n msg_body = isempty(msgs) ? ex : msgs[1]\n msg = string(msg_body)\n return :($ex ? nothing : throw(AssertionError($msg)))\n end\n@assert (macro with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Now @assert has two modes of operation, depending upon the number of arguments it receives! If there's only one argument, the tuple of expressions captured by msgs will be empty and it will behave the same as the simpler definition above. But now if the user specifies a second argument, it is printed in the message body instead of the failing expression. You can inspect the result of a macro expansion with the aptly named @macroexpand macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @macroexpand @assert a == b\n:(if Main.a == Main.b\n Main.nothing\n else\n Main.throw(Main.AssertionError(\"a == b\"))\n end)\n\njulia> @macroexpand @assert a==b \"a should equal b!\"\n:(if Main.a == Main.b\n Main.nothing\n else\n Main.throw(Main.AssertionError(\"a should equal b!\"))\n end)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"There is yet another case that the actual @assert macro handles: what if, in addition to printing \"a should equal b,\" we wanted to print their values? One might naively try to use string interpolation in the custom message, e.g., @assert a==b \"a ($a) should equal b ($b)!\", but this won't work as expected with the above macro. Can you see why? Recall from string interpolation that an interpolated string is rewritten to a call to string. Compare:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> typeof(:(\"a should equal b\"))\nString\n\njulia> typeof(:(\"a ($a) should equal b ($b)!\"))\nExpr\n\njulia> dump(:(\"a ($a) should equal b ($b)!\"))\nExpr\n head: Symbol string\n args: Array{Any}((5,))\n 1: String \"a (\"\n 2: Symbol a\n 3: String \") should equal b (\"\n 4: Symbol b\n 5: String \")!\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"So now instead of getting a plain string in msg_body, the macro is receiving a full expression that will need to be evaluated in order to display as expected. This can be spliced directly into the returned expression as an argument to the string call; see error.jl for the complete implementation.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The @assert macro makes great use of splicing into quoted expressions to simplify the manipulation of expressions inside the macro body.","category":"page"},{"location":"manual/metaprogramming/#Hygiene","page":"Metaprogramming","title":"Hygiene","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"An issue that arises in more complex macros is that of hygiene. In short, macros must ensure that the variables they introduce in their returned expressions do not accidentally clash with existing variables in the surrounding code they expand into. Conversely, the expressions that are passed into a macro as arguments are often expected to evaluate in the context of the surrounding code, interacting with and modifying the existing variables. Another concern arises from the fact that a macro may be called in a different module from where it was defined. In this case we need to ensure that all global variables are resolved to the correct module. Julia already has a major advantage over languages with textual macro expansion (like C) in that it only needs to consider the returned expression. All the other variables (such as msg in @assert above) follow the normal scoping block behavior.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"To demonstrate these issues, let us consider writing a @time macro that takes an expression as its argument, records the time, evaluates the expression, records the time again, prints the difference between the before and after times, and then has the value of the expression as its final value. The macro might look like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro time(ex)\n return quote\n local t0 = time_ns()\n local val = $ex\n local t1 = time_ns()\n println(\"elapsed time: \", (t1-t0)/1e9, \" seconds\")\n val\n end\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here, we want t0, t1, and val to be private temporary variables, and we want time_ns to refer to the time_ns function in Julia Base, not to any time_ns variable the user might have (the same applies to println). Imagine the problems that could occur if the user expression ex also contained assignments to a variable called t0, or defined its own time_ns variable. We might get errors, or mysteriously incorrect behavior.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Julia's macro expander solves these problems in the following way. First, variables within a macro result are classified as either local or global. A variable is considered local if it is assigned to (and not declared global), declared local, or used as a function argument name. Otherwise, it is considered global. Local variables are then renamed to be unique (using the gensym function, which generates new symbols), and global variables are resolved within the macro definition environment. Therefore both of the above concerns are handled; the macro's locals will not conflict with any user variables, and time_ns and println will refer to the Julia Base definitions.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"One problem remains however. Consider the following use of this macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"module MyModule\nimport Base.@time\n\ntime_ns() = ... # compute something\n\n@time time_ns()\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Here the user expression ex is a call to time_ns, but not the same time_ns function that the macro uses. It clearly refers to MyModule.time_ns. Therefore we must arrange for the code in ex to be resolved in the macro call environment. This is done by \"escaping\" the expression with esc:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro time(ex)\n ...\n local val = $(esc(ex))\n ...\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"An expression wrapped in this manner is left alone by the macro expander and simply pasted into the output verbatim. Therefore it will be resolved in the macro call environment.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This escaping mechanism can be used to \"violate\" hygiene when necessary, in order to introduce or manipulate user variables. For example, the following macro sets x to zero in the call environment:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro zerox()\n return esc(:(x = 0))\n end\n@zerox (macro with 1 method)\n\njulia> function foo()\n x = 1\n @zerox\n return x # is zero\n end\nfoo (generic function with 1 method)\n\njulia> foo()\n0","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This kind of manipulation of variables should be used judiciously, but is occasionally quite handy.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Getting the hygiene rules correct can be a formidable challenge. Before using a macro, you might want to consider whether a function closure would be sufficient. Another useful strategy is to defer as much work as possible to runtime. For example, many macros simply wrap their arguments in a QuoteNode or other similar Expr. Some examples of this include @task body which simply returns schedule(Task(() -> $body)), and @eval expr, which simply returns eval(QuoteNode(expr)).","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"To demonstrate, we might rewrite the @time example above as:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro time(expr)\n return :(timeit(() -> $(esc(expr))))\nend\nfunction timeit(f)\n t0 = time_ns()\n val = f()\n t1 = time_ns()\n println(\"elapsed time: \", (t1-t0)/1e9, \" seconds\")\n return val\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"However, we don't do this for a good reason: wrapping the expr in a new scope block (the anonymous function) also slightly changes the meaning of the expression (the scope of any variables in it), while we want @time to be usable with minimum impact on the wrapped code.","category":"page"},{"location":"manual/metaprogramming/#Macros-and-dispatch","page":"Metaprogramming","title":"Macros and dispatch","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Macros, just like Julia functions, are generic. This means they can also have multiple method definitions, thanks to multiple dispatch:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro m end\n@m (macro with 0 methods)\n\njulia> macro m(args...)\n println(\"$(length(args)) arguments\")\n end\n@m (macro with 1 method)\n\njulia> macro m(x,y)\n println(\"Two arguments\")\n end\n@m (macro with 2 methods)\n\njulia> @m \"asd\"\n1 arguments\n\njulia> @m 1 2\nTwo arguments","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"However one should keep in mind, that macro dispatch is based on the types of AST that are handed to the macro, not the types that the AST evaluates to at runtime:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> macro m(::Int)\n println(\"An Integer\")\n end\n@m (macro with 3 methods)\n\njulia> @m 2\nAn Integer\n\njulia> x = 2\n2\n\njulia> @m x\n1 arguments","category":"page"},{"location":"manual/metaprogramming/#Code-Generation","page":"Metaprogramming","title":"Code Generation","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"When a significant amount of repetitive boilerplate code is required, it is common to generate it programmatically to avoid redundancy. In most languages, this requires an extra build step, and a separate program to generate the repetitive code. In Julia, expression interpolation and eval allow such code generation to take place in the normal course of program execution. For example, consider the following custom type","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"struct MyNumber\n x::Float64\nend\n# output\n","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for which we want to add a number of methods to. We can do this programmatically in the following loop:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for op = (:sin, :cos, :tan, :log, :exp)\n eval(quote\n Base.$op(a::MyNumber) = MyNumber($op(a.x))\n end)\nend\n# output\n","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"and we can now use those functions with our custom type:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> x = MyNumber(π)\nMyNumber(3.141592653589793)\n\njulia> sin(x)\nMyNumber(1.2246467991473532e-16)\n\njulia> cos(x)\nMyNumber(-1.0)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In this manner, Julia acts as its own preprocessor, and allows code generation from inside the language. The above code could be written slightly more tersely using the : prefix quoting form:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for op = (:sin, :cos, :tan, :log, :exp)\n eval(:(Base.$op(a::MyNumber) = MyNumber($op(a.x))))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This sort of in-language code generation, however, using the eval(quote(...)) pattern, is common enough that Julia comes with a macro to abbreviate this pattern:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for op = (:sin, :cos, :tan, :log, :exp)\n @eval Base.$op(a::MyNumber) = MyNumber($op(a.x))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The @eval macro rewrites this call to be precisely equivalent to the above longer versions. For longer blocks of generated code, the expression argument given to @eval can be a block:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"@eval begin\n # multiple lines\nend","category":"page"},{"location":"manual/metaprogramming/#meta-non-standard-string-literals","page":"Metaprogramming","title":"Non-Standard String Literals","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Recall from Strings that string literals prefixed by an identifier are called non-standard string literals, and can have different semantics than un-prefixed string literals. For example:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"r\"^\\s*(?:#|$)\" produces a regular expression object rather than a string\nb\"DATA\\xff\\u2200\" is a byte array literal for [68,65,84,65,255,226,136,128].","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Perhaps surprisingly, these behaviors are not hard-coded into the Julia parser or compiler. Instead, they are custom behaviors provided by a general mechanism that anyone can use: prefixed string literals are parsed as calls to specially-named macros. For example, the regular expression macro is just the following:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro r_str(p)\n Regex(p)\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"That's all. This macro says that the literal contents of the string literal r\"^\\s*(?:#|$)\" should be passed to the @r_str macro and the result of that expansion should be placed in the syntax tree where the string literal occurs. In other words, the expression r\"^\\s*(?:#|$)\" is equivalent to placing the following object directly into the syntax tree:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Regex(\"^\\\\s*(?:#|\\$)\")","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Not only is the string literal form shorter and far more convenient, but it is also more efficient: since the regular expression is compiled and the Regex object is actually created when the code is compiled, the compilation occurs only once, rather than every time the code is executed. Consider if the regular expression occurs in a loop:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"for line = lines\n m = match(r\"^\\s*(?:#|$)\", line)\n if m === nothing\n # non-comment\n else\n # comment\n end\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Since the regular expression r\"^\\s*(?:#|$)\" is compiled and inserted into the syntax tree when this code is parsed, the expression is only compiled once instead of each time the loop is executed. In order to accomplish this without macros, one would have to write this loop like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"re = Regex(\"^\\\\s*(?:#|\\$)\")\nfor line = lines\n m = match(re, line)\n if m === nothing\n # non-comment\n else\n # comment\n end\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Moreover, if the compiler could not determine that the regex object was constant over all loops, certain optimizations might not be possible, making this version still less efficient than the more convenient literal form above. Of course, there are still situations where the non-literal form is more convenient: if one needs to interpolate a variable into the regular expression, one must take this more verbose approach; in cases where the regular expression pattern itself is dynamic, potentially changing upon each loop iteration, a new regular expression object must be constructed on each iteration. In the vast majority of use cases, however, regular expressions are not constructed based on run-time data. In this majority of cases, the ability to write regular expressions as compile-time values is invaluable.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The mechanism for user-defined string literals is deeply, profoundly powerful. Not only are Julia's non-standard literals implemented using it, but the command literal syntax (`echo \"Hello, $person\"`) is also implemented using the following innocuous-looking macro:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro cmd(str)\n :(cmd_gen($(shell_parse(str)[1])))\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Of course, a large amount of complexity is hidden in the functions used in this macro definition, but they are just functions, written entirely in Julia. You can read their source and see precisely what they do – and all they do is construct expression objects to be inserted into your program's syntax tree.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Like string literals, command literals can also be prefixed by an identifier to form what are called non-standard command literals. These command literals are parsed as calls to specially-named macros. For example, the syntax custom`literal` is parsed as @custom_cmd \"literal\". Julia itself does not contain any non-standard command literals, but packages can make use of this syntax. Aside from the different syntax and the _cmd suffix instead of the _str suffix, non-standard command literals behave exactly like non-standard string literals.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In the event that two modules provide non-standard string or command literals with the same name, it is possible to qualify the string or command literal with a module name. For instance, if both Foo and Bar provide non-standard string literal @x_str, then one can write Foo.x\"literal\" or Bar.x\"literal\" to disambiguate between the two.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Another way to define a macro would be like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"macro foo_str(str, flag)\n # do stuff\nend","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"This macro can then be called with the following syntax:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"foo\"str\"flag","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The type of flag in the above mentioned syntax would be a String with contents of whatever trails after the string literal.","category":"page"},{"location":"manual/metaprogramming/#Generated-functions","page":"Metaprogramming","title":"Generated functions","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"A very special macro is @generated, which allows you to define so-called generated functions. These have the capability to generate specialized code depending on the types of their arguments with more flexibility and/or less code than what can be achieved with multiple dispatch. While macros work with expressions at parse time and cannot access the types of their inputs, a generated function gets expanded at a time when the types of the arguments are known, but the function is not yet compiled.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Instead of performing some calculation or action, a generated function declaration returns a quoted expression which then forms the body for the method corresponding to the types of the arguments. When a generated function is called, the expression it returns is compiled and then run. To make this efficient, the result is usually cached. And to make this inferable, only a limited subset of the language is usable. Thus, generated functions provide a flexible way to move work from run time to compile time, at the expense of greater restrictions on allowed constructs.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"When defining generated functions, there are five main differences to ordinary functions:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"You annotate the function declaration with the @generated macro. This adds some information to the AST that lets the compiler know that this is a generated function.\nIn the body of the generated function you only have access to the types of the arguments – not their values.\nInstead of calculating something or performing some action, you return a quoted expression which, when evaluated, does what you want.\nGenerated functions are only permitted to call functions that were defined before the definition of the generated function. (Failure to follow this may result in getting MethodErrors referring to functions from a future world-age.)\nGenerated functions must not mutate or observe any non-constant global state (including, for example, IO, locks, non-local dictionaries, or using hasmethod). This means they can only read global constants, and cannot have any side effects. In other words, they must be completely pure. Due to an implementation limitation, this also means that they currently cannot define a closure or generator.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"It's easiest to illustrate this with an example. We can declare a generated function foo as","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated function foo(x)\n Core.println(x)\n return :(x * x)\n end\nfoo (generic function with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note that the body returns a quoted expression, namely :(x * x), rather than just the value of x * x.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"From the caller's perspective, this is identical to a regular function; in fact, you don't have to know whether you're calling a regular or generated function. Let's see how foo behaves:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> x = foo(2); # note: output is from println() statement in the body\nInt64\n\njulia> x # now we print x\n4\n\njulia> y = foo(\"bar\");\nString\n\njulia> y\n\"barbar\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"So, we see that in the body of the generated function, x is the type of the passed argument, and the value returned by the generated function, is the result of evaluating the quoted expression we returned from the definition, now with the value of x.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"What happens if we evaluate foo again with a type that we have already used?","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> foo(4)\n16","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note that there is no printout of Int64. We can see that the body of the generated function was only executed once here, for the specific set of argument types, and the result was cached. After that, for this example, the expression returned from the generated function on the first invocation was re-used as the method body. However, the actual caching behavior is an implementation-defined performance optimization, so it is invalid to depend too closely on this behavior.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The number of times a generated function is generated might be only once, but it might also be more often, or appear to not happen at all. As a consequence, you should never write a generated function with side effects - when, and how often, the side effects occur is undefined. (This is true for macros too - and just like for macros, the use of eval in a generated function is a sign that you're doing something the wrong way.) However, unlike macros, the runtime system cannot correctly handle a call to eval, so it is disallowed.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"It is also important to see how @generated functions interact with method redefinition. Following the principle that a correct @generated function must not observe any mutable state or cause any mutation of global state, we see the following behavior. Observe that the generated function cannot call any method that was not defined prior to the definition of the generated function itself.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Initially f(x) has one definition","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> f(x) = \"original definition\";","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Define other operations that use f(x):","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> g(x) = f(x);\n\njulia> @generated gen1(x) = f(x);\n\njulia> @generated gen2(x) = :(f(x));","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We now add some new definitions for f(x):","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> f(x::Int) = \"definition for Int\";\n\njulia> f(x::Type{Int}) = \"definition for Type{Int}\";","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"and compare how these results differ:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> f(1)\n\"definition for Int\"\n\njulia> g(1)\n\"definition for Int\"\n\njulia> gen1(1)\n\"original definition\"\n\njulia> gen2(1)\n\"definition for Int\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Each method of a generated function has its own view of defined functions:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated gen1(x::Real) = f(x);\n\njulia> gen1(1)\n\"definition for Type{Int}\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The example generated function foo above did not do anything a normal function foo(x) = x * x could not do (except printing the type on the first invocation, and incurring higher overhead). However, the power of a generated function lies in its ability to compute different quoted expressions depending on the types passed to it:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated function bar(x)\n if x <: Integer\n return :(x ^ 2)\n else\n return :(x)\n end\n end\nbar (generic function with 1 method)\n\njulia> bar(4)\n16\n\njulia> bar(\"baz\")\n\"baz\"","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"(although of course this contrived example would be more easily implemented using multiple dispatch...)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Abusing this will corrupt the runtime system and cause undefined behavior:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated function baz(x)\n if rand() < .9\n return :(x^2)\n else\n return :(\"boo!\")\n end\n end\nbaz (generic function with 1 method)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Since the body of the generated function is non-deterministic, its behavior, and the behavior of all subsequent code is undefined.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Don't copy these examples!","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"These examples are hopefully helpful to illustrate how generated functions work, both in the definition end and at the call site; however, don't copy them, for the following reasons:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"the foo function has side-effects (the call to Core.println), and it is undefined exactly when, how often or how many times these side-effects will occur\nthe bar function solves a problem that is better solved with multiple dispatch - defining bar(x) = x and bar(x::Integer) = x ^ 2 will do the same thing, but it is both simpler and faster.\nthe baz function is pathological","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Note that the set of operations that should not be attempted in a generated function is unbounded, and the runtime system can currently only detect a subset of the invalid operations. There are many other operations that will simply corrupt the runtime system without notification, usually in subtle ways not obviously connected to the bad definition. Because the function generator is run during inference, it must respect all of the limitations of that code.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Some operations that should not be attempted include:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Caching of native pointers.\nInteracting with the contents or methods of Core.Compiler in any way.\nObserving any mutable state.\nInference on the generated function may be run at any time, including while your code is attempting to observe or mutate this state.\nTaking any locks: C code you call out to may use locks internally, (for example, it is not problematic to call malloc, even though most implementations require locks internally) but don't attempt to hold or acquire any while executing Julia code.\nCalling any function that is defined after the body of the generated function. This condition is relaxed for incrementally-loaded precompiled modules to allow calling any function in the module.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Alright, now that we have a better understanding of how generated functions work, let's use them to build some more advanced (and valid) functionality...","category":"page"},{"location":"manual/metaprogramming/#An-advanced-example","page":"Metaprogramming","title":"An advanced example","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Julia's base library has an internal sub2ind function to calculate a linear index into an n-dimensional array, based on a set of n multilinear indices - in other words, to calculate the index i that can be used to index into an array A using A[i], instead of A[x,y,z,...]. One possible implementation is the following:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function sub2ind_loop(dims::NTuple{N}, I::Integer...) where N\n ind = I[N] - 1\n for i = N-1:-1:1\n ind = I[i]-1 + dims[i]*ind\n end\n return ind + 1\n end;\n\njulia> sub2ind_loop((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"The same thing can be done using recursion:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> sub2ind_rec(dims::Tuple{}) = 1;\n\njulia> sub2ind_rec(dims::Tuple{}, i1::Integer, I::Integer...) =\n i1 == 1 ? sub2ind_rec(dims, I...) : throw(BoundsError());\n\njulia> sub2ind_rec(dims::Tuple{Integer, Vararg{Integer}}, i1::Integer) = i1;\n\njulia> sub2ind_rec(dims::Tuple{Integer, Vararg{Integer}}, i1::Integer, I::Integer...) =\n i1 + dims[1] * (sub2ind_rec(Base.tail(dims), I...) - 1);\n\njulia> sub2ind_rec((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Both these implementations, although different, do essentially the same thing: a runtime loop over the dimensions of the array, collecting the offset in each dimension into the final index.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"However, all the information we need for the loop is embedded in the type information of the arguments. This allows the compiler to move the iteration to compile time and eliminate the runtime loops altogether. We can utilize generated functions to achieve a similar effect; in compiler parlance, we use generated functions to manually unroll the loop. The body becomes almost identical, but instead of calculating the linear index, we build up an expression that calculates the index:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> @generated function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N\n ex = :(I[$N] - 1)\n for i = (N - 1):-1:1\n ex = :(I[$i] - 1 + dims[$i] * $ex)\n end\n return :($ex + 1)\n end;\n\njulia> sub2ind_gen((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"What code will this generate?","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"An easy way to find out is to extract the body into another (regular) function:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function sub2ind_gen_impl(dims::Type{T}, I...) where T <: NTuple{N,Any} where N\n length(I) == N || return :(error(\"partial indexing is unsupported\"))\n ex = :(I[$N] - 1)\n for i = (N - 1):-1:1\n ex = :(I[$i] - 1 + dims[$i] * $ex)\n end\n return :($ex + 1)\n end;\n\njulia> @generated function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N\n return sub2ind_gen_impl(dims, I...)\n end;\n\njulia> sub2ind_gen((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"We can now execute sub2ind_gen_impl and examine the expression it returns:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> sub2ind_gen_impl(Tuple{Int,Int}, Int, Int)\n:(((I[1] - 1) + dims[1] * (I[2] - 1)) + 1)","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"So, the method body that will be used here doesn't include a loop at all - just indexing into the two tuples, multiplication and addition/subtraction. All the looping is performed compile-time, and we avoid looping during execution entirely. Thus, we only loop once per type, in this case once per N (except in edge cases where the function is generated more than once - see disclaimer above).","category":"page"},{"location":"manual/metaprogramming/#Optionally-generated-functions","page":"Metaprogramming","title":"Optionally-generated functions","text":"","category":"section"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Generated functions can achieve high efficiency at run time, but come with a compile time cost: a new function body must be generated for every combination of concrete argument types. Typically, Julia is able to compile \"generic\" versions of functions that will work for any arguments, but with generated functions this is impossible. This means that programs making heavy use of generated functions might be impossible to statically compile.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"To solve this problem, the language provides syntax for writing normal, non-generated alternative implementations of generated functions. Applied to the sub2ind example above, it would look like this:","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"julia> function sub2ind_gen_impl(dims::Type{T}, I...) where T <: NTuple{N,Any} where N\n ex = :(I[$N] - 1)\n for i = (N - 1):-1:1\n ex = :(I[$i] - 1 + dims[$i] * $ex)\n end\n return :($ex + 1)\n end;\n\njulia> function sub2ind_gen_fallback(dims::NTuple{N}, I) where N\n ind = I[N] - 1\n for i = (N - 1):-1:1\n ind = I[i] - 1 + dims[i]*ind\n end\n return ind + 1\n end;\n\njulia> function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N\n length(I) == N || error(\"partial indexing is unsupported\")\n if @generated\n return sub2ind_gen_impl(dims, I...)\n else\n return sub2ind_gen_fallback(dims, I)\n end\n end;\n\njulia> sub2ind_gen((3, 5), 1, 2)\n4","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Internally, this code creates two implementations of the function: a generated one where the first block in if @generated is used, and a normal one where the else block is used. Inside the then part of the if @generated block, code has the same semantics as other generated functions: argument names refer to types, and the code should return an expression. Multiple if @generated blocks may occur, in which case the generated implementation uses all of the then blocks and the alternate implementation uses all of the else blocks.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"Notice that we added an error check to the top of the function. This code will be common to both versions, and is run-time code in both versions (it will be quoted and returned as an expression from the generated version). That means that the values and types of local variables are not available at code generation time –- the code-generation code can only see the types of arguments.","category":"page"},{"location":"manual/metaprogramming/","page":"Metaprogramming","title":"Metaprogramming","text":"In this style of definition, the code generation feature is essentially an optional optimization. The compiler will use it if convenient, but otherwise may choose to use the normal implementation instead. This style is preferred, since it allows the compiler to make more decisions and compile programs in more ways, and since normal code is more readable than code-generating code. However, which implementation is used depends on compiler implementation details, so it is essential for the two implementations to behave identically.","category":"page"},{"location":"devdocs/offset-arrays/#man-custom-indices","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Conventionally, Julia's arrays are indexed starting at 1, whereas some other languages start numbering at 0, and yet others (e.g., Fortran) allow you to specify arbitrary starting indices. While there is much merit in picking a standard (i.e., 1 for Julia), there are some algorithms which simplify considerably if you can index outside the range 1:size(A,d) (and not just 0:size(A,d)-1, either). To facilitate such computations, Julia supports arrays with arbitrary indices.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"The purpose of this page is to address the question, \"what do I have to do to support such arrays in my own code?\" First, let's address the simplest case: if you know that your code will never need to handle arrays with unconventional indexing, hopefully the answer is \"nothing.\" Old code, on conventional arrays, should function essentially without alteration as long as it was using the exported interfaces of Julia. If you find it more convenient to just force your users to supply traditional arrays where indexing starts at one, you can add","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base.require_one_based_indexing(arrays...)","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"where arrays... is a list of the array objects that you wish to check for anything that violates 1-based indexing.","category":"page"},{"location":"devdocs/offset-arrays/#Generalizing-existing-code","page":"Arrays with custom indices","title":"Generalizing existing code","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"As an overview, the steps are:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"replace many uses of size with axes\nreplace 1:length(A) with eachindex(A), or in some cases LinearIndices(A)\nreplace explicit allocations like Array{Int}(undef, size(B)) with similar(Array{Int}, axes(B))","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"These are described in more detail below.","category":"page"},{"location":"devdocs/offset-arrays/#Things-to-watch-out-for","page":"Arrays with custom indices","title":"Things to watch out for","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Because unconventional indexing breaks many people's assumptions that all arrays start indexing with 1, there is always the chance that using such arrays will trigger errors. The most frustrating bugs would be incorrect results or segfaults (total crashes of Julia). For example, consider the following function:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"function mycopy!(dest::AbstractVector, src::AbstractVector)\n length(dest) == length(src) || throw(DimensionMismatch(\"vectors must match\"))\n # OK, now we're safe to use @inbounds, right? (not anymore!)\n for i = 1:length(src)\n @inbounds dest[i] = src[i]\n end\n dest\nend","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"This code implicitly assumes that vectors are indexed from 1; if dest starts at a different index than src, there is a chance that this code would trigger a segfault. (If you do get segfaults, to help locate the cause try running julia with the option --check-bounds=yes.)","category":"page"},{"location":"devdocs/offset-arrays/#Using-axes-for-bounds-checks-and-loop-iteration","page":"Arrays with custom indices","title":"Using axes for bounds checks and loop iteration","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"axes(A) (reminiscent of size(A)) returns a tuple of AbstractUnitRange{<:Integer} objects, specifying the range of valid indices along each dimension of A. When A has unconventional indexing, the ranges may not start at 1. If you just want the range for a particular dimension d, there is axes(A, d).","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base implements a custom range type, OneTo, where OneTo(n) means the same thing as 1:n but in a form that guarantees (via the type system) that the lower index is 1. For any new AbstractArray type, this is the default returned by axes, and it indicates that this array type uses \"conventional\" 1-based indexing.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"For bounds checking, note that there are dedicated functions checkbounds and checkindex which can sometimes simplify such tests.","category":"page"},{"location":"devdocs/offset-arrays/#Linear-indexing-(LinearIndices)","page":"Arrays with custom indices","title":"Linear indexing (LinearIndices)","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Some algorithms are most conveniently (or efficiently) written in terms of a single linear index, A[i] even if A is multi-dimensional. Regardless of the array's native indices, linear indices always range from 1:length(A). However, this raises an ambiguity for one-dimensional arrays (a.k.a., AbstractVector): does v[i] mean linear indexing , or Cartesian indexing with the array's native indices?","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"For this reason, your best option may be to iterate over the array with eachindex(A), or, if you require the indices to be sequential integers, to get the index range by calling LinearIndices(A). This will return axes(A, 1) if A is an AbstractVector, and the equivalent of 1:length(A) otherwise.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"By this definition, 1-dimensional arrays always use Cartesian indexing with the array's native indices. To help enforce this, it's worth noting that the index conversion functions will throw an error if shape indicates a 1-dimensional array with unconventional indexing (i.e., is a Tuple{UnitRange} rather than a tuple of OneTo). For arrays with conventional indexing, these functions continue to work the same as always.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Using axes and LinearIndices, here is one way you could rewrite mycopy!:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"function mycopy!(dest::AbstractVector, src::AbstractVector)\n axes(dest) == axes(src) || throw(DimensionMismatch(\"vectors must match\"))\n for i in LinearIndices(src)\n @inbounds dest[i] = src[i]\n end\n dest\nend","category":"page"},{"location":"devdocs/offset-arrays/#Allocating-storage-using-generalizations-of-similar","page":"Arrays with custom indices","title":"Allocating storage using generalizations of similar","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Storage is often allocated with Array{Int}(undef, dims) or similar(A, args...). When the result needs to match the indices of some other array, this may not always suffice. The generic replacement for such patterns is to use similar(storagetype, shape). storagetype indicates the kind of underlying \"conventional\" behavior you'd like, e.g., Array{Int} or BitArray or even dims->zeros(Float32, dims) (which would allocate an all-zeros array). shape is a tuple of Integer or AbstractUnitRange values, specifying the indices that you want the result to use. Note that a convenient way of producing an all-zeros array that matches the indices of A is simply zeros(A).","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Let's walk through a couple of explicit examples. First, if A has conventional indices, then similar(Array{Int}, axes(A)) would end up calling Array{Int}(undef, size(A)), and thus return an array. If A is an AbstractArray type with unconventional indexing, then similar(Array{Int}, axes(A)) should return something that \"behaves like\" an Array{Int} but with a shape (including indices) that matches A. (The most obvious implementation is to allocate an Array{Int}(undef, size(A)) and then \"wrap\" it in a type that shifts the indices.)","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Note also that similar(Array{Int}, (axes(A, 2),)) would allocate an AbstractVector{Int} (i.e., 1-dimensional array) that matches the indices of the columns of A.","category":"page"},{"location":"devdocs/offset-arrays/#Writing-custom-array-types-with-non-1-indexing","page":"Arrays with custom indices","title":"Writing custom array types with non-1 indexing","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Most of the methods you'll need to define are standard for any AbstractArray type, see Abstract Arrays. This page focuses on the steps needed to define unconventional indexing.","category":"page"},{"location":"devdocs/offset-arrays/#Custom-AbstractUnitRange-types","page":"Arrays with custom indices","title":"Custom AbstractUnitRange types","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"If you're writing a non-1 indexed array type, you will want to specialize axes so it returns a UnitRange, or (perhaps better) a custom AbstractUnitRange. The advantage of a custom type is that it \"signals\" the allocation type for functions like similar. If we're writing an array type for which indexing will start at 0, we likely want to begin by creating a new AbstractUnitRange, ZeroRange, where ZeroRange(n) is equivalent to 0:n-1.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"In general, you should probably not export ZeroRange from your package: there may be other packages that implement their own ZeroRange, and having multiple distinct ZeroRange types is (perhaps counterintuitively) an advantage: ModuleA.ZeroRange indicates that similar should create a ModuleA.ZeroArray, whereas ModuleB.ZeroRange indicates a ModuleB.ZeroArray type. This design allows peaceful coexistence among many different custom array types.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Note that the Julia package CustomUnitRanges.jl can sometimes be used to avoid the need to write your own ZeroRange type.","category":"page"},{"location":"devdocs/offset-arrays/#Specializing-axes","page":"Arrays with custom indices","title":"Specializing axes","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Once you have your AbstractUnitRange type, then specialize axes:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base.axes(A::ZeroArray) = map(n->ZeroRange(n), A.size)","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"where here we imagine that ZeroArray has a field called size (there would be other ways to implement this).","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"In some cases, the fallback definition for axes(A, d):","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"axes(A::AbstractArray{T,N}, d) where {T,N} = d <= N ? axes(A)[d] : OneTo(1)","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"may not be what you want: you may need to specialize it to return something other than OneTo(1) when d > ndims(A). Likewise, in Base there is a dedicated function axes1 which is equivalent to axes(A, 1) but which avoids checking (at runtime) whether ndims(A) > 0. (This is purely a performance optimization.) It is defined as:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"axes1(A::AbstractArray{T,0}) where {T} = OneTo(1)\naxes1(A::AbstractArray) = axes(A)[1]","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"If the first of these (the zero-dimensional case) is problematic for your custom array type, be sure to specialize it appropriately.","category":"page"},{"location":"devdocs/offset-arrays/#Specializing-similar","page":"Arrays with custom indices","title":"Specializing similar","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Given your custom ZeroRange type, then you should also add the following two specializations for similar:","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"function Base.similar(A::AbstractArray, T::Type, shape::Tuple{ZeroRange,Vararg{ZeroRange}})\n # body\nend\n\nfunction Base.similar(f::Union{Function,DataType}, shape::Tuple{ZeroRange,Vararg{ZeroRange}})\n # body\nend","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Both of these should allocate your custom array type.","category":"page"},{"location":"devdocs/offset-arrays/#Specializing-reshape","page":"Arrays with custom indices","title":"Specializing reshape","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Optionally, define a method","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base.reshape(A::AbstractArray, shape::Tuple{ZeroRange,Vararg{ZeroRange}}) = ...","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"and you can reshape an array so that the result has custom indices.","category":"page"},{"location":"devdocs/offset-arrays/#For-objects-that-mimic-AbstractArray-but-are-not-subtypes","page":"Arrays with custom indices","title":"For objects that mimic AbstractArray but are not subtypes","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"has_offset_axes depends on having axes defined for the objects you call it on. If there is some reason you don't have an axes method defined for your object, consider defining a method","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"Base.has_offset_axes(obj::MyNon1IndexedArraylikeObject) = true","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"This will allow code that assumes 1-based indexing to detect a problem and throw a helpful error, rather than returning incorrect results or segfaulting julia.","category":"page"},{"location":"devdocs/offset-arrays/#Catching-errors","page":"Arrays with custom indices","title":"Catching errors","text":"","category":"section"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"If your new array type triggers errors in other code, one helpful debugging step can be to comment out @boundscheck in your getindex and setindex! implementation. This will ensure that every element access checks bounds. Or, restart julia with --check-bounds=yes.","category":"page"},{"location":"devdocs/offset-arrays/","page":"Arrays with custom indices","title":"Arrays with custom indices","text":"In some cases it may also be helpful to temporarily disable size and length for your new array type, since code that makes incorrect assumptions frequently uses these functions.","category":"page"},{"location":"devdocs/boundscheck/#Bounds-checking","page":"Bounds checking","title":"Bounds checking","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Like many modern programming languages, Julia uses bounds checking to ensure program safety when accessing arrays. In tight inner loops or other performance critical situations, you may wish to skip these bounds checks to improve runtime performance. For instance, in order to emit vectorized (SIMD) instructions, your loop body cannot contain branches, and thus cannot contain bounds checks. Consequently, Julia includes an @inbounds(...) macro to tell the compiler to skip such bounds checks within the given block. User-defined array types can use the @boundscheck(...) macro to achieve context-sensitive code selection.","category":"page"},{"location":"devdocs/boundscheck/#Eliding-bounds-checks","page":"Bounds checking","title":"Eliding bounds checks","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"The @boundscheck(...) macro marks blocks of code that perform bounds checking. When such blocks are inlined into an @inbounds(...) block, the compiler may remove these blocks. The compiler removes the @boundscheck block only if it is inlined into the calling function. For example, you might write the method sum as:","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"function sum(A::AbstractArray)\n r = zero(eltype(A))\n for i in eachindex(A)\n @inbounds r += A[i]\n end\n return r\nend","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"With a custom array-like type MyArray having:","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"@inline getindex(A::MyArray, i::Real) = (@boundscheck checkbounds(A, i); A.data[to_index(i)])","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Then when getindex is inlined into sum, the call to checkbounds(A, i) will be elided. If your function contains multiple layers of inlining, only @boundscheck blocks at most one level of inlining deeper are eliminated. The rule prevents unintended changes in program behavior from code further up the stack.","category":"page"},{"location":"devdocs/boundscheck/#Caution!","page":"Bounds checking","title":"Caution!","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"It is easy to accidentally expose unsafe operations with @inbounds. You might be tempted to write the above example as","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"function sum(A::AbstractArray)\n r = zero(eltype(A))\n for i in 1:length(A)\n @inbounds r += A[i]\n end\n return r\nend","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Which quietly assumes 1-based indexing and therefore exposes unsafe memory access when used with OffsetArrays:","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"julia> using OffsetArrays\n\njulia> sum(OffsetArray([1, 2, 3], -10))\n9164911648 # inconsistent results or segfault","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"While the original source of the error here is 1:length(A), the use of @inbounds increases the consequences from a bounds error to a less easily caught and debugged unsafe memory access. It is often difficult or impossible to prove that a method which uses @inbounds is safe, so one must weigh the benefits of performance improvements against the risk of segfaults and silent misbehavior, especially in public facing APIs.","category":"page"},{"location":"devdocs/boundscheck/#Propagating-inbounds","page":"Bounds checking","title":"Propagating inbounds","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"There may be certain scenarios where for code-organization reasons you want more than one layer between the @inbounds and @boundscheck declarations. For instance, the default getindex methods have the chain getindex(A::AbstractArray, i::Real) calls getindex(IndexStyle(A), A, i) calls _getindex(::IndexLinear, A, i).","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"To override the \"one layer of inlining\" rule, a function may be marked with Base.@propagate_inbounds to propagate an inbounds context (or out of bounds context) through one additional layer of inlining.","category":"page"},{"location":"devdocs/boundscheck/#The-bounds-checking-call-hierarchy","page":"Bounds checking","title":"The bounds checking call hierarchy","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"The overall hierarchy is:","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"checkbounds(A, I...) which calls\ncheckbounds(Bool, A, I...) which calls\ncheckbounds_indices(Bool, axes(A), I) which recursively calls\ncheckindex for each dimension","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Here A is the array, and I contains the \"requested\" indices. axes(A) returns a tuple of \"permitted\" indices of A.","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"checkbounds(A, I...) throws an error if the indices are invalid, whereas checkbounds(Bool, A, I...) returns false in that circumstance. checkbounds_indices discards any information about the array other than its axes tuple, and performs a pure indices-vs-indices comparison: this allows relatively few compiled methods to serve a huge variety of array types. Indices are specified as tuples, and are usually compared in a 1-1 fashion with individual dimensions handled by calling another important function, checkindex: typically,","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"checkbounds_indices(Bool, (IA1, IA...), (I1, I...)) = checkindex(Bool, IA1, I1) &\n checkbounds_indices(Bool, IA, I)","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"so checkindex checks a single dimension. All of these functions, including the unexported checkbounds_indices have docstrings accessible with ? .","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"If you have to customize bounds checking for a specific array type, you should specialize checkbounds(Bool, A, I...). However, in most cases you should be able to rely on checkbounds_indices as long as you supply useful axes for your array type.","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"If you have novel index types, first consider specializing checkindex, which handles a single index for a particular dimension of an array. If you have a custom multidimensional index type (similar to CartesianIndex), then you may have to consider specializing checkbounds_indices.","category":"page"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Note this hierarchy has been designed to reduce the likelihood of method ambiguities. We try to make checkbounds the place to specialize on array type, and try to avoid specializations on index types; conversely, checkindex is intended to be specialized only on index type (especially, the last argument).","category":"page"},{"location":"devdocs/boundscheck/#Emit-bounds-checks","page":"Bounds checking","title":"Emit bounds checks","text":"","category":"section"},{"location":"devdocs/boundscheck/","page":"Bounds checking","title":"Bounds checking","text":"Julia can be launched with --check-bounds={yes|no|auto} to emit bounds checks always, never, or respect @inbounds declarations.","category":"page"},{"location":"devdocs/build/build/#Building-Julia-(Detailed)","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"","category":"section"},{"location":"devdocs/build/build/#Downloading-the-Julia-source-code","page":"Building Julia (Detailed)","title":"Downloading the Julia source code","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you are behind a firewall, you may need to use the https protocol instead of the git protocol:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"git config --global url.\"https://\".insteadOf git://","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Be sure to also configure your system to use the appropriate proxy settings, e.g. by setting the https_proxy and http_proxy variables.","category":"page"},{"location":"devdocs/build/build/#Building-Julia","page":"Building Julia (Detailed)","title":"Building Julia","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"When compiled the first time, the build will automatically download pre-built external dependencies. If you prefer to build all the dependencies on your own, or are building on a system that cannot access the network during the build process, add the following in Make.user:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"USE_BINARYBUILDER=0","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Building Julia requires 5GiB if building all dependencies and approximately 4GiB of virtual memory.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"To perform a parallel build, use make -j N and supply the maximum number of concurrent processes. If the defaults in the build do not work for you, and you need to set specific make parameters, you can save them in Make.user, and place the file in the root of your Julia source. The build will automatically check for the existence of Make.user and use it if it exists.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"You can create out-of-tree builds of Julia by specifying make O= configure on the command line. This will create a directory mirror, with all of the necessary Makefiles to build Julia, in the specified directory. These builds will share the source files in Julia and deps/srccache. Each out-of-tree build directory can have its own Make.user file to override the global Make.user file in the top-level folder.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If everything works correctly, you will see a Julia banner and an interactive prompt into which you can enter expressions for evaluation. (Errors related to libraries might be caused by old, incompatible libraries sitting around in your PATH. In this case, try moving the julia directory earlier in the PATH). Note that most of the instructions above apply to unix systems.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"To run julia from anywhere you can:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"add an alias (in bash: echo \"alias julia='/path/to/install/folder/bin/julia'\" >> ~/.bashrc && source ~/.bashrc), or\nadd a soft link to the julia executable in the julia directory to /usr/local/bin (or any suitable directory already in your path), or\nadd the julia directory to your executable path for this shell session (in bash: export PATH=\"$(pwd):$PATH\" ; in csh or tcsh:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"set path= ( $path $cwd ) ), or","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"add the julia directory to your executable path permanently (e.g. in .bash_profile), or\nwrite prefix=/path/to/install/folder into Make.user and then run make install. If there is a version of Julia already installed in this folder, you should delete it before running make install.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Some of the options you can set to control the build of Julia are listed and documented at the beginning of the file Make.inc, but you should never edit it for this purpose, use Make.user instead.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Julia's Makefiles define convenient automatic rules called print- for printing the value of variables, replacing with the name of the variable to print the value of. For example","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"$ make print-JULIA_PRECOMPILE\nJULIA_PRECOMPILE=1","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"These rules are useful for debugging purposes.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Now you should be able to run Julia like this:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"julia","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you are building a Julia package for distribution on Linux, macOS, or Windows, take a look at the detailed notes in distributing.md.","category":"page"},{"location":"devdocs/build/build/#Updating-an-existing-source-tree","page":"Building Julia (Detailed)","title":"Updating an existing source tree","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you have previously downloaded julia using git clone, you can update the existing source tree using git pull rather than starting anew:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"cd julia\ngit pull && make","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Assuming that you had made no changes to the source tree that will conflict with upstream updates, these commands will trigger a build to update to the latest version.","category":"page"},{"location":"devdocs/build/build/#General-troubleshooting","page":"Building Julia (Detailed)","title":"General troubleshooting","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Over time, the base library may accumulate enough changes such that the bootstrapping process in building the system image will fail. If this happens, the build may fail with an error like\n *** This error is usually fixed by running 'make clean'. If the error persists, try 'make cleanall' ***\nAs described, running make clean && make is usually sufficient. Occasionally, the stronger cleanup done by make cleanall is needed.\nNew versions of external dependencies may be introduced which may occasionally cause conflicts with existing builds of older versions.\na. Special make targets exist to help wipe the existing build of a dependency. For example, make -C deps clean-llvm will clean out the existing build of llvm so that llvm will be rebuilt from the downloaded source distribution the next time make is called. make -C deps distclean-llvm is a stronger wipe which will also delete the downloaded source distribution, ensuring that a fresh copy of the source distribution will be downloaded and that any new patches will be applied the next time make is called.\nb. To delete existing binaries of julia and all its dependencies, delete the ./usr directory in the source tree.\nIf you've updated macOS recently, be sure to run xcode-select --install to update the command line tools. Otherwise, you could run into errors for missing headers and libraries, such as ld: library not found for -lcrt1.10.6.o.\nIf you've moved the source directory, you might get errors such as CMake Error: The current CMakeCache.txt directory ... is different than the directory ... where CMakeCache.txt was created., in which case you may delete the offending dependency under deps\nIn extreme cases, you may wish to reset the source tree to a pristine state. The following git commands may be helpful:\n git reset --hard #Forcibly remove any changes to any files under version control\n git clean -x -f -d #Forcibly remove any file or directory not under version control\nTo avoid losing work, make sure you know what these commands do before you run them. git will not be able to undo these changes!","category":"page"},{"location":"devdocs/build/build/#Platform-Specific-Notes","page":"Building Julia (Detailed)","title":"Platform-Specific Notes","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Notes for various operating systems:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Linux\nmacOS\nWindows\nFreeBSD","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Notes for various architectures:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"ARM","category":"page"},{"location":"devdocs/build/build/#Required-Build-Tools-and-External-Libraries","page":"Building Julia (Detailed)","title":"Required Build Tools and External Libraries","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Building Julia requires that the following software be installed:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"[GNU make] — building dependencies.\n[gcc & g++][gcc] (>= 7.1) or [Clang][clang] (>= 5.0, >= 9.3 for Apple Clang) — compiling and linking C, C++.\n[libatomic][gcc] — provided by [gcc] and needed to support atomic operations.\n[python] (>=2.7) — needed to build LLVM.\n[gfortran] — compiling and linking Fortran libraries.\n[perl] — preprocessing of header files of libraries.\n[wget], [curl], or [fetch] (FreeBSD) — to automatically download external libraries.\n[m4] — needed to build GMP.\n[awk] — helper tool for Makefiles.\n[patch] — for modifying source code.\n[cmake] (>= 3.4.3) — needed to build libgit2.\n[pkg-config] — needed to build libgit2 correctly, especially for proxy support.\n[powershell] (>= 3.0) — necessary only on Windows.\n[which] — needed for checking build dependencies.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"On Debian-based distributions (e.g. Ubuntu), you can easily install them with apt-get:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"sudo apt-get install build-essential libatomic1 python gfortran perl wget m4 cmake pkg-config curl","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Julia uses the following external libraries, which are automatically downloaded (or in a few cases, included in the Julia source repository) and then compiled from source the first time you run make. The specific version numbers of these libraries that Julia uses are listed in deps/$(libname).version:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"[LLVM] (15.0 + patches) — compiler infrastructure (see note below).\n[FemtoLisp] — packaged with Julia source, and used to implement the compiler front-end.\n[libuv] (custom fork) — portable, high-performance event-based I/O library.\n[OpenLibm] — portable libm library containing elementary math functions.\n[DSFMT] — fast Mersenne Twister pseudorandom number generator library.\n[OpenBLAS] — fast, open, and maintained [basic linear algebra subprograms (BLAS)]\n[LAPACK] — library of linear algebra routines for solving systems of simultaneous linear equations, least-squares solutions of linear systems of equations, eigenvalue problems, and singular value problems.\n[MKL] (optional) – OpenBLAS and LAPACK may be replaced by Intel's MKL library.\n[SuiteSparse] — library of linear algebra routines for sparse matrices.\n[PCRE] — Perl-compatible regular expressions library.\n[GMP] — GNU multiple precision arithmetic library, needed for BigInt support.\n[MPFR] — GNU multiple precision floating point library, needed for arbitrary precision floating point (BigFloat) support.\n[libgit2] — Git linkable library, used by Julia's package manager.\n[curl] — libcurl provides download and proxy support.\n[libssh2] — library for SSH transport, used by libgit2 for packages with SSH remotes.\n[mbedtls] — library used for cryptography and transport layer security, used by libssh2\n[utf8proc] — a library for processing UTF-8 encoded Unicode strings.\n[LLVM libunwind] — LLVM's fork of [libunwind], a library that determines the call-chain of a program.\n[ITTAPI] — Intel's Instrumentation and Tracing Technology and Just-In-Time API.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"[GNU make]: https://www.gnu.org/software/make [patch]: https://www.gnu.org/software/patch [wget]: https://www.gnu.org/software/wget [m4]: https://www.gnu.org/software/m4 [awk]: https://www.gnu.org/software/gawk [gcc]: https://gcc.gnu.org [clang]: https://clang.llvm.org [python]: https://www.python.org/ [gfortran]: https://gcc.gnu.org/fortran/ [curl]: https://curl.haxx.se [fetch]: https://www.freebsd.org/cgi/man.cgi?fetch(1) [perl]: https://www.perl.org [cmake]: https://www.cmake.org [OpenLibm]: https://github.com/JuliaLang/openlibm [DSFMT]: https://github.com/MersenneTwister-Lab/dSFMT [OpenBLAS]: https://github.com/xianyi/OpenBLAS [LAPACK]: https://www.netlib.org/lapack [MKL]: https://software.intel.com/en-us/articles/intel-mkl [SuiteSparse]: https://people.engr.tamu.edu/davis/suitesparse.html [PCRE]: https://www.pcre.org [LLVM]: https://www.llvm.org [LLVM libunwind]: https://github.com/llvm/llvm-project/tree/main/libunwind [FemtoLisp]: https://github.com/JeffBezanson/femtolisp [GMP]: https://gmplib.org [MPFR]: https://www.mpfr.org [libuv]: https://github.com/JuliaLang/libuv [libgit2]: https://libgit2.org/ [utf8proc]: https://julialang.org/utf8proc/ [libunwind]: https://www.nongnu.org/libunwind [libssh2]: https://www.libssh2.org [mbedtls]: https://tls.mbed.org/ [pkg-config]: https://www.freedesktop.org/wiki/Software/pkg-config/ [powershell]: https://docs.microsoft.com/en-us/powershell/scripting/wmf/overview [which]: https://carlowood.github.io/which/ [ITTAPI]: https://github.com/intel/ittapi","category":"page"},{"location":"devdocs/build/build/#Build-dependencies","page":"Building Julia (Detailed)","title":"Build dependencies","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you already have one or more of these packages installed on your system, you can prevent Julia from compiling duplicates of these libraries by passing USE_SYSTEM_...=1 to make or adding the line to Make.user. The complete list of possible flags can be found in Make.inc.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Please be aware that this procedure is not officially supported, as it introduces additional variability into the installation and versioning of the dependencies, and is recommended only for system package maintainers. Unexpected compile errors may result, as the build system will do no further checking to ensure the proper packages are installed.","category":"page"},{"location":"devdocs/build/build/#LLVM","page":"Building Julia (Detailed)","title":"LLVM","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"The most complicated dependency is LLVM, for which we require additional patches from upstream (LLVM is not backward compatible).","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"For packaging Julia with LLVM, we recommend either:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"bundling a Julia-only LLVM library inside the Julia package, or\nadding the patches to the LLVM package of the distribution.\nA complete list of patches is available in on Github see the julia-release/15.x branch.\nThe only Julia-specific patch is the lib renaming (llvm7-symver-jlprefix.patch), which should not be applied to a system LLVM.\nThe remaining patches are all upstream bug fixes, and have been contributed into upstream LLVM.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Using an unpatched or different version of LLVM will result in errors and/or poor performance. You can build a different version of LLVM from a remote Git repository with the following options in the Make.user file:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"# Force source build of LLVM\nUSE_BINARYBUILDER_LLVM = 0\n# Use Git for fetching LLVM source code\n# this is either `1` to get all of them\nDEPS_GIT = 1\n# or a space-separated list of specific dependencies to download with git\nDEPS_GIT = llvm\n\n# Other useful options:\n#URL of the Git repository you want to obtain LLVM from:\n# LLVM_GIT_URL = ...\n#Name of the alternate branch to clone from git\n# LLVM_BRANCH = julia-16.0.6-0\n#SHA hash of the alternate commit to check out automatically\n# LLVM_SHA1 = $(LLVM_BRANCH)\n#List of LLVM targets to build. It is strongly recommended to keep at least all the\n#default targets listed in `deps/llvm.mk`, even if you don't necessarily need all of them.\n# LLVM_TARGETS = ...\n#Use ccache for faster recompilation in case you need to restart a build.\n# USECCACHE = 1\n# CMAKE_GENERATOR=Ninja\n# LLVM_ASSERTIONS=1\n# LLVM_DEBUG=Symbols","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"The various build phases are controlled by specific files:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"deps/llvm.version : touch or change to checkout a new version, make get-llvm check-llvm\ndeps/srccache/llvm/source-extracted : result of make extract-llvm\ndeps/llvm/build_Release*/build-configured : result of make configure-llvm\ndeps/llvm/build_Release*/build-configured : result of make compile-llvm\nusr-staging/llvm/build_Release*.tgz : result of make stage-llvm (regenerate with make reinstall-llvm)\nusr/manifest/llvm : result of make install-llvm (regenerate with make uninstall-llvm)\nmake version-check-llvm : runs every time to warn the user if there are local modifications","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Though Julia can be built with newer LLVM versions, support for this should be regarded as experimental and not suitable for packaging.","category":"page"},{"location":"devdocs/build/build/#libuv","page":"Building Julia (Detailed)","title":"libuv","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Julia uses a custom fork of libuv. It is a small dependency, and can be safely bundled in the same package as Julia, and will not conflict with the system library. Julia builds should not try to use the system libuv.","category":"page"},{"location":"devdocs/build/build/#BLAS-and-LAPACK","page":"Building Julia (Detailed)","title":"BLAS and LAPACK","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"As a high-performance numerical language, Julia should be linked to a multi-threaded BLAS and LAPACK, such as OpenBLAS or ATLAS, which will provide much better performance than the reference libblas implementations which may be default on some systems.","category":"page"},{"location":"devdocs/build/build/#Source-distributions-of-releases","page":"Building Julia (Detailed)","title":"Source distributions of releases","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Each pre-release and release of Julia has a \"full\" source distribution and a \"light\" source distribution.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"The full source distribution contains the source code for Julia and all dependencies so that it can be built from source without an internet connection. The light source distribution does not include the source code of dependencies.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"For example, julia-1.0.0.tar.gz is the light source distribution for the v1.0.0 release of Julia, while julia-1.0.0-full.tar.gz is the full source distribution.","category":"page"},{"location":"devdocs/build/build/#Building-Julia-from-source-with-a-Git-checkout-of-a-stdlib","page":"Building Julia (Detailed)","title":"Building Julia from source with a Git checkout of a stdlib","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you need to build Julia from source with a Git checkout of a stdlib, then use make DEPS_GIT=NAME_OF_STDLIB when building Julia.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"For example, if you need to build Julia from source with a Git checkout of Pkg, then use make DEPS_GIT=Pkg when building Julia. The Pkg repo is in stdlib/Pkg, and created initially with a detached HEAD. If you're doing this from a pre-existing Julia repository, you may need to make clean beforehand.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"If you need to build Julia from source with Git checkouts of more than one stdlib, then DEPS_GIT should be a space-separated list of the stdlib names. For example, if you need to build Julia from source with a Git checkout of Pkg, Tar, and Downloads, then use make DEPS_GIT='Pkg Tar Downloads' when building Julia.","category":"page"},{"location":"devdocs/build/build/#Building-an-\"assert-build\"-of-Julia","page":"Building Julia (Detailed)","title":"Building an \"assert build\" of Julia","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"An \"assert build\" of Julia is a build that was built with both FORCE_ASSERTIONS=1 and LLVM_ASSERTIONS=1. To build an assert build, define both of the following variables in your Make.user file:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"FORCE_ASSERTIONS=1\nLLVM_ASSERTIONS=1","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Please note that assert builds of Julia will be slower than regular (non-assert) builds.","category":"page"},{"location":"devdocs/build/build/#Building-32-bit-Julia-on-a-64-bit-machine","page":"Building Julia (Detailed)","title":"Building 32-bit Julia on a 64-bit machine","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Occasionally, bugs specific to 32-bit architectures may arise, and when this happens it is useful to be able to debug the problem on your local machine. Since most modern 64-bit systems support running programs built for 32-bit ones, if you don't have to recompile Julia from source (e.g. you mainly need to inspect the behavior of a 32-bit Julia without having to touch the C code), you can likely use a 32-bit build of Julia for your system that you can obtain from the official downloads page. However, if you do need to recompile Julia from source one option is to use a Docker container of a 32-bit system. At least for now, building a 32-bit version of Julia is relatively straightforward using ubuntu 32-bit docker images. In brief, after setting up docker here are the required steps:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"$ docker pull i386/ubuntu\n$ docker run --platform i386 -i -t i386/ubuntu /bin/bash","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"At this point you should be in a 32-bit machine console (note that uname reports the host architecture, so will still say 64-bit, but this will not affect the Julia build). You can add packages and compile code; when you exit, all the changes will be lost, so be sure to finish your analysis in a single session or set up a copy/pastable script you can use to set up your environment.","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"From this point, you should","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"# apt update","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"(Note that sudo isn't installed, but neither is it necessary since you are running as root, so you can omit sudo from all commands.)","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Then add all the build dependencies, a console-based editor of your choice, git, and anything else you'll need (e.g., gdb, rr, etc). Pick a directory to work in and git clone Julia, check out the branch you wish to debug, and build Julia as usual.","category":"page"},{"location":"devdocs/build/build/#Update-the-version-number-of-a-dependency","page":"Building Julia (Detailed)","title":"Update the version number of a dependency","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"There are two types of builds","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Build everything (deps/ and src/) from source code. (Add USE_BINARYBUILDER=0 to Make.user, see Building Julia)\nBuild from source (src/) with pre-compiled dependencies (default)","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"When you want to update the version number of a dependency in deps/, you may want to use the following checklist:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"### Check list\n\nVersion numbers:\n- [ ] `deps/$(libname).version`: `LIBNAME_VER`, `LIBNAME_BRANCH`, `LIBNAME_SHA1` and `LIBNAME_JLL_VER`\n- [ ] `stdlib/$(LIBNAME_JLL_NAME)_jll/Project.toml`: `version`\n\nChecksum:\n- [ ] `deps/checksums/$(libname)`\n- [ ] `deps/checksums/$(LIBNAME_JLL_NAME)-*/`: `md5` and `sha512`\n\nPatches:\n- [ ] `deps/$(libname).mk`\n- [ ] `deps/patches/$(libname)-*.patch`","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Note:","category":"page"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"For specific dependencies, some items in the checklist may not exist.\nFor checksum file, it may be a single file without a suffix, or a folder containing two files.","category":"page"},{"location":"devdocs/build/build/#Example:-OpenLibm","page":"Building Julia (Detailed)","title":"Example: OpenLibm","text":"","category":"section"},{"location":"devdocs/build/build/","page":"Building Julia (Detailed)","title":"Building Julia (Detailed)","text":"Update Version numbers in deps/openlibm.version\nOPENLIBM_VER := 0.X.Y\nOPENLIBM_BRANCH = v0.X.Y\nOPENLIBM_SHA1 = new-sha1-hash\nUpdate Version number in stdlib/OpenLibm_jll/Project.toml\nversion = \"0.X.Y+0\"\nUpdate checksums in deps/checksums/openlibm\nmake -f contrib/refresh_checksums.mk openlibm\nCheck if the patch files deps/patches/openlibm-*.patch exist\nif patches don't exist, skip.\nif patches exist, check if they have been merged into the new version and need to be removed. When deleting a patch, remember to modify the corresponding Makefile file (deps/openlibm.mk).","category":"page"},{"location":"devdocs/build/freebsd/#FreeBSD","page":"FreeBSD","title":"FreeBSD","text":"","category":"section"},{"location":"devdocs/build/freebsd/","page":"FreeBSD","title":"FreeBSD","text":"Clang is the default compiler on FreeBSD 11.0-RELEASE and above. The remaining build tools are available from the Ports Collection, and can be installed using pkg install git gcc gmake cmake pkgconf. To build Julia, simply run gmake. (Note that gmake must be used rather than make, since make on FreeBSD corresponds to the incompatible BSD Make rather than GNU Make.)","category":"page"},{"location":"devdocs/build/freebsd/","page":"FreeBSD","title":"FreeBSD","text":"As mentioned above, it is important to note that the USE_SYSTEM_* flags should be used with caution on FreeBSD. This is because many system libraries, and even libraries from the Ports Collection, link to the system's libgcc_s.so.1, or to another library which links to the system libgcc_s. This library declares its GCC version to be 4.6, which is too old to build Julia, and conflicts with other libraries when linking. Thus it is highly recommended to simply allow Julia to build all of its dependencies. If you do choose to use the USE_SYSTEM_* flags, note that /usr/local is not on the compiler path by default, so you may need to add LDFLAGS=-L/usr/local/lib and CPPFLAGS=-I/usr/local/include to your Make.user, though doing so may interfere with other dependencies.","category":"page"},{"location":"devdocs/build/freebsd/","page":"FreeBSD","title":"FreeBSD","text":"Note that the x86 architecture does not support threading due to lack of compiler runtime library support, so you may need to set JULIA_THREADS=0 in your Make.user if you're on a 32-bit system.","category":"page"},{"location":"stdlib/Downloads/#Downloads","page":"Downloads","title":"Downloads","text":"","category":"section"},{"location":"stdlib/Downloads/","page":"Downloads","title":"Downloads","text":"Downloads.download\nDownloads.request\nDownloads.Response\nDownloads.RequestError\nDownloads.Downloader","category":"page"},{"location":"stdlib/Downloads/#Downloads.download","page":"Downloads","title":"Downloads.download","text":"download(url, [ output = tempname() ];\n [ method = \"GET\", ]\n [ headers = , ]\n [ timeout = , ]\n [ progress = , ]\n [ verbose = false, ]\n [ debug = , ]\n [ downloader = , ]\n) -> output\n\n url :: AbstractString\n output :: Union{AbstractString, AbstractCmd, IO}\n method :: AbstractString\n headers :: Union{AbstractVector, AbstractDict}\n timeout :: Real\n progress :: (total::Integer, now::Integer) --> Any\n verbose :: Bool\n debug :: (type, message) --> Any\n downloader :: Downloader\n\nDownload a file from the given url, saving it to output or if not specified, a temporary path. The output can also be an IO handle, in which case the body of the response is streamed to that handle and the handle is returned. If output is a command, the command is run and output is sent to it on stdin.\n\nIf the downloader keyword argument is provided, it must be a Downloader object. Resources and connections will be shared between downloads performed by the same Downloader and cleaned up automatically when the object is garbage collected or there have been no downloads performed with it for a grace period. See Downloader for more info about configuration and usage.\n\nIf the headers keyword argument is provided, it must be a vector or dictionary whose elements are all pairs of strings. These pairs are passed as headers when downloading URLs with protocols that supports them, such as HTTP/S.\n\nThe timeout keyword argument specifies a timeout for the download to complete in seconds, with a resolution of milliseconds. By default no timeout is set, but this can also be explicitly requested by passing a timeout value of Inf. Separately, if 20 seconds elapse without receiving any data, the download will timeout. See extended help for how to disable this timeout.\n\nIf the progress keyword argument is provided, it must be a callback function which will be called whenever there are updates about the size and status of the ongoing download. The callback must take two integer arguments: total and now which are the total size of the download in bytes, and the number of bytes which have been downloaded so far. Note that total starts out as zero and remains zero until the server gives an indication of the total size of the download (e.g. with a Content-Length header), which may never happen. So a well-behaved progress callback should handle a total size of zero gracefully.\n\nIf the verbose option is set to true, libcurl, which is used to implement the download functionality will print debugging information to stderr. If the debug option is set to a function accepting two String arguments, then the verbose option is ignored and instead the data that would have been printed to stderr is passed to the debug callback with type and message arguments. The type argument indicates what kind of event has occurred, and is one of: TEXT, HEADER IN, HEADER OUT, DATA IN, DATA OUT, SSL DATA IN or SSL DATA OUT. The message argument is the description of the debug event.\n\nExtended Help\n\nFor further customization, use a Downloader and easy_hooks. For example, to disable the 20 second timeout when no data is received, you may use the following:\n\ndownloader = Downloads.Downloader()\ndownloader.easy_hook = (easy, info) -> Downloads.Curl.setopt(easy, Downloads.Curl.CURLOPT_LOW_SPEED_TIME, 0)\n\nDownloads.download(\"https://httpbingo.julialang.org/delay/30\"; downloader)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Downloads/#Downloads.request","page":"Downloads","title":"Downloads.request","text":"request(url;\n [ input = , ]\n [ output = , ]\n [ method = input ? \"PUT\" : output ? \"GET\" : \"HEAD\", ]\n [ headers = , ]\n [ timeout = , ]\n [ progress = , ]\n [ verbose = false, ]\n [ debug = , ]\n [ throw = true, ]\n [ downloader = , ]\n) -> Union{Response, RequestError}\n\n url :: AbstractString\n input :: Union{AbstractString, AbstractCmd, IO}\n output :: Union{AbstractString, AbstractCmd, IO}\n method :: AbstractString\n headers :: Union{AbstractVector, AbstractDict}\n timeout :: Real\n progress :: (dl_total, dl_now, ul_total, ul_now) --> Any\n verbose :: Bool\n debug :: (type, message) --> Any\n throw :: Bool\n downloader :: Downloader\n\nMake a request to the given url, returning a Response object capturing the status, headers and other information about the response. The body of the response is written to output if specified and discarded otherwise. For HTTP/S requests, if an input stream is given, a PUT request is made; otherwise if an output stream is given, a GET request is made; if neither is given a HEAD request is made. For other protocols, appropriate default methods are used based on what combination of input and output are requested. The following options differ from the download function:\n\ninput allows providing a request body; if provided default to PUT request\nprogress is a callback taking four integers for upload and download progress\nthrow controls whether to throw or return a RequestError on request error\n\nNote that unlike download which throws an error if the requested URL could not be downloaded (indicated by non-2xx status code), request returns a Response object no matter what the status code of the response is. If there is an error with getting a response at all, then a RequestError is thrown or returned.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Downloads/#Downloads.Response","page":"Downloads","title":"Downloads.Response","text":"struct Response\n proto :: String\n url :: String\n status :: Int\n message :: String\n headers :: Vector{Pair{String,String}}\nend\n\nResponse is a type capturing the properties of a successful response to a request as an object. It has the following fields:\n\nproto: the protocol that was used to get the response\nurl: the URL that was ultimately requested after following redirects\nstatus: the status code of the response, indicating success, failure, etc.\nmessage: a textual message describing the nature of the response\nheaders: any headers that were returned with the response\n\nThe meaning and availability of some of these responses depends on the protocol used for the request. For many protocols, including HTTP/S and S/FTP, a 2xx status code indicates a successful response. For responses in protocols that do not support headers, the headers vector will be empty. HTTP/2 does not include a status message, only a status code, so the message will be empty.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Downloads/#Downloads.RequestError","page":"Downloads","title":"Downloads.RequestError","text":"struct RequestError <: ErrorException\n url :: String\n code :: Int\n message :: String\n response :: Response\nend\n\nRequestError is a type capturing the properties of a failed response to a request as an exception object:\n\nurl: the original URL that was requested without any redirects\ncode: the libcurl error code; 0 if a protocol-only error occurred\nmessage: the libcurl error message indicating what went wrong\nresponse: response object capturing what response info is available\n\nThe same RequestError type is thrown by download if the request was successful but there was a protocol-level error indicated by a status code that is not in the 2xx range, in which case code will be zero and the message field will be the empty string. The request API only throws a RequestError if the libcurl error code is non-zero, in which case the included response object is likely to have a status of zero and an empty message. There are, however, situations where a curl-level error is thrown due to a protocol error, in which case both the inner and outer code and message may be of interest.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Downloads/#Downloads.Downloader","page":"Downloads","title":"Downloads.Downloader","text":"Downloader(; [ grace::Real = 30 ])\n\nDownloader objects are used to perform individual download operations. Connections, name lookups and other resources are shared within a Downloader. These connections and resources are cleaned up after a configurable grace period (default: 30 seconds) since anything was downloaded with it, or when it is garbage collected, whichever comes first. If the grace period is set to zero, all resources will be cleaned up immediately as soon as there are no more ongoing downloads in progress. If the grace period is set to Inf then resources are not cleaned up until Downloader is garbage collected.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Random/docs/src/index.md\"","category":"page"},{"location":"stdlib/Random/#Random-Numbers","page":"Random Numbers","title":"Random Numbers","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"DocTestSetup = :(using Random)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random number generation in Julia uses the Xoshiro256++ algorithm by default, with per-Task state. Other RNG types can be plugged in by inheriting the AbstractRNG type; they can then be used to obtain multiple streams of random numbers.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The PRNGs (pseudorandom number generators) exported by the Random package are:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"TaskLocalRNG: a token that represents use of the currently active Task-local stream, deterministically seeded from the parent task, or by RandomDevice (with system randomness) at program start\nXoshiro: generates a high-quality stream of random numbers with a small state vector and high performance using the Xoshiro256++ algorithm\nRandomDevice: for OS-provided entropy. This may be used for cryptographically secure random numbers (CS(P)RNG).\nMersenneTwister: an alternate high-quality PRNG which was the default in older versions of Julia, and is also quite fast, but requires much more space to store the state vector and generate a random sequence.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Most functions related to random generation accept an optional AbstractRNG object as first argument. Some also accept dimension specifications dims... (which can also be given as a tuple) to generate arrays of random values. In a multi-threaded program, you should generally use different RNG objects from different threads or tasks in order to be thread-safe. However, the default RNG is thread-safe as of Julia 1.3 (using a per-thread RNG up to version 1.6, and per-task thereafter).","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The provided RNGs can generate uniform random numbers of the following types: Float16, Float32, Float64, BigFloat, Bool, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, BigInt (or complex numbers of those types). Random floating point numbers are generated uniformly in 0 1). As BigInt represents unbounded integers, the interval must be specified (e.g. rand(big.(1:6))).","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Additionally, normal and exponential distributions are implemented for some AbstractFloat and Complex types, see randn and randexp for details.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"To generate random numbers from other distributions, see the Distributions.jl package.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"warning: Warning\nBecause the precise way in which random numbers are generated is considered an implementation detail, bug fixes and speed improvements may change the stream of numbers that are generated after a version change. Relying on a specific seed or generated stream of numbers during unit testing is thus discouraged - consider testing properties of the methods in question instead.","category":"page"},{"location":"stdlib/Random/#Random-numbers-module","page":"Random Numbers","title":"Random numbers module","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.Random","category":"page"},{"location":"stdlib/Random/#Random.Random","page":"Random Numbers","title":"Random.Random","text":"Random\n\nSupport for generating random numbers. Provides rand, randn, AbstractRNG, Xoshiro, MersenneTwister, and RandomDevice.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Random/#Random-generation-functions","page":"Random Numbers","title":"Random generation functions","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.rand\nRandom.rand!\nRandom.bitrand\nRandom.randn\nRandom.randn!\nRandom.randexp\nRandom.randexp!\nRandom.randstring","category":"page"},{"location":"stdlib/Random/#Base.rand","page":"Random Numbers","title":"Base.rand","text":"rand([rng=default_rng()], [S], [dims...])\n\nPick a random element or array of random elements from the set of values specified by S; S can be\n\nan indexable collection (for example 1:9 or ('x', \"y\", :z))\nan AbstractDict or AbstractSet object\na string (considered as a collection of characters), or\na type from the list below, corresponding to the specified set of values\nconcrete integer types sample from typemin(S):typemax(S) (excepting BigInt which is not supported)\nconcrete floating point types sample from [0, 1)\nconcrete complex types Complex{T} if T is a sampleable type take their real and imaginary components independently from the set of values corresponding to T, but are not supported if T is not sampleable.\nall <:AbstractChar types sample from the set of valid Unicode scalars\na user-defined type and set of values; for implementation guidance please see Hooking into the Random API\na tuple type of known size and where each parameter of S is itself a sampleable type; return a value of type S. Note that tuple types such as Tuple{Vararg{T}} (unknown size) and Tuple{1:2} (parameterized with a value) are not supported\na Pair type, e.g. Pair{X, Y} such that rand is defined for X and Y, in which case random pairs are produced.\n\nS defaults to Float64. When only one argument is passed besides the optional rng and is a Tuple, it is interpreted as a collection of values (S) and not as dims.\n\nSee also randn for normally distributed numbers, and rand! and randn! for the in-place equivalents.\n\ncompat: Julia 1.1\nSupport for S as a tuple requires at least Julia 1.1.\n\ncompat: Julia 1.11\nSupport for S as a Tuple type requires at least Julia 1.11.\n\nExamples\n\njulia> rand(Int, 2)\n2-element Array{Int64,1}:\n 1339893410598768192\n 1575814717733606317\n\njulia> using Random\n\njulia> rand(Xoshiro(0), Dict(1=>2, 3=>4))\n3 => 4\n\njulia> rand((2, 3))\n3\n\njulia> rand(Float64, (2, 3))\n2×3 Array{Float64,2}:\n 0.999717 0.0143835 0.540787\n 0.696556 0.783855 0.938235\n\nnote: Note\nThe complexity of rand(rng, s::Union{AbstractDict,AbstractSet}) is linear in the length of s, unless an optimized method with constant complexity is available, which is the case for Dict, Set and dense BitSets. For more than a few calls, use rand(rng, collect(s)) instead, or either rand(rng, Dict(s)) or rand(rng, Set(s)) as appropriate.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.rand!","page":"Random Numbers","title":"Random.rand!","text":"rand!([rng=default_rng()], A, [S=eltype(A)])\n\nPopulate the array A with random values. If S is specified (S can be a type or a collection, cf. rand for details), the values are picked randomly from S. This is equivalent to copyto!(A, rand(rng, S, size(A))) but without allocating a new array.\n\nExamples\n\njulia> rand!(Xoshiro(123), zeros(5))\n5-element Vector{Float64}:\n 0.521213795535383\n 0.5868067574533484\n 0.8908786980927811\n 0.19090669902576285\n 0.5256623915420473\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.bitrand","page":"Random Numbers","title":"Random.bitrand","text":"bitrand([rng=default_rng()], [dims...])\n\nGenerate a BitArray of random boolean values.\n\nExamples\n\njulia> bitrand(Xoshiro(123), 10)\n10-element BitVector:\n 0\n 1\n 0\n 1\n 0\n 1\n 0\n 0\n 1\n 1\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Base.randn","page":"Random Numbers","title":"Base.randn","text":"randn([rng=default_rng()], [T=Float64], [dims...])\n\nGenerate a normally-distributed random number of type T with mean 0 and standard deviation 1. Given the optional dims argument(s), generate an array of size dims of such numbers. Julia's standard library supports randn for any floating-point type that implements rand, e.g. the Base types Float16, Float32, Float64 (the default), and BigFloat, along with their Complex counterparts.\n\n(When T is complex, the values are drawn from the circularly symmetric complex normal distribution of variance 1, corresponding to real and imaginary parts having independent normal distribution with mean zero and variance 1/2).\n\nSee also randn! to act in-place.\n\nExamples\n\nGenerating a single random number (with the default Float64 type):\n\njulia> randn()\n-0.942481877315864\n\nGenerating a matrix of normal random numbers (with the default Float64 type):\n\njulia> randn(2,3)\n2×3 Matrix{Float64}:\n 1.18786 -0.678616 1.49463\n -0.342792 -0.134299 -1.45005\n\nSetting up of the random number generator rng with a user-defined seed (for reproducible numbers) and using it to generate a random Float32 number or a matrix of ComplexF32 random numbers:\n\njulia> using Random\n\njulia> rng = Xoshiro(123);\n\njulia> randn(rng, Float32)\n-0.6457307f0\n\njulia> randn(rng, ComplexF32, (2, 3))\n2×3 Matrix{ComplexF32}:\n -1.03467-1.14806im 0.693657+0.056538im 0.291442+0.419454im\n -0.153912+0.34807im 1.0954-0.948661im -0.543347-0.0538589im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randn!","page":"Random Numbers","title":"Random.randn!","text":"randn!([rng=default_rng()], A::AbstractArray) -> A\n\nFill the array A with normally-distributed (mean 0, standard deviation 1) random numbers. Also see the rand function.\n\nExamples\n\njulia> randn!(Xoshiro(123), zeros(5))\n5-element Vector{Float64}:\n -0.6457306721039767\n -1.4632513788889214\n -1.6236037455860806\n -0.21766510678354617\n 0.4922456865251828\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randexp","page":"Random Numbers","title":"Random.randexp","text":"randexp([rng=default_rng()], [T=Float64], [dims...])\n\nGenerate a random number of type T according to the exponential distribution with scale 1. Optionally generate an array of such random numbers. The Base module currently provides an implementation for the types Float16, Float32, and Float64 (the default).\n\nExamples\n\njulia> rng = Xoshiro(123);\n\njulia> randexp(rng, Float32)\n1.1757717f0\n\njulia> randexp(rng, 3, 3)\n3×3 Matrix{Float64}:\n 1.37766 0.456653 0.236418\n 3.40007 0.229917 0.0684921\n 0.48096 0.577481 0.71835\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randexp!","page":"Random Numbers","title":"Random.randexp!","text":"randexp!([rng=default_rng()], A::AbstractArray) -> A\n\nFill the array A with random numbers following the exponential distribution (with scale 1).\n\nExamples\n\njulia> randexp!(Xoshiro(123), zeros(5))\n5-element Vector{Float64}:\n 1.1757716836348473\n 1.758884569451514\n 1.0083623637301151\n 0.3510644315565272\n 0.6348266443720407\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randstring","page":"Random Numbers","title":"Random.randstring","text":"randstring([rng=default_rng()], [chars], [len=8])\n\nCreate a random string of length len, consisting of characters from chars, which defaults to the set of upper- and lower-case letters and the digits 0-9. The optional rng argument specifies a random number generator, see Random Numbers.\n\nExamples\n\njulia> Random.seed!(3); randstring()\n\"Lxz5hUwn\"\n\njulia> randstring(Xoshiro(3), 'a':'z', 6)\n\"iyzcsm\"\n\njulia> randstring(\"ACGT\")\n\"TGCTCCTC\"\n\nnote: Note\nchars can be any collection of characters, of type Char or UInt8 (more efficient), provided rand can randomly pick characters from it.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Subsequences,-permutations-and-shuffling","page":"Random Numbers","title":"Subsequences, permutations and shuffling","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.randsubseq\nRandom.randsubseq!\nRandom.randperm\nRandom.randperm!\nRandom.randcycle\nRandom.randcycle!\nRandom.shuffle\nRandom.shuffle!","category":"page"},{"location":"stdlib/Random/#Random.randsubseq","page":"Random Numbers","title":"Random.randsubseq","text":"randsubseq([rng=default_rng(),] A, p) -> Vector\n\nReturn a vector consisting of a random subsequence of the given array A, where each element of A is included (in order) with independent probability p. (Complexity is linear in p*length(A), so this function is efficient even if p is small and A is large.) Technically, this process is known as \"Bernoulli sampling\" of A.\n\nExamples\n\njulia> randsubseq(Xoshiro(123), 1:8, 0.3)\n2-element Vector{Int64}:\n 4\n 7\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randsubseq!","page":"Random Numbers","title":"Random.randsubseq!","text":"randsubseq!([rng=default_rng(),] S, A, p)\n\nLike randsubseq, but the results are stored in S (which is resized as needed).\n\nExamples\n\njulia> S = Int64[];\n\njulia> randsubseq!(Xoshiro(123), S, 1:8, 0.3)\n2-element Vector{Int64}:\n 4\n 7\n\njulia> S\n2-element Vector{Int64}:\n 4\n 7\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randperm","page":"Random Numbers","title":"Random.randperm","text":"randperm([rng=default_rng(),] n::Integer)\n\nConstruct a random permutation of length n. The optional rng argument specifies a random number generator (see Random Numbers). The element type of the result is the same as the type of n.\n\nTo randomly permute an arbitrary vector, see shuffle or shuffle!.\n\ncompat: Julia 1.1\nIn Julia 1.1 randperm returns a vector v with eltype(v) == typeof(n) while in Julia 1.0 eltype(v) == Int.\n\nExamples\n\njulia> randperm(Xoshiro(123), 4)\n4-element Vector{Int64}:\n 1\n 4\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randperm!","page":"Random Numbers","title":"Random.randperm!","text":"randperm!([rng=default_rng(),] A::Array{<:Integer})\n\nConstruct in A a random permutation of length length(A). The optional rng argument specifies a random number generator (see Random Numbers). To randomly permute an arbitrary vector, see shuffle or shuffle!.\n\nExamples\n\njulia> randperm!(Xoshiro(123), Vector{Int}(undef, 4))\n4-element Vector{Int64}:\n 1\n 4\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randcycle","page":"Random Numbers","title":"Random.randcycle","text":"randcycle([rng=default_rng(),] n::Integer)\n\nConstruct a random cyclic permutation of length n. The optional rng argument specifies a random number generator, see Random Numbers. The element type of the result is the same as the type of n.\n\nHere, a \"cyclic permutation\" means that all of the elements lie within a single cycle. If n > 0, there are (n-1) possible cyclic permutations, which are sampled uniformly. If n == 0, randcycle returns an empty vector.\n\nrandcycle! is an in-place variant of this function.\n\ncompat: Julia 1.1\nIn Julia 1.1 and above, randcycle returns a vector v with eltype(v) == typeof(n) while in Julia 1.0 eltype(v) == Int.\n\nExamples\n\njulia> randcycle(Xoshiro(123), 6)\n6-element Vector{Int64}:\n 5\n 4\n 2\n 6\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.randcycle!","page":"Random Numbers","title":"Random.randcycle!","text":"randcycle!([rng=default_rng(),] A::Array{<:Integer})\n\nConstruct in A a random cyclic permutation of length n = length(A). The optional rng argument specifies a random number generator, see Random Numbers.\n\nHere, a \"cyclic permutation\" means that all of the elements lie within a single cycle. If A is nonempty (n > 0), there are (n-1) possible cyclic permutations, which are sampled uniformly. If A is empty, randcycle! leaves it unchanged.\n\nrandcycle is a variant of this function that allocates a new vector.\n\nExamples\n\njulia> randcycle!(Xoshiro(123), Vector{Int}(undef, 6))\n6-element Vector{Int64}:\n 5\n 4\n 2\n 6\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.shuffle","page":"Random Numbers","title":"Random.shuffle","text":"shuffle([rng=default_rng(),] v::AbstractArray)\n\nReturn a randomly permuted copy of v. The optional rng argument specifies a random number generator (see Random Numbers). To permute v in-place, see shuffle!. To obtain randomly permuted indices, see randperm.\n\nExamples\n\njulia> shuffle(Xoshiro(123), Vector(1:10))\n10-element Vector{Int64}:\n 5\n 4\n 2\n 3\n 6\n 10\n 8\n 1\n 9\n 7\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.shuffle!","page":"Random Numbers","title":"Random.shuffle!","text":"shuffle!([rng=default_rng(),] v::AbstractArray)\n\nIn-place version of shuffle: randomly permute v in-place, optionally supplying the random-number generator rng.\n\nExamples\n\njulia> shuffle!(Xoshiro(123), Vector(1:10))\n10-element Vector{Int64}:\n 5\n 4\n 2\n 3\n 6\n 10\n 8\n 1\n 9\n 7\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Generators-(creation-and-seeding)","page":"Random Numbers","title":"Generators (creation and seeding)","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.default_rng\nRandom.seed!\nRandom.AbstractRNG\nRandom.TaskLocalRNG\nRandom.Xoshiro\nRandom.MersenneTwister\nRandom.RandomDevice","category":"page"},{"location":"stdlib/Random/#Random.default_rng","page":"Random Numbers","title":"Random.default_rng","text":"Random.default_rng() -> rng\n\nReturn the default global random number generator (RNG), which is used by rand-related functions when no explicit RNG is provided.\n\nWhen the Random module is loaded, the default RNG is randomly seeded, via Random.seed!(): this means that each time a new julia session is started, the first call to rand() produces a different result, unless seed!(seed) is called first.\n\nIt is thread-safe: distinct threads can safely call rand-related functions on default_rng() concurrently, e.g. rand(default_rng()).\n\nnote: Note\nThe type of the default RNG is an implementation detail. Across different versions of Julia, you should not expect the default RNG to always have the same type, nor that it will produce the same stream of random numbers for a given seed.\n\ncompat: Julia 1.3\nThis function was introduced in Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.seed!","page":"Random Numbers","title":"Random.seed!","text":"seed!([rng=default_rng()], seed) -> rng\nseed!([rng=default_rng()]) -> rng\n\nReseed the random number generator: rng will give a reproducible sequence of numbers if and only if a seed is provided. Some RNGs don't accept a seed, like RandomDevice. After the call to seed!, rng is equivalent to a newly created object initialized with the same seed. The types of accepted seeds depend on the type of rng, but in general, integer seeds should work.\n\nIf rng is not specified, it defaults to seeding the state of the shared task-local generator.\n\nExamples\n\njulia> Random.seed!(1234);\n\njulia> x1 = rand(2)\n2-element Vector{Float64}:\n 0.32597672886359486\n 0.5490511363155669\n\njulia> Random.seed!(1234);\n\njulia> x2 = rand(2)\n2-element Vector{Float64}:\n 0.32597672886359486\n 0.5490511363155669\n\njulia> x1 == x2\ntrue\n\njulia> rng = Xoshiro(1234); rand(rng, 2) == x1\ntrue\n\njulia> Xoshiro(1) == Random.seed!(rng, 1)\ntrue\n\njulia> rand(Random.seed!(rng), Bool) # not reproducible\ntrue\n\njulia> rand(Random.seed!(rng), Bool) # not reproducible either\nfalse\n\njulia> rand(Xoshiro(), Bool) # not reproducible either\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Random/#Random.AbstractRNG","page":"Random Numbers","title":"Random.AbstractRNG","text":"AbstractRNG\n\nSupertype for random number generators such as MersenneTwister and RandomDevice.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.TaskLocalRNG","page":"Random Numbers","title":"Random.TaskLocalRNG","text":"TaskLocalRNG\n\nThe TaskLocalRNG has state that is local to its task, not its thread. It is seeded upon task creation, from the state of its parent task. Therefore, task creation is an event that changes the parent's RNG state.\n\nAs an upside, the TaskLocalRNG is pretty fast, and permits reproducible multithreaded simulations (barring race conditions), independent of scheduler decisions. As long as the number of threads is not used to make decisions on task creation, simulation results are also independent of the number of available threads / CPUs. The random stream should not depend on hardware specifics, up to endianness and possibly word size.\n\nUsing or seeding the RNG of any other task than the one returned by current_task() is undefined behavior: it will work most of the time, and may sometimes fail silently.\n\nWhen seeding TaskLocalRNG() with seed!, the passed seed, if any, may be any integer.\n\ncompat: Julia 1.11\nSeeding TaskLocalRNG() with a negative integer seed requires at least Julia 1.11.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.Xoshiro","page":"Random Numbers","title":"Random.Xoshiro","text":"Xoshiro(seed::Union{Integer, AbstractString})\nXoshiro()\n\nXoshiro256++ is a fast pseudorandom number generator described by David Blackman and Sebastiano Vigna in \"Scrambled Linear Pseudorandom Number Generators\", ACM Trans. Math. Softw., 2021. Reference implementation is available at https://prng.di.unimi.it\n\nApart from the high speed, Xoshiro has a small memory footprint, making it suitable for applications where many different random states need to be held for long time.\n\nJulia's Xoshiro implementation has a bulk-generation mode; this seeds new virtual PRNGs from the parent, and uses SIMD to generate in parallel (i.e. the bulk stream consists of multiple interleaved xoshiro instances). The virtual PRNGs are discarded once the bulk request has been serviced (and should cause no heap allocations).\n\nIf no seed is provided, a randomly generated one is created (using entropy from the system). See the seed! function for reseeding an already existing Xoshiro object.\n\ncompat: Julia 1.11\nPassing a negative integer seed requires at least Julia 1.11.\n\nExamples\n\njulia> using Random\n\njulia> rng = Xoshiro(1234);\n\njulia> x1 = rand(rng, 2)\n2-element Vector{Float64}:\n 0.32597672886359486\n 0.5490511363155669\n\njulia> rng = Xoshiro(1234);\n\njulia> x2 = rand(rng, 2)\n2-element Vector{Float64}:\n 0.32597672886359486\n 0.5490511363155669\n\njulia> x1 == x2\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.MersenneTwister","page":"Random Numbers","title":"Random.MersenneTwister","text":"MersenneTwister(seed)\nMersenneTwister()\n\nCreate a MersenneTwister RNG object. Different RNG objects can have their own seeds, which may be useful for generating different streams of random numbers. The seed may be an integer, a string, or a vector of UInt32 integers. If no seed is provided, a randomly generated one is created (using entropy from the system). See the seed! function for reseeding an already existing MersenneTwister object.\n\ncompat: Julia 1.11\nPassing a negative integer seed requires at least Julia 1.11.\n\nExamples\n\njulia> rng = MersenneTwister(123);\n\njulia> x1 = rand(rng, 2)\n2-element Vector{Float64}:\n 0.37453777969575874\n 0.8735343642013971\n\njulia> x2 = rand(MersenneTwister(123), 2)\n2-element Vector{Float64}:\n 0.37453777969575874\n 0.8735343642013971\n\njulia> x1 == x2\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.RandomDevice","page":"Random Numbers","title":"Random.RandomDevice","text":"RandomDevice()\n\nCreate a RandomDevice RNG object. Two such objects will always generate different streams of random numbers. The entropy is obtained from the operating system.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#rand-api-hook","page":"Random Numbers","title":"Hooking into the Random API","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"There are two mostly orthogonal ways to extend Random functionalities:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"generating random values of custom types\ncreating new generators","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The API for 1) is quite functional, but is relatively recent so it may still have to evolve in subsequent releases of the Random module. For example, it's typically sufficient to implement one rand method in order to have all other usual methods work automatically.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The API for 2) is still rudimentary, and may require more work than strictly necessary from the implementer, in order to support usual types of generated values.","category":"page"},{"location":"stdlib/Random/#Generating-random-values-of-custom-types","page":"Random Numbers","title":"Generating random values of custom types","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Generating random values for some distributions may involve various trade-offs. Pre-computed values, such as an alias table for discrete distributions, or “squeezing” functions for univariate distributions, can speed up sampling considerably. How much information should be pre-computed can depend on the number of values we plan to draw from a distribution. Also, some random number generators can have certain properties that various algorithms may want to exploit.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The Random module defines a customizable framework for obtaining random values that can address these issues. Each invocation of rand generates a sampler which can be customized with the above trade-offs in mind, by adding methods to Sampler, which in turn can dispatch on the random number generator, the object that characterizes the distribution, and a suggestion for the number of repetitions. Currently, for the latter, Val{1} (for a single sample) and Val{Inf} (for an arbitrary number) are used, with Random.Repetition an alias for both.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The object returned by Sampler is then used to generate the random values. When implementing the random generation interface for a value X that can be sampled from, the implementer should define the method","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"rand(rng, sampler)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"for the particular sampler returned by Sampler(rng, X, repetition).","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Samplers can be arbitrary values that implement rand(rng, sampler), but for most applications the following predefined samplers may be sufficient:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"SamplerType{T}() can be used for implementing samplers that draw from type T (e.g. rand(Int)). This is the default returned by Sampler for types.\nSamplerTrivial(self) is a simple wrapper for self, which can be accessed with []. This is the recommended sampler when no pre-computed information is needed (e.g. rand(1:3)), and is the default returned by Sampler for values.\nSamplerSimple(self, data) also contains the additional data field, which can be used to store arbitrary pre-computed values, which should be computed in a custom method of Sampler.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"We provide examples for each of these. We assume here that the choice of algorithm is independent of the RNG, so we use AbstractRNG in our signatures.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.Sampler\nRandom.SamplerType\nRandom.SamplerTrivial\nRandom.SamplerSimple","category":"page"},{"location":"stdlib/Random/#Random.Sampler","page":"Random Numbers","title":"Random.Sampler","text":"Sampler(rng, x, repetition = Val(Inf))\n\nReturn a sampler object that can be used to generate random values from rng for x.\n\nWhen sp = Sampler(rng, x, repetition), rand(rng, sp) will be used to draw random values, and should be defined accordingly.\n\nrepetition can be Val(1) or Val(Inf), and should be used as a suggestion for deciding the amount of precomputation, if applicable.\n\nRandom.SamplerType and Random.SamplerTrivial are default fallbacks for types and values, respectively. Random.SamplerSimple can be used to store pre-computed values without defining extra types for only this purpose.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.SamplerType","page":"Random Numbers","title":"Random.SamplerType","text":"SamplerType{T}()\n\nA sampler for types, containing no other information. The default fallback for Sampler when called with types.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.SamplerTrivial","page":"Random Numbers","title":"Random.SamplerTrivial","text":"SamplerTrivial(x)\n\nCreate a sampler that just wraps the given value x. This is the default fall-back for values. The eltype of this sampler is equal to eltype(x).\n\nThe recommended use case is sampling from values without precomputed data.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/#Random.SamplerSimple","page":"Random Numbers","title":"Random.SamplerSimple","text":"SamplerSimple(x, data)\n\nCreate a sampler that wraps the given value x and the data. The eltype of this sampler is equal to eltype(x).\n\nThe recommended use case is sampling from values with precomputed data.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Decoupling pre-computation from actually generating the values is part of the API, and is also available to the user. As an example, assume that rand(rng, 1:20) has to be called repeatedly in a loop: the way to take advantage of this decoupling is as follows:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"rng = Xoshiro()\nsp = Random.Sampler(rng, 1:20) # or Random.Sampler(Xoshiro, 1:20)\nfor x in X\n n = rand(rng, sp) # similar to n = rand(rng, 1:20)\n # use n\nend","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"This is the mechanism that is also used in the standard library, e.g. by the default implementation of random array generation (like in rand(1:20, 10)).","category":"page"},{"location":"stdlib/Random/#Generating-values-from-a-type","page":"Random Numbers","title":"Generating values from a type","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Given a type T, it's currently assumed that if rand(T) is defined, an object of type T will be produced. SamplerType is the default sampler for types. In order to define random generation of values of type T, the rand(rng::AbstractRNG, ::Random.SamplerType{T}) method should be defined, and should return values what rand(rng, T) is expected to return.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Let's take the following example: we implement a Die type, with a variable number n of sides, numbered from 1 to n. We want rand(Die) to produce a Die with a random number of up to 20 sides (and at least 4):","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"struct Die\n nsides::Int # number of sides\nend\n\nRandom.rand(rng::AbstractRNG, ::Random.SamplerType{Die}) = Die(rand(rng, 4:20))\n\n# output\n","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Scalar and array methods for Die now work as expected:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"julia> rand(Die)\nDie(5)\n\njulia> rand(Xoshiro(0), Die)\nDie(10)\n\njulia> rand(Die, 3)\n3-element Vector{Die}:\n Die(9)\n Die(15)\n Die(14)\n\njulia> a = Vector{Die}(undef, 3); rand!(a)\n3-element Vector{Die}:\n Die(19)\n Die(7)\n Die(17)","category":"page"},{"location":"stdlib/Random/#A-simple-sampler-without-pre-computed-data","page":"Random Numbers","title":"A simple sampler without pre-computed data","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Here we define a sampler for a collection. If no pre-computed data is required, it can be implemented with a SamplerTrivial sampler, which is in fact the default fallback for values.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"In order to define random generation out of objects of type S, the following method should be defined: rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S}). Here, sp simply wraps an object of type S, which can be accessed via sp[]. Continuing the Die example, we want now to define rand(d::Die) to produce an Int corresponding to one of d's sides:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"julia> Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides);\n\njulia> rand(Die(4))\n1\n\njulia> rand(Die(4), 3)\n3-element Vector{Any}:\n 2\n 3\n 3","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Given a collection type S, it's currently assumed that if rand(::S) is defined, an object of type eltype(S) will be produced. In the last example, a Vector{Any} is produced; the reason is that eltype(Die) == Any. The remedy is to define Base.eltype(::Type{Die}) = Int.","category":"page"},{"location":"stdlib/Random/#Generating-values-for-an-AbstractFloat-type","page":"Random Numbers","title":"Generating values for an AbstractFloat type","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"AbstractFloat types are special-cased, because by default random values are not produced in the whole type domain, but rather in [0,1). The following method should be implemented for T <: AbstractFloat: Random.rand(::AbstractRNG, ::Random.SamplerTrivial{Random.CloseOpen01{T}})","category":"page"},{"location":"stdlib/Random/#An-optimized-sampler-with-pre-computed-data","page":"Random Numbers","title":"An optimized sampler with pre-computed data","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Consider a discrete distribution, where numbers 1:n are drawn with given probabilities that sum to one. When many values are needed from this distribution, the fastest method is using an alias table. We don't provide the algorithm for building such a table here, but suppose it is available in make_alias_table(probabilities) instead, and draw_number(rng, alias_table) can be used to draw a random number from it.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Suppose that the distribution is described by","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"struct DiscreteDistribution{V <: AbstractVector}\n probabilities::V\nend","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"and that we always want to build an alias table, regardless of the number of values needed (we learn how to customize this below). The methods","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Random.eltype(::Type{<:DiscreteDistribution}) = Int\n\nfunction Random.Sampler(::Type{<:AbstractRNG}, distribution::DiscreteDistribution, ::Repetition)\n SamplerSimple(distribution, make_alias_table(distribution.probabilities))\nend","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"should be defined to return a sampler with pre-computed data, then","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"function rand(rng::AbstractRNG, sp::SamplerSimple{<:DiscreteDistribution})\n draw_number(rng, sp.data)\nend","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"will be used to draw the values.","category":"page"},{"location":"stdlib/Random/#Custom-sampler-types","page":"Random Numbers","title":"Custom sampler types","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The SamplerSimple type is sufficient for most use cases with precomputed data. However, in order to demonstrate how to use custom sampler types, here we implement something similar to SamplerSimple.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Going back to our Die example: rand(::Die) uses random generation from a range, so there is an opportunity for this optimization. We call our custom sampler SamplerDie.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"import Random: Sampler, rand\n\nstruct SamplerDie <: Sampler{Int} # generates values of type Int\n die::Die\n sp::Sampler{Int} # this is an abstract type, so this could be improved\nend\n\nSampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) =\n SamplerDie(die, Sampler(RNG, 1:die.nsides, r))\n# the `r` parameter will be explained later on\n\nrand(rng::AbstractRNG, sp::SamplerDie) = rand(rng, sp.sp)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"It's now possible to get a sampler with sp = Sampler(rng, die), and use sp instead of die in any rand call involving rng. In the simplistic example above, die doesn't need to be stored in SamplerDie but this is often the case in practice.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Of course, this pattern is so frequent that the helper type used above, namely Random.SamplerSimple, is available, saving us the definition of SamplerDie: we could have implemented our decoupling with:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Sampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) =\n SamplerSimple(die, Sampler(RNG, 1:die.nsides, r))\n\nrand(rng::AbstractRNG, sp::SamplerSimple{Die}) = rand(rng, sp.data)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Here, sp.data refers to the second parameter in the call to the SamplerSimple constructor (in this case equal to Sampler(rng, 1:die.nsides, r)), while the Die object can be accessed via sp[].","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Like SamplerDie, any custom sampler must be a subtype of Sampler{T} where T is the type of the generated values. Note that SamplerSimple(x, data) isa Sampler{eltype(x)}, so this constrains what the first argument to SamplerSimple can be (it's recommended to use SamplerSimple like in the Die example, where x is simply forwarded while defining a Sampler method). Similarly, SamplerTrivial(x) isa Sampler{eltype(x)}.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Another helper type is currently available for other cases, Random.SamplerTag, but is considered as internal API, and can break at any time without proper deprecations.","category":"page"},{"location":"stdlib/Random/#Using-distinct-algorithms-for-scalar-or-array-generation","page":"Random Numbers","title":"Using distinct algorithms for scalar or array generation","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"In some cases, whether one wants to generate only a handful of values or a large number of values will have an impact on the choice of algorithm. This is handled with the third parameter of the Sampler constructor. Let's assume we defined two helper types for Die, say SamplerDie1 which should be used to generate only few random values, and SamplerDieMany for many values. We can use those types as follows:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{1}) = SamplerDie1(...)\nSampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{Inf}) = SamplerDieMany(...)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Of course, rand must also be defined on those types (i.e. rand(::AbstractRNG, ::SamplerDie1) and rand(::AbstractRNG, ::SamplerDieMany)). Note that, as usual, SamplerTrivial and SamplerSimple can be used if custom types are not necessary.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Note: Sampler(rng, x) is simply a shorthand for Sampler(rng, x, Val(Inf)), and Random.Repetition is an alias for Union{Val{1}, Val{Inf}}.","category":"page"},{"location":"stdlib/Random/#Creating-new-generators","page":"Random Numbers","title":"Creating new generators","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The API is not clearly defined yet, but as a rule of thumb:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"any rand method producing \"basic\" types (isbitstype integer and floating types in Base) should be defined for this specific RNG, if they are needed;\nother documented rand methods accepting an AbstractRNG should work out of the box, (provided the methods from 1) what are relied on are implemented), but can of course be specialized for this RNG if there is room for optimization;\ncopy for pseudo-RNGs should return an independent copy that generates the exact same random sequence as the original from that point when called in the same way. When this is not feasible (e.g. hardware-based RNGs), copy must not be implemented.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Concerning 1), a rand method may happen to work automatically, but it's not officially supported and may break without warnings in a subsequent release.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"To define a new rand method for an hypothetical MyRNG generator, and a value specification s (e.g. s == Int, or s == 1:10) of type S==typeof(s) or S==Type{s} if s is a type, the same two methods as we saw before must be defined:","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Sampler(::Type{MyRNG}, ::S, ::Repetition), which returns an object of type say SamplerS\nrand(rng::MyRNG, sp::SamplerS)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"It can happen that Sampler(rng::AbstractRNG, ::S, ::Repetition) is already defined in the Random module. It would then be possible to skip step 1) in practice (if one wants to specialize generation for this particular RNG type), but the corresponding SamplerS type is considered as internal detail, and may be changed without warning.","category":"page"},{"location":"stdlib/Random/#Specializing-array-generation","page":"Random Numbers","title":"Specializing array generation","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"In some cases, for a given RNG type, generating an array of random values can be more efficient with a specialized method than by merely using the decoupling technique explained before. This is for example the case for MersenneTwister, which natively writes random values in an array.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"To implement this specialization for MyRNG and for a specification s, producing elements of type S, the following method can be defined: rand!(rng::MyRNG, a::AbstractArray{S}, ::SamplerS), where SamplerS is the type of the sampler returned by Sampler(MyRNG, s, Val(Inf)). Instead of AbstractArray, it's possible to implement the functionality only for a subtype, e.g. Array{S}. The non-mutating array method of rand will automatically call this specialization internally.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/Random/#Reproducibility","page":"Random Numbers","title":"Reproducibility","text":"","category":"section"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"By using an RNG parameter initialized with a given seed, you can reproduce the same pseudorandom number sequence when running your program multiple times. However, a minor release of Julia (e.g. 1.3 to 1.4) may change the sequence of pseudorandom numbers generated from a specific seed, in particular if MersenneTwister is used. (Even if the sequence produced by a low-level function like rand does not change, the output of higher-level functions like randsubseq may change due to algorithm updates.) Rationale: guaranteeing that pseudorandom streams never change prohibits many algorithmic improvements.","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"If you need to guarantee exact reproducibility of random data, it is advisable to simply save the data (e.g. as a supplementary attachment in a scientific publication). (You can also, of course, specify a particular Julia version and package manifest, especially if you require bit reproducibility.)","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"Software tests that rely on specific \"random\" data should also generally either save the data, embed it into the test code, or use third-party packages like StableRNGs.jl. On the other hand, tests that should pass for most random data (e.g. testing A \\ (A*x) ≈ x for a random matrix A = randn(n,n)) can use an RNG with a fixed seed to ensure that simply running the test many times does not encounter a failure due to very improbable data (e.g. an extremely ill-conditioned matrix).","category":"page"},{"location":"stdlib/Random/","page":"Random Numbers","title":"Random Numbers","text":"The statistical distribution from which random samples are drawn is guaranteed to be the same across any minor Julia releases.","category":"page"},{"location":"base/reflection/#Reflection-and-introspection","page":"Reflection and introspection","title":"Reflection and introspection","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Julia provides a variety of runtime reflection capabilities.","category":"page"},{"location":"base/reflection/#Module-bindings","page":"Reflection and introspection","title":"Module bindings","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The public names for a Module are available using names(m::Module), which will return an array of Symbol elements representing the public bindings. names(m::Module, all = true) returns symbols for all bindings in m, regardless of public status.","category":"page"},{"location":"base/reflection/#DataType-fields","page":"Reflection and introspection","title":"DataType fields","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The names of DataType fields may be interrogated using fieldnames. For example, given the following type, fieldnames(Point) returns a tuple of Symbols representing the field names:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> struct Point\n x::Int\n y\n end\n\njulia> fieldnames(Point)\n(:x, :y)","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The type of each field in a Point object is stored in the types field of the Point variable itself:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> Point.types\nsvec(Int64, Any)","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"While x is annotated as an Int, y was unannotated in the type definition, therefore y defaults to the Any type.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Types are themselves represented as a structure called DataType:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> typeof(Point)\nDataType","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Note that fieldnames(DataType) gives the names for each field of DataType itself, and one of these fields is the types field observed in the example above.","category":"page"},{"location":"base/reflection/#Subtypes","page":"Reflection and introspection","title":"Subtypes","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The direct subtypes of any DataType may be listed using subtypes. For example, the abstract DataType AbstractFloat has four (concrete) subtypes:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> InteractiveUtils.subtypes(AbstractFloat)\n5-element Vector{Any}:\n BigFloat\n Core.BFloat16\n Float16\n Float32\n Float64","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Any abstract subtype will also be included in this list, but further subtypes thereof will not; recursive application of subtypes may be used to inspect the full type tree.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Note that subtypes is located inside InteractiveUtils but is automatically exported when using the REPL.","category":"page"},{"location":"base/reflection/#DataType-layout","page":"Reflection and introspection","title":"DataType layout","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The internal representation of a DataType is critically important when interfacing with C code and several functions are available to inspect these details. isbitstype(T::DataType) returns true if T is stored with C-compatible alignment. fieldoffset(T::DataType, i::Integer) returns the (byte) offset for field i relative to the start of the type.","category":"page"},{"location":"base/reflection/#Function-methods","page":"Reflection and introspection","title":"Function methods","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The methods of any generic function may be listed using methods. The method dispatch table may be searched for methods accepting a given type using methodswith.","category":"page"},{"location":"base/reflection/#Expansion-and-lowering","page":"Reflection and introspection","title":"Expansion and lowering","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"As discussed in the Metaprogramming section, the macroexpand function gives the unquoted and interpolated expression (Expr) form for a given macro. To use macroexpand, quote the expression block itself (otherwise, the macro will be evaluated and the result will be passed instead!). For example:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> InteractiveUtils.macroexpand(@__MODULE__, :(@edit println(\"\")) )\n:(InteractiveUtils.edit(println, (Base.typesof)(\"\")))","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The functions Base.Meta.show_sexpr and dump are used to display S-expr style views and depth-nested detail views for any expression.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Finally, the Meta.lower function gives the lowered form of any expression and is of particular interest for understanding how language constructs map to primitive operations such as assignments, branches, and calls:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] ))\n:($(Expr(:thunk, CodeInfo(\n1 ─ %1 = 1 + 2\n│ %2 = sin(0.5)\n│ %3 = Base.vect(%1, %2)\n└── return %3\n))))","category":"page"},{"location":"base/reflection/#Intermediate-and-compiled-representations","page":"Reflection and introspection","title":"Intermediate and compiled representations","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Inspecting the lowered form for functions requires selection of the specific method to display, because generic functions may have many methods with different type signatures. For this purpose, method-specific code-lowering is available using code_lowered, and the type-inferred form is available using code_typed. code_warntype adds highlighting to the output of code_typed.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Closer to the machine, the LLVM intermediate representation of a function may be printed using by code_llvm, and finally the compiled machine code is available using code_native (this will trigger JIT compilation/code generation for any function which has not previously been called).","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"For convenience, there are macro versions of the above functions which take standard function calls and expand argument types automatically:","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> @code_llvm +(1,1)\n; @ int.jl:87 within `+`\n; Function Attrs: sspstrong uwtable\ndefine i64 @\"julia_+_476\"(i64 signext %0, i64 signext %1) #0 {\ntop:\n %2 = add i64 %1, %0\n ret i64 %2\n}","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"For more information see @code_lowered, @code_typed, @code_warntype, @code_llvm, and @code_native.","category":"page"},{"location":"base/reflection/#Printing-of-debug-information","page":"Reflection and introspection","title":"Printing of debug information","text":"","category":"section"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"The aforementioned functions and macros take the keyword argument debuginfo that controls the level debug information printed.","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"julia> InteractiveUtils.@code_typed debuginfo=:source +(1,1)\nCodeInfo(\n @ int.jl:87 within `+`\n1 ─ %1 = Base.add_int(x, y)::Int64\n└── return %1\n) => Int64","category":"page"},{"location":"base/reflection/","page":"Reflection and introspection","title":"Reflection and introspection","text":"Possible values for debuginfo are: :none, :source, and :default. Per default debug information is not printed, but that can be changed by setting Base.IRShow.default_debuginfo[] = :source.","category":"page"},{"location":"stdlib/LibCURL/#LibCURL","page":"LibCURL","title":"LibCURL","text":"","category":"section"},{"location":"stdlib/LibCURL/","page":"LibCURL","title":"LibCURL","text":"This is a simple Julia wrapper around http://curl.haxx.se/libcurl/ generated using Clang.jl. Please see the libcurl API documentation for help on how to use this package.","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings","page":"StyledStrings","title":"StyledStrings","text":"","category":"section"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-styling","page":"StyledStrings","title":"Styling","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"When working with strings, formatting and styling often appear as a secondary concern.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"note: Note\nFor instance, when printing to a terminal you might want to sprinkle ANSI escape sequences in the output, when outputting HTML styling constructs (, etc.) serve a similar purpose, and so on. It is possible to simply insert the raw styling constructs into the string next to the content itself, but it quickly becomes apparent that this is not well suited for anything but the most basic use-cases. Not all terminals support the same ANSI codes, the styling constructs need to be painstakingly removed when calculating the width of already-styled content, and that's before you even get into handling multiple output formats.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Instead of leaving this headache to be widely experienced downstream, it is tackled head-on by the introduction of a special string type (AnnotatedString). This string type wraps any other string type and allows for formating information to be applied to regions (e.g. characters 1 through to 7 are bold and red).","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Regions of a string are styled by applying Faces to them —a structure that holds styling information— (think \"typeface\"). As a convenience, it is possible to name a face in the global faces dictionary instead of giving the Face directly.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Along with these capabilities, we also provide a convenient way for constructing AnnotatedStrings, detailed in Styled String Literals.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"julia> styled\"{yellow:hello} {blue:there}\"\n\"hello there\" # prints with colour in the REPL","category":"page"},{"location":"stdlib/StyledStrings/#Styling-via-[AnnotatedString](@ref-Base.AnnotatedString)s","page":"StyledStrings","title":"Styling via AnnotatedStrings","text":"","category":"section"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-faces","page":"StyledStrings","title":"Faces","text":"","category":"section"},{"location":"stdlib/StyledStrings/#The-Face-type","page":"StyledStrings","title":"The Face type","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"A Face specifies details of a typeface that text can be set in. It covers a set of basic attributes that generalise well across different formats, namely:","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"height\nweight\nslant\nforeground\nbackground\nunderline\nstrikethrough\ninverse\ninherit","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For details on the particular forms these attributes take, see the Face docstring, but of particular interest is inherit as it allows you to inherit attributes from other Faces.","category":"page"},{"location":"stdlib/StyledStrings/#The-global-faces-dictionary","page":"StyledStrings","title":"The global faces dictionary","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"To make referring to particular styles more convenient, there is a global Dict{Symbol, Face} that allows for Faces to be referred to simply by name. Packages can add faces to this dictionary via the addface! function, and the loaded faces can be easily customised.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"warning: Warning\nAny package registering new faces should ensure that they are prefixed by the package name, i.e. follow the format mypackage_myface. This is important for predictability, and to prevent name clashes.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"There is one set of exemptions to the package-prefix rule, the set of basic faces that are part of the default value of the faces dictionary.","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-basic-faces","page":"StyledStrings","title":"Basic faces","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Basic faces are intended represent a general idea, that is widely applicable.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For setting some text with a certain attribute, we have the bold, light, italic, underline, strikethrough, and inverse faces.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"There are also named faces for the 16 terminal colours: black, red, green, yellow, blue, magenta, cyan, white, bright_black/grey/gray, bright_red, bright_green, bright_blue, bright_magenta, bright_cyan, and bright_white.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For shadowed text (i.e. dim but there) there is the shadow face. To indicate a selected region, there is the region face. Similarly for emphasis and highlighting the emphasis and highlight faces are defined. There is also code for code-like text.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For visually indicating the severity of messages the error, warning, success, info, note, and tip faces are defined.","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-face-toml","page":"StyledStrings","title":"Customisation of faces (Faces.toml)","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"It is good for the name faces in the global face dictionary to be customizable. Theming and aesthetics are nice, and it is important for accessibility reasons too. A TOML file can be parsed into a list of Face specifications that are merged with the pre-existing entry in the face dictionary.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"A Face is represented in TOML like so:","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"[facename]\nattribute = \"value\"\n...\n\n[package.facename]\nattribute = \"value\"","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For example, if the shadow face is too hard to read it can be made brighter like so:","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"[shadow]\nforeground = \"white\"","category":"page"},{"location":"stdlib/StyledStrings/#Applying-faces-to-a-AnnotatedString","page":"StyledStrings","title":"Applying faces to a AnnotatedString","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"By convention, the :face attributes of a AnnotatedString hold information on the Faces that currently apply. This can be given in multiple forms, as a single Symbol naming a Faces in the global face dictionary, a Face itself, or a vector of either.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"The show(::IO, ::MIME\"text/plain\", ::AnnotatedString) and show(::IO, ::MIME\"text/html\", ::AnnotatedString) methods both look at the :face attributes and merge them all together when determining the overall styling.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"We can supply :face attributes to a AnnotatedString during construction, add them to the properties list afterwards, or use the convenient Styled String literals.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"julia> str1 = Base.AnnotatedString(\"blue text\", [(1:9, :face => :blue)])\n\"blue text\"\n\njulia> str2 = styled\"{blue:blue text}\"\n\"blue text\"\n\njulia> str1 == str2\ntrue\n\njulia> sprint(print, str1, context = :color => true)\n\"\\e[34mblue text\\e[39m\"\n\njulia> sprint(show, MIME(\"text/html\"), str1, context = :color => true)\n\"
    blue text
    \"","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstring-literals","page":"StyledStrings","title":"Styled String Literals","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"To ease construction of AnnotatedStrings with Faces applied, the styled\"...\" styled string literal allows for the content and attributes to be easily expressed together via a custom grammar.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Within a styled\"...\" literal, curly parenthesis are considered special characters and must be escaped in normal usage (\\{, \\}). This allows them to be used to express annotations with (nestable) {annotations...:text} constructs.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"The annotations... component is a comma-separated list of three types of annotations.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Face names\nInline Face expressions (key=val,...)\nkey=value pairs","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"Interpolation is possible everywhere except for inline face keys.","category":"page"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"For more information on the grammar, see the extended help of the styled\"...\" docstring.","category":"page"},{"location":"stdlib/StyledStrings/#stdlib-styledstrings-api","page":"StyledStrings","title":"API reference","text":"","category":"section"},{"location":"stdlib/StyledStrings/","page":"StyledStrings","title":"StyledStrings","text":"StyledStrings.@styled_str\nStyledStrings.Face\nStyledStrings.addface!\nStyledStrings.SimpleColor\nBase.parse(::Type{StyledStrings.SimpleColor}, ::String)\nBase.tryparse(::Type{StyledStrings.SimpleColor}, ::String)\nBase.merge(::StyledStrings.Face, ::StyledStrings.Face)","category":"page"},{"location":"stdlib/StyledStrings/#StyledStrings.@styled_str","page":"StyledStrings","title":"StyledStrings.@styled_str","text":"@styled_str -> AnnotatedString\n\nConstruct a styled string. Within the string, {:} structures apply the formatting to , according to the list of comma-separated specifications . Each spec can either take the form of a face name, an inline face specification, or a key=value pair. The value must be wrapped by {...} should it contain any of the characters ,=:{}.\n\nString interpolation with $ functions in the same way as regular strings, except quotes need to be escaped. Faces, keys, and values can also be interpolated with $.\n\nExample\n\nstyled\"The {bold:{italic:quick} {(foreground=#cd853f):brown} fox} jumped over the {link={https://en.wikipedia.org/wiki/Laziness}:lazy} dog\"\n\nExtended help\n\nThis macro can be described by the following EBNF grammar:\n\nstyledstring = { styled | interpolated | escaped | plain } ;\n\nspecialchar = '{' | '}' | '$' | '\\\"' ;\nanychar = [\\u0-\\u1fffff] ;\nalmostplain = { anychar - specialchar } ;\nplain = { anychar - specialchar } ;\nescaped = '\\\\', specialchar ;\n\ninterpolated = '$', ? expr ? | '$(', ? expr ?, ')' ;\n\nstyled = '{', ws, annotations, ':', content, '}' ;\ncontent = { interpolated | plain | escaped | styled } ;\nannotations = annotation | annotations, ws, ',', ws, annotation ;\nannotation = face | inlineface | keyvalue ;\nws = { ' ' | '\\t' | '\\n' } ; (* whitespace *)\n\nface = facename | interpolated ;\nfacename = [A-Za-z0-9_]+ ;\n\ninlineface = '(', ws, [ faceprop ], { ws, ',', faceprop }, ws, ')' ;\nfaceprop = [a-z]+, ws, '=', ws, ( [^,)]+ | interpolated) ;\n\nkeyvalue = key, ws, '=', ws, value ;\nkey = ( [^${}=,:], [^=,:]* ) | interpolated ;\nvalue = simplevalue | curlybraced | interpolated ;\ncurlybraced = '{' { escaped | plain } '}' ;\nsimplevalue = [^${},:], [^,:]* ;\n\nThe above grammar for inlineface is simplified, as the actual implementation is a bit more sophisticated. The full behaviour is given below.\n\nfaceprop = ( 'face', ws, '=', ws, ( ? string ? | interpolated ) ) |\n ( 'height', ws, '=', ws, ( ? number ? | interpolated ) ) |\n ( 'weight', ws, '=', ws, ( symbol | interpolated ) ) |\n ( 'slant', ws, '=', ws, ( symbol | interpolated ) ) |\n ( ( 'foreground' | 'fg' | 'background' | 'bg' ),\n ws, '=', ws, ( simplecolor | interpolated ) ) |\n ( 'underline', ws, '=', ws, ( underline | interpolated ) ) |\n ( 'strikethrough', ws, '=', ws, ( bool | interpolated ) ) |\n ( 'inverse', ws, '=', ws, ( bool | interpolated ) ) |\n ( 'inherit', ws, '=', ws, ( inherit | interpolated ) ) ;\n\nnothing = 'nothing' ;\nbool = 'true' | 'false' ;\nsymbol = [^ ,)]+ ;\nhexcolor = ('#' | '0x'), [0-9a-f]{6} ;\nsimplecolor = hexcolor | symbol | nothing ;\n\nunderline = nothing | bool | simplecolor | underlinestyled;\nunderlinestyled = '(', whitespace, ('' | nothing | simplecolor), whitespace,\n ',', whitespace, symbol, whitespace ')' ;\n\ninherit = ( '[', inheritval, { ',', inheritval }, ']' ) | inheritval;\ninheritval = whitespace, ':'?, symbol ;\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/StyledStrings/#StyledStrings.Face","page":"StyledStrings","title":"StyledStrings.Face","text":"A Face is a collection of graphical attributes for displaying text. Faces control how text is displayed in the terminal, and possibly other places too.\n\nMost of the time, a Face will be stored in the global faces dicts as a unique association with a face name Symbol, and will be most often referred to by this name instead of the Face object itself.\n\nAttributes\n\nAll attributes can be set via the keyword constructor, and default to nothing.\n\nheight (an Int or Float64): The height in either deci-pt (when an Int), or as a factor of the base size (when a Float64).\nweight (a Symbol): One of the symbols (from faintest to densest) :thin, :extralight, :light, :semilight, :normal, :medium, :semibold, :bold, :extrabold, or :black. In terminals any weight greater than :normal is displayed as bold, and in terminals that support variable-brightness text, any weight less than :normal is displayed as faint.\nslant (a Symbol): One of the symbols :italic, :oblique, or :normal.\nforeground (a SimpleColor): The text foreground color.\nbackground (a SimpleColor): The text background color.\nunderline, the text underline, which takes one of the following forms:\na Bool: Whether the text should be underlined or not.\n\na SimpleColor: The text should be underlined with this color.\n\na Tuple{Nothing, Symbol}: The text should be underlined using the style set by the Symbol, one of :straight, :double, :curly, :dotted, or :dashed.\n\na Tuple{SimpleColor, Symbol}: The text should be underlined in the specified SimpleColor, and using the style specified by the Symbol, as before.\nstrikethrough (a Bool): Whether the text should be struck through.\ninverse (a Bool): Whether the foreground and background colors should be inverted.\ninherit (a Vector{Symbol}): Names of faces to inherit from, with earlier faces taking priority. All faces inherit from the :default face.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/StyledStrings/#StyledStrings.addface!","page":"StyledStrings","title":"StyledStrings.addface!","text":"addface!(name::Symbol => default::Face)\n\nCreate a new face by the name name. So long as no face already exists by this name, default is added to both FACES.default and (a copy of) to FACES.current, with the current value returned.\n\nShould the face name already exist, nothing is returned.\n\nExamples\n\njulia> addface!(:mypkg_myface => Face(slant=:italic, underline=true))\nFace (sample)\n slant: italic\n underline: true\n\n\n\n\n\n","category":"function"},{"location":"stdlib/StyledStrings/#StyledStrings.SimpleColor","page":"StyledStrings","title":"StyledStrings.SimpleColor","text":"struct SimpleColor\n\nA basic representation of a color, intended for string styling purposes. It can either contain a named color (like :red), or an RGBTuple which is a NamedTuple specifying an r, g, b color with a bit-depth of 8.\n\nConstructors\n\nSimpleColor(name::Symbol) # e.g. :red\nSimpleColor(rgb::RGBTuple) # e.g. (r=1, b=2, g=3)\nSimpleColor(r::Integer, b::Integer, b::Integer)\nSimpleColor(rgb::UInt32) # e.g. 0x123456\n\nAlso see tryparse(SimpleColor, rgb::String).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/StyledStrings/#Base.parse-Tuple{Type{StyledStrings.SimpleColor}, String}","page":"StyledStrings","title":"Base.parse","text":"parse(::Type{SimpleColor}, rgb::String)\n\nAn analogue of tryparse(SimpleColor, rgb::String) (which see), that raises an error instead of returning nothing.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/StyledStrings/#Base.tryparse-Tuple{Type{StyledStrings.SimpleColor}, String}","page":"StyledStrings","title":"Base.tryparse","text":"tryparse(::Type{SimpleColor}, rgb::String)\n\nAttempt to parse rgb as a SimpleColor. If rgb starts with # and has a length of 7, it is converted into a RGBTuple-backed SimpleColor. If rgb starts with a-z, rgb is interpreted as a color name and converted to a Symbol-backed SimpleColor.\n\nOtherwise, nothing is returned.\n\nExamples\n\njulia> tryparse(SimpleColor, \"blue\")\nSimpleColor(blue)\n\njulia> tryparse(SimpleColor, \"#9558b2\")\nSimpleColor(#9558b2)\n\njulia> tryparse(SimpleColor, \"#nocolor\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/StyledStrings/#Base.merge-Tuple{StyledStrings.Face, StyledStrings.Face}","page":"StyledStrings","title":"Base.merge","text":"merge(initial::Face, others::Face...)\n\nMerge the properties of the initial face and others, with later faces taking priority.\n\n\n\n\n\n","category":"method"},{"location":"manual/variables/#man-variables","page":"Variables","title":"Variables","text":"","category":"section"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"A variable, in Julia, is a name associated (or bound) to a value. It's useful when you want to store a value (that you obtained after some math, for example) for later use. For example:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"# Assign the value 10 to the variable x\njulia> x = 10\n10\n\n# Doing math with x's value\njulia> x + 1\n11\n\n# Reassign x's value\njulia> x = 1 + 1\n2\n\n# You can assign values of other types, like strings of text\njulia> x = \"Hello World!\"\n\"Hello World!\"","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Julia provides an extremely flexible system for naming variables. Variable names are case-sensitive, and have no semantic meaning (that is, the language will not treat variables differently based on their names).","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> x = 1.0\n1.0\n\njulia> y = -3\n-3\n\njulia> Z = \"My string\"\n\"My string\"\n\njulia> customary_phrase = \"Hello world!\"\n\"Hello world!\"\n\njulia> UniversalDeclarationOfHumanRightsStart = \"人人生而自由,在尊严和权利上一律平等。\"\n\"人人生而自由,在尊严和权利上一律平等。\"","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Unicode names (in UTF-8 encoding) are allowed:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> δ = 0.00001\n1.0e-5\n\njulia> 안녕하세요 = \"Hello\"\n\"Hello\"","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"In the Julia REPL and several other Julia editing environments, you can type many Unicode math symbols by typing the backslashed LaTeX symbol name followed by tab. For example, the variable name δ can be entered by typing \\delta-tab, or even α̂⁽²⁾ by \\alpha-tab-\\hat- tab-\\^(2)-tab. (If you find a symbol somewhere, e.g. in someone else's code, that you don't know how to type, the REPL help will tell you: just type ? and then paste the symbol.)","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Julia will even let you shadow existing exported constants and functions with local ones (although this is not recommended to avoid potential confusions):","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> pi = 3\n3\n\njulia> pi\n3\n\njulia> sqrt = 4\n4\n\njulia> length() = 5\nlength (generic function with 1 method)\n\njulia> Base.length\nlength (generic function with 79 methods)","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"However, if you try to redefine a built-in constant or function already in use, Julia will give you an error:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> pi\nπ = 3.1415926535897...\n\njulia> pi = 3\nERROR: cannot assign a value to imported variable Base.pi from module Main\n\njulia> sqrt(100)\n10.0\n\njulia> sqrt = 4\nERROR: cannot assign a value to imported variable Base.sqrt from module Main","category":"page"},{"location":"manual/variables/#man-allowed-variable-names","page":"Variables","title":"Allowed Variable Names","text":"","category":"section"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Variable names must begin with a letter (A-Z or a-z), underscore, or a subset of Unicode code points greater than 00A0; in particular, Unicode character categories Lu/Ll/Lt/Lm/Lo/Nl (letters), Sc/So (currency and other symbols), and a few other letter-like characters (e.g. a subset of the Sm math symbols) are allowed. Subsequent characters may also include ! and digits (0-9 and other characters in categories Nd/No), as well as other Unicode code points: diacritics and other modifying marks (categories Mn/Mc/Me/Sk), some punctuation connectors (category Pc), primes, and a few other characters.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Operators like + are also valid identifiers, but are parsed specially. In some contexts, operators can be used just like variables; for example (+) refers to the addition function, and (+) = f will reassign it. Most of the Unicode infix operators (in category Sm), such as ⊕, are parsed as infix operators and are available for user-defined methods (e.g. you can use const ⊗ = kron to define ⊗ as an infix Kronecker product). Operators can also be suffixed with modifying marks, primes, and sub/superscripts, e.g. +̂ₐ″ is parsed as an infix operator with the same precedence as +. A space is required between an operator that ends with a subscript/superscript letter and a subsequent variable name. For example, if +ᵃ is an operator, then +ᵃx must be written as +ᵃ x to distinguish it from + ᵃx where ᵃx is the variable name.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"A particular class of variable names is one that contains only underscores. These identifiers are write-only. I.e. they can only be assigned values, which are immediately discarded, and their values cannot be used in any way.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> x, ___ = size([2 2; 1 1])\n(2, 2)\n\njulia> y = ___\nERROR: syntax: all-underscore identifiers are write-only and their values cannot be used in expressions\n\njulia> println(___)\nERROR: syntax: all-underscore identifiers are write-only and their values cannot be used in expressions","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"The only explicitly disallowed names for variables are the names of the built-in Keywords:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> else = false\nERROR: syntax: unexpected \"else\"\n\njulia> try = \"No\"\nERROR: syntax: unexpected \"=\"","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Some Unicode characters are considered to be equivalent in identifiers. Different ways of entering Unicode combining characters (e.g., accents) are treated as equivalent (specifically, Julia identifiers are NFC. Julia also includes a few non-standard equivalences for characters that are visually similar and are easily entered by some input methods. The Unicode characters ɛ (U+025B: Latin small letter open e) and µ (U+00B5: micro sign) are treated as equivalent to the corresponding Greek letters. The middle dot · (U+00B7) and the Greek interpunct · (U+0387) are both treated as the mathematical dot operator ⋅ (U+22C5). The minus sign − (U+2212) is treated as equivalent to the hyphen-minus sign - (U+002D).","category":"page"},{"location":"manual/variables/#man-assignment-expressions","page":"Variables","title":"Assignment expressions and assignment versus mutation","text":"","category":"section"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"An assignment variable = value \"binds\" the name variable to the value computed on the right-hand side, and the whole assignment is treated by Julia as an expression equal to the right-hand-side value. This means that assignments can be chained (the same value assigned to multiple variables with variable1 = variable2 = value) or used in other expressions, and is also why their result is shown in the REPL as the value of the right-hand side. (In general, the REPL displays the value of whatever expression you evaluate.) For example, here the value 4 of b = 2+2 is used in another arithmetic operation and assignment:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> a = (b = 2+2) + 3\n7\n\njulia> a\n7\n\njulia> b\n4","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"A common confusion is the distinction between assignment (giving a new \"name\" to a value) and mutation (changing a value). If you run a = 2 followed by a = 3, you have changed the \"name\" a to refer to a new value 3 … you haven't changed the number 2, so 2+2 will still give 4 and not 6! This distinction becomes more clear when dealing with mutable types like arrays, whose contents can be changed:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> a = [1,2,3] # an array of 3 integers\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> b = a # both b and a are names for the same array!\n3-element Vector{Int64}:\n 1\n 2\n 3","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Here, the line b = a does not make a copy of the array a, it simply binds the name b to the same array a: both b and a \"point\" to one array [1,2,3] in memory. In contrast, an assignment a[i] = value changes the contents of the array, and the modified array will be visible through both the names a and b:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"julia> a[1] = 42 # change the first element\n42\n\njulia> a = 3.14159 # a is now the name of a different object\n3.14159\n\njulia> b # b refers to the original array object, which has been mutated\n3-element Vector{Int64}:\n 42\n 2\n 3","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"That is, a[i] = value (an alias for setindex!) mutates an existing array object in memory, accessible via either a or b. Subsequently setting a = 3.14159 does not change this array, it simply binds a to a different object; the array is still accessible via b. Another common syntax to mutate an existing object is a.field = value (an alias for setproperty!), which can be used to change a mutable struct. There is also mutation via dot assignment, for example b .= 5:7 (which mutates our array b in-place to contain [5,6,7]), as part of Julia's vectorized \"dot\" syntax.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"When you call a function in Julia, it behaves as if you assigned the argument values to new variable names corresponding to the function arguments, as discussed in Argument-Passing Behavior. (By convention, functions that mutate one or more of their arguments have names ending with !.)","category":"page"},{"location":"manual/variables/#Stylistic-Conventions","page":"Variables","title":"Stylistic Conventions","text":"","category":"section"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"While Julia imposes few restrictions on valid names, it has become useful to adopt the following conventions:","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"Names of variables are in lower case.\nWord separation can be indicated by underscores ('_'), but use of underscores is discouraged unless the name would be hard to read otherwise.\nNames of Types and Modules begin with a capital letter and word separation is shown with upper camel case instead of underscores.\nNames of functions and macros are in lower case, without underscores.\nFunctions that write to their arguments have names that end in !. These are sometimes called \"mutating\" or \"in-place\" functions because they are intended to produce changes in their arguments after the function is called, not just return a value.","category":"page"},{"location":"manual/variables/","page":"Variables","title":"Variables","text":"For more information about stylistic conventions, see the Style Guide.","category":"page"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/NEWS.md\"","category":"page"},{"location":"NEWS/#Julia-v1.12-Release-Notes","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"","category":"section"},{"location":"NEWS/#New-language-features","page":"Julia v1.12 Release Notes","title":"New language features","text":"","category":"section"},{"location":"NEWS/#Language-changes","page":"Julia v1.12 Release Notes","title":"Language changes","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"When methods are replaced with exactly equivalent ones, the old method is no longer deleted implicitly simultaneously, although the new method does take priority and become more specific than the old method. Thus if the new method is deleted later, the old method will resume operating. This can be useful to mocking frameworks (such as in SparseArrays, Pluto, and Mocking, among others), as they do not need to explicitly restore the old method. While inference and compilation still must be repeated with this, it also may pave the way for inference to be able to intelligently re-use the old results, once the new method is deleted. (#53415)\nMacro expansion will no longer eargerly recurse into into Expr(:toplevel) expressions returned from macros. Instead, macro expansion of :toplevel expressions will be delayed until evaluation time. This allows a later expression within a given :toplevel expression to make use of macros defined earlier in the same :toplevel expression. (#53515)","category":"page"},{"location":"NEWS/#Compiler/Runtime-improvements","page":"Julia v1.12 Release Notes","title":"Compiler/Runtime improvements","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"Generated LLVM IR now uses actual pointer types instead of passing pointers as integers. This affects llvmcall: Inline LLVM IR should be updated to use i8* or ptr instead of i32 or i64, and remove unneeded ptrtoint/inttoptr conversions. For compatibility, IR with integer pointers is still supported, but generates a deprecation warning. (#53687)","category":"page"},{"location":"NEWS/#Command-line-option-changes","page":"Julia v1.12 Release Notes","title":"Command-line option changes","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"The -m/--module flag can be passed to run the main function inside a package with a set of arguments. This main function should be declared using @main to indicate that it is an entry point.","category":"page"},{"location":"NEWS/#Multi-threading-changes","page":"Julia v1.12 Release Notes","title":"Multi-threading changes","text":"","category":"section"},{"location":"NEWS/#Build-system-changes","page":"Julia v1.12 Release Notes","title":"Build system changes","text":"","category":"section"},{"location":"NEWS/#New-library-functions","page":"Julia v1.12 Release Notes","title":"New library functions","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"logrange(start, stop; length) makes a range of constant ratio, instead of constant step (#39071)\nThe new isfull(c::Channel) function can be used to check if put!(c, some_value) will block. (#53159)\nwaitany(tasks; throw=false) and waitall(tasks; failfast=false, throw=false) which wait multiple tasks at once (#53341).","category":"page"},{"location":"NEWS/#New-library-features","page":"Julia v1.12 Release Notes","title":"New library features","text":"","category":"section"},{"location":"NEWS/","page":"Julia v1.12 Release Notes","title":"Julia v1.12 Release Notes","text":"invmod(n, T) where T is a native integer type now computes the modular inverse of n in the modular integer ring that T defines (#52180).\ninvmod(n) is an abbreviation for invmod(n, typeof(n)) for native integer types (#52180).\nreplace(string, pattern...) now supports an optional IO argument to write the output to a stream rather than returning a string (#48625).\nsizehint!(s, n) now supports an optional shrink argument to disable shrinking (#51929).\nNew function Docs.hasdoc(module, symbol) tells whether a name has a docstring (#52139).\nNew function Docs.undocumented_names(module) returns a module's undocumented public names (#52413).\nPassing an IOBuffer as a stdout argument for Process spawn now works as expected, synchronized with wait or success, so a Base.BufferStream is no longer required there for correctness to avoid data races (#52461).\nAfter a process exits, closewrite will no longer be automatically called on the stream passed to it. Call wait on the process instead to ensure the content is fully written, then call closewrite manually to avoid data-races. Or use the callback form of open to have all that handled automatically.\n@timed now additionally returns the elapsed compilation and recompilation time (#52889)\nfilter can now act on a NamedTuple (#50795).\ntempname can now take a suffix string to allow the file name to include a suffix and include that suffix in the uniquing checking (#53474)\nRegexMatch objects can now be used to construct NamedTuples and Dicts (#50988)","category":"page"},{"location":"NEWS/#Standard-library-changes","page":"Julia v1.12 Release Notes","title":"Standard library changes","text":"","category":"section"},{"location":"NEWS/#StyledStrings","page":"Julia v1.12 Release Notes","title":"StyledStrings","text":"","category":"section"},{"location":"NEWS/#JuliaSyntaxHighlighting","page":"Julia v1.12 Release Notes","title":"JuliaSyntaxHighlighting","text":"","category":"section"},{"location":"NEWS/#Package-Manager","page":"Julia v1.12 Release Notes","title":"Package Manager","text":"","category":"section"},{"location":"NEWS/#LinearAlgebra","page":"Julia v1.12 Release Notes","title":"LinearAlgebra","text":"","category":"section"},{"location":"NEWS/#Logging","page":"Julia v1.12 Release Notes","title":"Logging","text":"","category":"section"},{"location":"NEWS/#Printf","page":"Julia v1.12 Release Notes","title":"Printf","text":"","category":"section"},{"location":"NEWS/#Profile","page":"Julia v1.12 Release Notes","title":"Profile","text":"","category":"section"},{"location":"NEWS/#Random","page":"Julia v1.12 Release Notes","title":"Random","text":"","category":"section"},{"location":"NEWS/#REPL","page":"Julia v1.12 Release Notes","title":"REPL","text":"","category":"section"},{"location":"NEWS/#SuiteSparse","page":"Julia v1.12 Release Notes","title":"SuiteSparse","text":"","category":"section"},{"location":"NEWS/#SparseArrays","page":"Julia v1.12 Release Notes","title":"SparseArrays","text":"","category":"section"},{"location":"NEWS/#Test","page":"Julia v1.12 Release Notes","title":"Test","text":"","category":"section"},{"location":"NEWS/#Dates","page":"Julia v1.12 Release Notes","title":"Dates","text":"","category":"section"},{"location":"NEWS/#Statistics","page":"Julia v1.12 Release Notes","title":"Statistics","text":"","category":"section"},{"location":"NEWS/#Distributed","page":"Julia v1.12 Release Notes","title":"Distributed","text":"","category":"section"},{"location":"NEWS/#Unicode","page":"Julia v1.12 Release Notes","title":"Unicode","text":"","category":"section"},{"location":"NEWS/#DelimitedFiles","page":"Julia v1.12 Release Notes","title":"DelimitedFiles","text":"","category":"section"},{"location":"NEWS/#InteractiveUtils","page":"Julia v1.12 Release Notes","title":"InteractiveUtils","text":"","category":"section"},{"location":"NEWS/#Deprecated-or-removed","page":"Julia v1.12 Release Notes","title":"Deprecated or removed","text":"","category":"section"},{"location":"NEWS/#External-dependencies","page":"Julia v1.12 Release Notes","title":"External dependencies","text":"","category":"section"},{"location":"NEWS/#Tooling-Improvements","page":"Julia v1.12 Release Notes","title":"Tooling Improvements","text":"","category":"section"},{"location":"stdlib/InteractiveUtils/","page":"Interactive Utilities","title":"Interactive Utilities","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/InteractiveUtils/docs/src/index.md\"","category":"page"},{"location":"stdlib/InteractiveUtils/#man-interactive-utils","page":"Interactive Utilities","title":"Interactive Utilities","text":"","category":"section"},{"location":"stdlib/InteractiveUtils/","page":"Interactive Utilities","title":"Interactive Utilities","text":"The InteractiveUtils module provides utilities for interactive use of Julia, such as code introspection and clipboard access. It is intended for interactive work and is loaded automatically in interactive mode.","category":"page"},{"location":"stdlib/InteractiveUtils/","page":"Interactive Utilities","title":"Interactive Utilities","text":"InteractiveUtils.apropos\nInteractiveUtils.varinfo\nInteractiveUtils.versioninfo\nInteractiveUtils.methodswith\nInteractiveUtils.subtypes\nInteractiveUtils.supertypes\nInteractiveUtils.edit(::AbstractString, ::Integer)\nInteractiveUtils.edit(::Any)\nInteractiveUtils.@edit\nInteractiveUtils.define_editor\nInteractiveUtils.less(::AbstractString)\nInteractiveUtils.less(::Any)\nInteractiveUtils.@less\nInteractiveUtils.@which\nInteractiveUtils.@functionloc\nInteractiveUtils.@code_lowered\nInteractiveUtils.@code_typed\nInteractiveUtils.code_warntype\nInteractiveUtils.@code_warntype\nInteractiveUtils.code_llvm\nInteractiveUtils.@code_llvm\nInteractiveUtils.code_native\nInteractiveUtils.@code_native\nInteractiveUtils.@time_imports\nInteractiveUtils.clipboard","category":"page"},{"location":"stdlib/InteractiveUtils/#Base.Docs.apropos","page":"Interactive Utilities","title":"Base.Docs.apropos","text":"apropos([io::IO=stdout], pattern::Union{AbstractString,Regex})\n\nSearch available docstrings for entries containing pattern.\n\nWhen pattern is a string, case is ignored. Results are printed to io.\n\napropos can be called from the help mode in the REPL by wrapping the query in double quotes:\n\nhelp?> \"pattern\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.varinfo","page":"Interactive Utilities","title":"InteractiveUtils.varinfo","text":"varinfo(m::Module=Main, pattern::Regex=r\"\"; all=false, imported=false, recursive=false, sortby::Symbol=:name, minsize::Int=0)\n\nReturn a markdown table giving information about public global variables in a module, optionally restricted to those matching pattern.\n\nThe memory consumption estimate is an approximate lower bound on the size of the internal structure of the object.\n\nall : also list non-public objects defined in the module, deprecated objects, and compiler-generated objects.\nimported : also list objects explicitly imported from other modules.\nrecursive : recursively include objects in sub-modules, observing the same settings in each.\nsortby : the column to sort results by. Options are :name (default), :size, and :summary.\nminsize : only includes objects with size at least minsize bytes. Defaults to 0.\n\nThe output of varinfo is intended for display purposes only. See also names to get an array of symbols defined in a module, which is suitable for more general manipulations.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.versioninfo","page":"Interactive Utilities","title":"InteractiveUtils.versioninfo","text":"versioninfo(io::IO=stdout; verbose::Bool=false)\n\nPrint information about the version of Julia in use. The output is controlled with boolean keyword arguments:\n\nverbose: print all additional information\n\nwarning: Warning\nThe output of this function may contain sensitive information. Before sharing the output, please review the output and remove any data that should not be shared publicly.\n\nSee also: VERSION.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.methodswith","page":"Interactive Utilities","title":"InteractiveUtils.methodswith","text":"methodswith(typ[, module or function]; supertypes::Bool=false])\n\nReturn an array of methods with an argument of type typ.\n\nThe optional second argument restricts the search to a particular module or function (the default is all top-level modules).\n\nIf keyword supertypes is true, also return arguments with a parent type of typ, excluding type Any.\n\nSee also: methods.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.subtypes","page":"Interactive Utilities","title":"InteractiveUtils.subtypes","text":"subtypes(T::DataType)\n\nReturn a list of immediate subtypes of DataType T. Note that all currently loaded subtypes are included, including those not visible in the current module.\n\nSee also supertype, supertypes, methodswith.\n\nExamples\n\njulia> subtypes(Integer)\n3-element Vector{Any}:\n Bool\n Signed\n Unsigned\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.supertypes","page":"Interactive Utilities","title":"InteractiveUtils.supertypes","text":"supertypes(T::Type)\n\nReturn a tuple (T, ..., Any) of T and all its supertypes, as determined by successive calls to the supertype function, listed in order of <: and terminated by Any.\n\nSee also subtypes.\n\nExamples\n\njulia> supertypes(Int)\n(Int64, Signed, Integer, Real, Number, Any)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.edit-Tuple{AbstractString, Integer}","page":"Interactive Utilities","title":"InteractiveUtils.edit","text":"edit(path::AbstractString, line::Integer=0, column::Integer=0)\n\nEdit a file or directory optionally providing a line number to edit the file at. Return to the julia prompt when you quit the editor. The editor can be changed by setting JULIA_EDITOR, VISUAL or EDITOR as an environment variable.\n\nSee also InteractiveUtils.define_editor.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.edit-Tuple{Any}","page":"Interactive Utilities","title":"InteractiveUtils.edit","text":"edit(function, [types])\nedit(module)\n\nEdit the definition of a function, optionally specifying a tuple of types to indicate which method to edit. For modules, open the main source file. The module needs to be loaded with using or import first.\n\ncompat: Julia 1.1\nedit on modules requires at least Julia 1.1.\n\nTo ensure that the file can be opened at the given line, you may need to call InteractiveUtils.define_editor first.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@edit","page":"Interactive Utilities","title":"InteractiveUtils.@edit","text":"@edit\n\nEvaluates the arguments to the function or macro call, determines their types, and calls the edit function on the resulting expression.\n\nSee also: @less, @which.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.define_editor","page":"Interactive Utilities","title":"InteractiveUtils.define_editor","text":"define_editor(fn, pattern; wait=false)\n\nDefine a new editor matching pattern that can be used to open a file (possibly at a given line number) using fn.\n\nThe fn argument is a function that determines how to open a file with the given editor. It should take four arguments, as follows:\n\ncmd - a base command object for the editor\npath - the path to the source file to open\nline - the line number to open the editor at\ncolumn - the column number to open the editor at\n\nEditors which cannot open to a specific line with a command or a specific column may ignore the line and/or column argument. The fn callback must return either an appropriate Cmd object to open a file or nothing to indicate that they cannot edit this file. Use nothing to indicate that this editor is not appropriate for the current environment and another editor should be attempted. It is possible to add more general editing hooks that need not spawn external commands by pushing a callback directly to the vector EDITOR_CALLBACKS.\n\nThe pattern argument is a string, regular expression, or an array of strings and regular expressions. For the fn to be called, one of the patterns must match the value of EDITOR, VISUAL or JULIA_EDITOR. For strings, the string must equal the basename of the first word of the editor command, with its extension, if any, removed. E.g. \"vi\" doesn't match \"vim -g\" but matches \"/usr/bin/vi -m\"; it also matches vi.exe. If pattern is a regex it is matched against all of the editor command as a shell-escaped string. An array pattern matches if any of its items match. If multiple editors match, the one added most recently is used.\n\nBy default julia does not wait for the editor to close, running it in the background. However, if the editor is terminal based, you will probably want to set wait=true and julia will wait for the editor to close before resuming.\n\nIf one of the editor environment variables is set, but no editor entry matches it, the default editor entry is invoked:\n\n(cmd, path, line, column) -> `$cmd $path`\n\nNote that many editors are already defined. All of the following commands should already work:\n\nemacs\nemacsclient\nvim\nnvim\nnano\nmicro\nkak\nhelix\ntextmate\nmate\nkate\nsubl\natom\nnotepad++\nVisual Studio Code\nopen\npycharm\nbbedit\n\nExamples\n\nThe following defines the usage of terminal-based emacs:\n\ndefine_editor(\n r\"\\bemacs\\b.*\\s(-nw|--no-window-system)\\b\", wait=true) do cmd, path, line\n `$cmd +$line $path`\nend\n\ncompat: Julia 1.4\ndefine_editor was introduced in Julia 1.4.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.less-Tuple{AbstractString}","page":"Interactive Utilities","title":"InteractiveUtils.less","text":"less(file::AbstractString, [line::Integer])\n\nShow a file using the default pager, optionally providing a starting line number. Returns to the julia prompt when you quit the pager.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.less-Tuple{Any}","page":"Interactive Utilities","title":"InteractiveUtils.less","text":"less(function, [types])\n\nShow the definition of a function using the default pager, optionally specifying a tuple of types to indicate which method to see.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@less","page":"Interactive Utilities","title":"InteractiveUtils.@less","text":"@less\n\nEvaluates the arguments to the function or macro call, determines their types, and calls the less function on the resulting expression.\n\nSee also: @edit, @which, @code_lowered.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@which","page":"Interactive Utilities","title":"InteractiveUtils.@which","text":"@which\n\nApplied to a function or macro call, it evaluates the arguments to the specified call, and returns the Method object for the method that would be called for those arguments. Applied to a variable, it returns the module in which the variable was bound. It calls out to the which function.\n\nSee also: @less, @edit.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@functionloc","page":"Interactive Utilities","title":"InteractiveUtils.@functionloc","text":"@functionloc\n\nApplied to a function or macro call, it evaluates the arguments to the specified call, and returns a tuple (filename,line) giving the location for the method that would be called for those arguments. It calls out to the functionloc function.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_lowered","page":"Interactive Utilities","title":"InteractiveUtils.@code_lowered","text":"@code_lowered\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_lowered on the resulting expression.\n\nSee also: code_lowered, @code_warntype, @code_typed, @code_llvm, @code_native.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_typed","page":"Interactive Utilities","title":"InteractiveUtils.@code_typed","text":"@code_typed\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_typed on the resulting expression. Use the optional argument optimize with\n\n@code_typed optimize=true foo(x)\n\nto control whether additional optimizations, such as inlining, are also applied.\n\nSee also: code_typed, @code_warntype, @code_lowered, @code_llvm, @code_native.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.code_warntype","page":"Interactive Utilities","title":"InteractiveUtils.code_warntype","text":"code_warntype([io::IO], f, types; debuginfo=:default)\n\nPrints lowered and type-inferred ASTs for the methods matching the given generic function and type signature to io which defaults to stdout. The ASTs are annotated in such a way as to cause \"non-leaf\" types which may be problematic for performance to be emphasized (if color is available, displayed in red). This serves as a warning of potential type instability.\n\nNot all non-leaf types are particularly problematic for performance, and the performance characteristics of a particular type is an implementation detail of the compiler. code_warntype will err on the side of coloring types red if they might be a performance concern, so some types may be colored red even if they do not impact performance. Small unions of concrete types are usually not a concern, so these are highlighted in yellow.\n\nKeyword argument debuginfo may be one of :source or :none (default), to specify the verbosity of code comments.\n\nSee the @code_warntype section in the Performance Tips page of the manual for more information.\n\nSee also: @code_warntype, code_typed, code_lowered, code_llvm, code_native.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype","page":"Interactive Utilities","title":"InteractiveUtils.@code_warntype","text":"@code_warntype\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_warntype on the resulting expression.\n\nSee also: code_warntype, @code_typed, @code_lowered, @code_llvm, @code_native.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.code_llvm","page":"Interactive Utilities","title":"InteractiveUtils.code_llvm","text":"code_llvm([io=stdout,], f, types; raw=false, dump_module=false, optimize=true, debuginfo=:default)\n\nPrints the LLVM bitcodes generated for running the method matching the given generic function and type signature to io.\n\nIf the optimize keyword is unset, the code will be shown before LLVM optimizations. All metadata and dbg.* calls are removed from the printed bitcode. For the full IR, set the raw keyword to true. To dump the entire module that encapsulates the function (with declarations), set the dump_module keyword to true. Keyword argument debuginfo may be one of source (default) or none, to specify the verbosity of code comments.\n\nSee also: @code_llvm, code_warntype, code_typed, code_lowered, code_native.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_llvm","page":"Interactive Utilities","title":"InteractiveUtils.@code_llvm","text":"@code_llvm\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_llvm on the resulting expression. Set the optional keyword arguments raw, dump_module, debuginfo, optimize by putting them and their value before the function call, like this:\n\n@code_llvm raw=true dump_module=true debuginfo=:default f(x)\n@code_llvm optimize=false f(x)\n\noptimize controls whether additional optimizations, such as inlining, are also applied. raw makes all metadata and dbg.* calls visible. debuginfo may be one of :source (default) or :none, to specify the verbosity of code comments. dump_module prints the entire module that encapsulates the function.\n\nSee also: code_llvm, @code_warntype, @code_typed, @code_lowered, @code_native.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.code_native","page":"Interactive Utilities","title":"InteractiveUtils.code_native","text":"code_native([io=stdout,], f, types; syntax=:intel, debuginfo=:default, binary=false, dump_module=true)\n\nPrints the native assembly instructions generated for running the method matching the given generic function and type signature to io.\n\nSet assembly syntax by setting syntax to :intel (default) for intel syntax or :att for AT&T syntax.\nSpecify verbosity of code comments by setting debuginfo to :source (default) or :none.\nIf binary is true, also print the binary machine code for each instruction precedented by an abbreviated address.\nIf dump_module is false, do not print metadata such as rodata or directives.\nIf raw is false, uninteresting instructions (like the safepoint function prologue) are elided.\n\nSee also: @code_native, code_warntype, code_typed, code_lowered, code_llvm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@code_native","page":"Interactive Utilities","title":"InteractiveUtils.@code_native","text":"@code_native\n\nEvaluates the arguments to the function or macro call, determines their types, and calls code_native on the resulting expression.\n\nSet any of the optional keyword arguments syntax, debuginfo, binary or dump_module by putting it before the function call, like this:\n\n@code_native syntax=:intel debuginfo=:default binary=true dump_module=false f(x)\n\nSet assembly syntax by setting syntax to :intel (default) for Intel syntax or :att for AT&T syntax.\nSpecify verbosity of code comments by setting debuginfo to :source (default) or :none.\nIf binary is true, also print the binary machine code for each instruction precedented by an abbreviated address.\nIf dump_module is false, do not print metadata such as rodata or directives.\n\nSee also: code_native, @code_warntype, @code_typed, @code_lowered, @code_llvm.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.@time_imports","page":"Interactive Utilities","title":"InteractiveUtils.@time_imports","text":"@time_imports\n\nA macro to execute an expression and produce a report of any time spent importing packages and their dependencies. Any compilation time will be reported as a percentage, and how much of which was recompilation, if any.\n\nOne line is printed per package or package extension. The duration shown is the time to import that package itself, not including the time to load any of its dependencies.\n\nOn Julia 1.9+ package extensions will show as Parent → Extension.\n\nnote: Note\nDuring the load process a package sequentially imports all of its dependencies, not just its direct dependencies.\n\njulia> @time_imports using CSV\n 50.7 ms Parsers 17.52% compilation time\n 0.2 ms DataValueInterfaces\n 1.6 ms DataAPI\n 0.1 ms IteratorInterfaceExtensions\n 0.1 ms TableTraits\n 17.5 ms Tables\n 26.8 ms PooledArrays\n 193.7 ms SentinelArrays 75.12% compilation time\n 8.6 ms InlineStrings\n 20.3 ms WeakRefStrings\n 2.0 ms TranscodingStreams\n 1.4 ms Zlib_jll\n 1.8 ms CodecZlib\n 0.8 ms Compat\n 13.1 ms FilePathsBase 28.39% compilation time\n 1681.2 ms CSV 92.40% compilation time\n\ncompat: Julia 1.8\nThis macro requires at least Julia 1.8\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/InteractiveUtils/#InteractiveUtils.clipboard","page":"Interactive Utilities","title":"InteractiveUtils.clipboard","text":"clipboard(x)\n\nSend a printed form of x to the operating system clipboard (\"copy\").\n\n\n\n\n\nclipboard() -> String\n\nReturn a string with the contents of the operating system clipboard (\"paste\").\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Serialization/","page":"Serialization","title":"Serialization","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Serialization/docs/src/index.md\"","category":"page"},{"location":"stdlib/Serialization/#Serialization","page":"Serialization","title":"Serialization","text":"","category":"section"},{"location":"stdlib/Serialization/","page":"Serialization","title":"Serialization","text":"Provides serialization of Julia objects.","category":"page"},{"location":"stdlib/Serialization/","page":"Serialization","title":"Serialization","text":"Serialization.serialize\nSerialization.deserialize\nSerialization.writeheader","category":"page"},{"location":"stdlib/Serialization/#Serialization.serialize","page":"Serialization","title":"Serialization.serialize","text":"serialize(stream::IO, value)\n\nWrite an arbitrary value to a stream in an opaque format, such that it can be read back by deserialize. The read-back value will be as identical as possible to the original, but note that Ptr values are serialized as all-zero bit patterns (NULL).\n\nAn 8-byte identifying header is written to the stream first. To avoid writing the header, construct a Serializer and use it as the first argument to serialize instead. See also Serialization.writeheader.\n\nThe data format can change in minor (1.x) Julia releases, but files written by prior 1.x versions will remain readable. The main exception to this is when the definition of a type in an external package changes. If that occurs, it may be necessary to specify an explicit compatible version of the affected package in your environment. Renaming functions, even private functions, inside packages can also put existing files out of sync. Anonymous functions require special care: because their names are automatically generated, minor code changes can cause them to be renamed. Serializing anonymous functions should be avoided in files intended for long-term storage.\n\nIn some cases, the word size (32- or 64-bit) of the reading and writing machines must match. In rarer cases the OS or architecture must also match, for example when using packages that contain platform-dependent code.\n\n\n\n\n\nserialize(filename::AbstractString, value)\n\nOpen a file and serialize the given value to it.\n\ncompat: Julia 1.1\nThis method is available as of Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Serialization/#Serialization.deserialize","page":"Serialization","title":"Serialization.deserialize","text":"deserialize(stream)\n\nRead a value written by serialize. deserialize assumes the binary data read from stream is correct and has been serialized by a compatible implementation of serialize. deserialize is designed for simplicity and performance, and so does not validate the data read. Malformed data can result in process termination. The caller must ensure the integrity and correctness of data read from stream.\n\n\n\n\n\ndeserialize(filename::AbstractString)\n\nOpen a file and deserialize its contents.\n\ncompat: Julia 1.1\nThis method is available as of Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Serialization/#Serialization.writeheader","page":"Serialization","title":"Serialization.writeheader","text":"Serialization.writeheader(s::AbstractSerializer)\n\nWrite an identifying header to the specified serializer. The header consists of 8 bytes as follows:\n\nOffset Description\n0 tag byte (0x37)\n1-2 signature bytes \"JL\"\n3 protocol version\n4 bits 0-1: endianness: 0 = little, 1 = big\n4 bits 2-3: platform: 0 = 32-bit, 1 = 64-bit\n5-7 reserved\n\n\n\n\n\n","category":"function"},{"location":"tutorials/external/#External-Tutorials","page":"External Tutorials","title":"External Tutorials","text":"","category":"section"},{"location":"tutorials/external/","page":"External Tutorials","title":"External Tutorials","text":"We have created a non-exhaustive list of community provided Julia tutorials. Check them out to learn Julia through the lens of someone from the community.","category":"page"},{"location":"stdlib/Future/","page":"Future","title":"Future","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Future/docs/src/index.md\"","category":"page"},{"location":"stdlib/Future/#Future","page":"Future","title":"Future","text":"","category":"section"},{"location":"stdlib/Future/","page":"Future","title":"Future","text":"The Future module implements future behavior of already existing functions, which will replace the current version in a future release of Julia.","category":"page"},{"location":"stdlib/Future/","page":"Future","title":"Future","text":"Future.copy!\nFuture.randjump","category":"page"},{"location":"stdlib/Future/#Future.copy!","page":"Future","title":"Future.copy!","text":"Future.copy!(dst, src) -> dst\n\nCopy src into dst.\n\ncompat: Julia 1.1\nThis function has moved to Base with Julia 1.1, consider using copy!(dst, src) instead. Future.copy! will be deprecated in the future.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Future/#Future.randjump","page":"Future","title":"Future.randjump","text":"randjump(r::MersenneTwister, steps::Integer) -> MersenneTwister\n\nCreate an initialized MersenneTwister object, whose state is moved forward (without generating numbers) from r by steps steps. One such step corresponds to the generation of two Float64 numbers. For each different value of steps, a large polynomial has to be generated internally. One is already pre-computed for steps=big(10)^20.\n\n\n\n\n\n","category":"function"},{"location":"manual/documentation/#man-documentation","page":"Documentation","title":"Documentation","text":"","category":"section"},{"location":"manual/documentation/#Accessing-Documentation","page":"Documentation","title":"Accessing Documentation","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Documentation can be accessed at the REPL or in IJulia by typing ? followed by the name of a function or macro, and pressing Enter. For example,","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"?cos\n?@time\n?r\"\"","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"will show documentation for the relevant function, macro or string macro respectively. Most Julia environments provide a way to access documentation directly:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"VS Code shows documentation when you hover over a function name. You can also use the Julia panel in the sidebar to search for documentation.\nIn Pluto, open the \"Live Docs\" panel on the bottom right.\nIn Juno using Ctrl-J, Ctrl-D will show the documentation for the object under the cursor.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Docs.hasdoc(module, name)::Bool tells whether a name has a docstring. Docs.undocumented_names(module; all) returns the undocumented names in a module.","category":"page"},{"location":"manual/documentation/#Writing-Documentation","page":"Documentation","title":"Writing Documentation","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Julia enables package developers and users to document functions, types and other objects easily via a built-in documentation system.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"The basic syntax is simple: any string appearing just before an object (function, macro, type or instance) will be interpreted as documenting it (these are called docstrings). Note that no blank lines or comments may intervene between a docstring and the documented object. Here is a basic example:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"Tell whether there are too foo items in the array.\"\nfoo(xs::Array) = ...","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Documentation is interpreted as Markdown, so you can use indentation and code fences to delimit code examples from text. Technically, any object can be associated with any other as metadata; Markdown happens to be the default, but one can construct other string macros and pass them to the @doc macro just as well.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"note: Note\nMarkdown support is implemented in the Markdown standard library and for a full list of supported syntax see the documentation.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Here is a more complex example, still using Markdown:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"\"\"\n bar(x[, y])\n\nCompute the Bar index between `x` and `y`.\n\nIf `y` is unspecified, compute the Bar index between all pairs of columns of `x`.\n\n# Examples\n```julia-repl\njulia> bar([1, 2], [1, 2])\n1\n```\n\"\"\"\nfunction bar(x, y) ...","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"As in the example above, we recommend following some simple conventions when writing documentation:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Always show the signature of a function at the top of the documentation, with a four-space indent so that it is printed as Julia code.\nThis can be identical to the signature present in the Julia code (like mean(x::AbstractArray)), or a simplified form. Optional arguments should be represented with their default values (i.e. f(x, y=1)) when possible, following the actual Julia syntax. Optional arguments which do not have a default value should be put in brackets (i.e. f(x[, y]) and f(x[, y[, z]])). An alternative solution is to use several lines: one without optional arguments, the other(s) with them. This solution can also be used to document several related methods of a given function. When a function accepts many keyword arguments, only include a placeholder in the signature (i.e. f(x; )), and give the complete list under an # Arguments section (see point 4 below).\nInclude a single one-line sentence describing what the function does or what the object represents after the simplified signature block. If needed, provide more details in a second paragraph, after a blank line.\nThe one-line sentence should use the imperative form (\"Do this\", \"Return that\") instead of the third person (do not write \"Returns the length...\") when documenting functions. It should end with a period. If the meaning of a function cannot be summarized easily, splitting it into separate composable parts could be beneficial (this should not be taken as an absolute requirement for every single case though).\nDo not repeat yourself.\nSince the function name is given by the signature, there is no need to start the documentation with \"The function bar...\": go straight to the point. Similarly, if the signature specifies the types of the arguments, mentioning them in the description is redundant.\nOnly provide an argument list when really necessary.\nFor simple functions, it is often clearer to mention the role of the arguments directly in the description of the function's purpose. An argument list would only repeat information already provided elsewhere. However, providing an argument list can be a good idea for complex functions with many arguments (in particular keyword arguments). In that case, insert it after the general description of the function, under an # Arguments header, with one - bullet for each argument. The list should mention the types and default values (if any) of the arguments:\n\"\"\"\n...\n# Arguments\n- `n::Integer`: the number of elements to compute.\n- `dim::Integer=1`: the dimensions along which to perform the computation.\n...\n\"\"\"\nProvide hints to related functions.\nSometimes there are functions of related functionality. To increase discoverability please provide a short list of these in a See also paragraph.\nSee also [`bar!`](@ref), [`baz`](@ref), [`baaz`](@ref).\nInclude any code examples in an # Examples section.\nExamples should, whenever possible, be written as doctests. A doctest is a fenced code block (see Code blocks) starting with ```jldoctest and contains any number of julia> prompts together with inputs and expected outputs that mimic the Julia REPL.\nnote: Note\nDoctests are enabled by Documenter.jl. For more detailed documentation see Documenter's manual.\nFor example in the following docstring a variable a is defined and the expected result, as printed in a Julia REPL, appears afterwards:\n\"\"\"\nSome nice documentation here.\n\n# Examples\n```jldoctest\njulia> a = [1 2; 3 4]\n2×2 Array{Int64,2}:\n 1 2\n 3 4\n```\n\"\"\"\nwarning: Warning\nCalling rand and other RNG-related functions should be avoided in doctests since they will not produce consistent outputs during different Julia sessions. If you would like to show some random number generation related functionality, one option is to explicitly construct and seed your own RNG object (see Random) and pass it to the functions you are doctesting.Operating system word size (Int32 or Int64) as well as path separator differences (/ or \\) will also affect the reproducibility of some doctests.Note that whitespace in your doctest is significant! The doctest will fail if you misalign the output of pretty-printing an array, for example.\nYou can then run make -C doc doctest=true to run all the doctests in the Julia Manual and API documentation, which will ensure that your example works.\nTo indicate that the output result is truncated, you may write [...] at the line where checking should stop. This is useful to hide a stacktrace (which contains non-permanent references to lines of julia code) when the doctest shows that an exception is thrown, for example:\n```jldoctest\njulia> div(1, 0)\nERROR: DivideError: integer division error\n[...]\n```\nExamples that are untestable should be written within fenced code blocks starting with ```julia so that they are highlighted correctly in the generated documentation.\ntip: Tip\nWherever possible examples should be self-contained and runnable so that readers are able to try them out without having to include any dependencies.\nUse backticks to identify code and equations.\nJulia identifiers and code excerpts should always appear between backticks ` to enable highlighting. Equations in the LaTeX syntax can be inserted between double backticks ``. Use Unicode characters rather than their LaTeX escape sequence, i.e. ``α = 1`` rather than ``\\\\alpha = 1``.\nPlace the starting and ending \"\"\" characters on lines by themselves.\nThat is, write:\n\"\"\"\n...\n\n...\n\"\"\"\nf(x, y) = ...\nrather than:\n\"\"\"...\n\n...\"\"\"\nf(x, y) = ...\nThis makes it clearer where docstrings start and end.\nRespect the line length limit used in the surrounding code.\nDocstrings are edited using the same tools as code. Therefore, the same conventions should apply. It is recommended that lines are at most 92 characters wide.\nProvide information allowing custom types to implement the function in an # Implementation section. These implementation details are intended for developers rather than users, explaining e.g. which functions should be overridden and which functions automatically use appropriate fallbacks. Such details are best kept separate from the main description of the function's behavior.\nFor long docstrings, consider splitting the documentation with an # Extended help header. The typical help-mode will show only the material above the header; you can access the full help by adding a '?' at the beginning of the expression (i.e., \"??foo\" rather than \"?foo\").","category":"page"},{"location":"manual/documentation/#Functions-and-Methods","page":"Documentation","title":"Functions & Methods","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Functions in Julia may have multiple implementations, known as methods. While it's good practice for generic functions to have a single purpose, Julia allows methods to be documented individually if necessary. In general, only the most generic method should be documented, or even the function itself (i.e. the object created without any methods by function bar end). Specific methods should only be documented if their behaviour differs from the more generic ones. In any case, they should not repeat the information provided elsewhere. For example:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"\"\"\n *(x, y, z...)\n\nMultiplication operator. `x * y * z *...` calls this function with multiple\narguments, i.e. `*(x, y, z...)`.\n\"\"\"\nfunction *(x, y, z...)\n # ... [implementation sold separately] ...\nend\n\n\"\"\"\n *(x::AbstractString, y::AbstractString, z::AbstractString...)\n\nWhen applied to strings, concatenates them.\n\"\"\"\nfunction *(x::AbstractString, y::AbstractString, z::AbstractString...)\n # ... [insert secret sauce here] ...\nend\n\nhelp?> *\nsearch: * .*\n\n *(x, y, z...)\n\n Multiplication operator. x * y * z *... calls this function with multiple\n arguments, i.e. *(x,y,z...).\n\n *(x::AbstractString, y::AbstractString, z::AbstractString...)\n\n When applied to strings, concatenates them.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"When retrieving documentation for a generic function, the metadata for each method is concatenated with the catdoc function, which can of course be overridden for custom types.","category":"page"},{"location":"manual/documentation/#Advanced-Usage","page":"Documentation","title":"Advanced Usage","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"The @doc macro associates its first argument with its second in a per-module dictionary called META.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"To make it easier to write documentation, the parser treats the macro name @doc specially: if a call to @doc has one argument, but another expression appears after a single line break, then that additional expression is added as an argument to the macro. Therefore the following syntax is parsed as a 2-argument call to @doc:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"@doc raw\"\"\"\n...\n\"\"\"\nf(x) = x","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"This makes it possible to use expressions other than normal string literals (such as the raw\"\" string macro) as a docstring.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"When used for retrieving documentation, the @doc macro (or equally, the doc function) will search all META dictionaries for metadata relevant to the given object and return it. The returned object (some Markdown content, for example) will by default display itself intelligently. This design also makes it easy to use the doc system in a programmatic way; for example, to re-use documentation between different versions of a function:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"@doc \"...\" foo!\n@doc (@doc foo!) foo","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Or for use with Julia's metaprogramming functionality:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"for (f, op) in ((:add, :+), (:subtract, :-), (:multiply, :*), (:divide, :/))\n @eval begin\n $f(a, b) = $op(a, b)\n end\nend\n@doc \"`add(a, b)` adds `a` and `b` together\" add\n@doc \"`subtract(a, b)` subtracts `b` from `a`\" subtract","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Documentation in non-toplevel blocks, such as begin, if, for, let, and inner constructors, should be added to the documentation system via @doc as well. For example:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"if condition()\n @doc \"...\"\n f(x) = x\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"will add documentation to f(x) when condition() is true. Note that even if f(x) goes out of scope at the end of a block, its documentation will remain.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"It is possible to make use of metaprogramming to assist in the creation of documentation. When using string-interpolation within the docstring you will need to use an extra $ as shown with $($name):","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"for func in (:day, :dayofmonth)\n name = string(func)\n @eval begin\n @doc \"\"\"\n $($name)(dt::TimeType) -> Int64\n\n The day of month of a `Date` or `DateTime` as an `Int64`.\n \"\"\" $func(dt::Dates.TimeType)\n end\nend","category":"page"},{"location":"manual/documentation/#Dynamic-documentation","page":"Documentation","title":"Dynamic documentation","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Sometimes the appropriate documentation for an instance of a type depends on the field values of that instance, rather than just on the type itself. In these cases, you can add a method to Docs.getdoc for your custom type that returns the documentation on a per-instance basis. For instance,","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"struct MyType\n value::Int\nend\n\nDocs.getdoc(t::MyType) = \"Documentation for MyType with value $(t.value)\"\n\nx = MyType(1)\ny = MyType(2)","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"?x will display \"Documentation for MyType with value 1\" while ?y will display \"Documentation for MyType with value 2\".","category":"page"},{"location":"manual/documentation/#Syntax-Guide","page":"Documentation","title":"Syntax Guide","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"This guide provides a comprehensive overview of how to attach documentation to all Julia syntax constructs for which providing documentation is possible.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"In the following examples \"...\" is used to illustrate an arbitrary docstring.","category":"page"},{"location":"manual/documentation/#and-\\-characters","page":"Documentation","title":"$ and \\ characters","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"The $ and \\ characters are still parsed as string interpolation or start of an escape sequence in docstrings too. The raw\"\" string macro together with the @doc macro can be used to avoid having to escape them. This is handy when the docstrings include LaTeX or Julia source code examples containing interpolation:","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"@doc raw\"\"\"\n```math\n\\LaTeX\n```\n\"\"\"\nfunction f end","category":"page"},{"location":"manual/documentation/#Functions-and-Methods-2","page":"Documentation","title":"Functions and Methods","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nfunction f end\n\n\"...\"\nf","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the function f. The first version is the preferred syntax, however both are equivalent.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nf(x) = x\n\n\"...\"\nfunction f(x)\n return x\nend\n\n\"...\"\nf(x)","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the method f(::Any).","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nf(x, y = 1) = x + y","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to two Methods, namely f(::Any) and f(::Any, ::Any).","category":"page"},{"location":"manual/documentation/#Macros","page":"Documentation","title":"Macros","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nmacro m(x) end","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the @m(::Any) macro definition.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\n:(@m1)\n\n\"...\"\nmacro m2 end","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the macros named @m1 and @m2.","category":"page"},{"location":"manual/documentation/#Types","page":"Documentation","title":"Types","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nabstract type T1 end\n\n\"...\"\nmutable struct T2\n ...\nend\n\n\"...\"\nstruct T3\n ...\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds the docstring \"...\" to types T1, T2, and T3.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nT1\n\n\"...\"\nT2\n\n\"...\"\nT3","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds the docstring \"...\" to types T1, T2, and T3. The previous version is the preferred syntax, however both are equivalent.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nstruct T\n \"x\"\n x\n \"y\"\n y\n\n @doc \"Inner constructor\"\n function T()\n new(...)\n end\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to type T, \"x\" to field T.x, \"y\" to field T.y, and \"Inner constructor\" to the inner constructor T(). Also applicable to mutable struct types.","category":"page"},{"location":"manual/documentation/#Modules","page":"Documentation","title":"Modules","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nmodule M end\n\nmodule M\n\n\"...\"\nM\n\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the Module M. Adding the docstring above the Module is the preferred syntax, however both are equivalent.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nbaremodule M\n# ...\nend\n\nbaremodule M\n\nimport Base: @doc\n\n\"...\"\nf(x) = x\n\nend","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Documenting a baremodule by placing a docstring above the expression automatically imports @doc into the module. These imports must be done manually when the module expression is not documented.","category":"page"},{"location":"manual/documentation/#Global-Variables","page":"Documentation","title":"Global Variables","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nconst a = 1\n\n\"...\"\nb = 2\n\n\"...\"\nglobal c = 3","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the Bindings a, b, and c.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Bindings are used to store a reference to a particular Symbol in a Module without storing the referenced value itself.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"note: Note\nWhen a const definition is only used to define an alias of another definition, such as is the case with the function div and its alias ÷ in Base, do not document the alias and instead document the actual function.If the alias is documented and not the real definition then the docsystem (? mode) will not return the docstring attached to the alias when the real definition is searched for.For example you should write\"...\"\nf(x) = x + 1\nconst alias = frather thanf(x) = x + 1\n\"...\"\nconst alias = f","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\nsym","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the value associated with sym. However, it is preferred that sym is documented where it is defined.","category":"page"},{"location":"manual/documentation/#Multiple-Objects","page":"Documentation","title":"Multiple Objects","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\na, b","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to a and b each of which should be a documentable expression. This syntax is equivalent to","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\na\n\n\"...\"\nb","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Any number of expressions many be documented together in this way. This syntax can be useful when two functions are related, such as non-mutating and mutating versions f and f!.","category":"page"},{"location":"manual/documentation/#Macro-generated-code","page":"Documentation","title":"Macro-generated code","text":"","category":"section"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"\"...\"\n@m expression","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Adds docstring \"...\" to the expression generated by expanding @m expression. This allows for expressions decorated with @inline, @noinline, @generated, or any other macro to be documented in the same way as undecorated expressions.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Macro authors should take note that only macros that generate a single expression will automatically support docstrings. If a macro returns a block containing multiple subexpressions then the subexpression that should be documented must be marked using the @__doc__ macro.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"The @enum macro makes use of @__doc__ to allow for documenting Enums. Examining its definition should serve as an example of how to use @__doc__ correctly.","category":"page"},{"location":"manual/documentation/","page":"Documentation","title":"Documentation","text":"Core.@__doc__","category":"page"},{"location":"manual/documentation/#Core.@__doc__","page":"Documentation","title":"Core.@__doc__","text":"@__doc__(ex)\n\nLow-level macro used to mark expressions returned by a macro that should be documented. If more than one expression is marked then the same docstring is applied to each expression.\n\nmacro example(f)\n quote\n $(f)() = 0\n @__doc__ $(f)(x) = 1\n $(f)(x, y) = 2\n end |> esc\nend\n\n@__doc__ has no effect when a macro that uses it is not documented.\n\ncompat: Julia 1.12\nThis section documents a very subtle corner case that is only relevant to macros which themselves both define other macros and then attempt to use them within the same expansion. Such macros were impossible to write prior to Julia 1.12 and are still quite rare. If you are not writing such a macro, you may ignore this note.In versions prior to Julia 1.12, macroexpansion would recursively expand through Expr(:toplevel) blocks. This behavior was changed in Julia 1.12 to allow macros to recursively define other macros and use them in the same returned expression. However, to preserve backwards compatibility with existing uses of @__doc__, the doc system will still expand through Expr(:toplevel) blocks when looking for @__doc__ markers. As a result, macro-defining-macros will have an observable behavior difference when annotated with a docstring:julia> macro macroception()\n Expr(:toplevel, :(macro foo() 1 end), :(@foo))\nend\n\njulia> @macroception\n1\n\njulia> \"Docstring\" @macroception\nERROR: LoadError: UndefVarError: `@foo` not defined in `Main`The supported workaround is to manually expand the @__doc__ macro in the defining macro, which the docsystem will recognize and suppress the recursive expansion:julia> macro macroception()\n Expr(:toplevel,\n macroexpand(__module__, :(@__doc__ macro foo() 1 end); recursive=false),\n :(@foo))\nend\n\njulia> @macroception\n1\n\njulia> \"Docstring\" @macroception\n1\n\n\n\n\n\n","category":"macro"},{"location":"manual/noteworthy-differences/#Noteworthy-Differences-from-other-Languages","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"","category":"section"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-MATLAB","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from MATLAB","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Although MATLAB users may find Julia's syntax familiar, Julia is not a MATLAB clone. There are major syntactic and functional differences. The following are some noteworthy differences that may trip up Julia users accustomed to MATLAB:","category":"page"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia arrays are indexed with square brackets, A[i,j].\nJulia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well. To avoid this, use A = copy(B).\nJulia values are not copied when passed to a function. If a function modifies an array, the changes will be visible in the caller.\nJulia does not automatically grow arrays in an assignment statement. Whereas in MATLAB a(4) = 3.2 can create the array a = [0 0 0 3.2] and a(5) = 7 can grow it into a = [0 0 0 3.2 7], the corresponding Julia statement a[5] = 7 throws an error if the length of a is less than 5 or if this statement is the first use of the identifier a. Julia has push! and append!, which grow Vectors much more efficiently than MATLAB's a(end+1) = val.\nThe imaginary unit sqrt(-1) is represented in Julia as im, not i or j as in MATLAB.\nIn Julia, literal numbers without a decimal point (such as 42) create integers instead of floating point numbers. As a result, some operations can throw a domain error if they expect a float; for example, julia> a = -1; 2^a throws a domain error, as the result is not an integer (see the FAQ entry on domain errors for details).\nIn Julia, multiple values are returned and assigned as tuples, e.g. (a, b) = (1, 2) or a, b = 1, 2. MATLAB's nargout, which is often used in MATLAB to do optional work based on the number of returned values, does not exist in Julia. Instead, users can use optional and keyword arguments to achieve similar capabilities.\nJulia has true one-dimensional arrays. Column vectors are of size N, not Nx1. For example, rand(N) makes a 1-dimensional array.\nIn Julia, [x,y,z] will always construct a 3-element array containing x, y and z.\nTo concatenate in the first (\"vertical\") dimension use either vcat(x,y,z) or separate with semicolons ([x; y; z]).\nTo concatenate in the second (\"horizontal\") dimension use either hcat(x,y,z) or separate with spaces ([x y z]).\nTo construct block matrices (concatenating in the first two dimensions), use either hvcat or combine spaces and semicolons ([a b; c d]).\nIn Julia, a:b and a:b:c construct AbstractRange objects. To construct a full vector like in MATLAB, use collect(a:b). Generally, there is no need to call collect though. An AbstractRange object will act like a normal array in most cases but is more efficient because it lazily computes its values. This pattern of creating specialized objects instead of full arrays is used frequently, and is also seen in functions such as range, or with iterators such as enumerate, and zip. The special objects can mostly be used as if they were normal arrays.\nFunctions in Julia return values from their last expression or the return keyword instead of listing the names of variables to return in the function definition (see The return Keyword for details).\nA Julia script may contain any number of functions, and all definitions will be externally visible when the file is loaded. Function definitions can be loaded from files outside the current working directory.\nIn Julia, reductions such as sum, prod, and maximum are performed over every element of an array when called with a single argument, as in sum(A), even if A has more than one dimension.\nIn Julia, parentheses must be used to call a function with zero arguments, like in rand().\nJulia discourages the use of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end with semicolons. println or @printf can be used to print specific output.\nIn Julia, if A and B are arrays, logical comparison operations like A == B do not return an array of booleans. Instead, use A .== B, and similarly for the other boolean operators like <, >.\nIn Julia, when you want to apply a scalar-valued function elementwise to an array, use broadcasting syntax: f.(A) instead of f(A). In some cases, both operations are defined but mean different things: in MATLAB exp(A) applies elementwise and expm(A) is the matrix exponential, but in Julia exp.(A) applies elementwise and exp(A) is the matrix exponential.\nIn Julia, the operators &, |, and ⊻ (xor) perform the bitwise operations equivalent to and, or, and xor respectively in MATLAB, and have precedence similar to Python's bitwise operators (unlike C). They can operate on scalars or element-wise across arrays and can be used to combine logical arrays, but note the difference in order of operations: parentheses may be required (e.g., to select elements of A equal to 1 or 2 use (A .== 1) .| (A .== 2)).\nIn Julia, the elements of a collection can be passed as arguments to a function using the splat operator ..., as in xs=[1,2]; f(xs...).\nJulia's svd returns singular values as a vector instead of as a dense diagonal matrix.\nIn Julia, ... is not used to continue lines of code. Instead, incomplete expressions automatically continue onto the next line.\nIn both Julia and MATLAB, the variable ans is set to the value of the last expression issued in an interactive session. In Julia, unlike MATLAB, ans is not set when Julia code is run in non-interactive mode.\nJulia's structs do not support dynamically adding fields at runtime, unlike MATLAB's classes. Instead, use a Dict. Dict in Julia isn't ordered.\nIn Julia each module has its own global scope/namespace, whereas in MATLAB there is just one global scope.\nIn MATLAB, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression x(x>3) or in the statement x(x>3) = [] to modify x in-place. In contrast, Julia provides the higher order functions filter and filter!, allowing users to write filter(z->z>3, x) and filter!(z->z>3, x) as alternatives to the corresponding transliterations x[x.>3] and x = x[x.>3]. Using filter! reduces the use of temporary arrays.\nThe analogue of extracting (or \"dereferencing\") all elements of a cell array, e.g. in vertcat(A{:}) in MATLAB, is written using the splat operator in Julia, e.g. as vcat(A...).\nIn Julia, the adjoint function performs conjugate transposition; in MATLAB, adjoint provides the \"adjugate\" or classical adjoint, which is the transpose of the matrix of cofactors.\nIn Julia, a^b^c is evaluated a^(b^c) while in MATLAB it's (a^b)^c.","category":"page"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-R","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from R","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"One of Julia's goals is to provide an effective language for data analysis and statistical programming. For users coming to Julia from R, these are some noteworthy differences:","category":"page"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia's single quotes enclose characters, not strings.\nJulia can create substrings by indexing into strings. In R, strings must be converted into character vectors before creating substrings.\nIn Julia, like Python but unlike R, strings can be created with triple quotes \"\"\" ... \"\"\". This syntax is convenient for constructing strings that contain line breaks.\nIn Julia, varargs are specified using the splat operator ..., which always follows the name of a specific variable, unlike R, for which ... can occur in isolation.\nIn Julia, modulus is mod(a, b), not a %% b. % in Julia is the remainder operator.\nJulia constructs vectors using brackets. Julia's [1, 2, 3] is the equivalent of R's c(1, 2, 3).\nIn Julia, not all data structures support logical indexing. Furthermore, logical indexing in Julia is supported only with vectors of length equal to the object being indexed. For example:\nIn R, c(1, 2, 3, 4)[c(TRUE, FALSE)] is equivalent to c(1, 3).\nIn R, c(1, 2, 3, 4)[c(TRUE, FALSE, TRUE, FALSE)] is equivalent to c(1, 3).\nIn Julia, [1, 2, 3, 4][[true, false]] throws a BoundsError.\nIn Julia, [1, 2, 3, 4][[true, false, true, false]] produces [1, 3].\nLike many languages, Julia does not always allow operations on vectors of different lengths, unlike R where the vectors only need to share a common index range. For example, c(1, 2, 3, 4) + c(1, 2) is valid R but the equivalent [1, 2, 3, 4] + [1, 2] will throw an error in Julia.\nJulia allows an optional trailing comma when that comma does not change the meaning of code. This can cause confusion among R users when indexing into arrays. For example, x[1,] in R would return the first row of a matrix; in Julia, however, the comma is ignored, so x[1,] == x[1], and will return the first element. To extract a row, be sure to use :, as in x[1,:].\nJulia's map takes the function first, then its arguments, unlike lapply(, function, ...) in R. Similarly Julia's equivalent of apply(X, MARGIN, FUN, ...) in R is mapslices where the function is the first argument.\nMultivariate apply in R, e.g. mapply(choose, 11:13, 1:3), can be written as broadcast(binomial, 11:13, 1:3) in Julia. Equivalently Julia offers a shorter dot syntax for vectorizing functions binomial.(11:13, 1:3).\nJulia uses end to denote the end of conditional blocks, like if, loop blocks, like while/ for, and functions. In lieu of the one-line if ( cond ) statement, Julia allows statements of the form if cond; statement; end, cond && statement and !cond || statement. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g. cond && (x = value).\nIn Julia, <-, <<- and -> are not assignment operators.\nJulia's -> creates an anonymous function.\nJulia's * operator can perform matrix multiplication, unlike in R. If A and B are matrices, then A * B denotes a matrix multiplication in Julia, equivalent to R's A %*% B. In R, this same notation would perform an element-wise (Hadamard) product. To get the element-wise multiplication operation, you need to write A .* B in Julia.\nJulia performs matrix transposition using the transpose function and conjugated transposition using the ' operator or the adjoint function. Julia's transpose(A) is therefore equivalent to R's t(A). Additionally a non-recursive transpose in Julia is provided by the permutedims function.\nJulia does not require parentheses when writing if statements or for/while loops: use for i in [1, 2, 3] instead of for (i in c(1, 2, 3)) and if i == 1 instead of if (i == 1).\nJulia does not treat the numbers 0 and 1 as Booleans. You cannot write if (1) in Julia, because if statements accept only booleans. Instead, you can write if true, if Bool(1), or if 1==1.\nJulia does not provide nrow and ncol. Instead, use size(M, 1) for nrow(M) and size(M, 2) for ncol(M).\nJulia is careful to distinguish scalars, vectors and matrices. In R, 1 and c(1) are the same. In Julia, they cannot be used interchangeably.\nJulia's diag and diagm are not like R's.\nJulia cannot assign to the results of function calls on the left hand side of an assignment operation: you cannot write diag(M) = fill(1, n).\nJulia discourages populating the main namespace with functions. Most statistical functionality for Julia is found in packages under the JuliaStats organization. For example:\nFunctions pertaining to probability distributions are provided by the Distributions package.\nThe DataFrames package provides data frames.\nGeneralized linear models are provided by the GLM package.\nJulia provides tuples and real hash tables, but not R-style lists. When returning multiple items, you should typically use a tuple or a named tuple: instead of list(a = 1, b = 2), use (1, 2) or (a=1, b=2).\nJulia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that table(x::TypeA) and table(x::TypeB) act like R's table.TypeA(x) and table.TypeB(x).\nIn Julia, values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. This is very different from R and allows new functions to operate on large data structures much more efficiently.\nIn Julia, vectors and matrices are concatenated using hcat, vcat and hvcat, not c, rbind and cbind like in R.\nIn Julia, a range like a:b is not shorthand for a vector like in R, but is a specialized AbstractRange object that is used for iteration. To convert a range into a vector, use collect(a:b).\nThe : operator has a different precedence in R and Julia. In particular, in Julia arithmetic operators have higher precedence than the : operator, whereas the reverse is true in R. For example, 1:n-1 in Julia is equivalent to 1:(n-1) in R.\nJulia's max and min are the equivalent of pmax and pmin respectively in R, but both arguments need to have the same dimensions. While maximum and minimum replace max and min in R, there are important differences.\nJulia's sum, prod, maximum, and minimum are different from their counterparts in R. They all accept an optional keyword argument dims, which indicates the dimensions, over which the operation is carried out. For instance, let A = [1 2; 3 4] in Julia and B <- rbind(c(1,2),c(3,4)) be the same matrix in R. Then sum(A) gives the same result as sum(B), but sum(A, dims=1) is a row vector containing the sum over each column and sum(A, dims=2) is a column vector containing the sum over each row. This contrasts to the behavior of R, where separate colSums(B) and rowSums(B) functions provide these functionalities. If the dims keyword argument is a vector, then it specifies all the dimensions over which the sum is performed, while retaining the dimensions of the summed array, e.g. sum(A, dims=(1,2)) == hcat(10). It should be noted that there is no error checking regarding the second argument.\nJulia has several functions that can mutate their arguments. For example, it has both sort and sort!.\nIn R, performance requires vectorization. In Julia, almost the opposite is true: the best performing code is often achieved by using devectorized loops.\nJulia is eagerly evaluated and does not support R-style lazy evaluation. For most users, this means that there are very few unquoted expressions or column names.\nJulia does not support the NULL type. The closest equivalent is nothing, but it behaves like a scalar value rather than like a list. Use x === nothing instead of is.null(x).\nIn Julia, missing values are represented by the missing object rather than by NA. Use ismissing(x) (or ismissing.(x) for element-wise operation on vectors) instead of is.na(x). The skipmissing function is generally used instead of na.rm=TRUE (though in some particular cases functions take a skipmissing argument).\nJulia lacks the equivalent of R's assign or get.\nIn Julia, return does not require parentheses.\nIn R, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression x[x>3] or in the statement x = x[x>3] to modify x in-place. In contrast, Julia provides the higher order functions filter and filter!, allowing users to write filter(z->z>3, x) and filter!(z->z>3, x) as alternatives to the corresponding transliterations x[x.>3] and x = x[x.>3]. Using filter! reduces the use of temporary arrays.","category":"page"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-Python","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from Python","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia's for, if, while, etc. blocks are terminated by the end keyword. Indentation level is not significant as it is in Python. Unlike Python, Julia has no pass keyword.\nStrings are denoted by double quotation marks (\"text\") in Julia (with three double quotation marks for multi-line strings), whereas in Python they can be denoted either by single ('text') or double quotation marks (\"text\"). Single quotation marks are used for characters in Julia ('c').\nString concatenation is done with * in Julia, not + like in Python. Analogously, string repetition is done with ^, not *. Implicit string concatenation of string literals like in Python (e.g. 'ab' 'cd' == 'abcd') is not done in Julia.\nPython Lists—flexible but slow—correspond to the Julia Vector{Any} type or more generally Vector{T} where T is some non-concrete element type. \"Fast\" arrays like NumPy arrays that store elements in-place (i.e., dtype is np.float64, [('f1', np.uint64), ('f2', np.int32)], etc.) can be represented by Array{T} where T is a concrete, immutable element type. This includes built-in types like Float64, Int32, Int64 but also more complex types like Tuple{UInt64,Float64} and many user-defined types as well.\nIn Julia, indexing of arrays, strings, etc. is 1-based not 0-based.\nJulia's slice indexing includes the last element, unlike in Python. a[2:3] in Julia is a[1:3] in Python.\nUnlike Python, Julia allows AbstractArrays with arbitrary indexes. Python's special interpretation of negative indexing, a[-1] and a[-2], should be written a[end] and a[end-1] in Julia.\nJulia requires end for indexing until the last element. x[1:] in Python is equivalent to x[2:end] in Julia.\nIn Julia, : before any object creates a Symbol or quotes an expression; so, x[:5] is same as x[5]. If you want to get the first n elements of an array, then use range indexing.\nJulia's range indexing has the format of x[start:step:stop], whereas Python's format is x[start:(stop+1):step]. Hence, x[0:10:2] in Python is equivalent to x[1:2:10] in Julia. Similarly, x[::-1] in Python, which refers to the reversed array, is equivalent to x[end:-1:1] in Julia.\nIn Julia, ranges can be constructed independently as start:step:stop, the same syntax it uses in array-indexing. The range function is also supported.\nIn Julia, indexing a matrix with arrays like X[[1,2], [1,3]] refers to a sub-matrix that contains the intersections of the first and second rows with the first and third columns. In Python, X[[1,2], [1,3]] refers to a vector that contains the values of cell [1,1] and [2,3] in the matrix. X[[1,2], [1,3]] in Julia is equivalent with X[np.ix_([0,1],[0,2])] in Python. X[[0,1], [0,2]] in Python is equivalent with X[[CartesianIndex(1,1), CartesianIndex(2,3)]] in Julia.\nJulia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.\nJulia arrays are column-major (Fortran-ordered) whereas NumPy arrays are row-major (C-ordered) by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to NumPy (see relevant section of Performance Tips).\nJulia's updating operators (e.g. +=, -=, ...) are not in-place whereas NumPy's are. This means A = [1, 1]; B = A; B += [3, 3] doesn't change values in A, it rather rebinds the name B to the result of the right-hand side B = B + 3, which is a new array. For in-place operation, use B .+= 3 (see also dot operators), explicit loops, or InplaceOps.jl.\nJulia evaluates default values of function arguments every time the method is invoked, unlike in Python where the default values are evaluated only once when the function is defined. For example, the function f(x=rand()) = x returns a new random number every time it is invoked without argument. On the other hand, the function g(x=[1,2]) = push!(x,3) returns [1,2,3] every time it is called as g().\nIn Julia, keyword arguments must be passed using keywords, unlike Python in which it is usually possible to pass them positionally. Attempting to pass a keyword argument positionally alters the method signature leading to a MethodError or calling of the wrong method.\nIn Julia % is the remainder operator, whereas in Python it is the modulus.\nIn Julia, the commonly used Int type corresponds to the machine integer type (Int32 or Int64), unlike in Python, where int is an arbitrary length integer. This means in Julia the Int type will overflow, such that 2^64 == 0. If you need larger values use another appropriate type, such as Int128, BigInt or a floating point type like Float64.\nThe imaginary unit sqrt(-1) is represented in Julia as im, not j as in Python.\nIn Julia, the exponentiation operator is ^, not ** as in Python.\nJulia uses nothing of type Nothing to represent a null value, whereas Python uses None of type NoneType.\nIn Julia, the standard operators over a matrix type are matrix operations, whereas, in Python, the standard operators are element-wise operations. When both A and B are matrices, A * B in Julia performs matrix multiplication, not element-wise multiplication as in Python. A * B in Julia is equivalent with A @ B in Python, whereas A * B in Python is equivalent with A .* B in Julia.\nIn Julia, when you want to apply a scalar-valued function elementwise to an array, use broadcasting syntax: f.(A) instead of f(A). In some cases, both operations are defined but mean different things: numpy.exp(A) applies elementwise and scipy.linalg.expm(A) is the matrix exponential, but in Julia exp.(A) applies elementwise and exp(A) is the matrix exponential.\nThe adjoint operator ' in Julia returns an adjoint of a vector (a lazy representation of row vector), whereas the transpose operator .T over a vector in Python returns the original vector (non-op).\nIn Julia, a function may contain multiple concrete implementations (called methods), which are selected via multiple dispatch based on the types of all arguments to the call, as compared to functions in Python, which have a single implementation and no polymorphism (as opposed to Python method calls which use a different syntax and allows dispatch on the receiver of the method).\nThere are no classes in Julia. Instead there are structures (mutable or immutable), containing data but no methods.\nCalling a method of a class instance in Python (x = MyClass(*args); x.f(y)) corresponds to a function call in Julia, e.g. x = MyType(args...); f(x, y). In general, multiple dispatch is more flexible and powerful than the Python class system.\nJulia structures may have exactly one abstract supertype, whereas Python classes can inherit from one or more (abstract or concrete) superclasses.\nThe logical Julia program structure (Packages and Modules) is independent of the file structure, whereas the Python code structure is defined by directories (Packages) and files (Modules).\nIn Julia, it is idiomatic to split the text of large modules into multiple files, without introducing a new module per file. The code is reassembled inside a single module in a main file via include. While the Python equivalent (exec) is not typical for this use (it will silently clobber prior definitions), Julia programs are defined as a unit at the module level with using or import, which will only get executed once when first needed–like include in Python. Within those modules, the individual files that make up that module are loaded with include by listing them once in the intended order.\nThe ternary operator x > 0 ? 1 : -1 in Julia corresponds to a conditional expression in Python 1 if x > 0 else -1.\nIn Julia the @ symbol refers to a macro, whereas in Python it refers to a decorator.\nException handling in Julia is done using try — catch — finally, instead of try — except — finally. In contrast to Python, it is not recommended to use exception handling as part of the normal workflow in Julia (compared with Python, Julia is faster at ordinary control flow but slower at exception-catching).\nIn Julia loops are fast, there is no need to write \"vectorized\" code for performance reasons.\nBe careful with non-constant global variables in Julia, especially in tight loops. Since you can write close-to-metal code in Julia (unlike Python), the effect of globals can be drastic (see Performance Tips).\nIn Julia, rounding and truncation are explicit. Python's int(3.7) should be floor(Int, 3.7) or Int(floor(3.7)) and is distinguished from round(Int, 3.7). floor(x) and round(x) on their own return an integer value of the same type as x rather than always returning Int.\nIn Julia, parsing is explicit. Python's float(\"3.7\") would be parse(Float64, \"3.7\") in Julia.\nIn Python, the majority of values can be used in logical contexts (e.g. if \"a\": means the following block is executed, and if \"\": means it is not). In Julia, you need explicit conversion to Bool (e.g. if \"a\" throws an exception). If you want to test for a non-empty string in Julia, you would explicitly write if !isempty(\"\"). Perhaps surprisingly, in Python if \"False\" and bool(\"False\") both evaluate to True (because \"False\" is a non-empty string); in Julia, parse(Bool, \"false\") returns false.\nIn Julia, a new local scope is introduced by most code blocks, including loops and try — catch — finally. Note that comprehensions (list, generator, etc.) introduce a new local scope both in Python and Julia, whereas if blocks do not introduce a new local scope in both languages.","category":"page"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-C/C","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from C/C++","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia arrays are indexed with square brackets, and can have more than one dimension A[i,j]. This syntax is not just syntactic sugar for a reference to a pointer or address as in C/C++. See the manual entry about array construction.\nIn Julia, indexing of arrays, strings, etc. is 1-based not 0-based.\nJulia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well. Updating operators like += do not operate in-place, they are equivalent to A = A + B which rebinds the left-hand side to the result of the right-hand side expression.\nJulia arrays are column major (Fortran ordered) whereas C/C++ arrays are row major ordered by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to C/C++ (see relevant section of Performance Tips).\nJulia values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller.\nIn Julia, whitespace is significant, unlike C/C++, so care must be taken when adding/removing whitespace from a Julia program.\nIn Julia, literal numbers without a decimal point (such as 42) create signed integers, of type Int, but literals too large to fit in the machine word size will automatically be promoted to a larger size type, such as Int64 (if Int is Int32), Int128, or the arbitrarily large BigInt type. There are no numeric literal suffixes, such as L, LL, U, UL, ULL to indicate unsigned and/or signed vs. unsigned. Decimal literals are always signed, and hexadecimal literals (which start with 0x like C/C++), are unsigned, unless when they encode more than 128 bits, in which case they are of type BigInt. Hexadecimal literals also, unlike C/C++/Java and unlike decimal literals in Julia, have a type based on the length of the literal, including leading 0s. For example, 0x0 and 0x00 have type UInt8, 0x000 and 0x0000 have type UInt16, then literals with 5 to 8 hex digits have type UInt32, 9 to 16 hex digits type UInt64, 17 to 32 hex digits type UInt128, and more that 32 hex digits type BigInt. This needs to be taken into account when defining hexadecimal masks, for example ~0xf == 0xf0 is very different from ~0x000f == 0xfff0. 64 bit Float64 and 32 bit Float32 bit literals are expressed as 1.0 and 1.0f0 respectively. Floating point literals are rounded (and not promoted to the BigFloat type) if they can not be exactly represented. Floating point literals are closer in behavior to C/C++. Octal (prefixed with 0o) and binary (prefixed with 0b) literals are also treated as unsigned (or BigInt for more than 128 bits).\nIn Julia, the division operator / returns a floating point number when both operands are of integer type. To perform integer division, use div or ÷.\nIndexing an Array with floating point types is generally an error in Julia. The Julia equivalent of the C expression a[i / 2] is a[i ÷ 2 + 1], where i is of integer type.\nString literals can be delimited with either \" or \"\"\", \"\"\" delimited literals can contain \" characters without quoting it like \"\\\"\". String literals can have values of other variables or expressions interpolated into them, indicated by $variablename or $(expression), which evaluates the variable name or the expression in the context of the function.\n// indicates a Rational number, and not a single-line comment (which is # in Julia)\n#= indicates the start of a multiline comment, and =# ends it.\nFunctions in Julia return values from their last expression(s) or the return keyword. Multiple values can be returned from functions and assigned as tuples, e.g. (a, b) = myfunction() or a, b = myfunction(), instead of having to pass pointers to values as one would have to do in C/C++ (i.e. a = myfunction(&b).\nJulia does not require the use of semicolons to end statements. The results of expressions are not automatically printed (except at the interactive prompt, i.e. the REPL), and lines of code do not need to end with semicolons. println or @printf can be used to print specific output. In the REPL, ; can be used to suppress output. ; also has a different meaning within [ ], something to watch out for. ; can be used to separate expressions on a single line, but are not strictly necessary in many cases, and are more an aid to readability.\nIn Julia, the operator ⊻ (xor) performs the bitwise XOR operation, i.e. ^ in C/C++. Also, the bitwise operators do not have the same precedence as C/C++, so parenthesis may be required.\nJulia's ^ is exponentiation (pow), not bitwise XOR as in C/C++ (use ⊻, or xor, in Julia)\nJulia has two right-shift operators, >> and >>>. >> performs an arithmetic shift, >>> always performs a logical shift, unlike C/C++, where the meaning of >> depends on the type of the value being shifted.\nJulia's -> creates an anonymous function, it does not access a member via a pointer.\nJulia does not require parentheses when writing if statements or for/while loops: use for i in [1, 2, 3] instead of for (int i=1; i <= 3; i++) and if i == 1 instead of if (i == 1).\nJulia does not treat the numbers 0 and 1 as Booleans. You cannot write if (1) in Julia, because if statements accept only booleans. Instead, you can write if true, if Bool(1), or if 1==1.\nJulia uses end to denote the end of conditional blocks, like if, loop blocks, like while/ for, and functions. In lieu of the one-line if ( cond ) statement, Julia allows statements of the form if cond; statement; end, cond && statement and !cond || statement. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g. cond && (x = value), because of the operator precedence.\nJulia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.\nJulia macros operate on parsed expressions, rather than the text of the program, which allows them to perform sophisticated transformations of Julia code. Macro names start with the @ character, and have both a function-like syntax, @mymacro(arg1, arg2, arg3), and a statement-like syntax, @mymacro arg1 arg2 arg3. The forms are interchangeable; the function-like form is particularly useful if the macro appears within another expression, and is often clearest. The statement-like form is often used to annotate blocks, as in the distributed for construct: @distributed for i in 1:n; #= body =#; end. Where the end of the macro construct may be unclear, use the function-like form.\nJulia has an enumeration type, expressed using the macro @enum(name, value1, value2, ...) For example: @enum(Fruit, banana=1, apple, pear)\nBy convention, functions that modify their arguments have a ! at the end of the name, for example push!.\nIn C++, by default, you have static dispatch, i.e. you need to annotate a function as virtual, in order to have dynamic dispatch. On the other hand, in Julia every method is \"virtual\" (although it's more general than that since methods are dispatched on every argument type, not only this, using the most-specific-declaration rule).","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Namespaces","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Namespaces","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"C/C++ namespaces correspond roughly to Julia modules.\nThere are no private globals or fields in Julia. Everything is publicly accessible through fully qualified paths (or relative paths, if desired).\nusing MyNamespace::myfun (C++) corresponds roughly to import MyModule: myfun (Julia).\nusing namespace MyNamespace (C++) corresponds roughly to using MyModule (Julia)\nIn Julia, only exported symbols are made available to the calling module.\nIn C++, only elements found in the included (public) header files are made available.\nCaveat: import/using keywords (Julia) also load modules (see below).\nCaveat: import/using (Julia) works only at the global scope level (modules)\nIn C++, using namespace X works within arbitrary scopes (ex: function scope).","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Module-loading","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Module loading","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"When you think of a C/C++ \"library\", you are likely looking for a Julia \"package\".\nCaveat: C/C++ libraries often house multiple \"software modules\" whereas Julia \"packages\" typically house one.\nReminder: Julia modules are global scopes (not necessarily \"software modules\").\nInstead of build/make scripts, Julia uses \"Project Environments\" (sometimes called either \"Project\" or \"Environment\").\nBuild scripts are only needed for more complex applications (like those needing to compile or download C/C++ executables).\nTo develop application or project in Julia, you can initialize its root directory as a \"Project Environment\", and house application-specific code/packages there. This provides good control over project dependencies, and future reproducibility.\nAvailable packages are added to a \"Project Environment\" with the Pkg.add() function or Pkg REPL mode. (This does not load said package, however).\nThe list of available packages (direct dependencies) for a \"Project Environment\" are saved in its Project.toml file.\nThe full dependency information for a \"Project Environment\" is auto-generated & saved in its Manifest.toml file by Pkg.resolve().\nPackages (\"software modules\") available to the \"Project Environment\" are loaded with import or using.\nIn C/C++, you #include to get object/function declarations, and link in libraries when you build the executable.\nIn Julia, calling using/import again just brings the existing module into scope, but does not load it again (similar to adding the non-standard #pragma once to C/C++).\nDirectory-based package repositories (Julia) can be made available by adding repository paths to the Base.LOAD_PATH array.\nPackages from directory-based repositories do not require the Pkg.add() tool prior to being loaded with import or using. They are simply available to the project.\nDirectory-based package repositories are the quickest solution to developing local libraries of \"software modules\".","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Assembling-modules","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Assembling modules","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"In C/C++, .c/.cpp files are compiled & added to a library with build/make scripts.\nIn Julia, import [PkgName]/using [PkgName] statements load [PkgName].jl located in a package's [PkgName]/src/ subdirectory.\nIn turn, [PkgName].jl typically loads associated source files with calls to include \"[someotherfile].jl\".\ninclude \"./path/to/somefile.jl\" (Julia) is very similar to #include \"./path/to/somefile.jl\" (C/C++).\nHowever include \"...\" (Julia) is not used to include header files (not required).\nDo not use include \"...\" (Julia) to load code from other \"software modules\" (use import/using instead).\ninclude \"path/to/some/module.jl\" (Julia) would instantiate multiple versions of the same code in different modules (creating distinct types (etc.) with the same names).\ninclude \"somefile.jl\" is typically used to assemble multiple files within the same Julia package (\"software module\"). It is therefore relatively straightforward to ensure file are included only once (No #ifdef confusion).","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Module-interface","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Module interface","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"C++ exposes interfaces using \"public\" .h/.hpp files whereas Julia modules mark specific symbols that are intended for their users as publicor exported.\nOften, Julia modules simply add functionality by generating new \"methods\" to existing functions (ex: Base.push!).\nDevelopers of Julia packages therefore cannot rely on header files for interface documentation.\nInterfaces for Julia packages are typically described using docstrings, README.md, static web pages, ...\nSome developers choose not to export all symbols required to use their package/module, but should still mark unexported user facing symbols as public.\nUsers might be expected to access these components by qualifying functions/structs/... with the package/module name (ex: MyModule.run_this_task(...)).","category":"page"},{"location":"manual/noteworthy-differences/#Julia-C/C:-Quick-reference","page":"Noteworthy Differences from other Languages","title":"Julia ⇔ C/C++: Quick reference","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Software Concept Julia C/C++\nunnamed scope begin ... end { ... }\nfunction scope function x() ... end int x() { ... }\nglobal scope module MyMod ... end namespace MyNS { ... }\nsoftware module A Julia \"package\" .h/.hpp files
    +compiled somelib.a\nassembling
    software modules SomePkg.jl: ...
    import(\"subfile1.jl\")
    import(\"subfile2.jl\")
    ... $(AR) *.o ⇒ somelib.a\nimport
    software module import SomePkg #include
    +link in somelib.a\nmodule library LOAD_PATH[], *Git repository,
    **custom package registry more .h/.hpp files
    +bigger compiled somebiglib.a","category":"page"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"* The Julia package manager supports registering multiple packages from a single Git repository.
    * This allows users to house a library of related packages in a single repository.
    ** Julia registries are primarily designed to provide versioning \\& distribution of packages.
    ** Custom package registries can be used to create a type of module library.","category":"page"},{"location":"manual/noteworthy-differences/#Noteworthy-differences-from-Common-Lisp","page":"Noteworthy Differences from other Languages","title":"Noteworthy differences from Common Lisp","text":"","category":"section"},{"location":"manual/noteworthy-differences/","page":"Noteworthy Differences from other Languages","title":"Noteworthy Differences from other Languages","text":"Julia uses 1-based indexing for arrays by default, and it can also handle arbitrary index offsets.\nFunctions and variables share the same namespace (“Lisp-1”).\nThere is a Pair type, but it is not meant to be used as a COMMON-LISP:CONS. Various iterable collections can be used interchangeably in most parts of the language (eg splatting, tuples, etc). Tuples are the closest to Common Lisp lists for short collections of heterogeneous elements. Use NamedTuples in place of alists. For larger collections of homogeneous types, Arrays and Dicts should be used.\nThe typical Julia workflow for prototyping also uses continuous manipulation of the image, implemented with the Revise.jl package.\nFor performance, Julia prefers that operations have type stability. Where Common Lisp abstracts away from the underlying machine operations, Julia cleaves closer to them. For example:\nInteger division using / always returns a floating-point result, even if the computation is exact.\n// always returns a rational result\n÷ always returns a (truncated) integer result\nBignums are supported, but conversion is not automatic; ordinary integers overflow.\nComplex numbers are supported, but to get complex results, you need complex inputs.\nThere are multiple Complex and Rational types, with different component types.\nModules (namespaces) can be hierarchical. import and using have a dual role: they load the code and make it available in the namespace. import for only the module name is possible (roughly equivalent to ASDF:LOAD-OP). Slot names don't need to be exported separately. Global variables can't be assigned to from outside the module (except with eval(mod, :(var = val)) as an escape hatch).\nMacros start with @, and are not as seamlessly integrated into the language as Common Lisp; consequently, macro usage is not as widespread as in the latter. A form of hygiene for macros is supported by the language. Because of the different surface syntax, there is no equivalent to COMMON-LISP:&BODY.\nAll functions are generic and use multiple dispatch. Argument lists don't have to follow the same template, which leads to a powerful idiom (see do). Optional and keyword arguments are handled differently. Method ambiguities are not resolved like in the Common Lisp Object System, necessitating the definition of a more specific method for the intersection.\nSymbols do not belong to any package, and do not contain any values per se. M.var evaluates the symbol var in the module M.\nA functional programming style is fully supported by the language, including closures, but isn't always the idiomatic solution for Julia. Some workarounds may be necessary for performance when modifying captured variables.","category":"page"},{"location":"stdlib/LibGit2/","page":"LibGit2","title":"LibGit2","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/LibGit2/docs/src/index.md\"","category":"page"},{"location":"stdlib/LibGit2/#LibGit2","page":"LibGit2","title":"LibGit2","text":"","category":"section"},{"location":"stdlib/LibGit2/","page":"LibGit2","title":"LibGit2","text":"The LibGit2 module provides bindings to libgit2, a portable C library that implements core functionality for the Git version control system. These bindings are currently used to power Julia's package manager. It is expected that this module will eventually be moved into a separate package.","category":"page"},{"location":"stdlib/LibGit2/#Functionality","page":"LibGit2","title":"Functionality","text":"","category":"section"},{"location":"stdlib/LibGit2/","page":"LibGit2","title":"LibGit2","text":"Some of this documentation assumes some prior knowledge of the libgit2 API. For more information on some of the objects and methods referenced here, consult the upstream libgit2 API reference.","category":"page"},{"location":"stdlib/LibGit2/","page":"LibGit2","title":"LibGit2","text":"LibGit2.Buffer\nLibGit2.CheckoutOptions\nLibGit2.CloneOptions\nLibGit2.DescribeOptions\nLibGit2.DescribeFormatOptions\nLibGit2.DiffDelta\nLibGit2.DiffFile\nLibGit2.DiffOptionsStruct\nLibGit2.FetchHead\nLibGit2.FetchOptions\nLibGit2.GitAnnotated\nLibGit2.GitBlame\nLibGit2.GitBlob\nLibGit2.GitCommit\nLibGit2.GitConfig\nLibGit2.GitHash\nLibGit2.GitObject\nLibGit2.GitRemote\nLibGit2.GitRemoteAnon\nLibGit2.GitRepo\nLibGit2.GitRepoExt\nLibGit2.GitRevWalker\nLibGit2.GitShortHash\nLibGit2.GitSignature\nLibGit2.GitStatus\nLibGit2.GitTag\nLibGit2.GitTree\nLibGit2.IndexEntry\nLibGit2.IndexTime\nLibGit2.BlameOptions\nLibGit2.MergeOptions\nLibGit2.ProxyOptions\nLibGit2.PushOptions\nLibGit2.RebaseOperation\nLibGit2.RebaseOptions\nLibGit2.RemoteCallbacks\nLibGit2.SignatureStruct\nLibGit2.StatusEntry\nLibGit2.StatusOptions\nLibGit2.StrArrayStruct\nLibGit2.TimeStruct\nLibGit2.addfile\nLibGit2.add!\nLibGit2.add_fetch!\nLibGit2.add_push!\nLibGit2.addblob!\nLibGit2.author\nLibGit2.authors\nLibGit2.branch\nLibGit2.branch!\nLibGit2.checkout!\nLibGit2.clone\nLibGit2.commit\nLibGit2.committer\nLibGit2.count\nLibGit2.counthunks\nLibGit2.create_branch\nLibGit2.credentials_callback\nLibGit2.credentials_cb\nLibGit2.default_signature\nLibGit2.delete_branch\nLibGit2.diff_files\nLibGit2.entryid\nLibGit2.entrytype\nLibGit2.fetch\nLibGit2.fetchheads\nLibGit2.fetch_refspecs\nLibGit2.fetchhead_foreach_cb\nLibGit2.merge_base\nLibGit2.merge!(::LibGit2.GitRepo; ::Any...)\nLibGit2.merge!(::LibGit2.GitRepo, ::Vector{LibGit2.GitAnnotated}; ::LibGit2.MergeOptions, ::LibGit2.CheckoutOptions)\nLibGit2.merge!(::LibGit2.GitRepo, ::Vector{LibGit2.GitAnnotated}, ::Bool; ::LibGit2.MergeOptions, ::LibGit2.CheckoutOptions)\nLibGit2.ffmerge!\nLibGit2.fullname\nLibGit2.features\nLibGit2.filename\nLibGit2.filemode\nLibGit2.gitdir\nLibGit2.git_url\nLibGit2.@githash_str\nLibGit2.head\nLibGit2.head!\nLibGit2.head_oid\nLibGit2.headname\nLibGit2.init\nLibGit2.is_ancestor_of\nLibGit2.isbinary\nLibGit2.iscommit\nLibGit2.isdiff\nLibGit2.isdirty\nLibGit2.isorphan\nLibGit2.isset\nLibGit2.iszero\nLibGit2.lookup_branch\nLibGit2.map\nLibGit2.mirror_callback\nLibGit2.mirror_cb\nLibGit2.message\nLibGit2.merge_analysis\nLibGit2.name\nLibGit2.need_update\nLibGit2.objtype\nLibGit2.path\nLibGit2.peel\nLibGit2.posixpath\nLibGit2.push\nLibGit2.push!(::LibGit2.GitRevWalker, ::LibGit2.GitHash)\nLibGit2.push_head!\nLibGit2.push_refspecs\nLibGit2.raw\nLibGit2.read_tree!\nLibGit2.rebase!\nLibGit2.ref_list\nLibGit2.reftype\nLibGit2.remotes\nLibGit2.remove!\nLibGit2.reset\nLibGit2.reset!\nLibGit2.restore\nLibGit2.revcount\nLibGit2.set_remote_url\nLibGit2.shortname\nLibGit2.snapshot\nLibGit2.split_cfg_entry\nLibGit2.status\nLibGit2.stage\nLibGit2.tag_create\nLibGit2.tag_delete\nLibGit2.tag_list\nLibGit2.target\nLibGit2.toggle\nLibGit2.transact\nLibGit2.treewalk\nLibGit2.upstream\nLibGit2.update!\nLibGit2.url\nLibGit2.version\nLibGit2.with\nLibGit2.with_warn\nLibGit2.workdir\nLibGit2.GitObject(::LibGit2.GitTreeEntry)\nLibGit2.UserPasswordCredential\nLibGit2.SSHCredential\nLibGit2.isfilled\nLibGit2.CachedCredentials\nLibGit2.CredentialPayload\nLibGit2.approve\nLibGit2.reject\nLibGit2.Consts.GIT_CONFIG","category":"page"},{"location":"stdlib/LibGit2/#LibGit2.Buffer","page":"LibGit2","title":"LibGit2.Buffer","text":"LibGit2.Buffer\n\nA data buffer for exporting data from libgit2. Matches the git_buf struct.\n\nWhen fetching data from LibGit2, a typical usage would look like:\n\nbuf_ref = Ref(Buffer())\n@check ccall(..., (Ptr{Buffer},), buf_ref)\n# operation on buf_ref\nfree(buf_ref)\n\nIn particular, note that LibGit2.free should be called afterward on the Ref object.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.CheckoutOptions","page":"LibGit2","title":"LibGit2.CheckoutOptions","text":"LibGit2.CheckoutOptions\n\nMatches the git_checkout_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\ncheckout_strategy: determine how to handle conflicts and whether to force the checkout/recreate missing files.\ndisable_filters: if nonzero, do not apply filters like CLRF (to convert file newlines between UNIX and DOS).\ndir_mode: read/write/access mode for any directories involved in the checkout. Default is 0755.\nfile_mode: read/write/access mode for any files involved in the checkout. Default is 0755 or 0644, depending on the blob.\nfile_open_flags: bitflags used to open any files during the checkout.\nnotify_flags: Flags for what sort of conflicts the user should be notified about.\nnotify_cb: An optional callback function to notify the user if a checkout conflict occurs. If this function returns a non-zero value, the checkout will be cancelled.\nnotify_payload: Payload for the notify callback function.\nprogress_cb: An optional callback function to display checkout progress.\nprogress_payload: Payload for the progress callback.\npaths: If not empty, describes which paths to search during the checkout. If empty, the checkout will occur over all files in the repository.\nbaseline: Expected content of the workdir, captured in a (pointer to a) GitTree. Defaults to the state of the tree at HEAD.\nbaseline_index: Expected content of the workdir, captured in a (pointer to a) GitIndex. Defaults to the state of the index at HEAD.\ntarget_directory: If not empty, checkout to this directory instead of the workdir.\nancestor_label: In case of conflicts, the name of the common ancestor side.\nour_label: In case of conflicts, the name of \"our\" side.\ntheir_label: In case of conflicts, the name of \"their\" side.\nperfdata_cb: An optional callback function to display performance data.\nperfdata_payload: Payload for the performance callback.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.CloneOptions","page":"LibGit2","title":"LibGit2.CloneOptions","text":"LibGit2.CloneOptions\n\nMatches the git_clone_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\ncheckout_opts: The options for performing the checkout of the remote as part of the clone.\nfetch_opts: The options for performing the pre-checkout fetch of the remote as part of the clone.\nbare: If 0, clone the full remote repository. If non-zero, perform a bare clone, in which there is no local copy of the source files in the repository and the gitdir and workdir are the same.\nlocalclone: Flag whether to clone a local object database or do a fetch. The default is to let git decide. It will not use the git-aware transport for a local clone, but will use it for URLs which begin with file://.\ncheckout_branch: The name of the branch to checkout. If an empty string, the default branch of the remote will be checked out.\nrepository_cb: An optional callback which will be used to create the new repository into which the clone is made.\nrepository_cb_payload: The payload for the repository callback.\nremote_cb: An optional callback used to create the GitRemote before making the clone from it.\nremote_cb_payload: The payload for the remote callback.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DescribeOptions","page":"LibGit2","title":"LibGit2.DescribeOptions","text":"LibGit2.DescribeOptions\n\nMatches the git_describe_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nmax_candidates_tags: consider this many most recent tags in refs/tags to describe a commit. Defaults to 10 (so that the 10 most recent tags would be examined to see if they describe a commit).\ndescribe_strategy: whether to consider all entries in refs/tags (equivalent to git-describe --tags) or all entries in refs/ (equivalent to git-describe --all). The default is to only show annotated tags. If Consts.DESCRIBE_TAGS is passed, all tags, annotated or not, will be considered. If Consts.DESCRIBE_ALL is passed, any ref in refs/ will be considered.\npattern: only consider tags which match pattern. Supports glob expansion.\nonly_follow_first_parent: when finding the distance from a matching reference to the described object, only consider the distance from the first parent.\nshow_commit_oid_as_fallback: if no matching reference can be found which describes a commit, show the commit's GitHash instead of throwing an error (the default behavior).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DescribeFormatOptions","page":"LibGit2","title":"LibGit2.DescribeFormatOptions","text":"LibGit2.DescribeFormatOptions\n\nMatches the git_describe_format_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nabbreviated_size: lower bound on the size of the abbreviated GitHash to use, defaulting to 7.\nalways_use_long_format: set to 1 to use the long format for strings even if a short format can be used.\ndirty_suffix: if set, this will be appended to the end of the description string if the workdir is dirty.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DiffDelta","page":"LibGit2","title":"LibGit2.DiffDelta","text":"LibGit2.DiffDelta\n\nDescription of changes to one entry. Matches the git_diff_delta struct.\n\nThe fields represent:\n\nstatus: One of Consts.DELTA_STATUS, indicating whether the file has been added/modified/deleted.\nflags: Flags for the delta and the objects on each side. Determines whether to treat the file(s) as binary/text, whether they exist on each side of the diff, and whether the object ids are known to be correct.\nsimilarity: Used to indicate if a file has been renamed or copied.\nnfiles: The number of files in the delta (for instance, if the delta was run on a submodule commit id, it may contain more than one file).\nold_file: A DiffFile containing information about the file(s) before the changes.\nnew_file: A DiffFile containing information about the file(s) after the changes.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DiffFile","page":"LibGit2","title":"LibGit2.DiffFile","text":"LibGit2.DiffFile\n\nDescription of one side of a delta. Matches the git_diff_file struct.\n\nThe fields represent:\n\nid: the GitHash of the item in the diff. If the item is empty on this side of the diff (for instance, if the diff is of the removal of a file), this will be GitHash(0).\npath: a NULL terminated path to the item relative to the working directory of the repository.\nsize: the size of the item in bytes.\nflags: a combination of the git_diff_flag_t flags. The ith bit of this integer sets the ith flag.\nmode: the stat mode for the item.\nid_abbrev: only present in LibGit2 versions newer than or equal to 0.25.0. The length of the id field when converted using string. Usually equal to OID_HEXSZ (40).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.DiffOptionsStruct","page":"LibGit2","title":"LibGit2.DiffOptionsStruct","text":"LibGit2.DiffOptionsStruct\n\nMatches the git_diff_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nflags: flags controlling which files will appear in the diff. Defaults to DIFF_NORMAL.\nignore_submodules: whether to look at files in submodules or not. Defaults to SUBMODULE_IGNORE_UNSPECIFIED, which means the submodule's configuration will control whether it appears in the diff or not.\npathspec: path to files to include in the diff. Default is to use all files in the repository.\nnotify_cb: optional callback which will notify the user of changes to the diff as file deltas are added to it.\nprogress_cb: optional callback which will display diff progress. Only relevant on libgit2 versions at least as new as 0.24.0.\npayload: the payload to pass to notify_cb and progress_cb.\ncontext_lines: the number of unchanged lines used to define the edges of a hunk. This is also the number of lines which will be shown before/after a hunk to provide context. Default is 3.\ninterhunk_lines: the maximum number of unchanged lines between two separate hunks allowed before the hunks will be combined. Default is 0.\nid_abbrev: sets the length of the abbreviated GitHash to print. Default is 7.\nmax_size: the maximum file size of a blob. Above this size, it will be treated as a binary blob. The default is 512 MB.\nold_prefix: the virtual file directory in which to place old files on one side of the diff. Default is \"a\".\nnew_prefix: the virtual file directory in which to place new files on one side of the diff. Default is \"b\".\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.FetchHead","page":"LibGit2","title":"LibGit2.FetchHead","text":"LibGit2.FetchHead\n\nContains the information about HEAD during a fetch, including the name and URL of the branch fetched from, the oid of the HEAD, and whether the fetched HEAD has been merged locally.\n\nThe fields represent:\n\nname: The name in the local reference database of the fetch head, for example, \"refs/heads/master\".\nurl: The URL of the fetch head.\noid: The GitHash of the tip of the fetch head.\nismerge: Boolean flag indicating whether the changes at the remote have been merged into the local copy yet or not. If true, the local copy is up to date with the remote fetch head.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.FetchOptions","page":"LibGit2","title":"LibGit2.FetchOptions","text":"LibGit2.FetchOptions\n\nMatches the git_fetch_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\ncallbacks: remote callbacks to use during the fetch.\nprune: whether to perform a prune after the fetch or not. The default is to use the setting from the GitConfig.\nupdate_fetchhead: whether to update the FetchHead after the fetch. The default is to perform the update, which is the normal git behavior.\ndownload_tags: whether to download tags present at the remote or not. The default is to request the tags for objects which are being downloaded anyway from the server.\nproxy_opts: options for connecting to the remote through a proxy. See ProxyOptions. Only present on libgit2 versions newer than or equal to 0.25.0.\ncustom_headers: any extra headers needed for the fetch. Only present on libgit2 versions newer than or equal to 0.24.0.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitAnnotated","page":"LibGit2","title":"LibGit2.GitAnnotated","text":"GitAnnotated(repo::GitRepo, commit_id::GitHash)\nGitAnnotated(repo::GitRepo, ref::GitReference)\nGitAnnotated(repo::GitRepo, fh::FetchHead)\nGitAnnotated(repo::GitRepo, committish::AbstractString)\n\nAn annotated git commit carries with it information about how it was looked up and why, so that rebase or merge operations have more information about the context of the commit. Conflict files contain information about the source/target branches in the merge which are conflicting, for instance. An annotated commit can refer to the tip of a remote branch, for instance when a FetchHead is passed, or to a branch head described using GitReference.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitBlame","page":"LibGit2","title":"LibGit2.GitBlame","text":"GitBlame(repo::GitRepo, path::AbstractString; options::BlameOptions=BlameOptions())\n\nConstruct a GitBlame object for the file at path, using change information gleaned from the history of repo. The GitBlame object records who changed which chunks of the file when, and how. options controls how to separate the contents of the file and which commits to probe - see BlameOptions for more information.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitBlob","page":"LibGit2","title":"LibGit2.GitBlob","text":"GitBlob(repo::GitRepo, hash::AbstractGitHash)\nGitBlob(repo::GitRepo, spec::AbstractString)\n\nReturn a GitBlob object from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitCommit","page":"LibGit2","title":"LibGit2.GitCommit","text":"GitCommit(repo::GitRepo, hash::AbstractGitHash)\nGitCommit(repo::GitRepo, spec::AbstractString)\n\nReturn a GitCommit object from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitConfig","page":"LibGit2","title":"LibGit2.GitConfig","text":"GitConfig(path::AbstractString, level::Consts.GIT_CONFIG=Consts.CONFIG_LEVEL_APP, force::Bool=false)\n\nCreate a new GitConfig by loading configuration information from the file at path. See addfile for more information about the level, repo and force options.\n\n\n\n\n\nGitConfig(repo::GitRepo)\n\nGet the stored configuration for the git repository repo. If repo does not have a specific configuration file set, the default git configuration will be used.\n\n\n\n\n\nGitConfig(level::Consts.GIT_CONFIG=Consts.CONFIG_LEVEL_DEFAULT)\n\nGet the default git configuration by loading the global and system configuration files into a prioritized configuration. This can be used to access default configuration options outside a specific git repository.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitHash","page":"LibGit2","title":"LibGit2.GitHash","text":"GitHash\n\nA git object identifier, based on the sha-1 hash. It is a 20 byte string (40 hex digits) used to identify a GitObject in a repository.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitObject","page":"LibGit2","title":"LibGit2.GitObject","text":"GitObject(repo::GitRepo, hash::AbstractGitHash)\nGitObject(repo::GitRepo, spec::AbstractString)\n\nReturn the specified object (GitCommit, GitBlob, GitTree or GitTag) from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitRemote","page":"LibGit2","title":"LibGit2.GitRemote","text":"GitRemote(repo::GitRepo, rmt_name::AbstractString, rmt_url::AbstractString) -> GitRemote\n\nLook up a remote git repository using its name and URL. Uses the default fetch refspec.\n\nExamples\n\nrepo = LibGit2.init(repo_path)\nremote = LibGit2.GitRemote(repo, \"upstream\", repo_url)\n\n\n\n\n\nGitRemote(repo::GitRepo, rmt_name::AbstractString, rmt_url::AbstractString, fetch_spec::AbstractString) -> GitRemote\n\nLook up a remote git repository using the repository's name and URL, as well as specifications for how to fetch from the remote (e.g. which remote branch to fetch from).\n\nExamples\n\nrepo = LibGit2.init(repo_path)\nrefspec = \"+refs/heads/mybranch:refs/remotes/origin/mybranch\"\nremote = LibGit2.GitRemote(repo, \"upstream\", repo_url, refspec)\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitRemoteAnon","page":"LibGit2","title":"LibGit2.GitRemoteAnon","text":"GitRemoteAnon(repo::GitRepo, url::AbstractString) -> GitRemote\n\nLook up a remote git repository using only its URL, not its name.\n\nExamples\n\nrepo = LibGit2.init(repo_path)\nremote = LibGit2.GitRemoteAnon(repo, repo_url)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.GitRepo","page":"LibGit2","title":"LibGit2.GitRepo","text":"LibGit2.GitRepo(path::AbstractString)\n\nOpen a git repository at path.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitRepoExt","page":"LibGit2","title":"LibGit2.GitRepoExt","text":"LibGit2.GitRepoExt(path::AbstractString, flags::Cuint = Cuint(Consts.REPOSITORY_OPEN_DEFAULT))\n\nOpen a git repository at path with extended controls (for instance, if the current user must be a member of a special access group to read path).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.GitRevWalker","page":"LibGit2","title":"LibGit2.GitRevWalker","text":"GitRevWalker(repo::GitRepo)\n\nA GitRevWalker walks through the revisions (i.e. commits) of a git repository repo. It is a collection of the commits in the repository, and supports iteration and calls to LibGit2.map and LibGit2.count (for instance, LibGit2.count could be used to determine what percentage of commits in a repository were made by a certain author).\n\ncnt = LibGit2.with(LibGit2.GitRevWalker(repo)) do walker\n LibGit2.count((oid,repo)->(oid == commit_oid1), walker, oid=commit_oid1, by=LibGit2.Consts.SORT_TIME)\nend\n\nHere, LibGit2.count finds the number of commits along the walk with a certain GitHash. Since the GitHash is unique to a commit, cnt will be 1.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitShortHash","page":"LibGit2","title":"LibGit2.GitShortHash","text":"GitShortHash(hash::GitHash, len::Integer)\n\nA shortened git object identifier, which can be used to identify a git object when it is unique, consisting of the initial len hexadecimal digits of hash (the remaining digits are ignored).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitSignature","page":"LibGit2","title":"LibGit2.GitSignature","text":"LibGit2.GitSignature\n\nThis is a Julia wrapper around a pointer to a git_signature object.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitStatus","page":"LibGit2","title":"LibGit2.GitStatus","text":"LibGit2.GitStatus(repo::GitRepo; status_opts=StatusOptions())\n\nCollect information about the status of each file in the git repository repo (e.g. is the file modified, staged, etc.). status_opts can be used to set various options, for instance whether or not to look at untracked files or whether to include submodules or not. See StatusOptions for more information.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitTag","page":"LibGit2","title":"LibGit2.GitTag","text":"GitTag(repo::GitRepo, hash::AbstractGitHash)\nGitTag(repo::GitRepo, spec::AbstractString)\n\nReturn a GitTag object from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.GitTree","page":"LibGit2","title":"LibGit2.GitTree","text":"GitTree(repo::GitRepo, hash::AbstractGitHash)\nGitTree(repo::GitRepo, spec::AbstractString)\n\nReturn a GitTree object from repo specified by hash/spec.\n\nhash is a full (GitHash) or partial (GitShortHash) hash.\nspec is a textual specification: see the git docs for a full list.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.IndexEntry","page":"LibGit2","title":"LibGit2.IndexEntry","text":"LibGit2.IndexEntry\n\nIn-memory representation of a file entry in the index. Matches the git_index_entry struct.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.IndexTime","page":"LibGit2","title":"LibGit2.IndexTime","text":"LibGit2.IndexTime\n\nMatches the git_index_time struct.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.BlameOptions","page":"LibGit2","title":"LibGit2.BlameOptions","text":"LibGit2.BlameOptions\n\nMatches the git_blame_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nflags: one of Consts.BLAME_NORMAL or Consts.BLAME_FIRST_PARENT (the other blame flags are not yet implemented by libgit2).\nmin_match_characters: the minimum number of alphanumeric characters which much change in a commit in order for the change to be associated with that commit. The default is 20. Only takes effect if one of the Consts.BLAME_*_COPIES flags are used, which libgit2 does not implement yet.\nnewest_commit: the GitHash of the newest commit from which to look at changes.\noldest_commit: the GitHash of the oldest commit from which to look at changes.\nmin_line: the first line of the file from which to starting blaming. The default is 1.\nmax_line: the last line of the file to which to blame. The default is 0, meaning the last line of the file.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.MergeOptions","page":"LibGit2","title":"LibGit2.MergeOptions","text":"LibGit2.MergeOptions\n\nMatches the git_merge_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nflags: an enum for flags describing merge behavior. Defined in git_merge_flag_t. The corresponding Julia enum is GIT_MERGE and has values:\nMERGE_FIND_RENAMES: detect if a file has been renamed between the common ancestor and the \"ours\" or \"theirs\" side of the merge. Allows merges where a file has been renamed.\nMERGE_FAIL_ON_CONFLICT: exit immediately if a conflict is found rather than trying to resolve it.\nMERGE_SKIP_REUC: do not write the REUC extension on the index resulting from the merge.\nMERGE_NO_RECURSIVE: if the commits being merged have multiple merge bases, use the first one, rather than trying to recursively merge the bases.\nrename_threshold: how similar two files must to consider one a rename of the other. This is an integer that sets the percentage similarity. The default is 50.\ntarget_limit: the maximum number of files to compare with to look for renames. The default is 200.\nmetric: optional custom function to use to determine the similarity between two files for rename detection.\nrecursion_limit: the upper limit on the number of merges of common ancestors to perform to try to build a new virtual merge base for the merge. The default is no limit. This field is only present on libgit2 versions newer than 0.24.0.\ndefault_driver: the merge driver to use if both sides have changed. This field is only present on libgit2 versions newer than 0.25.0.\nfile_favor: how to handle conflicting file contents for the text driver.\nMERGE_FILE_FAVOR_NORMAL: if both sides of the merge have changes to a section, make a note of the conflict in the index which git checkout will use to create a merge file, which the user can then reference to resolve the conflicts. This is the default.\nMERGE_FILE_FAVOR_OURS: if both sides of the merge have changes to a section, use the version in the \"ours\" side of the merge in the index.\nMERGE_FILE_FAVOR_THEIRS: if both sides of the merge have changes to a section, use the version in the \"theirs\" side of the merge in the index.\nMERGE_FILE_FAVOR_UNION: if both sides of the merge have changes to a section, include each unique line from both sides in the file which is put into the index.\nfile_flags: guidelines for merging files.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.ProxyOptions","page":"LibGit2","title":"LibGit2.ProxyOptions","text":"LibGit2.ProxyOptions\n\nOptions for connecting through a proxy.\n\nMatches the git_proxy_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nproxytype: an enum for the type of proxy to use. Defined in git_proxy_t. The corresponding Julia enum is GIT_PROXY and has values:\nPROXY_NONE: do not attempt the connection through a proxy.\nPROXY_AUTO: attempt to figure out the proxy configuration from the git configuration.\nPROXY_SPECIFIED: connect using the URL given in the url field of this struct.\nDefault is to auto-detect the proxy type.\nurl: the URL of the proxy.\ncredential_cb: a pointer to a callback function which will be called if the remote requires authentication to connect.\ncertificate_cb: a pointer to a callback function which will be called if certificate verification fails. This lets the user decide whether or not to keep connecting. If the function returns 1, connecting will be allowed. If it returns 0, the connection will not be allowed. A negative value can be used to return errors.\npayload: the payload to be provided to the two callback functions.\n\nExamples\n\njulia> fo = LibGit2.FetchOptions(\n proxy_opts = LibGit2.ProxyOptions(url = Cstring(\"https://my_proxy_url.com\")))\n\njulia> fetch(remote, \"master\", options=fo)\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.PushOptions","page":"LibGit2","title":"LibGit2.PushOptions","text":"LibGit2.PushOptions\n\nMatches the git_push_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nparallelism: if a pack file must be created, this variable sets the number of worker threads which will be spawned by the packbuilder. If 0, the packbuilder will auto-set the number of threads to use. The default is 1.\ncallbacks: the callbacks (e.g. for authentication with the remote) to use for the push.\nproxy_opts: only relevant if the LibGit2 version is greater than or equal to 0.25.0. Sets options for using a proxy to communicate with a remote. See ProxyOptions for more information.\ncustom_headers: only relevant if the LibGit2 version is greater than or equal to 0.24.0. Extra headers needed for the push operation.\nremote_push_options: only relevant if the LibGit2 version is greater than or equal to 1.8.0. \"Push options\" to deliver to the remote.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.RebaseOperation","page":"LibGit2","title":"LibGit2.RebaseOperation","text":"LibGit2.RebaseOperation\n\nDescribes a single instruction/operation to be performed during the rebase. Matches the git_rebase_operation struct.\n\nThe fields represent:\n\noptype: the type of rebase operation currently being performed. The options are:\nREBASE_OPERATION_PICK: cherry-pick the commit in question.\nREBASE_OPERATION_REWORD: cherry-pick the commit in question, but rewrite its message using the prompt.\nREBASE_OPERATION_EDIT: cherry-pick the commit in question, but allow the user to edit the commit's contents and its message.\nREBASE_OPERATION_SQUASH: squash the commit in question into the previous commit. The commit messages of the two commits will be merged.\nREBASE_OPERATION_FIXUP: squash the commit in question into the previous commit. Only the commit message of the previous commit will be used.\nREBASE_OPERATION_EXEC: do not cherry-pick a commit. Run a command and continue if the command exits successfully.\nid: the GitHash of the commit being worked on during this rebase step.\nexec: in case REBASE_OPERATION_EXEC is used, the command to run during this step (for instance, running the test suite after each commit).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.RebaseOptions","page":"LibGit2","title":"LibGit2.RebaseOptions","text":"LibGit2.RebaseOptions\n\nMatches the git_rebase_options struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nquiet: inform other git clients helping with/working on the rebase that the rebase should be done \"quietly\". Used for interoperability. The default is 1.\ninmemory: start an in-memory rebase. Callers working on the rebase can go through its steps and commit any changes, but cannot rewind HEAD or update the repository. The workdir will not be modified. Only present on libgit2 versions newer than or equal to 0.24.0.\nrewrite_notes_ref: name of the reference to notes to use to rewrite the commit notes as the rebase is finished.\nmerge_opts: merge options controlling how the trees will be merged at each rebase step. Only present on libgit2 versions newer than or equal to 0.24.0.\ncheckout_opts: checkout options for writing files when initializing the rebase, stepping through it, and aborting it. See CheckoutOptions for more information.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.RemoteCallbacks","page":"LibGit2","title":"LibGit2.RemoteCallbacks","text":"LibGit2.RemoteCallbacks\n\nCallback settings. Matches the git_remote_callbacks struct.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.SignatureStruct","page":"LibGit2","title":"LibGit2.SignatureStruct","text":"LibGit2.SignatureStruct\n\nAn action signature (e.g. for committers, taggers, etc). Matches the git_signature struct.\n\nThe fields represent:\n\nname: The full name of the committer or author of the commit.\nemail: The email at which the committer/author can be contacted.\nwhen: a TimeStruct indicating when the commit was authored/committed into the repository.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.StatusEntry","page":"LibGit2","title":"LibGit2.StatusEntry","text":"LibGit2.StatusEntry\n\nProviding the differences between the file as it exists in HEAD and the index, and providing the differences between the index and the working directory. Matches the git_status_entry struct.\n\nThe fields represent:\n\nstatus: contains the status flags for the file, indicating if it is current, or has been changed in some way in the index or work tree.\nhead_to_index: a pointer to a DiffDelta which encapsulates the difference(s) between the file as it exists in HEAD and in the index.\nindex_to_workdir: a pointer to a DiffDelta which encapsulates the difference(s) between the file as it exists in the index and in the workdir.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.StatusOptions","page":"LibGit2","title":"LibGit2.StatusOptions","text":"LibGit2.StatusOptions\n\nOptions to control how git_status_foreach_ext() will issue callbacks. Matches the git_status_opt_t struct.\n\nThe fields represent:\n\nversion: version of the struct in use, in case this changes later. For now, always 1.\nshow: a flag for which files to examine and in which order. The default is Consts.STATUS_SHOW_INDEX_AND_WORKDIR.\nflags: flags for controlling any callbacks used in a status call.\npathspec: an array of paths to use for path-matching. The behavior of the path-matching will vary depending on the values of show and flags.\nThe baseline is the tree to be used for comparison to the working directory and index; defaults to HEAD.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.StrArrayStruct","page":"LibGit2","title":"LibGit2.StrArrayStruct","text":"LibGit2.StrArrayStruct\n\nA LibGit2 representation of an array of strings. Matches the git_strarray struct.\n\nWhen fetching data from LibGit2, a typical usage would look like:\n\nsa_ref = Ref(StrArrayStruct())\n@check ccall(..., (Ptr{StrArrayStruct},), sa_ref)\nres = convert(Vector{String}, sa_ref[])\nfree(sa_ref)\n\nIn particular, note that LibGit2.free should be called afterward on the Ref object.\n\nConversely, when passing a vector of strings to LibGit2, it is generally simplest to rely on implicit conversion:\n\nstrs = String[...]\n@check ccall(..., (Ptr{StrArrayStruct},), strs)\n\nNote that no call to free is required as the data is allocated by Julia.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.TimeStruct","page":"LibGit2","title":"LibGit2.TimeStruct","text":"LibGit2.TimeStruct\n\nTime in a signature. Matches the git_time struct.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.addfile","page":"LibGit2","title":"LibGit2.addfile","text":"addfile(cfg::GitConfig, path::AbstractString,\n level::Consts.GIT_CONFIG=Consts.CONFIG_LEVEL_APP,\n repo::Union{GitRepo, Nothing} = nothing,\n force::Bool=false)\n\nAdd an existing git configuration file located at path to the current GitConfig cfg. If the file does not exist, it will be created.\n\nlevel sets the git configuration priority level and is determined by\n\nConsts.GIT_CONFIG.\n\nrepo is an optional repository to allow parsing of conditional includes.\nIf force is false and a configuration for the given priority level already exists,\n\naddfile will error. If force is true, the existing configuration will be replaced by the one in the file at path.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.add!","page":"LibGit2","title":"LibGit2.add!","text":"add!(repo::GitRepo, files::AbstractString...; flags::Cuint = Consts.INDEX_ADD_DEFAULT)\nadd!(idx::GitIndex, files::AbstractString...; flags::Cuint = Consts.INDEX_ADD_DEFAULT)\n\nAdd all the files with paths specified by files to the index idx (or the index of the repo). If the file already exists, the index entry will be updated. If the file does not exist already, it will be newly added into the index. files may contain glob patterns which will be expanded and any matching files will be added (unless INDEX_ADD_DISABLE_PATHSPEC_MATCH is set, see below). If a file has been ignored (in .gitignore or in the config), it will not be added, unless it is already being tracked in the index, in which case it will be updated. The keyword argument flags is a set of bit-flags which control the behavior with respect to ignored files:\n\nConsts.INDEX_ADD_DEFAULT - default, described above.\nConsts.INDEX_ADD_FORCE - disregard the existing ignore rules and force addition of the file to the index even if it is already ignored.\nConsts.INDEX_ADD_CHECK_PATHSPEC - cannot be used at the same time as INDEX_ADD_FORCE. Check that each file in files which exists on disk is not in the ignore list. If one of the files is ignored, the function will return EINVALIDSPEC.\nConsts.INDEX_ADD_DISABLE_PATHSPEC_MATCH - turn off glob matching, and only add files to the index which exactly match the paths specified in files.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.add_fetch!","page":"LibGit2","title":"LibGit2.add_fetch!","text":"add_fetch!(repo::GitRepo, rmt::GitRemote, fetch_spec::String)\n\nAdd a fetch refspec for the specified rmt. This refspec will contain information about which branch(es) to fetch from.\n\nExamples\n\njulia> LibGit2.add_fetch!(repo, remote, \"upstream\");\n\njulia> LibGit2.fetch_refspecs(remote)\nString[\"+refs/heads/*:refs/remotes/upstream/*\"]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.add_push!","page":"LibGit2","title":"LibGit2.add_push!","text":"add_push!(repo::GitRepo, rmt::GitRemote, push_spec::String)\n\nAdd a push refspec for the specified rmt. This refspec will contain information about which branch(es) to push to.\n\nExamples\n\njulia> LibGit2.add_push!(repo, remote, \"refs/heads/master\");\n\njulia> remote = LibGit2.get(LibGit2.GitRemote, repo, branch);\n\njulia> LibGit2.push_refspecs(remote)\nString[\"refs/heads/master\"]\n\nnote: Note\nYou may need to close and reopen the GitRemote in question after updating its push refspecs in order for the change to take effect and for calls to push to work.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.addblob!","page":"LibGit2","title":"LibGit2.addblob!","text":"LibGit2.addblob!(repo::GitRepo, path::AbstractString)\n\nRead the file at path and adds it to the object database of repo as a loose blob. Return the GitHash of the resulting blob.\n\nExamples\n\nhash_str = string(commit_oid)\nblob_file = joinpath(repo_path, \".git\", \"objects\", hash_str[1:2], hash_str[3:end])\nid = LibGit2.addblob!(repo, blob_file)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.author","page":"LibGit2","title":"LibGit2.author","text":"author(c::GitCommit)\n\nReturn the Signature of the author of the commit c. The author is the person who made changes to the relevant file(s). See also committer.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.authors","page":"LibGit2","title":"LibGit2.authors","text":"authors(repo::GitRepo) -> Vector{Signature}\n\nReturn all authors of commits to the repo repository.\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nrepo_file = open(joinpath(repo_path, test_file), \"a\")\n\nprintln(repo_file, commit_msg)\nflush(repo_file)\nLibGit2.add!(repo, test_file)\nsig = LibGit2.Signature(\"TEST\", \"TEST@TEST.COM\", round(time(), 0), 0)\ncommit_oid1 = LibGit2.commit(repo, \"commit1\"; author=sig, committer=sig)\nprintln(repo_file, randstring(10))\nflush(repo_file)\nLibGit2.add!(repo, test_file)\ncommit_oid2 = LibGit2.commit(repo, \"commit2\"; author=sig, committer=sig)\n\n# will be a Vector of [sig, sig]\nauths = LibGit2.authors(repo)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.branch","page":"LibGit2","title":"LibGit2.branch","text":"branch(repo::GitRepo)\n\nEquivalent to git branch. Create a new branch from the current HEAD.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.branch!","page":"LibGit2","title":"LibGit2.branch!","text":"branch!(repo::GitRepo, branch_name::AbstractString, commit::AbstractString=\"\"; kwargs...)\n\nCheckout a new git branch in the repo repository. commit is the GitHash, in string form, which will be the start of the new branch. If commit is an empty string, the current HEAD will be used.\n\nThe keyword arguments are:\n\ntrack::AbstractString=\"\": the name of the remote branch this new branch should track, if any. If empty (the default), no remote branch will be tracked.\nforce::Bool=false: if true, branch creation will be forced.\nset_head::Bool=true: if true, after the branch creation finishes the branch head will be set as the HEAD of repo.\n\nEquivalent to git checkout [-b|-B] [] [--track ].\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nLibGit2.branch!(repo, \"new_branch\", set_head=false)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.checkout!","page":"LibGit2","title":"LibGit2.checkout!","text":"checkout!(repo::GitRepo, commit::AbstractString=\"\"; force::Bool=true)\n\nEquivalent to git checkout [-f] --detach . Checkout the git commit commit (a GitHash in string form) in repo. If force is true, force the checkout and discard any current changes. Note that this detaches the current HEAD.\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nopen(joinpath(LibGit2.path(repo), \"file1\"), \"w\") do f\n write(f, \"111\n\")\nend\nLibGit2.add!(repo, \"file1\")\ncommit_oid = LibGit2.commit(repo, \"add file1\")\nopen(joinpath(LibGit2.path(repo), \"file1\"), \"w\") do f\n write(f, \"112\n\")\nend\n# would fail without the force=true\n# since there are modifications to the file\nLibGit2.checkout!(repo, string(commit_oid), force=true)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.clone","page":"LibGit2","title":"LibGit2.clone","text":"clone(repo_url::AbstractString, repo_path::AbstractString, clone_opts::CloneOptions)\n\nClone the remote repository at repo_url (which can be a remote URL or a path on the local filesystem) to repo_path (which must be a path on the local filesystem). Options for the clone, such as whether to perform a bare clone or not, are set by CloneOptions.\n\nExamples\n\nrepo_url = \"https://github.com/JuliaLang/Example.jl\"\nrepo = LibGit2.clone(repo_url, \"/home/me/projects/Example\")\n\n\n\n\n\nclone(repo_url::AbstractString, repo_path::AbstractString; kwargs...)\n\nClone a remote repository located at repo_url to the local filesystem location repo_path.\n\nThe keyword arguments are:\n\nbranch::AbstractString=\"\": which branch of the remote to clone, if not the default repository branch (usually master).\nisbare::Bool=false: if true, clone the remote as a bare repository, which will make repo_path itself the git directory instead of repo_path/.git. This means that a working tree cannot be checked out. Plays the role of the git CLI argument --bare.\nremote_cb::Ptr{Cvoid}=C_NULL: a callback which will be used to create the remote before it is cloned. If C_NULL (the default), no attempt will be made to create the remote - it will be assumed to already exist.\ncredentials::Creds=nothing: provides credentials and/or settings when authenticating against a private repository.\ncallbacks::Callbacks=Callbacks(): user provided callbacks and payloads.\n\nEquivalent to git clone [-b ] [--bare] .\n\nExamples\n\nrepo_url = \"https://github.com/JuliaLang/Example.jl\"\nrepo1 = LibGit2.clone(repo_url, \"test_path\")\nrepo2 = LibGit2.clone(repo_url, \"test_path\", isbare=true)\njulia_url = \"https://github.com/JuliaLang/julia\"\njulia_repo = LibGit2.clone(julia_url, \"julia_path\", branch=\"release-0.6\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.commit","page":"LibGit2","title":"LibGit2.commit","text":"commit(repo::GitRepo, msg::AbstractString; kwargs...) -> GitHash\n\nWrapper around git_commit_create. Create a commit in the repository repo. msg is the commit message. Return the OID of the new commit.\n\nThe keyword arguments are:\n\nrefname::AbstractString=Consts.HEAD_FILE: if not NULL, the name of the reference to update to point to the new commit. For example, \"HEAD\" will update the HEAD of the current branch. If the reference does not yet exist, it will be created.\nauthor::Signature = Signature(repo) is a Signature containing information about the person who authored the commit.\ncommitter::Signature = Signature(repo) is a Signature containing information about the person who committed the commit to the repository. Not necessarily the same as author, for instance if author emailed a patch to committer who committed it.\ntree_id::GitHash = GitHash() is a git tree to use to create the commit, showing its ancestry and relationship with any other history. tree must belong to repo.\nparent_ids::Vector{GitHash}=GitHash[] is a list of commits by GitHash to use as parent commits for the new one, and may be empty. A commit might have multiple parents if it is a merge commit, for example.\n\n\n\n\n\nLibGit2.commit(rb::GitRebase, sig::GitSignature)\n\nCommit the current patch to the rebase rb, using sig as the committer. Is silent if the commit has already been applied.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.committer","page":"LibGit2","title":"LibGit2.committer","text":"committer(c::GitCommit)\n\nReturn the Signature of the committer of the commit c. The committer is the person who committed the changes originally authored by the author, but need not be the same as the author, for example, if the author emailed a patch to a committer who committed it.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.count","page":"LibGit2","title":"LibGit2.count","text":"LibGit2.count(f::Function, walker::GitRevWalker; oid::GitHash=GitHash(), by::Cint=Consts.SORT_NONE, rev::Bool=false)\n\nUsing the GitRevWalker walker to \"walk\" over every commit in the repository's history, find the number of commits which return true when f is applied to them. The keyword arguments are: * oid: The GitHash of the commit to begin the walk from. The default is to use push_head! and therefore the HEAD commit and all its ancestors. * by: The sorting method. The default is not to sort. Other options are to sort by topology (LibGit2.Consts.SORT_TOPOLOGICAL), to sort forwards in time (LibGit2.Consts.SORT_TIME, most ancient first) or to sort backwards in time (LibGit2.Consts.SORT_REVERSE, most recent first). * rev: Whether to reverse the sorted order (for instance, if topological sorting is used).\n\nExamples\n\ncnt = LibGit2.with(LibGit2.GitRevWalker(repo)) do walker\n LibGit2.count((oid, repo)->(oid == commit_oid1), walker, oid=commit_oid1, by=LibGit2.Consts.SORT_TIME)\nend\n\nLibGit2.count finds the number of commits along the walk with a certain GitHash commit_oid1, starting the walk from that commit and moving forwards in time from it. Since the GitHash is unique to a commit, cnt will be 1.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.counthunks","page":"LibGit2","title":"LibGit2.counthunks","text":"counthunks(blame::GitBlame)\n\nReturn the number of distinct \"hunks\" with a file. A hunk may contain multiple lines. A hunk is usually a piece of a file that was added/changed/removed together, for example, a function added to a source file or an inner loop that was optimized out of that function later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.create_branch","page":"LibGit2","title":"LibGit2.create_branch","text":"LibGit2.create_branch(repo::GitRepo, bname::AbstractString, commit_obj::GitCommit; force::Bool=false)\n\nCreate a new branch in the repository repo with name bname, which points to commit commit_obj (which has to be part of repo). If force is true, overwrite an existing branch named bname if it exists. If force is false and a branch already exists named bname, this function will throw an error.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.credentials_callback","page":"LibGit2","title":"LibGit2.credentials_callback","text":"credential_callback(...) -> Cint\n\nA LibGit2 credential callback function which provides different credential acquisition functionality w.r.t. a connection protocol. The payload_ptr is required to contain a LibGit2.CredentialPayload object which will keep track of state and settings.\n\nThe allowed_types contains a bitmask of LibGit2.Consts.GIT_CREDTYPE values specifying which authentication methods should be attempted.\n\nCredential authentication is done in the following order (if supported):\n\nSSH agent\nSSH private/public key pair\nUsername/password plain text\n\nIf a user is presented with a credential prompt they can abort the prompt by typing ^D (pressing the control key together with the d key).\n\nNote: Due to the specifics of the libgit2 authentication procedure, when authentication fails, this function is called again without any indication whether authentication was successful or not. To avoid an infinite loop from repeatedly using the same faulty credentials, we will keep track of state using the payload.\n\nFor addition details see the LibGit2 guide on authenticating against a server.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.credentials_cb","page":"LibGit2","title":"LibGit2.credentials_cb","text":"C function pointer for credentials_callback\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.default_signature","page":"LibGit2","title":"LibGit2.default_signature","text":"Return signature object. Free it after use.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.delete_branch","page":"LibGit2","title":"LibGit2.delete_branch","text":"LibGit2.delete_branch(branch::GitReference)\n\nDelete the branch pointed to by branch.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.diff_files","page":"LibGit2","title":"LibGit2.diff_files","text":"diff_files(repo::GitRepo, branch1::AbstractString, branch2::AbstractString; kwarg...) -> Vector{AbstractString}\n\nShow which files have changed in the git repository repo between branches branch1 and branch2.\n\nThe keyword argument is:\n\nfilter::Set{Consts.DELTA_STATUS}=Set([Consts.DELTA_ADDED, Consts.DELTA_MODIFIED, Consts.DELTA_DELETED])), and it sets options for the diff. The default is to show files added, modified, or deleted.\n\nReturn only the names of the files which have changed, not their contents.\n\nExamples\n\nLibGit2.branch!(repo, \"branch/a\")\nLibGit2.branch!(repo, \"branch/b\")\n# add a file to repo\nopen(joinpath(LibGit2.path(repo),\"file\"),\"w\") do f\n write(f, \"hello repo\n\")\nend\nLibGit2.add!(repo, \"file\")\nLibGit2.commit(repo, \"add file\")\n# returns [\"file\"]\nfilt = Set([LibGit2.Consts.DELTA_ADDED])\nfiles = LibGit2.diff_files(repo, \"branch/a\", \"branch/b\", filter=filt)\n# returns [] because existing files weren't modified\nfilt = Set([LibGit2.Consts.DELTA_MODIFIED])\nfiles = LibGit2.diff_files(repo, \"branch/a\", \"branch/b\", filter=filt)\n\nEquivalent to git diff --name-only --diff-filter= .\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.entryid","page":"LibGit2","title":"LibGit2.entryid","text":"entryid(te::GitTreeEntry)\n\nReturn the GitHash of the object to which te refers.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.entrytype","page":"LibGit2","title":"LibGit2.entrytype","text":"entrytype(te::GitTreeEntry)\n\nReturn the type of the object to which te refers. The result will be one of the types which objtype returns, e.g. a GitTree or GitBlob.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fetch","page":"LibGit2","title":"LibGit2.fetch","text":"fetch(rmt::GitRemote, refspecs; options::FetchOptions=FetchOptions(), msg=\"\")\n\nFetch from the specified rmt remote git repository, using refspecs to determine which remote branch(es) to fetch. The keyword arguments are:\n\noptions: determines the options for the fetch, e.g. whether to prune afterwards. See FetchOptions for more information.\nmsg: a message to insert into the reflogs.\n\n\n\n\n\nfetch(repo::GitRepo; kwargs...)\n\nFetches updates from an upstream of the repository repo.\n\nThe keyword arguments are:\n\nremote::AbstractString=\"origin\": which remote, specified by name, of repo to fetch from. If this is empty, the URL will be used to construct an anonymous remote.\nremoteurl::AbstractString=\"\": the URL of remote. If not specified, will be assumed based on the given name of remote.\nrefspecs=AbstractString[]: determines properties of the fetch.\ncredentials=nothing: provides credentials and/or settings when authenticating against a private remote.\ncallbacks=Callbacks(): user provided callbacks and payloads.\n\nEquivalent to git fetch [|] [].\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fetchheads","page":"LibGit2","title":"LibGit2.fetchheads","text":"fetchheads(repo::GitRepo) -> Vector{FetchHead}\n\nReturn the list of all the fetch heads for repo, each represented as a FetchHead, including their names, URLs, and merge statuses.\n\nExamples\n\njulia> fetch_heads = LibGit2.fetchheads(repo);\n\njulia> fetch_heads[1].name\n\"refs/heads/master\"\n\njulia> fetch_heads[1].ismerge\ntrue\n\njulia> fetch_heads[2].name\n\"refs/heads/test_branch\"\n\njulia> fetch_heads[2].ismerge\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fetch_refspecs","page":"LibGit2","title":"LibGit2.fetch_refspecs","text":"fetch_refspecs(rmt::GitRemote) -> Vector{String}\n\nGet the fetch refspecs for the specified rmt. These refspecs contain information about which branch(es) to fetch from.\n\nExamples\n\njulia> remote = LibGit2.get(LibGit2.GitRemote, repo, \"upstream\");\n\njulia> LibGit2.add_fetch!(repo, remote, \"upstream\");\n\njulia> LibGit2.fetch_refspecs(remote)\nString[\"+refs/heads/*:refs/remotes/upstream/*\"]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fetchhead_foreach_cb","page":"LibGit2","title":"LibGit2.fetchhead_foreach_cb","text":"C function pointer for fetchhead_foreach_callback\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.merge_base","page":"LibGit2","title":"LibGit2.merge_base","text":"merge_base(repo::GitRepo, one::AbstractString, two::AbstractString) -> GitHash\n\nFind a merge base (a common ancestor) between the commits one and two. one and two may both be in string form. Return the GitHash of the merge base.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.merge!-Tuple{GitRepo}","page":"LibGit2","title":"LibGit2.merge!","text":"merge!(repo::GitRepo; kwargs...) -> Bool\n\nPerform a git merge on the repository repo, merging commits with diverging history into the current branch. Return true if the merge succeeded, false if not.\n\nThe keyword arguments are:\n\ncommittish::AbstractString=\"\": Merge the named commit(s) in committish.\nbranch::AbstractString=\"\": Merge the branch branch and all its commits since it diverged from the current branch.\nfastforward::Bool=false: If fastforward is true, only merge if the merge is a fast-forward (the current branch head is an ancestor of the commits to be merged), otherwise refuse to merge and return false. This is equivalent to the git CLI option --ff-only.\nmerge_opts::MergeOptions=MergeOptions(): merge_opts specifies options for the merge, such as merge strategy in case of conflicts.\ncheckout_opts::CheckoutOptions=CheckoutOptions(): checkout_opts specifies options for the checkout step.\n\nEquivalent to git merge [--ff-only] [ | ].\n\nnote: Note\nIf you specify a branch, this must be done in reference format, since the string will be turned into a GitReference. For example, if you wanted to merge branch branch_a, you would call merge!(repo, branch=\"refs/heads/branch_a\").\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.merge!-Tuple{GitRepo, Vector{LibGit2.GitAnnotated}}","page":"LibGit2","title":"LibGit2.merge!","text":"merge!(repo::GitRepo, anns::Vector{GitAnnotated}; kwargs...) -> Bool\n\nMerge changes from the annotated commits (captured as GitAnnotated objects) anns into the HEAD of the repository repo. The keyword arguments are:\n\nmerge_opts::MergeOptions = MergeOptions(): options for how to perform the merge, including whether fastforwarding is allowed. See MergeOptions for more information.\ncheckout_opts::CheckoutOptions = CheckoutOptions(): options for how to perform the checkout. See CheckoutOptions for more information.\n\nanns may refer to remote or local branch heads. Return true if the merge is successful, otherwise return false (for instance, if no merge is possible because the branches have no common ancestor).\n\nExamples\n\nupst_ann = LibGit2.GitAnnotated(repo, \"branch/a\")\n\n# merge the branch in\nLibGit2.merge!(repo, [upst_ann])\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.merge!-Tuple{GitRepo, Vector{LibGit2.GitAnnotated}, Bool}","page":"LibGit2","title":"LibGit2.merge!","text":"merge!(repo::GitRepo, anns::Vector{GitAnnotated}, fastforward::Bool; kwargs...) -> Bool\n\nMerge changes from the annotated commits (captured as GitAnnotated objects) anns into the HEAD of the repository repo. If fastforward is true, only a fastforward merge is allowed. In this case, if conflicts occur, the merge will fail. Otherwise, if fastforward is false, the merge may produce a conflict file which the user will need to resolve.\n\nThe keyword arguments are:\n\nmerge_opts::MergeOptions = MergeOptions(): options for how to perform the merge, including whether fastforwarding is allowed. See MergeOptions for more information.\ncheckout_opts::CheckoutOptions = CheckoutOptions(): options for how to perform the checkout. See CheckoutOptions for more information.\n\nanns may refer to remote or local branch heads. Return true if the merge is successful, otherwise return false (for instance, if no merge is possible because the branches have no common ancestor).\n\nExamples\n\nupst_ann_1 = LibGit2.GitAnnotated(repo, \"branch/a\")\n\n# merge the branch in, fastforward\nLibGit2.merge!(repo, [upst_ann_1], true)\n\n# merge conflicts!\nupst_ann_2 = LibGit2.GitAnnotated(repo, \"branch/b\")\n# merge the branch in, try to fastforward\nLibGit2.merge!(repo, [upst_ann_2], true) # will return false\nLibGit2.merge!(repo, [upst_ann_2], false) # will return true\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.ffmerge!","page":"LibGit2","title":"LibGit2.ffmerge!","text":"ffmerge!(repo::GitRepo, ann::GitAnnotated)\n\nFastforward merge changes into current HEAD. This is only possible if the commit referred to by ann is descended from the current HEAD (e.g. if pulling changes from a remote branch which is simply ahead of the local branch tip).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.fullname","page":"LibGit2","title":"LibGit2.fullname","text":"LibGit2.fullname(ref::GitReference)\n\nReturn the name of the reference pointed to by the symbolic reference ref. If ref is not a symbolic reference, return an empty string.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.features","page":"LibGit2","title":"LibGit2.features","text":"features()\n\nReturn a list of git features the current version of libgit2 supports, such as threading or using HTTPS or SSH.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.filename","page":"LibGit2","title":"LibGit2.filename","text":"filename(te::GitTreeEntry)\n\nReturn the filename of the object on disk to which te refers.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.filemode","page":"LibGit2","title":"LibGit2.filemode","text":"filemode(te::GitTreeEntry) -> Cint\n\nReturn the UNIX filemode of the object on disk to which te refers as an integer.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.gitdir","page":"LibGit2","title":"LibGit2.gitdir","text":"LibGit2.gitdir(repo::GitRepo)\n\nReturn the location of the \"git\" files of repo:\n\nfor normal repositories, this is the location of the .git folder.\nfor bare repositories, this is the location of the repository itself.\n\nSee also workdir, path.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.git_url","page":"LibGit2","title":"LibGit2.git_url","text":"LibGit2.git_url(; kwargs...) -> String\n\nCreate a string based upon the URL components provided. When the scheme keyword is not provided the URL produced will use the alternative scp-like syntax.\n\nKeywords\n\nscheme::AbstractString=\"\": the URL scheme which identifies the protocol to be used. For HTTP use \"http\", SSH use \"ssh\", etc. When scheme is not provided the output format will be \"ssh\" but using the scp-like syntax.\nusername::AbstractString=\"\": the username to use in the output if provided.\npassword::AbstractString=\"\": the password to use in the output if provided.\nhost::AbstractString=\"\": the hostname to use in the output. A hostname is required to be specified.\nport::Union{AbstractString,Integer}=\"\": the port number to use in the output if provided. Cannot be specified when using the scp-like syntax.\npath::AbstractString=\"\": the path to use in the output if provided.\n\nwarning: Warning\nAvoid using passwords in URLs. Unlike the credential objects, Julia is not able to securely zero or destroy the sensitive data after use and the password may remain in memory; possibly to be exposed by an uninitialized memory.\n\nExamples\n\njulia> LibGit2.git_url(username=\"git\", host=\"github.com\", path=\"JuliaLang/julia.git\")\n\"git@github.com:JuliaLang/julia.git\"\n\njulia> LibGit2.git_url(scheme=\"https\", host=\"github.com\", path=\"/JuliaLang/julia.git\")\n\"https://github.com/JuliaLang/julia.git\"\n\njulia> LibGit2.git_url(scheme=\"ssh\", username=\"git\", host=\"github.com\", port=2222, path=\"JuliaLang/julia.git\")\n\"ssh://git@github.com:2222/JuliaLang/julia.git\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.@githash_str","page":"LibGit2","title":"LibGit2.@githash_str","text":"@githash_str -> AbstractGitHash\n\nConstruct a git hash object from the given string, returning a GitShortHash if the string is shorter than 40 hexadecimal digits, otherwise a GitHash.\n\nExamples\n\njulia> LibGit2.githash\"d114feb74ce633\"\nGitShortHash(\"d114feb74ce633\")\n\njulia> LibGit2.githash\"d114feb74ce63307afe878a5228ad014e0289a85\"\nGitHash(\"d114feb74ce63307afe878a5228ad014e0289a85\")\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/LibGit2/#LibGit2.head","page":"LibGit2","title":"LibGit2.head","text":"LibGit2.head(repo::GitRepo) -> GitReference\n\nReturn a GitReference to the current HEAD of repo.\n\n\n\n\n\nhead(pkg::AbstractString) -> String\n\nReturn current HEAD GitHash of the pkg repo as a string.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.head!","page":"LibGit2","title":"LibGit2.head!","text":"LibGit2.head!(repo::GitRepo, ref::GitReference) -> GitReference\n\nSet the HEAD of repo to the object pointed to by ref.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.head_oid","page":"LibGit2","title":"LibGit2.head_oid","text":"LibGit2.head_oid(repo::GitRepo) -> GitHash\n\nLookup the object id of the current HEAD of git repository repo.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.headname","page":"LibGit2","title":"LibGit2.headname","text":"LibGit2.headname(repo::GitRepo)\n\nLookup the name of the current HEAD of git repository repo. If repo is currently detached, return the name of the HEAD it's detached from.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.init","page":"LibGit2","title":"LibGit2.init","text":"LibGit2.init(path::AbstractString, bare::Bool=false) -> GitRepo\n\nOpen a new git repository at path. If bare is false, the working tree will be created in path/.git. If bare is true, no working directory will be created.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.is_ancestor_of","page":"LibGit2","title":"LibGit2.is_ancestor_of","text":"is_ancestor_of(a::AbstractString, b::AbstractString, repo::GitRepo) -> Bool\n\nReturn true if a, a GitHash in string form, is an ancestor of b, a GitHash in string form.\n\nExamples\n\njulia> repo = GitRepo(repo_path);\n\njulia> LibGit2.add!(repo, test_file1);\n\njulia> commit_oid1 = LibGit2.commit(repo, \"commit1\");\n\njulia> LibGit2.add!(repo, test_file2);\n\njulia> commit_oid2 = LibGit2.commit(repo, \"commit2\");\n\njulia> LibGit2.is_ancestor_of(string(commit_oid1), string(commit_oid2), repo)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isbinary","page":"LibGit2","title":"LibGit2.isbinary","text":"isbinary(blob::GitBlob) -> Bool\n\nUse a heuristic to guess if a file is binary: searching for NULL bytes and looking for a reasonable ratio of printable to non-printable characters among the first 8000 bytes.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.iscommit","page":"LibGit2","title":"LibGit2.iscommit","text":"iscommit(id::AbstractString, repo::GitRepo) -> Bool\n\nCheck if commit id (which is a GitHash in string form) is in the repository.\n\nExamples\n\njulia> repo = GitRepo(repo_path);\n\njulia> LibGit2.add!(repo, test_file);\n\njulia> commit_oid = LibGit2.commit(repo, \"add test_file\");\n\njulia> LibGit2.iscommit(string(commit_oid), repo)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isdiff","page":"LibGit2","title":"LibGit2.isdiff","text":"LibGit2.isdiff(repo::GitRepo, treeish::AbstractString, pathspecs::AbstractString=\"\"; cached::Bool=false)\n\nChecks if there are any differences between the tree specified by treeish and the tracked files in the working tree (if cached=false) or the index (if cached=true). pathspecs are the specifications for options for the diff.\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nLibGit2.isdiff(repo, \"HEAD\") # should be false\nopen(joinpath(repo_path, new_file), \"a\") do f\n println(f, \"here's my cool new file\")\nend\nLibGit2.isdiff(repo, \"HEAD\") # now true\n\nEquivalent to git diff-index [-- ].\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isdirty","page":"LibGit2","title":"LibGit2.isdirty","text":"LibGit2.isdirty(repo::GitRepo, pathspecs::AbstractString=\"\"; cached::Bool=false) -> Bool\n\nCheck if there have been any changes to tracked files in the working tree (if cached=false) or the index (if cached=true). pathspecs are the specifications for options for the diff.\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nLibGit2.isdirty(repo) # should be false\nopen(joinpath(repo_path, new_file), \"a\") do f\n println(f, \"here's my cool new file\")\nend\nLibGit2.isdirty(repo) # now true\nLibGit2.isdirty(repo, new_file) # now true\n\nEquivalent to git diff-index HEAD [-- ].\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isorphan","page":"LibGit2","title":"LibGit2.isorphan","text":"LibGit2.isorphan(repo::GitRepo)\n\nCheck if the current branch is an \"orphan\" branch, i.e. has no commits. The first commit to this branch will have no parents.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.isset","page":"LibGit2","title":"LibGit2.isset","text":"isset(val::Integer, flag::Integer)\n\nTest whether the bits of val indexed by flag are set (1) or unset (0).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.iszero","page":"LibGit2","title":"LibGit2.iszero","text":"iszero(id::GitHash) -> Bool\n\nDetermine whether all hexadecimal digits of the given GitHash are zero.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.lookup_branch","page":"LibGit2","title":"LibGit2.lookup_branch","text":"lookup_branch(repo::GitRepo, branch_name::AbstractString, remote::Bool=false) -> Union{GitReference, Nothing}\n\nDetermine if the branch specified by branch_name exists in the repository repo. If remote is true, repo is assumed to be a remote git repository. Otherwise, it is part of the local filesystem.\n\nReturn either a GitReference to the requested branch if it exists, or nothing if not.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.map","page":"LibGit2","title":"LibGit2.map","text":"LibGit2.map(f::Function, walker::GitRevWalker; oid::GitHash=GitHash(), range::AbstractString=\"\", by::Cint=Consts.SORT_NONE, rev::Bool=false)\n\nUsing the GitRevWalker walker to \"walk\" over every commit in the repository's history, apply f to each commit in the walk. The keyword arguments are: * oid: The GitHash of the commit to begin the walk from. The default is to use push_head! and therefore the HEAD commit and all its ancestors. * range: A range of GitHashs in the format oid1..oid2. f will be applied to all commits between the two. * by: The sorting method. The default is not to sort. Other options are to sort by topology (LibGit2.Consts.SORT_TOPOLOGICAL), to sort forwards in time (LibGit2.Consts.SORT_TIME, most ancient first) or to sort backwards in time (LibGit2.Consts.SORT_REVERSE, most recent first). * rev: Whether to reverse the sorted order (for instance, if topological sorting is used).\n\nExamples\n\noids = LibGit2.with(LibGit2.GitRevWalker(repo)) do walker\n LibGit2.map((oid, repo)->string(oid), walker, by=LibGit2.Consts.SORT_TIME)\nend\n\nHere, LibGit2.map visits each commit using the GitRevWalker and finds its GitHash.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.mirror_callback","page":"LibGit2","title":"LibGit2.mirror_callback","text":"Mirror callback function\n\nFunction sets +refs/*:refs/* refspecs and mirror flag for remote reference.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.mirror_cb","page":"LibGit2","title":"LibGit2.mirror_cb","text":"C function pointer for mirror_callback\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.message","page":"LibGit2","title":"LibGit2.message","text":"message(c::GitCommit, raw::Bool=false)\n\nReturn the commit message describing the changes made in commit c. If raw is false, return a slightly \"cleaned up\" message (which has any leading newlines removed). If raw is true, the message is not stripped of any such newlines.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.merge_analysis","page":"LibGit2","title":"LibGit2.merge_analysis","text":"merge_analysis(repo::GitRepo, anns::Vector{GitAnnotated}) -> analysis, preference\n\nRun analysis on the branches pointed to by the annotated branch tips anns and determine under what circumstances they can be merged. For instance, if anns[1] is simply an ancestor of ann[2], then merge_analysis will report that a fast-forward merge is possible.\n\nReturn two outputs, analysis and preference. analysis has several possible values: * MERGE_ANALYSIS_NONE: it is not possible to merge the elements of anns. * MERGE_ANALYSIS_NORMAL: a regular merge, when HEAD and the commits that the user wishes to merge have all diverged from a common ancestor. In this case the changes have to be resolved and conflicts may occur. * MERGE_ANALYSIS_UP_TO_DATE: all the input commits the user wishes to merge can be reached from HEAD, so no merge needs to be performed. * MERGE_ANALYSIS_FASTFORWARD: the input commit is a descendant of HEAD and so no merge needs to be performed - instead, the user can simply checkout the input commit(s). * MERGE_ANALYSIS_UNBORN: the HEAD of the repository refers to a commit which does not exist. It is not possible to merge, but it may be possible to checkout the input commits. preference also has several possible values: * MERGE_PREFERENCE_NONE: the user has no preference. * MERGE_PREFERENCE_NO_FASTFORWARD: do not allow any fast-forward merges. * MERGE_PREFERENCE_FASTFORWARD_ONLY: allow only fast-forward merges and no other type (which may introduce conflicts). preference can be controlled through the repository or global git configuration.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.name","page":"LibGit2","title":"LibGit2.name","text":"LibGit2.name(ref::GitReference)\n\nReturn the full name of ref.\n\n\n\n\n\nname(rmt::GitRemote)\n\nGet the name of a remote repository, for instance \"origin\". If the remote is anonymous (see GitRemoteAnon) the name will be an empty string \"\".\n\nExamples\n\njulia> repo_url = \"https://github.com/JuliaLang/Example.jl\";\n\njulia> repo = LibGit2.clone(cache_repo, \"test_directory\");\n\njulia> remote = LibGit2.GitRemote(repo, \"origin\", repo_url);\n\njulia> name(remote)\n\"origin\"\n\n\n\n\n\nLibGit2.name(tag::GitTag)\n\nThe name of tag (e.g. \"v0.5\").\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.need_update","page":"LibGit2","title":"LibGit2.need_update","text":"need_update(repo::GitRepo)\n\nEquivalent to git update-index. Return true if repo needs updating.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.objtype","page":"LibGit2","title":"LibGit2.objtype","text":"objtype(obj_type::Consts.OBJECT)\n\nReturn the type corresponding to the enum value.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.path","page":"LibGit2","title":"LibGit2.path","text":"LibGit2.path(repo::GitRepo)\n\nReturn the base file path of the repository repo.\n\nfor normal repositories, this will typically be the parent directory of the \".git\" directory (note: this may be different than the working directory, see workdir for more details).\nfor bare repositories, this is the location of the \"git\" files.\n\nSee also gitdir, workdir.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.peel","page":"LibGit2","title":"LibGit2.peel","text":"peel([T,] ref::GitReference)\n\nRecursively peel ref until an object of type T is obtained. If no T is provided, then ref will be peeled until an object other than a GitTag is obtained.\n\nA GitTag will be peeled to the object it references.\nA GitCommit will be peeled to a GitTree.\n\nnote: Note\nOnly annotated tags can be peeled to GitTag objects. Lightweight tags (the default) are references under refs/tags/ which point directly to GitCommit objects.\n\n\n\n\n\npeel([T,] obj::GitObject)\n\nRecursively peel obj until an object of type T is obtained. If no T is provided, then obj will be peeled until the type changes.\n\nA GitTag will be peeled to the object it references.\nA GitCommit will be peeled to a GitTree.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.posixpath","page":"LibGit2","title":"LibGit2.posixpath","text":"LibGit2.posixpath(path)\n\nStandardise the path string path to use POSIX separators.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.push","page":"LibGit2","title":"LibGit2.push","text":"push(rmt::GitRemote, refspecs; force::Bool=false, options::PushOptions=PushOptions())\n\nPush to the specified rmt remote git repository, using refspecs to determine which remote branch(es) to push to. The keyword arguments are:\n\nforce: if true, a force-push will occur, disregarding conflicts.\noptions: determines the options for the push, e.g. which proxy headers to use. See PushOptions for more information.\n\nnote: Note\nYou can add information about the push refspecs in two other ways: by setting an option in the repository's GitConfig (with push.default as the key) or by calling add_push!. Otherwise you will need to explicitly specify a push refspec in the call to push for it to have any effect, like so: LibGit2.push(repo, refspecs=[\"refs/heads/master\"]).\n\n\n\n\n\npush(repo::GitRepo; kwargs...)\n\nPushes updates to an upstream of repo.\n\nThe keyword arguments are:\n\nremote::AbstractString=\"origin\": the name of the upstream remote to push to.\nremoteurl::AbstractString=\"\": the URL of remote.\nrefspecs=AbstractString[]: determines properties of the push.\nforce::Bool=false: determines if the push will be a force push, overwriting the remote branch.\ncredentials=nothing: provides credentials and/or settings when authenticating against a private remote.\ncallbacks=Callbacks(): user provided callbacks and payloads.\n\nEquivalent to git push [|] [].\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.push!-Tuple{LibGit2.GitRevWalker, LibGit2.GitHash}","page":"LibGit2","title":"LibGit2.push!","text":"LibGit2.push!(w::GitRevWalker, cid::GitHash)\n\nStart the GitRevWalker walker at commit cid. This function can be used to apply a function to all commits since a certain year, by passing the first commit of that year as cid and then passing the resulting w to LibGit2.map.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.push_head!","page":"LibGit2","title":"LibGit2.push_head!","text":"LibGit2.push_head!(w::GitRevWalker)\n\nPush the HEAD commit and its ancestors onto the GitRevWalker w. This ensures that HEAD and all its ancestor commits will be encountered during the walk.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.push_refspecs","page":"LibGit2","title":"LibGit2.push_refspecs","text":"push_refspecs(rmt::GitRemote) -> Vector{String}\n\nGet the push refspecs for the specified rmt. These refspecs contain information about which branch(es) to push to.\n\nExamples\n\njulia> remote = LibGit2.get(LibGit2.GitRemote, repo, \"upstream\");\n\njulia> LibGit2.add_push!(repo, remote, \"refs/heads/master\");\n\njulia> close(remote);\n\njulia> remote = LibGit2.get(LibGit2.GitRemote, repo, \"upstream\");\n\njulia> LibGit2.push_refspecs(remote)\nString[\"refs/heads/master\"]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.raw","page":"LibGit2","title":"LibGit2.raw","text":"raw(id::GitHash) -> Vector{UInt8}\n\nObtain the raw bytes of the GitHash as a vector of length 20.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.read_tree!","page":"LibGit2","title":"LibGit2.read_tree!","text":"LibGit2.read_tree!(idx::GitIndex, tree::GitTree)\nLibGit2.read_tree!(idx::GitIndex, treehash::AbstractGitHash)\n\nRead the tree tree (or the tree pointed to by treehash in the repository owned by idx) into the index idx. The current index contents will be replaced.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.rebase!","page":"LibGit2","title":"LibGit2.rebase!","text":"LibGit2.rebase!(repo::GitRepo, upstream::AbstractString=\"\", newbase::AbstractString=\"\")\n\nAttempt an automatic merge rebase of the current branch, from upstream if provided, or otherwise from the upstream tracking branch. newbase is the branch to rebase onto. By default this is upstream.\n\nIf any conflicts arise which cannot be automatically resolved, the rebase will abort, leaving the repository and working tree in its original state, and the function will throw a GitError. This is roughly equivalent to the following command line statement:\n\ngit rebase --merge []\nif [ -d \".git/rebase-merge\" ]; then\n git rebase --abort\nfi\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.ref_list","page":"LibGit2","title":"LibGit2.ref_list","text":"LibGit2.ref_list(repo::GitRepo) -> Vector{String}\n\nGet a list of all reference names in the repo repository.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.reftype","page":"LibGit2","title":"LibGit2.reftype","text":"LibGit2.reftype(ref::GitReference) -> Cint\n\nReturn a Cint corresponding to the type of ref:\n\n0 if the reference is invalid\n1 if the reference is an object id\n2 if the reference is symbolic\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.remotes","page":"LibGit2","title":"LibGit2.remotes","text":"LibGit2.remotes(repo::GitRepo)\n\nReturn a vector of the names of the remotes of repo.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.remove!","page":"LibGit2","title":"LibGit2.remove!","text":"remove!(repo::GitRepo, files::AbstractString...)\nremove!(idx::GitIndex, files::AbstractString...)\n\nRemove all the files with paths specified by files in the index idx (or the index of the repo).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.reset","page":"LibGit2","title":"LibGit2.reset","text":"reset(val::Integer, flag::Integer)\n\nUnset the bits of val indexed by flag, returning them to 0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.reset!","page":"LibGit2","title":"LibGit2.reset!","text":"reset!(payload, [config]) -> CredentialPayload\n\nReset the payload state back to the initial values so that it can be used again within the credential callback. If a config is provided the configuration will also be updated.\n\n\n\n\n\nUpdates some entries, determined by the pathspecs, in the index from the target commit tree.\n\n\n\n\n\nSets the current head to the specified commit oid and optionally resets the index and working tree to match.\n\n\n\n\n\ngit reset [] [–] ... \n\n\n\n\n\nreset!(repo::GitRepo, id::GitHash, mode::Cint=Consts.RESET_MIXED)\n\nReset the repository repo to its state at id, using one of three modes set by mode:\n\nConsts.RESET_SOFT - move HEAD to id.\nConsts.RESET_MIXED - default, move HEAD to id and reset the index to id.\nConsts.RESET_HARD - move HEAD to id, reset the index to id, and discard all working changes.\n\nExamples\n\n# fetch changes\nLibGit2.fetch(repo)\nisfile(joinpath(repo_path, our_file)) # will be false\n\n# fastforward merge the changes\nLibGit2.merge!(repo, fastforward=true)\n\n# because there was not any file locally, but there is\n# a file remotely, we need to reset the branch\nhead_oid = LibGit2.head_oid(repo)\nnew_head = LibGit2.reset!(repo, head_oid, LibGit2.Consts.RESET_HARD)\n\nIn this example, the remote which is being fetched from does have a file called our_file in its index, which is why we must reset.\n\nEquivalent to git reset [--soft | --mixed | --hard] .\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nhead_oid = LibGit2.head_oid(repo)\nopen(joinpath(repo_path, \"file1\"), \"w\") do f\n write(f, \"111\n\")\nend\nLibGit2.add!(repo, \"file1\")\nmode = LibGit2.Consts.RESET_HARD\n# will discard the changes to file1\n# and unstage it\nnew_head = LibGit2.reset!(repo, head_oid, mode)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.restore","page":"LibGit2","title":"LibGit2.restore","text":"restore(s::State, repo::GitRepo)\n\nReturn a repository repo to a previous State s, for example the HEAD of a branch before a merge attempt. s can be generated using the snapshot function.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.revcount","page":"LibGit2","title":"LibGit2.revcount","text":"LibGit2.revcount(repo::GitRepo, commit1::AbstractString, commit2::AbstractString)\n\nList the number of revisions between commit1 and commit2 (committish OIDs in string form). Since commit1 and commit2 may be on different branches, revcount performs a \"left-right\" revision list (and count), returning a tuple of Ints - the number of left and right commits, respectively. A left (or right) commit refers to which side of a symmetric difference in a tree the commit is reachable from.\n\nEquivalent to git rev-list --left-right --count .\n\nExamples\n\nrepo = LibGit2.GitRepo(repo_path)\nrepo_file = open(joinpath(repo_path, test_file), \"a\")\nprintln(repo_file, \"hello world\")\nflush(repo_file)\nLibGit2.add!(repo, test_file)\ncommit_oid1 = LibGit2.commit(repo, \"commit 1\")\nprintln(repo_file, \"hello world again\")\nflush(repo_file)\nLibGit2.add!(repo, test_file)\ncommit_oid2 = LibGit2.commit(repo, \"commit 2\")\nLibGit2.revcount(repo, string(commit_oid1), string(commit_oid2))\n\nThis will return (-1, 0).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.set_remote_url","page":"LibGit2","title":"LibGit2.set_remote_url","text":"set_remote_url(repo::GitRepo, remote_name, url)\nset_remote_url(repo::String, remote_name, url)\n\nSet both the fetch and push url for remote_name for the GitRepo or the git repository located at path. Typically git repos use \"origin\" as the remote name.\n\nExamples\n\nrepo_path = joinpath(tempdir(), \"Example\")\nrepo = LibGit2.init(repo_path)\nLibGit2.set_remote_url(repo, \"upstream\", \"https://github.com/JuliaLang/Example.jl\")\nLibGit2.set_remote_url(repo_path, \"upstream2\", \"https://github.com/JuliaLang/Example2.jl\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.shortname","page":"LibGit2","title":"LibGit2.shortname","text":"LibGit2.shortname(ref::GitReference)\n\nReturn a shortened version of the name of ref that's \"human-readable\".\n\njulia> repo = GitRepo(path_to_repo);\n\njulia> branch_ref = LibGit2.head(repo);\n\njulia> LibGit2.name(branch_ref)\n\"refs/heads/master\"\n\njulia> LibGit2.shortname(branch_ref)\n\"master\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.snapshot","page":"LibGit2","title":"LibGit2.snapshot","text":"snapshot(repo::GitRepo) -> State\n\nTake a snapshot of the current state of the repository repo, storing the current HEAD, index, and any uncommitted work. The output State can be used later during a call to restore to return the repository to the snapshotted state.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.split_cfg_entry","page":"LibGit2","title":"LibGit2.split_cfg_entry","text":"LibGit2.split_cfg_entry(ce::LibGit2.ConfigEntry) -> Tuple{String,String,String,String}\n\nBreak the ConfigEntry up to the following pieces: section, subsection, name, and value.\n\nExamples\n\nGiven the git configuration file containing:\n\n[credential \"https://example.com\"]\n username = me\n\nThe ConfigEntry would look like the following:\n\njulia> entry\nConfigEntry(\"credential.https://example.com.username\", \"me\")\n\njulia> LibGit2.split_cfg_entry(entry)\n(\"credential\", \"https://example.com\", \"username\", \"me\")\n\nRefer to the git config syntax documentation for more details.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.status","page":"LibGit2","title":"LibGit2.status","text":"LibGit2.status(repo::GitRepo, path::String) -> Union{Cuint, Cvoid}\n\nLookup the status of the file at path in the git repository repo. For instance, this can be used to check if the file at path has been modified and needs to be staged and committed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.stage","page":"LibGit2","title":"LibGit2.stage","text":"stage(ie::IndexEntry) -> Cint\n\nGet the stage number of ie. The stage number 0 represents the current state of the working tree, but other numbers can be used in the case of a merge conflict. In such a case, the various stage numbers on an IndexEntry describe which side(s) of the conflict the current state of the file belongs to. Stage 0 is the state before the attempted merge, stage 1 is the changes which have been made locally, stages 2 and larger are for changes from other branches (for instance, in the case of a multi-branch \"octopus\" merge, stages 2, 3, and 4 might be used).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.tag_create","page":"LibGit2","title":"LibGit2.tag_create","text":"LibGit2.tag_create(repo::GitRepo, tag::AbstractString, commit; kwargs...)\n\nCreate a new git tag tag (e.g. \"v0.5\") in the repository repo, at the commit commit.\n\nThe keyword arguments are:\n\nmsg::AbstractString=\"\": the message for the tag.\nforce::Bool=false: if true, existing references will be overwritten.\nsig::Signature=Signature(repo): the tagger's signature.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.tag_delete","page":"LibGit2","title":"LibGit2.tag_delete","text":"LibGit2.tag_delete(repo::GitRepo, tag::AbstractString)\n\nRemove the git tag tag from the repository repo.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.tag_list","page":"LibGit2","title":"LibGit2.tag_list","text":"LibGit2.tag_list(repo::GitRepo) -> Vector{String}\n\nGet a list of all tags in the git repository repo.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.target","page":"LibGit2","title":"LibGit2.target","text":"LibGit2.target(tag::GitTag)\n\nThe GitHash of the target object of tag.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.toggle","page":"LibGit2","title":"LibGit2.toggle","text":"toggle(val::Integer, flag::Integer)\n\nFlip the bits of val indexed by flag, so that if a bit is 0 it will be 1 after the toggle, and vice-versa.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.transact","page":"LibGit2","title":"LibGit2.transact","text":"transact(f::Function, repo::GitRepo)\n\nApply function f to the git repository repo, taking a snapshot before applying f. If an error occurs within f, repo will be returned to its snapshot state using restore. The error which occurred will be rethrown, but the state of repo will not be corrupted.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.treewalk","page":"LibGit2","title":"LibGit2.treewalk","text":"treewalk(f, tree::GitTree, post::Bool=false)\n\nTraverse the entries in tree and its subtrees in post or pre order. Preorder means beginning at the root and then traversing the leftmost subtree (and recursively on down through that subtree's leftmost subtrees) and moving right through the subtrees. Postorder means beginning at the bottom of the leftmost subtree, traversing upwards through it, then traversing the next right subtree (again beginning at the bottom) and finally visiting the tree root last of all.\n\nThe function parameter f should have following signature:\n\n(String, GitTreeEntry) -> Cint\n\nA negative value returned from f stops the tree walk. A positive value means that the entry will be skipped if post is false.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.upstream","page":"LibGit2","title":"LibGit2.upstream","text":"upstream(ref::GitReference) -> Union{GitReference, Nothing}\n\nDetermine if the branch containing ref has a specified upstream branch.\n\nReturn either a GitReference to the upstream branch if it exists, or nothing if the requested branch does not have an upstream counterpart.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.update!","page":"LibGit2","title":"LibGit2.update!","text":"update!(repo::GitRepo, files::AbstractString...)\nupdate!(idx::GitIndex, files::AbstractString...)\n\nUpdate all the files with paths specified by files in the index idx (or the index of the repo). Match the state of each file in the index with the current state on disk, removing it if it has been removed on disk, or updating its entry in the object database.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.url","page":"LibGit2","title":"LibGit2.url","text":"url(rmt::GitRemote)\n\nGet the fetch URL of a remote git repository.\n\nExamples\n\njulia> repo_url = \"https://github.com/JuliaLang/Example.jl\";\n\njulia> repo = LibGit2.init(mktempdir());\n\njulia> remote = LibGit2.GitRemote(repo, \"origin\", repo_url);\n\njulia> LibGit2.url(remote)\n\"https://github.com/JuliaLang/Example.jl\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.version","page":"LibGit2","title":"LibGit2.version","text":"version() -> VersionNumber\n\nReturn the version of libgit2 in use, as a VersionNumber.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.with","page":"LibGit2","title":"LibGit2.with","text":"with(f::Function, obj)\n\nResource management helper function. Applies f to obj, making sure to call close on obj after f successfully returns or throws an error. Ensures that allocated git resources are finalized as soon as they are no longer needed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.with_warn","page":"LibGit2","title":"LibGit2.with_warn","text":"with_warn(f::Function, ::Type{T}, args...)\n\nResource management helper function. Apply f to args, first constructing an instance of type T from args. Makes sure to call close on the resulting object after f successfully returns or throws an error. Ensures that allocated git resources are finalized as soon as they are no longer needed. If an error is thrown by f, a warning is shown containing the error.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.workdir","page":"LibGit2","title":"LibGit2.workdir","text":"LibGit2.workdir(repo::GitRepo)\n\nReturn the location of the working directory of repo. This will throw an error for bare repositories.\n\nnote: Note\nThis will typically be the parent directory of gitdir(repo), but can be different in some cases: e.g. if either the core.worktree configuration variable or the GIT_WORK_TREE environment variable is set.\n\nSee also gitdir, path.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.GitObject-Tuple{LibGit2.GitTreeEntry}","page":"LibGit2","title":"LibGit2.GitObject","text":"(::Type{T})(te::GitTreeEntry) where T<:GitObject\n\nGet the git object to which te refers and return it as its actual type (the type entrytype would show), for instance a GitBlob or GitTag.\n\nExamples\n\ntree = LibGit2.GitTree(repo, \"HEAD^{tree}\")\ntree_entry = tree[1]\nblob = LibGit2.GitBlob(tree_entry)\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LibGit2/#LibGit2.UserPasswordCredential","page":"LibGit2","title":"LibGit2.UserPasswordCredential","text":"Credential that support only user and password parameters\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.SSHCredential","page":"LibGit2","title":"LibGit2.SSHCredential","text":"SSH credential type\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.isfilled","page":"LibGit2","title":"LibGit2.isfilled","text":"isfilled(cred::AbstractCredential) -> Bool\n\nVerifies that a credential is ready for use in authentication.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.CachedCredentials","page":"LibGit2","title":"LibGit2.CachedCredentials","text":"Caches credential information for re-use\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.CredentialPayload","page":"LibGit2","title":"LibGit2.CredentialPayload","text":"LibGit2.CredentialPayload\n\nRetains the state between multiple calls to the credential callback for the same URL. A CredentialPayload instance is expected to be reset! whenever it will be used with a different URL.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LibGit2/#LibGit2.approve","page":"LibGit2","title":"LibGit2.approve","text":"approve(payload::CredentialPayload; shred::Bool=true) -> Nothing\n\nStore the payload credential for re-use in a future authentication. Should only be called when authentication was successful.\n\nThe shred keyword controls whether sensitive information in the payload credential field should be destroyed. Should only be set to false during testing.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.reject","page":"LibGit2","title":"LibGit2.reject","text":"reject(payload::CredentialPayload; shred::Bool=true) -> Nothing\n\nDiscard the payload credential from begin re-used in future authentication. Should only be called when authentication was unsuccessful.\n\nThe shred keyword controls whether sensitive information in the payload credential field should be destroyed. Should only be set to false during testing.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LibGit2/#LibGit2.Consts.GIT_CONFIG","page":"LibGit2","title":"LibGit2.Consts.GIT_CONFIG","text":"Priority level of a config file.\n\nThese priority levels correspond to the natural escalation logic (from higher to lower) when searching for config entries in git.\n\nCONFIG_LEVEL_DEFAULT - Open the global, XDG and system configuration files if any available.\nCONFIG_LEVEL_PROGRAMDATA - System-wide on Windows, for compatibility with portable git\nCONFIG_LEVEL_SYSTEM - System-wide configuration file; /etc/gitconfig on Linux systems\nCONFIG_LEVEL_XDG - XDG compatible configuration file; typically ~/.config/git/config\nCONFIG_LEVEL_GLOBAL - User-specific configuration file (also called Global configuration file); typically ~/.gitconfig\nCONFIG_LEVEL_LOCAL - Repository specific configuration file; $WORK_DIR/.git/config on non-bare repos\nCONFIG_LEVEL_WORKTREE - Worktree specific configuration file; $GIT_DIR/config.worktree\nCONFIG_LEVEL_APP - Application specific configuration file; freely defined by applications\nCONFIG_HIGHEST_LEVEL - Represents the highest level available config file (i.e. the most specific config file available that actually is loaded)\n\n\n\n\n\n","category":"type"},{"location":"base/punctuation/#man-punctuation","page":"Punctuation","title":"Punctuation","text":"","category":"section"},{"location":"base/punctuation/","page":"Punctuation","title":"Punctuation","text":"Extended documentation for mathematical symbols & functions is here.","category":"page"},{"location":"base/punctuation/","page":"Punctuation","title":"Punctuation","text":"symbol meaning\n@ the at-sign marks a macro invocation; optionally followed by an argument list\n! an exclamation mark is a prefix operator for logical negation (\"not\")\na! function names that end with an exclamation mark modify one or more of their arguments by convention\n# the number sign (or hash or pound) character begins single line comments\n#= when followed by an equals sign, it begins a multi-line comment (these are nestable)\n=# end a multi-line comment by immediately preceding the number sign with an equals sign\n$ the dollar sign is used for string and expression interpolation\n% the percent symbol is the remainder operator\n^ the caret is the exponentiation operator\n& single ampersand is bitwise and\n&& double ampersands is short-circuiting boolean and\n| single pipe character is bitwise or\n|| double pipe characters is short-circuiting boolean or\n⊻ the unicode xor character is bitwise exclusive or\n~ the tilde is an operator for bitwise not\n' a trailing apostrophe is the adjoint (that is, the complex transpose) operator Aᴴ\n* the asterisk is used for multiplication, including matrix multiplication and string concatenation\n/ forward slash divides the argument on its left by the one on its right\n\\ backslash operator divides the argument on its right by the one on its left, commonly used to solve matrix equations\n() parentheses with no arguments constructs an empty Tuple\n(a,...) parentheses with comma-separated arguments constructs a tuple containing its arguments\n(a=1,...) parentheses with comma-separated assignments constructs a NamedTuple\n(x;y) parentheses can also be used to group one or more semicolon separated expressions\na[] array indexing (calling getindex or setindex!)\n[,] vector literal constructor (calling vect)\n[;] vertical concatenation (calling vcat or hvcat)\n[ ] with space-separated expressions, horizontal concatenation (calling hcat or hvcat)\nT{ } curly braces following a type list that type's parameters\n{} curly braces can also be used to group multiple where expressions in function declarations\n; semicolons separate statements, begin a list of keyword arguments in function declarations or calls, or are used to separate array literals for vertical concatenation\n, commas separate function arguments or tuple or array components\n? the question mark delimits the ternary conditional operator (used like: conditional ? if_true : if_false)\n\" \" the single double-quote character delimits String literals\n\"\"\" \"\"\" three double-quote characters delimits string literals that may contain \" and ignore leading indentation\n' ' the single-quote character delimits Char (that is, character) literals\n` ` the backtick character delimits external process (Cmd) literals\nA... triple periods are a postfix operator that \"splat\" their arguments' contents into many arguments of a function call or declare a varargs function that \"slurps\" up many arguments into a single tuple\na.b single periods access named fields in objects/modules (calling getproperty or setproperty!)\nf.() periods may also prefix parentheses (like f.(...)) or infix operators (like .+) to perform the function element-wise (calling broadcast)\na:b colons (:) used as a binary infix operator construct a range from a to b (inclusive) with fixed step size 1\na:s:b colons (:) used as a ternary infix operator construct a range from a to b (inclusive) with step size s\n: when used by themselves, Colons represent all indices within a dimension, frequently combined with indexing\n:: double-colons represent a type annotation or typeassert, depending on context, frequently used when declaring function arguments\n:( ) quoted expression\n:a Symbol a\n<: subtype operator\n>: supertype operator (reverse of subtype operator)\n= single equals sign is assignment\n== double equals sign is value equality comparison\n=== triple equals sign is programmatically identical equality comparison\n=> right arrow using an equals sign defines a Pair typically used to populate dictionaries\n-> right arrow using a hyphen defines an anonymous function on a single line\n|> pipe operator passes output from the left argument to input of the right argument, usually a function\n∘ function composition operator (typed with \\circ{tab}) combines two functions as though they are a single larger function\n_ underscores may be assigned values which will not be saved, often used to ignore multiple return values or create repetitive comprehensions","category":"page"},{"location":"devdocs/build/linux/#Linux","page":"Linux","title":"Linux","text":"","category":"section"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"GCC version 4.7 or later is required to build Julia.\nTo use external shared libraries not in the system library search path, set USE_SYSTEM_XXX=1 and LDFLAGS=-Wl,-rpath,/path/to/dir/contains/libXXX.so in Make.user.\nInstead of setting LDFLAGS, putting the library directory into the environment variable LD_LIBRARY_PATH (at both compile and run time) also works.\nThe USE_SYSTEM_* flags should be used with caution. These are meant only for troubleshooting, porting, and packaging, where package maintainers work closely with the Julia developers to make sure that Julia is built correctly. Production use cases should use the officially provided binaries. Issues arising from the use of these flags will generally not be accepted.\nSee also the external dependencies.","category":"page"},{"location":"devdocs/build/linux/#Architecture-Customization","page":"Linux","title":"Architecture Customization","text":"","category":"section"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"Julia can be built for a non-generic architecture by configuring the ARCH Makefile variable in a Make.user file. See the appropriate section of Make.inc for additional customization options, such as MARCH and JULIA_CPU_TARGET.","category":"page"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"For example, to build for Pentium 4, set MARCH=pentium4 and install the necessary system libraries for linking. On Ubuntu, these may include lib32gfortran-6-dev, lib32gcc1, and lib32stdc++6, among others.","category":"page"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"You can also set MARCH=native in Make.user for a maximum-performance build customized for the current machine CPU.","category":"page"},{"location":"devdocs/build/linux/#Linux-Build-Troubleshooting","page":"Linux","title":"Linux Build Troubleshooting","text":"","category":"section"},{"location":"devdocs/build/linux/","page":"Linux","title":"Linux","text":"Problem Possible Solution\nOpenBLAS build failure Set one of the following build options in Make.user and build again:
    • OPENBLAS_TARGET_ARCH=BARCELONA (AMD CPUs) or OPENBLAS_TARGET_ARCH=NEHALEM (Intel CPUs)
        Set OPENBLAS_DYNAMIC_ARCH = 0 to disable compiling multiple architectures in a single binary.
    • OPENBLAS_NO_AVX2 = 1 disables AVX2 instructions, allowing OpenBLAS to compile with OPENBLAS_DYNAMIC_ARCH = 1 using old versions of binutils
    • USE_SYSTEM_BLAS=1 uses the system provided libblas
      • Set LIBBLAS=-lopenblas and LIBBLASNAME=libopenblas to force the use of the system provided OpenBLAS when multiple BLAS versions are installed.

    If you get an error that looks like ../kernel/x86_64/dgemm_kernel_4x4_haswell.S:1709: Error: no such instruction: `vpermpd $ 0xb1,%ymm0,%ymm0', then you need to set OPENBLAS_DYNAMIC_ARCH = 0 or OPENBLAS_NO_AVX2 = 1, or you need a newer version of binutils (2.18 or newer). (Issue #7653)

    If the linker cannot find gfortran and you get an error like julia /usr/bin/x86_64-linux-gnu-ld: cannot find -lgfortran, check the path with gfortran -print-file-name=libgfortran.so and use the output to export something similar to this: export LDFLAGS=-L/usr/lib/gcc/x86_64-linux-gnu/8/. See Issue #6150.

    \nIllegal Instruction error Check if your CPU supports AVX while your OS does not (e.g. through virtualization, as described in this issue).","category":"page"},{"location":"manual/multi-threading/#man-multithreading","page":"Multi-Threading","title":"Multi-Threading","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Visit this blog post for a presentation of Julia multi-threading features.","category":"page"},{"location":"manual/multi-threading/#Starting-Julia-with-multiple-threads","page":"Multi-Threading","title":"Starting Julia with multiple threads","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"By default, Julia starts up with a single thread of execution. This can be verified by using the command Threads.nthreads():","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> Threads.nthreads()\n1","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The number of execution threads is controlled either by using the -t/--threads command line argument or by using the JULIA_NUM_THREADS environment variable. When both are specified, then -t/--threads takes precedence.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The number of threads can either be specified as an integer (--threads=4) or as auto (--threads=auto), where auto tries to infer a useful default number of threads to use (see Command-line Options for more details).","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.5\nThe -t/--threads command line argument requires at least Julia 1.5. In older versions you must use the environment variable instead.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.7\nUsing auto as value of the environment variable JULIA_NUM_THREADS requires at least Julia 1.7. In older versions, this value is ignored.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Lets start Julia with 4 threads:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"$ julia --threads 4","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Let's verify there are 4 threads at our disposal.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> Threads.nthreads()\n4","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"But we are currently on the master thread. To check, we use the function Threads.threadid","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> Threads.threadid()\n1","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nIf you prefer to use the environment variable you can set it as follows in Bash (Linux/macOS):export JULIA_NUM_THREADS=4C shell on Linux/macOS, CMD on Windows:set JULIA_NUM_THREADS=4Powershell on Windows:$env:JULIA_NUM_THREADS=4Note that this must be done before starting Julia.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nThe number of threads specified with -t/--threads is propagated to worker processes that are spawned using the -p/--procs or --machine-file command line options. For example, julia -p2 -t2 spawns 1 main process with 2 worker processes, and all three processes have 2 threads enabled. For more fine grained control over worker threads use addprocs and pass -t/--threads as exeflags.","category":"page"},{"location":"manual/multi-threading/#Multiple-GC-Threads","page":"Multi-Threading","title":"Multiple GC Threads","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The Garbage Collector (GC) can use multiple threads. The amount used is either half the number of compute worker threads or configured by either the --gcthreads command line argument or by using the JULIA_NUM_GC_THREADS environment variable.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.10\nThe --gcthreads command line argument requires at least Julia 1.10.","category":"page"},{"location":"manual/multi-threading/#man-threadpools","page":"Multi-Threading","title":"Threadpools","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"When a program's threads are busy with many tasks to run, tasks may experience delays which may negatively affect the responsiveness and interactivity of the program. To address this, you can specify that a task is interactive when you Threads.@spawn it:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"using Base.Threads\n@spawn :interactive f()","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Interactive tasks should avoid performing high latency operations, and if they are long duration tasks, should yield frequently.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Julia may be started with one or more threads reserved to run interactive tasks:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"$ julia --threads 3,1","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The environment variable JULIA_NUM_THREADS can also be used similarly:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"export JULIA_NUM_THREADS=3,1","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"This starts Julia with 3 threads in the :default threadpool and 1 thread in the :interactive threadpool:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> using Base.Threads\n\njulia> nthreadpools()\n2\n\njulia> threadpool() # the main thread is in the interactive thread pool\n:interactive\n\njulia> nthreads(:default)\n3\n\njulia> nthreads(:interactive)\n1\n\njulia> nthreads()\n3","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nThe zero-argument version of nthreads returns the number of threads in the default pool.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nDepending on whether Julia has been started with interactive threads, the main thread is either in the default or interactive thread pool.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Either or both numbers can be replaced with the word auto, which causes Julia to choose a reasonable default.","category":"page"},{"location":"manual/multi-threading/#The-@threads-Macro","page":"Multi-Threading","title":"The @threads Macro","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Let's work a simple example using our native threads. Let us create an array of zeros:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> a = zeros(10)\n10-element Vector{Float64}:\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0\n 0.0","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Let us operate on this array simultaneously using 4 threads. We'll have each thread write its thread ID into each location.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Julia supports parallel loops using the Threads.@threads macro. This macro is affixed in front of a for loop to indicate to Julia that the loop is a multi-threaded region:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> Threads.@threads for i = 1:10\n a[i] = Threads.threadid()\n end","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The iteration space is split among the threads, after which each thread writes its thread ID to its assigned locations:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> a\n10-element Vector{Float64}:\n 1.0\n 1.0\n 1.0\n 2.0\n 2.0\n 2.0\n 3.0\n 3.0\n 4.0\n 4.0","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Note that Threads.@threads does not have an optional reduction parameter like @distributed.","category":"page"},{"location":"manual/multi-threading/#Using-@threads-without-data-races","page":"Multi-Threading","title":"Using @threads without data-races","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The concept of a data-race is elaborated on in \"Communication and data races between threads\". For now, just known that a data race can result in incorrect results and dangerous errors.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Lets say we want to make the function sum_single below multithreaded.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> function sum_single(a)\n s = 0\n for i in a\n s += i\n end\n s\n end\nsum_single (generic function with 1 method)\n\njulia> sum_single(1:1_000_000)\n500000500000","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Simply adding @threads exposes a data race with multiple threads reading and writing s at the same time.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> function sum_multi_bad(a)\n s = 0\n Threads.@threads for i in a\n s += i\n end\n s\n end\nsum_multi_bad (generic function with 1 method)\n\njulia> sum_multi_bad(1:1_000_000)\n70140554652","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Note that the result is not 500000500000 as it should be, and will most likely change each evaluation.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"To fix this, buffers that are specific to the task may be used to segment the sum into chunks that are race-free. Here sum_single is reused, with its own internal buffer s. The input vector a is split into at most nthreads() chunks for parallel work. We then use Threads.@spawn to create tasks that individually sum each chunk. Finally, we sum the results from each task using sum_single again:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> function sum_multi_good(a)\n chunks = Iterators.partition(a, cld(length(a), Threads.nthreads()))\n tasks = map(chunks) do chunk\n Threads.@spawn sum_single(chunk)\n end\n chunk_sums = fetch.(tasks)\n return sum_single(chunk_sums)\n end\nsum_multi_good (generic function with 1 method)\n\njulia> sum_multi_good(1:1_000_000)\n500000500000","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"note: Note\nBuffers should not be managed based on threadid() i.e. buffers = zeros(Threads.nthreads()) because concurrent tasks can yield, meaning multiple concurrent tasks may use the same buffer on a given thread, introducing risk of data races. Further, when more than one thread is available tasks may change thread at yield points, which is known as task migration.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Another option is the use of atomic operations on variables shared across tasks/threads, which may be more performant depending on the characteristics of the operations.","category":"page"},{"location":"manual/multi-threading/#man-communication-and-data-races","page":"Multi-Threading","title":"Communication and data-races between threads","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Although Julia's threads can communicate through shared memory, it is notoriously difficult to write correct and data-race free multi-threaded code. Julia's Channels are thread-safe and may be used to communicate safely. There are also sections below that explain how to use locks and atomics to avoid data-races.","category":"page"},{"location":"manual/multi-threading/#Data-race-freedom","page":"Multi-Threading","title":"Data-race freedom","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"You are entirely responsible for ensuring that your program is data-race free, and nothing promised here can be assumed if you do not observe that requirement. The observed results may be highly unintuitive.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"If data-races are introduced, Julia is not memory safe. Be very careful about reading any data if another thread might write to it, as it could result in segmentation faults or worse. Below are a couple of unsafe ways to access global variables from different threads:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Thread 1:\nglobal b = false\nglobal a = rand()\nglobal b = true\n\nThread 2:\nwhile !b; end\nbad_read1(a) # it is NOT safe to access `a` here!\n\nThread 3:\nwhile !@isdefined(a); end\nbad_read2(a) # it is NOT safe to access `a` here","category":"page"},{"location":"manual/multi-threading/#man-using-locks","page":"Multi-Threading","title":"Using locks to avoid data-races","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"An important tool to avoid data-races, and thereby write thread-safe code, is the concept of a \"lock\". A lock can be locked and unlocked. If a thread has locked a lock, and not unlocked it, it is said to \"hold\" the lock. If there is only one lock, and we write code the requires holding the lock to access some data, we can ensure that multiple threads will never access the same data simultaneously. Note that the link between a lock and a variable is made by the programmer, and not the program.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"For example, we can create a lock my_lock, and lock it while we mutate a variable my_variable. This is done most simply with the @lock macro:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> my_lock = ReentrantLock();\n\njulia> my_variable = [1, 2, 3];\n\njulia> @lock my_lock my_variable[1] = 100\n100","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"By using a similar pattern with the same lock and variable, but on another thread, the operations are free from data-races.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"We could have performed the operation above with the functional version of lock, in the following two ways:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> lock(my_lock) do\n my_variable[1] = 100\n end\n100\n\njulia> begin\n lock(my_lock)\n try\n my_variable[1] = 100\n finally\n unlock(my_lock)\n end\n end\n100","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"All three options are equivalent. Note how the final version requires an explicit try-block to ensure that the lock is always unlocked, whereas the first two version do this internally. One should always use the lock pattern above when changing data (such as assigning to a global or closure variable) accessed by other threads. Failing to do this could have unforeseen and serious consequences.","category":"page"},{"location":"manual/multi-threading/#man-atomic-operations","page":"Multi-Threading","title":"Atomic Operations","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Julia supports accessing and modifying values atomically, that is, in a thread-safe way to avoid race conditions. A value (which must be of a primitive type) can be wrapped as Threads.Atomic to indicate it must be accessed in this way. Here we can see an example:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> i = Threads.Atomic{Int}(0);\n\njulia> ids = zeros(4);\n\njulia> old_is = zeros(4);\n\njulia> Threads.@threads for id in 1:4\n old_is[id] = Threads.atomic_add!(i, id)\n ids[id] = id\n end\n\njulia> old_is\n4-element Vector{Float64}:\n 0.0\n 1.0\n 7.0\n 3.0\n\njulia> i[]\n 10\n\njulia> ids\n4-element Vector{Float64}:\n 1.0\n 2.0\n 3.0\n 4.0","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Had we tried to do the addition without the atomic tag, we might have gotten the wrong answer due to a race condition. An example of what would happen if we didn't avoid the race:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"julia> using Base.Threads\n\njulia> Threads.nthreads()\n4\n\njulia> acc = Ref(0)\nBase.RefValue{Int64}(0)\n\njulia> @threads for i in 1:1000\n acc[] += 1\n end\n\njulia> acc[]\n926\n\njulia> acc = Atomic{Int64}(0)\nAtomic{Int64}(0)\n\njulia> @threads for i in 1:1000\n atomic_add!(acc, 1)\n end\n\njulia> acc[]\n1000","category":"page"},{"location":"manual/multi-threading/#man-atomics","page":"Multi-Threading","title":"Per-field atomics","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"We can also use atomics on a more granular level using the @atomic, @atomicswap, @atomicreplace macros, and @atomiconce macros.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Specific details of the memory model and other details of the design are written in the Julia Atomics Manifesto, which will later be published formally.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Any field in a struct declaration can be decorated with @atomic, and then any write must be marked with @atomic also, and must use one of the defined atomic orderings (:monotonic, :acquire, :release, :acquire_release, or :sequentially_consistent). Any read of an atomic field can also be annotated with an atomic ordering constraint, or will be done with monotonic (relaxed) ordering if unspecified.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.7\nPer-field atomics requires at least Julia 1.7.","category":"page"},{"location":"manual/multi-threading/#Side-effects-and-mutable-function-arguments","page":"Multi-Threading","title":"Side effects and mutable function arguments","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"When using multi-threading we have to be careful when using functions that are not pure as we might get a wrong answer. For instance functions that have a name ending with ! by convention modify their arguments and thus are not pure.","category":"page"},{"location":"manual/multi-threading/#@threadcall","page":"Multi-Threading","title":"@threadcall","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"External libraries, such as those called via ccall, pose a problem for Julia's task-based I/O mechanism. If a C library performs a blocking operation, that prevents the Julia scheduler from executing any other tasks until the call returns. (Exceptions are calls into custom C code that call back into Julia, which may then yield, or C code that calls jl_yield(), the C equivalent of yield.)","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"The @threadcall macro provides a way to avoid stalling execution in such a scenario. It schedules a C function for execution in a separate thread. A threadpool with a default size of 4 is used for this. The size of the threadpool is controlled via environment variable UV_THREADPOOL_SIZE. While waiting for a free thread, and during function execution once a thread is available, the requesting task (on the main Julia event loop) yields to other tasks. Note that @threadcall does not return until the execution is complete. From a user point of view, it is therefore a blocking call like other Julia APIs.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"It is very important that the called function does not call back into Julia, as it will segfault.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"@threadcall may be removed/changed in future versions of Julia.","category":"page"},{"location":"manual/multi-threading/#Caveats","page":"Multi-Threading","title":"Caveats","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"At this time, most operations in the Julia runtime and standard libraries can be used in a thread-safe manner, if the user code is data-race free. However, in some areas work on stabilizing thread support is ongoing. Multi-threaded programming has many inherent difficulties, and if a program using threads exhibits unusual or undesirable behavior (e.g. crashes or mysterious results), thread interactions should typically be suspected first.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"There are a few specific limitations and warnings to be aware of when using threads in Julia:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base collection types require manual locking if used simultaneously by multiple threads where at least one thread modifies the collection (common examples include push! on arrays, or inserting items into a Dict).\nThe schedule used by @spawn is nondeterministic and should not be relied on.\nCompute-bound, non-memory-allocating tasks can prevent garbage collection from running in other threads that are allocating memory. In these cases it may be necessary to insert a manual call to GC.safepoint() to allow GC to run. This limitation will be removed in the future.\nAvoid running top-level operations, e.g. include, or eval of type, method, and module definitions in parallel.\nBe aware that finalizers registered by a library may break if threads are enabled. This may require some transitional work across the ecosystem before threading can be widely adopted with confidence. See the section on the safe use of finalizers for further details.","category":"page"},{"location":"manual/multi-threading/#man-task-migration","page":"Multi-Threading","title":"Task Migration","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"After a task starts running on a certain thread it may move to a different thread if the task yields.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Such tasks may have been started with @spawn or @threads, although the :static schedule option for @threads does freeze the threadid.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"This means that in most cases threadid() should not be treated as constant within a task, and therefore should not be used to index into a vector of buffers or stateful objects.","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"compat: Julia 1.7\nTask migration was introduced in Julia 1.7. Before this tasks always remained on the same thread that they were started on.","category":"page"},{"location":"manual/multi-threading/#man-finalizers","page":"Multi-Threading","title":"Safe use of Finalizers","text":"","category":"section"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Because finalizers can interrupt any code, they must be very careful in how they interact with any global state. Unfortunately, the main reason that finalizers are used is to update global state (a pure function is generally rather pointless as a finalizer). This leads us to a bit of a conundrum. There are a few approaches to dealing with this problem:","category":"page"},{"location":"manual/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"When single-threaded, code could call the internal jl_gc_enable_finalizers C function to prevent finalizers from being scheduled inside a critical region. Internally, this is used inside some functions (such as our C locks) to prevent recursion when doing certain operations (incremental package loading, codegen, etc.). The combination of a lock and this flag can be used to make finalizers safe.\nA second strategy, employed by Base in a couple places, is to explicitly delay a finalizer until it may be able to acquire its lock non-recursively. The following example demonstrates how this strategy could be applied to Distributed.finalize_ref:\nfunction finalize_ref(r::AbstractRemoteRef)\n if r.where > 0 # Check if the finalizer is already run\n if islocked(client_refs) || !trylock(client_refs)\n # delay finalizer for later if we aren't free to acquire the lock\n finalizer(finalize_ref, r)\n return nothing\n end\n try # `lock` should always be followed by `try`\n if r.where > 0 # Must check again here\n # Do actual cleanup here\n r.where = 0\n end\n finally\n unlock(client_refs)\n end\n end\n nothing\nend\nA related third strategy is to use a yield-free queue. We don't currently have a lock-free queue implemented in Base, but Base.IntrusiveLinkedListSynchronized{T} is suitable. This can frequently be a good strategy to use for code with event loops. For example, this strategy is employed by Gtk.jl to manage lifetime ref-counting. In this approach, we don't do any explicit work inside the finalizer, and instead add it to a queue to run at a safer time. In fact, Julia's task scheduler already uses this, so defining the finalizer as x -> @spawn do_cleanup(x) is one example of this approach. Note however that this doesn't control which thread do_cleanup runs on, so do_cleanup would still need to acquire a lock. That doesn't need to be true if you implement your own queue, as you can explicitly only drain that queue from your thread.","category":"page"},{"location":"manual/methods/#Methods","page":"Methods","title":"Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Recall from Functions that a function is an object that maps a tuple of arguments to a return value, or throws an exception if no appropriate value can be returned. It is common for the same conceptual function or operation to be implemented quite differently for different types of arguments: adding two integers is very different from adding two floating-point numbers, both of which are distinct from adding an integer to a floating-point number. Despite their implementation differences, these operations all fall under the general concept of \"addition\". Accordingly, in Julia, these behaviors all belong to a single object: the + function.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"To facilitate using many different implementations of the same concept smoothly, functions need not be defined all at once, but can rather be defined piecewise by providing specific behaviors for certain combinations of argument types and counts. A definition of one possible behavior for a function is called a method. Thus far, we have presented only examples of functions defined with a single method, applicable to all types of arguments. However, the signatures of method definitions can be annotated to indicate the types of arguments in addition to their number, and more than a single method definition may be provided. When a function is applied to a particular tuple of arguments, the most specific method applicable to those arguments is applied. Thus, the overall behavior of a function is a patchwork of the behaviors of its various method definitions. If the patchwork is well designed, even though the implementations of the methods may be quite different, the outward behavior of the function will appear seamless and consistent.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The choice of which method to execute when a function is applied is called dispatch. Julia allows the dispatch process to choose which of a function's methods to call based on the number of arguments given, and on the types of all of the function's arguments. This is different than traditional object-oriented languages, where dispatch occurs based only on the first argument, which often has a special argument syntax, and is sometimes implied rather than explicitly written as an argument. [1] Using all of a function's arguments to choose which method should be invoked, rather than just the first, is known as multiple dispatch. Multiple dispatch is particularly useful for mathematical code, where it makes little sense to artificially deem the operations to \"belong\" to one argument more than any of the others: does the addition operation in x + y belong to x any more than it does to y? The implementation of a mathematical operator generally depends on the types of all of its arguments. Even beyond mathematical operations, however, multiple dispatch ends up being a powerful and convenient paradigm for structuring and organizing programs.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"[1]: In C++ or Java, for example, in a method call like obj.meth(arg1,arg2), the object obj \"receives\" the method call and is implicitly passed to the method via the this keyword, rather than as an explicit method argument. When the current this object is the receiver of a method call, it can be omitted altogether, writing just meth(arg1,arg2), with this implied as the receiving object.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"note: Note\nAll the examples in this chapter assume that you are defining methods for a function in the same module. If you want to add methods to a function in another module, you have to import it or use the name qualified with module names. See the section on namespace management.","category":"page"},{"location":"manual/methods/#Defining-Methods","page":"Methods","title":"Defining Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Until now, we have, in our examples, defined only functions with a single method having unconstrained argument types. Such functions behave just like they would in traditional dynamically typed languages. Nevertheless, we have used multiple dispatch and methods almost continually without being aware of it: all of Julia's standard functions and operators, like the aforementioned + function, have many methods defining their behavior over various possible combinations of argument type and count.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When defining a function, one can optionally constrain the types of parameters it is applicable to, using the :: type-assertion operator, introduced in the section on Composite Types:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x::Float64, y::Float64) = 2x + y\nf (generic function with 1 method)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This function definition applies only to calls where x and y are both values of type Float64:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(2.0, 3.0)\n7.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Applying it to any other types of arguments will result in a MethodError:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(2.0, 3)\nERROR: MethodError: no method matching f(::Float64, ::Int64)\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(::Float64, !Matched::Float64)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> f(Float32(2.0), 3.0)\nERROR: MethodError: no method matching f(::Float32, ::Float64)\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(!Matched::Float64, ::Float64)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> f(2.0, \"3.0\")\nERROR: MethodError: no method matching f(::Float64, ::String)\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(::Float64, !Matched::Float64)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> f(\"2.0\", \"3.0\")\nERROR: MethodError: no method matching f(::String, ::String)\nThe function `f` exists, but no method is defined for this combination of argument types.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"As you can see, the arguments must be precisely of type Float64. Other numeric types, such as integers or 32-bit floating-point values, are not automatically converted to 64-bit floating-point, nor are strings parsed as numbers. Because Float64 is a concrete type and concrete types cannot be subclassed in Julia, such a definition can only be applied to arguments that are exactly of type Float64. It may often be useful, however, to write more general methods where the declared parameter types are abstract:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x::Number, y::Number) = 2x - y\nf (generic function with 2 methods)\n\njulia> f(2.0, 3)\n1.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This method definition applies to any pair of arguments that are instances of Number. They need not be of the same type, so long as they are each numeric values. The problem of handling disparate numeric types is delegated to the arithmetic operations in the expression 2x - y.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"To define a function with multiple methods, one simply defines the function multiple times, with different numbers and types of arguments. The first method definition for a function creates the function object, and subsequent method definitions add new methods to the existing function object. The most specific method definition matching the number and types of the arguments will be executed when the function is applied. Thus, the two method definitions above, taken together, define the behavior for f over all pairs of instances of the abstract type Number – but with a different behavior specific to pairs of Float64 values. If one of the arguments is a 64-bit float but the other one is not, then the f(Float64,Float64) method cannot be called and the more general f(Number,Number) method must be used:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(2.0, 3.0)\n7.0\n\njulia> f(2, 3.0)\n1.0\n\njulia> f(2.0, 3)\n1.0\n\njulia> f(2, 3)\n1","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The 2x + y definition is only used in the first case, while the 2x - y definition is used in the others. No automatic casting or conversion of function arguments is ever performed: all conversion in Julia is non-magical and completely explicit. Conversion and Promotion, however, shows how clever application of sufficiently advanced technology can be indistinguishable from magic. [Clarke61]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For non-numeric values, and for fewer or more than two arguments, the function f remains undefined, and applying it will still result in a MethodError:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(\"foo\", 3)\nERROR: MethodError: no method matching f(::String, ::Int64)\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(!Matched::Number, ::Number)\n @ Main none:1\n f(!Matched::Float64, !Matched::Float64)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> f()\nERROR: MethodError: no method matching f()\nThe function `f` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n f(!Matched::Float64, !Matched::Float64)\n @ Main none:1\n f(!Matched::Number, !Matched::Number)\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"You can easily see which methods exist for a function by entering the function object itself in an interactive session:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f\nf (generic function with 2 methods)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This output tells us that f is a function object with two methods. To find out what the signatures of those methods are, use the methods function:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> methods(f)\n# 2 methods for generic function \"f\" from Main:\n [1] f(x::Float64, y::Float64)\n @ none:1\n [2] f(x::Number, y::Number)\n @ none:1","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"which shows that f has two methods, one taking two Float64 arguments and one taking arguments of type Number. It also indicates the file and line number where the methods were defined: because these methods were defined at the REPL, we get the apparent line number none:1.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In the absence of a type declaration with ::, the type of a method parameter is Any by default, meaning that it is unconstrained since all values in Julia are instances of the abstract type Any. Thus, we can define a catch-all method for f like so:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x,y) = println(\"Whoa there, Nelly.\")\nf (generic function with 3 methods)\n\njulia> methods(f)\n# 3 methods for generic function \"f\" from Main:\n [1] f(x::Float64, y::Float64)\n @ none:1\n [2] f(x::Number, y::Number)\n @ none:1\n [3] f(x, y)\n @ none:1\n\njulia> f(\"foo\", 1)\nWhoa there, Nelly.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This catch-all is less specific than any other possible method definition for a pair of parameter values, so it will only be called on pairs of arguments to which no other method definition applies.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Note that in the signature of the third method, there is no type specified for the arguments x and y. This is a shortened way of expressing f(x::Any, y::Any).","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Although it seems a simple concept, multiple dispatch on the types of values is perhaps the single most powerful and central feature of the Julia language. Core operations typically have dozens of methods:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> methods(+)\n# 180 methods for generic function \"+\":\n[1] +(x::Bool, z::Complex{Bool}) in Base at complex.jl:227\n[2] +(x::Bool, y::Bool) in Base at bool.jl:89\n[3] +(x::Bool) in Base at bool.jl:86\n[4] +(x::Bool, y::T) where T<:AbstractFloat in Base at bool.jl:96\n[5] +(x::Bool, z::Complex) in Base at complex.jl:234\n[6] +(a::Float16, b::Float16) in Base at float.jl:373\n[7] +(x::Float32, y::Float32) in Base at float.jl:375\n[8] +(x::Float64, y::Float64) in Base at float.jl:376\n[9] +(z::Complex{Bool}, x::Bool) in Base at complex.jl:228\n[10] +(z::Complex{Bool}, x::Real) in Base at complex.jl:242\n[11] +(x::Char, y::Integer) in Base at char.jl:40\n[12] +(c::BigInt, x::BigFloat) in Base.MPFR at mpfr.jl:307\n[13] +(a::BigInt, b::BigInt, c::BigInt, d::BigInt, e::BigInt) in Base.GMP at gmp.jl:392\n[14] +(a::BigInt, b::BigInt, c::BigInt, d::BigInt) in Base.GMP at gmp.jl:391\n[15] +(a::BigInt, b::BigInt, c::BigInt) in Base.GMP at gmp.jl:390\n[16] +(x::BigInt, y::BigInt) in Base.GMP at gmp.jl:361\n[17] +(x::BigInt, c::Union{UInt16, UInt32, UInt64, UInt8}) in Base.GMP at gmp.jl:398\n...\n[180] +(a, b, c, xs...) in Base at operators.jl:424","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Multiple dispatch together with the flexible parametric type system give Julia its ability to abstractly express high-level algorithms decoupled from implementation details.","category":"page"},{"location":"manual/methods/#man-method-specializations","page":"Methods","title":"Method specializations","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When you create multiple methods of the same function, this is sometimes called \"specialization.\" In this case, you're specializing the function by adding additional methods to it: each new method is a new specialization of the function. As shown above, these specializations are returned by methods.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"There's another kind of specialization that occurs without programmer intervention: Julia's compiler can automatically specialize the method for the specific argument types used. Such specializations are not listed by methods, as this doesn't create new Methods, but tools like @code_typed allow you to inspect such specializations.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For example, if you create a method","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"mysum(x::Real, y::Real) = x + y","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"you've given the function mysum one new method (possibly its only method), and that method takes any pair of Real number inputs. But if you then execute","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> mysum(1, 2)\n3\n\njulia> mysum(1.0, 2.0)\n3.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Julia will compile mysum twice, once for x::Int, y::Int and again for x::Float64, y::Float64. The point of compiling twice is performance: the methods that get called for + (which mysum uses) vary depending on the specific types of x and y, and by compiling different specializations Julia can do all the method lookup ahead of time. This allows the program to run much more quickly, since it does not have to bother with method lookup while it is running. Julia's automatic specialization allows you to write generic algorithms and expect that the compiler will generate efficient, specialized code to handle each case you need.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In cases where the number of potential specializations might be effectively unlimited, Julia may avoid this default specialization. See Be aware of when Julia avoids specializing for more information.","category":"page"},{"location":"manual/methods/#man-ambiguities","page":"Methods","title":"Method Ambiguities","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"It is possible to define a set of function methods such that there is no unique most specific method applicable to some combinations of arguments:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> g(x::Float64, y) = 2x + y\ng (generic function with 1 method)\n\njulia> g(x, y::Float64) = x + 2y\ng (generic function with 2 methods)\n\njulia> g(2.0, 3)\n7.0\n\njulia> g(2, 3.0)\n8.0\n\njulia> g(2.0, 3.0)\nERROR: MethodError: g(::Float64, ::Float64) is ambiguous.\n\nCandidates:\n g(x, y::Float64)\n @ Main none:1\n g(x::Float64, y)\n @ Main none:1\n\nPossible fix, define\n g(::Float64, ::Float64)\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Here the call g(2.0, 3.0) could be handled by either the g(::Float64, ::Any) or the g(::Any, ::Float64) method. The order in which the methods are defined does not matter and neither is more specific than the other. In such cases, Julia raises a MethodError rather than arbitrarily picking a method. You can avoid method ambiguities by specifying an appropriate method for the intersection case:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> g(x::Float64, y::Float64) = 2x + 2y\ng (generic function with 3 methods)\n\njulia> g(2.0, 3)\n7.0\n\njulia> g(2, 3.0)\n8.0\n\njulia> g(2.0, 3.0)\n10.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"It is recommended that the disambiguating method be defined first, since otherwise the ambiguity exists, if transiently, until the more specific method is defined.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In more complex cases, resolving method ambiguities involves a certain element of design; this topic is explored further below.","category":"page"},{"location":"manual/methods/#Parametric-Methods","page":"Methods","title":"Parametric Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Method definitions can optionally have type parameters qualifying the signature:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> same_type(x::T, y::T) where {T} = true\nsame_type (generic function with 1 method)\n\njulia> same_type(x,y) = false\nsame_type (generic function with 2 methods)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The first method applies whenever both arguments are of the same concrete type, regardless of what type that is, while the second method acts as a catch-all, covering all other cases. Thus, overall, this defines a boolean function that checks whether its two arguments are of the same type:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> same_type(1, 2)\ntrue\n\njulia> same_type(1, 2.0)\nfalse\n\njulia> same_type(1.0, 2.0)\ntrue\n\njulia> same_type(\"foo\", 2.0)\nfalse\n\njulia> same_type(\"foo\", \"bar\")\ntrue\n\njulia> same_type(Int32(1), Int64(2))\nfalse","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Such definitions correspond to methods whose type signatures are UnionAll types (see UnionAll Types).","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This kind of definition of function behavior by dispatch is quite common – idiomatic, even – in Julia. Method type parameters are not restricted to being used as the types of arguments: they can be used anywhere a value would be in the signature of the function or body of the function. Here's an example where the method type parameter T is used as the type parameter to the parametric type Vector{T} in the method signature:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> function myappend(v::Vector{T}, x::T) where {T}\n return [v..., x]\n end\nmyappend (generic function with 1 method)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The type parameter T in this example ensures that the added element x is a subtype of the existing eltype of the vector v. The where keyword introduces a list of those constraints after the method signature definition. This works the same for one-line definitions, as seen above, and must appear before the return type declaration, if present, as illustrated below:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> (myappend(v::Vector{T}, x::T)::Vector) where {T} = [v..., x]\nmyappend (generic function with 1 method)\n\njulia> myappend([1,2,3],4)\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> myappend([1,2,3],2.5)\nERROR: MethodError: no method matching myappend(::Vector{Int64}, ::Float64)\nThe function `myappend` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n myappend(::Vector{T}, !Matched::T) where T\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> myappend([1.0,2.0,3.0],4.0)\n4-element Vector{Float64}:\n 1.0\n 2.0\n 3.0\n 4.0\n\njulia> myappend([1.0,2.0,3.0],4)\nERROR: MethodError: no method matching myappend(::Vector{Float64}, ::Int64)\nThe function `myappend` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n myappend(::Vector{T}, !Matched::T) where T\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"If the type of the appended element does not match the element type of the vector it is appended to, a MethodError is raised. In the following example, the method's type parameter T is used as the return value:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> mytypeof(x::T) where {T} = T\nmytypeof (generic function with 1 method)\n\njulia> mytypeof(1)\nInt64\n\njulia> mytypeof(1.0)\nFloat64","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Just as you can put subtype constraints on type parameters in type declarations (see Parametric Types), you can also constrain type parameters of methods:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> same_type_numeric(x::T, y::T) where {T<:Number} = true\nsame_type_numeric (generic function with 1 method)\n\njulia> same_type_numeric(x::Number, y::Number) = false\nsame_type_numeric (generic function with 2 methods)\n\njulia> same_type_numeric(1, 2)\ntrue\n\njulia> same_type_numeric(1, 2.0)\nfalse\n\njulia> same_type_numeric(1.0, 2.0)\ntrue\n\njulia> same_type_numeric(\"foo\", 2.0)\nERROR: MethodError: no method matching same_type_numeric(::String, ::Float64)\nThe function `same_type_numeric` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n same_type_numeric(!Matched::T, ::T) where T<:Number\n @ Main none:1\n same_type_numeric(!Matched::Number, ::Number)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> same_type_numeric(\"foo\", \"bar\")\nERROR: MethodError: no method matching same_type_numeric(::String, ::String)\nThe function `same_type_numeric` exists, but no method is defined for this combination of argument types.\n\njulia> same_type_numeric(Int32(1), Int64(2))\nfalse","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The same_type_numeric function behaves much like the same_type function defined above, but is only defined for pairs of numbers.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Parametric methods allow the same syntax as where expressions used to write types (see UnionAll Types). If there is only a single parameter, the enclosing curly braces (in where {T}) can be omitted, but are often preferred for clarity. Multiple parameters can be separated with commas, e.g. where {T, S<:Real}, or written using nested where, e.g. where S<:Real where T.","category":"page"},{"location":"manual/methods/#Redefining-Methods","page":"Methods","title":"Redefining Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When redefining a method or adding new methods, it is important to realize that these changes don't take effect immediately. This is key to Julia's ability to statically infer and compile code to run fast, without the usual JIT tricks and overhead. Indeed, any new method definition won't be visible to the current runtime environment, including Tasks and Threads (and any previously defined @generated functions). Let's start with an example to see what this means:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> function tryeval()\n @eval newfun() = 1\n newfun()\n end\ntryeval (generic function with 1 method)\n\njulia> tryeval()\nERROR: MethodError: no method matching newfun()\nThe applicable method may be too new: running in world age xxxx1, while current world is xxxx2.\nClosest candidates are:\n newfun() at none:1 (method too new to be called from this world context.)\n in tryeval() at none:1\n ...\n\njulia> newfun()\n1","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In this example, observe that the new definition for newfun has been created, but can't be immediately called. The new global is immediately visible to the tryeval function, so you could write return newfun (without parentheses). But neither you, nor any of your callers, nor the functions they call, or etc. can call this new method definition!","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"But there's an exception: future calls to newfun from the REPL work as expected, being able to both see and call the new definition of newfun.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"However, future calls to tryeval will continue to see the definition of newfun as it was at the previous statement at the REPL, and thus before that call to tryeval.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"You may want to try this for yourself to see how it works.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The implementation of this behavior is a \"world age counter\". This monotonically increasing value tracks each method definition operation. This allows describing \"the set of method definitions visible to a given runtime environment\" as a single number, or \"world age\". It also allows comparing the methods available in two worlds just by comparing their ordinal value. In the example above, we see that the \"current world\" (in which the method newfun exists), is one greater than the task-local \"runtime world\" that was fixed when the execution of tryeval started.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Sometimes it is necessary to get around this (for example, if you are implementing the above REPL). Fortunately, there is an easy solution: call the function using Base.invokelatest:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> function tryeval2()\n @eval newfun2() = 2\n Base.invokelatest(newfun2)\n end\ntryeval2 (generic function with 1 method)\n\njulia> tryeval2()\n2","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Finally, let's take a look at some more complex examples where this rule comes into play. Define a function f(x), which initially has one method:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x) = \"original definition\"\nf (generic function with 1 method)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Start some other operations that use f(x):","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> g(x) = f(x)\ng (generic function with 1 method)\n\njulia> t = @async f(wait()); yield();","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Now we add some new methods to f(x):","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(x::Int) = \"definition for Int\"\nf (generic function with 2 methods)\n\njulia> f(x::Type{Int}) = \"definition for Type{Int}\"\nf (generic function with 3 methods)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Compare how these results differ:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> f(1)\n\"definition for Int\"\n\njulia> g(1)\n\"definition for Int\"\n\njulia> fetch(schedule(t, 1))\n\"original definition\"\n\njulia> t = @async f(wait()); yield();\n\njulia> fetch(schedule(t, 1))\n\"definition for Int\"","category":"page"},{"location":"manual/methods/#Design-Patterns-with-Parametric-Methods","page":"Methods","title":"Design Patterns with Parametric Methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"While complex dispatch logic is not required for performance or usability, sometimes it can be the best way to express some algorithm. Here are a few common design patterns that come up sometimes when using dispatch in this way.","category":"page"},{"location":"manual/methods/#Extracting-the-type-parameter-from-a-super-type","page":"Methods","title":"Extracting the type parameter from a super-type","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Here is a correct code template for returning the element-type T of any arbitrary subtype of AbstractArray that has well-defined element type:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"abstract type AbstractArray{T, N} end\neltype(::Type{<:AbstractArray{T}}) where {T} = T","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"using so-called triangular dispatch. Note that UnionAll types, for example eltype(AbstractArray{T} where T <: Integer), do not match the above method. The implementation of eltype in Base adds a fallback method to Any for such cases.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"One common mistake is to try and get the element-type by using introspection:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"eltype_wrong(::Type{A}) where {A<:AbstractArray} = A.parameters[1]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"However, it is not hard to construct cases where this will fail:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"struct BitVector <: AbstractArray{Bool, 1}; end","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Here we have created a type BitVector which has no parameters, but where the element-type is still fully specified, with T equal to Bool!","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Another mistake is to try to walk up the type hierarchy using supertype:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"eltype_wrong(::Type{AbstractArray{T}}) where {T} = T\neltype_wrong(::Type{AbstractArray{T, N}}) where {T, N} = T\neltype_wrong(::Type{A}) where {A<:AbstractArray} = eltype_wrong(supertype(A))","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"While this works for declared types, it fails for types without supertypes:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> eltype_wrong(Union{AbstractArray{Int}, AbstractArray{Float64}})\nERROR: MethodError: no method matching supertype(::Type{Union{AbstractArray{Float64,N} where N, AbstractArray{Int64,N} where N}})\nClosest candidates are:\n supertype(::DataType) at operators.jl:43\n supertype(::UnionAll) at operators.jl:48","category":"page"},{"location":"manual/methods/#Building-a-similar-type-with-a-different-type-parameter","page":"Methods","title":"Building a similar type with a different type parameter","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When building generic code, there is often a need for constructing a similar object with some change made to the layout of the type, also necessitating a change of the type parameters. For instance, you might have some sort of abstract array with an arbitrary element type and want to write your computation on it with a specific element type. We must implement a method for each AbstractArray{T} subtype that describes how to compute this type transform. There is no general transform of one subtype into another subtype with a different parameter.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The subtypes of AbstractArray typically implement two methods to achieve this: A method to convert the input array to a subtype of a specific AbstractArray{T, N} abstract type; and a method to make a new uninitialized array with a specific element type. Sample implementations of these can be found in Julia Base. Here is a basic example usage of them, guaranteeing that input and output are of the same type:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"input = convert(AbstractArray{Eltype}, input)\noutput = similar(input, Eltype)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"As an extension of this, in cases where the algorithm needs a copy of the input array, convert is insufficient as the return value may alias the original input. Combining similar (to make the output array) and copyto! (to fill it with the input data) is a generic way to express the requirement for a mutable copy of the input argument:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"copy_with_eltype(input, Eltype) = copyto!(similar(input, Eltype), input)","category":"page"},{"location":"manual/methods/#Iterated-dispatch","page":"Methods","title":"Iterated dispatch","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"In order to dispatch a multi-level parametric argument list, often it is best to separate each level of dispatch into distinct functions. This may sound similar in approach to single-dispatch, but as we shall see below, it is still more flexible.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For example, trying to dispatch on the element-type of an array will often run into ambiguous situations. Instead, common code will dispatch first on the container type, then recurse down to a more specific method based on eltype. In most cases, the algorithms lend themselves conveniently to this hierarchical approach, while in other cases, this rigor must be resolved manually. This dispatching branching can be observed, for example, in the logic to sum two matrices:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"# First dispatch selects the map algorithm for element-wise summation.\n+(a::Matrix, b::Matrix) = map(+, a, b)\n# Then dispatch handles each element and selects the appropriate\n# common element type for the computation.\n+(a, b) = +(promote(a, b)...)\n# Once the elements have the same type, they can be added.\n# For example, via primitive operations exposed by the processor.\n+(a::Float64, b::Float64) = Core.add(a, b)","category":"page"},{"location":"manual/methods/#Trait-based-dispatch","page":"Methods","title":"Trait-based dispatch","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"A natural extension to the iterated dispatch above is to add a layer to method selection that allows to dispatch on sets of types which are independent from the sets defined by the type hierarchy. We could construct such a set by writing out a Union of the types in question, but then this set would not be extensible as Union-types cannot be altered after creation. However, such an extensible set can be programmed with a design pattern often referred to as a \"Holy-trait\".","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This pattern is implemented by defining a generic function which computes a different singleton value (or type) for each trait-set to which the function arguments may belong to. If this function is pure there is no impact on performance compared to normal dispatch.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The example in the previous section glossed over the implementation details of map and promote, which both operate in terms of these traits. When iterating over a matrix, such as in the implementation of map, one important question is what order to use to traverse the data. When AbstractArray subtypes implement the Base.IndexStyle trait, other functions such as map can dispatch on this information to pick the best algorithm (see Abstract Array Interface). This means that each subtype does not need to implement a custom version of map, since the generic definitions + trait classes will enable the system to select the fastest version. Here is a toy implementation of map illustrating the trait-based dispatch:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"map(f, a::AbstractArray, b::AbstractArray) = map(Base.IndexStyle(a, b), f, a, b)\n# generic implementation:\nmap(::Base.IndexCartesian, f, a::AbstractArray, b::AbstractArray) = ...\n# linear-indexing implementation (faster)\nmap(::Base.IndexLinear, f, a::AbstractArray, b::AbstractArray) = ...","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This trait-based approach is also present in the promote mechanism employed by the scalar +. It uses promote_type, which returns the optimal common type to compute the operation given the two types of the operands. This makes it possible to reduce the problem of implementing every function for every pair of possible type arguments, to the much smaller problem of implementing a conversion operation from each type to a common type, plus a table of preferred pair-wise promotion rules.","category":"page"},{"location":"manual/methods/#Output-type-computation","page":"Methods","title":"Output-type computation","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The discussion of trait-based promotion provides a transition into our next design pattern: computing the output element type for a matrix operation.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For implementing primitive operations, such as addition, we use the promote_type function to compute the desired output type. (As before, we saw this at work in the promote call in the call to +).","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For more complex functions on matrices, it may be necessary to compute the expected return type for a more complex sequence of operations. This is often performed by the following steps:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Write a small function op that expresses the set of operations performed by the kernel of the algorithm.\nCompute the element type R of the result matrix as promote_op(op, argument_types...), where argument_types is computed from eltype applied to each input array.\nBuild the output matrix as similar(R, dims), where dims are the desired dimensions of the output array.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For a more specific example, a generic square-matrix multiply pseudo-code might look like:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function matmul(a::AbstractMatrix, b::AbstractMatrix)\n op = (ai, bi) -> ai * bi + ai * bi\n\n ## this is insufficient because it assumes `one(eltype(a))` is constructable:\n # R = typeof(op(one(eltype(a)), one(eltype(b))))\n\n ## this fails because it assumes `a[1]` exists and is representative of all elements of the array\n # R = typeof(op(a[1], b[1]))\n\n ## this is incorrect because it assumes that `+` calls `promote_type`\n ## but this is not true for some types, such as Bool:\n # R = promote_type(ai, bi)\n\n # this is wrong, since depending on the return value\n # of type-inference is very brittle (as well as not being optimizable):\n # R = Base.return_types(op, (eltype(a), eltype(b)))\n\n ## but, finally, this works:\n R = promote_op(op, eltype(a), eltype(b))\n ## although sometimes it may give a larger type than desired\n ## it will always give a correct type\n\n output = similar(b, R, (size(a, 1), size(b, 2)))\n if size(a, 2) > 0\n for j in 1:size(b, 2)\n for i in 1:size(a, 1)\n ## here we don't use `ab = zero(R)`,\n ## since `R` might be `Any` and `zero(Any)` is not defined\n ## we also must declare `ab::R` to make the type of `ab` constant in the loop,\n ## since it is possible that typeof(a * b) != typeof(a * b + a * b) == R\n ab::R = a[i, 1] * b[1, j]\n for k in 2:size(a, 2)\n ab += a[i, k] * b[k, j]\n end\n output[i, j] = ab\n end\n end\n end\n return output\nend","category":"page"},{"location":"manual/methods/#Separate-convert-and-kernel-logic","page":"Methods","title":"Separate convert and kernel logic","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"One way to significantly cut down on compile-times and testing complexity is to isolate the logic for converting to the desired type and the computation. This lets the compiler specialize and inline the conversion logic independent from the rest of the body of the larger kernel.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This is a common pattern seen when converting from a larger class of types to the one specific argument type that is actually supported by the algorithm:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"complexfunction(arg::Int) = ...\ncomplexfunction(arg::Any) = complexfunction(convert(Int, arg))\n\nmatmul(a::T, b::T) = ...\nmatmul(a, b) = matmul(promote(a, b)...)","category":"page"},{"location":"manual/methods/#Parametrically-constrained-Varargs-methods","page":"Methods","title":"Parametrically-constrained Varargs methods","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Function parameters can also be used to constrain the number of arguments that may be supplied to a \"varargs\" function (Varargs Functions). The notation Vararg{T,N} is used to indicate such a constraint. For example:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> bar(a,b,x::Vararg{Any,2}) = (a,b,x)\nbar (generic function with 1 method)\n\njulia> bar(1,2,3)\nERROR: MethodError: no method matching bar(::Int64, ::Int64, ::Int64)\nThe function `bar` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n bar(::Any, ::Any, ::Any, !Matched::Any)\n @ Main none:1\n\nStacktrace:\n[...]\n\njulia> bar(1,2,3,4)\n(1, 2, (3, 4))\n\njulia> bar(1,2,3,4,5)\nERROR: MethodError: no method matching bar(::Int64, ::Int64, ::Int64, ::Int64, ::Int64)\nThe function `bar` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n bar(::Any, ::Any, ::Any, ::Any)\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"More usefully, it is possible to constrain varargs methods by a parameter. For example:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function getindex(A::AbstractArray{T,N}, indices::Vararg{Number,N}) where {T,N}","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"would be called only when the number of indices matches the dimensionality of the array.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When only the type of supplied arguments needs to be constrained Vararg{T} can be equivalently written as T.... For instance f(x::Int...) = x is a shorthand for f(x::Vararg{Int}) = x.","category":"page"},{"location":"manual/methods/#Note-on-Optional-and-keyword-Arguments","page":"Methods","title":"Note on Optional and keyword Arguments","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"As mentioned briefly in Functions, optional arguments are implemented as syntax for multiple method definitions. For example, this definition:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(a=1,b=2) = a+2b","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"translates to the following three methods:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(a,b) = a+2b\nf(a) = f(a,2)\nf() = f(1,2)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This means that calling f() is equivalent to calling f(1,2). In this case the result is 5, because f(1,2) invokes the first method of f above. However, this need not always be the case. If you define a fourth method that is more specialized for integers:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(a::Int,b::Int) = a-2b","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"then the result of both f() and f(1,2) is -3. In other words, optional arguments are tied to a function, not to any specific method of that function. It depends on the types of the optional arguments which method is invoked. When optional arguments are defined in terms of a global variable, the type of the optional argument may even change at run-time.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Keyword arguments behave quite differently from ordinary positional arguments. In particular, they do not participate in method dispatch. Methods are dispatched based only on positional arguments, with keyword arguments processed after the matching method is identified.","category":"page"},{"location":"manual/methods/#Function-like-objects","page":"Methods","title":"Function-like objects","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Methods are associated with types, so it is possible to make any arbitrary Julia object \"callable\" by adding methods to its type. (Such \"callable\" objects are sometimes called \"functors.\")","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For example, you can define a type that stores the coefficients of a polynomial, but behaves like a function evaluating the polynomial:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> struct Polynomial{R}\n coeffs::Vector{R}\n end\n\njulia> function (p::Polynomial)(x)\n v = p.coeffs[end]\n for i = (length(p.coeffs)-1):-1:1\n v = v*x + p.coeffs[i]\n end\n return v\n end\n\njulia> (p::Polynomial)() = p(5)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Notice that the function is specified by type instead of by name. As with normal functions there is a terse syntax form. In the function body, p will refer to the object that was called. A Polynomial can be used as follows:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> p = Polynomial([1,10,100])\nPolynomial{Int64}([1, 10, 100])\n\njulia> p(3)\n931\n\njulia> p()\n2551","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This mechanism is also the key to how type constructors and closures (inner functions that refer to their surrounding environment) work in Julia.","category":"page"},{"location":"manual/methods/#Empty-generic-functions","page":"Methods","title":"Empty generic functions","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Occasionally it is useful to introduce a generic function without yet adding methods. This can be used to separate interface definitions from implementations. It might also be done for the purpose of documentation or code readability. The syntax for this is an empty function block without a tuple of arguments:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function emptyfunc end","category":"page"},{"location":"manual/methods/#man-method-design-ambiguities","page":"Methods","title":"Method design and the avoidance of ambiguities","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Julia's method polymorphism is one of its most powerful features, yet exploiting this power can pose design challenges. In particular, in more complex method hierarchies it is not uncommon for ambiguities to arise.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Above, it was pointed out that one can resolve ambiguities like","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x, y::Int) = 1\nf(x::Int, y) = 2","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"by defining a method","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::Int, y::Int) = 3","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This is often the right strategy; however, there are circumstances where following this advice mindlessly can be counterproductive. In particular, the more methods a generic function has, the more possibilities there are for ambiguities. When your method hierarchies get more complicated than this simple example, it can be worth your while to think carefully about alternative strategies.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Below we discuss particular challenges and some alternative ways to resolve such issues.","category":"page"},{"location":"manual/methods/#Tuple-and-NTuple-arguments","page":"Methods","title":"Tuple and NTuple arguments","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Tuple (and NTuple) arguments present special challenges. For example,","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::NTuple{N,Int}) where {N} = 1\nf(x::NTuple{N,Float64}) where {N} = 2","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"are ambiguous because of the possibility that N == 0: there are no elements to determine whether the Int or Float64 variant should be called. To resolve the ambiguity, one approach is define a method for the empty tuple:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::Tuple{}) = 3","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Alternatively, for all methods but one you can insist that there is at least one element in the tuple:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::NTuple{N,Int}) where {N} = 1 # this is the fallback\nf(x::Tuple{Float64, Vararg{Float64}}) = 2 # this requires at least one Float64","category":"page"},{"location":"manual/methods/#man-methods-orthogonalize","page":"Methods","title":"Orthogonalize your design","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When you might be tempted to dispatch on two or more arguments, consider whether a \"wrapper\" function might make for a simpler design. For example, instead of writing multiple variants:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::A, y::A) = ...\nf(x::A, y::B) = ...\nf(x::B, y::A) = ...\nf(x::B, y::B) = ...","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"you might consider defining","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::A, y::A) = ...\nf(x, y) = f(g(x), g(y))","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"where g converts the argument to type A. This is a very specific example of the more general principle of orthogonal design, in which separate concepts are assigned to separate methods. Here, g will most likely need a fallback definition","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"g(x::A) = x","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"A related strategy exploits promote to bring x and y to a common type:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::T, y::T) where {T} = ...\nf(x, y) = f(promote(x, y)...)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"One risk with this design is the possibility that if there is no suitable promotion method converting x and y to the same type, the second method will recurse on itself infinitely and trigger a stack overflow.","category":"page"},{"location":"manual/methods/#Dispatch-on-one-argument-at-a-time","page":"Methods","title":"Dispatch on one argument at a time","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"If you need to dispatch on multiple arguments, and there are many fallbacks with too many combinations to make it practical to define all possible variants, then consider introducing a \"name cascade\" where (for example) you dispatch on the first argument and then call an internal method:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"f(x::A, y) = _fA(x, y)\nf(x::B, y) = _fB(x, y)","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Then the internal methods _fA and _fB can dispatch on y without concern about ambiguities with each other with respect to x.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Be aware that this strategy has at least one major disadvantage: in many cases, it is not possible for users to further customize the behavior of f by defining further specializations of your exported function f. Instead, they have to define specializations for your internal methods _fA and _fB, and this blurs the lines between exported and internal methods.","category":"page"},{"location":"manual/methods/#Abstract-containers-and-element-types","page":"Methods","title":"Abstract containers and element types","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Where possible, try to avoid defining methods that dispatch on specific element types of abstract containers. For example,","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"-(A::AbstractArray{T}, b::Date) where {T<:Date}","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"generates ambiguities for anyone who defines a method","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"-(A::MyArrayType{T}, b::T) where {T}","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The best approach is to avoid defining either of these methods: instead, rely on a generic method -(A::AbstractArray, b) and make sure this method is implemented with generic calls (like similar and -) that do the right thing for each container type and element type separately. This is just a more complex variant of the advice to orthogonalize your methods.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"When this approach is not possible, it may be worth starting a discussion with other developers about resolving the ambiguity; just because one method was defined first does not necessarily mean that it can't be modified or eliminated. As a last resort, one developer can define the \"band-aid\" method","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"-(A::MyArrayType{T}, b::Date) where {T<:Date} = ...","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"that resolves the ambiguity by brute force.","category":"page"},{"location":"manual/methods/#Complex-method-\"cascades\"-with-default-arguments","page":"Methods","title":"Complex method \"cascades\" with default arguments","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"If you are defining a method \"cascade\" that supplies defaults, be careful about dropping any arguments that correspond to potential defaults. For example, suppose you're writing a digital filtering algorithm and you have a method that handles the edges of the signal by applying padding:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function myfilter(A, kernel, ::Replicate)\n Apadded = replicate_edges(A, size(kernel))\n myfilter(Apadded, kernel) # now perform the \"real\" computation\nend","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"This will run afoul of a method that supplies default padding:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"myfilter(A, kernel) = myfilter(A, kernel, Replicate()) # replicate the edge by default","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"Together, these two methods generate an infinite recursion with A constantly growing bigger.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"The better design would be to define your call hierarchy like this:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"struct NoPad end # indicate that no padding is desired, or that it's already applied\n\nmyfilter(A, kernel) = myfilter(A, kernel, Replicate()) # default boundary conditions\n\nfunction myfilter(A, kernel, ::Replicate)\n Apadded = replicate_edges(A, size(kernel))\n myfilter(Apadded, kernel, NoPad()) # indicate the new boundary conditions\nend\n\n# other padding methods go here\n\nfunction myfilter(A, kernel, ::NoPad)\n # Here's the \"real\" implementation of the core computation\nend","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"NoPad is supplied in the same argument position as any other kind of padding, so it keeps the dispatch hierarchy well organized and with reduced likelihood of ambiguities. Moreover, it extends the \"public\" myfilter interface: a user who wants to control the padding explicitly can call the NoPad variant directly.","category":"page"},{"location":"manual/methods/#Defining-methods-in-local-scope","page":"Methods","title":"Defining methods in local scope","text":"","category":"section"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"You can define methods within a local scope, for example","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"julia> function f(x)\n g(y::Int) = y + x\n g(y) = y - x\n g\n end\nf (generic function with 1 method)\n\njulia> h = f(3);\n\njulia> h(4)\n7\n\njulia> h(4.0)\n1.0","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"However, you should not define local methods conditionally or subject to control flow, as in","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function f2(inc)\n if inc\n g(x) = x + 1\n else\n g(x) = x - 1\n end\nend\n\nfunction f3()\n function g end\n return g\n g() = 0\nend","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"as it is not clear what function will end up getting defined. In the future, it might be an error to define local methods in this manner.","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"For cases like this use anonymous functions instead:","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"function f2(inc)\n g = if inc\n x -> x + 1\n else\n x -> x - 1\n end\nend","category":"page"},{"location":"manual/methods/","page":"Methods","title":"Methods","text":"[Clarke61]: Arthur C. Clarke, Profiles of the Future (1961): Clarke's Third Law.","category":"page"},{"location":"manual/command-line-interface/#cli","page":"Command-line Interface","title":"Command-line Interface","text":"","category":"section"},{"location":"manual/command-line-interface/#Using-arguments-inside-scripts","page":"Command-line Interface","title":"Using arguments inside scripts","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"When running a script using julia, you can pass additional arguments to your script:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia script.jl arg1 arg2...","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"These additional command-line arguments are passed in the global constant ARGS. The name of the script itself is passed in as the global PROGRAM_FILE. Note that ARGS is also set when a Julia expression is given using the -e option on the command line (see the julia help output below) but PROGRAM_FILE will be empty. For example, to just print the arguments given to a script, you could do this:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'println(PROGRAM_FILE); for x in ARGS; println(x); end' foo bar\n\nfoo\nbar","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Or you could put that code into a script and run it:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ echo 'println(PROGRAM_FILE); for x in ARGS; println(x); end' > script.jl\n$ julia script.jl foo bar\nscript.jl\nfoo\nbar","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"The -- delimiter can be used to separate command-line arguments intended for the script file from arguments intended for Julia:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia --color=yes -O -- script.jl arg1 arg2..","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"See also Scripting for more information on writing Julia scripts.","category":"page"},{"location":"manual/command-line-interface/#The-Main.main-entry-point","page":"Command-line Interface","title":"The Main.main entry point","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"As of Julia, 1.11, Base exports the macro @main. This macro expands to the symbol main, but at the conclusion of executing a script or expression, julia will attempt to execute the function Main.main(ARGS) if such a function has been defined and this behavior was opted into by using the @main macro.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"This feature is intended to aid in the unification of compiled and interactive workflows. In compiled workflows, loading the code that defines the main function may be spatially and temporally separated from the invocation. However, for interactive workflows, the behavior is equivalent to explicitly calling exit(main(ARGS)) at the end of the evaluated script or expression.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"compat: Julia 1.11\nThe special entry point Main.main was added in Julia 1.11. For compatibility with prior julia versions, add an explicit @isdefined(var\"@main\") ? (@main) : exit(main(ARGS)) at the end of your scripts.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"To see this feature in action, consider the following definition, which will execute the print function despite there being no explicit call to main:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e '(@main)(ARGS) = println(\"Hello World!\")'\nHello World!\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Only the main binding in the Main module has this behavior and only if the macro @main was used within the defining module.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"For example, using hello instead of main will not result in the hello function executing:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'hello(ARGS) = println(\"Hello World!\")'\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"and neither will a plain definition of main:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'main(ARGS) = println(\"Hello World!\")'\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"However, the opt-in need not occur at definition time:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'main(ARGS) = println(\"Hello World!\"); @main'\nHello World!\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"The main binding may be imported from a package. A hello world package defined as","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"module Hello\n\nexport main\n(@main)(ARGS) = println(\"Hello from the package!\")\n\nend","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"may be used as:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ julia -e 'using Hello'\nHello from the package!\n$ julia -e 'import Hello' # N.B.: Execution depends on the binding not whether the package is loaded\n$","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"However, note that the current best practice recommendation is to not mix application and reusable library code in the same package. Helper applications may be distributed as separate packages or as scripts with separate main entry points in a package's bin folder.","category":"page"},{"location":"manual/command-line-interface/#Parallel-mode","page":"Command-line Interface","title":"Parallel mode","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Julia can be started in parallel mode with either the -p or the --machine-file options. -p n will launch an additional n worker processes, while --machine-file file will launch a worker for each line in file file. The machines defined in file must be accessible via a password-less ssh login, with Julia installed at the same location as the current host. Each machine definition takes the form [count*][user@]host[:port] [bind_addr[:port]]. user defaults to current user, port to the standard ssh port. count is the number of workers to spawn on the node, and defaults to 1. The optional bind-to bind_addr[:port] specifies the IP address and port that other workers should use to connect to this worker.","category":"page"},{"location":"manual/command-line-interface/#Startup-file","page":"Command-line Interface","title":"Startup file","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"If you have code that you want executed whenever Julia is run, you can put it in ~/.julia/config/startup.jl:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"$ echo 'println(\"Greetings! 你好! 안녕하세요?\")' > ~/.julia/config/startup.jl\n$ julia\nGreetings! 你好! 안녕하세요?\n\n...","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Note that although you should have a ~/.julia directory once you've run Julia for the first time, you may need to create the ~/.julia/config folder and the ~/.julia/config/startup.jl file if you use it.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"To have startup code run only in The Julia REPL (and not when julia is e.g. run on a script), use atreplinit in startup.jl:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"atreplinit() do repl\n # ...\nend","category":"page"},{"location":"manual/command-line-interface/#command-line-interface","page":"Command-line Interface","title":"Command-line switches for Julia","text":"","category":"section"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"There are various ways to run Julia code and provide options, similar to those available for the perl and ruby programs:","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"julia [switches] -- [programfile] [args...]","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"The following is a complete list of command-line switches available when launching julia (a '*' marks the default value, if applicable; settings marked '($)' may trigger package precompilation):","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"Switch Description\n-v, --version Display version information\n-h, --help Print command-line options (this message).\n--help-hidden Uncommon options not shown by -h\n--project[={|@.}] Set as the active project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.\n-J, --sysimage Start up with the given system image file\n-H, --home Set location of julia executable\n--startup-file={yes*|no} Load JULIA_DEPOT_PATH/config/startup.jl; if JULIA_DEPOT_PATH environment variable is unset, load ~/.julia/config/startup.jl\n--handle-signals={yes*|no} Enable or disable Julia's default signal handlers\n--sysimage-native-code={yes*|no} Use native code from system image if available\n`–compiled-modules={yes*|no|existing strict}`\n`–pkgimages={yes*|no existing}`\n-e, --eval Evaluate \n-E, --print Evaluate and display the result\n-L, --load Load immediately on all processors\n-t, --threads {N|auto} Enable N threads; auto tries to infer a useful default number of threads to use but the exact behavior might change in the future. Currently, auto uses the number of CPUs assigned to this julia process based on the OS-specific affinity assignment interface, if supported (Linux and Windows). If this is not supported (macOS) or process affinity is not configured, it uses the number of CPU threads.\n--gcthreads=N[,M] Use N threads for the mark phase of GC and M (0 or 1) threads for the concurrent sweeping phase of GC. N is set to half of the number of compute threads and M is set to 0 if unspecified.\n-p, --procs {N|auto} Integer value N launches N additional local worker processes; auto launches as many workers as the number of local CPU threads (logical cores)\n--machine-file Run processes on hosts listed in \n-i Interactive mode; REPL runs and isinteractive() is true\n-q, --quiet Quiet startup: no banner, suppress REPL warnings\n--banner={yes|no|auto*} Enable or disable startup banner\n--color={yes|no|auto*} Enable or disable color text\n--history-file={yes*|no} Load or save history\n--depwarn={yes|no*|error} Enable or disable syntax and method deprecation warnings (error turns warnings into errors)\n--warn-overwrite={yes|no*} Enable or disable method overwrite warnings\n--warn-scope={yes*|no} Enable or disable warning for ambiguous top-level scope\n-C, --cpu-target Limit usage of CPU features up to ; set to help to see the available options\n-O, --optimize={0,1,2*,3} Set the optimization level (level is 3 if -O is used without a level) ($)\n--min-optlevel={0*,1,2,3} Set the lower bound on per-module optimization\n-g, --debug-info={0,1*,2} Set the level of debug info generation (level is 2 if -g is used without a level) ($)\n--inline={yes|no} Control whether inlining is permitted, including overriding @inline declarations\n--check-bounds={yes|no|auto*} Emit bounds checks always, never, or respect @inbounds declarations ($)\n--math-mode={ieee,fast} Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)\n--code-coverage[={none*|user|all}] Count executions of source lines (omitting setting is equivalent to user)\n--code-coverage=@ Count executions but only in files that fall under the given file path/directory. The @ prefix is required to select this option. A @ with no path will track the current directory.\n--code-coverage=tracefile.info Append coverage information to the LCOV tracefile (filename supports format tokens).\n--track-allocation[={none*|user|all}] Count bytes allocated by each source line (omitting setting is equivalent to \"user\")\n--track-allocation=@ Count bytes but only in files that fall under the given file path/directory. The @ prefix is required to select this option. A @ with no path will track the current directory.\n--bug-report=KIND Launch a bug report session. It can be used to start a REPL, run a script, or evaluate expressions. It first tries to use BugReporting.jl installed in current environment and falls back to the latest compatible BugReporting.jl if not. For more information, see --bug-report=help.\n--compile={yes*|no|all|min} Enable or disable JIT compiler, or request exhaustive or minimal compilation\n--output-o Generate an object file (including system image data)\n--output-ji Generate a system image data file (.ji)\n--strip-metadata Remove docstrings and source location info from system image\n--strip-ir Remove IR (intermediate representation) of compiled functions\n--output-unopt-bc Generate unoptimized LLVM bitcode (.bc)\n--output-bc Generate LLVM bitcode (.bc)\n--output-asm Generate an assembly file (.s)\n--output-incremental={yes|no*} Generate an incremental output file (rather than complete)\n--trace-compile={stderr,name} Print precompile statements for methods compiled during execution or save to a path\n--image-codegen Force generate code in imaging mode\n--heap-size-hint= Forces garbage collection if memory usage is higher than the given value. The value may be specified as a number of bytes, optionally in units of KB, MB, GB, or TB, or as a percentage of physical memory with %.","category":"page"},{"location":"manual/command-line-interface/","page":"Command-line Interface","title":"Command-line Interface","text":"compat: Julia 1.1\nIn Julia 1.0, the default --project=@. option did not search up from the root directory of a Git repository for the Project.toml file. From Julia 1.1 forward, it does.","category":"page"},{"location":"devdocs/sanitizers/#Sanitizer-support","page":"Sanitizer support","title":"Sanitizer support","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Sanitizers can be used in custom Julia builds to make it easier to detect certain kinds of errors in Julia's internal C/C++ code.","category":"page"},{"location":"devdocs/sanitizers/#Address-Sanitizer:-easy-build","page":"Sanitizer support","title":"Address Sanitizer: easy build","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"From a source-checkout of Julia, you should be able to build a version supporting address sanitization in Julia and LLVM as follows:","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"$ mkdir /tmp/julia\n$ contrib/asan/build.sh /tmp/julia/","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Here we've chosen /tmp/julia as a build directory, but you can choose whatever you wish. Once built, run the workload you wish to test with /tmp/julia/julia. Memory bugs will result in errors.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"If you require customization or further detail, see the documentation below.","category":"page"},{"location":"devdocs/sanitizers/#General-considerations","page":"Sanitizer support","title":"General considerations","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Using Clang's sanitizers obviously requires you to use Clang (USECLANG=1), but there's another catch: most sanitizers require a run-time library, provided by the host compiler, while the instrumented code generated by Julia's JIT relies on functionality from that library. This implies that the LLVM version of your host compiler must match that of the LLVM library used within Julia.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"An easy solution is to have a dedicated build folder for providing a matching toolchain, by building with BUILD_LLVM_CLANG=1. You can then refer to this toolchain from another build folder by specifying USECLANG=1 while overriding the CC and CXX variables.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"The sanitizers error out when they detect a shared library being opened using RTLD_DEEPBIND (ref: google/sanitizers#611). Since libblastrampoline by default uses RTLD_DEEPBIND, we need to set the environment variable LBT_USE_RTLD_DEEPBIND=0 when using a sanitizer.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"To use one of of the sanitizers set SANITIZE=1 and then the appropriate flag for the sanitizer you want to use.","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"On macOS, this might need some extra flags also to work. Altogether, it might look like this, plus one or more of the SANITIZE_* flags listed below:","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"make -C deps USE_BINARYBUILDER_LLVM=0 LLVM_VER=svn stage-llvm\n\nmake -C src SANITIZE=1 USECLANG=1 \\\n CC=~+/deps/scratch/llvm-svn/build_Release/bin/clang \\\n CXX=~+/deps/scratch/llvm-svn/build_Release/bin/clang++ \\\n CPPFLAGS=\"-isysroot $(xcode-select -p)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk\" \\\n CXXFLAGS=\"-isystem $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1\"","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"(or put these into your Make.user, so you don't need to remember them every time).","category":"page"},{"location":"devdocs/sanitizers/#Address-Sanitizer-(ASAN)","page":"Sanitizer support","title":"Address Sanitizer (ASAN)","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"For detecting or debugging memory bugs, you can use Clang's address sanitizer (ASAN). By compiling with SANITIZE_ADDRESS=1 you enable ASAN for the Julia compiler and its generated code. In addition, you can specify LLVM_SANITIZE=1 to sanitize the LLVM library as well. Note that these options incur a high performance and memory cost. For example, using ASAN for Julia and LLVM makes testall1 take 8-10 times as long while using 20 times as much memory (this can be reduced to respectively a factor of 3 and 4 by using the options described below).","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"By default, Julia sets the allow_user_segv_handler=1 ASAN flag, which is required for signal delivery to work properly. You can define other options using the ASAN_OPTIONS environment flag, in which case you'll need to repeat the default option mentioned before. For example, memory usage can be reduced by specifying fast_unwind_on_malloc=0 and malloc_context_size=2, at the cost of backtrace accuracy. For now, Julia also sets detect_leaks=0, but this should be removed in the future.","category":"page"},{"location":"devdocs/sanitizers/#Example-setup","page":"Sanitizer support","title":"Example setup","text":"","category":"section"},{"location":"devdocs/sanitizers/#Step-1:-Install-toolchain","page":"Sanitizer support","title":"Step 1: Install toolchain","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Checkout a Git worktree (or create out-of-tree build directory) at $TOOLCHAIN_WORKTREE and create a config file $TOOLCHAIN_WORKTREE/Make.user with","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"USE_BINARYBUILDER_LLVM=1\nBUILD_LLVM_CLANG=1","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Run:","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"cd $TOOLCHAIN_WORKTREE\nmake -C deps install-llvm install-clang install-llvm-tools","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"to install toolchain binaries in $TOOLCHAIN_WORKTREE/usr/tools","category":"page"},{"location":"devdocs/sanitizers/#Step-2:-Build-Julia-with-ASAN","page":"Sanitizer support","title":"Step 2: Build Julia with ASAN","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Checkout a Git worktree (or create out-of-tree build directory) at $BUILD_WORKTREE and create a config file $BUILD_WORKTREE/Make.user with","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"TOOLCHAIN=$(TOOLCHAIN_WORKTREE)/usr/tools\n\n# use our new toolchain\nUSECLANG=1\noverride CC=$(TOOLCHAIN)/clang\noverride CXX=$(TOOLCHAIN)/clang++\nexport ASAN_SYMBOLIZER_PATH=$(TOOLCHAIN)/llvm-symbolizer\n\nUSE_BINARYBUILDER_LLVM=1\n\noverride SANITIZE=1\noverride SANITIZE_ADDRESS=1\n\n# make the GC use regular malloc/frees, which are hooked by ASAN\noverride WITH_GC_DEBUG_ENV=1\n\n# default to a debug build for better line number reporting\noverride JULIA_BUILD_MODE=debug\n\n# make ASAN consume less memory\nexport ASAN_OPTIONS=detect_leaks=0:fast_unwind_on_malloc=0:allow_user_segv_handler=1:malloc_context_size=2\n\nJULIA_PRECOMPILE=1\n\n# tell libblastrampoline to not use RTLD_DEEPBIND\nexport LBT_USE_RTLD_DEEPBIND=0","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"Run:","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"cd $BUILD_WORKTREE\nmake debug","category":"page"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"to build julia-debug with ASAN.","category":"page"},{"location":"devdocs/sanitizers/#Memory-Sanitizer-(MSAN)","page":"Sanitizer support","title":"Memory Sanitizer (MSAN)","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"For detecting use of uninitialized memory, you can use Clang's memory sanitizer (MSAN) by compiling with SANITIZE_MEMORY=1.","category":"page"},{"location":"devdocs/sanitizers/#Thread-Sanitizer-(TSAN)","page":"Sanitizer support","title":"Thread Sanitizer (TSAN)","text":"","category":"section"},{"location":"devdocs/sanitizers/","page":"Sanitizer support","title":"Sanitizer support","text":"For debugging data-races and other threading related issues you can use Clang's thread sanitizer (TSAN) by compiling with SANITIZE_THREAD=1.","category":"page"},{"location":"devdocs/build/arm/#ARM-(Linux)","page":"ARM (Linux)","title":"ARM (Linux)","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia fully supports ARMv8 (AArch64) processors, and supports ARMv7 and ARMv6 (AArch32) with some caveats. This file provides general guidelines for compilation, in addition to instructions for specific devices.","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"A list of known issues for ARM is available. If you encounter difficulties, please create an issue including the output from cat /proc/cpuinfo.","category":"page"},{"location":"devdocs/build/arm/#32-bit-(ARMv6,-ARMv7)","page":"ARM (Linux)","title":"32-bit (ARMv6, ARMv7)","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia has been successfully compiled on several variants of the following ARMv6 & ARMv7 devices:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"ARMv7 / Cortex A15 Samsung Chromebooks running Ubuntu Linux under Crouton;\nRaspberry Pi.\nOdroid.","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia requires at least the armv6 and vfpv2 instruction sets. It's recommended to use armv7-a. armv5 or soft float are not supported.","category":"page"},{"location":"devdocs/build/arm/#Raspberry-Pi-1-/-Raspberry-Pi-Zero","page":"ARM (Linux)","title":"Raspberry Pi 1 / Raspberry Pi Zero","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"If the type of ARM CPU used in the Raspberry Pi is not detected by LLVM, then explicitly set the CPU target by adding the following to Make.user:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"JULIA_CPU_TARGET=arm1176jzf-s","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"To complete the build, you may need to increase the swap file size. To do so, edit /etc/dphys-swapfile, changing the line:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"CONF_SWAPSIZE=100","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"to:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"CONF_SWAPSIZE=512","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"before restarting the swapfile service:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"sudo /etc/init.d/dphys-swapfile stop\nsudo /etc/init.d/dphys-swapfile start","category":"page"},{"location":"devdocs/build/arm/#Raspberry-Pi-2","page":"ARM (Linux)","title":"Raspberry Pi 2","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"The type of ARM CPU used in the Raspberry Pi 2 is not detected by LLVM. Explicitly set the CPU target by adding the following to Make.user:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"JULIA_CPU_TARGET=cortex-a7","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Depending on the exact compiler and distribution, there might be a build failure due to unsupported inline assembly. In that case, add MCPU=armv7-a to Make.user.","category":"page"},{"location":"devdocs/build/arm/#AArch64-(ARMv8)","page":"ARM (Linux)","title":"AArch64 (ARMv8)","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia has been successfully built on the following ARMv8 devices:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"nVidia Jetson TX1 & TX2;\nX-Gene 1;\nOverdrive 3000;\nCavium ThunderX on packet.net.","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Compilation on ARMv8-A requires that Make.user is configured as follows:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"MCPU=armv8-a","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Starting from Julia v1.10, JITLink is automatically enabled on this architecture for all operating systems when linking to LLVM 15 or later versions. Due to a bug in LLVM memory manager, non-trivial workloads may generate too many memory mappings that on Linux can exceed the limit of memory mappings (mmap) set in the file /proc/sys/vm/max_map_count, resulting in an error like","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"JIT session error: Cannot allocate memory","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Should this happen, ask your system administrator to increase the limit of memory mappings for example with the command","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"sysctl -w vm.max_map_count=262144","category":"page"},{"location":"devdocs/build/arm/#nVidia-Jetson-TX2","page":"ARM (Linux)","title":"nVidia Jetson TX2","text":"","category":"section"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"Julia builds and runs on the nVidia Jetson TX2 platform with minimal configuration changes.","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"After configuring Make.user as per the AArch64 instructions in this document, follow the general build instructions. The majority of the build dependencies specified in the instructions are installed by the default configuration flashed by Jetpack 3.0. The remaining tools can be installed by issuing the following command:","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"sudo apt-get install gfortran wget cmake","category":"page"},{"location":"devdocs/build/arm/","page":"ARM (Linux)","title":"ARM (Linux)","text":"A full parallel build, including LLVM, will complete in around two hours. All tests pass and CUDA functionality is available through, e.g., CUDAdrv.","category":"page"},{"location":"stdlib/Dates/#Dates","page":"Dates","title":"Dates","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"DocTestSetup = :(using Dates)","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The Dates module provides two types for working with dates: Date and DateTime, representing day and millisecond precision, respectively; both are subtypes of the abstract TimeType. The motivation for distinct types is simple: some operations are much simpler, both in terms of code and mental reasoning, when the complexities of greater precision don't have to be dealt with. For example, since the Date type only resolves to the precision of a single date (i.e. no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer time, and leap seconds are unnecessary and avoided.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Both Date and DateTime are basically immutable Int64 wrappers. The single instant field of either type is actually a UTInstant{P} type, which represents a continuously increasing machine timeline based on the UT second [1]. The DateTime type is not aware of time zones (naive, in Python parlance), analogous to a LocalDateTime in Java 8. Additional time zone functionality can be added through the TimeZones.jl package, which compiles the IANA time zone database. Both Date and DateTime are based on the ISO 8601 standard, which follows the proleptic Gregorian calendar. One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. The ISO standard, however, states that 1 BC/BCE is year zero, so 0000-12-31 is the day before 0001-01-01, and year -0001 (yes, negative one for the year) is 2 BC/BCE, year -0002 is 3 BC/BCE, etc.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"[1]: The notion of the UT second is actually quite fundamental. There are basically two different notions of time generally accepted, one based on the physical rotation of the earth (one full rotation = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! Think about it, a \"UT second\", as defined relative to the rotation of the earth, may have a different absolute length depending on the day! Anyway, the fact that Date and DateTime are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds and all their complexity can be avoided. This basis of time is formally called UT or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every day has 24 hours and leads to more natural calculations when working with calendar dates.","category":"page"},{"location":"stdlib/Dates/#Constructors","page":"Dates","title":"Constructors","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Date and DateTime types can be constructed by integer or Period types, by parsing, or through adjusters (more on those later):","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> DateTime(2013)\n2013-01-01T00:00:00\n\njulia> DateTime(2013,7)\n2013-07-01T00:00:00\n\njulia> DateTime(2013,7,1)\n2013-07-01T00:00:00\n\njulia> DateTime(2013,7,1,12)\n2013-07-01T12:00:00\n\njulia> DateTime(2013,7,1,12,30)\n2013-07-01T12:30:00\n\njulia> DateTime(2013,7,1,12,30,59)\n2013-07-01T12:30:59\n\njulia> DateTime(2013,7,1,12,30,59,1)\n2013-07-01T12:30:59.001\n\njulia> Date(2013)\n2013-01-01\n\njulia> Date(2013,7)\n2013-07-01\n\njulia> Date(2013,7,1)\n2013-07-01\n\njulia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1))\n2013-07-01\n\njulia> Date(Dates.Month(7),Dates.Year(2013))\n2013-07-01","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Date or DateTime parsing is accomplished by the use of format strings. Format strings work by the notion of defining delimited or fixed-width \"slots\" that contain a period to parse and passing the text to parse and format string to a Date or DateTime constructor, of the form Date(\"2015-01-01\",dateformat\"y-m-d\") or DateTime(\"20150101\",dateformat\"yyyymmdd\").","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent periods; so \"y-m-d\" lets the parser know that between the first and second slots in a date string like \"2014-07-16\", it should find the - character. The y, m, and d characters let the parser know which periods to parse in each slot.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As in the case of constructors above such as Date(2013), delimited DateFormats allow for missing parts of dates and times so long as the preceding parts are given. The other parts are given the usual default values. For example, Date(\"1981-03\", dateformat\"y-m-d\") returns 1981-03-01, whilst Date(\"31/12\", dateformat\"d/m/y\") gives 0001-12-31. (Note that the default year is 1 AD/CE.) An empty string, however, always throws an ArgumentError.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Fixed-width slots are specified by repeating the period character the number of times corresponding to the width with no delimiter between characters. So dateformat\"yyyymmdd\" would correspond to a date string like \"20140716\". The parser distinguishes a fixed-width slot by the absence of a delimiter, noting the transition \"yyyymm\" from one period character to the next.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Support for text-form month parsing is also supported through the u and U characters, for abbreviated and full-length month names, respectively. By default, only English month names are supported, so u corresponds to \"Jan\", \"Feb\", \"Mar\", etc. And U corresponds to \"January\", \"February\", \"March\", etc. Similar to other name=>value mapping functions dayname and monthname, custom locales can be loaded by passing in the locale=>Dict{String,Int} mapping to the MONTHTOVALUEABBR and MONTHTOVALUE dicts for abbreviated and full-name month names, respectively.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The above examples used the dateformat\"\" string macro. This macro creates a DateFormat object once when the macro is expanded and uses the same DateFormat object even if a code snippet is run multiple times.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> for i = 1:10^5\n Date(\"2015-01-01\", dateformat\"y-m-d\")\n end","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Or you can create the DateFormat object explicitly:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> df = DateFormat(\"y-m-d\");\n\njulia> dt = Date(\"2015-01-01\",df)\n2015-01-01\n\njulia> dt2 = Date(\"2015-01-02\",df)\n2015-01-02","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Alternatively, use broadcasting:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> years = [\"2015\", \"2016\"];\n\njulia> Date.(years, DateFormat(\"yyyy\"))\n2-element Vector{Date}:\n 2015-01-01\n 2016-01-01","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"For convenience, you may pass the format string directly (e.g., Date(\"2015-01-01\",\"y-m-d\")), although this form incurs performance costs if you are parsing the same format repeatedly, as it internally creates a new DateFormat object each time.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As well as via the constructors, a Date or DateTime can be constructed from strings using the parse and tryparse functions, but with an optional third argument of type DateFormat specifying the format; for example, parse(Date, \"06.23.2013\", dateformat\"m.d.y\"), or tryparse(DateTime, \"1999-12-31T23:59:59\") which uses the default format. The notable difference between the functions is that with tryparse, an error is not thrown if the string is empty or in an invalid format; instead nothing is returned.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"compat: Julia 1.9\nBefore Julia 1.9, empty strings could be passed to constructors and parse without error, returning as appropriate DateTime(1), Date(1) or Time(0). Likewise, tryparse did not return nothing.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"A full suite of parsing and formatting tests and examples is available in stdlib/Dates/test/io.jl.","category":"page"},{"location":"stdlib/Dates/#Durations/Comparisons","page":"Dates","title":"Durations/Comparisons","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Finding the length of time between two Date or DateTime is straightforward given their underlying representation as UTInstant{Day} and UTInstant{Millisecond}, respectively. The difference between Date is returned in the number of Day, and DateTime in the number of Millisecond. Similarly, comparing TimeType is a simple matter of comparing the underlying machine instants (which in turn compares the internal Int64 values).","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> dt = Date(2012,2,29)\n2012-02-29\n\njulia> dt2 = Date(2000,2,1)\n2000-02-01\n\njulia> dump(dt)\nDate\n instant: Dates.UTInstant{Day}\n periods: Day\n value: Int64 734562\n\njulia> dump(dt2)\nDate\n instant: Dates.UTInstant{Day}\n periods: Day\n value: Int64 730151\n\njulia> dt > dt2\ntrue\n\njulia> dt != dt2\ntrue\n\njulia> dt + dt2\nERROR: MethodError: no method matching +(::Date, ::Date)\n[...]\n\njulia> dt * dt2\nERROR: MethodError: no method matching *(::Date, ::Date)\n[...]\n\njulia> dt / dt2\nERROR: MethodError: no method matching /(::Date, ::Date)\n\njulia> dt - dt2\n4411 days\n\njulia> dt2 - dt\n-4411 days\n\njulia> dt = DateTime(2012,2,29)\n2012-02-29T00:00:00\n\njulia> dt2 = DateTime(2000,2,1)\n2000-02-01T00:00:00\n\njulia> dt - dt2\n381110400000 milliseconds","category":"page"},{"location":"stdlib/Dates/#Accessor-Functions","page":"Dates","title":"Accessor Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Because the Date and DateTime types are stored as single Int64 values, date parts or fields can be retrieved through accessor functions. The lowercase accessors return the field as an integer:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> t = Date(2014, 1, 31)\n2014-01-31\n\njulia> Dates.year(t)\n2014\n\njulia> Dates.month(t)\n1\n\njulia> Dates.week(t)\n5\n\njulia> Dates.day(t)\n31","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"While propercase return the same value in the corresponding Period type:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.Year(t)\n2014 years\n\njulia> Dates.Day(t)\n31 days","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Compound methods are provided because it is more efficient to access multiple fields at the same time than individually:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.yearmonth(t)\n(2014, 1)\n\njulia> Dates.monthday(t)\n(1, 31)\n\njulia> Dates.yearmonthday(t)\n(2014, 1, 31)","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"One may also access the underlying UTInstant or integer value:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> dump(t)\nDate\n instant: Dates.UTInstant{Day}\n periods: Day\n value: Int64 735264\n\njulia> t.instant\nDates.UTInstant{Day}(Day(735264))\n\njulia> Dates.value(t)\n735264","category":"page"},{"location":"stdlib/Dates/#Query-Functions","page":"Dates","title":"Query Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Query functions provide calendrical information about a TimeType. They include information about the day of the week:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> t = Date(2014, 1, 31)\n2014-01-31\n\njulia> Dates.dayofweek(t)\n5\n\njulia> Dates.dayname(t)\n\"Friday\"\n\njulia> Dates.dayofweekofmonth(t) # 5th Friday of January\n5","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Month of the year:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.monthname(t)\n\"January\"\n\njulia> Dates.daysinmonth(t)\n31","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As well as information about the TimeType's year and quarter:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.isleapyear(t)\nfalse\n\njulia> Dates.dayofyear(t)\n31\n\njulia> Dates.quarterofyear(t)\n1\n\njulia> Dates.dayofquarter(t)\n31","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The dayname and monthname methods can also take an optional locale keyword that can be used to return the name of the day or month of the year for other languages/locales. There are also versions of these functions returning the abbreviated names, namely dayabbr and monthabbr. First the mapping is loaded into the LOCALES variable:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> french_months = [\"janvier\", \"février\", \"mars\", \"avril\", \"mai\", \"juin\",\n \"juillet\", \"août\", \"septembre\", \"octobre\", \"novembre\", \"décembre\"];\n\njulia> french_months_abbrev = [\"janv\",\"févr\",\"mars\",\"avril\",\"mai\",\"juin\",\n \"juil\",\"août\",\"sept\",\"oct\",\"nov\",\"déc\"];\n\njulia> french_days = [\"lundi\",\"mardi\",\"mercredi\",\"jeudi\",\"vendredi\",\"samedi\",\"dimanche\"];\n\njulia> Dates.LOCALES[\"french\"] = Dates.DateLocale(french_months, french_months_abbrev, french_days, [\"\"]);","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The above mentioned functions can then be used to perform the queries:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.dayname(t;locale=\"french\")\n\"vendredi\"\n\njulia> Dates.monthname(t;locale=\"french\")\n\"janvier\"\n\njulia> Dates.monthabbr(t;locale=\"french\")\n\"janv\"","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Since the abbreviated versions of the days are not loaded, trying to use the function dayabbr will throw an error.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.dayabbr(t;locale=\"french\")\nERROR: BoundsError: attempt to access 1-element Vector{String} at index [5]\nStacktrace:\n[...]","category":"page"},{"location":"stdlib/Dates/#TimeType-Period-Arithmetic","page":"Dates","title":"TimeType-Period Arithmetic","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"It's good practice when using any language/date framework to be familiar with how date-period arithmetic is handled as there are some tricky issues to deal with (though much less so for day-precision types).","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The Dates module approach tries to follow the simple principle of trying to change as little as possible when doing Period arithmetic. This approach is also often known as calendrical arithmetic or what you would probably guess if someone were to ask you the same calculation in a conversation. Why all the fuss about this? Let's take a classic example: add 1 month to January 31st, 2014. What's the answer? Javascript will say March 3 (assumes 31 days). PHP says March 2 (assumes 30 days). The fact is, there is no right answer. In the Dates module, it gives the result of February 28th. How does it figure that out? Consider the classic 7-7-7 gambling game in casinos.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. Then the day number is checked if it is greater than the last valid day of the new month; if it is (as in the case above), the day number is adjusted down to the last valid day (28). What are the ramifications with this approach? Go ahead and add another month to our date, 2014-02-28 + Month(1) == 2014-03-28. What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things in different orders results in different outcomes). For example:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1)\n2014-02-28\n\njulia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1)\n2014-03-01","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"What's going on there? In the first line, we're adding 1 day to January 29th, which results in 2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. In the second example, we add 1 month first, where we get 2014-02-29, which adjusts down to 2014-02-28, and then add 1 day, which results in 2014-03-01. One design principle that helps in this case is that, in the presence of multiple Periods, the operations will be ordered by the Periods' types, not their value or positional order; this means Year will always be added first, then Month, then Week, etc. Hence the following does result in associativity and Just Works:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1)\n2014-03-01\n\njulia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1)\n2014-03-01","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Tricky? Perhaps. What is an innocent Dates user to do? The bottom line is to be aware that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected results, but otherwise, everything should work as expected. Thankfully, that's pretty much the extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the \"joys\" of dealing with daylight savings, leap seconds, etc.).","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As a bonus, all period arithmetic objects work directly with ranges:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3)\nDate(\"2014-01-29\"):Day(1):Date(\"2014-02-03\")\n\njulia> collect(dr)\n6-element Vector{Date}:\n 2014-01-29\n 2014-01-30\n 2014-01-31\n 2014-02-01\n 2014-02-02\n 2014-02-03\n\njulia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29)\nDate(\"2014-01-29\"):Month(1):Date(\"2014-07-29\")\n\njulia> collect(dr)\n7-element Vector{Date}:\n 2014-01-29\n 2014-02-28\n 2014-03-29\n 2014-04-29\n 2014-05-29\n 2014-06-29\n 2014-07-29","category":"page"},{"location":"stdlib/Dates/#Adjuster-Functions","page":"Dates","title":"Adjuster Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As convenient as date-period arithmetic is, often the kinds of calculations needed on dates take on a calendrical or temporal nature rather than a fixed number of periods. Holidays are a perfect example; most follow rules such as \"Memorial Day = Last Monday of May\", or \"Thanksgiving = 4th Thursday of November\". These kinds of temporal expressions deal with rules relative to the calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The Dates module provides the adjuster API through several convenient methods that aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal with the first and last of weeks, months, quarters, and years. They each take a single TimeType as input and return or adjust to the first or last of the desired period relative to the input.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week\n2014-07-14\n\njulia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month\n2014-07-31\n\njulia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter\n2014-09-30","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The next two higher-order methods, tonext, and toprev, generalize working with temporal expressions by taking a DateFunction as first argument, along with a starting TimeType. A DateFunction is just a function, usually anonymous, that takes a single TimeType as input and returns a Bool, true indicating a satisfied adjustment criterion. For example:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday\n\njulia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday\n2014-07-15\n\njulia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments\n2014-07-15","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"This is useful with the do-block syntax for more complex temporal expressions:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> Dates.tonext(Date(2014,7,13)) do x\n # Return true on the 4th Thursday of November (Thanksgiving)\n Dates.dayofweek(x) == Dates.Thursday &&\n Dates.dayofweekofmonth(x) == 4 &&\n Dates.month(x) == Dates.November\n end\n2014-11-27","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The Base.filter method can be used to obtain all valid dates/moments in a specified range:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"# Pittsburgh street cleaning; Every 2nd Tuesday from April to November\n# Date range from January 1st, 2014 to January 1st, 2015\njulia> dr = Dates.Date(2014):Day(1):Dates.Date(2015);\n\njulia> filter(dr) do x\n Dates.dayofweek(x) == Dates.Tue &&\n Dates.April <= Dates.month(x) <= Dates.Nov &&\n Dates.dayofweekofmonth(x) == 2\n end\n8-element Vector{Date}:\n 2014-04-08\n 2014-05-13\n 2014-06-10\n 2014-07-08\n 2014-08-12\n 2014-09-09\n 2014-10-14\n 2014-11-11","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Additional examples and tests are available in stdlib/Dates/test/adjusters.jl.","category":"page"},{"location":"stdlib/Dates/#Period-Types","page":"Dates","title":"Period Types","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. Or a year could represent 365 or 366 days in the case of a leap year. Period types are simple Int64 wrappers and are constructed by wrapping any Int64 convertible type, i.e. Year(1) or Month(3.0). Arithmetic between Period of the same type behave like integers, and limited Period-Real arithmetic is available. You can extract the underlying integer with Dates.value.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> y1 = Dates.Year(1)\n1 year\n\njulia> y2 = Dates.Year(2)\n2 years\n\njulia> y3 = Dates.Year(10)\n10 years\n\njulia> y1 + y2\n3 years\n\njulia> div(y3,y2)\n5\n\njulia> y3 - y2\n8 years\n\njulia> y3 % y2\n0 years\n\njulia> div(y3,3) # mirrors integer division\n3 years\n\njulia> Dates.value(Dates.Millisecond(10))\n10","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Representing periods or durations that are not integer multiples of the basic types can be achieved with the Dates.CompoundPeriod type. Compound periods may be constructed manually from simple Period types. Additionally, the canonicalize function can be used to break down a period into a Dates.CompoundPeriod. This is particularly useful to convert a duration, e.g., a difference of two DateTime, into a more convenient representation.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> cp = Dates.CompoundPeriod(Day(1),Minute(1))\n1 day, 1 minute\n\njulia> t1 = DateTime(2018,8,8,16,58,00)\n2018-08-08T16:58:00\n\njulia> t2 = DateTime(2021,6,23,10,00,00)\n2021-06-23T10:00:00\n\njulia> canonicalize(t2-t1) # creates a CompoundPeriod\n149 weeks, 6 days, 17 hours, 2 minutes","category":"page"},{"location":"stdlib/Dates/#Rounding","page":"Dates","title":"Rounding","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Date and DateTime values can be rounded to a specified resolution (e.g., 1 month or 15 minutes) with floor, ceil, or round:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> floor(Date(1985, 8, 16), Dates.Month)\n1985-08-01\n\njulia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15))\n2013-02-13T00:45:00\n\njulia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day)\n2016-08-07T00:00:00","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Unlike the numeric round method, which breaks ties toward the even number by default, the TimeTyperound method uses the RoundNearestTiesUp rounding mode. (It's difficult to guess what breaking ties to nearest \"even\" TimeType would entail.) Further details on the available RoundingMode s can be found in the API reference.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Rounding should generally behave as expected, but there are a few cases in which the expected behaviour is not obvious.","category":"page"},{"location":"stdlib/Dates/#Rounding-Epoch","page":"Dates","title":"Rounding Epoch","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"In many cases, the resolution specified for rounding (e.g., Dates.Second(30)) divides evenly into the next largest period (in this case, Dates.Minute(1)). But rounding behaviour in cases in which this is not true may lead to confusion. What is the expected result of rounding a DateTime to the nearest 10 hours?","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10))\n2016-07-17T12:00:00","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"That may seem confusing, given that the hour (12) is not divisible by 10. The reason that 2016-07-17T12:00:00 was chosen is that it is 17,676,660 hours after 0000-01-01T00:00:00, and 17,676,660 is divisible by 10.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"As Julia Date and DateTime values are represented according to the ISO 8601 standard, 0000-01-01T00:00:00 was chosen as base (or \"rounding epoch\") from which to begin the count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly from Julia's internal representation of Date s using Rata Die notation; but since the ISO 8601 standard is most visible to the end user, 0000-01-01T00:00:00 was chosen as the rounding epoch instead of the 0000-12-31T00:00:00 used internally to minimize confusion.)","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The only exception to the use of 0000-01-01T00:00:00 as the rounding epoch is when rounding to weeks. Rounding to the nearest week will always return a Monday (the first day of the week as specified by ISO 8601). For this reason, we use 0000-01-03T00:00:00 (the first day of the first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Here is a related case in which the expected behaviour is not necessarily obvious: What happens when we round to the nearest P(2), where P is a Period type? In some cases (specifically, when P <: Dates.TimePeriod) the answer is clear:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2))\n2016-07-17T08:00:00\n\njulia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2))\n2016-07-17T08:56:00","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"This seems obvious, because two of each of these periods still divides evenly into the next larger order period. But in the case of two months (which still divides evenly into one year), the answer may be surprising:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2))\n2016-07-01T00:00:00","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Why round to the first day in July, even though it is month 7 (an odd number)? The key is that months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds (the first of which are assigned 0).","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"This means that rounding a DateTime to an even multiple of seconds, minutes, hours, or years (because the ISO 8601 specification includes a year zero) will result in a DateTime with an even value in that field, while rounding a DateTime to an even multiple of months will result in the months field having an odd value. Because both months and years may contain an irregular number of days, whether rounding to an even number of days will result in an even value in the days field is uncertain.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"See the API reference for additional information on methods exported from the Dates module.","category":"page"},{"location":"stdlib/Dates/#stdlib-dates-api","page":"Dates","title":"API reference","text":"","category":"section"},{"location":"stdlib/Dates/#Dates-and-Time-Types","page":"Dates","title":"Dates and Time Types","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.Period\nDates.CompoundPeriod\nDates.Instant\nDates.UTInstant\nDates.TimeType\nDates.DateTime\nDates.Date\nDates.Time\nDates.TimeZone\nDates.UTC","category":"page"},{"location":"stdlib/Dates/#Dates.Period","page":"Dates","title":"Dates.Period","text":"Period\nYear\nQuarter\nMonth\nWeek\nDay\nHour\nMinute\nSecond\nMillisecond\nMicrosecond\nNanosecond\n\nPeriod types represent discrete, human representations of time.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.CompoundPeriod","page":"Dates","title":"Dates.CompoundPeriod","text":"CompoundPeriod\n\nA CompoundPeriod is useful for expressing time periods that are not a fixed multiple of smaller periods. For example, \"a year and a day\" is not a fixed number of days, but can be expressed using a CompoundPeriod. In fact, a CompoundPeriod is automatically generated by addition of different period types, e.g. Year(1) + Day(1) produces a CompoundPeriod result.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.Instant","page":"Dates","title":"Dates.Instant","text":"Instant\n\nInstant types represent integer-based, machine representations of time as continuous timelines starting from an epoch.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.UTInstant","page":"Dates","title":"Dates.UTInstant","text":"UTInstant{T}\n\nThe UTInstant represents a machine timeline based on UT time (1 day = one revolution of the earth). The T is a Period parameter that indicates the resolution or precision of the instant.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.TimeType","page":"Dates","title":"Dates.TimeType","text":"TimeType\n\nTimeType types wrap Instant machine instances to provide human representations of the machine instant. Time, DateTime and Date are subtypes of TimeType.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.DateTime","page":"Dates","title":"Dates.DateTime","text":"DateTime\n\nDateTime represents a point in time according to the proleptic Gregorian calendar. The finest resolution of the time is millisecond (i.e., microseconds or nanoseconds cannot be represented by this type). The type supports fixed-point arithmetic, and thus is prone to underflowing (and overflowing). A notable consequence is rounding when adding a Microsecond or a Nanosecond:\n\njulia> dt = DateTime(2023, 8, 19, 17, 45, 32, 900)\n2023-08-19T17:45:32.900\n\njulia> dt + Millisecond(1)\n2023-08-19T17:45:32.901\n\njulia> dt + Microsecond(1000) # 1000us == 1ms\n2023-08-19T17:45:32.901\n\njulia> dt + Microsecond(999) # 999us rounded to 1000us\n2023-08-19T17:45:32.901\n\njulia> dt + Microsecond(1499) # 1499 rounded to 1000us\n2023-08-19T17:45:32.901\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.Date","page":"Dates","title":"Dates.Date","text":"Date\n\nDate wraps a UTInstant{Day} and interprets it according to the proleptic Gregorian calendar.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.Time","page":"Dates","title":"Dates.Time","text":"Time\n\nTime wraps a Nanosecond and represents a specific moment in a 24-hour day.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.TimeZone","page":"Dates","title":"Dates.TimeZone","text":"TimeZone\n\nGeographic zone generally based on longitude determining what the time is at a certain location. Some time zones observe daylight savings (eg EST -> EDT). For implementations and more support, see the TimeZones.jl package\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.UTC","page":"Dates","title":"Dates.UTC","text":"UTC\n\nUTC, or Coordinated Universal Time, is the TimeZone from which all others are measured. It is associated with the time at 0° longitude. It is not adjusted for daylight savings.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates-Functions","page":"Dates","title":"Dates Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.DateTime(::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64)\nDates.DateTime(::Dates.Period)\nDates.DateTime(::Function, ::Any...)\nDates.DateTime(::Dates.TimeType)\nDates.DateTime(::AbstractString, ::AbstractString)\nDates.format(::Dates.TimeType, ::AbstractString)\nDates.DateFormat\nDates.@dateformat_str\nDates.DateTime(::AbstractString, ::Dates.DateFormat)\nDates.Date(::Int64, ::Int64, ::Int64)\nDates.Date(::Dates.Period)\nDates.Date(::Function, ::Any, ::Any, ::Any)\nDates.Date(::Dates.TimeType)\nDates.Date(::AbstractString, ::AbstractString)\nDates.Date(::AbstractString, ::Dates.DateFormat)\nDates.Time(::Int64::Int64, ::Int64, ::Int64, ::Int64, ::Int64)\nDates.Time(::Dates.TimePeriod)\nDates.Time(::Function, ::Any...)\nDates.Time(::Dates.DateTime)\nDates.Time(::AbstractString, ::AbstractString)\nDates.Time(::AbstractString, ::Dates.DateFormat)\nDates.now()\nDates.now(::Type{Dates.UTC})\nBase.eps(::Union{Type{DateTime}, Type{Date}, Type{Time}, TimeType})","category":"page"},{"location":"stdlib/Dates/#Dates.DateTime-NTuple{7, Int64}","page":"Dates","title":"Dates.DateTime","text":"DateTime(y, [m, d, h, mi, s, ms]) -> DateTime\n\nConstruct a DateTime type by parts. Arguments must be convertible to Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{Period}","page":"Dates","title":"Dates.DateTime","text":"DateTime(periods::Period...) -> DateTime\n\nConstruct a DateTime type by Period type parts. Arguments may be in any order. DateTime parts not provided will default to the value of Dates.default(period).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{Function, Vararg{Any}}","page":"Dates","title":"Dates.DateTime","text":"DateTime(f::Function, y[, m, d, h, mi, s]; step=Day(1), limit=10000) -> DateTime\n\nCreate a DateTime through the adjuster API. The starting point will be constructed from the provided y, m, d... arguments, and will be adjusted until f::Function returns true. The step size in adjusting can be provided manually through the step keyword. limit provides a limit to the max number of iterations the adjustment API will pursue before throwing an error (in the case that f::Function is never satisfied).\n\nExamples\n\njulia> DateTime(dt -> second(dt) == 40, 2010, 10, 20, 10; step = Second(1))\n2010-10-20T10:00:40\n\njulia> DateTime(dt -> hour(dt) == 20, 2010, 10, 20, 10; step = Hour(1), limit = 5)\nERROR: ArgumentError: Adjustment limit reached: 5 iterations\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{TimeType}","page":"Dates","title":"Dates.DateTime","text":"DateTime(dt::Date) -> DateTime\n\nConvert a Date to a DateTime. The hour, minute, second, and millisecond parts of the new DateTime are assumed to be zero.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{AbstractString, AbstractString}","page":"Dates","title":"Dates.DateTime","text":"DateTime(dt::AbstractString, format::AbstractString; locale=\"english\") -> DateTime\n\nConstruct a DateTime by parsing the dt date time string following the pattern given in the format string (see DateFormat for syntax).\n\nnote: Note\nThis method creates a DateFormat object each time it is called. It is recommended that you create a DateFormat object instead and use that as the second argument to avoid performance loss when using the same format repeatedly.\n\nExamples\n\njulia> DateTime(\"2020-01-01\", \"yyyy-mm-dd\")\n2020-01-01T00:00:00\n\njulia> a = (\"2020-01-01\", \"2020-01-02\");\n\njulia> [DateTime(d, dateformat\"yyyy-mm-dd\") for d ∈ a] # preferred\n2-element Vector{DateTime}:\n 2020-01-01T00:00:00\n 2020-01-02T00:00:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.format-Tuple{TimeType, AbstractString}","page":"Dates","title":"Dates.format","text":"format(dt::TimeType, format::AbstractString; locale=\"english\") -> AbstractString\n\nConstruct a string by using a TimeType object and applying the provided format. The following character codes can be used to construct the format string:\n\nCode Examples Comment\ny 6 Numeric year with a fixed width\nY 1996 Numeric year with a minimum width\nm 1, 12 Numeric month with a minimum width\nu Jan Month name shortened to 3-chars according to the locale\nU January Full month name according to the locale keyword\nd 1, 31 Day of the month with a minimum width\nH 0, 23 Hour (24-hour clock) with a minimum width\nM 0, 59 Minute with a minimum width\nS 0, 59 Second with a minimum width\ns 000, 500 Millisecond with a minimum width of 3\ne Mon, Tue Abbreviated days of the week\nE Monday Full day of week name\n\nThe number of sequential code characters indicate the width of the code. A format of yyyy-mm specifies that the code y should have a width of four while m a width of two. Codes that yield numeric digits have an associated mode: fixed-width or minimum-width. The fixed-width mode left-pads the value with zeros when it is shorter than the specified width and truncates the value when longer. Minimum-width mode works the same as fixed-width except that it does not truncate values longer than the width.\n\nWhen creating a format you can use any non-code characters as a separator. For example to generate the string \"1996-01-15T00:00:00\" you could use format: \"yyyy-mm-ddTHH:MM:SS\". Note that if you need to use a code character as a literal you can use the escape character backslash. The string \"1996y01m\" can be produced with the format \"yyyy\\ymm\\m\".\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.DateFormat","page":"Dates","title":"Dates.DateFormat","text":"DateFormat(format::AbstractString, locale=\"english\") -> DateFormat\n\nConstruct a date formatting object that can be used for parsing date strings or formatting a date object as a string. The following character codes can be used to construct the format string:\n\nCode Matches Comment\nY 1996, 96 Returns year of 1996, 0096\ny 1996, 96 Same as Y on parse but discards excess digits on format\nm 1, 01 Matches 1 or 2-digit months\nu Jan Matches abbreviated months according to the locale keyword\nU January Matches full month names according to the locale keyword\nd 1, 01 Matches 1 or 2-digit days\nH 00 Matches hours (24-hour clock)\nI 00 For outputting hours with 12-hour clock\nM 00 Matches minutes\nS 00 Matches seconds\ns .500 Matches milliseconds\ne Mon, Tues Matches abbreviated days of the week\nE Monday Matches full name days of the week\np AM Matches AM/PM (case-insensitive)\nyyyymmdd 19960101 Matches fixed-width year, month, and day\n\nCharacters not listed above are normally treated as delimiters between date and time slots. For example a dt string of \"1996-01-15T00:00:00.0\" would have a format string like \"y-m-dTH:M:S.s\". If you need to use a code character as a delimiter you can escape it using backslash. The date \"1995y01m\" would have the format \"y\\ym\\m\".\n\nNote that 12:00AM corresponds 00:00 (midnight), and 12:00PM corresponds to 12:00 (noon). When parsing a time with a p specifier, any hour (either H or I) is interpreted as as a 12-hour clock, so the I code is mainly useful for output.\n\nCreating a DateFormat object is expensive. Whenever possible, create it once and use it many times or try the dateformat\"\" string macro. Using this macro creates the DateFormat object once at macro expansion time and reuses it later. There are also several pre-defined formatters, listed later.\n\nSee DateTime and format for how to use a DateFormat object to parse and write Date strings respectively.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Dates/#Dates.@dateformat_str","page":"Dates","title":"Dates.@dateformat_str","text":"dateformat\"Y-m-d H:M:S\"\n\nCreate a DateFormat object. Similar to DateFormat(\"Y-m-d H:M:S\") but creates the DateFormat object once during macro expansion.\n\nSee DateFormat for details about format specifiers.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Dates/#Dates.DateTime-Tuple{AbstractString, DateFormat}","page":"Dates","title":"Dates.DateTime","text":"DateTime(dt::AbstractString, df::DateFormat=ISODateTimeFormat) -> DateTime\n\nConstruct a DateTime by parsing the dt date time string following the pattern given in the DateFormat object, or dateformat\"yyyy-mm-dd\\THH:MM:SS.s\" if omitted.\n\nSimilar to DateTime(::AbstractString, ::AbstractString) but more efficient when repeatedly parsing similarly formatted date time strings with a pre-created DateFormat object.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{Int64, Int64, Int64}","page":"Dates","title":"Dates.Date","text":"Date(y, [m, d]) -> Date\n\nConstruct a Date type by parts. Arguments must be convertible to Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{Period}","page":"Dates","title":"Dates.Date","text":"Date(period::Period...) -> Date\n\nConstruct a Date type by Period type parts. Arguments may be in any order. Date parts not provided will default to the value of Dates.default(period).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{Function, Any, Any, Any}","page":"Dates","title":"Dates.Date","text":"Date(f::Function, y[, m, d]; step=Day(1), limit=10000) -> Date\n\nCreate a Date through the adjuster API. The starting point will be constructed from the provided y, m, d arguments, and will be adjusted until f::Function returns true. The step size in adjusting can be provided manually through the step keyword. limit provides a limit to the max number of iterations the adjustment API will pursue before throwing an error (given that f::Function is never satisfied).\n\nExamples\n\njulia> Date(date -> week(date) == 20, 2010, 01, 01)\n2010-05-17\n\njulia> Date(date -> year(date) == 2010, 2000, 01, 01)\n2010-01-01\n\njulia> Date(date -> month(date) == 10, 2000, 01, 01; limit = 5)\nERROR: ArgumentError: Adjustment limit reached: 5 iterations\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{TimeType}","page":"Dates","title":"Dates.Date","text":"Date(dt::DateTime) -> Date\n\nConvert a DateTime to a Date. The hour, minute, second, and millisecond parts of the DateTime are truncated, so only the year, month and day parts are used in construction.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{AbstractString, AbstractString}","page":"Dates","title":"Dates.Date","text":"Date(d::AbstractString, format::AbstractString; locale=\"english\") -> Date\n\nConstruct a Date by parsing the d date string following the pattern given in the format string (see DateFormat for syntax).\n\nnote: Note\nThis method creates a DateFormat object each time it is called. It is recommended that you create a DateFormat object instead and use that as the second argument to avoid performance loss when using the same format repeatedly.\n\nExamples\n\njulia> Date(\"2020-01-01\", \"yyyy-mm-dd\")\n2020-01-01\n\njulia> a = (\"2020-01-01\", \"2020-01-02\");\n\njulia> [Date(d, dateformat\"yyyy-mm-dd\") for d ∈ a] # preferred\n2-element Vector{Date}:\n 2020-01-01\n 2020-01-02\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Date-Tuple{AbstractString, DateFormat}","page":"Dates","title":"Dates.Date","text":"Date(d::AbstractString, df::DateFormat=ISODateFormat) -> Date\n\nConstruct a Date by parsing the d date string following the pattern given in the DateFormat object, or dateformat\"yyyy-mm-dd\" if omitted.\n\nSimilar to Date(::AbstractString, ::AbstractString) but more efficient when repeatedly parsing similarly formatted date strings with a pre-created DateFormat object.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-NTuple{5, Int64}","page":"Dates","title":"Dates.Time","text":"Time(h, [mi, s, ms, us, ns]) -> Time\n\nConstruct a Time type by parts. Arguments must be convertible to Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{TimePeriod}","page":"Dates","title":"Dates.Time","text":"Time(period::TimePeriod...) -> Time\n\nConstruct a Time type by Period type parts. Arguments may be in any order. Time parts not provided will default to the value of Dates.default(period).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{Function, Vararg{Any}}","page":"Dates","title":"Dates.Time","text":"Time(f::Function, h, mi=0; step::Period=Second(1), limit::Int=10000)\nTime(f::Function, h, mi, s; step::Period=Millisecond(1), limit::Int=10000)\nTime(f::Function, h, mi, s, ms; step::Period=Microsecond(1), limit::Int=10000)\nTime(f::Function, h, mi, s, ms, us; step::Period=Nanosecond(1), limit::Int=10000)\n\nCreate a Time through the adjuster API. The starting point will be constructed from the provided h, mi, s, ms, us arguments, and will be adjusted until f::Function returns true. The step size in adjusting can be provided manually through the step keyword. limit provides a limit to the max number of iterations the adjustment API will pursue before throwing an error (in the case that f::Function is never satisfied). Note that the default step will adjust to allow for greater precision for the given arguments; i.e. if hour, minute, and second arguments are provided, the default step will be Millisecond(1) instead of Second(1).\n\nExamples\n\njulia> Time(t -> minute(t) == 30, 20)\n20:30:00\n\njulia> Time(t -> minute(t) == 0, 20)\n20:00:00\n\njulia> Time(t -> hour(t) == 10, 3; limit = 5)\nERROR: ArgumentError: Adjustment limit reached: 5 iterations\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{DateTime}","page":"Dates","title":"Dates.Time","text":"Time(dt::DateTime) -> Time\n\nConvert a DateTime to a Time. The hour, minute, second, and millisecond parts of the DateTime are used to create the new Time. Microsecond and nanoseconds are zero by default.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{AbstractString, AbstractString}","page":"Dates","title":"Dates.Time","text":"Time(t::AbstractString, format::AbstractString; locale=\"english\") -> Time\n\nConstruct a Time by parsing the t time string following the pattern given in the format string (see DateFormat for syntax).\n\nnote: Note\nThis method creates a DateFormat object each time it is called. It is recommended that you create a DateFormat object instead and use that as the second argument to avoid performance loss when using the same format repeatedly.\n\nExamples\n\njulia> Time(\"12:34pm\", \"HH:MMp\")\n12:34:00\n\njulia> a = (\"12:34pm\", \"2:34am\");\n\njulia> [Time(d, dateformat\"HH:MMp\") for d ∈ a] # preferred\n2-element Vector{Time}:\n 12:34:00\n 02:34:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Time-Tuple{AbstractString, DateFormat}","page":"Dates","title":"Dates.Time","text":"Time(t::AbstractString, df::DateFormat=ISOTimeFormat) -> Time\n\nConstruct a Time by parsing the t date time string following the pattern given in the DateFormat object, or dateformat\"HH:MM:SS.s\" if omitted.\n\nSimilar to Time(::AbstractString, ::AbstractString) but more efficient when repeatedly parsing similarly formatted time strings with a pre-created DateFormat object.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.now-Tuple{}","page":"Dates","title":"Dates.now","text":"now() -> DateTime\n\nReturn a DateTime corresponding to the user's system time including the system timezone locale.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.now-Tuple{Type{UTC}}","page":"Dates","title":"Dates.now","text":"now(::Type{UTC}) -> DateTime\n\nReturn a DateTime corresponding to the user's system time as UTC/GMT. For other time zones, see the TimeZones.jl package.\n\nExamples\n\njulia> now(UTC)\n2023-01-04T10:52:24.864\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.eps-Tuple{Union{Type{Date}, Type{DateTime}, Type{Time}, TimeType}}","page":"Dates","title":"Base.eps","text":"eps(::Type{DateTime}) -> Millisecond\neps(::Type{Date}) -> Day\neps(::Type{Time}) -> Nanosecond\neps(::TimeType) -> Period\n\nReturn the smallest unit value supported by the TimeType.\n\nExamples\n\njulia> eps(DateTime)\n1 millisecond\n\njulia> eps(Date)\n1 day\n\njulia> eps(Time)\n1 nanosecond\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Accessor-Functions-2","page":"Dates","title":"Accessor Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.year\nDates.month\nDates.week\nDates.day\nDates.hour\nDates.minute\nDates.second\nDates.millisecond\nDates.microsecond\nDates.nanosecond\nDates.Year(::Dates.TimeType)\nDates.Month(::Dates.TimeType)\nDates.Week(::Dates.TimeType)\nDates.Day(::Dates.TimeType)\nDates.Hour(::DateTime)\nDates.Minute(::DateTime)\nDates.Second(::DateTime)\nDates.Millisecond(::DateTime)\nDates.Microsecond(::Dates.Time)\nDates.Nanosecond(::Dates.Time)\nDates.yearmonth\nDates.monthday\nDates.yearmonthday","category":"page"},{"location":"stdlib/Dates/#Dates.year","page":"Dates","title":"Dates.year","text":"year(dt::TimeType) -> Int64\n\nThe year of a Date or DateTime as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.month","page":"Dates","title":"Dates.month","text":"month(dt::TimeType) -> Int64\n\nThe month of a Date or DateTime as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.week","page":"Dates","title":"Dates.week","text":"week(dt::TimeType) -> Int64\n\nReturn the ISO week date of a Date or DateTime as an Int64. Note that the first week of a year is the week that contains the first Thursday of the year, which can result in dates prior to January 4th being in the last week of the previous year. For example, week(Date(2005, 1, 1)) is the 53rd week of 2004.\n\nExamples\n\njulia> week(Date(1989, 6, 22))\n25\n\njulia> week(Date(2005, 1, 1))\n53\n\njulia> week(Date(2004, 12, 31))\n53\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.day","page":"Dates","title":"Dates.day","text":"day(dt::TimeType) -> Int64\n\nThe day of month of a Date or DateTime as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.hour","page":"Dates","title":"Dates.hour","text":"hour(dt::DateTime) -> Int64\n\nThe hour of day of a DateTime as an Int64.\n\n\n\n\n\nhour(t::Time) -> Int64\n\nThe hour of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.minute","page":"Dates","title":"Dates.minute","text":"minute(dt::DateTime) -> Int64\n\nThe minute of a DateTime as an Int64.\n\n\n\n\n\nminute(t::Time) -> Int64\n\nThe minute of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.second","page":"Dates","title":"Dates.second","text":"second(dt::DateTime) -> Int64\n\nThe second of a DateTime as an Int64.\n\n\n\n\n\nsecond(t::Time) -> Int64\n\nThe second of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.millisecond","page":"Dates","title":"Dates.millisecond","text":"millisecond(dt::DateTime) -> Int64\n\nThe millisecond of a DateTime as an Int64.\n\n\n\n\n\nmillisecond(t::Time) -> Int64\n\nThe millisecond of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.microsecond","page":"Dates","title":"Dates.microsecond","text":"microsecond(t::Time) -> Int64\n\nThe microsecond of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.nanosecond","page":"Dates","title":"Dates.nanosecond","text":"nanosecond(t::Time) -> Int64\n\nThe nanosecond of a Time as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.Year-Tuple{TimeType}","page":"Dates","title":"Dates.Year","text":"Year(v)\n\nConstruct a Year object with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Month-Tuple{TimeType}","page":"Dates","title":"Dates.Month","text":"Month(v)\n\nConstruct a Month object with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Week-Tuple{TimeType}","page":"Dates","title":"Dates.Week","text":"Week(v)\n\nConstruct a Week object with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Day-Tuple{TimeType}","page":"Dates","title":"Dates.Day","text":"Day(v)\n\nConstruct a Day object with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Hour-Tuple{DateTime}","page":"Dates","title":"Dates.Hour","text":"Hour(dt::DateTime) -> Hour\n\nThe hour part of a DateTime as a Hour.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Minute-Tuple{DateTime}","page":"Dates","title":"Dates.Minute","text":"Minute(dt::DateTime) -> Minute\n\nThe minute part of a DateTime as a Minute.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Second-Tuple{DateTime}","page":"Dates","title":"Dates.Second","text":"Second(dt::DateTime) -> Second\n\nThe second part of a DateTime as a Second.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Millisecond-Tuple{DateTime}","page":"Dates","title":"Dates.Millisecond","text":"Millisecond(dt::DateTime) -> Millisecond\n\nThe millisecond part of a DateTime as a Millisecond.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Microsecond-Tuple{Time}","page":"Dates","title":"Dates.Microsecond","text":"Microsecond(dt::Time) -> Microsecond\n\nThe microsecond part of a Time as a Microsecond.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.Nanosecond-Tuple{Time}","page":"Dates","title":"Dates.Nanosecond","text":"Nanosecond(dt::Time) -> Nanosecond\n\nThe nanosecond part of a Time as a Nanosecond.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.yearmonth","page":"Dates","title":"Dates.yearmonth","text":"yearmonth(dt::TimeType) -> (Int64, Int64)\n\nSimultaneously return the year and month parts of a Date or DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.monthday","page":"Dates","title":"Dates.monthday","text":"monthday(dt::TimeType) -> (Int64, Int64)\n\nSimultaneously return the month and day parts of a Date or DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.yearmonthday","page":"Dates","title":"Dates.yearmonthday","text":"yearmonthday(dt::TimeType) -> (Int64, Int64, Int64)\n\nSimultaneously return the year, month and day parts of a Date or DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Query-Functions-2","page":"Dates","title":"Query Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.dayname\nDates.dayabbr\nDates.dayofweek\nDates.dayofmonth\nDates.dayofweekofmonth\nDates.daysofweekinmonth\nDates.monthname\nDates.monthabbr\nDates.daysinmonth\nDates.isleapyear\nDates.dayofyear\nDates.daysinyear\nDates.quarterofyear\nDates.dayofquarter","category":"page"},{"location":"stdlib/Dates/#Dates.dayname","page":"Dates","title":"Dates.dayname","text":"dayname(dt::TimeType; locale=\"english\") -> String\ndayname(day::Integer; locale=\"english\") -> String\n\nReturn the full day name corresponding to the day of the week of the Date or DateTime in the given locale. Also accepts Integer.\n\nExamples\n\njulia> dayname(Date(\"2000-01-01\"))\n\"Saturday\"\n\njulia> dayname(4)\n\"Thursday\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayabbr","page":"Dates","title":"Dates.dayabbr","text":"dayabbr(dt::TimeType; locale=\"english\") -> String\ndayabbr(day::Integer; locale=\"english\") -> String\n\nReturn the abbreviated name corresponding to the day of the week of the Date or DateTime in the given locale. Also accepts Integer.\n\nExamples\n\njulia> dayabbr(Date(\"2000-01-01\"))\n\"Sat\"\n\njulia> dayabbr(3)\n\"Wed\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofweek","page":"Dates","title":"Dates.dayofweek","text":"dayofweek(dt::TimeType) -> Int64\n\nReturn the day of the week as an Int64 with 1 = Monday, 2 = Tuesday, etc..\n\nExamples\n\njulia> dayofweek(Date(\"2000-01-01\"))\n6\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofmonth","page":"Dates","title":"Dates.dayofmonth","text":"dayofmonth(dt::TimeType) -> Int64\n\nThe day of month of a Date or DateTime as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofweekofmonth","page":"Dates","title":"Dates.dayofweekofmonth","text":"dayofweekofmonth(dt::TimeType) -> Int\n\nFor the day of week of dt, return which number it is in dt's month. So if the day of the week of dt is Monday, then 1 = First Monday of the month, 2 = Second Monday of the month, etc. In the range 1:5.\n\nExamples\n\njulia> dayofweekofmonth(Date(\"2000-02-01\"))\n1\n\njulia> dayofweekofmonth(Date(\"2000-02-08\"))\n2\n\njulia> dayofweekofmonth(Date(\"2000-02-15\"))\n3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.daysofweekinmonth","page":"Dates","title":"Dates.daysofweekinmonth","text":"daysofweekinmonth(dt::TimeType) -> Int\n\nFor the day of week of dt, return the total number of that day of the week in dt's month. Returns 4 or 5. Useful in temporal expressions for specifying the last day of a week in a month by including dayofweekofmonth(dt) == daysofweekinmonth(dt) in the adjuster function.\n\nExamples\n\njulia> daysofweekinmonth(Date(\"2005-01-01\"))\n5\n\njulia> daysofweekinmonth(Date(\"2005-01-04\"))\n4\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.monthname","page":"Dates","title":"Dates.monthname","text":"monthname(dt::TimeType; locale=\"english\") -> String\nmonthname(month::Integer, locale=\"english\") -> String\n\nReturn the full name of the month of the Date or DateTime or Integer in the given locale.\n\nExamples\n\njulia> monthname(Date(\"2005-01-04\"))\n\"January\"\n\njulia> monthname(2)\n\"February\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.monthabbr","page":"Dates","title":"Dates.monthabbr","text":"monthabbr(dt::TimeType; locale=\"english\") -> String\nmonthabbr(month::Integer, locale=\"english\") -> String\n\nReturn the abbreviated month name of the Date or DateTime or Integer in the given locale.\n\nExamples\n\njulia> monthabbr(Date(\"2005-01-04\"))\n\"Jan\"\n\njulia> monthabbr(2)\n\"Feb\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.daysinmonth","page":"Dates","title":"Dates.daysinmonth","text":"daysinmonth(dt::TimeType) -> Int\n\nReturn the number of days in the month of dt. Value will be 28, 29, 30, or 31.\n\nExamples\n\njulia> daysinmonth(Date(\"2000-01\"))\n31\n\njulia> daysinmonth(Date(\"2001-02\"))\n28\n\njulia> daysinmonth(Date(\"2000-02\"))\n29\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.isleapyear","page":"Dates","title":"Dates.isleapyear","text":"isleapyear(dt::TimeType) -> Bool\n\nReturn true if the year of dt is a leap year.\n\nExamples\n\njulia> isleapyear(Date(\"2004\"))\ntrue\n\njulia> isleapyear(Date(\"2005\"))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofyear","page":"Dates","title":"Dates.dayofyear","text":"dayofyear(dt::TimeType) -> Int\n\nReturn the day of the year for dt with January 1st being day 1.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.daysinyear","page":"Dates","title":"Dates.daysinyear","text":"daysinyear(dt::TimeType) -> Int\n\nReturn 366 if the year of dt is a leap year, otherwise return 365.\n\nExamples\n\njulia> daysinyear(1999)\n365\n\njulia> daysinyear(2000)\n366\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.quarterofyear","page":"Dates","title":"Dates.quarterofyear","text":"quarterofyear(dt::TimeType) -> Int\n\nReturn the quarter that dt resides in. Range of value is 1:4.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.dayofquarter","page":"Dates","title":"Dates.dayofquarter","text":"dayofquarter(dt::TimeType) -> Int\n\nReturn the day of the current quarter of dt. Range of value is 1:92.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Adjuster-Functions-2","page":"Dates","title":"Adjuster Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Base.trunc(::Dates.TimeType, ::Type{Dates.Period})\nDates.firstdayofweek\nDates.lastdayofweek\nDates.firstdayofmonth\nDates.lastdayofmonth\nDates.firstdayofyear\nDates.lastdayofyear\nDates.firstdayofquarter\nDates.lastdayofquarter\nDates.tonext(::Dates.TimeType, ::Int)\nDates.toprev(::Dates.TimeType, ::Int)\nDates.tofirst\nDates.tolast\nDates.tonext(::Function, ::Dates.TimeType)\nDates.toprev(::Function, ::Dates.TimeType)","category":"page"},{"location":"stdlib/Dates/#Base.trunc-Tuple{TimeType, Type{Period}}","page":"Dates","title":"Base.trunc","text":"trunc(dt::TimeType, ::Type{Period}) -> TimeType\n\nTruncates the value of dt according to the provided Period type.\n\nExamples\n\njulia> trunc(DateTime(\"1996-01-01T12:30:00\"), Day)\n1996-01-01T00:00:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.firstdayofweek","page":"Dates","title":"Dates.firstdayofweek","text":"firstdayofweek(dt::TimeType) -> TimeType\n\nAdjusts dt to the Monday of its week.\n\nExamples\n\njulia> firstdayofweek(DateTime(\"1996-01-05T12:30:00\"))\n1996-01-01T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.lastdayofweek","page":"Dates","title":"Dates.lastdayofweek","text":"lastdayofweek(dt::TimeType) -> TimeType\n\nAdjusts dt to the Sunday of its week.\n\nExamples\n\njulia> lastdayofweek(DateTime(\"1996-01-05T12:30:00\"))\n1996-01-07T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.firstdayofmonth","page":"Dates","title":"Dates.firstdayofmonth","text":"firstdayofmonth(dt::TimeType) -> TimeType\n\nAdjusts dt to the first day of its month.\n\nExamples\n\njulia> firstdayofmonth(DateTime(\"1996-05-20\"))\n1996-05-01T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.lastdayofmonth","page":"Dates","title":"Dates.lastdayofmonth","text":"lastdayofmonth(dt::TimeType) -> TimeType\n\nAdjusts dt to the last day of its month.\n\nExamples\n\njulia> lastdayofmonth(DateTime(\"1996-05-20\"))\n1996-05-31T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.firstdayofyear","page":"Dates","title":"Dates.firstdayofyear","text":"firstdayofyear(dt::TimeType) -> TimeType\n\nAdjusts dt to the first day of its year.\n\nExamples\n\njulia> firstdayofyear(DateTime(\"1996-05-20\"))\n1996-01-01T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.lastdayofyear","page":"Dates","title":"Dates.lastdayofyear","text":"lastdayofyear(dt::TimeType) -> TimeType\n\nAdjusts dt to the last day of its year.\n\nExamples\n\njulia> lastdayofyear(DateTime(\"1996-05-20\"))\n1996-12-31T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.firstdayofquarter","page":"Dates","title":"Dates.firstdayofquarter","text":"firstdayofquarter(dt::TimeType) -> TimeType\n\nAdjusts dt to the first day of its quarter.\n\nExamples\n\njulia> firstdayofquarter(DateTime(\"1996-05-20\"))\n1996-04-01T00:00:00\n\njulia> firstdayofquarter(DateTime(\"1996-08-20\"))\n1996-07-01T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.lastdayofquarter","page":"Dates","title":"Dates.lastdayofquarter","text":"lastdayofquarter(dt::TimeType) -> TimeType\n\nAdjusts dt to the last day of its quarter.\n\nExamples\n\njulia> lastdayofquarter(DateTime(\"1996-05-20\"))\n1996-06-30T00:00:00\n\njulia> lastdayofquarter(DateTime(\"1996-08-20\"))\n1996-09-30T00:00:00\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.tonext-Tuple{TimeType, Int64}","page":"Dates","title":"Dates.tonext","text":"tonext(dt::TimeType, dow::Int; same::Bool=false) -> TimeType\n\nAdjusts dt to the next day of week corresponding to dow with 1 = Monday, 2 = Tuesday, etc. Setting same=true allows the current dt to be considered as the next dow, allowing for no adjustment to occur.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.toprev-Tuple{TimeType, Int64}","page":"Dates","title":"Dates.toprev","text":"toprev(dt::TimeType, dow::Int; same::Bool=false) -> TimeType\n\nAdjusts dt to the previous day of week corresponding to dow with 1 = Monday, 2 = Tuesday, etc. Setting same=true allows the current dt to be considered as the previous dow, allowing for no adjustment to occur.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.tofirst","page":"Dates","title":"Dates.tofirst","text":"tofirst(dt::TimeType, dow::Int; of=Month) -> TimeType\n\nAdjusts dt to the first dow of its month. Alternatively, of=Year will adjust to the first dow of the year.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.tolast","page":"Dates","title":"Dates.tolast","text":"tolast(dt::TimeType, dow::Int; of=Month) -> TimeType\n\nAdjusts dt to the last dow of its month. Alternatively, of=Year will adjust to the last dow of the year.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.tonext-Tuple{Function, TimeType}","page":"Dates","title":"Dates.tonext","text":"tonext(func::Function, dt::TimeType; step=Day(1), limit=10000, same=false) -> TimeType\n\nAdjusts dt by iterating at most limit iterations by step increments until func returns true. func must take a single TimeType argument and return a Bool. same allows dt to be considered in satisfying func.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.toprev-Tuple{Function, TimeType}","page":"Dates","title":"Dates.toprev","text":"toprev(func::Function, dt::TimeType; step=Day(-1), limit=10000, same=false) -> TimeType\n\nAdjusts dt by iterating at most limit iterations by step increments until func returns true. func must take a single TimeType argument and return a Bool. same allows dt to be considered in satisfying func.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Periods","page":"Dates","title":"Periods","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.Period(::Any)\nDates.CompoundPeriod(::Vector{<:Dates.Period})\nDates.canonicalize\nDates.value\nDates.default\nDates.periods","category":"page"},{"location":"stdlib/Dates/#Dates.Period-Tuple{Any}","page":"Dates","title":"Dates.Period","text":"Year(v)\nQuarter(v)\nMonth(v)\nWeek(v)\nDay(v)\nHour(v)\nMinute(v)\nSecond(v)\nMillisecond(v)\nMicrosecond(v)\nNanosecond(v)\n\nConstruct a Period type with the given v value. Input must be losslessly convertible to an Int64.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.CompoundPeriod-Tuple{Vector{<:Period}}","page":"Dates","title":"Dates.CompoundPeriod","text":"CompoundPeriod(periods) -> CompoundPeriod\n\nConstruct a CompoundPeriod from a Vector of Periods. All Periods of the same type will be added together.\n\nExamples\n\njulia> Dates.CompoundPeriod(Dates.Hour(12), Dates.Hour(13))\n25 hours\n\njulia> Dates.CompoundPeriod(Dates.Hour(-1), Dates.Minute(1))\n-1 hour, 1 minute\n\njulia> Dates.CompoundPeriod(Dates.Month(1), Dates.Week(-2))\n1 month, -2 weeks\n\njulia> Dates.CompoundPeriod(Dates.Minute(50000))\n50000 minutes\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Dates.canonicalize","page":"Dates","title":"Dates.canonicalize","text":"canonicalize(::CompoundPeriod) -> CompoundPeriod\n\nReduces the CompoundPeriod into its canonical form by applying the following rules:\n\nAny Period large enough be partially representable by a coarser Period will be broken into multiple Periods (eg. Hour(30) becomes Day(1) + Hour(6))\nPeriods with opposite signs will be combined when possible (eg. Hour(1) - Day(1) becomes -Hour(23))\n\nExamples\n\njulia> canonicalize(Dates.CompoundPeriod(Dates.Hour(12), Dates.Hour(13)))\n1 day, 1 hour\n\njulia> canonicalize(Dates.CompoundPeriod(Dates.Hour(-1), Dates.Minute(1)))\n-59 minutes\n\njulia> canonicalize(Dates.CompoundPeriod(Dates.Month(1), Dates.Week(-2)))\n1 month, -2 weeks\n\njulia> canonicalize(Dates.CompoundPeriod(Dates.Minute(50000)))\n4 weeks, 6 days, 17 hours, 20 minutes\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.value","page":"Dates","title":"Dates.value","text":"Dates.value(x::Period) -> Int64\n\nFor a given period, return the value associated with that period. For example, value(Millisecond(10)) returns 10 as an integer.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.default","page":"Dates","title":"Dates.default","text":"default(p::Period) -> Period\n\nReturn a sensible \"default\" value for the input Period by returning T(1) for Year, Month, and Day, and T(0) for Hour, Minute, Second, and Millisecond.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.periods","page":"Dates","title":"Dates.periods","text":"Dates.periods(::CompoundPeriod) -> Vector{Period}\n\nReturn the Vector of Periods that comprise the given CompoundPeriod.\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Rounding-Functions","page":"Dates","title":"Rounding Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Date and DateTime values can be rounded to a specified resolution (e.g., 1 month or 15 minutes) with floor, ceil, or round.","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Base.floor(::Dates.TimeType, ::Dates.Period)\nBase.ceil(::Dates.TimeType, ::Dates.Period)\nBase.round(::Dates.TimeType, ::Dates.Period, ::RoundingMode{:NearestTiesUp})","category":"page"},{"location":"stdlib/Dates/#Base.floor-Tuple{TimeType, Period}","page":"Dates","title":"Base.floor","text":"floor(dt::TimeType, p::Period) -> TimeType\n\nReturn the nearest Date or DateTime less than or equal to dt at resolution p.\n\nFor convenience, p may be a type instead of a value: floor(dt, Dates.Hour) is a shortcut for floor(dt, Dates.Hour(1)).\n\njulia> floor(Date(1985, 8, 16), Month)\n1985-08-01\n\njulia> floor(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))\n2013-02-13T00:30:00\n\njulia> floor(DateTime(2016, 8, 6, 12, 0, 0), Day)\n2016-08-06T00:00:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.ceil-Tuple{TimeType, Period}","page":"Dates","title":"Base.ceil","text":"ceil(dt::TimeType, p::Period) -> TimeType\n\nReturn the nearest Date or DateTime greater than or equal to dt at resolution p.\n\nFor convenience, p may be a type instead of a value: ceil(dt, Dates.Hour) is a shortcut for ceil(dt, Dates.Hour(1)).\n\njulia> ceil(Date(1985, 8, 16), Month)\n1985-09-01\n\njulia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))\n2013-02-13T00:45:00\n\njulia> ceil(DateTime(2016, 8, 6, 12, 0, 0), Day)\n2016-08-07T00:00:00\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.round-Tuple{TimeType, Period, RoundingMode{:NearestTiesUp}}","page":"Dates","title":"Base.round","text":"round(dt::TimeType, p::Period, [r::RoundingMode]) -> TimeType\n\nReturn the Date or DateTime nearest to dt at resolution p. By default (RoundNearestTiesUp), ties (e.g., rounding 9:30 to the nearest hour) will be rounded up.\n\nFor convenience, p may be a type instead of a value: round(dt, Dates.Hour) is a shortcut for round(dt, Dates.Hour(1)).\n\njulia> round(Date(1985, 8, 16), Month)\n1985-08-01\n\njulia> round(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))\n2013-02-13T00:30:00\n\njulia> round(DateTime(2016, 8, 6, 12, 0, 0), Day)\n2016-08-07T00:00:00\n\nValid rounding modes for round(::TimeType, ::Period, ::RoundingMode) are RoundNearestTiesUp (default), RoundDown (floor), and RoundUp (ceil).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Most Period values can also be rounded to a specified resolution:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Base.floor(::Dates.ConvertiblePeriod, ::T) where T <: Dates.ConvertiblePeriod\nBase.ceil(::Dates.ConvertiblePeriod, ::Dates.ConvertiblePeriod)\nBase.round(::Dates.ConvertiblePeriod, ::Dates.ConvertiblePeriod, ::RoundingMode{:NearestTiesUp})","category":"page"},{"location":"stdlib/Dates/#Base.floor-Union{Tuple{T}, Tuple{Union{Day, Week, TimePeriod}, T}} where T<:Union{Day, Week, TimePeriod}","page":"Dates","title":"Base.floor","text":"floor(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> T\n\nRound x down to the nearest multiple of precision. If x and precision are different subtypes of Period, the return value will have the same type as precision.\n\nFor convenience, precision may be a type instead of a value: floor(x, Dates.Hour) is a shortcut for floor(x, Dates.Hour(1)).\n\njulia> floor(Day(16), Week)\n2 weeks\n\njulia> floor(Minute(44), Minute(15))\n30 minutes\n\njulia> floor(Hour(36), Day)\n1 day\n\nRounding to a precision of Months or Years is not supported, as these Periods are of inconsistent length.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.ceil-Tuple{Union{Day, Week, TimePeriod}, Union{Day, Week, TimePeriod}}","page":"Dates","title":"Base.ceil","text":"ceil(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> T\n\nRound x up to the nearest multiple of precision. If x and precision are different subtypes of Period, the return value will have the same type as precision.\n\nFor convenience, precision may be a type instead of a value: ceil(x, Dates.Hour) is a shortcut for ceil(x, Dates.Hour(1)).\n\njulia> ceil(Day(16), Week)\n3 weeks\n\njulia> ceil(Minute(44), Minute(15))\n45 minutes\n\njulia> ceil(Hour(36), Day)\n2 days\n\nRounding to a precision of Months or Years is not supported, as these Periods are of inconsistent length.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/#Base.round-Tuple{Union{Day, Week, TimePeriod}, Union{Day, Week, TimePeriod}, RoundingMode{:NearestTiesUp}}","page":"Dates","title":"Base.round","text":"round(x::Period, precision::T, [r::RoundingMode]) where T <: Union{TimePeriod, Week, Day} -> T\n\nRound x to the nearest multiple of precision. If x and precision are different subtypes of Period, the return value will have the same type as precision. By default (RoundNearestTiesUp), ties (e.g., rounding 90 minutes to the nearest hour) will be rounded up.\n\nFor convenience, precision may be a type instead of a value: round(x, Dates.Hour) is a shortcut for round(x, Dates.Hour(1)).\n\njulia> round(Day(16), Week)\n2 weeks\n\njulia> round(Minute(44), Minute(15))\n45 minutes\n\njulia> round(Hour(36), Day)\n2 days\n\nValid rounding modes for round(::Period, ::T, ::RoundingMode) are RoundNearestTiesUp (default), RoundDown (floor), and RoundUp (ceil).\n\nRounding to a precision of Months or Years is not supported, as these Periods are of inconsistent length.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"The following functions are not exported:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.floorceil\nDates.epochdays2date\nDates.epochms2datetime\nDates.date2epochdays\nDates.datetime2epochms","category":"page"},{"location":"stdlib/Dates/#Dates.floorceil","page":"Dates","title":"Dates.floorceil","text":"floorceil(dt::TimeType, p::Period) -> (TimeType, TimeType)\n\nSimultaneously return the floor and ceil of a Date or DateTime at resolution p. More efficient than calling both floor and ceil individually.\n\n\n\n\n\nfloorceil(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> (T, T)\n\nSimultaneously return the floor and ceil of Period at resolution p. More efficient than calling both floor and ceil individually.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.epochdays2date","page":"Dates","title":"Dates.epochdays2date","text":"epochdays2date(days) -> Date\n\nTake the number of days since the rounding epoch (0000-01-01T00:00:00) and return the corresponding Date.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.epochms2datetime","page":"Dates","title":"Dates.epochms2datetime","text":"epochms2datetime(milliseconds) -> DateTime\n\nTake the number of milliseconds since the rounding epoch (0000-01-01T00:00:00) and return the corresponding DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.date2epochdays","page":"Dates","title":"Dates.date2epochdays","text":"date2epochdays(dt::Date) -> Int64\n\nTake the given Date and return the number of days since the rounding epoch (0000-01-01T00:00:00) as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.datetime2epochms","page":"Dates","title":"Dates.datetime2epochms","text":"datetime2epochms(dt::DateTime) -> Int64\n\nTake the given DateTime and return the number of milliseconds since the rounding epoch (0000-01-01T00:00:00) as an Int64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Conversion-Functions","page":"Dates","title":"Conversion Functions","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Dates.today\nDates.unix2datetime\nDates.datetime2unix\nDates.julian2datetime\nDates.datetime2julian\nDates.rata2datetime\nDates.datetime2rata","category":"page"},{"location":"stdlib/Dates/#Dates.today","page":"Dates","title":"Dates.today","text":"today() -> Date\n\nReturn the date portion of now().\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.unix2datetime","page":"Dates","title":"Dates.unix2datetime","text":"unix2datetime(x) -> DateTime\n\nTake the number of seconds since unix epoch 1970-01-01T00:00:00 and convert to the corresponding DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.datetime2unix","page":"Dates","title":"Dates.datetime2unix","text":"datetime2unix(dt::DateTime) -> Float64\n\nTake the given DateTime and return the number of seconds since the unix epoch 1970-01-01T00:00:00 as a Float64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.julian2datetime","page":"Dates","title":"Dates.julian2datetime","text":"julian2datetime(julian_days) -> DateTime\n\nTake the number of Julian calendar days since epoch -4713-11-24T12:00:00 and return the corresponding DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.datetime2julian","page":"Dates","title":"Dates.datetime2julian","text":"datetime2julian(dt::DateTime) -> Float64\n\nTake the given DateTime and return the number of Julian calendar days since the julian epoch -4713-11-24T12:00:00 as a Float64.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.rata2datetime","page":"Dates","title":"Dates.rata2datetime","text":"rata2datetime(days) -> DateTime\n\nTake the number of Rata Die days since epoch 0000-12-31T00:00:00 and return the corresponding DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Dates.datetime2rata","page":"Dates","title":"Dates.datetime2rata","text":"datetime2rata(dt::TimeType) -> Int64\n\nReturn the number of Rata Die days since epoch from the given Date or DateTime.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Dates/#Constants","page":"Dates","title":"Constants","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Days of the Week:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Variable Abbr. Value (Int)\nMonday Mon 1\nTuesday Tue 2\nWednesday Wed 3\nThursday Thu 4\nFriday Fri 5\nSaturday Sat 6\nSunday Sun 7","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Months of the Year:","category":"page"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"Variable Abbr. Value (Int)\nJanuary Jan 1\nFebruary Feb 2\nMarch Mar 3\nApril Apr 4\nMay May 5\nJune Jun 6\nJuly Jul 7\nAugust Aug 8\nSeptember Sep 9\nOctober Oct 10\nNovember Nov 11\nDecember Dec 12","category":"page"},{"location":"stdlib/Dates/#Common-Date-Formatters","page":"Dates","title":"Common Date Formatters","text":"","category":"section"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"ISODateTimeFormat\nISODateFormat\nISOTimeFormat\nRFC1123Format","category":"page"},{"location":"stdlib/Dates/#Dates.ISODateTimeFormat","page":"Dates","title":"Dates.ISODateTimeFormat","text":"Dates.ISODateTimeFormat\n\nDescribes the ISO8601 formatting for a date and time. This is the default value for Dates.format of a DateTime.\n\nExamples\n\njulia> Dates.format(DateTime(2018, 8, 8, 12, 0, 43, 1), ISODateTimeFormat)\n\"2018-08-08T12:00:43.001\"\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Dates/#Dates.ISODateFormat","page":"Dates","title":"Dates.ISODateFormat","text":"Dates.ISODateFormat\n\nDescribes the ISO8601 formatting for a date. This is the default value for Dates.format of a Date.\n\nExamples\n\njulia> Dates.format(Date(2018, 8, 8), ISODateFormat)\n\"2018-08-08\"\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Dates/#Dates.ISOTimeFormat","page":"Dates","title":"Dates.ISOTimeFormat","text":"Dates.ISOTimeFormat\n\nDescribes the ISO8601 formatting for a time. This is the default value for Dates.format of a Time.\n\nExamples\n\njulia> Dates.format(Time(12, 0, 43, 1), ISOTimeFormat)\n\"12:00:43.001\"\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Dates/#Dates.RFC1123Format","page":"Dates","title":"Dates.RFC1123Format","text":"Dates.RFC1123Format\n\nDescribes the RFC1123 formatting for a date and time.\n\nExamples\n\njulia> Dates.format(DateTime(2018, 8, 8, 12, 0, 43, 1), RFC1123Format)\n\"Wed, 08 Aug 2018 12:00:43\"\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Dates/","page":"Dates","title":"Dates","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/TOML/docs/src/index.md\"","category":"page"},{"location":"stdlib/TOML/#TOML","page":"TOML","title":"TOML","text":"","category":"section"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"TOML.jl is a Julia standard library for parsing and writing TOML v1.0 files.","category":"page"},{"location":"stdlib/TOML/#Parsing-TOML-data","page":"TOML","title":"Parsing TOML data","text":"","category":"section"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> data = \"\"\"\n [database]\n server = \"192.168.1.1\"\n ports = [ 8001, 8001, 8002 ]\n \"\"\";\n\njulia> TOML.parse(data)\nDict{String, Any} with 1 entry:\n \"database\" => Dict{String, Any}(\"server\"=>\"192.168.1.1\", \"ports\"=>[8001, 8001…","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"To parse a file, use TOML.parsefile. If the file has a syntax error, an exception is thrown:","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> TOML.parse(\"\"\"\n value = 0.0.0\n \"\"\")\nERROR: TOML Parser error:\nnone:1:16 error: failed to parse value\n value = 0.0.0\n ^\n[...]","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"There are other versions of the parse functions (TOML.tryparse and TOML.tryparsefile) that instead of throwing exceptions on parser error returns a TOML.ParserError with information:","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> err = TOML.tryparse(\"\"\"\n value = 0.0.0\n \"\"\");\n\njulia> err.type\nErrGenericValueError::ErrorType = 14\n\njulia> err.line\n1\n\njulia> err.column\n16","category":"page"},{"location":"stdlib/TOML/#Exporting-data-to-TOML-file","page":"TOML","title":"Exporting data to TOML file","text":"","category":"section"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"The TOML.print function is used to print (or serialize) data into TOML format.","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> data = Dict(\n \"names\" => [\"Julia\", \"Julio\"],\n \"age\" => [10, 20],\n );\n\njulia> TOML.print(data)\nnames = [\"Julia\", \"Julio\"]\nage = [10, 20]\n\njulia> fname = tempname();\n\njulia> open(fname, \"w\") do io\n TOML.print(io, data)\n end\n\njulia> TOML.parsefile(fname)\nDict{String, Any} with 2 entries:\n \"names\" => [\"Julia\", \"Julio\"]\n \"age\" => [10, 20]","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"Keys can be sorted according to some value","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> TOML.print(Dict(\n \"abc\" => 1,\n \"ab\" => 2,\n \"abcd\" => 3,\n ); sorted=true, by=length)\nab = 2\nabc = 1\nabcd = 3","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"For custom structs, pass a function that converts the struct to a supported type","category":"page"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"julia> using TOML\n\njulia> struct MyStruct\n a::Int\n b::String\n end\n\njulia> TOML.print(Dict(\"foo\" => MyStruct(5, \"bar\"))) do x\n x isa MyStruct && return [x.a, x.b]\n error(\"unhandled type $(typeof(x))\")\n end\nfoo = [5, \"bar\"]","category":"page"},{"location":"stdlib/TOML/#References","page":"TOML","title":"References","text":"","category":"section"},{"location":"stdlib/TOML/","page":"TOML","title":"TOML","text":"TOML.parse\nTOML.parsefile\nTOML.tryparse\nTOML.tryparsefile\nTOML.print\nTOML.Parser\nTOML.ParserError","category":"page"},{"location":"stdlib/TOML/#TOML.parse","page":"TOML","title":"TOML.parse","text":"parse(x::Union{AbstractString, IO})\nparse(p::Parser, x::Union{AbstractString, IO})\n\nParse the string or stream x, and return the resulting table (dictionary). Throw a ParserError upon failure.\n\nSee also TOML.tryparse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.parsefile","page":"TOML","title":"TOML.parsefile","text":"parsefile(f::AbstractString)\nparsefile(p::Parser, f::AbstractString)\n\nParse file f and return the resulting table (dictionary). Throw a ParserError upon failure.\n\nSee also TOML.tryparsefile.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.tryparse","page":"TOML","title":"TOML.tryparse","text":"tryparse(x::Union{AbstractString, IO})\ntryparse(p::Parser, x::Union{AbstractString, IO})\n\nParse the string or stream x, and return the resulting table (dictionary). Return a ParserError upon failure.\n\nSee also TOML.parse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.tryparsefile","page":"TOML","title":"TOML.tryparsefile","text":"tryparsefile(f::AbstractString)\ntryparsefile(p::Parser, f::AbstractString)\n\nParse file f and return the resulting table (dictionary). Return a ParserError upon failure.\n\nSee also TOML.parsefile.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.print","page":"TOML","title":"TOML.print","text":"print([to_toml::Function], io::IO [=stdout], data::AbstractDict; sorted=false, by=identity, inline_tables::IdSet{<:AbstractDict})\n\nWrite data as TOML syntax to the stream io. If the keyword argument sorted is set to true, sort tables according to the function given by the keyword argument by. If the keyword argument inline_tables is given, it should be a set of tables that should be printed \"inline\".\n\nThe following data types are supported: AbstractDict, AbstractVector, AbstractString, Integer, AbstractFloat, Bool, Dates.DateTime, Dates.Time, Dates.Date. Note that the integers and floats need to be convertible to Float64 and Int64 respectively. For other data types, pass the function to_toml that takes the data types and returns a value of a supported type.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/TOML/#TOML.Parser","page":"TOML","title":"TOML.Parser","text":"Parser()\n\nConstructor for a TOML Parser. Note that in most cases one does not need to explicitly create a Parser but instead one directly use use TOML.parsefile or TOML.parse. Using an explicit parser will however reuse some internal data structures which can be beneficial for performance if a larger number of small files are parsed.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/TOML/#TOML.ParserError","page":"TOML","title":"TOML.ParserError","text":"ParserError\n\nType that is returned from tryparse and tryparsefile when parsing fails. It contains (among others) the following fields:\n\npos, the position in the string when the error happened\ntable, the result that so far was successfully parsed\ntype, an error type, different for different types of errors\n\n\n\n\n\n","category":"type"},{"location":"manual/asynchronous-programming/#man-asynchronous","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"When a program needs to interact with the outside world, for example communicating with another machine over the internet, operations in the program may need to happen in an unpredictable order. Say your program needs to download a file. We would like to initiate the download operation, perform other operations while we wait for it to complete, and then resume the code that needs the downloaded file when it is available. This sort of scenario falls in the domain of asynchronous programming, sometimes also referred to as concurrent programming (since, conceptually, multiple things are happening at once).","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"To address these scenarios, Julia provides Tasks (also known by several other names, such as symmetric coroutines, lightweight threads, cooperative multitasking, or one-shot continuations). When a piece of computing work (in practice, executing a particular function) is designated as a Task, it becomes possible to interrupt it by switching to another Task. The original Task can later be resumed, at which point it will pick up right where it left off. At first, this may seem similar to a function call. However there are two key differences. First, switching tasks does not use any space, so any number of task switches can occur without consuming the call stack. Second, switching among tasks can occur in any order, unlike function calls, where the called function must finish executing before control returns to the calling function.","category":"page"},{"location":"manual/asynchronous-programming/#Basic-Task-operations","page":"Asynchronous Programming","title":"Basic Task operations","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"You can think of a Task as a handle to a unit of computational work to be performed. It has a create-start-run-finish lifecycle. Tasks are created by calling the Task constructor on a 0-argument function to run, or using the @task macro:","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> t = @task begin; sleep(5); println(\"done\"); end\nTask (runnable) @0x00007f13a40c0eb0","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"@task x is equivalent to Task(()->x).","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"This task will wait for five seconds, and then print done. However, it has not started running yet. We can run it whenever we're ready by calling schedule:","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> schedule(t);","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"If you try this in the REPL, you will see that schedule returns immediately. That is because it simply adds t to an internal queue of tasks to run. Then, the REPL will print the next prompt and wait for more input. Waiting for keyboard input provides an opportunity for other tasks to run, so at that point t will start. t calls sleep, which sets a timer and stops execution. If other tasks have been scheduled, they could run then. After five seconds, the timer fires and restarts t, and you will see done printed. t is then finished.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"The wait function blocks the calling task until some other task finishes. So for example if you type","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> schedule(t); wait(t)","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"instead of only calling schedule, you will see a five second pause before the next input prompt appears. That is because the REPL is waiting for t to finish before proceeding.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"It is common to want to create a task and schedule it right away, so the macro @async is provided for that purpose –- @async x is equivalent to schedule(@task x).","category":"page"},{"location":"manual/asynchronous-programming/#Communicating-with-Channels","page":"Asynchronous Programming","title":"Communicating with Channels","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"In some problems, the various pieces of required work are not naturally related by function calls; there is no obvious \"caller\" or \"callee\" among the jobs that need to be done. An example is the producer-consumer problem, where one complex procedure is generating values and another complex procedure is consuming them. The consumer cannot simply call a producer function to get a value, because the producer may have more values to generate and so might not yet be ready to return. With tasks, the producer and consumer can both run as long as they need to, passing values back and forth as necessary.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Julia provides a Channel mechanism for solving this problem. A Channel is a waitable first-in first-out queue which can have multiple tasks reading from and writing to it.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Let's define a producer task, which produces values via the put! call. To consume values, we need to schedule the producer to run in a new task. A special Channel constructor which accepts a 1-arg function as an argument can be used to run a task bound to a channel. We can then take! values repeatedly from the channel object:","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> function producer(c::Channel)\n put!(c, \"start\")\n for n=1:4\n put!(c, 2n)\n end\n put!(c, \"stop\")\n end;\n\njulia> chnl = Channel(producer);\n\njulia> take!(chnl)\n\"start\"\n\njulia> take!(chnl)\n2\n\njulia> take!(chnl)\n4\n\njulia> take!(chnl)\n6\n\njulia> take!(chnl)\n8\n\njulia> take!(chnl)\n\"stop\"","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"One way to think of this behavior is that producer was able to return multiple times. Between calls to put!, the producer's execution is suspended and the consumer has control.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"The returned Channel can be used as an iterable object in a for loop, in which case the loop variable takes on all the produced values. The loop is terminated when the channel is closed.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> for x in Channel(producer)\n println(x)\n end\nstart\n2\n4\n6\n8\nstop","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Note that we did not have to explicitly close the channel in the producer. This is because the act of binding a Channel to a Task associates the open lifetime of a channel with that of the bound task. The channel object is closed automatically when the task terminates. Multiple channels can be bound to a task, and vice-versa.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"While the Task constructor expects a 0-argument function, the Channel method that creates a task-bound channel expects a function that accepts a single argument of type Channel. A common pattern is for the producer to be parameterized, in which case a partial function application is needed to create a 0 or 1 argument anonymous function.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"For Task objects this can be done either directly or by use of a convenience macro:","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"function mytask(myarg)\n ...\nend\n\ntaskHdl = Task(() -> mytask(7))\n# or, equivalently\ntaskHdl = @task mytask(7)","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"To orchestrate more advanced work distribution patterns, bind and schedule can be used in conjunction with Task and Channel constructors to explicitly link a set of channels with a set of producer/consumer tasks.","category":"page"},{"location":"manual/asynchronous-programming/#More-on-Channels","page":"Asynchronous Programming","title":"More on Channels","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"A channel can be visualized as a pipe, i.e., it has a write end and a read end :","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Multiple writers in different tasks can write to the same channel concurrently via put! calls.\nMultiple readers in different tasks can read data concurrently via take! calls.\nAs an example:\n# Given Channels c1 and c2,\nc1 = Channel(32)\nc2 = Channel(32)\n\n# and a function `foo` which reads items from c1, processes the item read\n# and writes a result to c2,\nfunction foo()\n while true\n data = take!(c1)\n [...] # process data\n put!(c2, result) # write out result\n end\nend\n\n# we can schedule `n` instances of `foo` to be active concurrently.\nfor _ in 1:n\n errormonitor(@async foo())\nend\nChannels are created via the Channel{T}(sz) constructor. The channel will only hold objects of type T. If the type is not specified, the channel can hold objects of any type. sz refers to the maximum number of elements that can be held in the channel at any time. For example, Channel(32) creates a channel that can hold a maximum of 32 objects of any type. A Channel{MyType}(64) can hold up to 64 objects of MyType at any time.\nIf a Channel is empty, readers (on a take! call) will block until data is available (see isempty).\nIf a Channel is full, writers (on a put! call) will block until space becomes available (see isfull).\nisready tests for the presence of any object in the channel, while wait waits for an object to become available.\nNote that if another task is currently waiting to put! an object into a channel, a channel can have more items available than its capacity.\nA Channel is in an open state initially. This means that it can be read from and written to freely via take! and put! calls. close closes a Channel. On a closed Channel, put! will fail. For example:\njulia> c = Channel(2);\n\njulia> put!(c, 1) # `put!` on an open channel succeeds\n1\n\njulia> close(c);\n\njulia> put!(c, 2) # `put!` on a closed channel throws an exception.\nERROR: InvalidStateException: Channel is closed.\nStacktrace:\n[...]\ntake! and fetch (which retrieves but does not remove the value) on a closed channel successfully return any existing values until it is emptied. Continuing the above example:\njulia> fetch(c) # Any number of `fetch` calls succeed.\n1\n\njulia> fetch(c)\n1\n\njulia> take!(c) # The first `take!` removes the value.\n1\n\njulia> take!(c) # No more data available on a closed channel.\nERROR: InvalidStateException: Channel is closed.\nStacktrace:\n[...]","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Consider a simple example using channels for inter-task communication. We start 4 tasks to process data from a single jobs channel. Jobs, identified by an id (job_id), are written to the channel. Each task in this simulation reads a job_id, waits for a random amount of time and writes back a tuple of job_id and the simulated time to the results channel. Finally all the results are printed out.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"julia> const jobs = Channel{Int}(32);\n\njulia> const results = Channel{Tuple}(32);\n\njulia> function do_work()\n for job_id in jobs\n exec_time = rand()\n sleep(exec_time) # simulates elapsed time doing actual work\n # typically performed externally.\n put!(results, (job_id, exec_time))\n end\n end;\n\njulia> function make_jobs(n)\n for i in 1:n\n put!(jobs, i)\n end\n end;\n\njulia> n = 12;\n\njulia> errormonitor(@async make_jobs(n)); # feed the jobs channel with \"n\" jobs\n\njulia> for i in 1:4 # start 4 tasks to process requests in parallel\n errormonitor(@async do_work())\n end\n\njulia> @elapsed while n > 0 # print out results\n job_id, exec_time = take!(results)\n println(\"$job_id finished in $(round(exec_time; digits=2)) seconds\")\n global n = n - 1\n end\n4 finished in 0.22 seconds\n3 finished in 0.45 seconds\n1 finished in 0.5 seconds\n7 finished in 0.14 seconds\n2 finished in 0.78 seconds\n5 finished in 0.9 seconds\n9 finished in 0.36 seconds\n6 finished in 0.87 seconds\n8 finished in 0.79 seconds\n10 finished in 0.64 seconds\n12 finished in 0.5 seconds\n11 finished in 0.97 seconds\n0.029772311","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Instead of errormonitor(t), a more robust solution may be to use bind(results, t), as that will not only log any unexpected failures, but also force the associated resources to close and propagate the exception everywhere.","category":"page"},{"location":"manual/asynchronous-programming/#More-task-operations","page":"Asynchronous Programming","title":"More task operations","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Task operations are built on a low-level primitive called yieldto. yieldto(task, value) suspends the current task, switches to the specified task, and causes that task's last yieldto call to return the specified value. Notice that yieldto is the only operation required to use task-style control flow; instead of calling and returning we are always just switching to a different task. This is why this feature is also called \"symmetric coroutines\"; each task is switched to and from using the same mechanism.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"yieldto is powerful, but most uses of tasks do not invoke it directly. Consider why this might be. If you switch away from the current task, you will probably want to switch back to it at some point, but knowing when to switch back, and knowing which task has the responsibility of switching back, can require considerable coordination. For example, put! and take! are blocking operations, which, when used in the context of channels maintain state to remember who the consumers are. Not needing to manually keep track of the consuming task is what makes put! easier to use than the low-level yieldto.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"In addition to yieldto, a few other basic functions are needed to use tasks effectively.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"current_task gets a reference to the currently-running task.\nistaskdone queries whether a task has exited.\nistaskstarted queries whether a task has run yet.\ntask_local_storage manipulates a key-value store specific to the current task.","category":"page"},{"location":"manual/asynchronous-programming/#Tasks-and-events","page":"Asynchronous Programming","title":"Tasks and events","text":"","category":"section"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"Most task switches occur as a result of waiting for events such as I/O requests, and are performed by a scheduler included in Julia Base. The scheduler maintains a queue of runnable tasks, and executes an event loop that restarts tasks based on external events such as message arrival.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"The basic function for waiting for an event is wait. Several objects implement wait; for example, given a Process object, wait will wait for it to exit. wait is often implicit; for example, a wait can happen inside a call to read to wait for data to be available.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"In all of these cases, wait ultimately operates on a Condition object, which is in charge of queueing and restarting tasks. When a task calls wait on a Condition, the task is marked as non-runnable, added to the condition's queue, and switches to the scheduler. The scheduler will then pick another task to run, or block waiting for external events. If all goes well, eventually an event handler will call notify on the condition, which causes tasks waiting for that condition to become runnable again.","category":"page"},{"location":"manual/asynchronous-programming/","page":"Asynchronous Programming","title":"Asynchronous Programming","text":"A task created explicitly by calling Task is initially not known to the scheduler. This allows you to manage tasks manually using yieldto if you wish. However, when such a task waits for an event, it still gets restarted automatically when the event happens, as you would expect.","category":"page"},{"location":"base/strings/#lib-strings","page":"Strings","title":"Strings","text":"","category":"section"},{"location":"base/strings/","page":"Strings","title":"Strings","text":"Core.AbstractString\nCore.AbstractChar\nCore.Char\nBase.codepoint\nBase.length(::AbstractString)\nBase.sizeof(::AbstractString)\nBase.:*(::Union{AbstractChar, AbstractString}, ::Union{AbstractChar, AbstractString}...)\nBase.:^(::Union{AbstractString, AbstractChar}, ::Integer)\nBase.string\nBase.repeat(::AbstractString, ::Integer)\nBase.repeat(::AbstractChar, ::Integer)\nBase.repr(::Any)\nCore.String(::AbstractString)\nBase.SubString\nBase.LazyString\nBase.@lazy_str\nBase.AnnotatedString\nBase.AnnotatedChar\nBase.annotatedstring\nBase.annotations\nBase.annotate!\nBase.transcode\nBase.unsafe_string\nBase.ncodeunits(::AbstractString)\nBase.codeunit\nBase.codeunits\nBase.ascii\nBase.Regex\nBase.@r_str\nBase.SubstitutionString\nBase.@s_str\nBase.@raw_str\nBase.@b_str\nBase.Docs.@html_str\nBase.Docs.@text_str\nBase.isvalid(::Any)\nBase.isvalid(::Any, ::Any)\nBase.isvalid(::AbstractString, ::Integer)\nBase.match\nBase.eachmatch\nBase.RegexMatch\nBase.keys(::RegexMatch)\nBase.isless(::AbstractString, ::AbstractString)\nBase.:(==)(::AbstractString, ::AbstractString)\nBase.cmp(::AbstractString, ::AbstractString)\nBase.lpad\nBase.rpad\nBase.findfirst(::AbstractString, ::AbstractString)\nBase.findnext(::AbstractString, ::AbstractString, ::Integer)\nBase.findnext(::AbstractChar, ::AbstractString, ::Integer)\nBase.findlast(::AbstractString, ::AbstractString)\nBase.findlast(::AbstractChar, ::AbstractString)\nBase.findprev(::AbstractString, ::AbstractString, ::Integer)\nBase.occursin\nBase.reverse(::Union{String,SubString{String}})\nBase.replace(::IO, s::AbstractString, ::Pair...)\nBase.eachsplit\nBase.eachrsplit\nBase.split\nBase.rsplit\nBase.strip\nBase.lstrip\nBase.rstrip\nBase.startswith\nBase.endswith\nBase.contains\nBase.first(::AbstractString, ::Integer)\nBase.last(::AbstractString, ::Integer)\nBase.uppercase\nBase.lowercase\nBase.titlecase\nBase.uppercasefirst\nBase.lowercasefirst\nBase.join\nBase.chop\nBase.chopprefix\nBase.chopsuffix\nBase.chomp\nBase.thisind\nBase.nextind(::AbstractString, ::Integer, ::Integer)\nBase.prevind(::AbstractString, ::Integer, ::Integer)\nBase.textwidth\nBase.isascii\nBase.iscntrl\nBase.isdigit\nBase.isletter\nBase.islowercase\nBase.isnumeric\nBase.isprint\nBase.ispunct\nBase.isspace\nBase.isuppercase\nBase.isxdigit\nBase.escape_string\nBase.escape_raw_string\nBase.unescape_string","category":"page"},{"location":"base/strings/#Core.AbstractString","page":"Strings","title":"Core.AbstractString","text":"The AbstractString type is the supertype of all string implementations in Julia. Strings are encodings of sequences of Unicode code points as represented by the AbstractChar type. Julia makes a few assumptions about strings:\n\nStrings are encoded in terms of fixed-size \"code units\"\nCode units can be extracted with codeunit(s, i)\nThe first code unit has index 1\nThe last code unit has index ncodeunits(s)\nAny index i such that 1 ≤ i ≤ ncodeunits(s) is in bounds\nString indexing is done in terms of these code units:\nCharacters are extracted by s[i] with a valid string index i\nEach AbstractChar in a string is encoded by one or more code units\nOnly the index of the first code unit of an AbstractChar is a valid index\nThe encoding of an AbstractChar is independent of what precedes or follows it\nString encodings are self-synchronizing – i.e. isvalid(s, i) is O(1)\n\nSome string functions that extract code units, characters or substrings from strings error if you pass them out-of-bounds or invalid string indices. This includes codeunit(s, i) and s[i]. Functions that do string index arithmetic take a more relaxed approach to indexing and give you the closest valid string index when in-bounds, or when out-of-bounds, behave as if there were an infinite number of characters padding each side of the string. Usually these imaginary padding characters have code unit length 1 but string types may choose different \"imaginary\" character sizes as makes sense for their implementations (e.g. substrings may pass index arithmetic through to the underlying string they provide a view into). Relaxed indexing functions include those intended for index arithmetic: thisind, nextind and prevind. This model allows index arithmetic to work with out-of-bounds indices as intermediate values so long as one never uses them to retrieve a character, which often helps avoid needing to code around edge cases.\n\nSee also codeunit, ncodeunits, thisind, nextind, prevind.\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Core.AbstractChar","page":"Strings","title":"Core.AbstractChar","text":"The AbstractChar type is the supertype of all character implementations in Julia. A character represents a Unicode code point, and can be converted to an integer via the codepoint function in order to obtain the numerical value of the code point, or constructed from the same integer. These numerical values determine how characters are compared with < and ==, for example. New T <: AbstractChar types should define a codepoint(::T) method and a T(::UInt32) constructor, at minimum.\n\nA given AbstractChar subtype may be capable of representing only a subset of Unicode, in which case conversion from an unsupported UInt32 value may throw an error. Conversely, the built-in Char type represents a superset of Unicode (in order to losslessly encode invalid byte streams), in which case conversion of a non-Unicode value to UInt32 throws an error. The isvalid function can be used to check which codepoints are representable in a given AbstractChar type.\n\nInternally, an AbstractChar type may use a variety of encodings. Conversion via codepoint(char) will not reveal this encoding because it always returns the Unicode value of the character. print(io, c) of any c::AbstractChar produces an encoding determined by io (UTF-8 for all built-in IO types), via conversion to Char if necessary.\n\nwrite(io, c), in contrast, may emit an encoding depending on typeof(c), and read(io, typeof(c)) should read the same encoding as write. New AbstractChar types must provide their own implementations of write and read.\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Core.Char","page":"Strings","title":"Core.Char","text":"Char(c::Union{Number,AbstractChar})\n\nChar is a 32-bit AbstractChar type that is the default representation of characters in Julia. Char is the type used for character literals like 'x' and it is also the element type of String.\n\nIn order to losslessly represent arbitrary byte streams stored in a String, a Char value may store information that cannot be converted to a Unicode codepoint — converting such a Char to UInt32 will throw an error. The isvalid(c::Char) function can be used to query whether c represents a valid Unicode character.\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.codepoint","page":"Strings","title":"Base.codepoint","text":"codepoint(c::AbstractChar) -> Integer\n\nReturn the Unicode codepoint (an unsigned integer) corresponding to the character c (or throw an exception if c does not represent a valid character). For Char, this is a UInt32 value, but AbstractChar types that represent only a subset of Unicode may return a different-sized integer (e.g. UInt8).\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.length-Tuple{AbstractString}","page":"Strings","title":"Base.length","text":"length(s::AbstractString) -> Int\nlength(s::AbstractString, i::Integer, j::Integer) -> Int\n\nReturn the number of characters in string s from indices i through j.\n\nThis is computed as the number of code unit indices from i to j which are valid character indices. With only a single string argument, this computes the number of characters in the entire string. With i and j arguments it computes the number of indices between i and j inclusive that are valid indices in the string s. In addition to in-bounds values, i may take the out-of-bounds value ncodeunits(s) + 1 and j may take the out-of-bounds value 0.\n\nnote: Note\nThe time complexity of this operation is linear in general. That is, it will take the time proportional to the number of bytes or characters in the string because it counts the value on the fly. This is in contrast to the method for arrays, which is a constant-time operation.\n\nSee also isvalid, ncodeunits, lastindex, thisind, nextind, prevind.\n\nExamples\n\njulia> length(\"jμΛIα\")\n5\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.sizeof-Tuple{AbstractString}","page":"Strings","title":"Base.sizeof","text":"sizeof(str::AbstractString)\n\nSize, in bytes, of the string str. Equal to the number of code units in str multiplied by the size, in bytes, of one code unit in str.\n\nExamples\n\njulia> sizeof(\"\")\n0\n\njulia> sizeof(\"∀\")\n3\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.:*-Tuple{Union{AbstractChar, AbstractString}, Vararg{Union{AbstractChar, AbstractString}}}","page":"Strings","title":"Base.:*","text":"*(s::Union{AbstractString, AbstractChar}, t::Union{AbstractString, AbstractChar}...) -> AbstractString\n\nConcatenate strings and/or characters, producing a String or AnnotatedString (as appropriate). This is equivalent to calling the string or annotatedstring function on the arguments. Concatenation of built-in string types always produces a value of type String but other string types may choose to return a string of a different type as appropriate.\n\nExamples\n\njulia> \"Hello \" * \"world\"\n\"Hello world\"\n\njulia> 'j' * \"ulia\"\n\"julia\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.:^-Tuple{Union{AbstractChar, AbstractString}, Integer}","page":"Strings","title":"Base.:^","text":"^(s::Union{AbstractString,AbstractChar}, n::Integer) -> AbstractString\n\nRepeat a string or character n times. This can also be written as repeat(s, n).\n\nSee also repeat.\n\nExamples\n\njulia> \"Test \"^3\n\"Test Test Test \"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.string","page":"Strings","title":"Base.string","text":"string(n::Integer; base::Integer = 10, pad::Integer = 1)\n\nConvert an integer n to a string in the given base, optionally specifying a number of digits to pad to.\n\nSee also digits, bitstring, count_zeros.\n\nExamples\n\njulia> string(5, base = 13, pad = 4)\n\"0005\"\n\njulia> string(-13, base = 5, pad = 4)\n\"-0023\"\n\n\n\n\n\nstring(xs...)\n\nCreate a string from any values using the print function.\n\nstring should usually not be defined directly. Instead, define a method print(io::IO, x::MyType). If string(x) for a certain type needs to be highly efficient, then it may make sense to add a method to string and define print(io::IO, x::MyType) = print(io, string(x)) to ensure the functions are consistent.\n\nSee also: String, repr, sprint, show.\n\nExamples\n\njulia> string(\"a\", 1, true)\n\"a1true\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.repeat-Tuple{AbstractString, Integer}","page":"Strings","title":"Base.repeat","text":"repeat(s::AbstractString, r::Integer)\n\nRepeat a string r times. This can be written as s^r.\n\nSee also ^.\n\nExamples\n\njulia> repeat(\"ha\", 3)\n\"hahaha\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.repeat-Tuple{AbstractChar, Integer}","page":"Strings","title":"Base.repeat","text":"repeat(c::AbstractChar, r::Integer) -> String\n\nRepeat a character r times. This can equivalently be accomplished by calling c^r.\n\nExamples\n\njulia> repeat('A', 3)\n\"AAA\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.repr-Tuple{Any}","page":"Strings","title":"Base.repr","text":"repr(x; context=nothing)\n\nCreate a string from any value using the show function. You should not add methods to repr; define a show method instead.\n\nThe optional keyword argument context can be set to a :key=>value pair, a tuple of :key=>value pairs, or an IO or IOContext object whose attributes are used for the I/O stream passed to show.\n\nNote that repr(x) is usually similar to how the value of x would be entered in Julia. See also repr(MIME(\"text/plain\"), x) to instead return a \"pretty-printed\" version of x designed more for human consumption, equivalent to the REPL display of x.\n\ncompat: Julia 1.7\nPassing a tuple to keyword context requires Julia 1.7 or later.\n\nExamples\n\njulia> repr(1)\n\"1\"\n\njulia> repr(zeros(3))\n\"[0.0, 0.0, 0.0]\"\n\njulia> repr(big(1/3))\n\"0.333333333333333314829616256247390992939472198486328125\"\n\njulia> repr(big(1/3), context=:compact => true)\n\"0.333333\"\n\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Core.String-Tuple{AbstractString}","page":"Strings","title":"Core.String","text":"String(s::AbstractString)\n\nCreate a new String from an existing AbstractString.\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.SubString","page":"Strings","title":"Base.SubString","text":"SubString(s::AbstractString, i::Integer, j::Integer=lastindex(s))\nSubString(s::AbstractString, r::UnitRange{<:Integer})\n\nLike getindex, but returns a view into the parent string s within range i:j or r respectively instead of making a copy.\n\nThe @views macro converts any string slices s[i:j] into substrings SubString(s, i, j) in a block of code.\n\nExamples\n\njulia> SubString(\"abc\", 1, 2)\n\"ab\"\n\njulia> SubString(\"abc\", 1:2)\n\"ab\"\n\njulia> SubString(\"abc\", 2)\n\"bc\"\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.LazyString","page":"Strings","title":"Base.LazyString","text":"LazyString <: AbstractString\n\nA lazy representation of string interpolation. This is useful when a string needs to be constructed in a context where performing the actual interpolation and string construction is unnecessary or undesirable (e.g. in error paths of functions).\n\nThis type is designed to be cheap to construct at runtime, trying to offload as much work as possible to either the macro or later printing operations.\n\nExamples\n\njulia> n = 5; str = LazyString(\"n is \", n)\n\"n is 5\"\n\nSee also @lazy_str.\n\ncompat: Julia 1.8\nLazyString requires Julia 1.8 or later.\n\nExtended help\n\nSafety properties for concurrent programs\n\nA lazy string itself does not introduce any concurrency problems even if it is printed in multiple Julia tasks. However, if print methods on a captured value can have a concurrency issue when invoked without synchronizations, printing the lazy string may cause an issue. Furthermore, the print methods on the captured values may be invoked multiple times, though only exactly one result will be returned.\n\ncompat: Julia 1.9\nLazyString is safe in the above sense in Julia 1.9 and later.\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.@lazy_str","page":"Strings","title":"Base.@lazy_str","text":"lazy\"str\"\n\nCreate a LazyString using regular string interpolation syntax. Note that interpolations are evaluated at LazyString construction time, but printing is delayed until the first access to the string.\n\nSee LazyString documentation for the safety properties for concurrent programs.\n\nExamples\n\njulia> n = 5; str = lazy\"n is $n\"\n\"n is 5\"\n\njulia> typeof(str)\nLazyString\n\ncompat: Julia 1.8\nlazy\"str\" requires Julia 1.8 or later.\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.AnnotatedString","page":"Strings","title":"Base.AnnotatedString","text":"AnnotatedString{S <: AbstractString} <: AbstractString\n\nA string with metadata, in the form of annotated regions.\n\nMore specifically, this is a simple wrapper around any other AbstractString that allows for regions of the wrapped string to be annotated with labeled values.\n\n C\n ┌──────┸─────────┐\n \"this is an example annotated string\"\n └──┰────────┼─────┘ │\n A └─────┰─────────┘\n B\n\nThe above diagram represents a AnnotatedString where three ranges have been annotated (labeled A, B, and C). Each annotation holds a label (Symbol) and a value (Any), paired together as a Pair{Symbol, <:Any}.\n\nLabels do not need to be unique, the same region can hold multiple annotations with the same label.\n\nSee also AnnotatedChar, annotatedstring, annotations, and annotate!.\n\nwarning: Warning\nWhile the constructors are part of the Base public API, the fields of AnnotatedString are not. This is to allow for potential future changes in the implementation of this type. Instead use the annotations, and annotate! getter/setter functions.\n\nConstructors\n\nAnnotatedString(s::S<:AbstractString) -> AnnotatedString{S}\nAnnotatedString(s::S<:AbstractString, annotations::Vector{Tuple{UnitRange{Int}, Pair{Symbol, <:Any}}})\n\nA AnnotatedString can also be created with annotatedstring, which acts much like string but preserves any annotations present in the arguments.\n\nExamples\n\njulia> AnnotatedString(\"this is an example annotated string\",\n [(1:18, :A => 1), (12:28, :B => 2), (18:35, :C => 3)])\n\"this is an example annotated string\"\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.AnnotatedChar","page":"Strings","title":"Base.AnnotatedChar","text":"AnnotatedChar{S <: AbstractChar} <: AbstractChar\n\nA Char with annotations.\n\nMore specifically, this is a simple wrapper around any other AbstractChar, which holds a list of arbitrary labeled annotations (Pair{Symbol, <:Any}) with the wrapped character.\n\nSee also: AnnotatedString, annotatedstring, annotations, and annotate!.\n\nwarning: Warning\nWhile the constructors are part of the Base public API, the fields of AnnotatedChar are not. This it to allow for potential future changes in the implementation of this type. Instead use the annotations, and annotate! getter/setter functions.\n\nConstructors\n\nAnnotatedChar(s::S) -> AnnotatedChar{S}\nAnnotatedChar(s::S, annotations::Vector{Pair{Symbol, <:Any}})\n\nExamples\n\njulia> AnnotatedChar('j', :label => 1)\n'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.annotatedstring","page":"Strings","title":"Base.annotatedstring","text":"annotatedstring(values...)\n\nCreate a AnnotatedString from any number of values using their printed representation.\n\nThis acts like string, but takes care to preserve any annotations present (in the form of AnnotatedString or AnnotatedChar values).\n\nSee also AnnotatedString and AnnotatedChar.\n\nExamples\n\njulia> annotatedstring(\"now a AnnotatedString\")\n\"now a AnnotatedString\"\n\njulia> annotatedstring(AnnotatedString(\"annotated\", [(1:9, :label => 1)]), \", and unannotated\")\n\"annotated, and unannotated\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.annotations","page":"Strings","title":"Base.annotations","text":"annotations(str::Union{AnnotatedString, SubString{AnnotatedString}},\n [position::Union{Integer, UnitRange}]) ->\n Vector{Tuple{UnitRange{Int}, Pair{Symbol, Any}}}\n\nGet all annotations that apply to str. Should position be provided, only annotations that overlap with position will be returned.\n\nAnnotations are provided together with the regions they apply to, in the form of a vector of region–annotation tuples.\n\nSee also: annotate!.\n\n\n\n\n\nannotations(chr::AnnotatedChar) -> Vector{Pair{Symbol, Any}}\n\nGet all annotations of chr, in the form of a vector of annotation pairs.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.annotate!","page":"Strings","title":"Base.annotate!","text":"annotate!(str::AnnotatedString, [range::UnitRange{Int}], label::Symbol => value)\nannotate!(str::SubString{AnnotatedString}, [range::UnitRange{Int}], label::Symbol => value)\n\nAnnotate a range of str (or the entire string) with a labeled value (label => value). To remove existing label annotations, use a value of nothing.\n\n\n\n\n\nannotate!(char::AnnotatedChar, label::Symbol => value)\n\nAnnotate char with the pair label => value.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.transcode","page":"Strings","title":"Base.transcode","text":"transcode(T, src)\n\nConvert string data between Unicode encodings. src is either a String or a Vector{UIntXX} of UTF-XX code units, where XX is 8, 16, or 32. T indicates the encoding of the return value: String to return a (UTF-8 encoded) String or UIntXX to return a Vector{UIntXX} of UTF-XX data. (The alias Cwchar_t can also be used as the integer type, for converting wchar_t* strings used by external C libraries.)\n\nThe transcode function succeeds as long as the input data can be reasonably represented in the target encoding; it always succeeds for conversions between UTF-XX encodings, even for invalid Unicode data.\n\nOnly conversion to/from UTF-8 is currently supported.\n\nExamples\n\njulia> str = \"αβγ\"\n\"αβγ\"\n\njulia> transcode(UInt16, str)\n3-element Vector{UInt16}:\n 0x03b1\n 0x03b2\n 0x03b3\n\njulia> transcode(String, transcode(UInt16, str))\n\"αβγ\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.unsafe_string","page":"Strings","title":"Base.unsafe_string","text":"unsafe_string(p::Ptr{UInt8}, [length::Integer])\n\nCopy a string from the address of a C-style (NUL-terminated) string encoded as UTF-8. (The pointer can be safely freed afterwards.) If length is specified (the length of the data in bytes), the string does not have to be NUL-terminated.\n\nThis function is labeled \"unsafe\" because it will crash if p is not a valid memory address to data of the requested length.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.ncodeunits-Tuple{AbstractString}","page":"Strings","title":"Base.ncodeunits","text":"ncodeunits(s::AbstractString) -> Int\n\nReturn the number of code units in a string. Indices that are in bounds to access this string must satisfy 1 ≤ i ≤ ncodeunits(s). Not all such indices are valid – they may not be the start of a character, but they will return a code unit value when calling codeunit(s,i).\n\nExamples\n\njulia> ncodeunits(\"The Julia Language\")\n18\n\njulia> ncodeunits(\"∫eˣ\")\n6\n\njulia> ncodeunits('∫'), ncodeunits('e'), ncodeunits('ˣ')\n(3, 1, 2)\n\nSee also codeunit, checkbounds, sizeof, length, lastindex.\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.codeunit","page":"Strings","title":"Base.codeunit","text":"codeunit(s::AbstractString) -> Type{<:Union{UInt8, UInt16, UInt32}}\n\nReturn the code unit type of the given string object. For ASCII, Latin-1, or UTF-8 encoded strings, this would be UInt8; for UCS-2 and UTF-16 it would be UInt16; for UTF-32 it would be UInt32. The code unit type need not be limited to these three types, but it's hard to think of widely used string encodings that don't use one of these units. codeunit(s) is the same as typeof(codeunit(s,1)) when s is a non-empty string.\n\nSee also ncodeunits.\n\n\n\n\n\ncodeunit(s::AbstractString, i::Integer) -> Union{UInt8, UInt16, UInt32}\n\nReturn the code unit value in the string s at index i. Note that\n\ncodeunit(s, i) :: codeunit(s)\n\nI.e. the value returned by codeunit(s, i) is of the type returned by codeunit(s).\n\nExamples\n\njulia> a = codeunit(\"Hello\", 2)\n0x65\n\njulia> typeof(a)\nUInt8\n\nSee also ncodeunits, checkbounds.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.codeunits","page":"Strings","title":"Base.codeunits","text":"codeunits(s::AbstractString)\n\nObtain a vector-like object containing the code units of a string. Returns a CodeUnits wrapper by default, but codeunits may optionally be defined for new string types if necessary.\n\nExamples\n\njulia> codeunits(\"Juλia\")\n6-element Base.CodeUnits{UInt8, String}:\n 0x4a\n 0x75\n 0xce\n 0xbb\n 0x69\n 0x61\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.ascii","page":"Strings","title":"Base.ascii","text":"ascii(s::AbstractString)\n\nConvert a string to String type and check that it contains only ASCII data, otherwise throwing an ArgumentError indicating the position of the first non-ASCII byte.\n\nSee also the isascii predicate to filter or replace non-ASCII characters.\n\nExamples\n\njulia> ascii(\"abcdeγfgh\")\nERROR: ArgumentError: invalid ASCII at index 6 in \"abcdeγfgh\"\nStacktrace:\n[...]\n\njulia> ascii(\"abcdefgh\")\n\"abcdefgh\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Regex","page":"Strings","title":"Base.Regex","text":"Regex(pattern[, flags]) <: AbstractPattern\n\nA type representing a regular expression. Regex objects can be used to match strings with match.\n\nRegex objects can be created using the @r_str string macro. The Regex(pattern[, flags]) constructor is usually used if the pattern string needs to be interpolated. See the documentation of the string macro for details on flags.\n\nnote: Note\nTo escape interpolated variables use \\Q and \\E (e.g. Regex(\"\\\\Q$x\\\\E\"))\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.@r_str","page":"Strings","title":"Base.@r_str","text":"@r_str -> Regex\n\nConstruct a regex, such as r\"^[a-z]*$\", without interpolation and unescaping (except for quotation mark \" which still has to be escaped). The regex also accepts one or more flags, listed after the ending quote, to change its behaviour:\n\ni enables case-insensitive matching\nm treats the ^ and $ tokens as matching the start and end of individual lines, as opposed to the whole string.\ns allows the . modifier to match newlines.\nx enables \"free-spacing mode\": whitespace between regex tokens is ignored except when escaped with \\, and # in the regex is treated as starting a comment (which is ignored to the line ending).\na enables ASCII mode (disables UTF and UCP modes). By default \\B, \\b, \\D, \\d, \\S, \\s, \\W, \\w, etc. match based on Unicode character properties. With this option, these sequences only match ASCII characters. This includes \\u also, which will emit the specified character value directly as a single byte, and not attempt to encode it into UTF-8. Importantly, this option allows matching against invalid UTF-8 strings, by treating both matcher and target as simple bytes (as if they were ISO/IEC 8859-1 / Latin-1 bytes) instead of as character encodings. In this case, this option is often combined with s. This option can be further refined by starting the pattern with (UCP) or (UTF).\n\nSee Regex if interpolation is needed.\n\nExamples\n\njulia> match(r\"a+.*b+.*?d$\"ism, \"Goodbye,\\nOh, angry,\\nBad world\\n\")\nRegexMatch(\"angry,\\nBad world\")\n\nThis regex has the first three flags enabled.\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.SubstitutionString","page":"Strings","title":"Base.SubstitutionString","text":"SubstitutionString(substr) <: AbstractString\n\nStores the given string substr as a SubstitutionString, for use in regular expression substitutions. Most commonly constructed using the @s_str macro.\n\nExamples\n\njulia> SubstitutionString(\"Hello \\\\g, it's \\\\1\")\ns\"Hello \\g, it's \\1\"\n\njulia> subst = s\"Hello \\g, it's \\1\"\ns\"Hello \\g, it's \\1\"\n\njulia> typeof(subst)\nSubstitutionString{String}\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.@s_str","page":"Strings","title":"Base.@s_str","text":"@s_str -> SubstitutionString\n\nConstruct a substitution string, used for regular expression substitutions. Within the string, sequences of the form \\N refer to the Nth capture group in the regex, and \\g refers to a named capture group with name groupname.\n\nExamples\n\njulia> msg = \"#Hello# from Julia\";\n\njulia> replace(msg, r\"#(.+)# from (?\\w+)\" => s\"FROM: \\g; MESSAGE: \\1\")\n\"FROM: Julia; MESSAGE: Hello\"\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.@raw_str","page":"Strings","title":"Base.@raw_str","text":"@raw_str -> String\n\nCreate a raw string without interpolation and unescaping. The exception is that quotation marks still must be escaped. Backslashes escape both quotation marks and other backslashes, but only when a sequence of backslashes precedes a quote character. Thus, 2n backslashes followed by a quote encodes n backslashes and the end of the literal while 2n+1 backslashes followed by a quote encodes n backslashes followed by a quote character.\n\nExamples\n\njulia> println(raw\"\\ $x\")\n\\ $x\n\njulia> println(raw\"\\\"\")\n\"\n\njulia> println(raw\"\\\\\\\"\")\n\\\"\n\njulia> println(raw\"\\\\x \\\\\\\"\")\n\\\\x \\\"\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.@b_str","page":"Strings","title":"Base.@b_str","text":"@b_str\n\nCreate an immutable byte (UInt8) vector using string syntax.\n\nExamples\n\njulia> v = b\"12\\x01\\x02\"\n4-element Base.CodeUnits{UInt8, String}:\n 0x31\n 0x32\n 0x01\n 0x02\n\njulia> v[2]\n0x32\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.Docs.@html_str","page":"Strings","title":"Base.Docs.@html_str","text":"@html_str -> Docs.HTML\n\nCreate an HTML object from a literal string.\n\nExamples\n\njulia> html\"Julia\"\nHTML{String}(\"Julia\")\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.Docs.@text_str","page":"Strings","title":"Base.Docs.@text_str","text":"@text_str -> Docs.Text\n\nCreate a Text object from a literal string.\n\nExamples\n\njulia> text\"Julia\"\nJulia\n\n\n\n\n\n","category":"macro"},{"location":"base/strings/#Base.isvalid-Tuple{Any}","page":"Strings","title":"Base.isvalid","text":"isvalid(value) -> Bool\n\nReturn true if the given value is valid for its type, which currently can be either AbstractChar or String or SubString{String}.\n\nExamples\n\njulia> isvalid(Char(0xd800))\nfalse\n\njulia> isvalid(SubString(String(UInt8[0xfe,0x80,0x80,0x80,0x80,0x80]),1,2))\nfalse\n\njulia> isvalid(Char(0xd799))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.isvalid-Tuple{Any, Any}","page":"Strings","title":"Base.isvalid","text":"isvalid(T, value) -> Bool\n\nReturn true if the given value is valid for that type. Types currently can be either AbstractChar or String. Values for AbstractChar can be of type AbstractChar or UInt32. Values for String can be of that type, SubString{String}, Vector{UInt8}, or a contiguous subarray thereof.\n\nExamples\n\njulia> isvalid(Char, 0xd800)\nfalse\n\njulia> isvalid(String, SubString(\"thisisvalid\",1,5))\ntrue\n\njulia> isvalid(Char, 0xd799)\ntrue\n\ncompat: Julia 1.6\nSupport for subarray values was added in Julia 1.6.\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.isvalid-Tuple{AbstractString, Integer}","page":"Strings","title":"Base.isvalid","text":"isvalid(s::AbstractString, i::Integer) -> Bool\n\nPredicate indicating whether the given index is the start of the encoding of a character in s or not. If isvalid(s, i) is true then s[i] will return the character whose encoding starts at that index, if it's false, then s[i] will raise an invalid index error or a bounds error depending on if i is in bounds. In order for isvalid(s, i) to be an O(1) function, the encoding of s must be self-synchronizing. This is a basic assumption of Julia's generic string support.\n\nSee also getindex, iterate, thisind, nextind, prevind, length.\n\nExamples\n\njulia> str = \"αβγdef\";\n\njulia> isvalid(str, 1)\ntrue\n\njulia> str[1]\n'α': Unicode U+03B1 (category Ll: Letter, lowercase)\n\njulia> isvalid(str, 2)\nfalse\n\njulia> str[2]\nERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'α', [3]=>'β'\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.match","page":"Strings","title":"Base.match","text":"match(r::Regex, s::AbstractString[, idx::Integer[, addopts]])\n\nSearch for the first match of the regular expression r in s and return a RegexMatch object containing the match, or nothing if the match failed. The optional idx argument specifies an index at which to start the search. The matching substring can be retrieved by accessing m.match, the captured sequences can be retrieved by accessing m.captures. The resulting RegexMatch object can be used to construct other collections: e.g. Tuple(m), NamedTuple(m).\n\ncompat: Julia 1.11\nConstructing NamedTuples and Dicts requires Julia 1.11\n\nExamples\n\njulia> rx = r\"a(.)a\"\nr\"a(.)a\"\n\njulia> m = match(rx, \"cabac\")\nRegexMatch(\"aba\", 1=\"b\")\n\njulia> m.captures\n1-element Vector{Union{Nothing, SubString{String}}}:\n \"b\"\n\njulia> m.match\n\"aba\"\n\njulia> match(rx, \"cabac\", 3) === nothing\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.eachmatch","page":"Strings","title":"Base.eachmatch","text":"eachmatch(r::Regex, s::AbstractString; overlap::Bool=false)\n\nSearch for all matches of the regular expression r in s and return an iterator over the matches. If overlap is true, the matching sequences are allowed to overlap indices in the original string, otherwise they must be from distinct character ranges.\n\nExamples\n\njulia> rx = r\"a.a\"\nr\"a.a\"\n\njulia> m = eachmatch(rx, \"a1a2a3a\")\nBase.RegexMatchIterator{String}(r\"a.a\", \"a1a2a3a\", false)\n\njulia> collect(m)\n2-element Vector{RegexMatch}:\n RegexMatch(\"a1a\")\n RegexMatch(\"a3a\")\n\njulia> collect(eachmatch(rx, \"a1a2a3a\", overlap = true))\n3-element Vector{RegexMatch}:\n RegexMatch(\"a1a\")\n RegexMatch(\"a2a\")\n RegexMatch(\"a3a\")\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.RegexMatch","page":"Strings","title":"Base.RegexMatch","text":"RegexMatch <: AbstractMatch\n\nA type representing a single match to a Regex found in a string. Typically created from the match function.\n\nThe match field stores the substring of the entire matched string. The captures field stores the substrings for each capture group, indexed by number. To index by capture group name, the entire match object should be indexed instead, as shown in the examples. The location of the start of the match is stored in the offset field. The offsets field stores the locations of the start of each capture group, with 0 denoting a group that was not captured.\n\nThis type can be used as an iterator over the capture groups of the Regex, yielding the substrings captured in each group. Because of this, the captures of a match can be destructured. If a group was not captured, nothing will be yielded instead of a substring.\n\nMethods that accept a RegexMatch object are defined for iterate, length, eltype, keys, haskey, and getindex, where keys are the names or numbers of a capture group. See keys for more information.\n\nTuple(m), NamedTuple(m), and Dict(m) can be used to construct more flexible collection types from RegexMatch objects.\n\ncompat: Julia 1.11\nConstructing NamedTuples and Dicts from RegexMatches requires Julia 1.11\n\nExamples\n\njulia> m = match(r\"(?\\d+):(?\\d+)(am|pm)?\", \"11:30 in the morning\")\nRegexMatch(\"11:30\", hour=\"11\", minute=\"30\", 3=nothing)\n\njulia> m.match\n\"11:30\"\n\njulia> m.captures\n3-element Vector{Union{Nothing, SubString{String}}}:\n \"11\"\n \"30\"\n nothing\n\n\njulia> m[\"minute\"]\n\"30\"\n\njulia> hr, min, ampm = m; # destructure capture groups by iteration\n\njulia> hr\n\"11\"\n\njulia> Dict(m)\nDict{Any, Union{Nothing, SubString{String}}} with 3 entries:\n \"hour\" => \"11\"\n 3 => nothing\n \"minute\" => \"30\"\n\n\n\n\n\n","category":"type"},{"location":"base/strings/#Base.keys-Tuple{RegexMatch}","page":"Strings","title":"Base.keys","text":"keys(m::RegexMatch) -> Vector\n\nReturn a vector of keys for all capture groups of the underlying regex. A key is included even if the capture group fails to match. That is, idx will be in the return value even if m[idx] == nothing.\n\nUnnamed capture groups will have integer keys corresponding to their index. Named capture groups will have string keys.\n\ncompat: Julia 1.7\nThis method was added in Julia 1.7\n\nExamples\n\njulia> keys(match(r\"(?\\d+):(?\\d+)(am|pm)?\", \"11:30\"))\n3-element Vector{Any}:\n \"hour\"\n \"minute\"\n 3\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.isless-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.isless","text":"isless(a::AbstractString, b::AbstractString) -> Bool\n\nTest whether string a comes before string b in alphabetical order (technically, in lexicographical order by Unicode code points).\n\nExamples\n\njulia> isless(\"a\", \"b\")\ntrue\n\njulia> isless(\"β\", \"α\")\nfalse\n\njulia> isless(\"a\", \"a\")\nfalse\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.:==-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.:==","text":"==(a::AbstractString, b::AbstractString) -> Bool\n\nTest whether two strings are equal character by character (technically, Unicode code point by code point). Should either string be a AnnotatedString the string properties must match too.\n\nExamples\n\njulia> \"abc\" == \"abc\"\ntrue\n\njulia> \"abc\" == \"αβγ\"\nfalse\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.cmp-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.cmp","text":"cmp(a::AbstractString, b::AbstractString) -> Int\n\nCompare two strings. Return 0 if both strings have the same length and the character at each index is the same in both strings. Return -1 if a is a prefix of b, or if a comes before b in alphabetical order. Return 1 if b is a prefix of a, or if b comes before a in alphabetical order (technically, lexicographical order by Unicode code points).\n\nExamples\n\njulia> cmp(\"abc\", \"abc\")\n0\n\njulia> cmp(\"ab\", \"abc\")\n-1\n\njulia> cmp(\"abc\", \"ab\")\n1\n\njulia> cmp(\"ab\", \"ac\")\n-1\n\njulia> cmp(\"ac\", \"ab\")\n1\n\njulia> cmp(\"α\", \"a\")\n1\n\njulia> cmp(\"b\", \"β\")\n-1\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.lpad","page":"Strings","title":"Base.lpad","text":"lpad(s, n::Integer, p::Union{AbstractChar,AbstractString}=' ') -> String\n\nStringify s and pad the resulting string on the left with p to make it n characters (in textwidth) long. If s is already n characters long, an equal string is returned. Pad with spaces by default.\n\nExamples\n\njulia> lpad(\"March\", 10)\n\" March\"\n\ncompat: Julia 1.7\nIn Julia 1.7, this function was changed to use textwidth rather than a raw character (codepoint) count.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.rpad","page":"Strings","title":"Base.rpad","text":"rpad(s, n::Integer, p::Union{AbstractChar,AbstractString}=' ') -> String\n\nStringify s and pad the resulting string on the right with p to make it n characters (in textwidth) long. If s is already n characters long, an equal string is returned. Pad with spaces by default.\n\nExamples\n\njulia> rpad(\"March\", 20)\n\"March \"\n\ncompat: Julia 1.7\nIn Julia 1.7, this function was changed to use textwidth rather than a raw character (codepoint) count.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.findfirst-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.findfirst","text":"findfirst(pattern::AbstractString, string::AbstractString)\nfindfirst(pattern::AbstractPattern, string::String)\n\nFind the first occurrence of pattern in string. Equivalent to findnext(pattern, string, firstindex(s)).\n\nExamples\n\njulia> findfirst(\"z\", \"Hello to the world\") # returns nothing, but not printed in the REPL\n\njulia> findfirst(\"Julia\", \"JuliaLang\")\n1:5\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findnext-Tuple{AbstractString, AbstractString, Integer}","page":"Strings","title":"Base.findnext","text":"findnext(pattern::AbstractString, string::AbstractString, start::Integer)\nfindnext(pattern::AbstractPattern, string::String, start::Integer)\n\nFind the next occurrence of pattern in string starting at position start. pattern can be either a string, or a regular expression, in which case string must be of type String.\n\nThe return value is a range of indices where the matching sequence is found, such that s[findnext(x, s, i)] == x:\n\nfindnext(\"substring\", string, i) == start:stop such that string[start:stop] == \"substring\" and i <= start, or nothing if unmatched.\n\nExamples\n\njulia> findnext(\"z\", \"Hello to the world\", 1) === nothing\ntrue\n\njulia> findnext(\"o\", \"Hello to the world\", 6)\n8:8\n\njulia> findnext(\"Lang\", \"JuliaLang\", 2)\n6:9\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findnext-Tuple{AbstractChar, AbstractString, Integer}","page":"Strings","title":"Base.findnext","text":"findnext(ch::AbstractChar, string::AbstractString, start::Integer)\n\nFind the next occurrence of character ch in string starting at position start.\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\nExamples\n\njulia> findnext('z', \"Hello to the world\", 1) === nothing\ntrue\n\njulia> findnext('o', \"Hello to the world\", 6)\n8\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findlast-Tuple{AbstractString, AbstractString}","page":"Strings","title":"Base.findlast","text":"findlast(pattern::AbstractString, string::AbstractString)\n\nFind the last occurrence of pattern in string. Equivalent to findprev(pattern, string, lastindex(string)).\n\nExamples\n\njulia> findlast(\"o\", \"Hello to the world\")\n15:15\n\njulia> findfirst(\"Julia\", \"JuliaLang\")\n1:5\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findlast-Tuple{AbstractChar, AbstractString}","page":"Strings","title":"Base.findlast","text":"findlast(ch::AbstractChar, string::AbstractString)\n\nFind the last occurrence of character ch in string.\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\nExamples\n\njulia> findlast('p', \"happy\")\n4\n\njulia> findlast('z', \"happy\") === nothing\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.findprev-Tuple{AbstractString, AbstractString, Integer}","page":"Strings","title":"Base.findprev","text":"findprev(pattern::AbstractString, string::AbstractString, start::Integer)\n\nFind the previous occurrence of pattern in string starting at position start.\n\nThe return value is a range of indices where the matching sequence is found, such that s[findprev(x, s, i)] == x:\n\nfindprev(\"substring\", string, i) == start:stop such that string[start:stop] == \"substring\" and stop <= i, or nothing if unmatched.\n\nExamples\n\njulia> findprev(\"z\", \"Hello to the world\", 18) === nothing\ntrue\n\njulia> findprev(\"o\", \"Hello to the world\", 18)\n15:15\n\njulia> findprev(\"Julia\", \"JuliaLang\", 6)\n1:5\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.occursin","page":"Strings","title":"Base.occursin","text":"occursin(needle::Union{AbstractString,AbstractPattern,AbstractChar}, haystack::AbstractString)\n\nDetermine whether the first argument is a substring of the second. If needle is a regular expression, checks whether haystack contains a match.\n\nExamples\n\njulia> occursin(\"Julia\", \"JuliaLang is pretty cool!\")\ntrue\n\njulia> occursin('a', \"JuliaLang is pretty cool!\")\ntrue\n\njulia> occursin(r\"a.a\", \"aba\")\ntrue\n\njulia> occursin(r\"a.a\", \"abba\")\nfalse\n\nSee also contains.\n\n\n\n\n\noccursin(haystack)\n\nCreate a function that checks whether its argument occurs in haystack, i.e. a function equivalent to needle -> occursin(needle, haystack).\n\nThe returned function is of type Base.Fix2{typeof(occursin)}.\n\ncompat: Julia 1.6\nThis method requires Julia 1.6 or later.\n\nExamples\n\njulia> search_f = occursin(\"JuliaLang is a programming language\");\n\njulia> search_f(\"JuliaLang\")\ntrue\n\njulia> search_f(\"Python\")\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.reverse-Tuple{Union{SubString{String}, String}}","page":"Strings","title":"Base.reverse","text":"reverse(s::AbstractString) -> AbstractString\n\nReverses a string. Technically, this function reverses the codepoints in a string and its main utility is for reversed-order string processing, especially for reversed regular-expression searches. See also reverseind to convert indices in s to indices in reverse(s) and vice-versa, and graphemes from module Unicode to operate on user-visible \"characters\" (graphemes) rather than codepoints. See also Iterators.reverse for reverse-order iteration without making a copy. Custom string types must implement the reverse function themselves and should typically return a string with the same type and encoding. If they return a string with a different encoding, they must also override reverseind for that string type to satisfy s[reverseind(s,i)] == reverse(s)[i].\n\nExamples\n\njulia> reverse(\"JuliaLang\")\n\"gnaLailuJ\"\n\nnote: Note\nThe examples below may be rendered differently on different systems. The comments indicate how they're supposed to be rendered\n\nCombining characters can lead to surprising results:\n\njulia> reverse(\"ax̂e\") # hat is above x in the input, above e in the output\n\"êxa\"\n\njulia> using Unicode\n\njulia> join(reverse(collect(graphemes(\"ax̂e\")))) # reverses graphemes; hat is above x in both in- and output\n\"ex̂a\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.replace-Tuple{IO, AbstractString, Vararg{Pair}}","page":"Strings","title":"Base.replace","text":"replace([io::IO], s::AbstractString, pat=>r, [pat2=>r2, ...]; [count::Integer])\n\nSearch for the given pattern pat in s, and replace each occurrence with r. If count is provided, replace at most count occurrences. pat may be a single character, a vector or a set of characters, a string, or a regular expression. If r is a function, each occurrence is replaced with r(s) where s is the matched substring (when pat is a AbstractPattern or AbstractString) or character (when pat is an AbstractChar or a collection of AbstractChar). If pat is a regular expression and r is a SubstitutionString, then capture group references in r are replaced with the corresponding matched text. To remove instances of pat from string, set r to the empty String (\"\").\n\nThe return value is a new string after the replacements. If the io::IO argument is supplied, the transformed string is instead written to io (returning io). (For example, this can be used in conjunction with an IOBuffer to re-use a pre-allocated buffer array in-place.)\n\nMultiple patterns can be specified, and they will be applied left-to-right simultaneously, so only one pattern will be applied to any character, and the patterns will only be applied to the input text, not the replacements.\n\ncompat: Julia 1.7\nSupport for multiple patterns requires version 1.7.\n\ncompat: Julia 1.10\nThe io::IO argument requires version 1.10.\n\nExamples\n\njulia> replace(\"Python is a programming language.\", \"Python\" => \"Julia\")\n\"Julia is a programming language.\"\n\njulia> replace(\"The quick foxes run quickly.\", \"quick\" => \"slow\", count=1)\n\"The slow foxes run quickly.\"\n\njulia> replace(\"The quick foxes run quickly.\", \"quick\" => \"\", count=1)\n\"The foxes run quickly.\"\n\njulia> replace(\"The quick foxes run quickly.\", r\"fox(es)?\" => s\"bus\\1\")\n\"The quick buses run quickly.\"\n\njulia> replace(\"abcabc\", \"a\" => \"b\", \"b\" => \"c\", r\".+\" => \"a\")\n\"bca\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.eachsplit","page":"Strings","title":"Base.eachsplit","text":"eachsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)\neachsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false)\n\nSplit str on occurrences of the delimiter(s) dlm and return an iterator over the substrings. dlm can be any of the formats allowed by findnext's first argument (i.e. as a string, regular expression or a function), or as a single character or collection of characters.\n\nIf dlm is omitted, it defaults to isspace.\n\nThe optional keyword arguments are:\n\nlimit: the maximum size of the result. limit=0 implies no maximum (default)\nkeepempty: whether empty fields should be kept in the result. Default is false without a dlm argument, true with a dlm argument.\n\nSee also split.\n\ncompat: Julia 1.8\nThe eachsplit function requires at least Julia 1.8.\n\nExamples\n\njulia> a = \"Ma.rch\"\n\"Ma.rch\"\n\njulia> b = eachsplit(a, \".\")\nBase.SplitIterator{String, String}(\"Ma.rch\", \".\", 0, true)\n\njulia> collect(b)\n2-element Vector{SubString{String}}:\n \"Ma\"\n \"rch\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.eachrsplit","page":"Strings","title":"Base.eachrsplit","text":"eachrsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)\neachrsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false)\n\nReturn an iterator over SubStrings of str, produced when splitting on the delimiter(s) dlm, and yielded in reverse order (from right to left). dlm can be any of the formats allowed by findprev's first argument (i.e. a string, a single character or a function), or a collection of characters.\n\nIf dlm is omitted, it defaults to isspace, and keepempty default to false.\n\nThe optional keyword arguments are:\n\nIf limit > 0, the iterator will split at most limit - 1 times before returning the rest of the string unsplit. limit < 1 implies no cap to splits (default).\nkeepempty: whether empty fields should be returned when iterating Default is false without a dlm argument, true with a dlm argument.\n\nNote that unlike split, rsplit and eachsplit, this function iterates the substrings right to left as they occur in the input.\n\nSee also eachsplit, rsplit.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nExamples\n\njulia> a = \"Ma.r.ch\";\n\njulia> collect(eachrsplit(a, \".\")) == [\"ch\", \"r\", \"Ma\"]\ntrue\n\njulia> collect(eachrsplit(a, \".\"; limit=2)) == [\"ch\", \"Ma.r\"]\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.split","page":"Strings","title":"Base.split","text":"split(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true)\nsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false)\n\nSplit str into an array of substrings on occurrences of the delimiter(s) dlm. dlm can be any of the formats allowed by findnext's first argument (i.e. as a string, regular expression or a function), or as a single character or collection of characters.\n\nIf dlm is omitted, it defaults to isspace.\n\nThe optional keyword arguments are:\n\nlimit: the maximum size of the result. limit=0 implies no maximum (default)\nkeepempty: whether empty fields should be kept in the result. Default is false without a dlm argument, true with a dlm argument.\n\nSee also rsplit, eachsplit.\n\nExamples\n\njulia> a = \"Ma.rch\"\n\"Ma.rch\"\n\njulia> split(a, \".\")\n2-element Vector{SubString{String}}:\n \"Ma\"\n \"rch\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.rsplit","page":"Strings","title":"Base.rsplit","text":"rsplit(s::AbstractString; limit::Integer=0, keepempty::Bool=false)\nrsplit(s::AbstractString, chars; limit::Integer=0, keepempty::Bool=true)\n\nSimilar to split, but starting from the end of the string.\n\nExamples\n\njulia> a = \"M.a.r.c.h\"\n\"M.a.r.c.h\"\n\njulia> rsplit(a, \".\")\n5-element Vector{SubString{String}}:\n \"M\"\n \"a\"\n \"r\"\n \"c\"\n \"h\"\n\njulia> rsplit(a, \".\"; limit=1)\n1-element Vector{SubString{String}}:\n \"M.a.r.c.h\"\n\njulia> rsplit(a, \".\"; limit=2)\n2-element Vector{SubString{String}}:\n \"M.a.r.c\"\n \"h\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.strip","page":"Strings","title":"Base.strip","text":"strip([pred=isspace,] str::AbstractString) -> SubString\nstrip(str::AbstractString, chars) -> SubString\n\nRemove leading and trailing characters from str, either those specified by chars or those for which the function pred returns true.\n\nThe default behaviour is to remove leading and trailing whitespace and delimiters: see isspace for precise details.\n\nThe optional chars argument specifies which characters to remove: it can be a single character, vector or set of characters.\n\nSee also lstrip and rstrip.\n\ncompat: Julia 1.2\nThe method which accepts a predicate function requires Julia 1.2 or later.\n\nExamples\n\njulia> strip(\"{3, 5}\\n\", ['{', '}', '\\n'])\n\"3, 5\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.lstrip","page":"Strings","title":"Base.lstrip","text":"lstrip([pred=isspace,] str::AbstractString) -> SubString\nlstrip(str::AbstractString, chars) -> SubString\n\nRemove leading characters from str, either those specified by chars or those for which the function pred returns true.\n\nThe default behaviour is to remove leading whitespace and delimiters: see isspace for precise details.\n\nThe optional chars argument specifies which characters to remove: it can be a single character, or a vector or set of characters.\n\nSee also strip and rstrip.\n\nExamples\n\njulia> a = lpad(\"March\", 20)\n\" March\"\n\njulia> lstrip(a)\n\"March\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.rstrip","page":"Strings","title":"Base.rstrip","text":"rstrip([pred=isspace,] str::AbstractString) -> SubString\nrstrip(str::AbstractString, chars) -> SubString\n\nRemove trailing characters from str, either those specified by chars or those for which the function pred returns true.\n\nThe default behaviour is to remove trailing whitespace and delimiters: see isspace for precise details.\n\nThe optional chars argument specifies which characters to remove: it can be a single character, or a vector or set of characters.\n\nSee also strip and lstrip.\n\nExamples\n\njulia> a = rpad(\"March\", 20)\n\"March \"\n\njulia> rstrip(a)\n\"March\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.startswith","page":"Strings","title":"Base.startswith","text":"startswith(s::AbstractString, prefix::Union{AbstractString,Base.Chars})\n\nReturn true if s starts with prefix, which can be a string, a character, or a tuple/vector/set of characters. If prefix is a tuple/vector/set of characters, test whether the first character of s belongs to that set.\n\nSee also endswith, contains.\n\nExamples\n\njulia> startswith(\"JuliaLang\", \"Julia\")\ntrue\n\n\n\n\n\nstartswith(io::IO, prefix::Union{AbstractString,Base.Chars})\n\nCheck if an IO object starts with a prefix, which can be either a string, a character, or a tuple/vector/set of characters. See also peek.\n\n\n\n\n\nstartswith(prefix)\n\nCreate a function that checks whether its argument starts with prefix, i.e. a function equivalent to y -> startswith(y, prefix).\n\nThe returned function is of type Base.Fix2{typeof(startswith)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.5\nThe single argument startswith(prefix) requires at least Julia 1.5.\n\nExamples\n\njulia> startswith(\"Julia\")(\"JuliaLang\")\ntrue\n\njulia> startswith(\"Julia\")(\"Ends with Julia\")\nfalse\n\n\n\n\n\nstartswith(s::AbstractString, prefix::Regex)\n\nReturn true if s starts with the regex pattern, prefix.\n\nnote: Note\nstartswith does not compile the anchoring into the regular expression, but instead passes the anchoring as match_option to PCRE. If compile time is amortized, occursin(r\"^...\", s) is faster than startswith(s, r\"...\").\n\nSee also occursin and endswith.\n\ncompat: Julia 1.2\nThis method requires at least Julia 1.2.\n\nExamples\n\njulia> startswith(\"JuliaLang\", r\"Julia|Romeo\")\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.endswith","page":"Strings","title":"Base.endswith","text":"endswith(s::AbstractString, suffix::Union{AbstractString,Base.Chars})\n\nReturn true if s ends with suffix, which can be a string, a character, or a tuple/vector/set of characters. If suffix is a tuple/vector/set of characters, test whether the last character of s belongs to that set.\n\nSee also startswith, contains.\n\nExamples\n\njulia> endswith(\"Sunday\", \"day\")\ntrue\n\n\n\n\n\nendswith(suffix)\n\nCreate a function that checks whether its argument ends with suffix, i.e. a function equivalent to y -> endswith(y, suffix).\n\nThe returned function is of type Base.Fix2{typeof(endswith)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.5\nThe single argument endswith(suffix) requires at least Julia 1.5.\n\nExamples\n\njulia> endswith(\"Julia\")(\"Ends with Julia\")\ntrue\n\njulia> endswith(\"Julia\")(\"JuliaLang\")\nfalse\n\n\n\n\n\nendswith(s::AbstractString, suffix::Regex)\n\nReturn true if s ends with the regex pattern, suffix.\n\nnote: Note\nendswith does not compile the anchoring into the regular expression, but instead passes the anchoring as match_option to PCRE. If compile time is amortized, occursin(r\"...$\", s) is faster than endswith(s, r\"...\").\n\nSee also occursin and startswith.\n\ncompat: Julia 1.2\nThis method requires at least Julia 1.2.\n\nExamples\n\njulia> endswith(\"JuliaLang\", r\"Lang|Roberts\")\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.contains","page":"Strings","title":"Base.contains","text":"contains(haystack::AbstractString, needle)\n\nReturn true if haystack contains needle. This is the same as occursin(needle, haystack), but is provided for consistency with startswith(haystack, needle) and endswith(haystack, needle).\n\nSee also occursin, in, issubset.\n\nExamples\n\njulia> contains(\"JuliaLang is pretty cool!\", \"Julia\")\ntrue\n\njulia> contains(\"JuliaLang is pretty cool!\", 'a')\ntrue\n\njulia> contains(\"aba\", r\"a.a\")\ntrue\n\njulia> contains(\"abba\", r\"a.a\")\nfalse\n\ncompat: Julia 1.5\nThe contains function requires at least Julia 1.5.\n\n\n\n\n\ncontains(needle)\n\nCreate a function that checks whether its argument contains needle, i.e. a function equivalent to haystack -> contains(haystack, needle).\n\nThe returned function is of type Base.Fix2{typeof(contains)}, which can be used to implement specialized methods.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.first-Tuple{AbstractString, Integer}","page":"Strings","title":"Base.first","text":"first(s::AbstractString, n::Integer)\n\nGet a string consisting of the first n characters of s.\n\nExamples\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 0)\n\"\"\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 1)\n\"∀\"\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 3)\n\"∀ϵ≠\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.last-Tuple{AbstractString, Integer}","page":"Strings","title":"Base.last","text":"last(s::AbstractString, n::Integer)\n\nGet a string consisting of the last n characters of s.\n\nExamples\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 0)\n\"\"\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 1)\n\"0\"\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 3)\n\"²>0\"\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.Unicode.uppercase","page":"Strings","title":"Base.Unicode.uppercase","text":"uppercase(c::AbstractChar)\n\nConvert c to uppercase.\n\nSee also lowercase, titlecase.\n\nExamples\n\njulia> uppercase('a')\n'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)\n\njulia> uppercase('ê')\n'Ê': Unicode U+00CA (category Lu: Letter, uppercase)\n\n\n\n\n\nuppercase(s::AbstractString)\n\nReturn s with all characters converted to uppercase.\n\nSee also lowercase, titlecase, uppercasefirst.\n\nExamples\n\njulia> uppercase(\"Julia\")\n\"JULIA\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.lowercase","page":"Strings","title":"Base.Unicode.lowercase","text":"lowercase(c::AbstractChar)\n\nConvert c to lowercase.\n\nSee also uppercase, titlecase.\n\nExamples\n\njulia> lowercase('A')\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> lowercase('Ö')\n'ö': Unicode U+00F6 (category Ll: Letter, lowercase)\n\n\n\n\n\nlowercase(s::AbstractString)\n\nReturn s with all characters converted to lowercase.\n\nSee also uppercase, titlecase, lowercasefirst.\n\nExamples\n\njulia> lowercase(\"STRINGS AND THINGS\")\n\"strings and things\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.titlecase","page":"Strings","title":"Base.Unicode.titlecase","text":"titlecase(c::AbstractChar)\n\nConvert c to titlecase. This may differ from uppercase for digraphs, compare the example below.\n\nSee also uppercase, lowercase.\n\nExamples\n\njulia> titlecase('a')\n'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)\n\njulia> titlecase('dž')\n'Dž': Unicode U+01C5 (category Lt: Letter, titlecase)\n\njulia> uppercase('dž')\n'DŽ': Unicode U+01C4 (category Lu: Letter, uppercase)\n\n\n\n\n\ntitlecase(s::AbstractString; [wordsep::Function], strict::Bool=true) -> String\n\nCapitalize the first character of each word in s; if strict is true, every other character is converted to lowercase, otherwise they are left unchanged. By default, all non-letters beginning a new grapheme are considered as word separators; a predicate can be passed as the wordsep keyword to determine which characters should be considered as word separators. See also uppercasefirst to capitalize only the first character in s.\n\nSee also uppercase, lowercase, uppercasefirst.\n\nExamples\n\njulia> titlecase(\"the JULIA programming language\")\n\"The Julia Programming Language\"\n\njulia> titlecase(\"ISS - international space station\", strict=false)\n\"ISS - International Space Station\"\n\njulia> titlecase(\"a-a b-b\", wordsep = c->c==' ')\n\"A-a B-b\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.uppercasefirst","page":"Strings","title":"Base.Unicode.uppercasefirst","text":"uppercasefirst(s::AbstractString) -> String\n\nReturn s with the first character converted to uppercase (technically \"title case\" for Unicode). See also titlecase to capitalize the first character of every word in s.\n\nSee also lowercasefirst, uppercase, lowercase, titlecase.\n\nExamples\n\njulia> uppercasefirst(\"python\")\n\"Python\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.lowercasefirst","page":"Strings","title":"Base.Unicode.lowercasefirst","text":"lowercasefirst(s::AbstractString)\n\nReturn s with the first character converted to lowercase.\n\nSee also uppercasefirst, uppercase, lowercase, titlecase.\n\nExamples\n\njulia> lowercasefirst(\"Julia\")\n\"julia\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.join","page":"Strings","title":"Base.join","text":"join([io::IO,] iterator [, delim [, last]])\n\nJoin any iterator into a single string, inserting the given delimiter (if any) between adjacent items. If last is given, it will be used instead of delim between the last two items. Each item of iterator is converted to a string via print(io::IOBuffer, x). If io is given, the result is written to io rather than returned as a String.\n\nExamples\n\njulia> join([\"apples\", \"bananas\", \"pineapples\"], \", \", \" and \")\n\"apples, bananas and pineapples\"\n\njulia> join([1,2,3,4,5])\n\"12345\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.chop","page":"Strings","title":"Base.chop","text":"chop(s::AbstractString; head::Integer = 0, tail::Integer = 1)\n\nRemove the first head and the last tail characters from s. The call chop(s) removes the last character from s. If it is requested to remove more characters than length(s) then an empty string is returned.\n\nSee also chomp, startswith, first.\n\nExamples\n\njulia> a = \"March\"\n\"March\"\n\njulia> chop(a)\n\"Marc\"\n\njulia> chop(a, head = 1, tail = 2)\n\"ar\"\n\njulia> chop(a, head = 5, tail = 5)\n\"\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.chopprefix","page":"Strings","title":"Base.chopprefix","text":"chopprefix(s::AbstractString, prefix::Union{AbstractString,Regex}) -> SubString\n\nRemove the prefix prefix from s. If s does not start with prefix, a string equal to s is returned.\n\nSee also chopsuffix.\n\ncompat: Julia 1.8\nThis function is available as of Julia 1.8.\n\nExamples\n\njulia> chopprefix(\"Hamburger\", \"Ham\")\n\"burger\"\n\njulia> chopprefix(\"Hamburger\", \"hotdog\")\n\"Hamburger\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.chopsuffix","page":"Strings","title":"Base.chopsuffix","text":"chopsuffix(s::AbstractString, suffix::Union{AbstractString,Regex}) -> SubString\n\nRemove the suffix suffix from s. If s does not end with suffix, a string equal to s is returned.\n\nSee also chopprefix.\n\ncompat: Julia 1.8\nThis function is available as of Julia 1.8.\n\nExamples\n\njulia> chopsuffix(\"Hamburger\", \"er\")\n\"Hamburg\"\n\njulia> chopsuffix(\"Hamburger\", \"hotdog\")\n\"Hamburger\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.chomp","page":"Strings","title":"Base.chomp","text":"chomp(s::AbstractString) -> SubString\n\nRemove a single trailing newline from a string.\n\nSee also chop.\n\nExamples\n\njulia> chomp(\"Hello\\n\")\n\"Hello\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.thisind","page":"Strings","title":"Base.thisind","text":"thisind(s::AbstractString, i::Integer) -> Int\n\nIf i is in bounds in s return the index of the start of the character whose encoding code unit i is part of. In other words, if i is the start of a character, return i; if i is not the start of a character, rewind until the start of a character and return that index. If i is equal to 0 or ncodeunits(s)+1 return i. In all other cases throw BoundsError.\n\nExamples\n\njulia> thisind(\"α\", 0)\n0\n\njulia> thisind(\"α\", 1)\n1\n\njulia> thisind(\"α\", 2)\n1\n\njulia> thisind(\"α\", 3)\n3\n\njulia> thisind(\"α\", 4)\nERROR: BoundsError: attempt to access 2-codeunit String at index [4]\n[...]\n\njulia> thisind(\"α\", -1)\nERROR: BoundsError: attempt to access 2-codeunit String at index [-1]\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.nextind-Tuple{AbstractString, Integer, Integer}","page":"Strings","title":"Base.nextind","text":"nextind(str::AbstractString, i::Integer, n::Integer=1) -> Int\n\nCase n == 1\nIf i is in bounds in s return the index of the start of the character whose encoding starts after index i. In other words, if i is the start of a character, return the start of the next character; if i is not the start of a character, move forward until the start of a character and return that index. If i is equal to 0 return 1. If i is in bounds but greater or equal to lastindex(str) return ncodeunits(str)+1. Otherwise throw BoundsError.\nCase n > 1\nBehaves like applying n times nextind for n==1. The only difference is that if n is so large that applying nextind would reach ncodeunits(str)+1 then each remaining iteration increases the returned value by 1. This means that in this case nextind can return a value greater than ncodeunits(str)+1.\nCase n == 0\nReturn i only if i is a valid index in s or is equal to 0. Otherwise StringIndexError or BoundsError is thrown.\n\nExamples\n\njulia> nextind(\"α\", 0)\n1\n\njulia> nextind(\"α\", 1)\n3\n\njulia> nextind(\"α\", 3)\nERROR: BoundsError: attempt to access 2-codeunit String at index [3]\n[...]\n\njulia> nextind(\"α\", 0, 2)\n3\n\njulia> nextind(\"α\", 1, 2)\n4\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.prevind-Tuple{AbstractString, Integer, Integer}","page":"Strings","title":"Base.prevind","text":"prevind(str::AbstractString, i::Integer, n::Integer=1) -> Int\n\nCase n == 1\nIf i is in bounds in s return the index of the start of the character whose encoding starts before index i. In other words, if i is the start of a character, return the start of the previous character; if i is not the start of a character, rewind until the start of a character and return that index. If i is equal to 1 return 0. If i is equal to ncodeunits(str)+1 return lastindex(str). Otherwise throw BoundsError.\nCase n > 1\nBehaves like applying n times prevind for n==1. The only difference is that if n is so large that applying prevind would reach 0 then each remaining iteration decreases the returned value by 1. This means that in this case prevind can return a negative value.\nCase n == 0\nReturn i only if i is a valid index in str or is equal to ncodeunits(str)+1. Otherwise StringIndexError or BoundsError is thrown.\n\nExamples\n\njulia> prevind(\"α\", 3)\n1\n\njulia> prevind(\"α\", 1)\n0\n\njulia> prevind(\"α\", 0)\nERROR: BoundsError: attempt to access 2-codeunit String at index [0]\n[...]\n\njulia> prevind(\"α\", 2, 2)\n0\n\njulia> prevind(\"α\", 2, 3)\n-1\n\n\n\n\n\n","category":"method"},{"location":"base/strings/#Base.Unicode.textwidth","page":"Strings","title":"Base.Unicode.textwidth","text":"textwidth(c)\n\nGive the number of columns needed to print a character.\n\nExamples\n\njulia> textwidth('α')\n1\n\njulia> textwidth('⛵')\n2\n\n\n\n\n\ntextwidth(s::AbstractString)\n\nGive the number of columns needed to print a string.\n\nExamples\n\njulia> textwidth(\"March\")\n5\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.isascii","page":"Strings","title":"Base.isascii","text":"isascii(c::Union{AbstractChar,AbstractString}) -> Bool\n\nTest whether a character belongs to the ASCII character set, or whether this is true for all elements of a string.\n\nExamples\n\njulia> isascii('a')\ntrue\n\njulia> isascii('α')\nfalse\n\njulia> isascii(\"abc\")\ntrue\n\njulia> isascii(\"αβγ\")\nfalse\n\nFor example, isascii can be used as a predicate function for filter or replace to remove or replace non-ASCII characters, respectively:\n\njulia> filter(isascii, \"abcdeγfgh\") # discard non-ASCII chars\n\"abcdefgh\"\n\njulia> replace(\"abcdeγfgh\", !isascii=>' ') # replace non-ASCII chars with spaces\n\"abcde fgh\"\n\n\n\n\n\nisascii(cu::AbstractVector{CU}) where {CU <: Integer} -> Bool\n\nTest whether all values in the vector belong to the ASCII character set (0x00 to 0x7f). This function is intended to be used by other string implementations that need a fast ASCII check.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.iscntrl","page":"Strings","title":"Base.Unicode.iscntrl","text":"iscntrl(c::AbstractChar) -> Bool\n\nTests whether a character is a control character. Control characters are the non-printing characters of the Latin-1 subset of Unicode.\n\nExamples\n\njulia> iscntrl('\\x01')\ntrue\n\njulia> iscntrl('a')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isdigit","page":"Strings","title":"Base.Unicode.isdigit","text":"isdigit(c::AbstractChar) -> Bool\n\nTests whether a character is a decimal digit (0-9).\n\nSee also: isletter.\n\nExamples\n\njulia> isdigit('❤')\nfalse\n\njulia> isdigit('9')\ntrue\n\njulia> isdigit('α')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isletter","page":"Strings","title":"Base.Unicode.isletter","text":"isletter(c::AbstractChar) -> Bool\n\nTest whether a character is a letter. A character is classified as a letter if it belongs to the Unicode general category Letter, i.e. a character whose category code begins with 'L'.\n\nSee also: isdigit.\n\nExamples\n\njulia> isletter('❤')\nfalse\n\njulia> isletter('α')\ntrue\n\njulia> isletter('9')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.islowercase","page":"Strings","title":"Base.Unicode.islowercase","text":"islowercase(c::AbstractChar) -> Bool\n\nTests whether a character is a lowercase letter (according to the Unicode standard's Lowercase derived property).\n\nSee also isuppercase.\n\nExamples\n\njulia> islowercase('α')\ntrue\n\njulia> islowercase('Γ')\nfalse\n\njulia> islowercase('❤')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isnumeric","page":"Strings","title":"Base.Unicode.isnumeric","text":"isnumeric(c::AbstractChar) -> Bool\n\nTests whether a character is numeric. A character is classified as numeric if it belongs to the Unicode general category Number, i.e. a character whose category code begins with 'N'.\n\nNote that this broad category includes characters such as ¾ and ௰. Use isdigit to check whether a character is a decimal digit between 0 and 9.\n\nExamples\n\njulia> isnumeric('௰')\ntrue\n\njulia> isnumeric('9')\ntrue\n\njulia> isnumeric('α')\nfalse\n\njulia> isnumeric('❤')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isprint","page":"Strings","title":"Base.Unicode.isprint","text":"isprint(c::AbstractChar) -> Bool\n\nTests whether a character is printable, including spaces, but not a control character.\n\nExamples\n\njulia> isprint('\\x01')\nfalse\n\njulia> isprint('A')\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.ispunct","page":"Strings","title":"Base.Unicode.ispunct","text":"ispunct(c::AbstractChar) -> Bool\n\nTests whether a character belongs to the Unicode general category Punctuation, i.e. a character whose category code begins with 'P'.\n\nExamples\n\njulia> ispunct('α')\nfalse\n\njulia> ispunct('/')\ntrue\n\njulia> ispunct(';')\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isspace","page":"Strings","title":"Base.Unicode.isspace","text":"isspace(c::AbstractChar) -> Bool\n\nTests whether a character is any whitespace character. Includes ASCII characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' ', Latin-1 character U+0085, and characters in Unicode category Zs.\n\nExamples\n\njulia> isspace('\\n')\ntrue\n\njulia> isspace('\\r')\ntrue\n\njulia> isspace(' ')\ntrue\n\njulia> isspace('\\x20')\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isuppercase","page":"Strings","title":"Base.Unicode.isuppercase","text":"isuppercase(c::AbstractChar) -> Bool\n\nTests whether a character is an uppercase letter (according to the Unicode standard's Uppercase derived property).\n\nSee also islowercase.\n\nExamples\n\njulia> isuppercase('γ')\nfalse\n\njulia> isuppercase('Γ')\ntrue\n\njulia> isuppercase('❤')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.Unicode.isxdigit","page":"Strings","title":"Base.Unicode.isxdigit","text":"isxdigit(c::AbstractChar) -> Bool\n\nTest whether a character is a valid hexadecimal digit. Note that this does not include x (as in the standard 0x prefix).\n\nExamples\n\njulia> isxdigit('a')\ntrue\n\njulia> isxdigit('x')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.escape_string","page":"Strings","title":"Base.escape_string","text":"escape_string(str::AbstractString[, esc]; keep = ())::AbstractString\nescape_string(io, str::AbstractString[, esc]; keep = ())::Nothing\n\nGeneral escaping of traditional C and Unicode escape sequences. The first form returns the escaped string, the second prints the result to io.\n\nBackslashes (\\) are escaped with a double-backslash (\"\\\\\"). Non-printable characters are escaped either with their standard C escape codes, \"\\0\" for NUL (if unambiguous), unicode code point (\"\\u\" prefix) or hex (\"\\x\" prefix).\n\nThe optional esc argument specifies any additional characters that should also be escaped by a prepending backslash (\" is also escaped by default in the first form).\n\nThe argument keep specifies a collection of characters which are to be kept as they are. Notice that esc has precedence here.\n\nSee also unescape_string for the reverse operation.\n\ncompat: Julia 1.7\nThe keep argument is available as of Julia 1.7.\n\nExamples\n\njulia> escape_string(\"aaa\\nbbb\")\n\"aaa\\\\nbbb\"\n\njulia> escape_string(\"aaa\\nbbb\"; keep = '\\n')\n\"aaa\\nbbb\"\n\njulia> escape_string(\"\\xfe\\xff\") # invalid utf-8\n\"\\\\xfe\\\\xff\"\n\njulia> escape_string(string('\\u2135','\\0')) # unambiguous\n\"ℵ\\\\0\"\n\njulia> escape_string(string('\\u2135','\\0','0')) # \\0 would be ambiguous\n\"ℵ\\\\x000\"\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.escape_raw_string","page":"Strings","title":"Base.escape_raw_string","text":"escape_raw_string(s::AbstractString, delim='\"') -> AbstractString\nescape_raw_string(io, s::AbstractString, delim='\"')\n\nEscape a string in the manner used for parsing raw string literals. For each double-quote (\") character in input string s (or delim if specified), this function counts the number n of preceding backslash (\\) characters, and then increases there the number of backslashes from n to 2n+1 (even for n = 0). It also doubles a sequence of backslashes at the end of the string.\n\nThis escaping convention is used in raw strings and other non-standard string literals. (It also happens to be the escaping convention expected by the Microsoft C/C++ compiler runtime when it parses a command-line string into the argv[] array.)\n\nSee also escape_string.\n\n\n\n\n\n","category":"function"},{"location":"base/strings/#Base.unescape_string","page":"Strings","title":"Base.unescape_string","text":"unescape_string(str::AbstractString, keep = ())::AbstractString\nunescape_string(io, s::AbstractString, keep = ())::Nothing\n\nGeneral unescaping of traditional C and Unicode escape sequences. The first form returns the escaped string, the second prints the result to io. The argument keep specifies a collection of characters which (along with backlashes) are to be kept as they are.\n\nThe following escape sequences are recognised:\n\nEscaped backslash (\\\\)\nEscaped double-quote (\\\")\nStandard C escape sequences (\\a, \\b, \\t, \\n, \\v, \\f, \\r, \\e)\nUnicode BMP code points (\\u with 1-4 trailing hex digits)\nAll Unicode code points (\\U with 1-8 trailing hex digits; max value = 0010ffff)\nHex bytes (\\x with 1-2 trailing hex digits)\nOctal bytes (\\ with 1-3 trailing octal digits)\n\nSee also escape_string.\n\nExamples\n\njulia> unescape_string(\"aaa\\\\nbbb\") # C escape sequence\n\"aaa\\nbbb\"\n\njulia> unescape_string(\"\\\\u03c0\") # unicode\n\"π\"\n\njulia> unescape_string(\"\\\\101\") # octal\n\"A\"\n\njulia> unescape_string(\"aaa \\\\g \\\\n\", ['g']) # using `keep` argument\n\"aaa \\\\g \\n\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/","page":"Dynamic Linker","title":"Dynamic Linker","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Libdl/docs/src/index.md\"","category":"page"},{"location":"stdlib/Libdl/","page":"Dynamic Linker","title":"Dynamic Linker","text":"Libdl","category":"page"},{"location":"stdlib/Libdl/#Libdl","page":"Dynamic Linker","title":"Libdl","text":"The Libdl module in Julia provides specialized and lower-level facilities for dynamic linking with shared libraries. While Julia inherently supports linking to runtime shared libraries through the ccall intrinsic, Libdl extends this capability by offering additional, more granular control. It enables users to search for shared libraries both in memory and the filesystem, manually load them with specific runtime linker options, and look up library symbols as low-level pointers.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Libdl/#Dynamic-Linker","page":"Dynamic Linker","title":"Dynamic Linker","text":"","category":"section"},{"location":"stdlib/Libdl/","page":"Dynamic Linker","title":"Dynamic Linker","text":"Libdl.dlopen\nLibdl.dlopen_e\nLibdl.RTLD_NOW\nLibdl.dlsym\nLibdl.dlsym_e\nLibdl.dlclose\nLibdl.dlext\nLibdl.dllist\nLibdl.dlpath\nLibdl.find_library\nLibdl.DL_LOAD_PATH","category":"page"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlopen","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlopen","text":"dlopen(libfile::AbstractString [, flags::Integer]; throw_error:Bool = true)\n\nLoad a shared library, returning an opaque handle.\n\nThe extension given by the constant dlext (.so, .dll, or .dylib) can be omitted from the libfile string, as it is automatically appended if needed. If libfile is not an absolute path name, then the paths in the array DL_LOAD_PATH are searched for libfile, followed by the system load path.\n\nThe optional flags argument is a bitwise-or of zero or more of RTLD_LOCAL, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, and RTLD_FIRST. These are converted to the corresponding flags of the POSIX (and/or GNU libc and/or MacOS) dlopen command, if possible, or are ignored if the specified functionality is not available on the current platform. The default flags are platform specific. On MacOS the default dlopen flags are RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL while on other platforms the defaults are RTLD_LAZY|RTLD_DEEPBIND|RTLD_LOCAL. An important usage of these flags is to specify non default behavior for when the dynamic library loader binds library references to exported symbols and if the bound references are put into process local or global scope. For instance RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL allows the library's symbols to be available for usage in other shared libraries, addressing situations where there are dependencies between shared libraries.\n\nIf the library cannot be found, this method throws an error, unless the keyword argument throw_error is set to false, in which case this method returns nothing.\n\nnote: Note\nFrom Julia 1.6 on, this method replaces paths starting with @executable_path/ with the path to the Julia executable, allowing for relocatable relative-path loads. In Julia 1.5 and earlier, this only worked on macOS.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlopen_e","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlopen_e","text":"dlopen_e(libfile::AbstractString [, flags::Integer])\n\nSimilar to dlopen, except returns C_NULL instead of raising errors. This method is now deprecated in favor of dlopen(libfile::AbstractString [, flags::Integer]; throw_error=false).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.RTLD_NOW","page":"Dynamic Linker","title":"Base.Libc.Libdl.RTLD_NOW","text":"RTLD_DEEPBIND\nRTLD_FIRST\nRTLD_GLOBAL\nRTLD_LAZY\nRTLD_LOCAL\nRTLD_NODELETE\nRTLD_NOLOAD\nRTLD_NOW\n\nEnum constant for dlopen. See your platform man page for details, if applicable.\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlsym","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlsym","text":"dlsym(handle, sym; throw_error::Bool = true)\n\nLook up a symbol from a shared library handle, return callable function pointer on success.\n\nIf the symbol cannot be found, this method throws an error, unless the keyword argument throw_error is set to false, in which case this method returns nothing.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlsym_e","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlsym_e","text":"dlsym_e(handle, sym)\n\nLook up a symbol from a shared library handle, silently return C_NULL on lookup failure. This method is now deprecated in favor of dlsym(handle, sym; throw_error=false).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlclose","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlclose","text":"dlclose(handle)\n\nClose shared library referenced by handle.\n\n\n\n\n\ndlclose(::Nothing)\n\nFor the very common pattern usage pattern of\n\ntry\n hdl = dlopen(library_name)\n ... do something\nfinally\n dlclose(hdl)\nend\n\nWe define a dlclose() method that accepts a parameter of type Nothing, so that user code does not have to change its behavior for the case that library_name was not found.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlext","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlext","text":"dlext\n\nFile extension for dynamic libraries (e.g. dll, dylib, so) on the current platform.\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dllist","page":"Dynamic Linker","title":"Base.Libc.Libdl.dllist","text":"dllist()\n\nReturn the paths of dynamic libraries currently loaded in a Vector{String}.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.dlpath","page":"Dynamic Linker","title":"Base.Libc.Libdl.dlpath","text":"dlpath(handle::Ptr{Cvoid})\n\nGiven a library handle from dlopen, return the full path.\n\n\n\n\n\ndlpath(libname::Union{AbstractString, Symbol})\n\nGet the full path of the library libname.\n\nExamples\n\njulia> dlpath(\"libjulia\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.Libc.Libdl.find_library","page":"Dynamic Linker","title":"Base.Libc.Libdl.find_library","text":"find_library(names [, locations])\n\nSearches for the first library in names in the paths in the locations list, DL_LOAD_PATH, or system library paths (in that order) which can successfully be dlopen'd. On success, the return value will be one of the names (potentially prefixed by one of the paths in locations). This string can be assigned to a global const and used as the library name in future ccall's. On failure, it returns the empty string.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Libdl/#Base.DL_LOAD_PATH","page":"Dynamic Linker","title":"Base.DL_LOAD_PATH","text":"DL_LOAD_PATH\n\nWhen calling dlopen, the paths in this list will be searched first, in order, before searching the system locations for a valid library handle.\n\n\n\n\n\n","category":"constant"},{"location":"base/arrays/#lib-arrays","page":"Arrays","title":"Arrays","text":"","category":"section"},{"location":"base/arrays/#Constructors-and-Types","page":"Arrays","title":"Constructors and Types","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Core.AbstractArray\nBase.AbstractVector\nBase.AbstractMatrix\nBase.AbstractVecOrMat\nCore.Array\nCore.Array(::UndefInitializer, ::Any)\nCore.Array(::Nothing, ::Any)\nCore.Array(::Missing, ::Any)\nCore.UndefInitializer\nCore.undef\nBase.Vector\nBase.Vector(::UndefInitializer, ::Any)\nBase.Vector(::Nothing, ::Any)\nBase.Vector(::Missing, ::Any)\nBase.Matrix\nBase.Matrix(::UndefInitializer, ::Any, ::Any)\nBase.Matrix(::Nothing, ::Any, ::Any)\nBase.Matrix(::Missing, ::Any, ::Any)\nBase.VecOrMat\nCore.DenseArray\nBase.DenseVector\nBase.DenseMatrix\nBase.DenseVecOrMat\nBase.StridedArray\nBase.StridedVector\nBase.StridedMatrix\nBase.StridedVecOrMat\nBase.Memory\nBase.MemoryRef\nBase.Slices\nBase.RowSlices\nBase.ColumnSlices\nBase.getindex(::Type, ::Any...)\nBase.zeros\nBase.ones\nBase.BitArray\nBase.BitArray(::UndefInitializer, ::Integer...)\nBase.BitArray(::Any)\nBase.trues\nBase.falses\nBase.fill\nBase.fill!\nBase.empty\nBase.similar","category":"page"},{"location":"base/arrays/#Core.AbstractArray","page":"Arrays","title":"Core.AbstractArray","text":"AbstractArray{T,N}\n\nSupertype for N-dimensional arrays (or array-like types) with elements of type T. Array and other types are subtypes of this. See the manual section on the AbstractArray interface.\n\nSee also: AbstractVector, AbstractMatrix, eltype, ndims.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.AbstractVector","page":"Arrays","title":"Base.AbstractVector","text":"AbstractVector{T}\n\nSupertype for one-dimensional arrays (or array-like types) with elements of type T. Alias for AbstractArray{T,1}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.AbstractMatrix","page":"Arrays","title":"Base.AbstractMatrix","text":"AbstractMatrix{T}\n\nSupertype for two-dimensional arrays (or array-like types) with elements of type T. Alias for AbstractArray{T,2}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.AbstractVecOrMat","page":"Arrays","title":"Base.AbstractVecOrMat","text":"AbstractVecOrMat{T}\n\nUnion type of AbstractVector{T} and AbstractMatrix{T}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.Array","page":"Arrays","title":"Core.Array","text":"Array{T,N} <: AbstractArray{T,N}\n\nN-dimensional dense array with elements of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.Array-Tuple{UndefInitializer, Any}","page":"Arrays","title":"Core.Array","text":"Array{T}(undef, dims)\nArray{T,N}(undef, dims)\n\nConstruct an uninitialized N-dimensional Array containing elements of type T. N can either be supplied explicitly, as in Array{T,N}(undef, dims), or be determined by the length or number of dims. dims may be a tuple or a series of integer arguments corresponding to the lengths in each dimension. If the rank N is supplied explicitly, then it must match the length or number of dims. Here undef is the UndefInitializer.\n\nExamples\n\njulia> A = Array{Float64, 2}(undef, 2, 3) # N given explicitly\n2×3 Matrix{Float64}:\n 6.90198e-310 6.90198e-310 6.90198e-310\n 6.90198e-310 6.90198e-310 0.0\n\njulia> B = Array{Float64}(undef, 4) # N determined by the input\n4-element Vector{Float64}:\n 2.360075077e-314\n NaN\n 2.2671131793e-314\n 2.299821756e-314\n\njulia> similar(B, 2, 4, 1) # use typeof(B), and the given size\n2×4×1 Array{Float64, 3}:\n[:, :, 1] =\n 2.26703e-314 2.26708e-314 0.0 2.80997e-314\n 0.0 2.26703e-314 2.26708e-314 0.0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Core.Array-Tuple{Nothing, Any}","page":"Arrays","title":"Core.Array","text":"Array{T}(nothing, dims)\nArray{T,N}(nothing, dims)\n\nConstruct an N-dimensional Array containing elements of type T, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.\n\nExamples\n\njulia> Array{Union{Nothing, String}}(nothing, 2)\n2-element Vector{Union{Nothing, String}}:\n nothing\n nothing\n\njulia> Array{Union{Nothing, Int}}(nothing, 2, 3)\n2×3 Matrix{Union{Nothing, Int64}}:\n nothing nothing nothing\n nothing nothing nothing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Core.Array-Tuple{Missing, Any}","page":"Arrays","title":"Core.Array","text":"Array{T}(missing, dims)\nArray{T,N}(missing, dims)\n\nConstruct an N-dimensional Array containing elements of type T, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.\n\nExamples\n\njulia> Array{Union{Missing, String}}(missing, 2)\n2-element Vector{Union{Missing, String}}:\n missing\n missing\n\njulia> Array{Union{Missing, Int}}(missing, 2, 3)\n2×3 Matrix{Union{Missing, Int64}}:\n missing missing missing\n missing missing missing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Core.UndefInitializer","page":"Arrays","title":"Core.UndefInitializer","text":"UndefInitializer\n\nSingleton type used in array initialization, indicating the array-constructor-caller would like an uninitialized array. See also undef, an alias for UndefInitializer().\n\nExamples\n\njulia> Array{Float64, 1}(UndefInitializer(), 3)\n3-element Array{Float64, 1}:\n 2.2752528595e-314\n 2.202942107e-314\n 2.275252907e-314\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.undef","page":"Arrays","title":"Core.undef","text":"undef\n\nAlias for UndefInitializer(), which constructs an instance of the singleton type UndefInitializer, used in array initialization to indicate the array-constructor-caller would like an uninitialized array.\n\nSee also: missing, similar.\n\nExamples\n\njulia> Array{Float64, 1}(undef, 3)\n3-element Vector{Float64}:\n 2.2752528595e-314\n 2.202942107e-314\n 2.275252907e-314\n\n\n\n\n\n","category":"constant"},{"location":"base/arrays/#Base.Vector","page":"Arrays","title":"Base.Vector","text":"Vector{T} <: AbstractVector{T}\n\nOne-dimensional dense array with elements of type T, often used to represent a mathematical vector. Alias for Array{T,1}.\n\nSee also empty, similar and zero for creating vectors.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Vector-Tuple{UndefInitializer, Any}","page":"Arrays","title":"Base.Vector","text":"Vector{T}(undef, n)\n\nConstruct an uninitialized Vector{T} of length n.\n\nExamples\n\njulia> Vector{Float64}(undef, 3)\n3-element Array{Float64, 1}:\n 6.90966e-310\n 6.90966e-310\n 6.90966e-310\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Vector-Tuple{Nothing, Any}","page":"Arrays","title":"Base.Vector","text":"Vector{T}(nothing, m)\n\nConstruct a Vector{T} of length m, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.\n\nExamples\n\njulia> Vector{Union{Nothing, String}}(nothing, 2)\n2-element Vector{Union{Nothing, String}}:\n nothing\n nothing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Vector-Tuple{Missing, Any}","page":"Arrays","title":"Base.Vector","text":"Vector{T}(missing, m)\n\nConstruct a Vector{T} of length m, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.\n\nExamples\n\njulia> Vector{Union{Missing, String}}(missing, 2)\n2-element Vector{Union{Missing, String}}:\n missing\n missing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Matrix","page":"Arrays","title":"Base.Matrix","text":"Matrix{T} <: AbstractMatrix{T}\n\nTwo-dimensional dense array with elements of type T, often used to represent a mathematical matrix. Alias for Array{T,2}.\n\nSee also fill, zeros, undef and similar for creating matrices.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Matrix-Tuple{UndefInitializer, Any, Any}","page":"Arrays","title":"Base.Matrix","text":"Matrix{T}(undef, m, n)\n\nConstruct an uninitialized Matrix{T} of size m×n.\n\nExamples\n\njulia> Matrix{Float64}(undef, 2, 3)\n2×3 Array{Float64, 2}:\n 2.36365e-314 2.28473e-314 5.0e-324\n 2.26704e-314 2.26711e-314 NaN\n\njulia> similar(ans, Int32, 2, 2)\n2×2 Matrix{Int32}:\n 490537216 1277177453\n 1 1936748399\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Matrix-Tuple{Nothing, Any, Any}","page":"Arrays","title":"Base.Matrix","text":"Matrix{T}(nothing, m, n)\n\nConstruct a Matrix{T} of size m×n, initialized with nothing entries. Element type T must be able to hold these values, i.e. Nothing <: T.\n\nExamples\n\njulia> Matrix{Union{Nothing, String}}(nothing, 2, 3)\n2×3 Matrix{Union{Nothing, String}}:\n nothing nothing nothing\n nothing nothing nothing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.Matrix-Tuple{Missing, Any, Any}","page":"Arrays","title":"Base.Matrix","text":"Matrix{T}(missing, m, n)\n\nConstruct a Matrix{T} of size m×n, initialized with missing entries. Element type T must be able to hold these values, i.e. Missing <: T.\n\nExamples\n\njulia> Matrix{Union{Missing, String}}(missing, 2, 3)\n2×3 Matrix{Union{Missing, String}}:\n missing missing missing\n missing missing missing\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.VecOrMat","page":"Arrays","title":"Base.VecOrMat","text":"VecOrMat{T}\n\nUnion type of Vector{T} and Matrix{T} which allows functions to accept either a Matrix or a Vector.\n\nExamples\n\njulia> Vector{Float64} <: VecOrMat{Float64}\ntrue\n\njulia> Matrix{Float64} <: VecOrMat{Float64}\ntrue\n\njulia> Array{Float64, 3} <: VecOrMat{Float64}\nfalse\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.DenseArray","page":"Arrays","title":"Core.DenseArray","text":"DenseArray{T, N} <: AbstractArray{T,N}\n\nN-dimensional dense array with elements of type T. The elements of a dense array are stored contiguously in memory.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.DenseVector","page":"Arrays","title":"Base.DenseVector","text":"DenseVector{T}\n\nOne-dimensional DenseArray with elements of type T. Alias for DenseArray{T,1}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.DenseMatrix","page":"Arrays","title":"Base.DenseMatrix","text":"DenseMatrix{T}\n\nTwo-dimensional DenseArray with elements of type T. Alias for DenseArray{T,2}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.DenseVecOrMat","page":"Arrays","title":"Base.DenseVecOrMat","text":"DenseVecOrMat{T}\n\nUnion type of DenseVector{T} and DenseMatrix{T}.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.StridedArray","page":"Arrays","title":"Base.StridedArray","text":"StridedArray{T, N}\n\nA hard-coded Union of common array types that follow the strided array interface, with elements of type T and N dimensions.\n\nIf A is a StridedArray, then its elements are stored in memory with offsets, which may vary between dimensions but are constant within a dimension. For example, A could have stride 2 in dimension 1, and stride 3 in dimension 2. Incrementing A along dimension d jumps in memory by [stride(A, d)] slots. Strided arrays are particularly important and useful because they can sometimes be passed directly as pointers to foreign language libraries like BLAS.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.StridedVector","page":"Arrays","title":"Base.StridedVector","text":"StridedVector{T}\n\nOne dimensional StridedArray with elements of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.StridedMatrix","page":"Arrays","title":"Base.StridedMatrix","text":"StridedMatrix{T}\n\nTwo dimensional StridedArray with elements of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.StridedVecOrMat","page":"Arrays","title":"Base.StridedVecOrMat","text":"StridedVecOrMat{T}\n\nUnion type of StridedVector and StridedMatrix with elements of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.Memory","page":"Arrays","title":"Core.Memory","text":"Memory{T} == GenericMemory{:not_atomic, T, Core.CPU}\n\nOne-dimensional dense array with elements of type T.\n\ncompat: Julia 1.11\nThis type requires Julia 1.11 or later.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Core.MemoryRef","page":"Arrays","title":"Core.MemoryRef","text":"MemoryRef(memory)\n\nConstruct a MemoryRef from a memory object. This does not fail, but the resulting memory may point out-of-bounds if the memory is empty.\n\n\n\n\n\nMemoryRef(::Memory, index::Integer)\nMemoryRef(::MemoryRef, index::Integer)\n\nConstruct a MemoryRef from a memory object and an offset index (1-based) which can also be negative. This always returns an inbounds object, and will throw an error if that is not possible (because the index would result in a shift out-of-bounds of the underlying memory).\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Slices","page":"Arrays","title":"Base.Slices","text":"Slices{P,SM,AX,S,N} <: AbstractSlices{S,N}\n\nAn AbstractArray of slices into a parent array over specified dimension(s), returning views that select all the data from the other dimension(s).\n\nThese should typically be constructed by eachslice, eachcol or eachrow.\n\nparent(s::Slices) will return the parent array.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.RowSlices","page":"Arrays","title":"Base.RowSlices","text":"RowSlices{M,AX,S}\n\nA special case of Slices that is a vector of row slices of a matrix, as constructed by eachrow.\n\nparent can be used to get the underlying matrix.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.ColumnSlices","page":"Arrays","title":"Base.ColumnSlices","text":"ColumnSlices{M,AX,S}\n\nA special case of Slices that is a vector of column slices of a matrix, as constructed by eachcol.\n\nparent can be used to get the underlying matrix.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.getindex-Tuple{Type, Vararg{Any}}","page":"Arrays","title":"Base.getindex","text":"getindex(type[, elements...])\n\nConstruct a 1-d array of the specified type. This is usually called with the syntax Type[]. Element values can be specified using Type[a,b,c,...].\n\nExamples\n\njulia> Int8[1, 2, 3]\n3-element Vector{Int8}:\n 1\n 2\n 3\n\njulia> getindex(Int8, 1, 2, 3)\n3-element Vector{Int8}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.zeros","page":"Arrays","title":"Base.zeros","text":"zeros([T=Float64,] dims::Tuple)\nzeros([T=Float64,] dims...)\n\nCreate an Array, with element type T, of all zeros with size specified by dims. See also fill, ones, zero.\n\nExamples\n\njulia> zeros(1)\n1-element Vector{Float64}:\n 0.0\n\njulia> zeros(Int8, 2, 3)\n2×3 Matrix{Int8}:\n 0 0 0\n 0 0 0\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.ones","page":"Arrays","title":"Base.ones","text":"ones([T=Float64,] dims::Tuple)\nones([T=Float64,] dims...)\n\nCreate an Array, with element type T, of all ones with size specified by dims. See also fill, zeros.\n\nExamples\n\njulia> ones(1,2)\n1×2 Matrix{Float64}:\n 1.0 1.0\n\njulia> ones(ComplexF64, 2, 3)\n2×3 Matrix{ComplexF64}:\n 1.0+0.0im 1.0+0.0im 1.0+0.0im\n 1.0+0.0im 1.0+0.0im 1.0+0.0im\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.BitArray","page":"Arrays","title":"Base.BitArray","text":"BitArray{N} <: AbstractArray{Bool, N}\n\nSpace-efficient N-dimensional boolean array, using just one bit for each boolean value.\n\nBitArrays pack up to 64 values into every 8 bytes, resulting in an 8x space efficiency over Array{Bool, N} and allowing some operations to work on 64 values at once.\n\nBy default, Julia returns BitArrays from broadcasting operations that generate boolean elements (including dotted-comparisons like .==) as well as from the functions trues and falses.\n\nnote: Note\nDue to its packed storage format, concurrent access to the elements of a BitArray where at least one of them is a write is not thread-safe.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.BitArray-Tuple{UndefInitializer, Vararg{Integer}}","page":"Arrays","title":"Base.BitArray","text":"BitArray(undef, dims::Integer...)\nBitArray{N}(undef, dims::NTuple{N,Int})\n\nConstruct an undef BitArray with the given dimensions. Behaves identically to the Array constructor. See undef.\n\nExamples\n\njulia> BitArray(undef, 2, 2)\n2×2 BitMatrix:\n 0 0\n 0 0\n\njulia> BitArray(undef, (3, 1))\n3×1 BitMatrix:\n 0\n 0\n 0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.BitArray-Tuple{Any}","page":"Arrays","title":"Base.BitArray","text":"BitArray(itr)\n\nConstruct a BitArray generated by the given iterable object. The shape is inferred from the itr object.\n\nExamples\n\njulia> BitArray([1 0; 0 1])\n2×2 BitMatrix:\n 1 0\n 0 1\n\njulia> BitArray(x+y == 3 for x = 1:2, y = 1:3)\n2×3 BitMatrix:\n 0 1 0\n 1 0 0\n\njulia> BitArray(x+y == 3 for x = 1:2 for y = 1:3)\n6-element BitVector:\n 0\n 1\n 0\n 1\n 0\n 0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.trues","page":"Arrays","title":"Base.trues","text":"trues(dims)\n\nCreate a BitArray with all values set to true.\n\nExamples\n\njulia> trues(2,3)\n2×3 BitMatrix:\n 1 1 1\n 1 1 1\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.falses","page":"Arrays","title":"Base.falses","text":"falses(dims)\n\nCreate a BitArray with all values set to false.\n\nExamples\n\njulia> falses(2,3)\n2×3 BitMatrix:\n 0 0 0\n 0 0 0\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.fill","page":"Arrays","title":"Base.fill","text":"fill(value, dims::Tuple)\nfill(value, dims...)\n\nCreate an array of size dims with every location set to value.\n\nFor example, fill(1.0, (5,5)) returns a 5×5 array of floats, with 1.0 in every location of the array.\n\nThe dimension lengths dims may be specified as either a tuple or a sequence of arguments. An N-length tuple or N arguments following the value specify an N-dimensional array. Thus, a common idiom for creating a zero-dimensional array with its only location set to x is fill(x).\n\nEvery location of the returned array is set to (and is thus === to) the value that was passed; this means that if the value is itself modified, all elements of the filled array will reflect that modification because they're still that very value. This is of no concern with fill(1.0, (5,5)) as the value 1.0 is immutable and cannot itself be modified, but can be unexpected with mutable values like — most commonly — arrays. For example, fill([], 3) places the very same empty array in all three locations of the returned vector:\n\njulia> v = fill([], 3)\n3-element Vector{Vector{Any}}:\n []\n []\n []\n\njulia> v[1] === v[2] === v[3]\ntrue\n\njulia> value = v[1]\nAny[]\n\njulia> push!(value, 867_5309)\n1-element Vector{Any}:\n 8675309\n\njulia> v\n3-element Vector{Vector{Any}}:\n [8675309]\n [8675309]\n [8675309]\n\nTo create an array of many independent inner arrays, use a comprehension instead. This creates a new and distinct array on each iteration of the loop:\n\njulia> v2 = [[] for _ in 1:3]\n3-element Vector{Vector{Any}}:\n []\n []\n []\n\njulia> v2[1] === v2[2] === v2[3]\nfalse\n\njulia> push!(v2[1], 8675309)\n1-element Vector{Any}:\n 8675309\n\njulia> v2\n3-element Vector{Vector{Any}}:\n [8675309]\n []\n []\n\nSee also: fill!, zeros, ones, similar.\n\nExamples\n\njulia> fill(1.0, (2,3))\n2×3 Matrix{Float64}:\n 1.0 1.0 1.0\n 1.0 1.0 1.0\n\njulia> fill(42)\n0-dimensional Array{Int64, 0}:\n42\n\njulia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector\n2-element Vector{Vector{Float64}}:\n [0.0, 0.0]\n [0.0, 0.0]\n\njulia> A[1][1] = 42; # modifies the filled value to be [42.0, 0.0]\n\njulia> A # both A[1] and A[2] are the very same vector\n2-element Vector{Vector{Float64}}:\n [42.0, 0.0]\n [42.0, 0.0]\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.fill!","page":"Arrays","title":"Base.fill!","text":"fill!(A, x)\n\nFill array A with the value x. If x is an object reference, all elements will refer to the same object. fill!(A, Foo()) will return A filled with the result of evaluating Foo() once.\n\nExamples\n\njulia> A = zeros(2,3)\n2×3 Matrix{Float64}:\n 0.0 0.0 0.0\n 0.0 0.0 0.0\n\njulia> fill!(A, 2.)\n2×3 Matrix{Float64}:\n 2.0 2.0 2.0\n 2.0 2.0 2.0\n\njulia> a = [1, 1, 1]; A = fill!(Vector{Vector{Int}}(undef, 3), a); a[1] = 2; A\n3-element Vector{Vector{Int64}}:\n [2, 1, 1]\n [2, 1, 1]\n [2, 1, 1]\n\njulia> x = 0; f() = (global x += 1; x); fill!(Vector{Int}(undef, 3), f())\n3-element Vector{Int64}:\n 1\n 1\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.empty","page":"Arrays","title":"Base.empty","text":"empty(x::Tuple)\n\nReturn an empty tuple, ().\n\n\n\n\n\nempty(v::AbstractVector, [eltype])\n\nCreate an empty vector similar to v, optionally changing the eltype.\n\nSee also: empty!, isempty, isassigned.\n\nExamples\n\njulia> empty([1.0, 2.0, 3.0])\nFloat64[]\n\njulia> empty([1.0, 2.0, 3.0], String)\nString[]\n\n\n\n\n\nempty(a::AbstractDict, [index_type=keytype(a)], [value_type=valtype(a)])\n\nCreate an empty AbstractDict container which can accept indices of type index_type and values of type value_type. The second and third arguments are optional and default to the input's keytype and valtype, respectively. (If only one of the two types is specified, it is assumed to be the value_type, and the index_type we default to keytype(a)).\n\nCustom AbstractDict subtypes may choose which specific dictionary type is best suited to return for the given index and value types, by specializing on the three-argument signature. The default is to return an empty Dict.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.similar","page":"Arrays","title":"Base.similar","text":"similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}\n\nCreate an uninitialized mutable array with the given element type, index type, and size, based upon the given source SparseMatrixCSC. The new sparse matrix maintains the structure of the original sparse matrix, except in the case where dimensions of the output matrix are different from the output.\n\nThe output matrix has zeros in the same locations as the input, but uninitialized values for the nonzero locations.\n\n\n\n\n\nsimilar(array, [element_type=eltype(array)], [dims=size(array)])\n\nCreate an uninitialized mutable array with the given element type and size, based upon the given source array. The second and third arguments are both optional, defaulting to the given array's eltype and size. The dimensions may be specified either as a single tuple argument or as a series of integer arguments.\n\nCustom AbstractArray subtypes may choose which specific array type is best-suited to return for the given element type and dimensionality. If they do not specialize this method, the default is an Array{element_type}(undef, dims...).\n\nFor example, similar(1:10, 1, 4) returns an uninitialized Array{Int,2} since ranges are neither mutable nor support 2 dimensions:\n\njulia> similar(1:10, 1, 4)\n1×4 Matrix{Int64}:\n 4419743872 4374413872 4419743888 0\n\nConversely, similar(trues(10,10), 2) returns an uninitialized BitVector with two elements since BitArrays are both mutable and can support 1-dimensional arrays:\n\njulia> similar(trues(10,10), 2)\n2-element BitVector:\n 0\n 0\n\nSince BitArrays can only store elements of type Bool, however, if you request a different element type it will create a regular Array instead:\n\njulia> similar(falses(10), Float64, 2, 4)\n2×4 Matrix{Float64}:\n 2.18425e-314 2.18425e-314 2.18425e-314 2.18425e-314\n 2.18425e-314 2.18425e-314 2.18425e-314 2.18425e-314\n\nSee also: undef, isassigned.\n\n\n\n\n\nsimilar(storagetype, axes)\n\nCreate an uninitialized mutable array analogous to that specified by storagetype, but with axes specified by the last argument.\n\nExamples:\n\nsimilar(Array{Int}, axes(A))\n\ncreates an array that \"acts like\" an Array{Int} (and might indeed be backed by one), but which is indexed identically to A. If A has conventional indexing, this will be identical to Array{Int}(undef, size(A)), but if A has unconventional indexing then the indices of the result will match A.\n\nsimilar(BitArray, (axes(A, 2),))\n\nwould create a 1-dimensional logical array whose indices match those of the columns of A.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Basic-functions","page":"Arrays","title":"Basic functions","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.ndims\nBase.size\nBase.axes(::Any)\nBase.axes(::AbstractArray, ::Any)\nBase.length(::AbstractArray)\nBase.keys(::AbstractArray)\nBase.eachindex\nBase.IndexStyle\nBase.IndexLinear\nBase.IndexCartesian\nBase.conj!\nBase.stride\nBase.strides","category":"page"},{"location":"base/arrays/#Base.ndims","page":"Arrays","title":"Base.ndims","text":"ndims(A::AbstractArray) -> Integer\n\nReturn the number of dimensions of A.\n\nSee also: size, axes.\n\nExamples\n\njulia> A = fill(1, (3,4,5));\n\njulia> ndims(A)\n3\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.size","page":"Arrays","title":"Base.size","text":"size(A::AbstractArray, [dim])\n\nReturn a tuple containing the dimensions of A. Optionally you can specify a dimension to just get the length of that dimension.\n\nNote that size may not be defined for arrays with non-standard indices, in which case axes may be useful. See the manual chapter on arrays with custom indices.\n\nSee also: length, ndims, eachindex, sizeof.\n\nExamples\n\njulia> A = fill(1, (2,3,4));\n\njulia> size(A)\n(2, 3, 4)\n\njulia> size(A, 2)\n3\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.axes-Tuple{Any}","page":"Arrays","title":"Base.axes","text":"axes(A)\n\nReturn the tuple of valid indices for array A.\n\nSee also: size, keys, eachindex.\n\nExamples\n\njulia> A = fill(1, (5,6,7));\n\njulia> axes(A)\n(Base.OneTo(5), Base.OneTo(6), Base.OneTo(7))\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.axes-Tuple{AbstractArray, Any}","page":"Arrays","title":"Base.axes","text":"axes(A, d)\n\nReturn the valid range of indices for array A along dimension d.\n\nSee also size, and the manual chapter on arrays with custom indices.\n\nExamples\n\njulia> A = fill(1, (5,6,7));\n\njulia> axes(A, 2)\nBase.OneTo(6)\n\njulia> axes(A, 4) == 1:1 # all dimensions d > ndims(A) have size 1\ntrue\n\nUsage note\n\nEach of the indices has to be an AbstractUnitRange{<:Integer}, but at the same time can be a type that uses custom indices. So, for example, if you need a subset, use generalized indexing constructs like begin/end or firstindex/lastindex:\n\nix = axes(v, 1)\nix[2:end] # will work for eg Vector, but may fail in general\nix[(begin+1):end] # works for generalized indexes\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.length-Tuple{AbstractArray}","page":"Arrays","title":"Base.length","text":"length(A::AbstractArray)\n\nReturn the number of elements in the array, defaults to prod(size(A)).\n\nExamples\n\njulia> length([1, 2, 3, 4])\n4\n\njulia> length([1 2; 3 4])\n4\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.keys-Tuple{AbstractArray}","page":"Arrays","title":"Base.keys","text":"keys(a::AbstractArray)\n\nReturn an efficient array describing all valid indices for a arranged in the shape of a itself.\n\nThe keys of 1-dimensional arrays (vectors) are integers, whereas all other N-dimensional arrays use CartesianIndex to describe their locations. Often the special array types LinearIndices and CartesianIndices are used to efficiently represent these arrays of integers and CartesianIndexes, respectively.\n\nNote that the keys of an array might not be the most efficient index type; for maximum performance use eachindex instead.\n\nExamples\n\njulia> keys([4, 5, 6])\n3-element LinearIndices{1, Tuple{Base.OneTo{Int64}}}:\n 1\n 2\n 3\n\njulia> keys([4 5; 6 7])\nCartesianIndices((2, 2))\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.eachindex","page":"Arrays","title":"Base.eachindex","text":"eachindex(A...)\neachindex(::IndexStyle, A::AbstractArray...)\n\nCreate an iterable object for visiting each index of an AbstractArray A in an efficient manner. For array types that have opted into fast linear indexing (like Array), this is simply the range 1:length(A) if they use 1-based indexing. For array types that have not opted into fast linear indexing, a specialized Cartesian range is typically returned to efficiently index into the array with indices specified for every dimension.\n\nIn general eachindex accepts arbitrary iterables, including strings and dictionaries, and returns an iterator object supporting arbitrary index types (e.g. unevenly spaced or non-integer indices).\n\nIf A is AbstractArray it is possible to explicitly specify the style of the indices that should be returned by eachindex by passing a value having IndexStyle type as its first argument (typically IndexLinear() if linear indices are required or IndexCartesian() if Cartesian range is wanted).\n\nIf you supply more than one AbstractArray argument, eachindex will create an iterable object that is fast for all arguments (typically a UnitRange if all inputs have fast linear indexing, a CartesianIndices otherwise). If the arrays have different sizes and/or dimensionalities, a DimensionMismatch exception will be thrown.\n\nSee also pairs(A) to iterate over indices and values together, and axes(A, 2) for valid indices along one dimension.\n\nExamples\n\njulia> A = [10 20; 30 40];\n\njulia> for i in eachindex(A) # linear indexing\n println(\"A[\", i, \"] == \", A[i])\n end\nA[1] == 10\nA[2] == 30\nA[3] == 20\nA[4] == 40\n\njulia> for i in eachindex(view(A, 1:2, 1:1)) # Cartesian indexing\n println(i)\n end\nCartesianIndex(1, 1)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.IndexStyle","page":"Arrays","title":"Base.IndexStyle","text":"IndexStyle(A)\nIndexStyle(typeof(A))\n\nIndexStyle specifies the \"native indexing style\" for array A. When you define a new AbstractArray type, you can choose to implement either linear indexing (with IndexLinear) or cartesian indexing. If you decide to only implement linear indexing, then you must set this trait for your array type:\n\nBase.IndexStyle(::Type{<:MyArray}) = IndexLinear()\n\nThe default is IndexCartesian().\n\nJulia's internal indexing machinery will automatically (and invisibly) recompute all indexing operations into the preferred style. This allows users to access elements of your array using any indexing style, even when explicit methods have not been provided.\n\nIf you define both styles of indexing for your AbstractArray, this trait can be used to select the most performant indexing style. Some methods check this trait on their inputs, and dispatch to different algorithms depending on the most efficient access pattern. In particular, eachindex creates an iterator whose type depends on the setting of this trait.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.IndexLinear","page":"Arrays","title":"Base.IndexLinear","text":"IndexLinear()\n\nSubtype of IndexStyle used to describe arrays which are optimally indexed by one linear index.\n\nA linear indexing style uses one integer index to describe the position in the array (even if it's a multidimensional array) and column-major ordering is used to efficiently access the elements. This means that requesting eachindex from an array that is IndexLinear will return a simple one-dimensional range, even if it is multidimensional.\n\nA custom array that reports its IndexStyle as IndexLinear only needs to implement indexing (and indexed assignment) with a single Int index; all other indexing expressions — including multidimensional accesses — will be recomputed to the linear index. For example, if A were a 2×3 custom matrix with linear indexing, and we referenced A[1, 3], this would be recomputed to the equivalent linear index and call A[5] since 1 + 2*(3 - 1) = 5.\n\nSee also IndexCartesian.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.IndexCartesian","page":"Arrays","title":"Base.IndexCartesian","text":"IndexCartesian()\n\nSubtype of IndexStyle used to describe arrays which are optimally indexed by a Cartesian index. This is the default for new custom AbstractArray subtypes.\n\nA Cartesian indexing style uses multiple integer indices to describe the position in a multidimensional array, with exactly one index per dimension. This means that requesting eachindex from an array that is IndexCartesian will return a range of CartesianIndices.\n\nA N-dimensional custom array that reports its IndexStyle as IndexCartesian needs to implement indexing (and indexed assignment) with exactly N Int indices; all other indexing expressions — including linear indexing — will be recomputed to the equivalent Cartesian location. For example, if A were a 2×3 custom matrix with cartesian indexing, and we referenced A[5], this would be recomputed to the equivalent Cartesian index and call A[1, 3] since 5 = 1 + 2*(3 - 1).\n\nIt is significantly more expensive to compute Cartesian indices from a linear index than it is to go the other way. The former operation requires division — a very costly operation — whereas the latter only uses multiplication and addition and is essentially free. This asymmetry means it is far more costly to use linear indexing with an IndexCartesian array than it is to use Cartesian indexing with an IndexLinear array.\n\nSee also IndexLinear.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.conj!","page":"Arrays","title":"Base.conj!","text":"conj!(A)\n\nTransform an array to its complex conjugate in-place.\n\nSee also conj.\n\nExamples\n\njulia> A = [1+im 2-im; 2+2im 3+im]\n2×2 Matrix{Complex{Int64}}:\n 1+1im 2-1im\n 2+2im 3+1im\n\njulia> conj!(A);\n\njulia> A\n2×2 Matrix{Complex{Int64}}:\n 1-1im 2+1im\n 2-2im 3-1im\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.stride","page":"Arrays","title":"Base.stride","text":"stride(A, k::Integer)\n\nReturn the distance in memory (in number of elements) between adjacent elements in dimension k.\n\nSee also: strides.\n\nExamples\n\njulia> A = fill(1, (3,4,5));\n\njulia> stride(A,2)\n3\n\njulia> stride(A,3)\n12\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.strides","page":"Arrays","title":"Base.strides","text":"strides(A)\n\nReturn a tuple of the memory strides in each dimension.\n\nSee also: stride.\n\nExamples\n\njulia> A = fill(1, (3,4,5));\n\njulia> strides(A)\n(1, 3, 12)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Broadcast-and-vectorization","page":"Arrays","title":"Broadcast and vectorization","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"See also the dot syntax for vectorizing functions; for example, f.(args...) implicitly calls broadcast(f, args...). Rather than relying on \"vectorized\" methods of functions like sin to operate on arrays, you should use sin.(a) to vectorize via broadcast.","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.broadcast\nBase.Broadcast.broadcast!\nBase.@__dot__","category":"page"},{"location":"base/arrays/#Base.Broadcast.broadcast","page":"Arrays","title":"Base.Broadcast.broadcast","text":"broadcast(f, As...)\n\nBroadcast the function f over the arrays, tuples, collections, Refs and/or scalars As.\n\nBroadcasting applies the function f over the elements of the container arguments and the scalars themselves in As. Singleton and missing dimensions are expanded to match the extents of the other arguments by virtually repeating the value. By default, only a limited number of types are considered scalars, including Numbers, Strings, Symbols, Types, Functions and some common singletons like missing and nothing. All other arguments are iterated over or indexed into elementwise.\n\nThe resulting container type is established by the following rules:\n\nIf all the arguments are scalars or zero-dimensional arrays, it returns an unwrapped scalar.\nIf at least one argument is a tuple and all others are scalars or zero-dimensional arrays, it returns a tuple.\nAll other combinations of arguments default to returning an Array, but custom container types can define their own implementation and promotion-like rules to customize the result when they appear as arguments.\n\nA special syntax exists for broadcasting: f.(args...) is equivalent to broadcast(f, args...), and nested f.(g.(args...)) calls are fused into a single broadcast loop.\n\nExamples\n\njulia> A = [1, 2, 3, 4, 5]\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n\njulia> B = [1 2; 3 4; 5 6; 7 8; 9 10]\n5×2 Matrix{Int64}:\n 1 2\n 3 4\n 5 6\n 7 8\n 9 10\n\njulia> broadcast(+, A, B)\n5×2 Matrix{Int64}:\n 2 3\n 5 6\n 8 9\n 11 12\n 14 15\n\njulia> parse.(Int, [\"1\", \"2\"])\n2-element Vector{Int64}:\n 1\n 2\n\njulia> abs.((1, -2))\n(1, 2)\n\njulia> broadcast(+, 1.0, (0, -2.0))\n(1.0, -1.0)\n\njulia> (+).([[0,2], [1,3]], Ref{Vector{Int}}([1,-1]))\n2-element Vector{Vector{Int64}}:\n [1, 1]\n [2, 2]\n\njulia> string.((\"one\",\"two\",\"three\",\"four\"), \": \", 1:4)\n4-element Vector{String}:\n \"one: 1\"\n \"two: 2\"\n \"three: 3\"\n \"four: 4\"\n\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.broadcast!","page":"Arrays","title":"Base.Broadcast.broadcast!","text":"broadcast!(f, dest, As...)\n\nLike broadcast, but store the result of broadcast(f, As...) in the dest array. Note that dest is only used to store the result, and does not supply arguments to f unless it is also listed in the As, as in broadcast!(f, A, A, B) to perform A[:] = broadcast(f, A, B).\n\nExamples\n\njulia> A = [1.0; 0.0]; B = [0.0; 0.0];\n\njulia> broadcast!(+, B, A, (0, -2.0));\n\njulia> B\n2-element Vector{Float64}:\n 1.0\n -2.0\n\njulia> A\n2-element Vector{Float64}:\n 1.0\n 0.0\n\njulia> broadcast!(+, A, A, (0, -2.0));\n\njulia> A\n2-element Vector{Float64}:\n 1.0\n -2.0\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.@__dot__","page":"Arrays","title":"Base.Broadcast.@__dot__","text":"@. expr\n\nConvert every function call or operator in expr into a \"dot call\" (e.g. convert f(x) to f.(x)), and convert every assignment in expr to a \"dot assignment\" (e.g. convert += to .+=).\n\nIf you want to avoid adding dots for selected function calls in expr, splice those function calls in with $. For example, @. sqrt(abs($sort(x))) is equivalent to sqrt.(abs.(sort(x))) (no dot for sort).\n\n(@. is equivalent to a call to @__dot__.)\n\nExamples\n\njulia> x = 1.0:3.0; y = similar(x);\n\njulia> @. y = x + 3 * sin(x)\n3-element Vector{Float64}:\n 3.5244129544236893\n 4.727892280477045\n 3.4233600241796016\n\n\n\n\n\n","category":"macro"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"For specializing broadcast on custom types, see","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.BroadcastStyle\nBase.Broadcast.AbstractArrayStyle\nBase.Broadcast.ArrayStyle\nBase.Broadcast.DefaultArrayStyle\nBase.Broadcast.broadcastable\nBase.Broadcast.combine_axes\nBase.Broadcast.combine_styles\nBase.Broadcast.result_style","category":"page"},{"location":"base/arrays/#Base.Broadcast.BroadcastStyle","page":"Arrays","title":"Base.Broadcast.BroadcastStyle","text":"BroadcastStyle is an abstract type and trait-function used to determine behavior of objects under broadcasting. BroadcastStyle(typeof(x)) returns the style associated with x. To customize the broadcasting behavior of a type, one can declare a style by defining a type/method pair\n\nstruct MyContainerStyle <: BroadcastStyle end\nBase.BroadcastStyle(::Type{<:MyContainer}) = MyContainerStyle()\n\nOne then writes method(s) (at least similar) operating on Broadcasted{MyContainerStyle}. There are also several pre-defined subtypes of BroadcastStyle that you may be able to leverage; see the Interfaces chapter for more information.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Broadcast.AbstractArrayStyle","page":"Arrays","title":"Base.Broadcast.AbstractArrayStyle","text":"Broadcast.AbstractArrayStyle{N} <: BroadcastStyle is the abstract supertype for any style associated with an AbstractArray type. The N parameter is the dimensionality, which can be handy for AbstractArray types that only support specific dimensionalities:\n\nstruct SparseMatrixStyle <: Broadcast.AbstractArrayStyle{2} end\nBase.BroadcastStyle(::Type{<:SparseMatrixCSC}) = SparseMatrixStyle()\n\nFor AbstractArray types that support arbitrary dimensionality, N can be set to Any:\n\nstruct MyArrayStyle <: Broadcast.AbstractArrayStyle{Any} end\nBase.BroadcastStyle(::Type{<:MyArray}) = MyArrayStyle()\n\nIn cases where you want to be able to mix multiple AbstractArrayStyles and keep track of dimensionality, your style needs to support a Val constructor:\n\nstruct MyArrayStyleDim{N} <: Broadcast.AbstractArrayStyle{N} end\n(::Type{<:MyArrayStyleDim})(::Val{N}) where N = MyArrayStyleDim{N}()\n\nNote that if two or more AbstractArrayStyle subtypes conflict, broadcasting machinery will fall back to producing Arrays. If this is undesirable, you may need to define binary BroadcastStyle rules to control the output type.\n\nSee also Broadcast.DefaultArrayStyle.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Broadcast.ArrayStyle","page":"Arrays","title":"Base.Broadcast.ArrayStyle","text":"Broadcast.ArrayStyle{MyArrayType}() is a BroadcastStyle indicating that an object behaves as an array for broadcasting. It presents a simple way to construct Broadcast.AbstractArrayStyles for specific AbstractArray container types. Broadcast styles created this way lose track of dimensionality; if keeping track is important for your type, you should create your own custom Broadcast.AbstractArrayStyle.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Broadcast.DefaultArrayStyle","page":"Arrays","title":"Base.Broadcast.DefaultArrayStyle","text":"Broadcast.DefaultArrayStyle{N}() is a BroadcastStyle indicating that an object behaves as an N-dimensional array for broadcasting. Specifically, DefaultArrayStyle is used for any AbstractArray type that hasn't defined a specialized style, and in the absence of overrides from other broadcast arguments the resulting output type is Array. When there are multiple inputs to broadcast, DefaultArrayStyle \"loses\" to any other Broadcast.ArrayStyle.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Broadcast.broadcastable","page":"Arrays","title":"Base.Broadcast.broadcastable","text":"Broadcast.broadcastable(x)\n\nReturn either x or an object like x such that it supports axes, indexing, and its type supports ndims.\n\nIf x supports iteration, the returned value should have the same axes and indexing behaviors as collect(x).\n\nIf x is not an AbstractArray but it supports axes, indexing, and its type supports ndims, then broadcastable(::typeof(x)) may be implemented to just return itself. Further, if x defines its own BroadcastStyle, then it must define its broadcastable method to return itself for the custom style to have any effect.\n\nExamples\n\njulia> Broadcast.broadcastable([1,2,3]) # like `identity` since arrays already support axes and indexing\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> Broadcast.broadcastable(Int) # Types don't support axes, indexing, or iteration but are commonly used as scalars\nBase.RefValue{Type{Int64}}(Int64)\n\njulia> Broadcast.broadcastable(\"hello\") # Strings break convention of matching iteration and act like a scalar instead\nBase.RefValue{String}(\"hello\")\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.combine_axes","page":"Arrays","title":"Base.Broadcast.combine_axes","text":"combine_axes(As...) -> Tuple\n\nDetermine the result axes for broadcasting across all values in As.\n\njulia> Broadcast.combine_axes([1], [1 2; 3 4; 5 6])\n(Base.OneTo(3), Base.OneTo(2))\n\njulia> Broadcast.combine_axes(1, 1, 1)\n()\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.combine_styles","page":"Arrays","title":"Base.Broadcast.combine_styles","text":"combine_styles(cs...) -> BroadcastStyle\n\nDecides which BroadcastStyle to use for any number of value arguments. Uses BroadcastStyle to get the style for each argument, and uses result_style to combine styles.\n\nExamples\n\njulia> Broadcast.combine_styles([1], [1 2; 3 4])\nBase.Broadcast.DefaultArrayStyle{2}()\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Broadcast.result_style","page":"Arrays","title":"Base.Broadcast.result_style","text":"result_style(s1::BroadcastStyle[, s2::BroadcastStyle]) -> BroadcastStyle\n\nTakes one or two BroadcastStyles and combines them using BroadcastStyle to determine a common BroadcastStyle.\n\nExamples\n\njulia> Broadcast.result_style(Broadcast.DefaultArrayStyle{0}(), Broadcast.DefaultArrayStyle{3}())\nBase.Broadcast.DefaultArrayStyle{3}()\n\njulia> Broadcast.result_style(Broadcast.Unknown(), Broadcast.DefaultArrayStyle{1}())\nBase.Broadcast.DefaultArrayStyle{1}()\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Indexing-and-assignment","page":"Arrays","title":"Indexing and assignment","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.getindex(::AbstractArray, ::Any...)\nBase.setindex!(::AbstractArray, ::Any, ::Any...)\nBase.nextind\nBase.prevind\nBase.copyto!(::AbstractArray, ::CartesianIndices, ::AbstractArray, ::CartesianIndices)\nBase.copy!\nBase.isassigned\nBase.Colon\nBase.CartesianIndex\nBase.CartesianIndices\nBase.Dims\nBase.LinearIndices\nBase.to_indices\nBase.checkbounds\nBase.checkindex\nBase.elsize","category":"page"},{"location":"base/arrays/#Base.getindex-Tuple{AbstractArray, Vararg{Any}}","page":"Arrays","title":"Base.getindex","text":"getindex(A, inds...)\n\nReturn a subset of array A as selected by the indices inds.\n\nEach index may be any supported index type, such as an Integer, CartesianIndex, range, or array of supported indices. A : may be used to select all elements along a specific dimension, and a boolean array (e.g. an Array{Bool} or a BitArray) may be used to filter for elements where the corresponding index is true.\n\nWhen inds selects multiple elements, this function returns a newly allocated array. To index multiple elements without making a copy, use view instead.\n\nSee the manual section on array indexing for details.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> getindex(A, 1)\n1\n\njulia> getindex(A, [2, 1])\n2-element Vector{Int64}:\n 3\n 1\n\njulia> getindex(A, 2:4)\n3-element Vector{Int64}:\n 3\n 2\n 4\n\njulia> getindex(A, 2, 1)\n3\n\njulia> getindex(A, CartesianIndex(2, 1))\n3\n\njulia> getindex(A, :, 2)\n2-element Vector{Int64}:\n 2\n 4\n\njulia> getindex(A, 2, :)\n2-element Vector{Int64}:\n 3\n 4\n\njulia> getindex(A, A .> 2)\n2-element Vector{Int64}:\n 3\n 4\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.setindex!-Tuple{AbstractArray, Any, Vararg{Any}}","page":"Arrays","title":"Base.setindex!","text":"setindex!(A, X, inds...)\nA[inds...] = X\n\nStore values from array X within some subset of A as specified by inds. The syntax A[inds...] = X is equivalent to (setindex!(A, X, inds...); X).\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = zeros(2,2);\n\njulia> setindex!(A, [10, 20], [1, 2]);\n\njulia> A[[3, 4]] = [30, 40];\n\njulia> A\n2×2 Matrix{Float64}:\n 10.0 30.0\n 20.0 40.0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.nextind","page":"Arrays","title":"Base.nextind","text":"nextind(A, i)\n\nReturn the index after i in A. The returned index is often equivalent to `i\n\n1for an integeri`. This function can be useful for generic code.\n\nwarning: Warning\nThe returned index might be out of bounds. Consider using checkbounds.\n\nSee also: prevind.\n\nExamples\n\njulia> x = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> nextind(x, 1) # valid result\n2\n\njulia> nextind(x, 4) # invalid result\n5\n\njulia> nextind(x, CartesianIndex(1, 1)) # valid result\nCartesianIndex(2, 1)\n\njulia> nextind(x, CartesianIndex(2, 2)) # invalid result\nCartesianIndex(1, 3)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.prevind","page":"Arrays","title":"Base.prevind","text":"prevind(A, i)\n\nReturn the index before i in A. The returned index is often equivalent to `i\n\n1for an integeri`. This function can be useful for generic code.\n\nwarning: Warning\nThe returned index might be out of bounds. Consider using checkbounds.\n\nSee also: nextind.\n\nExamples\n\njulia> x = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> prevind(x, 4) # valid result\n3\n\njulia> prevind(x, 1) # invalid result\n0\n\njulia> prevind(x, CartesianIndex(2, 2)) # valid result\nCartesianIndex(1, 2)\n\njulia> prevind(x, CartesianIndex(1, 1)) # invalid result\nCartesianIndex(2, 0)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.copyto!-Tuple{AbstractArray, CartesianIndices, AbstractArray, CartesianIndices}","page":"Arrays","title":"Base.copyto!","text":"copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest\n\nCopy the block of src in the range of Rsrc to the block of dest in the range of Rdest. The sizes of the two regions must match.\n\nExamples\n\njulia> A = zeros(5, 5);\n\njulia> B = [1 2; 3 4];\n\njulia> Ainds = CartesianIndices((2:3, 2:3));\n\njulia> Binds = CartesianIndices(B);\n\njulia> copyto!(A, Ainds, B, Binds)\n5×5 Matrix{Float64}:\n 0.0 0.0 0.0 0.0 0.0\n 0.0 1.0 2.0 0.0 0.0\n 0.0 3.0 4.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.copy!","page":"Arrays","title":"Base.copy!","text":"copy!(dst, src) -> dst\n\nIn-place copy of src into dst, discarding any pre-existing elements in dst. If dst and src are of the same type, dst == src should hold after the call. If dst and src are multidimensional arrays, they must have equal axes.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also copyto!.\n\ncompat: Julia 1.1\nThis method requires at least Julia 1.1. In Julia 1.0 this method is available from the Future standard library as Future.copy!.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.isassigned","page":"Arrays","title":"Base.isassigned","text":"isassigned(array, i) -> Bool\n\nTest whether the given array has a value associated with index i. Return false if the index is out of bounds, or has an undefined reference.\n\nExamples\n\njulia> isassigned(rand(3, 3), 5)\ntrue\n\njulia> isassigned(rand(3, 3), 3 * 3 + 1)\nfalse\n\njulia> mutable struct Foo end\n\njulia> v = similar(rand(3), Foo)\n3-element Vector{Foo}:\n #undef\n #undef\n #undef\n\njulia> isassigned(v, 1)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.Colon","page":"Arrays","title":"Base.Colon","text":"Colon()\n\nColons (:) are used to signify indexing entire objects or dimensions at once.\n\nVery few operations are defined on Colons directly; instead they are converted by to_indices to an internal vector type (Base.Slice) to represent the collection of indices they span before being used.\n\nThe singleton instance of Colon is also a function used to construct ranges; see :.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.IteratorsMD.CartesianIndex","page":"Arrays","title":"Base.IteratorsMD.CartesianIndex","text":"CartesianIndex(i, j, k...) -> I\nCartesianIndex((i, j, k...)) -> I\n\nCreate a multidimensional index I, which can be used for indexing a multidimensional array A. In particular, A[I] is equivalent to A[i,j,k...]. One can freely mix integer and CartesianIndex indices; for example, A[Ipre, i, Ipost] (where Ipre and Ipost are CartesianIndex indices and i is an Int) can be a useful expression when writing algorithms that work along a single dimension of an array of arbitrary dimensionality.\n\nA CartesianIndex is sometimes produced by eachindex, and always when iterating with an explicit CartesianIndices.\n\nAn I::CartesianIndex is treated as a \"scalar\" (not a container) for broadcast. In order to iterate over the components of a CartesianIndex, convert it to a tuple with Tuple(I).\n\nExamples\n\njulia> A = reshape(Vector(1:16), (2, 2, 2, 2))\n2×2×2×2 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 3\n 2 4\n\n[:, :, 2, 1] =\n 5 7\n 6 8\n\n[:, :, 1, 2] =\n 9 11\n 10 12\n\n[:, :, 2, 2] =\n 13 15\n 14 16\n\njulia> A[CartesianIndex((1, 1, 1, 1))]\n1\n\njulia> A[CartesianIndex((1, 1, 1, 2))]\n9\n\njulia> A[CartesianIndex((1, 1, 2, 1))]\n5\n\ncompat: Julia 1.10\nUsing a CartesianIndex as a \"scalar\" for broadcast requires Julia 1.10; in previous releases, use Ref(I).\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.IteratorsMD.CartesianIndices","page":"Arrays","title":"Base.IteratorsMD.CartesianIndices","text":"CartesianIndices(sz::Dims) -> R\nCartesianIndices((istart:[istep:]istop, jstart:[jstep:]jstop, ...)) -> R\n\nDefine a region R spanning a multidimensional rectangular range of integer indices. These are most commonly encountered in the context of iteration, where for I in R ... end will return CartesianIndex indices I equivalent to the nested loops\n\nfor j = jstart:jstep:jstop\n for i = istart:istep:istop\n ...\n end\nend\n\nConsequently these can be useful for writing algorithms that work in arbitrary dimensions.\n\nCartesianIndices(A::AbstractArray) -> R\n\nAs a convenience, constructing a CartesianIndices from an array makes a range of its indices.\n\ncompat: Julia 1.6\nThe step range method CartesianIndices((istart:istep:istop, jstart:[jstep:]jstop, ...)) requires at least Julia 1.6.\n\nExamples\n\njulia> foreach(println, CartesianIndices((2, 2, 2)))\nCartesianIndex(1, 1, 1)\nCartesianIndex(2, 1, 1)\nCartesianIndex(1, 2, 1)\nCartesianIndex(2, 2, 1)\nCartesianIndex(1, 1, 2)\nCartesianIndex(2, 1, 2)\nCartesianIndex(1, 2, 2)\nCartesianIndex(2, 2, 2)\n\njulia> CartesianIndices(fill(1, (2,3)))\nCartesianIndices((2, 3))\n\nConversion between linear and cartesian indices\n\nLinear index to cartesian index conversion exploits the fact that a CartesianIndices is an AbstractArray and can be indexed linearly:\n\njulia> cartesian = CartesianIndices((1:3, 1:2))\nCartesianIndices((1:3, 1:2))\n\njulia> cartesian[4]\nCartesianIndex(1, 2)\n\njulia> cartesian = CartesianIndices((1:2:5, 1:2))\nCartesianIndices((1:2:5, 1:2))\n\njulia> cartesian[2, 2]\nCartesianIndex(3, 2)\n\nBroadcasting\n\nCartesianIndices support broadcasting arithmetic (+ and -) with a CartesianIndex.\n\ncompat: Julia 1.1\nBroadcasting of CartesianIndices requires at least Julia 1.1.\n\njulia> CIs = CartesianIndices((2:3, 5:6))\nCartesianIndices((2:3, 5:6))\n\njulia> CI = CartesianIndex(3, 4)\nCartesianIndex(3, 4)\n\njulia> CIs .+ CI\nCartesianIndices((5:6, 9:10))\n\nFor cartesian to linear index conversion, see LinearIndices.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.Dims","page":"Arrays","title":"Base.Dims","text":"Dims{N}\n\nAn NTuple of N Ints used to represent the dimensions of an AbstractArray.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.LinearIndices","page":"Arrays","title":"Base.LinearIndices","text":"LinearIndices(A::AbstractArray)\n\nReturn a LinearIndices array with the same shape and axes as A, holding the linear index of each entry in A. Indexing this array with cartesian indices allows mapping them to linear indices.\n\nFor arrays with conventional indexing (indices start at 1), or any multidimensional array, linear indices range from 1 to length(A). However, for AbstractVectors linear indices are axes(A, 1), and therefore do not start at 1 for vectors with unconventional indexing.\n\nCalling this function is the \"safe\" way to write algorithms that exploit linear indexing.\n\nExamples\n\njulia> A = fill(1, (5,6,7));\n\njulia> b = LinearIndices(A);\n\njulia> extrema(b)\n(1, 210)\n\nLinearIndices(inds::CartesianIndices) -> R\nLinearIndices(sz::Dims) -> R\nLinearIndices((istart:istop, jstart:jstop, ...)) -> R\n\nReturn a LinearIndices array with the specified shape or axes.\n\nExamples\n\nThe main purpose of this constructor is intuitive conversion from cartesian to linear indexing:\n\njulia> linear = LinearIndices((1:3, 1:2))\n3×2 LinearIndices{2, Tuple{UnitRange{Int64}, UnitRange{Int64}}}:\n 1 4\n 2 5\n 3 6\n\njulia> linear[1,2]\n4\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.to_indices","page":"Arrays","title":"Base.to_indices","text":"to_indices(A, I::Tuple)\n\nConvert the tuple I to a tuple of indices for use in indexing into array A.\n\nThe returned tuple must only contain either Ints or AbstractArrays of scalar indices that are supported by array A. It will error upon encountering a novel index type that it does not know how to process.\n\nFor simple index types, it defers to the unexported Base.to_index(A, i) to process each index i. While this internal function is not intended to be called directly, Base.to_index may be extended by custom array or index types to provide custom indexing behaviors.\n\nMore complicated index types may require more context about the dimension into which they index. To support those cases, to_indices(A, I) calls to_indices(A, axes(A), I), which then recursively walks through both the given tuple of indices and the dimensional indices of A in tandem. As such, not all index types are guaranteed to propagate to Base.to_index.\n\nExamples\n\njulia> A = zeros(1,2,3,4);\n\njulia> to_indices(A, (1,1,2,2))\n(1, 1, 2, 2)\n\njulia> to_indices(A, (1,1,2,20)) # no bounds checking\n(1, 1, 2, 20)\n\njulia> to_indices(A, (CartesianIndex((1,)), 2, CartesianIndex((3,4)))) # exotic index\n(1, 2, 3, 4)\n\njulia> to_indices(A, ([1,1], 1:2, 3, 4))\n([1, 1], 1:2, 3, 4)\n\njulia> to_indices(A, (1,2)) # no shape checking\n(1, 2)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.checkbounds","page":"Arrays","title":"Base.checkbounds","text":"checkbounds(Bool, A, I...)\n\nReturn true if the specified indices I are in bounds for the given array A. Subtypes of AbstractArray should specialize this method if they need to provide custom bounds checking behaviors; however, in many cases one can rely on A's indices and checkindex.\n\nSee also checkindex.\n\nExamples\n\njulia> A = rand(3, 3);\n\njulia> checkbounds(Bool, A, 2)\ntrue\n\njulia> checkbounds(Bool, A, 3, 4)\nfalse\n\njulia> checkbounds(Bool, A, 1:3)\ntrue\n\njulia> checkbounds(Bool, A, 1:3, 2:4)\nfalse\n\n\n\n\n\ncheckbounds(A, I...)\n\nThrow an error if the specified indices I are not in bounds for the given array A.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.checkindex","page":"Arrays","title":"Base.checkindex","text":"checkindex(Bool, inds::AbstractUnitRange, index)\n\nReturn true if the given index is within the bounds of inds. Custom types that would like to behave as indices for all arrays can extend this method in order to provide a specialized bounds checking implementation.\n\nSee also checkbounds.\n\nExamples\n\njulia> checkindex(Bool, 1:20, 8)\ntrue\n\njulia> checkindex(Bool, 1:20, 21)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.elsize","page":"Arrays","title":"Base.elsize","text":"elsize(type)\n\nCompute the memory stride in bytes between consecutive elements of eltype stored inside the given type, if the array elements are stored densely with a uniform linear stride.\n\nExamples\n\njulia> Base.elsize(rand(Float32, 10))\n4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Views-(SubArrays-and-other-view-types)","page":"Arrays","title":"Views (SubArrays and other view types)","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"A “view” is a data structure that acts like an array (it is a subtype of AbstractArray), but the underlying data is actually part of another array.","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"For example, if x is an array and v = @view x[1:10], then v acts like a 10-element array, but its data is actually accessing the first 10 elements of x. Writing to a view, e.g. v[3] = 2, writes directly to the underlying array x (in this case modifying x[3]).","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Slicing operations like x[1:10] create a copy by default in Julia. @view x[1:10] changes it to make a view. The @views macro can be used on a whole block of code (e.g. @views function foo() .... end or @views begin ... end) to change all the slicing operations in that block to use views. Sometimes making a copy of the data is faster and sometimes using a view is faster, as described in the performance tips.","category":"page"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.view\nBase.@view\nBase.@views\nBase.parent\nBase.parentindices\nBase.selectdim\nBase.reinterpret\nBase.reshape\nBase.dropdims\nBase.vec\nBase.SubArray\nBase.wrap","category":"page"},{"location":"base/arrays/#Base.view","page":"Arrays","title":"Base.view","text":"view(A, inds...)\n\nLike getindex, but returns a lightweight array that lazily references (or is effectively a view into) the parent array A at the given index or indices inds instead of eagerly extracting elements or constructing a copied subset. Calling getindex or setindex! on the returned value (often a SubArray) computes the indices to access or modify the parent array on the fly. The behavior is undefined if the shape of the parent array is changed after view is called because there is no bound check for the parent array; e.g., it may cause a segmentation fault.\n\nSome immutable parent arrays (like ranges) may choose to simply recompute a new array in some circumstances instead of returning a SubArray if doing so is efficient and provides compatible semantics.\n\ncompat: Julia 1.6\nIn Julia 1.6 or later, view can be called on an AbstractString, returning a SubString.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> b = view(A, :, 1)\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 1\n 3\n\njulia> fill!(b, 0)\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 0\n 0\n\njulia> A # Note A has changed even though we modified b\n2×2 Matrix{Int64}:\n 0 2\n 0 4\n\njulia> view(2:5, 2:3) # returns a range as type is immutable\n3:4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.@view","page":"Arrays","title":"Base.@view","text":"@view A[inds...]\n\nTransform the indexing expression A[inds...] into the equivalent view call.\n\nThis can only be applied directly to a single indexing expression and is particularly helpful for expressions that include the special begin or end indexing syntaxes like A[begin, 2:end-1] (as those are not supported by the normal view function).\n\nNote that @view cannot be used as the target of a regular assignment (e.g., @view(A[1, 2:end]) = ...), nor would the un-decorated indexed assignment (A[1, 2:end] = ...) or broadcasted indexed assignment (A[1, 2:end] .= ...) make a copy. It can be useful, however, for updating broadcasted assignments like @view(A[1, 2:end]) .+= 1 because this is a simple syntax for @view(A[1, 2:end]) .= @view(A[1, 2:end]) + 1, and the indexing expression on the right-hand side would otherwise make a copy without the @view.\n\nSee also @views to switch an entire block of code to use views for non-scalar indexing.\n\ncompat: Julia 1.5\nUsing begin in an indexing expression to refer to the first index requires at least Julia 1.5.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> b = @view A[:, 1]\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 1\n 3\n\njulia> fill!(b, 0)\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 0\n 0\n\njulia> A\n2×2 Matrix{Int64}:\n 0 2\n 0 4\n\n\n\n\n\n","category":"macro"},{"location":"base/arrays/#Base.@views","page":"Arrays","title":"Base.@views","text":"@views expression\n\nConvert every array-slicing operation in the given expression (which may be a begin/end block, loop, function, etc.) to return a view. Scalar indices, non-array types, and explicit getindex calls (as opposed to array[...]) are unaffected.\n\nSimilarly, @views converts string slices into SubString views.\n\nnote: Note\nThe @views macro only affects array[...] expressions that appear explicitly in the given expression, not array slicing that occurs in functions called by that code.\n\ncompat: Julia 1.5\nUsing begin in an indexing expression to refer to the first index was implemented in Julia 1.4, but was only supported by @views starting in Julia 1.5.\n\nExamples\n\njulia> A = zeros(3, 3);\n\njulia> @views for row in 1:3\n b = A[row, :] # b is a view, not a copy\n b .= row # assign every element to the row index\n end\n\njulia> A\n3×3 Matrix{Float64}:\n 1.0 1.0 1.0\n 2.0 2.0 2.0\n 3.0 3.0 3.0\n\n\n\n\n\n","category":"macro"},{"location":"base/arrays/#Base.parent","page":"Arrays","title":"Base.parent","text":"parent(A)\n\nReturn the underlying parent object of the view. This parent of objects of types SubArray, SubString, ReshapedArray or LinearAlgebra.Transpose is what was passed as an argument to view, reshape, transpose, etc. during object creation. If the input is not a wrapped object, return the input itself. If the input is wrapped multiple times, only the outermost wrapper will be removed.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> V = view(A, 1:2, :)\n2×2 view(::Matrix{Int64}, 1:2, :) with eltype Int64:\n 1 2\n 3 4\n\njulia> parent(V)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.parentindices","page":"Arrays","title":"Base.parentindices","text":"parentindices(A)\n\nReturn the indices in the parent which correspond to the view A.\n\nExamples\n\njulia> A = [1 2; 3 4];\n\njulia> V = view(A, 1, :)\n2-element view(::Matrix{Int64}, 1, :) with eltype Int64:\n 1\n 2\n\njulia> parentindices(V)\n(1, Base.Slice(Base.OneTo(2)))\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.selectdim","page":"Arrays","title":"Base.selectdim","text":"selectdim(A, d::Integer, i)\n\nReturn a view of all the data of A where the index for dimension d equals i.\n\nEquivalent to view(A,:,:,...,i,:,:,...) where i is in position d.\n\nSee also: eachslice.\n\nExamples\n\njulia> A = [1 2 3 4; 5 6 7 8]\n2×4 Matrix{Int64}:\n 1 2 3 4\n 5 6 7 8\n\njulia> selectdim(A, 2, 3)\n2-element view(::Matrix{Int64}, :, 3) with eltype Int64:\n 3\n 7\n\njulia> selectdim(A, 2, 3:4)\n2×2 view(::Matrix{Int64}, :, 3:4) with eltype Int64:\n 3 4\n 7 8\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.reinterpret","page":"Arrays","title":"Base.reinterpret","text":"reinterpret(::Type{Out}, x::In)\n\nChange the type-interpretation of the binary data in the isbits value x to that of the isbits type Out. The size (ignoring padding) of Out has to be the same as that of the type of x. For example, reinterpret(Float32, UInt32(7)) interprets the 4 bytes corresponding to UInt32(7) as a Float32. Note that reinterpret(In, reinterpret(Out, x)) === x\n\njulia> reinterpret(Float32, UInt32(7))\n1.0f-44\n\njulia> reinterpret(NTuple{2, UInt8}, 0x1234)\n(0x34, 0x12)\n\njulia> reinterpret(UInt16, (0x34, 0x12))\n0x1234\n\njulia> reinterpret(Tuple{UInt16, UInt8}, (0x01, 0x0203))\n(0x0301, 0x02)\n\nnote: Note\nThe treatment of padding differs from reinterpret(::DataType, ::AbstractArray).\n\nwarning: Warning\nUse caution if some combinations of bits in Out are not considered valid and would otherwise be prevented by the type's constructors and methods. Unexpected behavior may result without additional validation.\n\n\n\n\n\nreinterpret(T::DataType, A::AbstractArray)\n\nConstruct a view of the array with the same binary data as the given array, but with T as element type.\n\nThis function also works on \"lazy\" array whose elements are not computed until they are explicitly retrieved. For instance, reinterpret on the range 1:6 works similarly as on the dense vector collect(1:6):\n\njulia> reinterpret(Float32, UInt32[1 2 3 4 5])\n1×5 reinterpret(Float32, ::Matrix{UInt32}):\n 1.0f-45 3.0f-45 4.0f-45 6.0f-45 7.0f-45\n\njulia> reinterpret(Complex{Int}, 1:6)\n3-element reinterpret(Complex{Int64}, ::UnitRange{Int64}):\n 1 + 2im\n 3 + 4im\n 5 + 6im\n\nIf the location of padding bits does not line up between T and eltype(A), the resulting array will be read-only or write-only, to prevent invalid bits from being written to or read from, respectively.\n\njulia> a = reinterpret(Tuple{UInt8, UInt32}, UInt32[1, 2])\n1-element reinterpret(Tuple{UInt8, UInt32}, ::Vector{UInt32}):\n (0x01, 0x00000002)\n\njulia> a[1] = 3\nERROR: Padding of type Tuple{UInt8, UInt32} is not compatible with type UInt32.\n\njulia> b = reinterpret(UInt32, Tuple{UInt8, UInt32}[(0x01, 0x00000002)]); # showing will error\n\njulia> b[1]\nERROR: Padding of type UInt32 is not compatible with type Tuple{UInt8, UInt32}.\n\n\n\n\n\nreinterpret(reshape, T, A::AbstractArray{S}) -> B\n\nChange the type-interpretation of A while consuming or adding a \"channel dimension.\"\n\nIf sizeof(T) = n*sizeof(S) for n>1, A's first dimension must be of size n and B lacks A's first dimension. Conversely, if sizeof(S) = n*sizeof(T) for n>1, B gets a new first dimension of size n. The dimensionality is unchanged if sizeof(T) == sizeof(S).\n\ncompat: Julia 1.6\nThis method requires at least Julia 1.6.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> reinterpret(reshape, Complex{Int}, A) # the result is a vector\n2-element reinterpret(reshape, Complex{Int64}, ::Matrix{Int64}) with eltype Complex{Int64}:\n 1 + 3im\n 2 + 4im\n\njulia> a = [(1,2,3), (4,5,6)]\n2-element Vector{Tuple{Int64, Int64, Int64}}:\n (1, 2, 3)\n (4, 5, 6)\n\njulia> reinterpret(reshape, Int, a) # the result is a matrix\n3×2 reinterpret(reshape, Int64, ::Vector{Tuple{Int64, Int64, Int64}}) with eltype Int64:\n 1 4\n 2 5\n 3 6\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.reshape","page":"Arrays","title":"Base.reshape","text":"reshape(A, dims...) -> AbstractArray\nreshape(A, dims) -> AbstractArray\n\nReturn an array with the same data as A, but with different dimension sizes or number of dimensions. The two arrays share the same underlying data, so that the result is mutable if and only if A is mutable, and setting elements of one alters the values of the other.\n\nThe new dimensions may be specified either as a list of arguments or as a shape tuple. At most one dimension may be specified with a :, in which case its length is computed such that its product with all the specified dimensions is equal to the length of the original array A. The total number of elements must not change.\n\nExamples\n\njulia> A = Vector(1:16)\n16-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n 11\n 12\n 13\n 14\n 15\n 16\n\njulia> reshape(A, (4, 4))\n4×4 Matrix{Int64}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> reshape(A, 2, :)\n2×8 Matrix{Int64}:\n 1 3 5 7 9 11 13 15\n 2 4 6 8 10 12 14 16\n\njulia> reshape(1:6, 2, 3)\n2×3 reshape(::UnitRange{Int64}, 2, 3) with eltype Int64:\n 1 3 5\n 2 4 6\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.dropdims","page":"Arrays","title":"Base.dropdims","text":"dropdims(A; dims)\n\nReturn an array with the same data as A, but with the dimensions specified by dims removed. size(A,d) must equal 1 for every d in dims, and repeated dimensions or numbers outside 1:ndims(A) are forbidden.\n\nThe result shares the same underlying data as A, such that the result is mutable if and only if A is mutable, and setting elements of one alters the values of the other.\n\nSee also: reshape, vec.\n\nExamples\n\njulia> a = reshape(Vector(1:4),(2,2,1,1))\n2×2×1×1 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 3\n 2 4\n\njulia> b = dropdims(a; dims=3)\n2×2×1 Array{Int64, 3}:\n[:, :, 1] =\n 1 3\n 2 4\n\njulia> b[1,1,1] = 5; a\n2×2×1×1 Array{Int64, 4}:\n[:, :, 1, 1] =\n 5 3\n 2 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.vec","page":"Arrays","title":"Base.vec","text":"vec(a::AbstractArray) -> AbstractVector\n\nReshape the array a as a one-dimensional column vector. Return a if it is already an AbstractVector. The resulting array shares the same underlying data as a, so it will only be mutable if a is mutable, in which case modifying one will also modify the other.\n\nExamples\n\njulia> a = [1 2 3; 4 5 6]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> vec(a)\n6-element Vector{Int64}:\n 1\n 4\n 2\n 5\n 3\n 6\n\njulia> vec(1:3)\n1:3\n\nSee also reshape, dropdims.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.SubArray","page":"Arrays","title":"Base.SubArray","text":"SubArray{T,N,P,I,L} <: AbstractArray{T,N}\n\nN-dimensional view into a parent array (of type P) with an element type T, restricted by a tuple of indices (of type I). L is true for types that support fast linear indexing, and false otherwise.\n\nConstruct SubArrays using the view function.\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.wrap","page":"Arrays","title":"Base.wrap","text":"wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)\n\nCreate an array of size dims using m as the underlying memory. This can be thought of as a safe version of unsafe_wrap utilizing Memory or MemoryRef instead of raw pointers.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Concatenation-and-permutation","page":"Arrays","title":"Concatenation and permutation","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.cat\nBase.vcat\nBase.hcat\nBase.hvcat\nBase.hvncat\nBase.stack\nBase.vect\nBase.circshift\nBase.circshift!\nBase.circcopy!\nBase.findall(::Any)\nBase.findall(::Function, ::Any)\nBase.findfirst(::Any)\nBase.findfirst(::Function, ::Any)\nBase.findlast(::Any)\nBase.findlast(::Function, ::Any)\nBase.findnext(::Any, ::Integer)\nBase.findnext(::Function, ::Any, ::Integer)\nBase.findprev(::Any, ::Integer)\nBase.findprev(::Function, ::Any, ::Integer)\nBase.permutedims\nBase.permutedims!\nBase.PermutedDimsArray\nBase.promote_shape","category":"page"},{"location":"base/arrays/#Base.cat","page":"Arrays","title":"Base.cat","text":"cat(A...; dims)\n\nConcatenate the input arrays along the dimensions specified in dims.\n\nAlong a dimension d in dims, the size of the output array is sum(size(a,d) for a in A). Along other dimensions, all input arrays should have the same size, which will also be the size of the output array along those dimensions.\n\nIf dims is a single number, the different arrays are tightly packed along that dimension. If dims is an iterable containing several dimensions, the positions along these dimensions are increased simultaneously for each input array, filling with zero elsewhere. This allows one to construct block-diagonal matrices as cat(matrices...; dims=(1,2)), and their higher-dimensional analogues.\n\nThe special case dims=1 is vcat, and dims=2 is hcat. See also hvcat, hvncat, stack, repeat.\n\nThe keyword also accepts Val(dims).\n\ncompat: Julia 1.8\nFor multiple dimensions dims = Val(::Tuple) was added in Julia 1.8.\n\nExamples\n\nConcatenate two arrays in different dimensions:\n\njulia> a = [1 2 3]\n1×3 Matrix{Int64}:\n 1 2 3\n\njulia> b = [4 5 6]\n1×3 Matrix{Int64}:\n 4 5 6\n\njulia> cat(a, b; dims=1)\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> cat(a, b; dims=2)\n1×6 Matrix{Int64}:\n 1 2 3 4 5 6\n\njulia> cat(a, b; dims=(1, 2))\n2×6 Matrix{Int64}:\n 1 2 3 0 0 0\n 0 0 0 4 5 6\n\nExtended Help\n\nConcatenate 3D arrays:\n\njulia> a = ones(2, 2, 3);\n\njulia> b = ones(2, 2, 4);\n\njulia> c = cat(a, b; dims=3);\n\njulia> size(c) == (2, 2, 7)\ntrue\n\nConcatenate arrays of different sizes:\n\njulia> cat([1 2; 3 4], [pi, pi], fill(10, 2,3,1); dims=2) # same as hcat\n2×6×1 Array{Float64, 3}:\n[:, :, 1] =\n 1.0 2.0 3.14159 10.0 10.0 10.0\n 3.0 4.0 3.14159 10.0 10.0 10.0\n\nConstruct a block diagonal matrix:\n\njulia> cat(true, trues(2,2), trues(4)', dims=(1,2)) # block-diagonal\n4×7 Matrix{Bool}:\n 1 0 0 0 0 0 0\n 0 1 1 0 0 0 0\n 0 1 1 0 0 0 0\n 0 0 0 1 1 1 1\n\njulia> cat(1, [2], [3;;]; dims=Val(2))\n1×3 Matrix{Int64}:\n 1 2 3\n\nnote: Note\ncat does not join two strings, you may want to use *.\n\njulia> a = \"aaa\";\n\njulia> b = \"bbb\";\n\njulia> cat(a, b; dims=1)\n2-element Vector{String}:\n \"aaa\"\n \"bbb\"\n\njulia> cat(a, b; dims=2)\n1×2 Matrix{String}:\n \"aaa\" \"bbb\"\n\njulia> a * b\n\"aaabbb\"\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.vcat","page":"Arrays","title":"Base.vcat","text":"vcat(A...)\n\nConcatenate arrays or numbers vertically. Equivalent to cat(A...; dims=1), and to the syntax [a; b; c].\n\nTo concatenate a large vector of arrays, reduce(vcat, A) calls an efficient method when A isa AbstractVector{<:AbstractVecOrMat}, rather than working pairwise.\n\nSee also hcat, Iterators.flatten, stack.\n\nExamples\n\njulia> v = vcat([1,2], [3,4])\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> v == vcat(1, 2, [3,4]) # accepts numbers\ntrue\n\njulia> v == [1; 2; [3,4]] # syntax for the same operation\ntrue\n\njulia> summary(ComplexF64[1; 2; [3,4]]) # syntax for supplying the element type\n\"4-element Vector{ComplexF64}\"\n\njulia> vcat(range(1, 2, length=3)) # collects lazy ranges\n3-element Vector{Float64}:\n 1.0\n 1.5\n 2.0\n\njulia> two = ([10, 20, 30]', Float64[4 5 6; 7 8 9]) # row vector and a matrix\n([10 20 30], [4.0 5.0 6.0; 7.0 8.0 9.0])\n\njulia> vcat(two...)\n3×3 Matrix{Float64}:\n 10.0 20.0 30.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> vs = [[1, 2], [3, 4], [5, 6]];\n\njulia> reduce(vcat, vs) # more efficient than vcat(vs...)\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\njulia> ans == collect(Iterators.flatten(vs))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.hcat","page":"Arrays","title":"Base.hcat","text":"hcat(A...)\n\nConcatenate arrays or numbers horizontally. Equivalent to cat(A...; dims=2), and to the syntax [a b c] or [a;; b;; c].\n\nFor a large vector of arrays, reduce(hcat, A) calls an efficient method when A isa AbstractVector{<:AbstractVecOrMat}. For a vector of vectors, this can also be written stack(A).\n\nSee also vcat, hvcat.\n\nExamples\n\njulia> hcat([1,2], [3,4], [5,6])\n2×3 Matrix{Int64}:\n 1 3 5\n 2 4 6\n\njulia> hcat(1, 2, [30 40], [5, 6, 7]') # accepts numbers\n1×7 Matrix{Int64}:\n 1 2 30 40 5 6 7\n\njulia> ans == [1 2 [30 40] [5, 6, 7]'] # syntax for the same operation\ntrue\n\njulia> Float32[1 2 [30 40] [5, 6, 7]'] # syntax for supplying the eltype\n1×7 Matrix{Float32}:\n 1.0 2.0 30.0 40.0 5.0 6.0 7.0\n\njulia> ms = [zeros(2,2), [1 2; 3 4], [50 60; 70 80]];\n\njulia> reduce(hcat, ms) # more efficient than hcat(ms...)\n2×6 Matrix{Float64}:\n 0.0 0.0 1.0 2.0 50.0 60.0\n 0.0 0.0 3.0 4.0 70.0 80.0\n\njulia> stack(ms) |> summary # disagrees on a vector of matrices\n\"2×2×3 Array{Float64, 3}\"\n\njulia> hcat(Int[], Int[], Int[]) # empty vectors, each of size (0,)\n0×3 Matrix{Int64}\n\njulia> hcat([1.1, 9.9], Matrix(undef, 2, 0)) # hcat with empty 2×0 Matrix\n2×1 Matrix{Any}:\n 1.1\n 9.9\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.hvcat","page":"Arrays","title":"Base.hvcat","text":"hvcat(blocks_per_row::Union{Tuple{Vararg{Int}}, Int}, values...)\n\nHorizontal and vertical concatenation in one call. This function is called for block matrix syntax. The first argument specifies the number of arguments to concatenate in each block row. If the first argument is a single integer n, then all block rows are assumed to have n block columns.\n\nExamples\n\njulia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6\n(1, 2, 3, 4, 5, 6)\n\njulia> [a b c; d e f]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> hvcat((3,3), a,b,c,d,e,f)\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> [a b; c d; e f]\n3×2 Matrix{Int64}:\n 1 2\n 3 4\n 5 6\n\njulia> hvcat((2,2,2), a,b,c,d,e,f)\n3×2 Matrix{Int64}:\n 1 2\n 3 4\n 5 6\njulia> hvcat((2,2,2), a,b,c,d,e,f) == hvcat(2, a,b,c,d,e,f)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.hvncat","page":"Arrays","title":"Base.hvncat","text":"hvncat(dim::Int, row_first, values...)\nhvncat(dims::Tuple{Vararg{Int}}, row_first, values...)\nhvncat(shape::Tuple{Vararg{Tuple}}, row_first, values...)\n\nHorizontal, vertical, and n-dimensional concatenation of many values in one call.\n\nThis function is called for block matrix syntax. The first argument either specifies the shape of the concatenation, similar to hvcat, as a tuple of tuples, or the dimensions that specify the key number of elements along each axis, and is used to determine the output dimensions. The dims form is more performant, and is used by default when the concatenation operation has the same number of elements along each axis (e.g., [a b; c d;;; e f ; g h]). The shape form is used when the number of elements along each axis is unbalanced (e.g., [a b ; c]). Unbalanced syntax needs additional validation overhead. The dim form is an optimization for concatenation along just one dimension. row_first indicates how values are ordered. The meaning of the first and second elements of shape are also swapped based on row_first.\n\nExamples\n\njulia> a, b, c, d, e, f = 1, 2, 3, 4, 5, 6\n(1, 2, 3, 4, 5, 6)\n\njulia> [a b c;;; d e f]\n1×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 2 3\n\n[:, :, 2] =\n 4 5 6\n\njulia> hvncat((2,1,3), false, a,b,c,d,e,f)\n2×1×3 Array{Int64, 3}:\n[:, :, 1] =\n 1\n 2\n\n[:, :, 2] =\n 3\n 4\n\n[:, :, 3] =\n 5\n 6\n\njulia> [a b;;; c d;;; e f]\n1×2×3 Array{Int64, 3}:\n[:, :, 1] =\n 1 2\n\n[:, :, 2] =\n 3 4\n\n[:, :, 3] =\n 5 6\n\njulia> hvncat(((3, 3), (3, 3), (6,)), true, a, b, c, d, e, f)\n1×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 2 3\n\n[:, :, 2] =\n 4 5 6\n\nExamples for construction of the arguments\n\n[a b c ; d e f ;;;\n g h i ; j k l ;;;\n m n o ; p q r ;;;\n s t u ; v w x]\n⇒ dims = (2, 3, 4)\n\n[a b ; c ;;; d ;;;;]\n ___ _ _\n 2 1 1 = elements in each row (2, 1, 1)\n _______ _\n 3 1 = elements in each column (3, 1)\n _____________\n 4 = elements in each 3d slice (4,)\n _____________\n 4 = elements in each 4d slice (4,)\n⇒ shape = ((2, 1, 1), (3, 1), (4,), (4,)) with `row_first` = true\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.stack","page":"Arrays","title":"Base.stack","text":"stack(iter; [dims])\n\nCombine a collection of arrays (or other iterable objects) of equal size into one larger array, by arranging them along one or more new dimensions.\n\nBy default the axes of the elements are placed first, giving size(result) = (size(first(iter))..., size(iter)...). This has the same order of elements as Iterators.flatten(iter).\n\nWith keyword dims::Integer, instead the ith element of iter becomes the slice selectdim(result, dims, i), so that size(result, dims) == length(iter). In this case stack reverses the action of eachslice with the same dims.\n\nThe various cat functions also combine arrays. However, these all extend the arrays' existing (possibly trivial) dimensions, rather than placing the arrays along new dimensions. They also accept arrays as separate arguments, rather than a single collection.\n\ncompat: Julia 1.9\nThis function requires at least Julia 1.9.\n\nExamples\n\njulia> vecs = (1:2, [30, 40], Float32[500, 600]);\n\njulia> mat = stack(vecs)\n2×3 Matrix{Float32}:\n 1.0 30.0 500.0\n 2.0 40.0 600.0\n\njulia> mat == hcat(vecs...) == reduce(hcat, collect(vecs))\ntrue\n\njulia> vec(mat) == vcat(vecs...) == reduce(vcat, collect(vecs))\ntrue\n\njulia> stack(zip(1:4, 10:99)) # accepts any iterators of iterators\n2×4 Matrix{Int64}:\n 1 2 3 4\n 10 11 12 13\n\njulia> vec(ans) == collect(Iterators.flatten(zip(1:4, 10:99)))\ntrue\n\njulia> stack(vecs; dims=1) # unlike any cat function, 1st axis of vecs[1] is 2nd axis of result\n3×2 Matrix{Float32}:\n 1.0 2.0\n 30.0 40.0\n 500.0 600.0\n\njulia> x = rand(3,4);\n\njulia> x == stack(eachcol(x)) == stack(eachrow(x), dims=1) # inverse of eachslice\ntrue\n\nHigher-dimensional examples:\n\njulia> A = rand(5, 7, 11);\n\njulia> E = eachslice(A, dims=2); # a vector of matrices\n\njulia> (element = size(first(E)), container = size(E))\n(element = (5, 11), container = (7,))\n\njulia> stack(E) |> size\n(5, 11, 7)\n\njulia> stack(E) == stack(E; dims=3) == cat(E...; dims=3)\ntrue\n\njulia> A == stack(E; dims=2)\ntrue\n\njulia> M = (fill(10i+j, 2, 3) for i in 1:5, j in 1:7);\n\njulia> (element = size(first(M)), container = size(M))\n(element = (2, 3), container = (5, 7))\n\njulia> stack(M) |> size # keeps all dimensions\n(2, 3, 5, 7)\n\njulia> stack(M; dims=1) |> size # vec(container) along dims=1\n(35, 2, 3)\n\njulia> hvcat(5, M...) |> size # hvcat puts matrices next to each other\n(14, 15)\n\n\n\n\n\nstack(f, args...; [dims])\n\nApply a function to each element of a collection, and stack the result. Or to several collections, zipped together.\n\nThe function should return arrays (or tuples, or other iterators) all of the same size. These become slices of the result, each separated along dims (if given) or by default along the last dimensions.\n\nSee also mapslices, eachcol.\n\nExamples\n\njulia> stack(c -> (c, c-32), \"julia\")\n2×5 Matrix{Char}:\n 'j' 'u' 'l' 'i' 'a'\n 'J' 'U' 'L' 'I' 'A'\n\njulia> stack(eachrow([1 2 3; 4 5 6]), (10, 100); dims=1) do row, n\n vcat(row, row .* n, row ./ n)\n end\n2×9 Matrix{Float64}:\n 1.0 2.0 3.0 10.0 20.0 30.0 0.1 0.2 0.3\n 4.0 5.0 6.0 400.0 500.0 600.0 0.04 0.05 0.06\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.vect","page":"Arrays","title":"Base.vect","text":"vect(X...)\n\nCreate a Vector with element type computed from the promote_typeof of the argument, containing the argument list.\n\nExamples\n\njulia> a = Base.vect(UInt8(1), 2.5, 1//2)\n3-element Vector{Float64}:\n 1.0\n 2.5\n 0.5\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.circshift","page":"Arrays","title":"Base.circshift","text":"circshift(A, shifts)\n\nCircularly shift, i.e. rotate, the data in A. The second argument is a tuple or vector giving the amount to shift in each dimension, or an integer to shift only in the first dimension.\n\nThe generated code is most efficient when the shift amounts are known at compile-time, i.e., compile-time constants.\n\nSee also: circshift!, circcopy!, bitrotate, <<.\n\nExamples\n\njulia> b = reshape(Vector(1:16), (4,4))\n4×4 Matrix{Int64}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> circshift(b, (0,2))\n4×4 Matrix{Int64}:\n 9 13 1 5\n 10 14 2 6\n 11 15 3 7\n 12 16 4 8\n\njulia> circshift(b, (-1,0))\n4×4 Matrix{Int64}:\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n 1 5 9 13\n\njulia> a = BitArray([true, true, false, false, true])\n5-element BitVector:\n 1\n 1\n 0\n 0\n 1\n\njulia> circshift(a, 1)\n5-element BitVector:\n 1\n 1\n 1\n 0\n 0\n\njulia> circshift(a, -1)\n5-element BitVector:\n 1\n 0\n 0\n 1\n 1\n\njulia> x = (1, 2, 3, 4, 5)\n(1, 2, 3, 4, 5)\n\njulia> circshift(x, 4)\n(2, 3, 4, 5, 1)\n\njulia> z = (1, 'a', -7.0, 3)\n(1, 'a', -7.0, 3)\n\njulia> circshift(z, -1)\n('a', -7.0, 3, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.circshift!","page":"Arrays","title":"Base.circshift!","text":"circshift!(dest, src, shifts)\n\nCircularly shift, i.e. rotate, the data in src, storing the result in dest. shifts specifies the amount to shift in each dimension.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also circshift.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.circcopy!","page":"Arrays","title":"Base.circcopy!","text":"circcopy!(dest, src)\n\nCopy src to dest, indexing each dimension modulo its length. src and dest must have the same size, but can be offset in their indices; any offset results in a (circular) wraparound. If the arrays have overlapping indices, then on the domain of the overlap dest agrees with src.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also: circshift.\n\nExamples\n\njulia> src = reshape(Vector(1:16), (4,4))\n4×4 Array{Int64,2}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> dest = OffsetArray{Int}(undef, (0:3,2:5))\n\njulia> circcopy!(dest, src)\nOffsetArrays.OffsetArray{Int64,2,Array{Int64,2}} with indices 0:3×2:5:\n 8 12 16 4\n 5 9 13 1\n 6 10 14 2\n 7 11 15 3\n\njulia> dest[1:3,2:4] == src[1:3,2:4]\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.findall-Tuple{Any}","page":"Arrays","title":"Base.findall","text":"findall(A)\n\nReturn a vector I of the true indices or keys of A. If there are no such elements of A, return an empty array. To search for other kinds of values, pass a predicate as the first argument.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nSee also: findfirst, searchsorted.\n\nExamples\n\njulia> A = [true, false, false, true]\n4-element Vector{Bool}:\n 1\n 0\n 0\n 1\n\njulia> findall(A)\n2-element Vector{Int64}:\n 1\n 4\n\njulia> A = [true false; false true]\n2×2 Matrix{Bool}:\n 1 0\n 0 1\n\njulia> findall(A)\n2-element Vector{CartesianIndex{2}}:\n CartesianIndex(1, 1)\n CartesianIndex(2, 2)\n\njulia> findall(falses(3))\nInt64[]\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findall-Tuple{Function, Any}","page":"Arrays","title":"Base.findall","text":"findall(f::Function, A)\n\nReturn a vector I of the indices or keys of A where f(A[I]) returns true. If there are no such elements of A, return an empty array.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> x = [1, 3, 4]\n3-element Vector{Int64}:\n 1\n 3\n 4\n\njulia> findall(isodd, x)\n2-element Vector{Int64}:\n 1\n 2\n\njulia> A = [1 2 0; 3 4 0]\n2×3 Matrix{Int64}:\n 1 2 0\n 3 4 0\njulia> findall(isodd, A)\n2-element Vector{CartesianIndex{2}}:\n CartesianIndex(1, 1)\n CartesianIndex(2, 1)\n\njulia> findall(!iszero, A)\n4-element Vector{CartesianIndex{2}}:\n CartesianIndex(1, 1)\n CartesianIndex(2, 1)\n CartesianIndex(1, 2)\n CartesianIndex(2, 2)\n\njulia> d = Dict(:A => 10, :B => -1, :C => 0)\nDict{Symbol, Int64} with 3 entries:\n :A => 10\n :B => -1\n :C => 0\n\njulia> findall(≥(0), d)\n2-element Vector{Symbol}:\n :A\n :C\n\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findfirst-Tuple{Any}","page":"Arrays","title":"Base.findfirst","text":"findfirst(A)\n\nReturn the index or key of the first true value in A. Return nothing if no such value is found. To search for other kinds of values, pass a predicate as the first argument.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nSee also: findall, findnext, findlast, searchsortedfirst.\n\nExamples\n\njulia> A = [false, false, true, false]\n4-element Vector{Bool}:\n 0\n 0\n 1\n 0\n\njulia> findfirst(A)\n3\n\njulia> findfirst(falses(3)) # returns nothing, but not printed in the REPL\n\njulia> A = [false false; true false]\n2×2 Matrix{Bool}:\n 0 0\n 1 0\n\njulia> findfirst(A)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findfirst-Tuple{Function, Any}","page":"Arrays","title":"Base.findfirst","text":"findfirst(predicate::Function, A)\n\nReturn the index or key of the first element of A for which predicate returns true. Return nothing if there is no such element.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [1, 4, 2, 2]\n4-element Vector{Int64}:\n 1\n 4\n 2\n 2\n\njulia> findfirst(iseven, A)\n2\n\njulia> findfirst(x -> x>10, A) # returns nothing, but not printed in the REPL\n\njulia> findfirst(isequal(4), A)\n2\n\njulia> A = [1 4; 2 2]\n2×2 Matrix{Int64}:\n 1 4\n 2 2\n\njulia> findfirst(iseven, A)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findlast-Tuple{Any}","page":"Arrays","title":"Base.findlast","text":"findlast(A)\n\nReturn the index or key of the last true value in A. Return nothing if there is no true value in A.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nSee also: findfirst, findprev, findall.\n\nExamples\n\njulia> A = [true, false, true, false]\n4-element Vector{Bool}:\n 1\n 0\n 1\n 0\n\njulia> findlast(A)\n3\n\njulia> A = falses(2,2);\n\njulia> findlast(A) # returns nothing, but not printed in the REPL\n\njulia> A = [true false; true false]\n2×2 Matrix{Bool}:\n 1 0\n 1 0\n\njulia> findlast(A)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findlast-Tuple{Function, Any}","page":"Arrays","title":"Base.findlast","text":"findlast(predicate::Function, A)\n\nReturn the index or key of the last element of A for which predicate returns true. Return nothing if there is no such element.\n\nIndices or keys are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> findlast(isodd, A)\n3\n\njulia> findlast(x -> x > 5, A) # returns nothing, but not printed in the REPL\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> findlast(isodd, A)\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findnext-Tuple{Any, Integer}","page":"Arrays","title":"Base.findnext","text":"findnext(A, i)\n\nFind the next index after or including i of a true element of A, or nothing if not found.\n\nIndices are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [false, false, true, false]\n4-element Vector{Bool}:\n 0\n 0\n 1\n 0\n\njulia> findnext(A, 1)\n3\n\njulia> findnext(A, 4) # returns nothing, but not printed in the REPL\n\njulia> A = [false false; true false]\n2×2 Matrix{Bool}:\n 0 0\n 1 0\n\njulia> findnext(A, CartesianIndex(1, 1))\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findnext-Tuple{Function, Any, Integer}","page":"Arrays","title":"Base.findnext","text":"findnext(predicate::Function, A, i)\n\nFind the next index after or including i of an element of A for which predicate returns true, or nothing if not found. This works for Arrays, Strings, and most other collections that support getindex, keys(A), and nextind.\n\nIndices are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [1, 4, 2, 2];\n\njulia> findnext(isodd, A, 1)\n1\n\njulia> findnext(isodd, A, 2) # returns nothing, but not printed in the REPL\n\njulia> A = [1 4; 2 2];\n\njulia> findnext(isodd, A, CartesianIndex(1, 1))\nCartesianIndex(1, 1)\n\njulia> findnext(isspace, \"a b c\", 3)\n4\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findprev-Tuple{Any, Integer}","page":"Arrays","title":"Base.findprev","text":"findprev(A, i)\n\nFind the previous index before or including i of a true element of A, or nothing if not found.\n\nIndices are of the same type as those returned by keys(A) and pairs(A).\n\nSee also: findnext, findfirst, findall.\n\nExamples\n\njulia> A = [false, false, true, true]\n4-element Vector{Bool}:\n 0\n 0\n 1\n 1\n\njulia> findprev(A, 3)\n3\n\njulia> findprev(A, 1) # returns nothing, but not printed in the REPL\n\njulia> A = [false false; true true]\n2×2 Matrix{Bool}:\n 0 0\n 1 1\n\njulia> findprev(A, CartesianIndex(2, 1))\nCartesianIndex(2, 1)\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.findprev-Tuple{Function, Any, Integer}","page":"Arrays","title":"Base.findprev","text":"findprev(predicate::Function, A, i)\n\nFind the previous index before or including i of an element of A for which predicate returns true, or nothing if not found. This works for Arrays, Strings, and most other collections that support getindex, keys(A), and nextind.\n\nIndices are of the same type as those returned by keys(A) and pairs(A).\n\nExamples\n\njulia> A = [4, 6, 1, 2]\n4-element Vector{Int64}:\n 4\n 6\n 1\n 2\n\njulia> findprev(isodd, A, 1) # returns nothing, but not printed in the REPL\n\njulia> findprev(isodd, A, 3)\n3\n\njulia> A = [4 6; 1 2]\n2×2 Matrix{Int64}:\n 4 6\n 1 2\n\njulia> findprev(isodd, A, CartesianIndex(1, 2))\nCartesianIndex(2, 1)\n\njulia> findprev(isspace, \"a b c\", 3)\n2\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.permutedims","page":"Arrays","title":"Base.permutedims","text":"permutedims(A::AbstractArray, perm)\npermutedims(A::AbstractMatrix)\n\nPermute the dimensions (axes) of array A. perm is a tuple or vector of ndims(A) integers specifying the permutation.\n\nIf A is a 2d array (AbstractMatrix), then perm defaults to (2,1), swapping the two axes of A (the rows and columns of the matrix). This differs from transpose in that the operation is not recursive, which is especially useful for arrays of non-numeric values (where the recursive transpose would throw an error) and/or 2d arrays that do not represent linear operators.\n\nFor 1d arrays, see permutedims(v::AbstractVector), which returns a 1-row “matrix”.\n\nSee also permutedims!, PermutedDimsArray, transpose, invperm.\n\nExamples\n\n2d arrays:\n\nUnlike transpose, permutedims can be used to swap rows and columns of 2d arrays of arbitrary non-numeric elements, such as strings:\n\njulia> A = [\"a\" \"b\" \"c\"\n \"d\" \"e\" \"f\"]\n2×3 Matrix{String}:\n \"a\" \"b\" \"c\"\n \"d\" \"e\" \"f\"\n\njulia> permutedims(A)\n3×2 Matrix{String}:\n \"a\" \"d\"\n \"b\" \"e\"\n \"c\" \"f\"\n\nAnd permutedims produces results that differ from transpose for matrices whose elements are themselves numeric matrices:\n\njulia> a = [1 2; 3 4];\n\njulia> b = [5 6; 7 8];\n\njulia> c = [9 10; 11 12];\n\njulia> d = [13 14; 15 16];\n\njulia> X = [[a] [b]; [c] [d]]\n2×2 Matrix{Matrix{Int64}}:\n [1 2; 3 4] [5 6; 7 8]\n [9 10; 11 12] [13 14; 15 16]\n\njulia> permutedims(X)\n2×2 Matrix{Matrix{Int64}}:\n [1 2; 3 4] [9 10; 11 12]\n [5 6; 7 8] [13 14; 15 16]\n\njulia> transpose(X)\n2×2 transpose(::Matrix{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:\n [1 3; 2 4] [9 11; 10 12]\n [5 7; 6 8] [13 15; 14 16]\n\nMulti-dimensional arrays\n\njulia> A = reshape(Vector(1:8), (2,2,2))\n2×2×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 3\n 2 4\n\n[:, :, 2] =\n 5 7\n 6 8\n\njulia> perm = (3, 1, 2); # put the last dimension first\n\njulia> B = permutedims(A, perm)\n2×2×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 2\n 5 6\n\n[:, :, 2] =\n 3 4\n 7 8\n\njulia> A == permutedims(B, invperm(perm)) # the inverse permutation\ntrue\n\nFor each dimension i of B = permutedims(A, perm), its corresponding dimension of A will be perm[i]. This means the equality size(B, i) == size(A, perm[i]) holds.\n\njulia> A = randn(5, 7, 11, 13);\n\njulia> perm = [4, 1, 3, 2];\n\njulia> B = permutedims(A, perm);\n\njulia> size(B)\n(13, 5, 11, 7)\n\njulia> size(A)[perm] == ans\ntrue\n\n\n\n\n\npermutedims(v::AbstractVector)\n\nReshape vector v into a 1 × length(v) row matrix. Differs from transpose in that the operation is not recursive, which is especially useful for arrays of non-numeric values (where the recursive transpose might throw an error).\n\nExamples\n\nUnlike transpose, permutedims can be used on vectors of arbitrary non-numeric elements, such as strings:\n\njulia> permutedims([\"a\", \"b\", \"c\"])\n1×3 Matrix{String}:\n \"a\" \"b\" \"c\"\n\nFor vectors of numbers, permutedims(v) works much like transpose(v) except that the return type differs (it uses reshape rather than a LinearAlgebra.Transpose view, though both share memory with the original array v):\n\njulia> v = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> p = permutedims(v)\n1×4 Matrix{Int64}:\n 1 2 3 4\n\njulia> r = transpose(v)\n1×4 transpose(::Vector{Int64}) with eltype Int64:\n 1 2 3 4\n\njulia> p == r\ntrue\n\njulia> typeof(r)\nTranspose{Int64, Vector{Int64}}\n\njulia> p[1] = 5; r[2] = 6; # mutating p or r also changes v\n\njulia> v # shares memory with both p and r\n4-element Vector{Int64}:\n 5\n 6\n 3\n 4\n\nHowever, permutedims produces results that differ from transpose for vectors whose elements are themselves numeric matrices:\n\njulia> V = [[[1 2; 3 4]]; [[5 6; 7 8]]]\n2-element Vector{Matrix{Int64}}:\n [1 2; 3 4]\n [5 6; 7 8]\n\njulia> permutedims(V)\n1×2 Matrix{Matrix{Int64}}:\n [1 2; 3 4] [5 6; 7 8]\n\njulia> transpose(V)\n1×2 transpose(::Vector{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:\n [1 3; 2 4] [5 7; 6 8]\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.permutedims!","page":"Arrays","title":"Base.permutedims!","text":"permutedims!(dest, src, perm)\n\nPermute the dimensions of array src and store the result in the array dest. perm is a vector specifying a permutation of length ndims(src). The preallocated array dest should have size(dest) == size(src)[perm] and is completely overwritten. No in-place permutation is supported and unexpected results will happen if src and dest have overlapping memory regions.\n\nSee also permutedims.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.PermutedDimsArrays.PermutedDimsArray","page":"Arrays","title":"Base.PermutedDimsArrays.PermutedDimsArray","text":"PermutedDimsArray(A, perm) -> B\n\nGiven an AbstractArray A, create a view B such that the dimensions appear to be permuted. Similar to permutedims, except that no copying occurs (B shares storage with A).\n\nSee also permutedims, invperm.\n\nExamples\n\njulia> A = rand(3,5,4);\n\njulia> B = PermutedDimsArray(A, (3,1,2));\n\njulia> size(B)\n(4, 3, 5)\n\njulia> B[3,1,2] == A[1,2,3]\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/arrays/#Base.promote_shape","page":"Arrays","title":"Base.promote_shape","text":"promote_shape(s1, s2)\n\nCheck two array shapes for compatibility, allowing trailing singleton dimensions, and return whichever shape has more dimensions.\n\nExamples\n\njulia> a = fill(1, (3,4,1,1,1));\n\njulia> b = fill(1, (3,4));\n\njulia> promote_shape(a,b)\n(Base.OneTo(3), Base.OneTo(4), Base.OneTo(1), Base.OneTo(1), Base.OneTo(1))\n\njulia> promote_shape((2,3,1,4), (2, 3, 1, 4, 1))\n(2, 3, 1, 4, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Array-functions","page":"Arrays","title":"Array functions","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.accumulate\nBase.accumulate!\nBase.cumprod\nBase.cumprod!\nBase.cumsum\nBase.cumsum!\nBase.diff\nBase.repeat\nBase.rot180\nBase.rotl90\nBase.rotr90\nBase.mapslices\nBase.eachrow\nBase.eachcol\nBase.eachslice","category":"page"},{"location":"base/arrays/#Base.accumulate","page":"Arrays","title":"Base.accumulate","text":"accumulate(op, A; dims::Integer, [init])\n\nCumulative operation op along the dimension dims of A (providing dims is optional for vectors). An initial value init may optionally be provided by a keyword argument. See also accumulate! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).\n\nFor common operations there are specialized variants of accumulate, see cumsum, cumprod. For a lazy version, see Iterators.accumulate.\n\ncompat: Julia 1.5\naccumulate on a non-array iterator requires at least Julia 1.5.\n\nExamples\n\njulia> accumulate(+, [1,2,3])\n3-element Vector{Int64}:\n 1\n 3\n 6\n\njulia> accumulate(min, (1, -2, 3, -4, 5), init=0)\n(0, -2, -2, -4, -4)\n\njulia> accumulate(/, (2, 4, Inf), init=100)\n(50.0, 12.5, 0.0)\n\njulia> accumulate(=>, i^2 for i in 1:3)\n3-element Vector{Any}:\n 1\n 1 => 4\n (1 => 4) => 9\n\njulia> accumulate(+, fill(1, 3, 4))\n3×4 Matrix{Int64}:\n 1 4 7 10\n 2 5 8 11\n 3 6 9 12\n\njulia> accumulate(+, fill(1, 2, 5), dims=2, init=100.0)\n2×5 Matrix{Float64}:\n 101.0 102.0 103.0 104.0 105.0\n 101.0 102.0 103.0 104.0 105.0\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.accumulate!","page":"Arrays","title":"Base.accumulate!","text":"accumulate!(op, B, A; [dims], [init])\n\nCumulative operation op on A along the dimension dims, storing the result in B. Providing dims is optional for vectors. If the keyword argument init is given, its value is used to instantiate the accumulation.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also accumulate, cumsum!, cumprod!.\n\nExamples\n\njulia> x = [1, 0, 2, 0, 3];\n\njulia> y = rand(5);\n\njulia> accumulate!(+, y, x);\n\njulia> y\n5-element Vector{Float64}:\n 1.0\n 1.0\n 3.0\n 3.0\n 6.0\n\njulia> A = [1 2 3; 4 5 6];\n\njulia> B = similar(A);\n\njulia> accumulate!(-, B, A, dims=1)\n2×3 Matrix{Int64}:\n 1 2 3\n -3 -3 -3\n\njulia> accumulate!(*, B, A, dims=2, init=10)\n2×3 Matrix{Int64}:\n 10 20 60\n 40 200 1200\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.cumprod","page":"Arrays","title":"Base.cumprod","text":"cumprod(A; dims::Integer)\n\nCumulative product along the dimension dim. See also cumprod! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).\n\nExamples\n\njulia> a = Int8[1 2 3; 4 5 6];\n\njulia> cumprod(a, dims=1)\n2×3 Matrix{Int64}:\n 1 2 3\n 4 10 18\n\njulia> cumprod(a, dims=2)\n2×3 Matrix{Int64}:\n 1 2 6\n 4 20 120\n\n\n\n\n\ncumprod(itr)\n\nCumulative product of an iterator.\n\nSee also cumprod!, accumulate, cumsum.\n\ncompat: Julia 1.5\ncumprod on a non-array iterator requires at least Julia 1.5.\n\nExamples\n\njulia> cumprod(fill(1//2, 3))\n3-element Vector{Rational{Int64}}:\n 1//2\n 1//4\n 1//8\n\njulia> cumprod((1, 2, 1, 3, 1))\n(1, 2, 2, 6, 6)\n\njulia> cumprod(\"julia\")\n5-element Vector{String}:\n \"j\"\n \"ju\"\n \"jul\"\n \"juli\"\n \"julia\"\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.cumprod!","page":"Arrays","title":"Base.cumprod!","text":"cumprod!(B, A; dims::Integer)\n\nCumulative product of A along the dimension dims, storing the result in B. See also cumprod.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\ncumprod!(y::AbstractVector, x::AbstractVector)\n\nCumulative product of a vector x, storing the result in y. See also cumprod.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.cumsum","page":"Arrays","title":"Base.cumsum","text":"cumsum(A; dims::Integer)\n\nCumulative sum along the dimension dims. See also cumsum! to use a preallocated output array, both for performance and to control the precision of the output (e.g. to avoid overflow).\n\nExamples\n\njulia> a = [1 2 3; 4 5 6]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> cumsum(a, dims=1)\n2×3 Matrix{Int64}:\n 1 2 3\n 5 7 9\n\njulia> cumsum(a, dims=2)\n2×3 Matrix{Int64}:\n 1 3 6\n 4 9 15\n\nnote: Note\nThe return array's eltype is Int for signed integers of less than system word size and UInt for unsigned integers of less than system word size. To preserve eltype of arrays with small signed or unsigned integer accumulate(+, A) should be used.julia> cumsum(Int8[100, 28])\n2-element Vector{Int64}:\n 100\n 128\n\njulia> accumulate(+,Int8[100, 28])\n2-element Vector{Int8}:\n 100\n -128In the former case, the integers are widened to system word size and therefore the result is Int64[100, 128]. In the latter case, no such widening happens and integer overflow results in Int8[100, -128].\n\n\n\n\n\ncumsum(itr)\n\nCumulative sum of an iterator.\n\nSee also accumulate to apply functions other than +.\n\ncompat: Julia 1.5\ncumsum on a non-array iterator requires at least Julia 1.5.\n\nExamples\n\njulia> cumsum(1:3)\n3-element Vector{Int64}:\n 1\n 3\n 6\n\njulia> cumsum((true, false, true, false, true))\n(1, 1, 2, 2, 3)\n\njulia> cumsum(fill(1, 2) for i in 1:3)\n3-element Vector{Vector{Int64}}:\n [1, 1]\n [2, 2]\n [3, 3]\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.cumsum!","page":"Arrays","title":"Base.cumsum!","text":"cumsum!(B, A; dims::Integer)\n\nCumulative sum of A along the dimension dims, storing the result in B. See also cumsum.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.diff","page":"Arrays","title":"Base.diff","text":"diff(A::AbstractVector)\ndiff(A::AbstractArray; dims::Integer)\n\nFinite difference operator on a vector or a multidimensional array A. In the latter case the dimension to operate on needs to be specified with the dims keyword argument.\n\ncompat: Julia 1.1\ndiff for arrays with dimension higher than 2 requires at least Julia 1.1.\n\nExamples\n\njulia> a = [2 4; 6 16]\n2×2 Matrix{Int64}:\n 2 4\n 6 16\n\njulia> diff(a, dims=2)\n2×1 Matrix{Int64}:\n 2\n 10\n\njulia> diff(vec(a))\n3-element Vector{Int64}:\n 4\n -2\n 12\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.repeat","page":"Arrays","title":"Base.repeat","text":"repeat(A::AbstractArray, counts::Integer...)\n\nConstruct an array by repeating array A a given number of times in each dimension, specified by counts.\n\nSee also: fill, Iterators.repeated, Iterators.cycle.\n\nExamples\n\njulia> repeat([1, 2, 3], 2)\n6-element Vector{Int64}:\n 1\n 2\n 3\n 1\n 2\n 3\n\njulia> repeat([1, 2, 3], 2, 3)\n6×3 Matrix{Int64}:\n 1 1 1\n 2 2 2\n 3 3 3\n 1 1 1\n 2 2 2\n 3 3 3\n\n\n\n\n\nrepeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A)))\n\nConstruct an array by repeating the entries of A. The i-th element of inner specifies the number of times that the individual entries of the i-th dimension of A should be repeated. The i-th element of outer specifies the number of times that a slice along the i-th dimension of A should be repeated. If inner or outer are omitted, no repetition is performed.\n\nExamples\n\njulia> repeat(1:2, inner=2)\n4-element Vector{Int64}:\n 1\n 1\n 2\n 2\n\njulia> repeat(1:2, outer=2)\n4-element Vector{Int64}:\n 1\n 2\n 1\n 2\n\njulia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))\n4×6 Matrix{Int64}:\n 1 2 1 2 1 2\n 1 2 1 2 1 2\n 3 4 3 4 3 4\n 3 4 3 4 3 4\n\n\n\n\n\nrepeat(s::AbstractString, r::Integer)\n\nRepeat a string r times. This can be written as s^r.\n\nSee also ^.\n\nExamples\n\njulia> repeat(\"ha\", 3)\n\"hahaha\"\n\n\n\n\n\nrepeat(c::AbstractChar, r::Integer) -> String\n\nRepeat a character r times. This can equivalently be accomplished by calling c^r.\n\nExamples\n\njulia> repeat('A', 3)\n\"AAA\"\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.rot180","page":"Arrays","title":"Base.rot180","text":"rot180(A)\n\nRotate matrix A 180 degrees.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rot180(a)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\n\n\n\n\nrot180(A, k)\n\nRotate matrix A 180 degrees an integer k number of times. If k is even, this is equivalent to a copy.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rot180(a,1)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\njulia> rot180(a,2)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.rotl90","page":"Arrays","title":"Base.rotl90","text":"rotl90(A)\n\nRotate matrix A left 90 degrees.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rotl90(a)\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\n\n\n\n\nrotl90(A, k)\n\nLeft-rotate matrix A 90 degrees counterclockwise an integer k number of times. If k is a multiple of four (including zero), this is equivalent to a copy.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rotl90(a,1)\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\njulia> rotl90(a,2)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\njulia> rotl90(a,3)\n2×2 Matrix{Int64}:\n 3 1\n 4 2\n\njulia> rotl90(a,4)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.rotr90","page":"Arrays","title":"Base.rotr90","text":"rotr90(A)\n\nRotate matrix A right 90 degrees.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rotr90(a)\n2×2 Matrix{Int64}:\n 3 1\n 4 2\n\n\n\n\n\nrotr90(A, k)\n\nRight-rotate matrix A 90 degrees clockwise an integer k number of times. If k is a multiple of four (including zero), this is equivalent to a copy.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rotr90(a,1)\n2×2 Matrix{Int64}:\n 3 1\n 4 2\n\njulia> rotr90(a,2)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\njulia> rotr90(a,3)\n2×2 Matrix{Int64}:\n 2 4\n 1 3\n\njulia> rotr90(a,4)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.mapslices","page":"Arrays","title":"Base.mapslices","text":"mapslices(f, A; dims)\n\nTransform the given dimensions of array A by applying a function f on each slice of the form A[..., :, ..., :, ...], with a colon at each d in dims. The results are concatenated along the remaining dimensions.\n\nFor example, if dims = [1,2] and A is 4-dimensional, then f is called on x = A[:,:,i,j] for all i and j, and f(x) becomes R[:,:,i,j] in the result R.\n\nSee also eachcol or eachslice, used with map or stack.\n\nExamples\n\njulia> A = reshape(1:30,(2,5,3))\n2×5×3 reshape(::UnitRange{Int64}, 2, 5, 3) with eltype Int64:\n[:, :, 1] =\n 1 3 5 7 9\n 2 4 6 8 10\n\n[:, :, 2] =\n 11 13 15 17 19\n 12 14 16 18 20\n\n[:, :, 3] =\n 21 23 25 27 29\n 22 24 26 28 30\n\njulia> f(x::Matrix) = fill(x[1,1], 1,4); # returns a 1×4 matrix\n\njulia> B = mapslices(f, A, dims=(1,2))\n1×4×3 Array{Int64, 3}:\n[:, :, 1] =\n 1 1 1 1\n\n[:, :, 2] =\n 11 11 11 11\n\n[:, :, 3] =\n 21 21 21 21\n\njulia> f2(x::AbstractMatrix) = fill(x[1,1], 1,4);\n\njulia> B == stack(f2, eachslice(A, dims=3))\ntrue\n\njulia> g(x) = x[begin] // x[end-1]; # returns a number\n\njulia> mapslices(g, A, dims=[1,3])\n1×5×1 Array{Rational{Int64}, 3}:\n[:, :, 1] =\n 1//21 3//23 1//5 7//27 9//29\n\njulia> map(g, eachslice(A, dims=2))\n5-element Vector{Rational{Int64}}:\n 1//21\n 3//23\n 1//5\n 7//27\n 9//29\n\njulia> mapslices(sum, A; dims=(1,3)) == sum(A; dims=(1,3))\ntrue\n\nNotice that in eachslice(A; dims=2), the specified dimension is the one without a colon in the slice. This is view(A,:,i,:), whereas mapslices(f, A; dims=(1,3)) uses A[:,i,:]. The function f may mutate values in the slice without affecting A.\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.eachrow","page":"Arrays","title":"Base.eachrow","text":"eachrow(A::AbstractVecOrMat) <: AbstractVector\n\nCreate a RowSlices object that is a vector of rows of matrix or vector A. Row slices are returned as AbstractVector views of A.\n\nFor the inverse, see stack(rows; dims=1).\n\nSee also eachcol, eachslice and mapslices.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this returned an iterator.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> s = eachrow(a)\n2-element RowSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:\n [1, 2]\n [3, 4]\n\njulia> s[1]\n2-element view(::Matrix{Int64}, 1, :) with eltype Int64:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.eachcol","page":"Arrays","title":"Base.eachcol","text":"eachcol(A::AbstractVecOrMat) <: AbstractVector\n\nCreate a ColumnSlices object that is a vector of columns of matrix or vector A. Column slices are returned as AbstractVector views of A.\n\nFor the inverse, see stack(cols) or reduce(hcat, cols).\n\nSee also eachrow, eachslice and mapslices.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this returned an iterator.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> s = eachcol(a)\n2-element ColumnSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}:\n [1, 3]\n [2, 4]\n\njulia> s[1]\n2-element view(::Matrix{Int64}, :, 1) with eltype Int64:\n 1\n 3\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.eachslice","page":"Arrays","title":"Base.eachslice","text":"eachslice(A::AbstractArray; dims, drop=true)\n\nCreate a Slices object that is an array of slices over dimensions dims of A, returning views that select all the data from the other dimensions in A. dims can either be an integer or a tuple of integers.\n\nIf drop = true (the default), the outer Slices will drop the inner dimensions, and the ordering of the dimensions will match those in dims. If drop = false, then the Slices will have the same dimensionality as the underlying array, with inner dimensions having size 1.\n\nSee stack(slices; dims) for the inverse of eachslice(A; dims::Integer).\n\nSee also eachrow, eachcol, mapslices and selectdim.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this returned an iterator, and only a single dimension dims was supported.\n\nExamples\n\njulia> m = [1 2 3; 4 5 6; 7 8 9]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n 7 8 9\n\njulia> s = eachslice(m, dims=1)\n3-element RowSlices{Matrix{Int64}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}}:\n [1, 2, 3]\n [4, 5, 6]\n [7, 8, 9]\n\njulia> s[1]\n3-element view(::Matrix{Int64}, 1, :) with eltype Int64:\n 1\n 2\n 3\n\njulia> eachslice(m, dims=1, drop=false)\n3×1 Slices{Matrix{Int64}, Tuple{Int64, Colon}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}, 2}:\n [1, 2, 3]\n [4, 5, 6]\n [7, 8, 9]\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Combinatorics","page":"Arrays","title":"Combinatorics","text":"","category":"section"},{"location":"base/arrays/","page":"Arrays","title":"Arrays","text":"Base.invperm\nBase.isperm\nBase.permute!(::Any, ::AbstractVector)\nBase.invpermute!\nBase.reverse(::AbstractVector; kwargs...)\nBase.reverseind\nBase.reverse!","category":"page"},{"location":"base/arrays/#Base.invperm","page":"Arrays","title":"Base.invperm","text":"invperm(v)\n\nReturn the inverse permutation of v. If B = A[v], then A == B[invperm(v)].\n\nSee also sortperm, invpermute!, isperm, permutedims.\n\nExamples\n\njulia> p = (2, 3, 1);\n\njulia> invperm(p)\n(3, 1, 2)\n\njulia> v = [2; 4; 3; 1];\n\njulia> invperm(v)\n4-element Vector{Int64}:\n 4\n 1\n 3\n 2\n\njulia> A = ['a','b','c','d'];\n\njulia> B = A[v]\n4-element Vector{Char}:\n 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)\n 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)\n 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)\n 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> B[invperm(v)]\n4-element Vector{Char}:\n 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)\n 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)\n 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.isperm","page":"Arrays","title":"Base.isperm","text":"isperm(v) -> Bool\n\nReturn true if v is a valid permutation.\n\nExamples\n\njulia> isperm([1; 2])\ntrue\n\njulia> isperm([1; 3])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.permute!-Tuple{Any, AbstractVector}","page":"Arrays","title":"Base.permute!","text":"permute!(v, p)\n\nPermute vector v in-place, according to permutation p. No checking is done to verify that p is a permutation.\n\nTo return a new permutation, use v[p]. This is generally faster than permute!(v, p); it is even faster to write into a pre-allocated output array with u .= @view v[p]. (Even though permute! overwrites v in-place, it internally requires some allocation to keep track of which elements have been moved.)\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also invpermute!.\n\nExamples\n\njulia> A = [1, 1, 3, 4];\n\njulia> perm = [2, 4, 3, 1];\n\njulia> permute!(A, perm);\n\njulia> A\n4-element Vector{Int64}:\n 1\n 4\n 3\n 1\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.invpermute!","page":"Arrays","title":"Base.invpermute!","text":"invpermute!(v, p)\n\nLike permute!, but the inverse of the given permutation is applied.\n\nNote that if you have a pre-allocated output array (e.g. u = similar(v)), it is quicker to instead employ u[p] = v. (invpermute! internally allocates a copy of the data.)\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1, 1, 3, 4];\n\njulia> perm = [2, 4, 3, 1];\n\njulia> invpermute!(A, perm);\n\njulia> A\n4-element Vector{Int64}:\n 4\n 1\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.reverse-Tuple{AbstractVector}","page":"Arrays","title":"Base.reverse","text":"reverse(A; dims=:)\n\nReverse A along dimension dims, which can be an integer (a single dimension), a tuple of integers (a tuple of dimensions) or : (reverse along all the dimensions, the default). See also reverse! for in-place reversal.\n\nExamples\n\njulia> b = Int64[1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> reverse(b, dims=2)\n2×2 Matrix{Int64}:\n 2 1\n 4 3\n\njulia> reverse(b)\n2×2 Matrix{Int64}:\n 4 3\n 2 1\n\ncompat: Julia 1.6\nPrior to Julia 1.6, only single-integer dims are supported in reverse.\n\n\n\n\n\n","category":"method"},{"location":"base/arrays/#Base.reverseind","page":"Arrays","title":"Base.reverseind","text":"reverseind(v, i)\n\nGiven an index i in reverse(v), return the corresponding index in v so that v[reverseind(v,i)] == reverse(v)[i]. (This can be nontrivial in cases where v contains non-ASCII characters.)\n\nExamples\n\njulia> s = \"Julia🚀\"\n\"Julia🚀\"\n\njulia> r = reverse(s)\n\"🚀ailuJ\"\n\njulia> for i in eachindex(s)\n print(r[reverseind(r, i)])\n end\nJulia🚀\n\n\n\n\n\n","category":"function"},{"location":"base/arrays/#Base.reverse!","page":"Arrays","title":"Base.reverse!","text":"reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v\n\nIn-place version of reverse.\n\nExamples\n\njulia> A = Vector(1:5)\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n\njulia> reverse!(A);\n\njulia> A\n5-element Vector{Int64}:\n 5\n 4\n 3\n 2\n 1\n\n\n\n\n\nreverse!(A; dims=:)\n\nLike reverse, but operates in-place in A.\n\ncompat: Julia 1.6\nMultidimensional reverse! requires Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"manual/handling-operating-system-variation/#Handling-Operating-System-Variation","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"","category":"section"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"When writing cross-platform applications or libraries, it is often necessary to allow for differences between operating systems. The variable Sys.KERNEL can be used to handle such cases. There are several functions in the Sys module intended to make this easier, such as isunix, islinux, isapple, isbsd, isfreebsd, and iswindows. These may be used as follows:","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"if Sys.iswindows()\n windows_specific_thing(a)\nend","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"Note that islinux, isapple, and isfreebsd are mutually exclusive subsets of isunix. Additionally, there is a macro @static which makes it possible to use these functions to conditionally hide invalid code, as demonstrated in the following examples.","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"Simple blocks:","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"ccall((@static Sys.iswindows() ? :_fopen : :fopen), ...)","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"Complex blocks:","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"@static if Sys.islinux()\n linux_specific_thing(a)\nelseif Sys.isapple()\n apple_specific_thing(a)\nelse\n generic_thing(a)\nend","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"When nesting conditionals, the @static must be repeated for each level (parentheses optional, but recommended for readability):","category":"page"},{"location":"manual/handling-operating-system-variation/","page":"Handling Operating System Variation","title":"Handling Operating System Variation","text":"@static Sys.iswindows() ? :a : (@static Sys.isapple() ? :b : :c)","category":"page"},{"location":"manual/performance-tips/#man-performance-tips","page":"Performance Tips","title":"Performance Tips","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In the following sections, we briefly go through a few techniques that can help make your Julia code run as fast as possible.","category":"page"},{"location":"manual/performance-tips/#Performance-critical-code-should-be-inside-a-function","page":"Performance Tips","title":"Performance critical code should be inside a function","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Any code that is performance critical should be inside a function. Code inside functions tends to run much faster than top level code, due to how Julia's compiler works.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The use of functions is not only important for performance: functions are more reusable and testable, and clarify what steps are being done and what their inputs and outputs are, Write functions, not just scripts is also a recommendation of Julia's Styleguide.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The functions should take arguments, instead of operating directly on global variables, see the next point.","category":"page"},{"location":"manual/performance-tips/#Avoid-untyped-global-variables","page":"Performance Tips","title":"Avoid untyped global variables","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The value of an untyped global variable might change at any point, possibly leading to a change of its type. This makes it difficult for the compiler to optimize code using global variables. This also applies to type-valued variables, i.e. type aliases on the global level. Variables should be local, or passed as arguments to functions, whenever possible.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"We find that global names are frequently constants, and declaring them as such greatly improves performance:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"const DEFAULT_VAL = 0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If a global is known to always be of the same type, the type should be annotated.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Uses of untyped globals can be optimized by annotating their types at the point of use:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"global x = rand(1000)\n\nfunction loop_over_global()\n s = 0.0\n for i in x::Vector{Float64}\n s += i\n end\n return s\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Passing arguments to functions is better style. It leads to more reusable code and clarifies what the inputs and outputs are.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"note: Note\nAll code in the REPL is evaluated in global scope, so a variable defined and assigned at top level will be a global variable. Variables defined at top level scope inside modules are also global.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In the following REPL session:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = 1.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"is equivalent to:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> global x = 1.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"so all the performance issues discussed previously apply.","category":"page"},{"location":"manual/performance-tips/#Measure-performance-with-[@time](@ref)-and-pay-attention-to-memory-allocation","page":"Performance Tips","title":"Measure performance with @time and pay attention to memory allocation","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"A useful tool for measuring performance is the @time macro. We here repeat the example with the global variable above, but this time with the type annotation removed:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = rand(1000);\n\njulia> function sum_global()\n s = 0.0\n for i in x\n s += i\n end\n return s\n end;\n\njulia> @time sum_global()\n 0.011539 seconds (9.08 k allocations: 373.386 KiB, 98.69% compilation time)\n523.0007221951678\n\njulia> @time sum_global()\n 0.000091 seconds (3.49 k allocations: 70.156 KiB)\n523.0007221951678","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"On the first call (@time sum_global()) the function gets compiled. (If you've not yet used @time in this session, it will also compile functions needed for timing.) You should not take the results of this run seriously. For the second run, note that in addition to reporting the time, it also indicated that a significant amount of memory was allocated. We are here just computing a sum over all elements in a vector of 64-bit floats so there should be no need to allocate (heap) memory.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"We should clarify that what @time reports is specifically heap allocations, which are typically needed for either mutable objects or for creating/growing variable-sized containers (such as Array or Dict, strings, or \"type-unstable\" objects whose type is only known at runtime). Allocating (or deallocating) such blocks of memory may require an expensive function call to libc (e.g. via malloc in C), and they must be tracked for garbage collection. In contrast, immutable values like numbers (except bignums), tuples, and immutable structs can be stored much more cheaply, e.g. in stack or CPU-register memory, so one doesn’t typically worry about the performance cost of \"allocating\" them.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Unexpected memory allocation is almost always a sign of some problem with your code, usually a problem with type-stability or creating many small temporary arrays. Consequently, in addition to the allocation itself, it's very likely that the code generated for your function is far from optimal. Take such indications seriously and follow the advice below.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In this particular case, the memory allocation is due to the usage of a type-unstable global variable x, so if we instead pass x as an argument to the function it no longer allocates memory (the remaining allocation reported below is due to running the @time macro in global scope) and is significantly faster after the first call:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = rand(1000);\n\njulia> function sum_arg(x)\n s = 0.0\n for i in x\n s += i\n end\n return s\n end;\n\njulia> @time sum_arg(x)\n 0.007551 seconds (3.98 k allocations: 200.548 KiB, 99.77% compilation time)\n523.0007221951678\n\njulia> @time sum_arg(x)\n 0.000006 seconds (1 allocation: 16 bytes)\n523.0007221951678","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The 1 allocation seen is from running the @time macro itself in global scope. If we instead run the timing in a function, we can see that indeed no allocations are performed:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> time_sum(x) = @time sum_arg(x);\n\njulia> time_sum(x)\n 0.000002 seconds\n523.0007221951678","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In some situations, your function may need to allocate memory as part of its operation, and this can complicate the simple picture above. In such cases, consider using one of the tools below to diagnose problems, or write a version of your function that separates allocation from its algorithmic aspects (see Pre-allocating outputs).","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"note: Note\nFor more serious benchmarking, consider the BenchmarkTools.jl package which among other things evaluates the function multiple times in order to reduce noise.","category":"page"},{"location":"manual/performance-tips/#tools","page":"Performance Tips","title":"Tools","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia and its package ecosystem includes tools that may help you diagnose problems and improve the performance of your code:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Profiling allows you to measure the performance of your running code and identify lines that serve as bottlenecks. For complex projects, the ProfileView package can help you visualize your profiling results.\nThe JET package can help you find common performance problems in your code.\nUnexpectedly-large memory allocations–as reported by @time, @allocated, or the profiler (through calls to the garbage-collection routines)–hint that there might be issues with your code. If you don't see another reason for the allocations, suspect a type problem. You can also start Julia with the --track-allocation=user option and examine the resulting *.mem files to see information about where those allocations occur. See Memory allocation analysis.\n@code_warntype generates a representation of your code that can be helpful in finding expressions that result in type uncertainty. See @code_warntype below.","category":"page"},{"location":"manual/performance-tips/#man-performance-abstract-container","page":"Performance Tips","title":"Avoid containers with abstract type parameters","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When working with parameterized types, including arrays, it is best to avoid parameterizing with abstract types where possible.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Consider the following:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> a = Real[]\nReal[]\n\njulia> push!(a, 1); push!(a, 2.0); push!(a, π)\n3-element Vector{Real}:\n 1\n 2.0\n π = 3.1415926535897...","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Because a is an array of abstract type Real, it must be able to hold any Real value. Since Real objects can be of arbitrary size and structure, a must be represented as an array of pointers to individually allocated Real objects. However, if we instead only allow numbers of the same type, e.g. Float64, to be stored in a these can be stored more efficiently:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> a = Float64[]\nFloat64[]\n\njulia> push!(a, 1); push!(a, 2.0); push!(a, π)\n3-element Vector{Float64}:\n 1.0\n 2.0\n 3.141592653589793","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Assigning numbers into a will now convert them to Float64 and a will be stored as a contiguous block of 64-bit floating-point values that can be manipulated efficiently.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If you cannot avoid containers with abstract value types, it is sometimes better to parametrize with Any to avoid runtime type checking. E.g. IdDict{Any, Any} performs better than IdDict{Type, Vector}","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"See also the discussion under Parametric Types.","category":"page"},{"location":"manual/performance-tips/#Type-declarations","page":"Performance Tips","title":"Type declarations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In many languages with optional type declarations, adding declarations is the principal way to make code run faster. This is not the case in Julia. In Julia, the compiler generally knows the types of all function arguments, local variables, and expressions. However, there are a few specific instances where declarations are helpful.","category":"page"},{"location":"manual/performance-tips/#Avoid-fields-with-abstract-type","page":"Performance Tips","title":"Avoid fields with abstract type","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Types can be declared without specifying the types of their fields:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> struct MyAmbiguousType\n a\n end","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This allows a to be of any type. This can often be useful, but it does have a downside: for objects of type MyAmbiguousType, the compiler will not be able to generate high-performance code. The reason is that the compiler uses the types of objects, not their values, to determine how to build code. Unfortunately, very little can be inferred about an object of type MyAmbiguousType:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> b = MyAmbiguousType(\"Hello\")\nMyAmbiguousType(\"Hello\")\n\njulia> c = MyAmbiguousType(17)\nMyAmbiguousType(17)\n\njulia> typeof(b)\nMyAmbiguousType\n\njulia> typeof(c)\nMyAmbiguousType","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The values of b and c have the same type, yet their underlying representation of data in memory is very different. Even if you stored just numeric values in field a, the fact that the memory representation of a UInt8 differs from a Float64 also means that the CPU needs to handle them using two different kinds of instructions. Since the required information is not available in the type, such decisions have to be made at run-time. This slows performance.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"You can do better by declaring the type of a. Here, we are focused on the case where a might be any one of several types, in which case the natural solution is to use parameters. For example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> mutable struct MyType{T<:AbstractFloat}\n a::T\n end","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This is a better choice than","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> mutable struct MyStillAmbiguousType\n a::AbstractFloat\n end","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"because the first version specifies the type of a from the type of the wrapper object. For example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> m = MyType(3.2)\nMyType{Float64}(3.2)\n\njulia> t = MyStillAmbiguousType(3.2)\nMyStillAmbiguousType(3.2)\n\njulia> typeof(m)\nMyType{Float64}\n\njulia> typeof(t)\nMyStillAmbiguousType","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The type of field a can be readily determined from the type of m, but not from the type of t. Indeed, in t it's possible to change the type of the field a:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> typeof(t.a)\nFloat64\n\njulia> t.a = 4.5f0\n4.5f0\n\njulia> typeof(t.a)\nFloat32","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In contrast, once m is constructed, the type of m.a cannot change:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> m.a = 4.5f0\n4.5f0\n\njulia> typeof(m.a)\nFloat64","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The fact that the type of m.a is known from m's type—coupled with the fact that its type cannot change mid-function—allows the compiler to generate highly-optimized code for objects like m but not for objects like t.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Of course, all of this is true only if we construct m with a concrete type. We can break this by explicitly constructing it with an abstract type:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> m = MyType{AbstractFloat}(3.2)\nMyType{AbstractFloat}(3.2)\n\njulia> typeof(m.a)\nFloat64\n\njulia> m.a = 4.5f0\n4.5f0\n\njulia> typeof(m.a)\nFloat32","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For all practical purposes, such objects behave identically to those of MyStillAmbiguousType.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"It's quite instructive to compare the sheer amount of code generated for a simple function","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"func(m::MyType) = m.a+1","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"using","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"code_llvm(func, Tuple{MyType{Float64}})\ncode_llvm(func, Tuple{MyType{AbstractFloat}})","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For reasons of length the results are not shown here, but you may wish to try this yourself. Because the type is fully-specified in the first case, the compiler doesn't need to generate any code to resolve the type at run-time. This results in shorter and faster code.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"One should also keep in mind that not-fully-parameterized types behave like abstract types. For example, even though a fully specified Array{T,n} is concrete, Array itself with no parameters given is not concrete:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> !isconcretetype(Array), !isabstracttype(Array), isstructtype(Array), !isconcretetype(Array{Int}), isconcretetype(Array{Int,1})\n(true, true, true, true, true)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In this case, it would be better to avoid declaring MyType with a field a::Array and instead declare the field as a::Array{T,N} or as a::A, where {T,N} or A are parameters of MyType.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The previous advice is especially useful when the fields of a struct are meant to be functions, or more generally callable objects. It is very tempting to define a struct as follows:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"struct MyCallableWrapper\n f::Function\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"But since Function is an abstract type, every call to wrapper.f will require dynamic dispatch, due to the type instability of accessing the field f. Instead, you should write something like:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"struct MyCallableWrapper{F}\n f::F\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"which has nearly identical behavior but will be much faster (because the type instability is eliminated). Note that we do not impose F<:Function: this means callable objects which do not subtype Function are also allowed for the field f.","category":"page"},{"location":"manual/performance-tips/#Avoid-fields-with-abstract-containers","page":"Performance Tips","title":"Avoid fields with abstract containers","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The same best practices also work for container types:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> struct MySimpleContainer{A<:AbstractVector}\n a::A\n end\n\njulia> struct MyAmbiguousContainer{T}\n a::AbstractVector{T}\n end\n\njulia> struct MyAlsoAmbiguousContainer\n a::Array\n end","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> c = MySimpleContainer(1:3);\n\njulia> typeof(c)\nMySimpleContainer{UnitRange{Int64}}\n\njulia> c = MySimpleContainer([1:3;]);\n\njulia> typeof(c)\nMySimpleContainer{Vector{Int64}}\n\njulia> b = MyAmbiguousContainer(1:3);\n\njulia> typeof(b)\nMyAmbiguousContainer{Int64}\n\njulia> b = MyAmbiguousContainer([1:3;]);\n\njulia> typeof(b)\nMyAmbiguousContainer{Int64}\n\njulia> d = MyAlsoAmbiguousContainer(1:3);\n\njulia> typeof(d), typeof(d.a)\n(MyAlsoAmbiguousContainer, Vector{Int64})\n\njulia> d = MyAlsoAmbiguousContainer(1:1.0:3);\n\njulia> typeof(d), typeof(d.a)\n(MyAlsoAmbiguousContainer, Vector{Float64})\n","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For MySimpleContainer, the object is fully-specified by its type and parameters, so the compiler can generate optimized functions. In most instances, this will probably suffice.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"While the compiler can now do its job perfectly well, there are cases where you might wish that your code could do different things depending on the element type of a. Usually the best way to achieve this is to wrap your specific operation (here, foo) in a separate function:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function sumfoo(c::MySimpleContainer)\n s = 0\n for x in c.a\n s += foo(x)\n end\n s\n end\nsumfoo (generic function with 1 method)\n\njulia> foo(x::Integer) = x\nfoo (generic function with 1 method)\n\njulia> foo(x::AbstractFloat) = round(x)\nfoo (generic function with 2 methods)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This keeps things simple, while allowing the compiler to generate optimized code in all cases.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"However, there are cases where you may need to declare different versions of the outer function for different element types or types of the AbstractVector of the field a in MySimpleContainer. You could do it like this:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function myfunc(c::MySimpleContainer{<:AbstractArray{<:Integer}})\n return c.a[1]+1\n end\nmyfunc (generic function with 1 method)\n\njulia> function myfunc(c::MySimpleContainer{<:AbstractArray{<:AbstractFloat}})\n return c.a[1]+2\n end\nmyfunc (generic function with 2 methods)\n\njulia> function myfunc(c::MySimpleContainer{Vector{T}}) where T <: Integer\n return c.a[1]+3\n end\nmyfunc (generic function with 3 methods)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> myfunc(MySimpleContainer(1:3))\n2\n\njulia> myfunc(MySimpleContainer(1.0:3))\n3.0\n\njulia> myfunc(MySimpleContainer([1:3;]))\n4","category":"page"},{"location":"manual/performance-tips/#Annotate-values-taken-from-untyped-locations","page":"Performance Tips","title":"Annotate values taken from untyped locations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"It is often convenient to work with data structures that may contain values of any type (arrays of type Array{Any}). But, if you're using one of these structures and happen to know the type of an element, it helps to share this knowledge with the compiler:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function foo(a::Array{Any,1})\n x = a[1]::Int32\n b = x+1\n ...\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here, we happened to know that the first element of a would be an Int32. Making an annotation like this has the added benefit that it will raise a run-time error if the value is not of the expected type, potentially catching certain bugs earlier.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In the case that the type of a[1] is not known precisely, x can be declared via x = convert(Int32, a[1])::Int32. The use of the convert function allows a[1] to be any object convertible to an Int32 (such as UInt8), thus increasing the genericity of the code by loosening the type requirement. Notice that convert itself needs a type annotation in this context in order to achieve type stability. This is because the compiler cannot deduce the type of the return value of a function, even convert, unless the types of all the function's arguments are known.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Type annotation will not enhance (and can actually hinder) performance if the type is abstract, or constructed at run-time. This is because the compiler cannot use the annotation to specialize the subsequent code, and the type-check itself takes time. For example, in the code:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function nr(a, prec)\n ctype = prec == 32 ? Float32 : Float64\n b = Complex{ctype}(a)\n c = (b + 1.0f0)::Complex{ctype}\n abs(c)\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"the annotation of c harms performance. To write performant code involving types constructed at run-time, use the function-barrier technique discussed below, and ensure that the constructed type appears among the argument types of the kernel function so that the kernel operations are properly specialized by the compiler. For example, in the above snippet, as soon as b is constructed, it can be passed to another function k, the kernel. If, for example, function k declares b as an argument of type Complex{T}, where T is a type parameter, then a type annotation appearing in an assignment statement within k of the form:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"c = (b + 1.0f0)::Complex{T}","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"does not hinder performance (but does not help either) since the compiler can determine the type of c at the time k is compiled.","category":"page"},{"location":"manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing","page":"Performance Tips","title":"Be aware of when Julia avoids specializing","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"As a heuristic, Julia avoids automatically specializing on argument type parameters in three specific cases: Type, Function, and Vararg. Julia will always specialize when the argument is used within the method, but not if the argument is just passed through to another function. This usually has no performance impact at runtime and improves compiler performance. If you find it does have a performance impact at runtime in your case, you can trigger specialization by adding a type parameter to the method declaration. Here are some examples:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This will not specialize:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function f_type(t) # or t::Type\n x = ones(t, 10)\n return sum(map(sin, x))\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"but this will:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function g_type(t::Type{T}) where T\n x = ones(T, 10)\n return sum(map(sin, x))\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"These will not specialize:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"f_func(f, num) = ntuple(f, div(num, 2))\ng_func(g::Function, num) = ntuple(g, div(num, 2))","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"but this will:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"h_func(h::H, num) where {H} = ntuple(h, div(num, 2))","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This will not specialize:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"f_vararg(x::Int...) = tuple(x...)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"but this will:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"g_vararg(x::Vararg{Int, N}) where {N} = tuple(x...)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"One only needs to introduce a single type parameter to force specialization, even if the other types are unconstrained. For example, this will also specialize, and is useful when the arguments are not all of the same type:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"h_vararg(x::Vararg{Any, N}) where {N} = tuple(x...)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Note that @code_typed and friends will always show you specialized code, even if Julia would not normally specialize that method call. You need to check the method internals if you want to see whether specializations are generated when argument types are changed, i.e., if Base.specializations(@which f(...)) contains specializations for the argument in question.","category":"page"},{"location":"manual/performance-tips/#Break-functions-into-multiple-definitions","page":"Performance Tips","title":"Break functions into multiple definitions","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Writing a function as many small definitions allows the compiler to directly call the most applicable code, or even inline it.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here is an example of a \"compound function\" that should really be written as multiple definitions:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"using LinearAlgebra\n\nfunction mynorm(A)\n if isa(A, Vector)\n return sqrt(real(dot(A,A)))\n elseif isa(A, Matrix)\n return maximum(svdvals(A))\n else\n error(\"mynorm: invalid argument\")\n end\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This can be written more concisely and efficiently as:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"mynorm(x::Vector) = sqrt(real(dot(x, x)))\nmynorm(A::Matrix) = maximum(svdvals(A))","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"It should however be noted that the compiler is quite efficient at optimizing away the dead branches in code written as the mynorm example.","category":"page"},{"location":"manual/performance-tips/#Write-\"type-stable\"-functions","page":"Performance Tips","title":"Write \"type-stable\" functions","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When possible, it helps to ensure that a function always returns a value of the same type. Consider the following definition:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"pos(x) = x < 0 ? 0 : x","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Although this seems innocent enough, the problem is that 0 is an integer (of type Int) and x might be of any type. Thus, depending on the value of x, this function might return a value of either of two types. This behavior is allowed, and may be desirable in some cases. But it can easily be fixed as follows:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"pos(x) = x < 0 ? zero(x) : x","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"There is also a oneunit function, and a more general oftype(x, y) function, which returns y converted to the type of x.","category":"page"},{"location":"manual/performance-tips/#Avoid-changing-the-type-of-a-variable","page":"Performance Tips","title":"Avoid changing the type of a variable","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"An analogous \"type-stability\" problem exists for variables used repeatedly within a function:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function foo()\n x = 1\n for i = 1:10\n x /= rand()\n end\n return x\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Local variable x starts as an integer, and after one loop iteration becomes a floating-point number (the result of / operator). This makes it more difficult for the compiler to optimize the body of the loop. There are several possible fixes:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Initialize x with x = 1.0\nDeclare the type of x explicitly as x::Float64 = 1\nUse an explicit conversion by x = oneunit(Float64)\nInitialize with the first loop iteration, to x = 1 / rand(), then loop for i = 2:10","category":"page"},{"location":"manual/performance-tips/#kernel-functions","page":"Performance Tips","title":"Separate kernel functions (aka, function barriers)","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Many functions follow a pattern of performing some set-up work, and then running many iterations to perform a core computation. Where possible, it is a good idea to put these core computations in separate functions. For example, the following contrived function returns an array of a randomly-chosen type:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function strange_twos(n)\n a = Vector{rand(Bool) ? Int64 : Float64}(undef, n)\n for i = 1:n\n a[i] = 2\n end\n return a\n end;\n\njulia> strange_twos(3)\n3-element Vector{Int64}:\n 2\n 2\n 2","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This should be written as:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function fill_twos!(a)\n for i = eachindex(a)\n a[i] = 2\n end\n end;\n\njulia> function strange_twos(n)\n a = Vector{rand(Bool) ? Int64 : Float64}(undef, n)\n fill_twos!(a)\n return a\n end;\n\njulia> strange_twos(3)\n3-element Vector{Int64}:\n 2\n 2\n 2","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia's compiler specializes code for argument types at function boundaries, so in the original implementation it does not know the type of a during the loop (since it is chosen randomly). Therefore the second version is generally faster since the inner loop can be recompiled as part of fill_twos! for different types of a.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The second form is also often better style and can lead to more code reuse.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This pattern is used in several places in Julia Base. For example, see vcat and hcat in abstractarray.jl, or the fill! function, which we could have used instead of writing our own fill_twos!.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Functions like strange_twos occur when dealing with data of uncertain type, for example data loaded from an input file that might contain either integers, floats, strings, or something else.","category":"page"},{"location":"manual/performance-tips/#man-performance-value-type","page":"Performance Tips","title":"Types with values-as-parameters","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Let's say you want to create an N-dimensional array that has size 3 along each axis. Such arrays can be created like this:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> A = fill(5.0, (3, 3))\n3×3 Matrix{Float64}:\n 5.0 5.0 5.0\n 5.0 5.0 5.0\n 5.0 5.0 5.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This approach works very well: the compiler can figure out that A is an Array{Float64,2} because it knows the type of the fill value (5.0::Float64) and the dimensionality ((3, 3)::NTuple{2,Int}). This implies that the compiler can generate very efficient code for any future usage of A in the same function.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"But now let's say you want to write a function that creates a 3×3×... array in arbitrary dimensions; you might be tempted to write a function","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function array3(fillval, N)\n fill(fillval, ntuple(d->3, N))\n end\narray3 (generic function with 1 method)\n\njulia> array3(5.0, 2)\n3×3 Matrix{Float64}:\n 5.0 5.0 5.0\n 5.0 5.0 5.0\n 5.0 5.0 5.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This works, but (as you can verify for yourself using @code_warntype array3(5.0, 2)) the problem is that the output type cannot be inferred: the argument N is a value of type Int, and type-inference does not (and cannot) predict its value in advance. This means that code using the output of this function has to be conservative, checking the type on each access of A; such code will be very slow.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Now, one very good way to solve such problems is by using the function-barrier technique. However, in some cases you might want to eliminate the type-instability altogether. In such cases, one approach is to pass the dimensionality as a parameter, for example through Val{T}() (see \"Value types\"):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function array3(fillval, ::Val{N}) where N\n fill(fillval, ntuple(d->3, Val(N)))\n end\narray3 (generic function with 1 method)\n\njulia> array3(5.0, Val(2))\n3×3 Matrix{Float64}:\n 5.0 5.0 5.0\n 5.0 5.0 5.0\n 5.0 5.0 5.0","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia has a specialized version of ntuple that accepts a Val{::Int} instance as the second parameter; by passing N as a type-parameter, you make its \"value\" known to the compiler. Consequently, this version of array3 allows the compiler to predict the return type.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"However, making use of such techniques can be surprisingly subtle. For example, it would be of no help if you called array3 from a function like this:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function call_array3(fillval, n)\n A = array3(fillval, Val(n))\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here, you've created the same problem all over again: the compiler can't guess what n is, so it doesn't know the type of Val(n). Attempting to use Val, but doing so incorrectly, can easily make performance worse in many situations. (Only in situations where you're effectively combining Val with the function-barrier trick, to make the kernel function more efficient, should code like the above be used.)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"An example of correct usage of Val would be:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function filter3(A::AbstractArray{T,N}) where {T,N}\n kernel = array3(1, Val(N))\n filter(A, kernel)\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In this example, N is passed as a parameter, so its \"value\" is known to the compiler. Essentially, Val(T) works only when T is either hard-coded/literal (Val(3)) or already specified in the type-domain.","category":"page"},{"location":"manual/performance-tips/#The-dangers-of-abusing-multiple-dispatch-(aka,-more-on-types-with-values-as-parameters)","page":"Performance Tips","title":"The dangers of abusing multiple dispatch (aka, more on types with values-as-parameters)","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Once one learns to appreciate multiple dispatch, there's an understandable tendency to go overboard and try to use it for everything. For example, you might imagine using it to store information, e.g.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"struct Car{Make, Model}\n year::Int\n ...more fields...\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"and then dispatch on objects like Car{:Honda,:Accord}(year, args...).","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This might be worthwhile when either of the following are true:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"You require CPU-intensive processing on each Car, and it becomes vastly more efficient if you know the Make and Model at compile time and the total number of different Make or Model that will be used is not too large.\nYou have homogeneous lists of the same type of Car to process, so that you can store them all in an Array{Car{:Honda,:Accord},N}.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When the latter holds, a function processing such a homogeneous array can be productively specialized: Julia knows the type of each element in advance (all objects in the container have the same concrete type), so Julia can \"look up\" the correct method calls when the function is being compiled (obviating the need to check at run-time) and thereby emit efficient code for processing the whole list.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When these do not hold, then it's likely that you'll get no benefit; worse, the resulting \"combinatorial explosion of types\" will be counterproductive. If items[i+1] has a different type than item[i], Julia has to look up the type at run-time, search for the appropriate method in method tables, decide (via type intersection) which one matches, determine whether it has been JIT-compiled yet (and do so if not), and then make the call. In essence, you're asking the full type- system and JIT-compilation machinery to basically execute the equivalent of a switch statement or dictionary lookup in your own code.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Some run-time benchmarks comparing (1) type dispatch, (2) dictionary lookup, and (3) a \"switch\" statement can be found on the mailing list.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Perhaps even worse than the run-time impact is the compile-time impact: Julia will compile specialized functions for each different Car{Make, Model}; if you have hundreds or thousands of such types, then every function that accepts such an object as a parameter (from a custom get_year function you might write yourself, to the generic push! function in Julia Base) will have hundreds or thousands of variants compiled for it. Each of these increases the size of the cache of compiled code, the length of internal lists of methods, etc. Excess enthusiasm for values-as-parameters can easily waste enormous resources.","category":"page"},{"location":"manual/performance-tips/#man-performance-column-major","page":"Performance Tips","title":"Access arrays in memory order, along columns","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Multidimensional arrays in Julia are stored in column-major order. This means that arrays are stacked one column at a time. This can be verified using the vec function or the syntax [:] as shown below (notice that the array is ordered [1 3 2 4], not [1 2 3 4]):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> x[:]\n4-element Vector{Int64}:\n 1\n 3\n 2\n 4","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This convention for ordering arrays is common in many languages like Fortran, Matlab, and R (to name a few). The alternative to column-major ordering is row-major ordering, which is the convention adopted by C and Python (numpy) among other languages. Remembering the ordering of arrays can have significant performance effects when looping over arrays. A rule of thumb to keep in mind is that with column-major arrays, the first index changes most rapidly. Essentially this means that looping will be faster if the inner-most loop index is the first to appear in a slice expression. Keep in mind that indexing an array with : is an implicit loop that iteratively accesses all elements within a particular dimension; it can be faster to extract columns than rows, for example.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Consider the following contrived example. Imagine we wanted to write a function that accepts a Vector and returns a square Matrix with either the rows or the columns filled with copies of the input vector. Assume that it is not important whether rows or columns are filled with these copies (perhaps the rest of the code can be easily adapted accordingly). We could conceivably do this in at least four ways (in addition to the recommended call to the built-in repeat):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function copy_cols(x::Vector{T}) where T\n inds = axes(x, 1)\n out = similar(Array{T}, inds, inds)\n for i = inds\n out[:, i] = x\n end\n return out\nend\n\nfunction copy_rows(x::Vector{T}) where T\n inds = axes(x, 1)\n out = similar(Array{T}, inds, inds)\n for i = inds\n out[i, :] = x\n end\n return out\nend\n\nfunction copy_col_row(x::Vector{T}) where T\n inds = axes(x, 1)\n out = similar(Array{T}, inds, inds)\n for col = inds, row = inds\n out[row, col] = x[row]\n end\n return out\nend\n\nfunction copy_row_col(x::Vector{T}) where T\n inds = axes(x, 1)\n out = similar(Array{T}, inds, inds)\n for row = inds, col = inds\n out[row, col] = x[col]\n end\n return out\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Now we will time each of these functions using the same random 10000 by 1 input vector:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = randn(10000);\n\njulia> fmt(f) = println(rpad(string(f)*\": \", 14, ' '), @elapsed f(x))\n\njulia> map(fmt, [copy_cols, copy_rows, copy_col_row, copy_row_col]);\ncopy_cols: 0.331706323\ncopy_rows: 1.799009911\ncopy_col_row: 0.415630047\ncopy_row_col: 1.721531501","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Notice that copy_cols is much faster than copy_rows. This is expected because copy_cols respects the column-based memory layout of the Matrix and fills it one column at a time. Additionally, copy_col_row is much faster than copy_row_col because it follows our rule of thumb that the first element to appear in a slice expression should be coupled with the inner-most loop.","category":"page"},{"location":"manual/performance-tips/#Pre-allocating-outputs","page":"Performance Tips","title":"Pre-allocating outputs","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If your function returns an Array or some other complex type, it may have to allocate memory. Unfortunately, oftentimes allocation and its converse, garbage collection, are substantial bottlenecks.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Sometimes you can circumvent the need to allocate memory on each function call by preallocating the output. As a trivial example, compare","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function xinc(x)\n return [x, x+1, x+2]\n end;\n\njulia> function loopinc()\n y = 0\n for i = 1:10^7\n ret = xinc(i)\n y += ret[2]\n end\n return y\n end;","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"with","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> function xinc!(ret::AbstractVector{T}, x::T) where T\n ret[1] = x\n ret[2] = x+1\n ret[3] = x+2\n nothing\n end;\n\njulia> function loopinc_prealloc()\n ret = Vector{Int}(undef, 3)\n y = 0\n for i = 1:10^7\n xinc!(ret, i)\n y += ret[2]\n end\n return y\n end;","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Timing results:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> @time loopinc()\n 0.529894 seconds (40.00 M allocations: 1.490 GiB, 12.14% gc time)\n50000015000000\n\njulia> @time loopinc_prealloc()\n 0.030850 seconds (6 allocations: 288 bytes)\n50000015000000","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Preallocation has other advantages, for example by allowing the caller to control the \"output\" type from an algorithm. In the example above, we could have passed a SubArray rather than an Array, had we so desired.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Taken to its extreme, pre-allocation can make your code uglier, so performance measurements and some judgment may be required. However, for \"vectorized\" (element-wise) functions, the convenient syntax x .= f.(y) can be used for in-place operations with fused loops and no temporary arrays (see the dot syntax for vectorizing functions).","category":"page"},{"location":"manual/performance-tips/#man-perftips-mutablearithmetics","page":"Performance Tips","title":"Use MutableArithmetics for more control over allocation for mutable arithmetic types","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Some Number subtypes, such as BigInt or BigFloat, may be implemented as mutable struct types, or they may have mutable components. The arithmetic interfaces in Julia Base usually opt for convenience over efficiency in such cases, so using them in a naive manner may result in suboptimal performance. The abstractions of the MutableArithmetics package, on the other hand, make it possible to exploit the mutability of such types for writing fast code that allocates only as much as necessary. MutableArithmetics also makes it possible to copy values of mutable arithmetic types explicitly when necessary. MutableArithmetics is a user package and is not affiliated with the Julia project.","category":"page"},{"location":"manual/performance-tips/#More-dots:-Fuse-vectorized-operations","page":"Performance Tips","title":"More dots: Fuse vectorized operations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia has a special dot syntax that converts any scalar function into a \"vectorized\" function call, and any operator into a \"vectorized\" operator, with the special property that nested \"dot calls\" are fusing: they are combined at the syntax level into a single loop, without allocating temporary arrays. If you use .= and similar assignment operators, the result can also be stored in-place in a pre-allocated array (see above).","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In a linear-algebra context, this means that even though operations like vector + vector and vector * scalar are defined, it can be advantageous to instead use vector .+ vector and vector .* scalar because the resulting loops can be fused with surrounding computations. For example, consider the two functions:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> f(x) = 3x.^2 + 4x + 7x.^3;\n\njulia> fdot(x) = @. 3x^2 + 4x + 7x^3; # equivalent to 3 .* x.^2 .+ 4 .* x .+ 7 .* x.^3","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Both f and fdot compute the same thing. However, fdot (defined with the help of the @. macro) is significantly faster when applied to an array:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = rand(10^6);\n\njulia> @time f(x);\n 0.019049 seconds (16 allocations: 45.777 MiB, 18.59% gc time)\n\njulia> @time fdot(x);\n 0.002790 seconds (6 allocations: 7.630 MiB)\n\njulia> @time f.(x);\n 0.002626 seconds (8 allocations: 7.630 MiB)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"That is, fdot(x) is ten times faster and allocates 1/6 the memory of f(x), because each * and + operation in f(x) allocates a new temporary array and executes in a separate loop. In this example f.(x) is as fast as fdot(x) but in many contexts it is more convenient to sprinkle some dots in your expressions than to define a separate function for each vectorized operation.","category":"page"},{"location":"manual/performance-tips/#man-performance-unfuse","page":"Performance Tips","title":"Fewer dots: Unfuse certain intermediate broadcasts","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The dot loop fusion mentioned above enables concise and idiomatic code to express highly performant operations. However, it is important to remember that the fused operation will be computed at every iteration of the broadcast. This means that in some situations, particularly in the presence of composed or multidimensional broadcasts, an expression with dot calls may be computing a function more times than intended. As an example, say we want to build a random matrix whose rows have Euclidean norm one. We might write something like the following:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = rand(1000, 1000);\n\njulia> d = sum(abs2, x; dims=2);\n\njulia> @time x ./= sqrt.(d);\n 0.002049 seconds (4 allocations: 96 bytes)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This will work. However, this expression will actually recompute sqrt(d[i]) for every element in the row x[i, :], meaning that many more square roots are computed than necessary. To see precisely over which indices the broadcast will iterate, we can call Broadcast.combine_axes on the arguments of the fused expression. This will return a tuple of ranges whose entries correspond to the axes of iteration; the product of lengths of these ranges will be the total number of calls to the fused operation.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"It follows that when some components of the broadcast expression are constant along an axis—like the sqrt along the second dimension in the preceding example—there is potential for a performance improvement by forcibly \"unfusing\" those components, i.e. allocating the result of the broadcasted operation in advance and reusing the cached value along its constant axis. Some such potential approaches are to use temporary variables, wrap components of a dot expression in identity, or use an equivalent intrinsically vectorized (but non-fused) function.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> @time let s = sqrt.(d); x ./= s end;\n 0.000809 seconds (5 allocations: 8.031 KiB)\n\njulia> @time x ./= identity(sqrt.(d));\n 0.000608 seconds (5 allocations: 8.031 KiB)\n\njulia> @time x ./= map(sqrt, d);\n 0.000611 seconds (4 allocations: 8.016 KiB)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Any of these options yields approximately a three-fold speedup at the cost of an allocation; for large broadcastables this speedup can be asymptotically very large.","category":"page"},{"location":"manual/performance-tips/#man-performance-views","page":"Performance Tips","title":"Consider using views for slices","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In Julia, an array \"slice\" expression like array[1:5, :] creates a copy of that data (except on the left-hand side of an assignment, where array[1:5, :] = ... assigns in-place to that portion of array). If you are doing many operations on the slice, this can be good for performance because it is more efficient to work with a smaller contiguous copy than it would be to index into the original array. On the other hand, if you are just doing a few simple operations on the slice, the cost of the allocation and copy operations can be substantial.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"An alternative is to create a \"view\" of the array, which is an array object (a SubArray) that actually references the data of the original array in-place, without making a copy. (If you write to a view, it modifies the original array's data as well.) This can be done for individual slices by calling view, or more simply for a whole expression or block of code by putting @views in front of that expression. For example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> fcopy(x) = sum(x[2:end-1]);\n\njulia> @views fview(x) = sum(x[2:end-1]);\n\njulia> x = rand(10^6);\n\njulia> @time fcopy(x);\n 0.003051 seconds (3 allocations: 7.629 MB)\n\njulia> @time fview(x);\n 0.001020 seconds (1 allocation: 16 bytes)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Notice both the 3× speedup and the decreased memory allocation of the fview version of the function.","category":"page"},{"location":"manual/performance-tips/#Copying-data-is-not-always-bad","page":"Performance Tips","title":"Copying data is not always bad","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Arrays are stored contiguously in memory, lending themselves to CPU vectorization and fewer memory accesses due to caching. These are the same reasons that it is recommended to access arrays in column-major order (see above). Irregular access patterns and non-contiguous views can drastically slow down computations on arrays because of non-sequential memory access.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Copying irregularly-accessed data into a contiguous array before repeatedly accessing it can result in a large speedup, such as in the example below. Here, a matrix is being accessed at randomly-shuffled indices before being multiplied. Copying into plain arrays speeds up the multiplication even with the added cost of copying and allocation.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> using Random\n\njulia> A = randn(3000, 3000);\n\njulia> x = randn(2000);\n\njulia> inds = shuffle(1:3000)[1:2000];\n\njulia> function iterated_neural_network(A, x, depth)\n for _ in 1:depth\n x .= max.(0, A * x)\n end\n argmax(x)\n end\n\njulia> @time iterated_neural_network(view(A, inds, inds), x, 10)\n 0.324903 seconds (12 allocations: 157.562 KiB)\n1569\n\njulia> @time iterated_neural_network(A[inds, inds], x, 10)\n 0.054576 seconds (13 allocations: 30.671 MiB, 13.33% gc time)\n1569","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Provided there is enough memory, the cost of copying the view to an array is outweighed by the speed boost from doing the repeated matrix multiplications on a contiguous array.","category":"page"},{"location":"manual/performance-tips/#Consider-StaticArrays.jl-for-small-fixed-size-vector/matrix-operations","page":"Performance Tips","title":"Consider StaticArrays.jl for small fixed-size vector/matrix operations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If your application involves many small (< 100 element) arrays of fixed sizes (i.e. the size is known prior to execution), then you might want to consider using the StaticArrays.jl package. This package allows you to represent such arrays in a way that avoids unnecessary heap allocations and allows the compiler to specialize code for the size of the array, e.g. by completely unrolling vector operations (eliminating the loops) and storing elements in CPU registers.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For example, if you are doing computations with 2d geometries, you might have many computations with 2-component vectors. By using the SVector type from StaticArrays.jl, you can use convenient vector notation and operations like norm(3v - w) on vectors v and w, while allowing the compiler to unroll the code to a minimal computation equivalent to @inbounds hypot(3v[1]-w[1], 3v[2]-w[2]).","category":"page"},{"location":"manual/performance-tips/#Avoid-string-interpolation-for-I/O","page":"Performance Tips","title":"Avoid string interpolation for I/O","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When writing data to a file (or other I/O device), forming extra intermediate strings is a source of overhead. Instead of:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"println(file, \"$a $b\")","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"use:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"println(file, a, \" \", b)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The first version of the code forms a string, then writes it to the file, while the second version writes values directly to the file. Also notice that in some cases string interpolation can be harder to read. Consider:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"println(file, \"$(f(a))$(f(b))\")","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"versus:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"println(file, f(a), f(b))","category":"page"},{"location":"manual/performance-tips/#Avoid-eager-string-materialization","page":"Performance Tips","title":"Avoid eager string materialization","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In settings where a string representation of an object is only needed conditionally (e.g. in error paths of functions or conditional warnings such as deprecations), it is advisable to avoid the overhead of eagerly materializing the string. Since Julia 1.8, this can be achieved via LazyString and the corresponding string macro @lazy_str.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"For example, instead of:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Base.depwarn(\"`foo` is deprecated for type $(typeof(x))\", :bar)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"use:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Base.depwarn(lazy\"`foo` is deprecated for type $(typeof(x))\", :bar)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"or the equivalent macro-free version:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Base.depwarn(LazyString(\"`foo` is deprecated for type \", typeof(x)), :bar)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Through this approach, the interpolated string will only be constructed when it is actually displayed.","category":"page"},{"location":"manual/performance-tips/#Optimize-network-I/O-during-parallel-execution","page":"Performance Tips","title":"Optimize network I/O during parallel execution","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When executing a remote function in parallel:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"using Distributed\n\nresponses = Vector{Any}(undef, nworkers())\n@sync begin\n for (idx, pid) in enumerate(workers())\n @async responses[idx] = remotecall_fetch(foo, pid, args...)\n end\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"is faster than:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"using Distributed\n\nrefs = Vector{Any}(undef, nworkers())\nfor (idx, pid) in enumerate(workers())\n refs[idx] = @spawnat pid foo(args...)\nend\nresponses = [fetch(r) for r in refs]","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The former results in a single network round-trip to every worker, while the latter results in two network calls - first by the @spawnat and the second due to the fetch (or even a wait). The fetch/wait is also being executed serially resulting in an overall poorer performance.","category":"page"},{"location":"manual/performance-tips/#Fix-deprecation-warnings","page":"Performance Tips","title":"Fix deprecation warnings","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"A deprecated function internally performs a lookup in order to print a relevant warning only once. This extra lookup can cause a significant slowdown, so all uses of deprecated functions should be modified as suggested by the warnings.","category":"page"},{"location":"manual/performance-tips/#Tweaks","page":"Performance Tips","title":"Tweaks","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"These are some minor points that might help in tight inner loops.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Avoid unnecessary arrays. For example, instead of sum([x,y,z]) use x+y+z.\nUse abs2(z) instead of abs(z)^2 for complex z. In general, try to rewrite code to use abs2 instead of abs for complex arguments.\nUse div(x,y) for truncating division of integers instead of trunc(x/y), fld(x,y) instead of floor(x/y), and cld(x,y) instead of ceil(x/y).","category":"page"},{"location":"manual/performance-tips/#man-performance-annotations","page":"Performance Tips","title":"Performance Annotations","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Sometimes you can enable better optimization by promising certain program properties.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Use @inbounds to eliminate array bounds checking within expressions. Be certain before doing this. If the subscripts are ever out of bounds, you may suffer crashes or silent corruption.\nUse @fastmath to allow floating point optimizations that are correct for real numbers, but lead to differences for IEEE numbers. Be careful when doing this, as this may change numerical results. This corresponds to the -ffast-math option of clang.\nWrite @simd in front of for loops to promise that the iterations are independent and may be reordered. Note that in many cases, Julia can automatically vectorize code without the @simd macro; it is only beneficial in cases where such a transformation would otherwise be illegal, including cases like allowing floating-point re-associativity and ignoring dependent memory accesses (@simd ivdep). Again, be very careful when asserting @simd as erroneously annotating a loop with dependent iterations may result in unexpected results. In particular, note that setindex! on some AbstractArray subtypes is inherently dependent upon iteration order. This feature is experimental and could change or disappear in future versions of Julia.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The common idiom of using 1:n to index into an AbstractArray is not safe if the Array uses unconventional indexing, and may cause a segmentation fault if bounds checking is turned off. Use LinearIndices(x) or eachindex(x) instead (see also Arrays with custom indices).","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"note: Note\nWhile @simd needs to be placed directly in front of an innermost for loop, both @inbounds and @fastmath can be applied to either single expressions or all the expressions that appear within nested blocks of code, e.g., using @inbounds begin or @inbounds for ....","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here is an example with both @inbounds and @simd markup (we here use @noinline to prevent the optimizer from trying to be too clever and defeat our benchmark):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"@noinline function inner(x, y)\n s = zero(eltype(x))\n for i=eachindex(x)\n @inbounds s += x[i]*y[i]\n end\n return s\nend\n\n@noinline function innersimd(x, y)\n s = zero(eltype(x))\n @simd for i = eachindex(x)\n @inbounds s += x[i] * y[i]\n end\n return s\nend\n\nfunction timeit(n, reps)\n x = rand(Float32, n)\n y = rand(Float32, n)\n s = zero(Float64)\n time = @elapsed for j in 1:reps\n s += inner(x, y)\n end\n println(\"GFlop/sec = \", 2n*reps / time*1E-9)\n time = @elapsed for j in 1:reps\n s += innersimd(x, y)\n end\n println(\"GFlop/sec (SIMD) = \", 2n*reps / time*1E-9)\nend\n\ntimeit(1000, 1000)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"On a computer with a 2.4GHz Intel Core i5 processor, this produces:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"GFlop/sec = 1.9467069505224963\nGFlop/sec (SIMD) = 17.578554163920018","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"(GFlop/sec measures the performance, and larger numbers are better.)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here is an example with all three kinds of markup. This program first calculates the finite difference of a one-dimensional array, and then evaluates the L2-norm of the result:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function init!(u::Vector)\n n = length(u)\n dx = 1.0 / (n-1)\n @fastmath @inbounds @simd for i in 1:n #by asserting that `u` is a `Vector` we can assume it has 1-based indexing\n u[i] = sin(2pi*dx*i)\n end\nend\n\nfunction deriv!(u::Vector, du)\n n = length(u)\n dx = 1.0 / (n-1)\n @fastmath @inbounds du[1] = (u[2] - u[1]) / dx\n @fastmath @inbounds @simd for i in 2:n-1\n du[i] = (u[i+1] - u[i-1]) / (2*dx)\n end\n @fastmath @inbounds du[n] = (u[n] - u[n-1]) / dx\nend\n\nfunction mynorm(u::Vector)\n n = length(u)\n T = eltype(u)\n s = zero(T)\n @fastmath @inbounds @simd for i in 1:n\n s += u[i]^2\n end\n @fastmath @inbounds return sqrt(s)\nend\n\nfunction main()\n n = 2000\n u = Vector{Float64}(undef, n)\n init!(u)\n du = similar(u)\n\n deriv!(u, du)\n nu = mynorm(du)\n\n @time for i in 1:10^6\n deriv!(u, du)\n nu = mynorm(du)\n end\n\n println(nu)\nend\n\nmain()","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"On a computer with a 2.7 GHz Intel Core i7 processor, this produces:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"$ julia wave.jl;\n 1.207814709 seconds\n4.443986180758249\n\n$ julia --math-mode=ieee wave.jl;\n 4.487083643 seconds\n4.443986180758249","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Here, the option --math-mode=ieee disables the @fastmath macro, so that we can compare results.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In this case, the speedup due to @fastmath is a factor of about 3.7. This is unusually large – in general, the speedup will be smaller. (In this particular example, the working set of the benchmark is small enough to fit into the L1 cache of the processor, so that memory access latency does not play a role, and computing time is dominated by CPU usage. In many real world programs this is not the case.) Also, in this case this optimization does not change the result – in general, the result will be slightly different. In some cases, especially for numerically unstable algorithms, the result can be very different.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The annotation @fastmath re-arranges floating point expressions, e.g. changing the order of evaluation, or assuming that certain special cases (inf, nan) cannot occur. In this case (and on this particular computer), the main difference is that the expression 1 / (2*dx) in the function deriv is hoisted out of the loop (i.e. calculated outside the loop), as if one had written idx = 1 / (2*dx). In the loop, the expression ... / (2*dx) then becomes ... * idx, which is much faster to evaluate. Of course, both the actual optimization that is applied by the compiler as well as the resulting speedup depend very much on the hardware. You can examine the change in generated code by using Julia's code_native function.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Note that @fastmath also assumes that NaNs will not occur during the computation, which can lead to surprising behavior:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> f(x) = isnan(x);\n\njulia> f(NaN)\ntrue\n\njulia> f_fast(x) = @fastmath isnan(x);\n\njulia> f_fast(NaN)\nfalse","category":"page"},{"location":"manual/performance-tips/#Treat-Subnormal-Numbers-as-Zeros","page":"Performance Tips","title":"Treat Subnormal Numbers as Zeros","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Subnormal numbers, formerly called denormal numbers, are useful in many contexts, but incur a performance penalty on some hardware. A call set_zero_subnormals(true) grants permission for floating-point operations to treat subnormal inputs or outputs as zeros, which may improve performance on some hardware. A call set_zero_subnormals(false) enforces strict IEEE behavior for subnormal numbers.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Below is an example where subnormals noticeably impact performance on some hardware:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function timestep(b::Vector{T}, a::Vector{T}, Δt::T) where T\n @assert length(a)==length(b)\n n = length(b)\n b[1] = 1 # Boundary condition\n for i=2:n-1\n b[i] = a[i] + (a[i-1] - T(2)*a[i] + a[i+1]) * Δt\n end\n b[n] = 0 # Boundary condition\nend\n\nfunction heatflow(a::Vector{T}, nstep::Integer) where T\n b = similar(a)\n for t=1:div(nstep,2) # Assume nstep is even\n timestep(b,a,T(0.1))\n timestep(a,b,T(0.1))\n end\nend\n\nheatflow(zeros(Float32,10),2) # Force compilation\nfor trial=1:6\n a = zeros(Float32,1000)\n set_zero_subnormals(iseven(trial)) # Odd trials use strict IEEE arithmetic\n @time heatflow(a,1000)\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This gives an output similar to","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":" 0.002202 seconds (1 allocation: 4.063 KiB)\n 0.001502 seconds (1 allocation: 4.063 KiB)\n 0.002139 seconds (1 allocation: 4.063 KiB)\n 0.001454 seconds (1 allocation: 4.063 KiB)\n 0.002115 seconds (1 allocation: 4.063 KiB)\n 0.001455 seconds (1 allocation: 4.063 KiB)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Note how each even iteration is significantly faster.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This example generates many subnormal numbers because the values in a become an exponentially decreasing curve, which slowly flattens out over time.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Treating subnormals as zeros should be used with caution, because doing so breaks some identities, such as x-y == 0 implies x == y:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> x = 3f-38; y = 2f-38;\n\njulia> set_zero_subnormals(true); (x - y, x == y)\n(0.0f0, false)\n\njulia> set_zero_subnormals(false); (x - y, x == y)\n(1.0000001f-38, false)","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"In some applications, an alternative to zeroing subnormal numbers is to inject a tiny bit of noise. For example, instead of initializing a with zeros, initialize it with:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"a = rand(Float32,1000) * 1.f-9","category":"page"},{"location":"manual/performance-tips/#man-code-warntype","page":"Performance Tips","title":"@code_warntype","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The macro @code_warntype (or its function variant code_warntype) can sometimes be helpful in diagnosing type-related problems. Here's an example:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"julia> @noinline pos(x) = x < 0 ? 0 : x;\n\njulia> function f(x)\n y = pos(x)\n return sin(y*x + 1)\n end;\n\njulia> @code_warntype f(3.2)\nMethodInstance for f(::Float64)\n from f(x) @ Main REPL[9]:1\nArguments\n #self#::Core.Const(f)\n x::Float64\nLocals\n y::Union{Float64, Int64}\nBody::Float64\n1 ─ (y = Main.pos(x))\n│ %2 = (y * x)::Float64\n│ %3 = (%2 + 1)::Float64\n│ %4 = Main.sin(%3)::Float64\n└── return %4","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Interpreting the output of @code_warntype, like that of its cousins @code_lowered, @code_typed, @code_llvm, and @code_native, takes a little practice. Your code is being presented in form that has been heavily digested on its way to generating compiled machine code. Most of the expressions are annotated by a type, indicated by the ::T (where T might be Float64, for example). The most important characteristic of @code_warntype is that non-concrete types are displayed in red; since this document is written in Markdown, which has no color, in this document, red text is denoted by uppercase.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"At the top, the inferred return type of the function is shown as Body::Float64. The next lines represent the body of f in Julia's SSA IR form. The numbered boxes are labels and represent targets for jumps (via goto) in your code. Looking at the body, you can see that the first thing that happens is that pos is called and the return value has been inferred as the Union type Union{Float64, Int64} shown in uppercase since it is a non-concrete type. This means that we cannot know the exact return type of pos based on the input types. However, the result of y*xis a Float64 no matter if y is a Float64 or Int64 The net result is that f(x::Float64) will not be type-unstable in its output, even if some of the intermediate computations are type-unstable.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"How you use this information is up to you. Obviously, it would be far and away best to fix pos to be type-stable: if you did so, all of the variables in f would be concrete, and its performance would be optimal. However, there are circumstances where this kind of ephemeral type instability might not matter too much: for example, if pos is never used in isolation, the fact that f's output is type-stable (for Float64 inputs) will shield later code from the propagating effects of type instability. This is particularly relevant in cases where fixing the type instability is difficult or impossible. In such cases, the tips above (e.g., adding type annotations and/or breaking up functions) are your best tools to contain the \"damage\" from type instability. Also, note that even Julia Base has functions that are type unstable. For example, the function findfirst returns the index into an array where a key is found, or nothing if it is not found, a clear type instability. In order to make it easier to find the type instabilities that are likely to be important, Unions containing either missing or nothing are color highlighted in yellow, instead of red.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The following examples may help you interpret expressions marked as containing non-leaf types:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Function body starting with Body::Union{T1,T2})\nInterpretation: function with unstable return type\nSuggestion: make the return value type-stable, even if you have to annotate it\ninvoke Main.g(%%x::Int64)::Union{Float64, Int64}\nInterpretation: call to a type-unstable function g.\nSuggestion: fix the function, or if necessary annotate the return value\ninvoke Base.getindex(%%x::Array{Any,1}, 1::Int64)::Any\nInterpretation: accessing elements of poorly-typed arrays\nSuggestion: use arrays with better-defined types, or if necessary annotate the type of individual element accesses\nBase.getfield(%%x, :(:data))::Array{Float64,N} where N\nInterpretation: getting a field that is of non-leaf type. In this case, the type of x, say ArrayContainer, had a field data::Array{T}. But Array needs the dimension N, too, to be a concrete type.\nSuggestion: use concrete types like Array{T,3} or Array{T,N}, where N is now a parameter of ArrayContainer","category":"page"},{"location":"manual/performance-tips/#man-performance-captured","page":"Performance Tips","title":"Performance of captured variable","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Consider the following example that defines an inner function:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function abmult(r::Int)\n if r < 0\n r = -r\n end\n f = x -> x * r\n return f\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Function abmult returns a function f that multiplies its argument by the absolute value of r. The inner function assigned to f is called a \"closure\". Inner functions are also used by the language for do-blocks and for generator expressions.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This style of code presents performance challenges for the language. The parser, when translating it into lower-level instructions, substantially reorganizes the above code by extracting the inner function to a separate code block. \"Captured\" variables such as r that are shared by inner functions and their enclosing scope are also extracted into a heap-allocated \"box\" accessible to both inner and outer functions because the language specifies that r in the inner scope must be identical to r in the outer scope even after the outer scope (or another inner function) modifies r.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The discussion in the preceding paragraph referred to the \"parser\", that is, the phase of compilation that takes place when the module containing abmult is first loaded, as opposed to the later phase when it is first invoked. The parser does not \"know\" that Int is a fixed type, or that the statement r = -r transforms an Int to another Int. The magic of type inference takes place in the later phase of compilation.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Thus, the parser does not know that r has a fixed type (Int). nor that r does not change value once the inner function is created (so that the box is unneeded). Therefore, the parser emits code for box that holds an object with an abstract type such as Any, which requires run-time type dispatch for each occurrence of r. This can be verified by applying @code_warntype to the above function. Both the boxing and the run-time type dispatch can cause loss of performance.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If captured variables are used in a performance-critical section of the code, then the following tips help ensure that their use is performant. First, if it is known that a captured variable does not change its type, then this can be declared explicitly with a type annotation (on the variable, not the right-hand side):","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function abmult2(r0::Int)\n r::Int = r0\n if r < 0\n r = -r\n end\n f = x -> x * r\n return f\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The type annotation partially recovers lost performance due to capturing because the parser can associate a concrete type to the object in the box. Going further, if the captured variable does not need to be boxed at all (because it will not be reassigned after the closure is created), this can be indicated with let blocks as follows.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"function abmult3(r::Int)\n if r < 0\n r = -r\n end\n f = let r = r\n x -> x * r\n end\n return f\nend","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"The let block creates a new variable r whose scope is only the inner function. The second technique recovers full language performance in the presence of captured variables. Note that this is a rapidly evolving aspect of the compiler, and it is likely that future releases will not require this degree of programmer annotation to attain performance. In the mean time, some user-contributed packages like FastClosures automate the insertion of let statements as in abmult3.","category":"page"},{"location":"manual/performance-tips/#man-multithreading-linear-algebra","page":"Performance Tips","title":"Multithreading and linear algebra","text":"","category":"section"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"This section applies to multithreaded Julia code which, in each thread, performs linear algebra operations. Indeed, these linear algebra operations involve BLAS / LAPACK calls, which are themselves multithreaded. In this case, one must ensure that cores aren't oversubscribed due to the two different types of multithreading.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"Julia compiles and uses its own copy of OpenBLAS for linear algebra, whose number of threads is controlled by the environment variable OPENBLAS_NUM_THREADS. It can either be set as a command line option when launching Julia, or modified during the Julia session with BLAS.set_num_threads(N) (the submodule BLAS is exported by using LinearAlgebra). Its current value can be accessed with BLAS.get_num_threads().","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When the user does not specify anything, Julia tries to choose a reasonable value for the number of OpenBLAS threads (e.g. based on the platform, the Julia version, etc.). However, it is generally recommended to check and set the value manually. The OpenBLAS behavior is as follows:","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"If OPENBLAS_NUM_THREADS=1, OpenBLAS uses the calling Julia thread(s), i.e. it \"lives in\" the Julia thread that runs the computation.\nIf OPENBLAS_NUM_THREADS=N>1, OpenBLAS creates and manages its own pool of threads (N in total). There is just one OpenBLAS thread pool shared among all Julia threads.","category":"page"},{"location":"manual/performance-tips/","page":"Performance Tips","title":"Performance Tips","text":"When you start Julia in multithreaded mode with JULIA_NUM_THREADS=X, it is generally recommended to set OPENBLAS_NUM_THREADS=1. Given the behavior described above, increasing the number of BLAS threads to N>1 can very easily lead to worse performance, in particular when N< c = 'x'\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\njulia> typeof(c)\nChar","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can easily convert a Char to its integer value, i.e. code point:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> c = Int('x')\n120\n\njulia> typeof(c)\nInt64","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"On 32-bit architectures, typeof(c) will be Int32. You can convert an integer value back to a Char just as easily:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> Char(120)\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Not all integer values are valid Unicode code points, but for performance, the Char conversion does not check that every character value is valid. If you want to check that each converted value is a valid code point, use the isvalid function:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> Char(0x110000)\n'\\U110000': Unicode U+110000 (category In: Invalid, too high)\n\njulia> isvalid(Char, 0x110000)\nfalse","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"As of this writing, the valid Unicode code points are U+0000 through U+D7FF and U+E000 through U+10FFFF. These have not all been assigned intelligible meanings yet, nor are they necessarily interpretable by applications, but all of these values are considered to be valid Unicode characters.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can input any Unicode character in single quotes using \\u followed by up to four hexadecimal digits or \\U followed by up to eight hexadecimal digits (the longest valid value only requires six):","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> '\\u0'\n'\\0': ASCII/Unicode U+0000 (category Cc: Other, control)\n\njulia> '\\u78'\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\njulia> '\\u2200'\n'∀': Unicode U+2200 (category Sm: Symbol, math)\n\njulia> '\\U10ffff'\n'\\U10ffff': Unicode U+10FFFF (category Cn: Other, not assigned)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia uses your system's locale and language settings to determine which characters can be printed as-is and which must be output using the generic, escaped \\u or \\U input forms. In addition to these Unicode escape forms, all of C's traditional escaped input forms can also be used:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> Int('\\0')\n0\n\njulia> Int('\\t')\n9\n\njulia> Int('\\n')\n10\n\njulia> Int('\\e')\n27\n\njulia> Int('\\x7f')\n127\n\njulia> Int('\\177')\n127","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can do comparisons and a limited amount of arithmetic with Char values:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> 'A' < 'a'\ntrue\n\njulia> 'A' <= 'a' <= 'Z'\nfalse\n\njulia> 'A' <= 'X' <= 'Z'\ntrue\n\njulia> 'x' - 'a'\n23\n\njulia> 'A' + 1\n'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)","category":"page"},{"location":"manual/strings/#String-Basics","page":"Strings","title":"String Basics","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"String literals are delimited by double quotes or triple double quotes (not single quotes):","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str = \"Hello, world.\\n\"\n\"Hello, world.\\n\"\n\njulia> \"\"\"Contains \"quote\" characters\"\"\"\n\"Contains \\\"quote\\\" characters\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Long lines in strings can be broken up by preceding the newline with a backslash (\\):","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"This is a long \\\n line\"\n\"This is a long line\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If you want to extract a character from a string, you index into it:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[begin]\n'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)\n\njulia> str[1]\n'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)\n\njulia> str[6]\n',': ASCII/Unicode U+002C (category Po: Punctuation, other)\n\njulia> str[end]\n'\\n': ASCII/Unicode U+000A (category Cc: Other, control)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Many Julia objects, including strings, can be indexed with integers. The index of the first element (the first character of a string) is returned by firstindex(str), and the index of the last element (character) with lastindex(str). The keywords begin and end can be used inside an indexing operation as shorthand for the first and last indices, respectively, along the given dimension. String indexing, like most indexing in Julia, is 1-based: firstindex always returns 1 for any AbstractString. As we will see below, however, lastindex(str) is not in general the same as length(str) for a string, because some Unicode characters can occupy multiple \"code units\".","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can perform arithmetic and other operations with end, just like a normal value:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[end-1]\n'.': ASCII/Unicode U+002E (category Po: Punctuation, other)\n\njulia> str[end÷2]\n' ': ASCII/Unicode U+0020 (category Zs: Separator, space)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Using an index less than begin (1) or greater than end raises an error:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[begin-1]\nERROR: BoundsError: attempt to access 14-codeunit String at index [0]\n[...]\n\njulia> str[end+1]\nERROR: BoundsError: attempt to access 14-codeunit String at index [15]\n[...]","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can also extract a substring using range indexing:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[4:9]\n\"lo, wo\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Notice that the expressions str[k] and str[k:k] do not give the same result:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str[6]\n',': ASCII/Unicode U+002C (category Po: Punctuation, other)\n\njulia> str[6:6]\n\",\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The former is a single character value of type Char, while the latter is a string value that happens to contain only a single character. In Julia these are very different things.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Range indexing makes a copy of the selected part of the original string. Alternatively, it is possible to create a view into a string using the type SubString. More simply, using the @views macro on a block of code converts all string slices into substrings. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str = \"long string\"\n\"long string\"\n\njulia> substr = SubString(str, 1, 4)\n\"long\"\n\njulia> typeof(substr)\nSubString{String}\n\njulia> @views typeof(str[1:4]) # @views converts slices to SubStrings\nSubString{String}","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Several standard functions like chop, chomp or strip return a SubString.","category":"page"},{"location":"manual/strings/#Unicode-and-UTF-8","page":"Strings","title":"Unicode and UTF-8","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia fully supports Unicode characters and strings. As discussed above, in character literals, Unicode code points can be represented using Unicode \\u and \\U escape sequences, as well as all the standard C escape sequences. These can likewise be used to write string literals:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s = \"\\u2200 x \\u2203 y\"\n\"∀ x ∃ y\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Whether these Unicode characters are displayed as escapes or shown as special characters depends on your terminal's locale settings and its support for Unicode. String literals are encoded using the UTF-8 encoding. UTF-8 is a variable-width encoding, meaning that not all characters are encoded in the same number of bytes (\"code units\"). In UTF-8, ASCII characters — i.e. those with code points less than 0x80 (128) – are encoded as they are in ASCII, using a single byte, while code points 0x80 and above are encoded using multiple bytes — up to four per character.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"String indices in Julia refer to code units (= bytes for UTF-8), the fixed-width building blocks that are used to encode arbitrary characters (code points). This means that not every index into a String is necessarily a valid index for a character. If you index into a string at such an invalid byte index, an error is thrown:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s[1]\n'∀': Unicode U+2200 (category Sm: Symbol, math)\n\njulia> s[2]\nERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'∀', [4]=>' '\nStacktrace:\n[...]\n\njulia> s[3]\nERROR: StringIndexError: invalid index [3], valid nearby indices [1]=>'∀', [4]=>' '\nStacktrace:\n[...]\n\njulia> s[4]\n' ': ASCII/Unicode U+0020 (category Zs: Separator, space)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"In this case, the character ∀ is a three-byte character, so the indices 2 and 3 are invalid and the next character's index is 4; this next valid index can be computed by nextind(s,1), and the next index after that by nextind(s,4) and so on.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Since end is always the last valid index into a collection, end-1 references an invalid byte index if the second-to-last character is multibyte.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s[end-1]\n' ': ASCII/Unicode U+0020 (category Zs: Separator, space)\n\njulia> s[end-2]\nERROR: StringIndexError: invalid index [9], valid nearby indices [7]=>'∃', [10]=>' '\nStacktrace:\n[...]\n\njulia> s[prevind(s, end, 2)]\n'∃': Unicode U+2203 (category Sm: Symbol, math)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The first case works, because the last character y and the space are one-byte characters, whereas end-2 indexes into the middle of the ∃ multibyte representation. The correct way for this case is using prevind(s, lastindex(s), 2) or, if you're using that value to index into s you can write s[prevind(s, end, 2)] and end expands to lastindex(s).","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Extraction of a substring using range indexing also expects valid byte indices or an error is thrown:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s[1:1]\n\"∀\"\n\njulia> s[1:2]\nERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'∀', [4]=>' '\nStacktrace:\n[...]\n\njulia> s[1:4]\n\"∀ \"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Because of variable-length encodings, the number of characters in a string (given by length(s)) is not always the same as the last index. If you iterate through the indices 1 through lastindex(s) and index into s, the sequence of characters returned when errors aren't thrown is the sequence of characters comprising the string s. Thus length(s) <= lastindex(s), since each character in a string must have its own index. The following is an inefficient and verbose way to iterate through the characters of s:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> for i = firstindex(s):lastindex(s)\n try\n println(s[i])\n catch\n # ignore the index error\n end\n end\n∀\n\nx\n\n∃\n\ny","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The blank lines actually have spaces on them. Fortunately, the above awkward idiom is unnecessary for iterating through the characters in a string, since you can just use the string as an iterable object, no exception handling required:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> for c in s\n println(c)\n end\n∀\n\nx\n\n∃\n\ny","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If you need to obtain valid indices for a string, you can use the nextind and prevind functions to increment/decrement to the next/previous valid index, as mentioned above. You can also use the eachindex function to iterate over the valid character indices:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> collect(eachindex(s))\n7-element Vector{Int64}:\n 1\n 4\n 5\n 6\n 7\n 10\n 11","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"To access the raw code units (bytes for UTF-8) of the encoding, you can use the codeunit(s,i) function, where the index i runs consecutively from 1 to ncodeunits(s). The codeunits(s) function returns an AbstractVector{UInt8} wrapper that lets you access these raw codeunits (bytes) as an array.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Strings in Julia can contain invalid UTF-8 code unit sequences. This convention allows to treat any byte sequence as a String. In such situations a rule is that when parsing a sequence of code units from left to right characters are formed by the longest sequence of 8-bit code units that matches the start of one of the following bit patterns (each x can be 0 or 1):","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"0xxxxxxx;\n110xxxxx 10xxxxxx;\n1110xxxx 10xxxxxx 10xxxxxx;\n11110xxx 10xxxxxx 10xxxxxx 10xxxxxx;\n10xxxxxx;\n11111xxx.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"In particular this means that overlong and too-high code unit sequences and prefixes thereof are treated as a single invalid character rather than multiple invalid characters. This rule may be best explained with an example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> s = \"\\xc0\\xa0\\xe2\\x88\\xe2|\"\n\"\\xc0\\xa0\\xe2\\x88\\xe2|\"\n\njulia> foreach(display, s)\n'\\xc0\\xa0': [overlong] ASCII/Unicode U+0020 (category Zs: Separator, space)\n'\\xe2\\x88': Malformed UTF-8 (category Ma: Malformed, bad data)\n'\\xe2': Malformed UTF-8 (category Ma: Malformed, bad data)\n'|': ASCII/Unicode U+007C (category Sm: Symbol, math)\n\njulia> isvalid.(collect(s))\n4-element BitArray{1}:\n 0\n 0\n 0\n 1\n\njulia> s2 = \"\\xf7\\xbf\\xbf\\xbf\"\n\"\\U1fffff\"\n\njulia> foreach(display, s2)\n'\\U1fffff': Unicode U+1FFFFF (category In: Invalid, too high)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"We can see that the first two code units in the string s form an overlong encoding of space character. It is invalid, but is accepted in a string as a single character. The next two code units form a valid start of a three-byte UTF-8 sequence. However, the fifth code unit \\xe2 is not its valid continuation. Therefore code units 3 and 4 are also interpreted as malformed characters in this string. Similarly code unit 5 forms a malformed character because | is not a valid continuation to it. Finally the string s2 contains one too high code point.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia uses the UTF-8 encoding by default, and support for new encodings can be added by packages. For example, the LegacyStrings.jl package implements UTF16String and UTF32String types. Additional discussion of other encodings and how to implement support for them is beyond the scope of this document for the time being. For further discussion of UTF-8 encoding issues, see the section below on byte array literals. The transcode function is provided to convert data between the various UTF-xx encodings, primarily for working with external data and libraries.","category":"page"},{"location":"manual/strings/#man-concatenation","page":"Strings","title":"Concatenation","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"One of the most common and useful string operations is concatenation:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> greet = \"Hello\"\n\"Hello\"\n\njulia> whom = \"world\"\n\"world\"\n\njulia> string(greet, \", \", whom, \".\\n\")\n\"Hello, world.\\n\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"It's important to be aware of potentially dangerous situations such as concatenation of invalid UTF-8 strings. The resulting string may contain different characters than the input strings, and its number of characters may be lower than sum of numbers of characters of the concatenated strings, e.g.:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> a, b = \"\\xe2\\x88\", \"\\x80\"\n(\"\\xe2\\x88\", \"\\x80\")\n\njulia> c = string(a, b)\n\"∀\"\n\njulia> collect.([a, b, c])\n3-element Vector{Vector{Char}}:\n ['\\xe2\\x88']\n ['\\x80']\n ['∀']\n\njulia> length.([a, b, c])\n3-element Vector{Int64}:\n 1\n 1\n 1","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"This situation can happen only for invalid UTF-8 strings. For valid UTF-8 strings concatenation preserves all characters in strings and additivity of string lengths.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia also provides * for string concatenation:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> greet * \", \" * whom * \".\\n\"\n\"Hello, world.\\n\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"While * may seem like a surprising choice to users of languages that provide + for string concatenation, this use of * has precedent in mathematics, particularly in abstract algebra.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"In mathematics, + usually denotes a commutative operation, where the order of the operands does not matter. An example of this is matrix addition, where A + B == B + A for any matrices A and B that have the same shape. In contrast, * typically denotes a noncommutative operation, where the order of the operands does matter. An example of this is matrix multiplication, where in general A * B != B * A. As with matrix multiplication, string concatenation is noncommutative: greet * whom != whom * greet. As such, * is a more natural choice for an infix string concatenation operator, consistent with common mathematical use.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"More precisely, the set of all finite-length strings S together with the string concatenation operator * forms a free monoid (S, *). The identity element of this set is the empty string, \"\". Whenever a free monoid is not commutative, the operation is typically represented as \\cdot, *, or a similar symbol, rather than +, which as stated usually implies commutativity.","category":"page"},{"location":"manual/strings/#string-interpolation","page":"Strings","title":"Interpolation","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Constructing strings using concatenation can become a bit cumbersome, however. To reduce the need for these verbose calls to string or repeated multiplications, Julia allows interpolation into string literals using $, as in Perl:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> greet = \"Hello\"; whom = \"world\";\n\njulia> \"$greet, $whom.\\n\"\n\"Hello, world.\\n\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"This is more readable and convenient and equivalent to the above string concatenation – the system rewrites this apparent single string literal into the call string(greet, \", \", whom, \".\\n\").","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The shortest complete expression after the $ is taken as the expression whose value is to be interpolated into the string. Thus, you can interpolate any expression into a string using parentheses:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"1 + 2 = $(1 + 2)\"\n\"1 + 2 = 3\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Both concatenation and string interpolation call string to convert objects into string form. However, string actually just returns the output of print, so new types should add methods to print or show instead of string.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Most non-AbstractString objects are converted to strings closely corresponding to how they are entered as literal expressions:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> v = [1,2,3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> \"v: $v\"\n\"v: [1, 2, 3]\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"string is the identity for AbstractString and AbstractChar values, so these are interpolated into strings as themselves, unquoted and unescaped:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> c = 'x'\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\njulia> \"hi, $c\"\n\"hi, x\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"To include a literal $ in a string literal, escape it with a backslash:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> print(\"I have \\$100 in my account.\\n\")\nI have $100 in my account.","category":"page"},{"location":"manual/strings/#Triple-Quoted-String-Literals","page":"Strings","title":"Triple-Quoted String Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"When strings are created using triple-quotes (\"\"\"...\"\"\") they have some special behavior that can be useful for creating longer blocks of text.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"First, triple-quoted strings are also dedented to the level of the least-indented line. This is useful for defining strings within code that is indented. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str = \"\"\"\n Hello,\n world.\n \"\"\"\n\" Hello,\\n world.\\n\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"In this case the final (empty) line before the closing \"\"\" sets the indentation level.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The dedentation level is determined as the longest common starting sequence of spaces or tabs in all lines, excluding the line following the opening \"\"\" and lines containing only spaces or tabs (the line containing the closing \"\"\" is always included). Then for all lines, excluding the text following the opening \"\"\", the common starting sequence is removed (including lines containing only spaces and tabs if they start with this sequence), e.g.:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"\"\" This\n is\n a test\"\"\"\n\" This\\nis\\n a test\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Next, if the opening \"\"\" is followed by a newline, the newline is stripped from the resulting string.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"\"\"\"hello\"\"\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"is equivalent to","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"\"\"\"\nhello\"\"\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"but","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"\"\"\"\n\nhello\"\"\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"will contain a literal newline at the beginning.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Stripping of the newline is performed after the dedentation. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"\"\"\n Hello,\n world.\"\"\"\n\"Hello,\\nworld.\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If the newline is removed using a backslash, dedentation will be respected as well:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"\"\"\n Averylong\\\n word\"\"\"\n\"Averylongword\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Trailing whitespace is left unaltered.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Triple-quoted string literals can contain \" characters without escaping.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Note that line breaks in literal strings, whether single- or triple-quoted, result in a newline (LF) character \\n in the string, even if your editor uses a carriage return \\r (CR) or CRLF combination to end lines. To include a CR in a string, use an explicit escape \\r; for example, you can enter the literal string \"a CRLF line ending\\r\\n\".","category":"page"},{"location":"manual/strings/#Common-Operations","page":"Strings","title":"Common Operations","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can lexicographically compare strings using the standard comparison operators:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> \"abracadabra\" < \"xylophone\"\ntrue\n\njulia> \"abracadabra\" == \"xylophone\"\nfalse\n\njulia> \"Hello, world.\" != \"Goodbye, world.\"\ntrue\n\njulia> \"1 + 2 = 3\" == \"1 + 2 = $(1 + 2)\"\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can search for the index of a particular character using the findfirst and findlast functions:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> findfirst('o', \"xylophone\")\n4\n\njulia> findlast('o', \"xylophone\")\n7\n\njulia> findfirst('z', \"xylophone\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can start the search for a character at a given offset by using the functions findnext and findprev:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> findnext('o', \"xylophone\", 1)\n4\n\njulia> findnext('o', \"xylophone\", 5)\n7\n\njulia> findprev('o', \"xylophone\", 5)\n4\n\njulia> findnext('o', \"xylophone\", 8)","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can use the occursin function to check if a substring is found within a string:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> occursin(\"world\", \"Hello, world.\")\ntrue\n\njulia> occursin(\"o\", \"Xylophon\")\ntrue\n\njulia> occursin(\"a\", \"Xylophon\")\nfalse\n\njulia> occursin('o', \"Xylophon\")\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The last example shows that occursin can also look for a character literal.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Two other handy string functions are repeat and join:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> repeat(\".:Z:.\", 10)\n\".:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:.\"\n\njulia> join([\"apples\", \"bananas\", \"pineapples\"], \", \", \" and \")\n\"apples, bananas and pineapples\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Some other useful functions include:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"firstindex(str) gives the minimal (byte) index that can be used to index into str (always 1 for strings, not necessarily true for other containers).\nlastindex(str) gives the maximal (byte) index that can be used to index into str.\nlength(str) the number of characters in str.\nlength(str, i, j) the number of valid character indices in str from i to j.\nncodeunits(str) number of code units in a string.\ncodeunit(str, i) gives the code unit value in the string str at index i.\nthisind(str, i) given an arbitrary index into a string find the first index of the character into which the index points.\nnextind(str, i, n=1) find the start of the nth character starting after index i.\nprevind(str, i, n=1) find the start of the nth character starting before index i.","category":"page"},{"location":"manual/strings/#non-standard-string-literals","page":"Strings","title":"Non-Standard String Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"There are situations when you want to construct a string or use string semantics, but the behavior of the standard string construct is not quite what is needed. For these kinds of situations, Julia provides non-standard string literals. A non-standard string literal looks like a regular double-quoted string literal, but is immediately prefixed by an identifier, and may behave differently from a normal string literal.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Regular expressions, byte array literals, and version number literals, as described below, are some examples of non-standard string literals. Users and packages may also define new non-standard string literals. Further documentation is given in the Metaprogramming section.","category":"page"},{"location":"manual/strings/#man-regex-literals","page":"Strings","title":"Regular Expressions","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Sometimes you are not looking for an exact string, but a particular pattern. For example, suppose you are trying to extract a single date from a large text file. You don’t know what that date is (that’s why you are searching for it), but you do know it will look something like YYYY-MM-DD. Regular expressions allow you to specify these patterns and search for them.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Julia uses version 2 of Perl-compatible regular expressions (regexes), as provided by the PCRE library (see the PCRE2 syntax description for more details). Regular expressions are related to strings in two ways: the obvious connection is that regular expressions are used to find regular patterns in strings; the other connection is that regular expressions are themselves input as strings, which are parsed into a state machine that can be used to efficiently search for patterns in strings. In Julia, regular expressions are input using non-standard string literals prefixed with various identifiers beginning with r. The most basic regular expression literal without any options turned on just uses r\"...\":","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> re = r\"^\\s*(?:#|$)\"\nr\"^\\s*(?:#|$)\"\n\njulia> typeof(re)\nRegex","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"To check if a regex matches a string, use occursin:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> occursin(r\"^\\s*(?:#|$)\", \"not a comment\")\nfalse\n\njulia> occursin(r\"^\\s*(?:#|$)\", \"# a comment\")\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"As one can see here, occursin simply returns true or false, indicating whether a match for the given regex occurs in the string. Commonly, however, one wants to know not just whether a string matched, but also how it matched. To capture this information about a match, use the match function instead:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> match(r\"^\\s*(?:#|$)\", \"not a comment\")\n\njulia> match(r\"^\\s*(?:#|$)\", \"# a comment\")\nRegexMatch(\"#\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If the regular expression does not match the given string, match returns nothing – a special value that does not print anything at the interactive prompt. Other than not printing, it is a completely normal value and you can test for it programmatically:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"m = match(r\"^\\s*(?:#|$)\", line)\nif m === nothing\n println(\"not a comment\")\nelse\n println(\"blank or comment\")\nend","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If a regular expression does match, the value returned by match is a RegexMatch object. These objects record how the expression matches, including the substring that the pattern matches and any captured substrings, if there are any. This example only captures the portion of the substring that matches, but perhaps we want to capture any non-blank text after the comment character. We could do the following:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> m = match(r\"^\\s*(?:#\\s*(.*?)\\s*$)\", \"# a comment \")\nRegexMatch(\"# a comment \", 1=\"a comment\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"When calling match, you have the option to specify an index at which to start the search. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> m = match(r\"[0-9]\",\"aaaa1aaaa2aaaa3\",1)\nRegexMatch(\"1\")\n\njulia> m = match(r\"[0-9]\",\"aaaa1aaaa2aaaa3\",6)\nRegexMatch(\"2\")\n\njulia> m = match(r\"[0-9]\",\"aaaa1aaaa2aaaa3\",11)\nRegexMatch(\"3\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can extract the following info from a RegexMatch object:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"the entire substring matched: m.match\nthe captured substrings as an array of strings: m.captures\nthe offset at which the whole match begins: m.offset\nthe offsets of the captured substrings as a vector: m.offsets","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"For when a capture doesn't match, instead of a substring, m.captures contains nothing in that position, and m.offsets has a zero offset (recall that indices in Julia are 1-based, so a zero offset into a string is invalid). Here is a pair of somewhat contrived examples:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> m = match(r\"(a|b)(c)?(d)\", \"acd\")\nRegexMatch(\"acd\", 1=\"a\", 2=\"c\", 3=\"d\")\n\njulia> m.match\n\"acd\"\n\njulia> m.captures\n3-element Vector{Union{Nothing, SubString{String}}}:\n \"a\"\n \"c\"\n \"d\"\n\njulia> m.offset\n1\n\njulia> m.offsets\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> m = match(r\"(a|b)(c)?(d)\", \"ad\")\nRegexMatch(\"ad\", 1=\"a\", 2=nothing, 3=\"d\")\n\njulia> m.match\n\"ad\"\n\njulia> m.captures\n3-element Vector{Union{Nothing, SubString{String}}}:\n \"a\"\n nothing\n \"d\"\n\njulia> m.offset\n1\n\njulia> m.offsets\n3-element Vector{Int64}:\n 1\n 0\n 2","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"It is convenient to have captures returned as an array so that one can use destructuring syntax to bind them to local variables. As a convenience, the RegexMatch object implements iterator methods that pass through to the captures field, so you can destructure the match object directly:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> first, second, third = m; first\n\"a\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Captures can also be accessed by indexing the RegexMatch object with the number or name of the capture group:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> m=match(r\"(?\\d+):(?\\d+)\",\"12:45\")\nRegexMatch(\"12:45\", hour=\"12\", minute=\"45\")\n\njulia> m[:minute]\n\"45\"\n\njulia> m[2]\n\"45\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Captures can be referenced in a substitution string when using replace by using \\n to refer to the nth capture group and prefixing the substitution string with s. Capture group 0 refers to the entire match object. Named capture groups can be referenced in the substitution with \\g. For example:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> replace(\"first second\", r\"(\\w+) (?\\w+)\" => s\"\\g \\1\")\n\"second first\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Numbered capture groups can also be referenced as \\g for disambiguation, as in:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> replace(\"a\", r\".\" => s\"\\g<0>1\")\n\"a1\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"You can modify the behavior of regular expressions by some combination of the flags i, m, s, and x after the closing double quote mark. These flags have the same meaning as they do in Perl, as explained in this excerpt from the perlre manpage:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"i Do case-insensitive pattern matching.\n\n If locale matching rules are in effect, the case map is taken\n from the current locale for code points less than 255, and\n from Unicode rules for larger code points. However, matches\n that would cross the Unicode rules/non-Unicode rules boundary\n (ords 255/256) will not succeed.\n\nm Treat string as multiple lines. That is, change \"^\" and \"$\"\n from matching the start or end of the string to matching the\n start or end of any line anywhere within the string.\n\ns Treat string as single line. That is, change \".\" to match any\n character whatsoever, even a newline, which normally it would\n not match.\n\n Used together, as r\"\"ms, they let the \".\" match any character\n whatsoever, while still allowing \"^\" and \"$\" to match,\n respectively, just after and just before newlines within the\n string.\n\nx Tells the regular expression parser to ignore most whitespace\n that is neither backslashed nor within a character class. You\n can use this to break up your regular expression into\n (slightly) more readable parts. The '#' character is also\n treated as a metacharacter introducing a comment, just as in\n ordinary code.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"For example, the following regex has all three flags turned on:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> r\"a+.*b+.*d$\"ism\nr\"a+.*b+.*d$\"ims\n\njulia> match(r\"a+.*b+.*d$\"ism, \"Goodbye,\\nOh, angry,\\nBad world\\n\")\nRegexMatch(\"angry,\\nBad world\")","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The r\"...\" literal is constructed without interpolation and unescaping (except for quotation mark \" which still has to be escaped). Here is an example showing the difference from standard string literals:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> x = 10\n10\n\njulia> r\"$x\"\nr\"$x\"\n\njulia> \"$x\"\n\"10\"\n\njulia> r\"\\x\"\nr\"\\x\"\n\njulia> \"\\x\"\nERROR: syntax: invalid escape sequence","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Triple-quoted regex strings, of the form r\"\"\"...\"\"\", are also supported (and may be convenient for regular expressions containing quotation marks or newlines).","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The Regex() constructor may be used to create a valid regex string programmatically. This permits using the contents of string variables and other string operations when constructing the regex string. Any of the regex codes above can be used within the single string argument to Regex(). Here are some examples:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> using Dates\n\njulia> d = Date(1962,7,10)\n1962-07-10\n\njulia> regex_d = Regex(\"Day \" * string(day(d)))\nr\"Day 10\"\n\njulia> match(regex_d, \"It happened on Day 10\")\nRegexMatch(\"Day 10\")\n\njulia> name = \"Jon\"\n\"Jon\"\n\njulia> regex_name = Regex(\"[\\\"( ]\\\\Q$name\\\\E[\\\") ]\") # interpolate value of name\nr\"[\\\"( ]\\QJon\\E[\\\") ]\"\n\njulia> match(regex_name, \" Jon \")\nRegexMatch(\" Jon \")\n\njulia> match(regex_name, \"[Jon]\") === nothing\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Note the use of the \\Q...\\E escape sequence. All characters between the \\Q and the \\E are interpreted as literal characters. This is convenient for matching characters that would otherwise be regex metacharacters. However, caution is needed when using this feature together with string interpolation, since the interpolated string might itself contain the \\E sequence, unexpectedly terminating literal matching. User inputs need to be sanitized before inclusion in a regex.","category":"page"},{"location":"manual/strings/#man-byte-array-literals","page":"Strings","title":"Byte Array Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Another useful non-standard string literal is the byte-array string literal: b\"...\". This form lets you use string notation to express read only literal byte arrays – i.e. arrays of UInt8 values. The type of those objects is CodeUnits{UInt8, String}. The rules for byte array literals are the following:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"ASCII characters and ASCII escapes produce a single byte.\n\\x and octal escape sequences produce the byte corresponding to the escape value.\nUnicode escape sequences produce a sequence of bytes encoding that code point in UTF-8.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"There is some overlap between these rules since the behavior of \\x and octal escapes less than 0x80 (128) are covered by both of the first two rules, but here these rules agree. Together, these rules allow one to easily use ASCII characters, arbitrary byte values, and UTF-8 sequences to produce arrays of bytes. Here is an example using all three:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> b\"DATA\\xff\\u2200\"\n8-element Base.CodeUnits{UInt8, String}:\n 0x44\n 0x41\n 0x54\n 0x41\n 0xff\n 0xe2\n 0x88\n 0x80","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The ASCII string \"DATA\" corresponds to the bytes 68, 65, 84, 65. \\xff produces the single byte 255. The Unicode escape \\u2200 is encoded in UTF-8 as the three bytes 226, 136, 128. Note that the resulting byte array does not correspond to a valid UTF-8 string:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> isvalid(\"DATA\\xff\\u2200\")\nfalse","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"As it was mentioned CodeUnits{UInt8, String} type behaves like read only array of UInt8 and if you need a standard vector you can convert it using Vector{UInt8}:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> x = b\"123\"\n3-element Base.CodeUnits{UInt8, String}:\n 0x31\n 0x32\n 0x33\n\njulia> x[1]\n0x31\n\njulia> x[1] = 0x32\nERROR: CanonicalIndexError: setindex! not defined for Base.CodeUnits{UInt8, String}\n[...]\n\njulia> Vector{UInt8}(x)\n3-element Vector{UInt8}:\n 0x31\n 0x32\n 0x33","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Also observe the significant distinction between \\xff and \\uff: the former escape sequence encodes the byte 255, whereas the latter escape sequence represents the code point 255, which is encoded as two bytes in UTF-8:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> b\"\\xff\"\n1-element Base.CodeUnits{UInt8, String}:\n 0xff\n\njulia> b\"\\uff\"\n2-element Base.CodeUnits{UInt8, String}:\n 0xc3\n 0xbf","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Character literals use the same behavior.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"For code points less than \\u80, it happens that the UTF-8 encoding of each code point is just the single byte produced by the corresponding \\x escape, so the distinction can safely be ignored. For the escapes \\x80 through \\xff as compared to \\u80 through \\uff, however, there is a major difference: the former escapes all encode single bytes, which – unless followed by very specific continuation bytes – do not form valid UTF-8 data, whereas the latter escapes all represent Unicode code points with two-byte encodings.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"If this is all extremely confusing, try reading \"The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets\". It's an excellent introduction to Unicode and UTF-8, and may help alleviate some confusion regarding the matter.","category":"page"},{"location":"manual/strings/#man-version-number-literals","page":"Strings","title":"Version Number Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Version numbers can easily be expressed with non-standard string literals of the form v\"...\". Version number literals create VersionNumber objects which follow the specifications of semantic versioning 2.0.0-rc2, and therefore are composed of major, minor and patch numeric values, followed by pre-release and build alphanumeric annotations. For example, v\"0.2.1-rc1+win64\" is broken into major version 0, minor version 2, patch version 1, pre-release rc1 and build win64. When entering a version literal, everything except the major version number is optional, therefore e.g. v\"0.2\" is equivalent to v\"0.2.0\" (with empty pre-release/build annotations), v\"2\" is equivalent to v\"2.0.0\", and so on.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"VersionNumber objects are mostly useful to easily and correctly compare two (or more) versions. For example, the constant VERSION holds Julia version number as a VersionNumber object, and therefore one can define some version-specific behavior using simple statements as:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"if v\"0.2\" <= VERSION < v\"0.3-\"\n # do something specific to 0.2 release series\nend","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Note that in the above example the non-standard version number v\"0.3-\" is used, with a trailing -: this notation is a Julia extension of the standard, and it's used to indicate a version which is lower than any 0.3 release, including all of its pre-releases. So in the above example the code would only run with stable 0.2 versions, and exclude such versions as v\"0.3.0-rc1\". In order to also allow for unstable (i.e. pre-release) 0.2 versions, the lower bound check should be modified like this: v\"0.2-\" <= VERSION.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Another non-standard version specification extension allows one to use a trailing + to express an upper limit on build versions, e.g. VERSION > v\"0.2-rc1+\" can be used to mean any version above 0.2-rc1 and any of its builds: it will return false for version v\"0.2-rc1+win64\" and true for v\"0.2-rc2\".","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"It is good practice to use such special versions in comparisons (particularly, the trailing - should always be used on upper bounds unless there's a good reason not to), but they must not be used as the actual version number of anything, as they are invalid in the semantic versioning scheme.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Besides being used for the VERSION constant, VersionNumber objects are widely used in the Pkg module, to specify packages versions and their dependencies.","category":"page"},{"location":"manual/strings/#man-raw-string-literals","page":"Strings","title":"Raw String Literals","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Raw strings without interpolation or unescaping can be expressed with non-standard string literals of the form raw\"...\". Raw string literals create ordinary String objects which contain the enclosed contents exactly as entered with no interpolation or unescaping. This is useful for strings which contain code or markup in other languages which use $ or \\ as special characters.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The exception is that quotation marks still must be escaped, e.g. raw\"\\\"\" is equivalent to \"\\\"\". To make it possible to express all strings, backslashes then also must be escaped, but only when appearing right before a quote character:","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> println(raw\"\\\\ \\\\\\\"\")\n\\\\ \\\"","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"Notice that the first two backslashes appear verbatim in the output, since they do not precede a quote character. However, the next backslash character escapes the backslash that follows it, and the last backslash escapes a quote, since these backslashes appear before a quote.","category":"page"},{"location":"manual/strings/#man-annotated-strings","page":"Strings","title":"Annotated Strings","text":"","category":"section"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"It is sometimes useful to be able to hold metadata relating to regions of a string. A AnnotatedString wraps another string and allows for regions of it to be annotated with labelled values (:label => value). All generic string operations are applied to the underlying string. However, when possible, styling information is preserved. This means you can manipulate a AnnotatedString —taking substrings, padding them, concatenating them with other strings— and the metadata annotations will \"come along for the ride\".","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"This string type is fundamental to the StyledStrings stdlib, which uses :face-labelled annotations to hold styling information.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"When concatenating a AnnotatedString, take care to use annotatedstring instead of string if you want to keep the string annotations.","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"julia> str = Base.AnnotatedString(\"hello there\",\n [(1:5, :word => :greeting), (7:11, :label => 1)])\n\"hello there\"\n\njulia> length(str)\n11\n\njulia> lpad(str, 14)\n\" hello there\"\n\njulia> typeof(lpad(str, 7))\nBase.AnnotatedString{String}\n\njulia> str2 = Base.AnnotatedString(\" julia\", [(2:6, :face => :magenta)])\n\" julia\"\n\njulia> Base.annotatedstring(str, str2)\n\"hello there julia\"\n\njulia> str * str2 == Base.annotatedstring(str, str2) # *-concatenation still works\ntrue","category":"page"},{"location":"manual/strings/","page":"Strings","title":"Strings","text":"The annotations of a AnnotatedString can be accessed and modified via the annotations and annotate! functions.","category":"page"},{"location":"base/base/#Essentials","page":"Essentials","title":"Essentials","text":"","category":"section"},{"location":"base/base/#Introduction","page":"Essentials","title":"Introduction","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Julia Base contains a range of functions and macros appropriate for performing scientific and numerical computing, but is also as broad as those of many general purpose programming languages. Additional functionality is available from a growing collection of available packages. Functions are grouped by topic below.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Some general notes:","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"To use module functions, use import Module to import the module, and Module.fn(x) to use the functions.\nAlternatively, using Module will import all exported Module functions into the current namespace.\nBy convention, function names ending with an exclamation point (!) modify their arguments. Some functions have both modifying (e.g., sort!) and non-modifying (sort) versions.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"The behaviors of Base and standard libraries are stable as defined in SemVer only if they are documented; i.e., included in the Julia documentation and not marked as unstable. See API FAQ for more information.","category":"page"},{"location":"base/base/#Getting-Around","page":"Essentials","title":"Getting Around","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.exit\nBase.atexit\nBase.isinteractive\nBase.summarysize\nBase.__precompile__\nBase.include\nMain.include\nBase.include_string\nBase.include_dependency\n__init__\nBase.which(::Any, ::Any)\nBase.methods\nBase.@show\nans\nerr\nBase.active_project\nBase.set_active_project","category":"page"},{"location":"base/base/#Base.exit","page":"Essentials","title":"Base.exit","text":"exit(code=0)\n\nStop the program with an exit code. The default exit code is zero, indicating that the program completed successfully. In an interactive session, exit() can be called with the keyboard shortcut ^D.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.atexit","page":"Essentials","title":"Base.atexit","text":"atexit(f)\n\nRegister a zero- or one-argument function f() to be called at process exit. atexit() hooks are called in last in first out (LIFO) order and run before object finalizers.\n\nIf f has a method defined for one integer argument, it will be called as f(n::Int32), where n is the current exit code, otherwise it will be called as f().\n\ncompat: Julia 1.9\nThe one-argument form requires Julia 1.9\n\nExit hooks are allowed to call exit(n), in which case Julia will exit with exit code n (instead of the original exit code). If more than one exit hook calls exit(n), then Julia will exit with the exit code corresponding to the last called exit hook that calls exit(n). (Because exit hooks are called in LIFO order, \"last called\" is equivalent to \"first registered\".)\n\nNote: Once all exit hooks have been called, no more exit hooks can be registered, and any call to atexit(f) after all hooks have completed will throw an exception. This situation may occur if you are registering exit hooks from background Tasks that may still be executing concurrently during shutdown.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isinteractive","page":"Essentials","title":"Base.isinteractive","text":"isinteractive() -> Bool\n\nDetermine whether Julia is running an interactive session.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.summarysize","page":"Essentials","title":"Base.summarysize","text":"Base.summarysize(obj; exclude=Union{...}, chargeall=Union{...}) -> Int\n\nCompute the amount of memory, in bytes, used by all unique objects reachable from the argument.\n\nKeyword Arguments\n\nexclude: specifies the types of objects to exclude from the traversal.\nchargeall: specifies the types of objects to always charge the size of all of their fields, even if those fields would normally be excluded.\n\nSee also sizeof.\n\nExamples\n\njulia> Base.summarysize(1.0)\n8\n\njulia> Base.summarysize(Ref(rand(100)))\n864\n\njulia> sizeof(Ref(rand(100)))\n8\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.__precompile__","page":"Essentials","title":"Base.__precompile__","text":"__precompile__(isprecompilable::Bool)\n\nSpecify whether the file calling this function is precompilable, defaulting to true. If a module or file is not safely precompilable, it should call __precompile__(false) in order to throw an error if Julia attempts to precompile it.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.include","page":"Essentials","title":"Base.include","text":"Base.include([mapexpr::Function,] m::Module, path::AbstractString)\n\nEvaluate the contents of the input source file in the global scope of module m. Every module (except those defined with baremodule) has its own definition of include omitting the m argument, which evaluates the file in that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to include will search relative to that path. This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files.\n\nThe optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in path, the include function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.\n\ncompat: Julia 1.5\nJulia 1.5 is required for passing the mapexpr argument.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#include","page":"Essentials","title":"include","text":"include([mapexpr::Function,] path::AbstractString)\n\nEvaluate the contents of the input source file in the global scope of the containing module. Every module (except those defined with baremodule) has its own definition of include, which evaluates the file in that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to include will search relative to that path. This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files. The argument path is normalized using normpath which will resolve relative path tokens such as .. and convert / to the appropriate path separator.\n\nThe optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in path, the include function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.\n\nUse Base.include to evaluate a file into another module.\n\ncompat: Julia 1.5\nJulia 1.5 is required for passing the mapexpr argument.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.include_string","page":"Essentials","title":"Base.include_string","text":"include_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString=\"string\")\n\nLike include, except reads code from the given string rather than from a file.\n\nThe optional first argument mapexpr can be used to transform the included code before it is evaluated: for each parsed expression expr in code, the include_string function actually evaluates mapexpr(expr). If it is omitted, mapexpr defaults to identity.\n\ncompat: Julia 1.5\nJulia 1.5 is required for passing the mapexpr argument.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.include_dependency","page":"Essentials","title":"Base.include_dependency","text":"include_dependency(path::AbstractString; track_content::Bool=false)\n\nIn a module, declare that the file, directory, or symbolic link specified by path (relative or absolute) is a dependency for precompilation; that is, the module will need to be recompiled if the modification time mtime of path changes. If track_content=true recompilation is triggered when the content of path changes (if path is a directory the content equals join(readdir(path))).\n\nThis is only needed if your module depends on a path that is not used via include. It has no effect outside of compilation.\n\ncompat: Julia 1.11\nKeyword argument track_content requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#__init__","page":"Essentials","title":"__init__","text":"__init__\n\nThe __init__() function in a module executes immediately after the module is loaded at runtime for the first time. It is called once, after all other statements in the module have been executed. Because it is called after fully importing the module, __init__ functions of submodules will be executed first. Two typical uses of __init__ are calling runtime initialization functions of external C libraries and initializing global constants that involve pointers returned by external libraries. See the manual section about modules for more details.\n\nExamples\n\nconst foo_data_ptr = Ref{Ptr{Cvoid}}(0)\nfunction __init__()\n ccall((:foo_init, :libfoo), Cvoid, ())\n foo_data_ptr[] = ccall((:foo_data, :libfoo), Ptr{Cvoid}, ())\n nothing\nend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.which-Tuple{Any, Any}","page":"Essentials","title":"Base.which","text":"which(f, types)\n\nReturns the method of f (a Method object) that would be called for arguments of the given types.\n\nIf types is an abstract type, then the method that would be called by invoke is returned.\n\nSee also: parentmodule, @which, and @edit.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.methods","page":"Essentials","title":"Base.methods","text":"methods(f, [types], [module])\n\nReturn the method table for f.\n\nIf types is specified, return an array of methods whose types match. If module is specified, return an array of methods defined in that module. A list of modules can also be specified as an array.\n\ncompat: Julia 1.4\nAt least Julia 1.4 is required for specifying a module.\n\nSee also: which, @which and methodswith.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@show","page":"Essentials","title":"Base.@show","text":"@show exs...\n\nPrints one or more expressions, and their results, to stdout, and returns the last result.\n\nSee also: show, @info, println.\n\nExamples\n\njulia> x = @show 1+2\n1 + 2 = 3\n3\n\njulia> @show x^2 x/2;\nx ^ 2 = 9\nx / 2 = 1.5\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.MainInclude.ans","page":"Essentials","title":"Base.MainInclude.ans","text":"ans\n\nA variable referring to the last computed value, automatically imported to the interactive prompt.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.MainInclude.err","page":"Essentials","title":"Base.MainInclude.err","text":"err\n\nA variable referring to the last thrown errors, automatically imported to the interactive prompt. The thrown errors are collected in a stack of exceptions.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.active_project","page":"Essentials","title":"Base.active_project","text":"active_project()\n\nReturn the path of the active Project.toml file. See also Base.set_active_project.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.set_active_project","page":"Essentials","title":"Base.set_active_project","text":"set_active_project(projfile::Union{AbstractString,Nothing})\n\nSet the active Project.toml file to projfile. See also Base.active_project.\n\ncompat: Julia 1.8\nThis function requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Keywords","page":"Essentials","title":"Keywords","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"This is the list of reserved keywords in Julia: baremodule, begin, break, catch, const, continue, do, else, elseif, end, export, false, finally, for, function, global, if, import, let, local, macro, module, quote, return, struct, true, try, using, while. Those keywords are not allowed to be used as variable names.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"The following two-word sequences are reserved: abstract type, mutable struct, primitive type. However, you can create variables with names: abstract, mutable, primitive and type.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Finally: where is parsed as an infix operator for writing parametric method and type definitions; in and isa are parsed as infix operators; public is parsed as a keyword when beginning a toplevel statement; outer is parsed as a keyword when used to modify the scope of a variable in an iteration specification of a for loop; and as is used as a keyword to rename an identifier brought into scope by import or using. Creation of variables named where, in, isa, outer and as is allowed, though.","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"module\nexport\npublic\nimport\nusing\nas\nbaremodule\nfunction\nmacro\nreturn\ndo\nbegin\nend\nlet\nif\nfor\nwhile\nbreak\ncontinue\ntry\nfinally\nquote\nlocal\nglobal\nouter\nconst\nstruct\nmutable struct\n@kwdef\nabstract type\nprimitive type\nwhere\n...\n;\n=\n?:","category":"page"},{"location":"base/base/#module","page":"Essentials","title":"module","text":"module\n\nmodule declares a Module, which is a separate global variable workspace. Within a module, you can control which names from other modules are visible (via importing), and specify which of your names are intended to be public (via export and public). Modules allow you to create top-level definitions without worrying about name conflicts when your code is used together with somebody else’s. See the manual section about modules for more details.\n\nExamples\n\nmodule Foo\nimport Base.show\nexport MyType, foo\n\nstruct MyType\n x\nend\n\nbar(x) = 2x\nfoo(a::MyType) = bar(a.x) + 1\nshow(io::IO, a::MyType) = print(io, \"MyType $(a.x)\")\nend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#export","page":"Essentials","title":"export","text":"export\n\nexport is used within modules to tell Julia which names should be made available to the user. For example: export foo makes the name foo available when using the module. See the manual section about modules for details.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#public","page":"Essentials","title":"public","text":"public\n\npublic is used within modules to tell Julia which names are part of the public API of the module. For example: public foo indicates that the name foo is public, without making it available when using the module.\n\nAs export already indicates that a name is public, it is unnecessary and an error to declare a name both as public and as exported. See the manual section about modules for details.\n\ncompat: Julia 1.11\nThe public keyword was added in Julia 1.11. Prior to this the notion of publicness was less explicit.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#import","page":"Essentials","title":"import","text":"import\n\nimport Foo will load the module or package Foo. Names from the imported Foo module can be accessed with dot syntax (e.g. Foo.foo to access the name foo). See the manual section about modules for details.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#using","page":"Essentials","title":"using","text":"using\n\nusing Foo will load the module or package Foo and make its exported names available for direct use. Names can also be used via dot syntax (e.g. Foo.foo to access the name foo), whether they are exported or not. See the manual section about modules for details.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#as","page":"Essentials","title":"as","text":"as\n\nas is used as a keyword to rename an identifier brought into scope by import or using, for the purpose of working around name conflicts as well as for shortening names. (Outside of import or using statements, as is not a keyword and can be used as an ordinary identifier.)\n\nimport LinearAlgebra as LA brings the imported LinearAlgebra standard library into scope as LA.\n\nimport LinearAlgebra: eigen as eig, cholesky as chol brings the eigen and cholesky methods from LinearAlgebra into scope as eig and chol respectively.\n\nas works with using only when individual identifiers are brought into scope. For example, using LinearAlgebra: eigen as eig or using LinearAlgebra: eigen as eig, cholesky as chol works, but using LinearAlgebra as LA is invalid syntax, since it is nonsensical to rename all exported names from LinearAlgebra to LA.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#baremodule","page":"Essentials","title":"baremodule","text":"baremodule\n\nbaremodule declares a module that does not contain using Base or local definitions of eval and include. It does still import Core. In other words,\n\nmodule Mod\n\n...\n\nend\n\nis equivalent to\n\nbaremodule Mod\n\nusing Base\n\neval(x) = Core.eval(Mod, x)\ninclude(p) = Base.include(Mod, p)\n\n...\n\nend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#function","page":"Essentials","title":"function","text":"function\n\nFunctions are defined with the function keyword:\n\nfunction add(a, b)\n return a + b\nend\n\nOr the short form notation:\n\nadd(a, b) = a + b\n\nThe use of the return keyword is exactly the same as in other languages, but is often optional. A function without an explicit return statement will return the last expression in the function body.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#macro","page":"Essentials","title":"macro","text":"macro\n\nmacro defines a method for inserting generated code into a program. A macro maps a sequence of argument expressions to a returned expression, and the resulting expression is substituted directly into the program at the point where the macro is invoked. Macros are a way to run generated code without calling eval, since the generated code instead simply becomes part of the surrounding program. Macro arguments may include expressions, literal values, and symbols. Macros can be defined for variable number of arguments (varargs), but do not accept keyword arguments. Every macro also implicitly gets passed the arguments __source__, which contains the line number and file name the macro is called from, and __module__, which is the module the macro is expanded in.\n\nSee the manual section on Metaprogramming for more information about how to write a macro.\n\nExamples\n\njulia> macro sayhello(name)\n return :( println(\"Hello, \", $name, \"!\") )\n end\n@sayhello (macro with 1 method)\n\njulia> @sayhello \"Charlie\"\nHello, Charlie!\n\njulia> macro saylots(x...)\n return :( println(\"Say: \", $(x...)) )\n end\n@saylots (macro with 1 method)\n\njulia> @saylots \"hey \" \"there \" \"friend\"\nSay: hey there friend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#return","page":"Essentials","title":"return","text":"return\n\nreturn x causes the enclosing function to exit early, passing the given value x back to its caller. return by itself with no value is equivalent to return nothing (see nothing).\n\nfunction compare(a, b)\n a == b && return \"equal to\"\n a < b ? \"less than\" : \"greater than\"\nend\n\nIn general you can place a return statement anywhere within a function body, including within deeply nested loops or conditionals, but be careful with do blocks. For example:\n\nfunction test1(xs)\n for x in xs\n iseven(x) && return 2x\n end\nend\n\nfunction test2(xs)\n map(xs) do x\n iseven(x) && return 2x\n x\n end\nend\n\nIn the first example, the return breaks out of test1 as soon as it hits an even number, so test1([5,6,7]) returns 12.\n\nYou might expect the second example to behave the same way, but in fact the return there only breaks out of the inner function (inside the do block) and gives a value back to map. test2([5,6,7]) then returns [5,12,7].\n\nWhen used in a top-level expression (i.e. outside any function), return causes the entire current top-level expression to terminate early.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#do","page":"Essentials","title":"do","text":"do\n\nCreate an anonymous function and pass it as the first argument to a function call. For example:\n\nmap(1:10) do x\n 2x\nend\n\nis equivalent to map(x->2x, 1:10).\n\nUse multiple arguments like so:\n\nmap(1:10, 11:20) do x, y\n x + y\nend\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#begin","page":"Essentials","title":"begin","text":"begin\n\nbegin...end denotes a block of code.\n\nbegin\n println(\"Hello, \")\n println(\"World!\")\nend\n\nUsually begin will not be necessary, since keywords such as function and let implicitly begin blocks of code. See also ;.\n\nbegin may also be used when indexing to represent the first index of a collection or the first index of a dimension of an array.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Array{Int64,2}:\n 1 2\n 3 4\n\njulia> A[begin, :]\n2-element Array{Int64,1}:\n 1\n 2\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#end","page":"Essentials","title":"end","text":"end\n\nend marks the conclusion of a block of expressions, for example module, struct, mutable struct, begin, let, for etc.\n\nend may also be used when indexing to represent the last index of a collection or the last index of a dimension of an array.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Array{Int64, 2}:\n 1 2\n 3 4\n\njulia> A[end, :]\n2-element Array{Int64, 1}:\n 3\n 4\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#let","page":"Essentials","title":"let","text":"let\n\nlet blocks create a new hard scope and optionally introduce new local bindings.\n\nJust like the other scope constructs, let blocks define the block of code where newly introduced local variables are accessible. Additionally, the syntax has a special meaning for comma-separated assignments and variable names that may optionally appear on the same line as the let:\n\nlet var1 = value1, var2, var3 = value3\n code\nend\n\nThe variables introduced on this line are local to the let block and the assignments are evaluated in order, with each right-hand side evaluated in the scope without considering the name on the left-hand side. Therefore it makes sense to write something like let x = x, since the two x variables are distinct with the left-hand side locally shadowing the x from the outer scope. This can even be a useful idiom as new local variables are freshly created each time local scopes are entered, but this is only observable in the case of variables that outlive their scope via closures. A let variable without an assignment, such as var2 in the example above, declares a new local variable that is not yet bound to a value.\n\nBy contrast, begin blocks also group multiple expressions together but do not introduce scope or have the special assignment syntax.\n\nExamples\n\nIn the function below, there is a single x that is iteratively updated three times by the map. The closures returned all reference that one x at its final value:\n\njulia> function test_outer_x()\n x = 0\n map(1:3) do _\n x += 1\n return ()->x\n end\n end\ntest_outer_x (generic function with 1 method)\n\njulia> [f() for f in test_outer_x()]\n3-element Vector{Int64}:\n 3\n 3\n 3\n\nIf, however, we add a let block that introduces a new local variable we will end up with three distinct variables being captured (one at each iteration) even though we chose to use (shadow) the same name.\n\njulia> function test_let_x()\n x = 0\n map(1:3) do _\n x += 1\n let x = x\n return ()->x\n end\n end\n end\ntest_let_x (generic function with 1 method)\n\njulia> [f() for f in test_let_x()]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\nAll scope constructs that introduce new local variables behave this way when repeatedly run; the distinctive feature of let is its ability to succinctly declare new locals that may shadow outer variables of the same name. For example, directly using the argument of the do function similarly captures three distinct variables:\n\njulia> function test_do_x()\n map(1:3) do x\n return ()->x\n end\n end\ntest_do_x (generic function with 1 method)\n\njulia> [f() for f in test_do_x()]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#if","page":"Essentials","title":"if","text":"if/elseif/else\n\nif/elseif/else performs conditional evaluation, which allows portions of code to be evaluated or not evaluated depending on the value of a boolean expression. Here is the anatomy of the if/elseif/else conditional syntax:\n\nif x < y\n println(\"x is less than y\")\nelseif x > y\n println(\"x is greater than y\")\nelse\n println(\"x is equal to y\")\nend\n\nIf the condition expression x < y is true, then the corresponding block is evaluated; otherwise the condition expression x > y is evaluated, and if it is true, the corresponding block is evaluated; if neither expression is true, the else block is evaluated. The elseif and else blocks are optional, and as many elseif blocks as desired can be used.\n\nIn contrast to some other languages conditions must be of type Bool. It does not suffice for conditions to be convertible to Bool.\n\njulia> if 1 end\nERROR: TypeError: non-boolean (Int64) used in boolean context\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#for","page":"Essentials","title":"for","text":"for\n\nfor loops repeatedly evaluate a block of statements while iterating over a sequence of values.\n\nThe iteration variable is always a new variable, even if a variable of the same name exists in the enclosing scope. Use outer to reuse an existing local variable for iteration.\n\nExamples\n\njulia> for i in [1, 4, 0]\n println(i)\n end\n1\n4\n0\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#while","page":"Essentials","title":"while","text":"while\n\nwhile loops repeatedly evaluate a conditional expression, and continue evaluating the body of the while loop as long as the expression remains true. If the condition expression is false when the while loop is first reached, the body is never evaluated.\n\nExamples\n\njulia> i = 1\n1\n\njulia> while i < 5\n println(i)\n global i += 1\n end\n1\n2\n3\n4\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#break","page":"Essentials","title":"break","text":"break\n\nBreak out of a loop immediately.\n\nExamples\n\njulia> i = 0\n0\n\njulia> while true\n global i += 1\n i > 5 && break\n println(i)\n end\n1\n2\n3\n4\n5\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#continue","page":"Essentials","title":"continue","text":"continue\n\nSkip the rest of the current loop iteration.\n\nExamples\n\njulia> for i = 1:6\n iseven(i) && continue\n println(i)\n end\n1\n3\n5\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#try","page":"Essentials","title":"try","text":"try/catch\n\nA try/catch statement allows intercepting errors (exceptions) thrown by throw so that program execution can continue. For example, the following code attempts to write a file, but warns the user and proceeds instead of terminating execution if the file cannot be written:\n\ntry\n open(\"/danger\", \"w\") do f\n println(f, \"Hello\")\n end\ncatch\n @warn \"Could not write file.\"\nend\n\nor, when the file cannot be read into a variable:\n\nlines = try\n open(\"/danger\", \"r\") do f\n readlines(f)\n end\ncatch\n @warn \"File not found.\"\nend\n\nThe syntax catch e (where e is any variable) assigns the thrown exception object to the given variable within the catch block.\n\nThe power of the try/catch construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#finally","page":"Essentials","title":"finally","text":"finally\n\nRun some code when a given block of code exits, regardless of how it exits. For example, here is how we can guarantee that an opened file is closed:\n\nf = open(\"file\")\ntry\n operate_on_file(f)\nfinally\n close(f)\nend\n\nWhen control leaves the try block (for example, due to a return, or just finishing normally), close(f) will be executed. If the try block exits due to an exception, the exception will continue propagating. A catch block may be combined with try and finally as well. In this case the finally block will run after catch has handled the error.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#quote","page":"Essentials","title":"quote","text":"quote\n\nquote creates multiple expression objects in a block without using the explicit Expr constructor. For example:\n\nex = quote\n x = 1\n y = 2\n x + y\nend\n\nUnlike the other means of quoting, :( ... ), this form introduces QuoteNode elements to the expression tree, which must be considered when directly manipulating the tree. For other purposes, :( ... ) and quote .. end blocks are treated identically.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#local","page":"Essentials","title":"local","text":"local\n\nlocal introduces a new local variable. See the manual section on variable scoping for more information.\n\nExamples\n\njulia> function foo(n)\n x = 0\n for i = 1:n\n local x # introduce a loop-local x\n x = i\n end\n x\n end\nfoo (generic function with 1 method)\n\njulia> foo(10)\n0\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#global","page":"Essentials","title":"global","text":"global\n\nglobal x makes x in the current scope and its inner scopes refer to the global variable of that name. See the manual section on variable scoping for more information.\n\nExamples\n\njulia> z = 3\n3\n\njulia> function foo()\n global z = 6 # use the z variable defined outside foo\n end\nfoo (generic function with 1 method)\n\njulia> foo()\n6\n\njulia> z\n6\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#outer","page":"Essentials","title":"outer","text":"for outer\n\nReuse an existing local variable for iteration in a for loop.\n\nSee the manual section on variable scoping for more information.\n\nSee also for.\n\nExamples\n\njulia> function f()\n i = 0\n for i = 1:3\n # empty\n end\n return i\n end;\n\njulia> f()\n0\n\njulia> function f()\n i = 0\n for outer i = 1:3\n # empty\n end\n return i\n end;\n\njulia> f()\n3\n\njulia> i = 0 # global variable\n for outer i = 1:3\n end\nERROR: syntax: no outer local variable declaration exists for \"for outer\"\n[...]\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#const","page":"Essentials","title":"const","text":"const\n\nconst is used to declare global variables whose values will not change. In almost all code (and particularly performance sensitive code) global variables should be declared constant in this way.\n\nconst x = 5\n\nMultiple variables can be declared within a single const:\n\nconst y, z = 7, 11\n\nNote that const only applies to one = operation, therefore const x = y = 1 declares x to be constant but not y. On the other hand, const x = const y = 1 declares both x and y constant.\n\nNote that \"constant-ness\" does not extend into mutable containers; only the association between a variable and its value is constant. If x is an array or dictionary (for example) you can still modify, add, or remove elements.\n\nIn some cases changing the value of a const variable gives a warning instead of an error. However, this can produce unpredictable behavior or corrupt the state of your program, and so should be avoided. This feature is intended only for convenience during interactive use.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#struct","page":"Essentials","title":"struct","text":"struct\n\nThe most commonly used kind of type in Julia is a struct, specified as a name and a set of fields.\n\nstruct Point\n x\n y\nend\n\nFields can have type restrictions, which may be parameterized:\n\nstruct Point{X}\n x::X\n y::Float64\nend\n\nA struct can also declare an abstract super type via <: syntax:\n\nstruct Point <: AbstractPoint\n x\n y\nend\n\nstructs are immutable by default; an instance of one of these types cannot be modified after construction. Use mutable struct instead to declare a type whose instances can be modified.\n\nSee the manual section on Composite Types for more details, such as how to define constructors.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#mutable struct","page":"Essentials","title":"mutable struct","text":"mutable struct\n\nmutable struct is similar to struct, but additionally allows the fields of the type to be set after construction. See the manual section on Composite Types for more information.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.@kwdef","page":"Essentials","title":"Base.@kwdef","text":"@kwdef typedef\n\nThis is a helper macro that automatically defines a keyword-based constructor for the type declared in the expression typedef, which must be a struct or mutable struct expression. The default argument is supplied by declaring fields of the form field::T = default or field = default. If no default is provided then the keyword argument becomes a required keyword argument in the resulting type constructor.\n\nInner constructors can still be defined, but at least one should accept arguments in the same form as the default inner constructor (i.e. one positional argument per field) in order to function correctly with the keyword outer constructor.\n\ncompat: Julia 1.1\nBase.@kwdef for parametric structs, and structs with supertypes requires at least Julia 1.1.\n\ncompat: Julia 1.9\nThis macro is exported as of Julia 1.9.\n\nExamples\n\njulia> @kwdef struct Foo\n a::Int = 1 # specified default\n b::String # required keyword\n end\nFoo\n\njulia> Foo(b=\"hi\")\nFoo(1, \"hi\")\n\njulia> Foo()\nERROR: UndefKeywordError: keyword argument `b` not assigned\nStacktrace:\n[...]\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#abstract type","page":"Essentials","title":"abstract type","text":"abstract type\n\nabstract type declares a type that cannot be instantiated, and serves only as a node in the type graph, thereby describing sets of related concrete types: those concrete types which are their descendants. Abstract types form the conceptual hierarchy which makes Julia’s type system more than just a collection of object implementations. For example:\n\nabstract type Number end\nabstract type Real <: Number end\n\nNumber has no supertype, whereas Real is an abstract subtype of Number.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#primitive type","page":"Essentials","title":"primitive type","text":"primitive type\n\nprimitive type declares a concrete type whose data consists only of a series of bits. Classic examples of primitive types are integers and floating-point values. Some example built-in primitive type declarations:\n\nprimitive type Char 32 end\nprimitive type Bool <: Integer 8 end\n\nThe number after the name indicates how many bits of storage the type requires. Currently, only sizes that are multiples of 8 bits are supported. The Bool declaration shows how a primitive type can be optionally declared to be a subtype of some supertype.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#where","page":"Essentials","title":"where","text":"where\n\nThe where keyword creates a type that is an iterated union of other types, over all values of some variable. For example Vector{T} where T<:Real includes all Vectors where the element type is some kind of Real number.\n\nThe variable bound defaults to Any if it is omitted:\n\nVector{T} where T # short for `where T<:Any`\n\nVariables can also have lower bounds:\n\nVector{T} where T>:Int\nVector{T} where Int<:T<:Real\n\nThere is also a concise syntax for nested where expressions. For example, this:\n\nPair{T, S} where S<:Array{T} where T<:Number\n\ncan be shortened to:\n\nPair{T, S} where {T<:Number, S<:Array{T}}\n\nThis form is often found on method signatures.\n\nNote that in this form, the variables are listed outermost-first. This matches the order in which variables are substituted when a type is \"applied\" to parameter values using the syntax T{p1, p2, ...}.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#...","page":"Essentials","title":"...","text":"...\n\nThe \"splat\" operator, ..., represents a sequence of arguments. ... can be used in function definitions, to indicate that the function accepts an arbitrary number of arguments. ... can also be used to apply a function to a sequence of arguments.\n\nExamples\n\njulia> add(xs...) = reduce(+, xs)\nadd (generic function with 1 method)\n\njulia> add(1, 2, 3, 4, 5)\n15\n\njulia> add([1, 2, 3]...)\n6\n\njulia> add(7, 1:100..., 1000:1100...)\n111107\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#;","page":"Essentials","title":";","text":";\n\n; has a similar role in Julia as in many C-like languages, and is used to delimit the end of the previous statement.\n\n; is not necessary at the end of a line, but can be used to separate statements on a single line or to join statements into a single expression.\n\nAdding ; at the end of a line in the REPL will suppress printing the result of that expression.\n\nIn function declarations, and optionally in calls, ; separates regular arguments from keywords.\n\nIn array literals, arguments separated by semicolons have their contents concatenated together. A separator made of a single ; concatenates vertically (i.e. along the first dimension), ;; concatenates horizontally (second dimension), ;;; concatenates along the third dimension, etc. Such a separator can also be used in last position in the square brackets to add trailing dimensions of length 1.\n\nA ; in first position inside of parentheses can be used to construct a named tuple. The same (; ...) syntax on the left side of an assignment allows for property destructuring.\n\nIn the standard REPL, typing ; on an empty line will switch to shell mode.\n\nExamples\n\njulia> function foo()\n x = \"Hello, \"; x *= \"World!\"\n return x\n end\nfoo (generic function with 1 method)\n\njulia> bar() = (x = \"Hello, Mars!\"; return x)\nbar (generic function with 1 method)\n\njulia> foo();\n\njulia> bar()\n\"Hello, Mars!\"\n\njulia> function plot(x, y; style=\"solid\", width=1, color=\"black\")\n ###\n end\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> [1; 3;; 2; 4;;; 10*A]\n2×2×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 2\n 3 4\n\n[:, :, 2] =\n 10 20\n 30 40\n\njulia> [2; 3;;;]\n2×1×1 Array{Int64, 3}:\n[:, :, 1] =\n 2\n 3\n\njulia> nt = (; x=1) # without the ; or a trailing comma this would assign to x\n(x = 1,)\n\njulia> key = :a; c = 3;\n\njulia> nt2 = (; key => 1, b=2, c, nt.x)\n(a = 1, b = 2, c = 3, x = 1)\n\njulia> (; b, x) = nt2; # set variables b and x using property destructuring\n\njulia> b, x\n(2, 1)\n\njulia> ; # upon typing ;, the prompt changes (in place) to: shell>\nshell> echo hello\nhello\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#=","page":"Essentials","title":"=","text":"=\n\n= is the assignment operator.\n\nFor variable a and expression b, a = b makes a refer to the value of b.\nFor functions f(x), f(x) = x defines a new function constant f, or adds a new method to f if f is already defined; this usage is equivalent to function f(x); x; end.\na[i] = v calls setindex!(a,v,i).\na.b = c calls setproperty!(a,:b,c).\nInside a function call, f(a=b) passes b as the value of keyword argument a.\nInside parentheses with commas, (a=1,) constructs a NamedTuple.\n\nExamples\n\nAssigning a to b does not create a copy of b; instead use copy or deepcopy.\n\njulia> b = [1]; a = b; b[1] = 2; a\n1-element Array{Int64, 1}:\n 2\n\njulia> b = [1]; a = copy(b); b[1] = 2; a\n1-element Array{Int64, 1}:\n 1\n\n\nCollections passed to functions are also not copied. Functions can modify (mutate) the contents of the objects their arguments refer to. (The names of functions which do this are conventionally suffixed with '!'.)\n\njulia> function f!(x); x[:] .+= 1; end\nf! (generic function with 1 method)\n\njulia> a = [1]; f!(a); a\n1-element Array{Int64, 1}:\n 2\n\n\nAssignment can operate on multiple variables in parallel, taking values from an iterable:\n\njulia> a, b = 4, 5\n(4, 5)\n\njulia> a, b = 1:3\n1:3\n\njulia> a, b\n(1, 2)\n\n\nAssignment can operate on multiple variables in series, and will return the value of the right-hand-most expression:\n\njulia> a = [1]; b = [2]; c = [3]; a = b = c\n1-element Array{Int64, 1}:\n 3\n\njulia> b[1] = 2; a, b, c\n([2], [2], [2])\n\n\nAssignment at out-of-bounds indices does not grow a collection. If the collection is a Vector it can instead be grown with push! or append!.\n\njulia> a = [1, 1]; a[3] = 2\nERROR: BoundsError: attempt to access 2-element Array{Int64, 1} at index [3]\n[...]\n\njulia> push!(a, 2, 3)\n4-element Array{Int64, 1}:\n 1\n 1\n 2\n 3\n\n\nAssigning [] does not eliminate elements from a collection; instead use filter!.\n\njulia> a = collect(1:3); a[a .<= 1] = []\nERROR: DimensionMismatch: tried to assign 0 elements to 1 destinations\n[...]\n\njulia> filter!(x -> x > 1, a) # in-place & thus more efficient than a = a[a .> 1]\n2-element Array{Int64, 1}:\n 2\n 3\n\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#?:","page":"Essentials","title":"?:","text":"a ? b : c\n\nShort form for conditionals; read \"if a, evaluate b otherwise evaluate c\". Also known as the ternary operator.\n\nThis syntax is equivalent to if a; b else c end, but is often used to emphasize the value b-or-c which is being used as part of a larger expression, rather than the side effects that evaluating b or c may have.\n\nSee the manual section on control flow for more details.\n\nExamples\n\njulia> x = 1; y = 2;\n\njulia> x > y ? println(\"x is larger\") : println(\"y is larger\")\ny is larger\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Standard-Modules","page":"Essentials","title":"Standard Modules","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Main\nCore\nBase","category":"page"},{"location":"base/base/#Main","page":"Essentials","title":"Main","text":"Main\n\nMain is the top-level module, and Julia starts with Main set as the current module. Variables defined at the prompt go in Main, and varinfo lists variables in Main.\n\njulia> @__MODULE__\nMain\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Core","page":"Essentials","title":"Core","text":"Core\n\nCore is the module that contains all identifiers considered \"built in\" to the language, i.e. part of the core language and not libraries. Every module implicitly specifies using Core, since you can't do anything without those definitions.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base","page":"Essentials","title":"Base","text":"Base\n\nThe base library of Julia. Base is a module that contains basic functionality (the contents of base/). All modules implicitly contain using Base, since this is needed in the vast majority of cases.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base-Submodules","page":"Essentials","title":"Base Submodules","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.Broadcast\nBase.Docs\nBase.Iterators\nBase.Libc\nBase.Meta\nBase.StackTraces\nBase.Sys\nBase.Threads\nBase.GC","category":"page"},{"location":"base/base/#Base.Broadcast","page":"Essentials","title":"Base.Broadcast","text":"Base.Broadcast\n\nModule containing the broadcasting implementation.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Docs","page":"Essentials","title":"Base.Docs","text":"Docs\n\nThe Docs module provides the @doc macro which can be used to set and retrieve documentation metadata for Julia objects.\n\nPlease see the manual section on documentation for more information.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Iterators","page":"Essentials","title":"Base.Iterators","text":"Methods for working with Iterators.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Libc","page":"Essentials","title":"Base.Libc","text":"Interface to libc, the C standard library.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Meta","page":"Essentials","title":"Base.Meta","text":"Convenience functions for metaprogramming.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.StackTraces","page":"Essentials","title":"Base.StackTraces","text":"Tools for collecting and manipulating stack traces. Mainly used for building errors.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Sys","page":"Essentials","title":"Base.Sys","text":"Provide methods for retrieving information about hardware and the operating system.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.Threads","page":"Essentials","title":"Base.Threads","text":"Multithreading support.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#Base.GC","page":"Essentials","title":"Base.GC","text":"Base.GC\n\nModule with garbage collection utilities.\n\n\n\n\n\n","category":"module"},{"location":"base/base/#All-Objects","page":"Essentials","title":"All Objects","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Core.:(===)\nCore.isa\nBase.isequal\nBase.isless\nBase.isunordered\nBase.ifelse\nCore.typeassert\nCore.typeof\nCore.tuple\nBase.ntuple\nBase.objectid\nBase.hash\nBase.finalizer\nBase.finalize\nBase.copy\nBase.deepcopy\nBase.getproperty\nBase.setproperty!\nBase.replaceproperty!\nBase.swapproperty!\nBase.modifyproperty!\nBase.setpropertyonce!\nBase.propertynames\nBase.hasproperty\nCore.getfield\nCore.setfield!\nCore.modifyfield!\nCore.replacefield!\nCore.swapfield!\nCore.setfieldonce!\nCore.isdefined\nBase.@isdefined\nBase.convert\nBase.promote\nBase.oftype\nBase.widen\nBase.identity\nBase.WeakRef","category":"page"},{"location":"base/base/#Core.:===","page":"Essentials","title":"Core.:===","text":"===(x,y) -> Bool\n≡(x,y) -> Bool\n\nDetermine whether x and y are identical, in the sense that no program could distinguish them. First the types of x and y are compared. If those are identical, mutable objects are compared by address in memory and immutable objects (such as numbers) are compared by contents at the bit level. This function is sometimes called \"egal\". It always returns a Bool value.\n\nExamples\n\njulia> a = [1, 2]; b = [1, 2];\n\njulia> a == b\ntrue\n\njulia> a === b\nfalse\n\njulia> a === a\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.isa","page":"Essentials","title":"Core.isa","text":"isa(x, type) -> Bool\n\nDetermine whether x is of the given type. Can also be used as an infix operator, e.g. x isa type.\n\nExamples\n\njulia> isa(1, Int)\ntrue\n\njulia> isa(1, Matrix)\nfalse\n\njulia> isa(1, Char)\nfalse\n\njulia> isa(1, Number)\ntrue\n\njulia> 1 isa Number\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isequal","page":"Essentials","title":"Base.isequal","text":"isequal(x, y) -> Bool\n\nSimilar to ==, except for the treatment of floating point numbers and of missing values. isequal treats all floating-point NaN values as equal to each other, treats -0.0 as unequal to 0.0, and missing as equal to missing. Always returns a Bool value.\n\nisequal is an equivalence relation - it is reflexive (=== implies isequal), symmetric (isequal(a, b) implies isequal(b, a)) and transitive (isequal(a, b) and isequal(b, c) implies isequal(a, c)).\n\nImplementation\n\nThe default implementation of isequal calls ==, so a type that does not involve floating-point values generally only needs to define ==.\n\nisequal is the comparison function used by hash tables (Dict). isequal(x,y) must imply that hash(x) == hash(y).\n\nThis typically means that types for which a custom == or isequal method exists must implement a corresponding hash method (and vice versa). Collections typically implement isequal by calling isequal recursively on all contents.\n\nFurthermore, isequal is linked with isless, and they work together to define a fixed total ordering, where exactly one of isequal(x, y), isless(x, y), or isless(y, x) must be true (and the other two false).\n\nScalar types generally do not need to implement isequal separate from ==, unless they represent floating-point numbers amenable to a more efficient implementation than that provided as a generic fallback (based on isnan, signbit, and ==).\n\nExamples\n\njulia> isequal([1., NaN], [1., NaN])\ntrue\n\njulia> [1., NaN] == [1., NaN]\nfalse\n\njulia> 0.0 == -0.0\ntrue\n\njulia> isequal(0.0, -0.0)\nfalse\n\njulia> missing == missing\nmissing\n\njulia> isequal(missing, missing)\ntrue\n\n\n\n\n\nisequal(x)\n\nCreate a function that compares its argument to x using isequal, i.e. a function equivalent to y -> isequal(y, x).\n\nThe returned function is of type Base.Fix2{typeof(isequal)}, which can be used to implement specialized methods.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isless","page":"Essentials","title":"Base.isless","text":"isless(x, y)\n\nTest whether x is less than y, according to a fixed total order (defined together with isequal). isless is not defined for pairs (x, y) of all types. However, if it is defined, it is expected to satisfy the following:\n\nIf isless(x, y) is defined, then so is isless(y, x) and isequal(x, y), and exactly one of those three yields true.\nThe relation defined by isless is transitive, i.e., isless(x, y) && isless(y, z) implies isless(x, z).\n\nValues that are normally unordered, such as NaN, are ordered after regular values. missing values are ordered last.\n\nThis is the default comparison used by sort!.\n\nImplementation\n\nNon-numeric types with a total order should implement this function. Numeric types only need to implement it if they have special values such as NaN. Types with a partial order should implement <. See the documentation on Alternate Orderings for how to define alternate ordering methods that can be used in sorting and related functions.\n\nExamples\n\njulia> isless(1, 3)\ntrue\n\njulia> isless(\"Red\", \"Blue\")\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isunordered","page":"Essentials","title":"Base.isunordered","text":"isunordered(x)\n\nReturn true if x is a value that is not orderable according to <, such as NaN or missing.\n\nThe values that evaluate to true with this predicate may be orderable with respect to other orderings such as isless.\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ifelse","page":"Essentials","title":"Base.ifelse","text":"ifelse(condition::Bool, x, y)\n\nReturn x if condition is true, otherwise return y. This differs from ? or if in that it is an ordinary function, so all the arguments are evaluated first. In some cases, using ifelse instead of an if statement can eliminate the branch in generated code and provide higher performance in tight loops.\n\nExamples\n\njulia> ifelse(1 > 2, 1, 2)\n2\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.typeassert","page":"Essentials","title":"Core.typeassert","text":"typeassert(x, type)\n\nThrow a TypeError unless x isa type. The syntax x::type calls this function.\n\nExamples\n\njulia> typeassert(2.5, Int)\nERROR: TypeError: in typeassert, expected Int64, got a value of type Float64\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.typeof","page":"Essentials","title":"Core.typeof","text":"typeof(x)\n\nGet the concrete type of x.\n\nSee also eltype.\n\nExamples\n\njulia> a = 1//2;\n\njulia> typeof(a)\nRational{Int64}\n\njulia> M = [1 2; 3.5 4];\n\njulia> typeof(M)\nMatrix{Float64} (alias for Array{Float64, 2})\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.tuple","page":"Essentials","title":"Core.tuple","text":"tuple(xs...)\n\nConstruct a tuple of the given objects.\n\nSee also Tuple, ntuple, NamedTuple.\n\nExamples\n\njulia> tuple(1, 'b', pi)\n(1, 'b', π)\n\njulia> ans === (1, 'b', π)\ntrue\n\njulia> Tuple(Real[1, 2, pi]) # takes a collection\n(1, 2, π)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ntuple","page":"Essentials","title":"Base.ntuple","text":"ntuple(f, n::Integer)\n\nCreate a tuple of length n, computing each element as f(i), where i is the index of the element.\n\nExamples\n\njulia> ntuple(i -> 2*i, 4)\n(2, 4, 6, 8)\n\n\n\n\n\nntuple(f, ::Val{N})\n\nCreate a tuple of length N, computing each element as f(i), where i is the index of the element. By taking a Val(N) argument, it is possible that this version of ntuple may generate more efficient code than the version taking the length as an integer. But ntuple(f, N) is preferable to ntuple(f, Val(N)) in cases where N cannot be determined at compile time.\n\nExamples\n\njulia> ntuple(i -> 2*i, Val(4))\n(2, 4, 6, 8)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.objectid","page":"Essentials","title":"Base.objectid","text":"objectid(x) -> UInt\n\nGet a hash value for x based on object identity.\n\nIf x === y then objectid(x) == objectid(y), and usually when x !== y, objectid(x) != objectid(y).\n\nSee also hash, IdDict.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.hash","page":"Essentials","title":"Base.hash","text":"hash(x[, h::UInt]) -> UInt\n\nCompute an integer hash code such that isequal(x,y) implies hash(x)==hash(y). The optional second argument h is another hash code to be mixed with the result.\n\nNew types should implement the 2-argument form, typically by calling the 2-argument hash method recursively in order to mix hashes of the contents with each other (and with h). Typically, any type that implements hash should also implement its own == (hence isequal) to guarantee the property mentioned above. Types supporting subtraction (operator -) should also implement widen, which is required to hash values inside heterogeneous arrays.\n\nThe hash value may change when a new Julia process is started.\n\njulia> a = hash(10)\n0x95ea2955abd45275\n\njulia> hash(10, a) # only use the output of another hash function as the second argument\n0xd42bad54a8575b16\n\nSee also: objectid, Dict, Set.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.finalizer","page":"Essentials","title":"Base.finalizer","text":"finalizer(f, x)\n\nRegister a function f(x) to be called when there are no program-accessible references to x, and return x. The type of x must be a mutable struct, otherwise the function will throw.\n\nf must not cause a task switch, which excludes most I/O operations such as println. Using the @async macro (to defer context switching to outside of the finalizer) or ccall to directly invoke IO functions in C may be helpful for debugging purposes.\n\nNote that there is no guaranteed world age for the execution of f. It may be called in the world age in which the finalizer was registered or any later world age.\n\nExamples\n\nfinalizer(my_mutable_struct) do x\n @async println(\"Finalizing $x.\")\nend\n\nfinalizer(my_mutable_struct) do x\n ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), \"Finalizing %s.\", repr(x))\nend\n\nA finalizer may be registered at object construction. In the following example note that we implicitly rely on the finalizer returning the newly created mutable struct x.\n\nmutable struct MyMutableStruct\n bar\n function MyMutableStruct(bar)\n x = new(bar)\n f(t) = @async println(\"Finalizing $t.\")\n finalizer(f, x)\n end\nend\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.finalize","page":"Essentials","title":"Base.finalize","text":"finalize(x)\n\nImmediately run finalizers registered for object x.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.copy","page":"Essentials","title":"Base.copy","text":"copy(x)\n\nCreate a shallow copy of x: the outer structure is copied, but not all internal values. For example, copying an array produces a new array with identically-same elements as the original.\n\nSee also copy!, copyto!, deepcopy.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.deepcopy","page":"Essentials","title":"Base.deepcopy","text":"deepcopy(x)\n\nCreate a deep copy of x: everything is copied recursively, resulting in a fully independent object. For example, deep-copying an array creates deep copies of all the objects it contains and produces a new array with the consistent relationship structure (e.g., if the first two elements are the same object in the original array, the first two elements of the new array will also be the same deepcopyed object). Calling deepcopy on an object should generally have the same effect as serializing and then deserializing it.\n\nWhile it isn't normally necessary, user-defined types can override the default deepcopy behavior by defining a specialized version of the function deepcopy_internal(x::T, dict::IdDict) (which shouldn't otherwise be used), where T is the type to be specialized for, and dict keeps track of objects copied so far within the recursion. Within the definition, deepcopy_internal should be used in place of deepcopy, and the dict variable should be updated as appropriate before returning.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.getproperty","page":"Essentials","title":"Base.getproperty","text":"getproperty(value, name::Symbol)\ngetproperty(value, name::Symbol, order::Symbol)\n\nThe syntax a.b calls getproperty(a, :b). The syntax @atomic order a.b calls getproperty(a, :b, :order) and the syntax @atomic a.b calls getproperty(a, :b, :sequentially_consistent).\n\nExamples\n\njulia> struct MyType{T <: Number}\n x::T\n end\n\njulia> function Base.getproperty(obj::MyType, sym::Symbol)\n if sym === :special\n return obj.x + 1\n else # fallback to getfield\n return getfield(obj, sym)\n end\n end\n\njulia> obj = MyType(1);\n\njulia> obj.special\n2\n\njulia> obj.x\n1\n\nOne should overload getproperty only when necessary, as it can be confusing if the behavior of the syntax obj.f is unusual. Also note that using methods is often preferable. See also this style guide documentation for more information: Prefer exported methods over direct field access.\n\nSee also getfield, propertynames and setproperty!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.setproperty!","page":"Essentials","title":"Base.setproperty!","text":"setproperty!(value, name::Symbol, x)\nsetproperty!(value, name::Symbol, x, order::Symbol)\n\nThe syntax a.b = c calls setproperty!(a, :b, c). The syntax @atomic order a.b = c calls setproperty!(a, :b, c, :order) and the syntax @atomic a.b = c calls setproperty!(a, :b, c, :sequentially_consistent).\n\ncompat: Julia 1.8\nsetproperty! on modules requires at least Julia 1.8.\n\nSee also setfield!, propertynames and getproperty.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.replaceproperty!","page":"Essentials","title":"Base.replaceproperty!","text":"replaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)\n\nPerform a compare-and-swap operation on x.f from expected to desired, per egal. The syntax @atomicreplace x.f expected => desired can be used instead of the function call form.\n\nSee also replacefield! setproperty!, setpropertyonce!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.swapproperty!","page":"Essentials","title":"Base.swapproperty!","text":"swapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)\n\nThe syntax @atomic a.b, _ = c, a.b returns (c, swapproperty!(a, :b, c, :sequentially_consistent)), where there must be one getproperty expression common to both sides.\n\nSee also swapfield! and setproperty!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.modifyproperty!","page":"Essentials","title":"Base.modifyproperty!","text":"modifyproperty!(x, f::Symbol, op, v, order::Symbol=:not_atomic)\n\nThe syntax @atomic op(x.f, v) (and its equivalent @atomic x.f op v) returns modifyproperty!(x, :f, op, v, :sequentially_consistent), where the first argument must be a getproperty expression and is modified atomically.\n\nInvocation of op(getproperty(x, f), v) must return a value that can be stored in the field f of the object x by default. In particular, unlike the default behavior of setproperty!, the convert function is not called automatically.\n\nSee also modifyfield! and setproperty!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.setpropertyonce!","page":"Essentials","title":"Base.setpropertyonce!","text":"setpropertyonce!(x, f::Symbol, value, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)\n\nPerform a compare-and-swap operation on x.f to set it to value if previously unset. The syntax @atomiconce x.f = value can be used instead of the function call form.\n\nSee also setfieldonce!, setproperty!, replaceproperty!.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.propertynames","page":"Essentials","title":"Base.propertynames","text":"propertynames(x, private=false)\n\nGet a tuple or a vector of the properties (x.property) of an object x. This is typically the same as fieldnames(typeof(x)), but types that overload getproperty should generally overload propertynames as well to get the properties of an instance of the type.\n\npropertynames(x) may return only \"public\" property names that are part of the documented interface of x. If you want it to also return \"private\" property names intended for internal use, pass true for the optional second argument. REPL tab completion on x. shows only the private=false properties.\n\nSee also: hasproperty, hasfield.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.hasproperty","page":"Essentials","title":"Base.hasproperty","text":"hasproperty(x, s::Symbol)\n\nReturn a boolean indicating whether the object x has s as one of its own properties.\n\ncompat: Julia 1.2\nThis function requires at least Julia 1.2.\n\nSee also: propertynames, hasfield.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.getfield","page":"Essentials","title":"Core.getfield","text":"getfield(value, name::Symbol, [order::Symbol])\ngetfield(value, i::Int, [order::Symbol])\n\nExtract a field from a composite value by name or position. Optionally, an ordering can be defined for the operation. If the field was declared @atomic, the specification is strongly recommended to be compatible with the stores to that location. Otherwise, if not declared as @atomic, this parameter must be :not_atomic if specified. See also getproperty and fieldnames.\n\nExamples\n\njulia> a = 1//2\n1//2\n\njulia> getfield(a, :num)\n1\n\njulia> a.num\n1\n\njulia> getfield(a, 1)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.setfield!","page":"Essentials","title":"Core.setfield!","text":"setfield!(value, name::Symbol, x, [order::Symbol])\nsetfield!(value, i::Int, x, [order::Symbol])\n\nAssign x to a named field in value of composite type. The value must be mutable and x must be a subtype of fieldtype(typeof(value), name). Additionally, an ordering can be specified for this operation. If the field was declared @atomic, this specification is mandatory. Otherwise, if not declared as @atomic, it must be :not_atomic if specified. See also setproperty!.\n\nExamples\n\njulia> mutable struct MyMutableStruct\n field::Int\n end\n\njulia> a = MyMutableStruct(1);\n\njulia> setfield!(a, :field, 2);\n\njulia> getfield(a, :field)\n2\n\njulia> a = 1//2\n1//2\n\njulia> setfield!(a, :num, 3);\nERROR: setfield!: immutable struct of type Rational cannot be changed\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.modifyfield!","page":"Essentials","title":"Core.modifyfield!","text":"modifyfield!(value, name::Symbol, op, x, [order::Symbol]) -> Pair\nmodifyfield!(value, i::Int, op, x, [order::Symbol]) -> Pair\n\nAtomically perform the operations to get and set a field after applying the function op.\n\ny = getfield(value, name)\nz = op(y, x)\nsetfield!(value, name, z)\nreturn y => z\n\nIf supported by the hardware (for example, atomic increment), this may be optimized to the appropriate hardware instruction, otherwise it'll use a loop.\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.replacefield!","page":"Essentials","title":"Core.replacefield!","text":"replacefield!(value, name::Symbol, expected, desired,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)\nreplacefield!(value, i::Int, expected, desired,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)\n\nAtomically perform the operations to get and conditionally set a field to a given value.\n\ny = getfield(value, name, fail_order)\nok = y === expected\nif ok\n setfield!(value, name, desired, success_order)\nend\nreturn (; old = y, success = ok)\n\nIf supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise it'll use a loop.\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.swapfield!","page":"Essentials","title":"Core.swapfield!","text":"swapfield!(value, name::Symbol, x, [order::Symbol])\nswapfield!(value, i::Int, x, [order::Symbol])\n\nAtomically perform the operations to simultaneously get and set a field:\n\ny = getfield(value, name)\nsetfield!(value, name, x)\nreturn y\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.setfieldonce!","page":"Essentials","title":"Core.setfieldonce!","text":"setfieldonce!(value, name::Union{Int,Symbol}, desired,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool\n\nAtomically perform the operations to set a field to a given value, only if it was previously not set.\n\nok = !isdefined(value, name, fail_order)\nif ok\n setfield!(value, name, desired, success_order)\nend\nreturn ok\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.isdefined","page":"Essentials","title":"Core.isdefined","text":"isdefined(m::Module, s::Symbol, [order::Symbol])\nisdefined(object, s::Symbol, [order::Symbol])\nisdefined(object, index::Int, [order::Symbol])\n\nTests whether a global variable or object field is defined. The arguments can be a module and a symbol or a composite object and field name (as a symbol) or index. Optionally, an ordering can be defined for the operation. If the field was declared @atomic, the specification is strongly recommended to be compatible with the stores to that location. Otherwise, if not declared as @atomic, this parameter must be :not_atomic if specified.\n\nTo test whether an array element is defined, use isassigned instead.\n\nSee also @isdefined.\n\nExamples\n\njulia> isdefined(Base, :sum)\ntrue\n\njulia> isdefined(Base, :NonExistentMethod)\nfalse\n\njulia> a = 1//2;\n\njulia> isdefined(a, 2)\ntrue\n\njulia> isdefined(a, 3)\nfalse\n\njulia> isdefined(a, :num)\ntrue\n\njulia> isdefined(a, :numerator)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@isdefined","page":"Essentials","title":"Base.@isdefined","text":"@isdefined s -> Bool\n\nTests whether variable s is defined in the current scope.\n\nSee also isdefined for field properties and isassigned for array indexes or haskey for other mappings.\n\nExamples\n\njulia> @isdefined newvar\nfalse\n\njulia> newvar = 1\n1\n\njulia> @isdefined newvar\ntrue\n\njulia> function f()\n println(@isdefined x)\n x = 3\n println(@isdefined x)\n end\nf (generic function with 1 method)\n\njulia> f()\nfalse\ntrue\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.convert","page":"Essentials","title":"Base.convert","text":"convert(T, x)\n\nConvert x to a value of type T.\n\nIf T is an Integer type, an InexactError will be raised if x is not representable by T, for example if x is not integer-valued, or is outside the range supported by T.\n\nExamples\n\njulia> convert(Int, 3.0)\n3\n\njulia> convert(Int, 3.5)\nERROR: InexactError: Int64(3.5)\nStacktrace:\n[...]\n\nIf T is a AbstractFloat type, then it will return the closest value to x representable by T.\n\njulia> x = 1/3\n0.3333333333333333\n\njulia> convert(Float32, x)\n0.33333334f0\n\njulia> convert(BigFloat, x)\n0.333333333333333314829616256247390992939472198486328125\n\nIf T is a collection type and x a collection, the result of convert(T, x) may alias all or part of x.\n\njulia> x = Int[1, 2, 3];\n\njulia> y = convert(Vector{Int}, x);\n\njulia> y === x\ntrue\n\nSee also: round, trunc, oftype, reinterpret.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.promote","page":"Essentials","title":"Base.promote","text":"promote(xs...)\n\nConvert all arguments to a common type, and return them all (as a tuple). If no arguments can be converted, an error is raised.\n\nSee also: promote_type, promote_rule.\n\nExamples\n\njulia> promote(Int8(1), Float16(4.5), Float32(4.1))\n(1.0f0, 4.5f0, 4.1f0)\n\njulia> promote_type(Int8, Float16, Float32)\nFloat32\n\njulia> reduce(Base.promote_typejoin, (Int8, Float16, Float32))\nReal\n\njulia> promote(1, \"x\")\nERROR: promotion of types Int64 and String failed to change any arguments\n[...]\n\njulia> promote_type(Int, String)\nAny\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.oftype","page":"Essentials","title":"Base.oftype","text":"oftype(x, y)\n\nConvert y to the type of x i.e. convert(typeof(x), y).\n\nExamples\n\njulia> x = 4;\n\njulia> y = 3.;\n\njulia> oftype(x, y)\n3\n\njulia> oftype(y, x)\n4.0\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.widen","page":"Essentials","title":"Base.widen","text":"widen(x)\n\nIf x is a type, return a \"larger\" type, defined so that arithmetic operations + and - are guaranteed not to overflow nor lose precision for any combination of values that type x can hold.\n\nFor fixed-size integer types less than 128 bits, widen will return a type with twice the number of bits.\n\nIf x is a value, it is converted to widen(typeof(x)).\n\nExamples\n\njulia> widen(Int32)\nInt64\n\njulia> widen(1.5f0)\n1.5\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.identity","page":"Essentials","title":"Base.identity","text":"identity(x)\n\nThe identity function. Returns its argument.\n\nSee also: one, oneunit, and LinearAlgebra's I.\n\nExamples\n\njulia> identity(\"Well, what did you expect?\")\n\"Well, what did you expect?\"\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.WeakRef","page":"Essentials","title":"Core.WeakRef","text":"WeakRef(x)\n\nw = WeakRef(x) constructs a weak reference to the Julia value x: although w contains a reference to x, it does not prevent x from being garbage collected. w.value is either x (if x has not been garbage-collected yet) or nothing (if x has been garbage-collected).\n\njulia> x = \"a string\"\n\"a string\"\n\njulia> w = WeakRef(x)\nWeakRef(\"a string\")\n\njulia> GC.gc()\n\njulia> w # a reference is maintained via `x`\nWeakRef(\"a string\")\n\njulia> x = nothing # clear reference\n\njulia> GC.gc()\n\njulia> w\nWeakRef(nothing)\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Properties-of-Types","page":"Essentials","title":"Properties of Types","text":"","category":"section"},{"location":"base/base/#Type-relations","page":"Essentials","title":"Type relations","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.supertype\nCore.Type\nCore.DataType\nCore.:(<:)\nBase.:(>:)\nBase.typejoin\nBase.typeintersect\nBase.promote_type\nBase.promote_rule\nBase.promote_typejoin\nBase.isdispatchtuple","category":"page"},{"location":"base/base/#Base.supertype","page":"Essentials","title":"Base.supertype","text":"supertype(T::DataType)\n\nReturn the supertype of DataType T.\n\nExamples\n\njulia> supertype(Int32)\nSigned\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.Type","page":"Essentials","title":"Core.Type","text":"Core.Type{T}\n\nCore.Type is an abstract type which has all type objects as its instances. The only instance of the singleton type Core.Type{T} is the object T.\n\nExamples\n\njulia> isa(Type{Float64}, Type)\ntrue\n\njulia> isa(Float64, Type)\ntrue\n\njulia> isa(Real, Type{Float64})\nfalse\n\njulia> isa(Real, Type{Real})\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.DataType","page":"Essentials","title":"Core.DataType","text":"DataType <: Type{T}\n\nDataType represents explicitly declared types that have names, explicitly declared supertypes, and, optionally, parameters. Every concrete value in the system is an instance of some DataType.\n\nExamples\n\njulia> typeof(Real)\nDataType\n\njulia> typeof(Int)\nDataType\n\njulia> struct Point\n x::Int\n y\n end\n\njulia> typeof(Point)\nDataType\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.:<:","page":"Essentials","title":"Core.:<:","text":"<:(T1, T2)::Bool\n\nSubtyping relation, defined between two types. In Julia, a type S is said to be a subtype of a type T if and only if we have S <: T.\n\nFor any type L and any type R, L <: R implies that any value v of type L is also of type R. I.e., (L <: R) && (v isa L) implies v isa R.\n\nThe subtyping relation is a partial order. I.e., <: is:\n\nreflexive: for any type T, T <: T holds\nantisymmetric: for any type A and any type B, (A <: B) && (B <: A) implies A == B\ntransitive: for any type A, any type B and any type C; (A <: B) && (B <: C) implies A <: C\n\nSee also info on Types, Union{}, Any, isa.\n\nExamples\n\njulia> Float64 <: AbstractFloat\ntrue\n\njulia> Vector{Int} <: AbstractArray\ntrue\n\njulia> Matrix{Float64} <: Matrix{AbstractFloat} # `Matrix` is invariant\nfalse\n\njulia> Tuple{Float64} <: Tuple{AbstractFloat} # `Tuple` is covariant\ntrue\n\njulia> Union{} <: Int # The bottom type, `Union{}`, subtypes each type.\ntrue\n\njulia> Union{} <: Float32 <: AbstractFloat <: Real <: Number <: Any # Operator chaining\ntrue\n\nThe <: keyword also has several syntactic uses which represent the same subtyping relation, but which do not execute the operator or return a Bool:\n\nTo specify the lower bound and the upper bound on a parameter of a UnionAll type in a where statement.\nTo specify the lower bound and the upper bound on a (static) parameter of a method, see Parametric Methods.\nTo define a subtyping relation while declaring a new type, see struct and abstract type.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.:>:","page":"Essentials","title":"Base.:>:","text":">:(T1, T2)\n\nSupertype operator, equivalent to T2 <: T1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.typejoin","page":"Essentials","title":"Base.typejoin","text":"typejoin(T, S, ...)\n\nReturn the closest common ancestor of types T and S, i.e. the narrowest type from which they both inherit. Recurses on additional varargs.\n\nExamples\n\njulia> typejoin(Int, Float64)\nReal\n\njulia> typejoin(Int, Float64, ComplexF32)\nNumber\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.typeintersect","page":"Essentials","title":"Base.typeintersect","text":"typeintersect(T::Type, S::Type)\n\nCompute a type that contains the intersection of T and S. Usually this will be the smallest such type or one close to it.\n\nA special case where exact behavior is guaranteed: when T <: S, typeintersect(S, T) == T == typeintersect(T, S).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.promote_type","page":"Essentials","title":"Base.promote_type","text":"promote_type(type1, type2, ...)\n\nPromotion refers to converting values of mixed types to a single common type. promote_type represents the default promotion behavior in Julia when operators (usually mathematical) are given arguments of differing types. promote_type generally tries to return a type which can at least approximate most values of either input type without excessively widening. Some loss is tolerated; for example, promote_type(Int64, Float64) returns Float64 even though strictly, not all Int64 values can be represented exactly as Float64 values.\n\nSee also: promote, promote_typejoin, promote_rule.\n\nExamples\n\njulia> promote_type(Int64, Float64)\nFloat64\n\njulia> promote_type(Int32, Int64)\nInt64\n\njulia> promote_type(Float32, BigInt)\nBigFloat\n\njulia> promote_type(Int16, Float16)\nFloat16\n\njulia> promote_type(Int64, Float16)\nFloat16\n\njulia> promote_type(Int8, UInt16)\nUInt16\n\nwarning: Don't overload this directly\nTo overload promotion for your own types you should overload promote_rule. promote_type calls promote_rule internally to determine the type. Overloading promote_type directly can cause ambiguity errors.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.promote_rule","page":"Essentials","title":"Base.promote_rule","text":"promote_rule(type1, type2)\n\nSpecifies what type should be used by promote when given values of types type1 and type2. This function should not be called directly, but should have definitions added to it for new types as appropriate.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.promote_typejoin","page":"Essentials","title":"Base.promote_typejoin","text":"promote_typejoin(T, S)\n\nCompute a type that contains both T and S, which could be either a parent of both types, or a Union if appropriate. Falls back to typejoin.\n\nSee instead promote, promote_type.\n\nExamples\n\njulia> Base.promote_typejoin(Int, Float64)\nReal\n\njulia> Base.promote_type(Int, Float64)\nFloat64\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isdispatchtuple","page":"Essentials","title":"Base.isdispatchtuple","text":"isdispatchtuple(T)\n\nDetermine whether type T is a tuple \"leaf type\", meaning it could appear as a type signature in dispatch and has no subtypes (or supertypes) which could appear in a call. If T is not a type, then return false.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Declared-structure","page":"Essentials","title":"Declared structure","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.ismutable\nBase.isimmutable\nBase.ismutabletype\nBase.isabstracttype\nBase.isprimitivetype\nBase.issingletontype\nBase.isstructtype\nBase.nameof(::DataType)\nBase.fieldnames\nBase.fieldname\nCore.fieldtype\nBase.fieldtypes\nBase.fieldcount\nBase.hasfield\nCore.nfields\nBase.isconst\nBase.isfieldatomic","category":"page"},{"location":"base/base/#Base.ismutable","page":"Essentials","title":"Base.ismutable","text":"ismutable(v) -> Bool\n\nReturn true if and only if value v is mutable. See Mutable Composite Types for a discussion of immutability. Note that this function works on values, so if you give it a DataType, it will tell you that a value of the type is mutable.\n\nnote: Note\nFor technical reasons, ismutable returns true for values of certain special types (for example String and Symbol) even though they cannot be mutated in a permissible way.\n\nSee also isbits, isstructtype.\n\nExamples\n\njulia> ismutable(1)\nfalse\n\njulia> ismutable([1,2])\ntrue\n\ncompat: Julia 1.5\nThis function requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isimmutable","page":"Essentials","title":"Base.isimmutable","text":"isimmutable(v) -> Bool\n\nwarning: Warning\nConsider using !ismutable(v) instead, as isimmutable(v) will be replaced by !ismutable(v) in a future release. (Since Julia 1.5)\n\nReturn true iff value v is immutable. See Mutable Composite Types for a discussion of immutability. Note that this function works on values, so if you give it a type, it will tell you that a value of DataType is mutable.\n\nExamples\n\njulia> isimmutable(1)\ntrue\n\njulia> isimmutable([1,2])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ismutabletype","page":"Essentials","title":"Base.ismutabletype","text":"ismutabletype(T) -> Bool\n\nDetermine whether type T was declared as a mutable type (i.e. using mutable struct keyword). If T is not a type, then return false.\n\ncompat: Julia 1.7\nThis function requires at least Julia 1.7.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isabstracttype","page":"Essentials","title":"Base.isabstracttype","text":"isabstracttype(T)\n\nDetermine whether type T was declared as an abstract type (i.e. using the abstract type syntax). Note that this is not the negation of isconcretetype(T). If T is not a type, then return false.\n\nExamples\n\njulia> isabstracttype(AbstractArray)\ntrue\n\njulia> isabstracttype(Vector)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isprimitivetype","page":"Essentials","title":"Base.isprimitivetype","text":"isprimitivetype(T) -> Bool\n\nDetermine whether type T was declared as a primitive type (i.e. using the primitive type syntax). If T is not a type, then return false.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.issingletontype","page":"Essentials","title":"Base.issingletontype","text":"Base.issingletontype(T)\n\nDetermine whether type T has exactly one possible instance; for example, a struct type with no fields except other singleton values. If T is not a concrete type, then return false.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isstructtype","page":"Essentials","title":"Base.isstructtype","text":"isstructtype(T) -> Bool\n\nDetermine whether type T was declared as a struct type (i.e. using the struct or mutable struct keyword). If T is not a type, then return false.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.nameof-Tuple{DataType}","page":"Essentials","title":"Base.nameof","text":"nameof(t::DataType) -> Symbol\n\nGet the name of a (potentially UnionAll-wrapped) DataType (without its parent module) as a symbol.\n\nExamples\n\njulia> module Foo\n struct S{T}\n end\n end\nFoo\n\njulia> nameof(Foo.S{T} where T)\n:S\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.fieldnames","page":"Essentials","title":"Base.fieldnames","text":"fieldnames(x::DataType)\n\nGet a tuple with the names of the fields of a DataType.\n\nSee also propertynames, hasfield.\n\nExamples\n\njulia> fieldnames(Rational)\n(:num, :den)\n\njulia> fieldnames(typeof(1+im))\n(:re, :im)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.fieldname","page":"Essentials","title":"Base.fieldname","text":"fieldname(x::DataType, i::Integer)\n\nGet the name of field i of a DataType.\n\nExamples\n\njulia> fieldname(Rational, 1)\n:num\n\njulia> fieldname(Rational, 2)\n:den\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.fieldtype","page":"Essentials","title":"Core.fieldtype","text":"fieldtype(T, name::Symbol | index::Int)\n\nDetermine the declared type of a field (specified by name or index) in a composite DataType T.\n\nExamples\n\njulia> struct Foo\n x::Int64\n y::String\n end\n\njulia> fieldtype(Foo, :x)\nInt64\n\njulia> fieldtype(Foo, 2)\nString\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.fieldtypes","page":"Essentials","title":"Base.fieldtypes","text":"fieldtypes(T::Type)\n\nThe declared types of all fields in a composite DataType T as a tuple.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nExamples\n\njulia> struct Foo\n x::Int64\n y::String\n end\n\njulia> fieldtypes(Foo)\n(Int64, String)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.fieldcount","page":"Essentials","title":"Base.fieldcount","text":"fieldcount(t::Type)\n\nGet the number of fields that an instance of the given type would have. An error is thrown if the type is too abstract to determine this.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.hasfield","page":"Essentials","title":"Base.hasfield","text":"hasfield(T::Type, name::Symbol)\n\nReturn a boolean indicating whether T has name as one of its own fields.\n\nSee also fieldnames, fieldcount, hasproperty.\n\ncompat: Julia 1.2\nThis function requires at least Julia 1.2.\n\nExamples\n\njulia> struct Foo\n bar::Int\n end\n\njulia> hasfield(Foo, :bar)\ntrue\n\njulia> hasfield(Foo, :x)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.nfields","page":"Essentials","title":"Core.nfields","text":"nfields(x) -> Int\n\nGet the number of fields in the given object.\n\nExamples\n\njulia> a = 1//2;\n\njulia> nfields(a)\n2\n\njulia> b = 1\n1\n\njulia> nfields(b)\n0\n\njulia> ex = ErrorException(\"I've done a bad thing\");\n\njulia> nfields(ex)\n1\n\nIn these examples, a is a Rational, which has two fields. b is an Int, which is a primitive bitstype with no fields at all. ex is an ErrorException, which has one field.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isconst","page":"Essentials","title":"Base.isconst","text":"isconst(m::Module, s::Symbol) -> Bool\n\nDetermine whether a global is declared const in a given module m.\n\n\n\n\n\nisconst(t::DataType, s::Union{Int,Symbol}) -> Bool\n\nDetermine whether a field s is declared const in a given type t.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isfieldatomic","page":"Essentials","title":"Base.isfieldatomic","text":"isfieldatomic(t::DataType, s::Union{Int,Symbol}) -> Bool\n\nDetermine whether a field s is declared @atomic in a given type t.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Memory-layout","page":"Essentials","title":"Memory layout","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.sizeof(::Type)\nBase.isconcretetype\nBase.isbits\nBase.isbitstype\nBase.fieldoffset\nBase.datatype_alignment\nBase.datatype_haspadding\nBase.datatype_pointerfree","category":"page"},{"location":"base/base/#Base.sizeof-Tuple{Type}","page":"Essentials","title":"Base.sizeof","text":"sizeof(T::DataType)\nsizeof(obj)\n\nSize, in bytes, of the canonical binary representation of the given DataType T, if any. Or the size, in bytes, of object obj if it is not a DataType.\n\nSee also Base.summarysize.\n\nExamples\n\njulia> sizeof(Float32)\n4\n\njulia> sizeof(ComplexF64)\n16\n\njulia> sizeof(1.0)\n8\n\njulia> sizeof(collect(1.0:10.0))\n80\n\njulia> struct StructWithPadding\n x::Int64\n flag::Bool\n end\n\njulia> sizeof(StructWithPadding) # not the sum of `sizeof` of fields due to padding\n16\n\njulia> sizeof(Int64) + sizeof(Bool) # different from above\n9\n\nIf DataType T does not have a specific size, an error is thrown.\n\njulia> sizeof(AbstractArray)\nERROR: Abstract type AbstractArray does not have a definite size.\nStacktrace:\n[...]\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.isconcretetype","page":"Essentials","title":"Base.isconcretetype","text":"isconcretetype(T)\n\nDetermine whether type T is a concrete type, meaning it could have direct instances (values x such that typeof(x) === T). Note that this is not the negation of isabstracttype(T). If T is not a type, then return false.\n\nSee also: isbits, isabstracttype, issingletontype.\n\nExamples\n\njulia> isconcretetype(Complex)\nfalse\n\njulia> isconcretetype(Complex{Float32})\ntrue\n\njulia> isconcretetype(Vector{Complex})\ntrue\n\njulia> isconcretetype(Vector{Complex{Float32}})\ntrue\n\njulia> isconcretetype(Union{})\nfalse\n\njulia> isconcretetype(Union{Int,String})\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isbits","page":"Essentials","title":"Base.isbits","text":"isbits(x)\n\nReturn true if x is an instance of an isbitstype type.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isbitstype","page":"Essentials","title":"Base.isbitstype","text":"isbitstype(T)\n\nReturn true if type T is a \"plain data\" type, meaning it is immutable and contains no references to other values, only primitive types and other isbitstype types. Typical examples are numeric types such as UInt8, Float64, and Complex{Float64}. This category of types is significant since they are valid as type parameters, may not track isdefined / isassigned status, and have a defined layout that is compatible with C. If T is not a type, then return false.\n\nSee also isbits, isprimitivetype, ismutable.\n\nExamples\n\njulia> isbitstype(Complex{Float64})\ntrue\n\njulia> isbitstype(Complex)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.fieldoffset","page":"Essentials","title":"Base.fieldoffset","text":"fieldoffset(type, i)\n\nThe byte offset of field i of a type relative to the data start. For example, we could use it in the following manner to summarize information about a struct:\n\njulia> structinfo(T) = [(fieldoffset(T,i), fieldname(T,i), fieldtype(T,i)) for i = 1:fieldcount(T)];\n\njulia> structinfo(Base.Filesystem.StatStruct)\n13-element Vector{Tuple{UInt64, Symbol, Type}}:\n (0x0000000000000000, :desc, Union{RawFD, String})\n (0x0000000000000008, :device, UInt64)\n (0x0000000000000010, :inode, UInt64)\n (0x0000000000000018, :mode, UInt64)\n (0x0000000000000020, :nlink, Int64)\n (0x0000000000000028, :uid, UInt64)\n (0x0000000000000030, :gid, UInt64)\n (0x0000000000000038, :rdev, UInt64)\n (0x0000000000000040, :size, Int64)\n (0x0000000000000048, :blksize, Int64)\n (0x0000000000000050, :blocks, Int64)\n (0x0000000000000058, :mtime, Float64)\n (0x0000000000000060, :ctime, Float64)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.datatype_alignment","page":"Essentials","title":"Base.datatype_alignment","text":"Base.datatype_alignment(dt::DataType) -> Int\n\nMemory allocation minimum alignment for instances of this type. Can be called on any isconcretetype, although for Memory it will give the alignment of the elements, not the whole object.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.datatype_haspadding","page":"Essentials","title":"Base.datatype_haspadding","text":"Base.datatype_haspadding(dt::DataType) -> Bool\n\nReturn whether the fields of instances of this type are packed in memory, with no intervening padding bits (defined as bits whose value does not uniquely impact the egal test when applied to the struct fields). Can be called on any isconcretetype.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.datatype_pointerfree","page":"Essentials","title":"Base.datatype_pointerfree","text":"Base.datatype_pointerfree(dt::DataType) -> Bool\n\nReturn whether instances of this type can contain references to gc-managed memory. Can be called on any isconcretetype.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Special-values","page":"Essentials","title":"Special values","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.typemin\nBase.typemax\nBase.floatmin\nBase.floatmax\nBase.maxintfloat\nBase.eps(::Type{<:AbstractFloat})\nBase.eps(::AbstractFloat)\nBase.instances","category":"page"},{"location":"base/base/#Base.typemin","page":"Essentials","title":"Base.typemin","text":"typemin(T)\n\nThe lowest value representable by the given (real) numeric DataType T.\n\nSee also: floatmin, typemax, eps.\n\nExamples\n\njulia> typemin(Int8)\n-128\n\njulia> typemin(UInt32)\n0x00000000\n\njulia> typemin(Float16)\n-Inf16\n\njulia> typemin(Float32)\n-Inf32\n\njulia> nextfloat(-Inf32) # smallest finite Float32 floating point number\n-3.4028235f38\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.typemax","page":"Essentials","title":"Base.typemax","text":"typemax(T)\n\nThe highest value representable by the given (real) numeric DataType.\n\nSee also: floatmax, typemin, eps.\n\nExamples\n\njulia> typemax(Int8)\n127\n\njulia> typemax(UInt32)\n0xffffffff\n\njulia> typemax(Float64)\nInf\n\njulia> typemax(Float32)\nInf32\n\njulia> floatmax(Float32) # largest finite Float32 floating point number\n3.4028235f38\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.floatmin","page":"Essentials","title":"Base.floatmin","text":"floatmin(T = Float64)\n\nReturn the smallest positive normal number representable by the floating-point type T.\n\nExamples\n\njulia> floatmin(Float16)\nFloat16(6.104e-5)\n\njulia> floatmin(Float32)\n1.1754944f-38\n\njulia> floatmin()\n2.2250738585072014e-308\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.floatmax","page":"Essentials","title":"Base.floatmax","text":"floatmax(T = Float64)\n\nReturn the largest finite number representable by the floating-point type T.\n\nSee also: typemax, floatmin, eps.\n\nExamples\n\njulia> floatmax(Float16)\nFloat16(6.55e4)\n\njulia> floatmax(Float32)\n3.4028235f38\n\njulia> floatmax()\n1.7976931348623157e308\n\njulia> typemax(Float64)\nInf\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.maxintfloat","page":"Essentials","title":"Base.maxintfloat","text":"maxintfloat(T=Float64)\n\nThe largest consecutive integer-valued floating-point number that is exactly represented in the given floating-point type T (which defaults to Float64).\n\nThat is, maxintfloat returns the smallest positive integer-valued floating-point number n such that n+1 is not exactly representable in the type T.\n\nWhen an Integer-type value is needed, use Integer(maxintfloat(T)).\n\n\n\n\n\nmaxintfloat(T, S)\n\nThe largest consecutive integer representable in the given floating-point type T that also does not exceed the maximum integer representable by the integer type S. Equivalently, it is the minimum of maxintfloat(T) and typemax(S).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.eps-Tuple{Type{<:AbstractFloat}}","page":"Essentials","title":"Base.eps","text":"eps(::Type{T}) where T<:AbstractFloat\neps()\n\nReturn the machine epsilon of the floating point type T (T = Float64 by default). This is defined as the gap between 1 and the next largest value representable by typeof(one(T)), and is equivalent to eps(one(T)). (Since eps(T) is a bound on the relative error of T, it is a \"dimensionless\" quantity like one.)\n\nExamples\n\njulia> eps()\n2.220446049250313e-16\n\njulia> eps(Float32)\n1.1920929f-7\n\njulia> 1.0 + eps()\n1.0000000000000002\n\njulia> 1.0 + eps()/2\n1.0\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.eps-Tuple{AbstractFloat}","page":"Essentials","title":"Base.eps","text":"eps(x::AbstractFloat)\n\nReturn the unit in last place (ulp) of x. This is the distance between consecutive representable floating point values at x. In most cases, if the distance on either side of x is different, then the larger of the two is taken, that is\n\neps(x) == max(x-prevfloat(x), nextfloat(x)-x)\n\nThe exceptions to this rule are the smallest and largest finite values (e.g. nextfloat(-Inf) and prevfloat(Inf) for Float64), which round to the smaller of the values.\n\nThe rationale for this behavior is that eps bounds the floating point rounding error. Under the default RoundNearest rounding mode, if y is a real number and x is the nearest floating point number to y, then\n\ny-x leq operatornameeps(x)2\n\nSee also: nextfloat, issubnormal, floatmax.\n\nExamples\n\njulia> eps(1.0)\n2.220446049250313e-16\n\njulia> eps(prevfloat(2.0))\n2.220446049250313e-16\n\njulia> eps(2.0)\n4.440892098500626e-16\n\njulia> x = prevfloat(Inf) # largest finite Float64\n1.7976931348623157e308\n\njulia> x + eps(x)/2 # rounds up\nInf\n\njulia> x + prevfloat(eps(x)/2) # rounds down\n1.7976931348623157e308\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.instances","page":"Essentials","title":"Base.instances","text":"instances(T::Type)\n\nReturn a collection of all instances of the given type, if applicable. Mostly used for enumerated types (see @enum).\n\nExamples\n\njulia> @enum Color red blue green\n\njulia> instances(Color)\n(red, blue, green)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Special-Types","page":"Essentials","title":"Special Types","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Core.Any\nCore.Union\nUnion{}\nCore.UnionAll\nCore.Tuple\nCore.NTuple\nCore.NamedTuple\nBase.@NamedTuple\nBase.@Kwargs\nBase.Val\nCore.Vararg\nCore.Nothing\nBase.isnothing\nBase.notnothing\nBase.Some\nBase.something\nBase.@something\nBase.Enums.Enum\nBase.Enums.@enum\nCore.Expr\nCore.Symbol\nCore.Symbol(x...)\nCore.Module","category":"page"},{"location":"base/base/#Core.Any","page":"Essentials","title":"Core.Any","text":"Any::DataType\n\nAny is the union of all types. It has the defining property isa(x, Any) == true for any x. Any therefore describes the entire universe of possible values. For example Integer is a subset of Any that includes Int, Int8, and other integer types.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Union","page":"Essentials","title":"Core.Union","text":"Union{Types...}\n\nA Union type is an abstract type which includes all instances of any of its argument types. This means that T <: Union{T,S} and S <: Union{T,S}.\n\nLike other abstract types, it cannot be instantiated, even if all of its arguments are non abstract.\n\nExamples\n\njulia> IntOrString = Union{Int,AbstractString}\nUnion{Int64, AbstractString}\n\njulia> 1 isa IntOrString # instance of Int is included in the union\ntrue\n\njulia> \"Hello!\" isa IntOrString # String is also included\ntrue\n\njulia> 1.0 isa IntOrString # Float64 is not included because it is neither Int nor AbstractString\nfalse\n\nExtended Help\n\nUnlike most other parametric types, unions are covariant in their parameters. For example, Union{Real, String} is a subtype of Union{Number, AbstractString}.\n\nThe empty union Union{} is the bottom type of Julia.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Union{}","page":"Essentials","title":"Union{}","text":"Union{}\n\nUnion{}, the empty Union of types, is the type that has no values. That is, it has the defining property isa(x, Union{}) == false for any x. Base.Bottom is defined as its alias and the type of Union{} is Core.TypeofBottom.\n\nExamples\n\njulia> isa(nothing, Union{})\nfalse\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Core.UnionAll","page":"Essentials","title":"Core.UnionAll","text":"UnionAll\n\nA union of types over all values of a type parameter. UnionAll is used to describe parametric types where the values of some parameters are not known. See the manual section on UnionAll Types.\n\nExamples\n\njulia> typeof(Vector)\nUnionAll\n\njulia> typeof(Vector{Int})\nDataType\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Tuple","page":"Essentials","title":"Core.Tuple","text":"Tuple{Types...}\n\nA tuple is a fixed-length container that can hold any values of different types, but cannot be modified (it is immutable). The values can be accessed via indexing. Tuple literals are written with commas and parentheses:\n\njulia> (1, 1+1)\n(1, 2)\n\njulia> (1,)\n(1,)\n\njulia> x = (0.0, \"hello\", 6*7)\n(0.0, \"hello\", 42)\n\njulia> x[2]\n\"hello\"\n\njulia> typeof(x)\nTuple{Float64, String, Int64}\n\nA length-1 tuple must be written with a comma, (1,), since (1) would just be a parenthesized value. () represents the empty (length-0) tuple.\n\nA tuple can be constructed from an iterator by using a Tuple type as constructor:\n\njulia> Tuple([\"a\", 1])\n(\"a\", 1)\n\njulia> Tuple{String, Float64}([\"a\", 1])\n(\"a\", 1.0)\n\nTuple types are covariant in their parameters: Tuple{Int} is a subtype of Tuple{Any}. Therefore Tuple{Any} is considered an abstract type, and tuple types are only concrete if their parameters are. Tuples do not have field names; fields are only accessed by index. Tuple types may have any number of parameters.\n\nSee the manual section on Tuple Types.\n\nSee also Vararg, NTuple, ntuple, tuple, NamedTuple.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.NTuple","page":"Essentials","title":"Core.NTuple","text":"NTuple{N, T}\n\nA compact way of representing the type for a tuple of length N where all elements are of type T.\n\nExamples\n\njulia> isa((1, 2, 3, 4, 5, 6), NTuple{6, Int})\ntrue\n\nSee also ntuple.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.NamedTuple","page":"Essentials","title":"Core.NamedTuple","text":"NamedTuple\n\nNamedTuples are, as their name suggests, named Tuples. That is, they're a tuple-like collection of values, where each entry has a unique name, represented as a Symbol. Like Tuples, NamedTuples are immutable; neither the names nor the values can be modified in place after construction.\n\nA named tuple can be created as a tuple literal with keys, e.g. (a=1, b=2), or as a tuple literal with semicolon after the opening parenthesis, e.g. (; a=1, b=2) (this form also accepts programmatically generated names as described below), or using a NamedTuple type as constructor, e.g. NamedTuple{(:a, :b)}((1,2)).\n\nAccessing the value associated with a name in a named tuple can be done using field access syntax, e.g. x.a, or using getindex, e.g. x[:a] or x[(:a, :b)]. A tuple of the names can be obtained using keys, and a tuple of the values can be obtained using values.\n\nnote: Note\nIteration over NamedTuples produces the values without the names. (See example below.) To iterate over the name-value pairs, use the pairs function.\n\nThe @NamedTuple macro can be used for conveniently declaring NamedTuple types.\n\nExamples\n\njulia> x = (a=1, b=2)\n(a = 1, b = 2)\n\njulia> x.a\n1\n\njulia> x[:a]\n1\n\njulia> x[(:a,)]\n(a = 1,)\n\njulia> keys(x)\n(:a, :b)\n\njulia> values(x)\n(1, 2)\n\njulia> collect(x)\n2-element Vector{Int64}:\n 1\n 2\n\njulia> collect(pairs(x))\n2-element Vector{Pair{Symbol, Int64}}:\n :a => 1\n :b => 2\n\nIn a similar fashion as to how one can define keyword arguments programmatically, a named tuple can be created by giving pairs name::Symbol => value after a semicolon inside a tuple literal. This and the name=value syntax can be mixed:\n\njulia> (; :a => 1, :b => 2, c=3)\n(a = 1, b = 2, c = 3)\n\nThe name-value pairs can also be provided by splatting a named tuple or any iterator that yields two-value collections holding each a symbol as first value:\n\njulia> keys = (:a, :b, :c); values = (1, 2, 3);\n\njulia> NamedTuple{keys}(values)\n(a = 1, b = 2, c = 3)\n\njulia> (; (keys .=> values)...)\n(a = 1, b = 2, c = 3)\n\njulia> nt1 = (a=1, b=2);\n\njulia> nt2 = (c=3, d=4);\n\njulia> (; nt1..., nt2..., b=20) # the final b overwrites the value from nt1\n(a = 1, b = 20, c = 3, d = 4)\n\njulia> (; zip(keys, values)...) # zip yields tuples such as (:a, 1)\n(a = 1, b = 2, c = 3)\n\nAs in keyword arguments, identifiers and dot expressions imply names:\n\njulia> x = 0\n0\n\njulia> t = (; x)\n(x = 0,)\n\njulia> (; t.x)\n(x = 0,)\n\ncompat: Julia 1.5\nImplicit names from identifiers and dot expressions are available as of Julia 1.5.\n\ncompat: Julia 1.7\nUse of getindex methods with multiple Symbols is available as of Julia 1.7.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.@NamedTuple","page":"Essentials","title":"Base.@NamedTuple","text":"@NamedTuple{key1::Type1, key2::Type2, ...}\n@NamedTuple begin key1::Type1; key2::Type2; ...; end\n\nThis macro gives a more convenient syntax for declaring NamedTuple types. It returns a NamedTuple type with the given keys and types, equivalent to NamedTuple{(:key1, :key2, ...), Tuple{Type1,Type2,...}}. If the ::Type declaration is omitted, it is taken to be Any. The begin ... end form allows the declarations to be split across multiple lines (similar to a struct declaration), but is otherwise equivalent. The NamedTuple macro is used when printing NamedTuple types to e.g. the REPL.\n\nFor example, the tuple (a=3.1, b=\"hello\") has a type NamedTuple{(:a, :b), Tuple{Float64, String}}, which can also be declared via @NamedTuple as:\n\njulia> @NamedTuple{a::Float64, b::String}\n@NamedTuple{a::Float64, b::String}\n\njulia> @NamedTuple begin\n a::Float64\n b::String\n end\n@NamedTuple{a::Float64, b::String}\n\ncompat: Julia 1.5\nThis macro is available as of Julia 1.5.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@Kwargs","page":"Essentials","title":"Base.@Kwargs","text":"@Kwargs{key1::Type1, key2::Type2, ...}\n\nThis macro gives a convenient way to construct the type representation of keyword arguments from the same syntax as @NamedTuple. For example, when we have a function call like func([positional arguments]; kw1=1.0, kw2=\"2\"), we can use this macro to construct the internal type representation of the keyword arguments as @Kwargs{kw1::Float64, kw2::String}. The macro syntax is specifically designed to simplify the signature type of a keyword method when it is printed in the stack trace view.\n\njulia> @Kwargs{init::Int} # the internal representation of keyword arguments\nBase.Pairs{Symbol, Int64, Tuple{Symbol}, @NamedTuple{init::Int64}}\n\njulia> sum(\"julia\"; init=1)\nERROR: MethodError: no method matching +(::Char, ::Char)\nThe function `+` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n +(::Any, ::Any, ::Any, ::Any...)\n @ Base operators.jl:585\n +(::Integer, ::AbstractChar)\n @ Base char.jl:247\n +(::T, ::Integer) where T<:AbstractChar\n @ Base char.jl:237\n\nStacktrace:\n [1] add_sum(x::Char, y::Char)\n @ Base ./reduce.jl:24\n [2] BottomRF\n @ Base ./reduce.jl:86 [inlined]\n [3] _foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, init::Int64, itr::String)\n @ Base ./reduce.jl:62\n [4] foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, nt::Int64, itr::String)\n @ Base ./reduce.jl:48 [inlined]\n [5] mapfoldl_impl(f::typeof(identity), op::typeof(Base.add_sum), nt::Int64, itr::String)\n @ Base ./reduce.jl:44 [inlined]\n [6] mapfoldl(f::typeof(identity), op::typeof(Base.add_sum), itr::String; init::Int64)\n @ Base ./reduce.jl:175 [inlined]\n [7] mapreduce(f::typeof(identity), op::typeof(Base.add_sum), itr::String; kw::@Kwargs{init::Int64})\n @ Base ./reduce.jl:307 [inlined]\n [8] sum(f::typeof(identity), a::String; kw::@Kwargs{init::Int64})\n @ Base ./reduce.jl:535 [inlined]\n [9] sum(a::String; kw::@Kwargs{init::Int64})\n @ Base ./reduce.jl:564 [inlined]\n [10] top-level scope\n @ REPL[12]:1\n\ncompat: Julia 1.10\nThis macro is available as of Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Val","page":"Essentials","title":"Base.Val","text":"Val(c)\n\nReturn Val{c}(), which contains no run-time data. Types like this can be used to pass the information between functions through the value c, which must be an isbits value or a Symbol. The intent of this construct is to be able to dispatch on constants directly (at compile time) without having to test the value of the constant at run time.\n\nExamples\n\njulia> f(::Val{true}) = \"Good\"\nf (generic function with 1 method)\n\njulia> f(::Val{false}) = \"Bad\"\nf (generic function with 2 methods)\n\njulia> f(Val(true))\n\"Good\"\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Vararg","page":"Essentials","title":"Core.Vararg","text":"Vararg{T,N}\n\nThe last parameter of a tuple type Tuple can be the special value Vararg, which denotes any number of trailing elements. Vararg{T,N} corresponds to exactly N elements of type T. Finally Vararg{T} corresponds to zero or more elements of type T. Vararg tuple types are used to represent the arguments accepted by varargs methods (see the section on Varargs Functions in the manual.)\n\nSee also NTuple.\n\nExamples\n\njulia> mytupletype = Tuple{AbstractString, Vararg{Int}}\nTuple{AbstractString, Vararg{Int64}}\n\njulia> isa((\"1\",), mytupletype)\ntrue\n\njulia> isa((\"1\",1), mytupletype)\ntrue\n\njulia> isa((\"1\",1,2), mytupletype)\ntrue\n\njulia> isa((\"1\",1,2,3.0), mytupletype)\nfalse\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Core.Nothing","page":"Essentials","title":"Core.Nothing","text":"Nothing\n\nA type with no fields that is the type of nothing.\n\nSee also: isnothing, Some, Missing.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.isnothing","page":"Essentials","title":"Base.isnothing","text":"isnothing(x)\n\nReturn true if x === nothing, and return false if not.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nSee also something, Base.notnothing, ismissing.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.notnothing","page":"Essentials","title":"Base.notnothing","text":"notnothing(x)\n\nThrow an error if x === nothing, and return x if not.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Some","page":"Essentials","title":"Base.Some","text":"Some{T}\n\nA wrapper type used in Union{Some{T}, Nothing} to distinguish between the absence of a value (nothing) and the presence of a nothing value (i.e. Some(nothing)).\n\nUse something to access the value wrapped by a Some object.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.something","page":"Essentials","title":"Base.something","text":"something(x...)\n\nReturn the first value in the arguments which is not equal to nothing, if any. Otherwise throw an error. Arguments of type Some are unwrapped.\n\nSee also coalesce, skipmissing, @something.\n\nExamples\n\njulia> something(nothing, 1)\n1\n\njulia> something(Some(1), nothing)\n1\n\njulia> something(Some(nothing), 2) === nothing\ntrue\n\njulia> something(missing, nothing)\nmissing\n\njulia> something(nothing, nothing)\nERROR: ArgumentError: No value arguments present\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@something","page":"Essentials","title":"Base.@something","text":"@something(x...)\n\nShort-circuiting version of something.\n\nExamples\n\njulia> f(x) = (println(\"f($x)\"); nothing);\n\njulia> a = 1;\n\njulia> a = @something a f(2) f(3) error(\"Unable to find default for `a`\")\n1\n\njulia> b = nothing;\n\njulia> b = @something b f(2) f(3) error(\"Unable to find default for `b`\")\nf(2)\nf(3)\nERROR: Unable to find default for `b`\n[...]\n\njulia> b = @something b f(2) f(3) Some(nothing)\nf(2)\nf(3)\n\njulia> b === nothing\ntrue\n\ncompat: Julia 1.7\nThis macro is available as of Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Enums.Enum","page":"Essentials","title":"Base.Enums.Enum","text":"Enum{T<:Integer}\n\nThe abstract supertype of all enumerated types defined with @enum.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.Enums.@enum","page":"Essentials","title":"Base.Enums.@enum","text":"@enum EnumName[::BaseType] value1[=x] value2[=y]\n\nCreate an Enum{BaseType} subtype with name EnumName and enum member values of value1 and value2 with optional assigned values of x and y, respectively. EnumName can be used just like other types and enum member values as regular values, such as\n\nExamples\n\njulia> @enum Fruit apple=1 orange=2 kiwi=3\n\njulia> f(x::Fruit) = \"I'm a Fruit with value: $(Int(x))\"\nf (generic function with 1 method)\n\njulia> f(apple)\n\"I'm a Fruit with value: 1\"\n\njulia> Fruit(1)\napple::Fruit = 1\n\nValues can also be specified inside a begin block, e.g.\n\n@enum EnumName begin\n value1\n value2\nend\n\nBaseType, which defaults to Int32, must be a primitive subtype of Integer. Member values can be converted between the enum type and BaseType. read and write perform these conversions automatically. In case the enum is created with a non-default BaseType, Integer(value1) will return the integer value1 with the type BaseType.\n\nTo list all the instances of an enum use instances, e.g.\n\njulia> instances(Fruit)\n(apple, orange, kiwi)\n\nIt is possible to construct a symbol from an enum instance:\n\njulia> Symbol(apple)\n:apple\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Core.Expr","page":"Essentials","title":"Core.Expr","text":"Expr(head::Symbol, args...)\n\nA type representing compound expressions in parsed julia code (ASTs). Each expression consists of a head Symbol identifying which kind of expression it is (e.g. a call, for loop, conditional statement, etc.), and subexpressions (e.g. the arguments of a call). The subexpressions are stored in a Vector{Any} field called args.\n\nSee the manual chapter on Metaprogramming and the developer documentation Julia ASTs.\n\nExamples\n\njulia> Expr(:call, :+, 1, 2)\n:(1 + 2)\n\njulia> dump(:(a ? b : c))\nExpr\n head: Symbol if\n args: Array{Any}((3,))\n 1: Symbol a\n 2: Symbol b\n 3: Symbol c\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Symbol","page":"Essentials","title":"Core.Symbol","text":"Symbol\n\nThe type of object used to represent identifiers in parsed julia code (ASTs). Also often used as a name or label to identify an entity (e.g. as a dictionary key). Symbols can be entered using the : quote operator:\n\njulia> :name\n:name\n\njulia> typeof(:name)\nSymbol\n\njulia> x = 42\n42\n\njulia> eval(:x)\n42\n\nSymbols can also be constructed from strings or other values by calling the constructor Symbol(x...).\n\nSymbols are immutable and their implementation re-uses the same object for all Symbols with the same name.\n\nUnlike strings, Symbols are \"atomic\" or \"scalar\" entities that do not support iteration over characters.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.Symbol-Tuple","page":"Essentials","title":"Core.Symbol","text":"Symbol(x...) -> Symbol\n\nCreate a Symbol by concatenating the string representations of the arguments together.\n\nExamples\n\njulia> Symbol(\"my\", \"name\")\n:myname\n\njulia> Symbol(\"day\", 4)\n:day4\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Core.Module","page":"Essentials","title":"Core.Module","text":"Module\n\nA Module is a separate global variable workspace. See module and the manual section about modules for details.\n\nModule(name::Symbol=:anonymous, std_imports=true, default_names=true)\n\nReturn a module with the specified name. A baremodule corresponds to Module(:ModuleName, false)\n\nAn empty module containing no names at all can be created with Module(:ModuleName, false, false). This module will not import Base or Core and does not contain a reference to itself.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Generic-Functions","page":"Essentials","title":"Generic Functions","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Core.Function\nBase.hasmethod\nCore.applicable\nBase.isambiguous\nCore.invoke\nBase.@invoke\nBase.invokelatest\nBase.@invokelatest\nnew\nBase.:(|>)\nBase.:(∘)\nBase.ComposedFunction\nBase.splat\nBase.Fix1\nBase.Fix2","category":"page"},{"location":"base/base/#Core.Function","page":"Essentials","title":"Core.Function","text":"Function\n\nAbstract type of all functions.\n\nExamples\n\njulia> isa(+, Function)\ntrue\n\njulia> typeof(sin)\ntypeof(sin) (singleton type of function sin, subtype of Function)\n\njulia> ans <: Function\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.hasmethod","page":"Essentials","title":"Base.hasmethod","text":"hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool\n\nDetermine whether the given generic function has a method matching the given Tuple of argument types with the upper bound of world age given by world.\n\nIf a tuple of keyword argument names kwnames is provided, this also checks whether the method of f matching t has the given keyword argument names. If the matching method accepts a variable number of keyword arguments, e.g. with kwargs..., any names given in kwnames are considered valid. Otherwise the provided names must be a subset of the method's keyword arguments.\n\nSee also applicable.\n\ncompat: Julia 1.2\nProviding keyword argument names requires Julia 1.2 or later.\n\nExamples\n\njulia> hasmethod(length, Tuple{Array})\ntrue\n\njulia> f(; oranges=0) = oranges;\n\njulia> hasmethod(f, Tuple{}, (:oranges,))\ntrue\n\njulia> hasmethod(f, Tuple{}, (:apples, :bananas))\nfalse\n\njulia> g(; xs...) = 4;\n\njulia> hasmethod(g, Tuple{}, (:a, :b, :c, :d)) # g accepts arbitrary kwargs\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.applicable","page":"Essentials","title":"Core.applicable","text":"applicable(f, args...) -> Bool\n\nDetermine whether the given generic function has a method applicable to the given arguments.\n\nSee also hasmethod.\n\nExamples\n\njulia> function f(x, y)\n x + y\n end;\n\njulia> applicable(f, 1)\nfalse\n\njulia> applicable(f, 1, 2)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isambiguous","page":"Essentials","title":"Base.isambiguous","text":"Base.isambiguous(m1, m2; ambiguous_bottom=false) -> Bool\n\nDetermine whether two methods m1 and m2 may be ambiguous for some call signature. This test is performed in the context of other methods of the same function; in isolation, m1 and m2 might be ambiguous, but if a third method resolving the ambiguity has been defined, this returns false. Alternatively, in isolation m1 and m2 might be ordered, but if a third method cannot be sorted with them, they may cause an ambiguity together.\n\nFor parametric types, the ambiguous_bottom keyword argument controls whether Union{} counts as an ambiguous intersection of type parameters – when true, it is considered ambiguous, when false it is not.\n\nExamples\n\njulia> foo(x::Complex{<:Integer}) = 1\nfoo (generic function with 1 method)\n\njulia> foo(x::Complex{<:Rational}) = 2\nfoo (generic function with 2 methods)\n\njulia> m1, m2 = collect(methods(foo));\n\njulia> typeintersect(m1.sig, m2.sig)\nTuple{typeof(foo), Complex{Union{}}}\n\njulia> Base.isambiguous(m1, m2, ambiguous_bottom=true)\ntrue\n\njulia> Base.isambiguous(m1, m2, ambiguous_bottom=false)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.invoke","page":"Essentials","title":"Core.invoke","text":"invoke(f, argtypes::Type, args...; kwargs...)\n\nInvoke a method for the given generic function f matching the specified types argtypes on the specified arguments args and passing the keyword arguments kwargs. The arguments args must conform with the specified types in argtypes, i.e. conversion is not automatically performed. This method allows invoking a method other than the most specific matching method, which is useful when the behavior of a more general definition is explicitly needed (often as part of the implementation of a more specific method of the same function).\n\nBe careful when using invoke for functions that you don't write. What definition is used for given argtypes is an implementation detail unless the function is explicitly states that calling with certain argtypes is a part of public API. For example, the change between f1 and f2 in the example below is usually considered compatible because the change is invisible by the caller with a normal (non-invoke) call. However, the change is visible if you use invoke.\n\nExamples\n\njulia> f(x::Real) = x^2;\n\njulia> f(x::Integer) = 1 + invoke(f, Tuple{Real}, x);\n\njulia> f(2)\n5\n\njulia> f1(::Integer) = Integer\n f1(::Real) = Real;\n\njulia> f2(x::Real) = _f2(x)\n _f2(::Integer) = Integer\n _f2(_) = Real;\n\njulia> f1(1)\nInteger\n\njulia> f2(1)\nInteger\n\njulia> invoke(f1, Tuple{Real}, 1)\nReal\n\njulia> invoke(f2, Tuple{Real}, 1)\nInteger\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@invoke","page":"Essentials","title":"Base.@invoke","text":"@invoke f(arg::T, ...; kwargs...)\n\nProvides a convenient way to call invoke by expanding @invoke f(arg1::T1, arg2::T2; kwargs...) to invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...). When an argument's type annotation is omitted, it's replaced with Core.Typeof that argument. To invoke a method where an argument is untyped or explicitly typed as Any, annotate the argument with ::Any.\n\nIt also supports the following syntax:\n\n@invoke (x::X).f expands to invoke(getproperty, Tuple{X,Symbol}, x, :f)\n@invoke (x::X).f = v::V expands to invoke(setproperty!, Tuple{X,Symbol,V}, x, :f, v)\n@invoke (xs::Xs)[i::I] expands to invoke(getindex, Tuple{Xs,I}, xs, i)\n@invoke (xs::Xs)[i::I] = v::V expands to invoke(setindex!, Tuple{Xs,V,I}, xs, v, i)\n\nExamples\n\njulia> @macroexpand @invoke f(x::T, y)\n:(Core.invoke(f, Tuple{T, Core.Typeof(y)}, x, y))\n\njulia> @invoke 420::Integer % Unsigned\n0x00000000000001a4\n\njulia> @macroexpand @invoke (x::X).f\n:(Core.invoke(Base.getproperty, Tuple{X, Core.Typeof(:f)}, x, :f))\n\njulia> @macroexpand @invoke (x::X).f = v::V\n:(Core.invoke(Base.setproperty!, Tuple{X, Core.Typeof(:f), V}, x, :f, v))\n\njulia> @macroexpand @invoke (xs::Xs)[i::I]\n:(Core.invoke(Base.getindex, Tuple{Xs, I}, xs, i))\n\njulia> @macroexpand @invoke (xs::Xs)[i::I] = v::V\n:(Core.invoke(Base.setindex!, Tuple{Xs, V, I}, xs, v, i))\n\ncompat: Julia 1.7\nThis macro requires Julia 1.7 or later.\n\ncompat: Julia 1.9\nThis macro is exported as of Julia 1.9.\n\ncompat: Julia 1.10\nThe additional syntax is supported as of Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.invokelatest","page":"Essentials","title":"Base.invokelatest","text":"invokelatest(f, args...; kwargs...)\n\nCalls f(args...; kwargs...), but guarantees that the most recent method of f will be executed. This is useful in specialized circumstances, e.g. long-running event loops or callback functions that may call obsolete versions of a function f. (The drawback is that invokelatest is somewhat slower than calling f directly, and the type of the result cannot be inferred by the compiler.)\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this function was not exported, and was called as Base.invokelatest.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@invokelatest","page":"Essentials","title":"Base.@invokelatest","text":"@invokelatest f(args...; kwargs...)\n\nProvides a convenient way to call invokelatest. @invokelatest f(args...; kwargs...) will simply be expanded into Base.invokelatest(f, args...; kwargs...).\n\nIt also supports the following syntax:\n\n@invokelatest x.f expands to Base.invokelatest(getproperty, x, :f)\n@invokelatest x.f = v expands to Base.invokelatest(setproperty!, x, :f, v)\n@invokelatest xs[i] expands to Base.invokelatest(getindex, xs, i)\n@invokelatest xs[i] = v expands to Base.invokelatest(setindex!, xs, v, i)\n\njulia> @macroexpand @invokelatest f(x; kw=kwv)\n:(Base.invokelatest(f, x; kw = kwv))\n\njulia> @macroexpand @invokelatest x.f\n:(Base.invokelatest(Base.getproperty, x, :f))\n\njulia> @macroexpand @invokelatest x.f = v\n:(Base.invokelatest(Base.setproperty!, x, :f, v))\n\njulia> @macroexpand @invokelatest xs[i]\n:(Base.invokelatest(Base.getindex, xs, i))\n\njulia> @macroexpand @invokelatest xs[i] = v\n:(Base.invokelatest(Base.setindex!, xs, v, i))\n\ncompat: Julia 1.7\nThis macro requires Julia 1.7 or later.\n\ncompat: Julia 1.9\nPrior to Julia 1.9, this macro was not exported, and was called as Base.@invokelatest.\n\ncompat: Julia 1.10\nThe additional x.f and xs[i] syntax requires Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#new","page":"Essentials","title":"new","text":"new, or new{A,B,...}\n\nSpecial function available to inner constructors which creates a new object of the type. The form new{A,B,...} explicitly specifies values of parameters for parametric types. See the manual section on Inner Constructor Methods for more information.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.:|>","page":"Essentials","title":"Base.:|>","text":"|>(x, f)\n\nInfix operator which applies function f to the argument x. This allows f(g(x)) to be written x |> g |> f. When used with anonymous functions, parentheses are typically required around the definition to get the intended chain.\n\nExamples\n\njulia> 4 |> inv\n0.25\n\njulia> [2, 3, 5] |> sum |> inv\n0.1\n\njulia> [0 1; 2 3] .|> (x -> x^2) |> sum\n14\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.:∘","page":"Essentials","title":"Base.:∘","text":"f ∘ g\n\nCompose functions: i.e. (f ∘ g)(args...; kwargs...) means f(g(args...; kwargs...)). The ∘ symbol can be entered in the Julia REPL (and most editors, appropriately configured) by typing \\circ.\n\nFunction composition also works in prefix form: ∘(f, g) is the same as f ∘ g. The prefix form supports composition of multiple functions: ∘(f, g, h) = f ∘ g ∘ h and splatting ∘(fs...) for composing an iterable collection of functions. The last argument to ∘ execute first.\n\ncompat: Julia 1.4\nMultiple function composition requires at least Julia 1.4.\n\ncompat: Julia 1.5\nComposition of one function ∘(f) requires at least Julia 1.5.\n\ncompat: Julia 1.7\nUsing keyword arguments requires at least Julia 1.7.\n\nExamples\n\njulia> map(uppercase∘first, [\"apple\", \"banana\", \"carrot\"])\n3-element Vector{Char}:\n 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)\n 'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)\n 'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)\n\njulia> (==(6)∘length).([\"apple\", \"banana\", \"carrot\"])\n3-element BitVector:\n 0\n 1\n 1\n\njulia> fs = [\n x -> 2x\n x -> x-1\n x -> x/2\n x -> x+1\n ];\n\njulia> ∘(fs...)(3)\n2.0\n\nSee also ComposedFunction, !f::Function.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ComposedFunction","page":"Essentials","title":"Base.ComposedFunction","text":"ComposedFunction{Outer,Inner} <: Function\n\nRepresents the composition of two callable objects outer::Outer and inner::Inner. That is\n\nComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))\n\nThe preferred way to construct an instance of ComposedFunction is to use the composition operator ∘:\n\njulia> sin ∘ cos === ComposedFunction(sin, cos)\ntrue\n\njulia> typeof(sin∘cos)\nComposedFunction{typeof(sin), typeof(cos)}\n\nThe composed pieces are stored in the fields of ComposedFunction and can be retrieved as follows:\n\njulia> composition = sin ∘ cos\nsin ∘ cos\n\njulia> composition.outer === sin\ntrue\n\njulia> composition.inner === cos\ntrue\n\ncompat: Julia 1.6\nComposedFunction requires at least Julia 1.6. In earlier versions ∘ returns an anonymous function instead.\n\nSee also ∘.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.splat","page":"Essentials","title":"Base.splat","text":"splat(f)\n\nEquivalent to\n\n my_splat(f) = args->f(args...)\n\ni.e. given a function returns a new function that takes one argument and splats it into the original function. This is useful as an adaptor to pass a multi-argument function in a context that expects a single argument, but passes a tuple as that single argument.\n\nExamples\n\njulia> map(splat(+), zip(1:3,4:6))\n3-element Vector{Int64}:\n 5\n 7\n 9\n\njulia> my_add = splat(+)\nsplat(+)\n\njulia> my_add((1,2,3))\n6\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Fix1","page":"Essentials","title":"Base.Fix1","text":"Fix1(f, x)\n\nA type representing a partially-applied version of the two-argument function f, with the first argument fixed to the value \"x\". In other words, Fix1(f, x) behaves similarly to y->f(x, y).\n\nSee also Fix2.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.Fix2","page":"Essentials","title":"Base.Fix2","text":"Fix2(f, x)\n\nA type representing a partially-applied version of the two-argument function f, with the second argument fixed to the value \"x\". In other words, Fix2(f, x) behaves similarly to y->f(y, x).\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Syntax","page":"Essentials","title":"Syntax","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Core.eval\nMain.eval\nBase.@eval\nBase.evalfile\nBase.esc\nBase.@inbounds\nBase.@boundscheck\nBase.@propagate_inbounds\nBase.@inline\nBase.@noinline\nBase.@nospecialize\nBase.@specialize\nBase.@nospecializeinfer\nBase.@constprop\nBase.gensym\nBase.@gensym\nvar\"name\"\nBase.@goto\nBase.@label\nBase.@simd\nBase.@polly\nBase.@generated\nBase.@assume_effects\nBase.@deprecate","category":"page"},{"location":"base/base/#Core.eval","page":"Essentials","title":"Core.eval","text":"Core.eval(m::Module, expr)\n\nEvaluate an expression in the given module and return the result.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#eval","page":"Essentials","title":"eval","text":"eval(expr)\n\nEvaluate an expression in the global scope of the containing module. Every Module (except those defined with baremodule) has its own 1-argument definition of eval, which evaluates expressions in that module.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@eval","page":"Essentials","title":"Base.@eval","text":"@eval [mod,] ex\n\nEvaluate an expression with values interpolated into it using eval. If two arguments are provided, the first is the module to evaluate in.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.evalfile","page":"Essentials","title":"Base.evalfile","text":"evalfile(path::AbstractString, args::Vector{String}=String[])\n\nLoad the file into an anonymous module using include, evaluate all expressions, and return the value of the last expression. The optional args argument can be used to set the input arguments of the script (i.e. the global ARGS variable). Note that definitions (e.g. methods, globals) are evaluated in the anonymous module and do not affect the current module.\n\nExamples\n\njulia> write(\"testfile.jl\", \"\"\"\n @show ARGS\n 1 + 1\n \"\"\");\n\njulia> x = evalfile(\"testfile.jl\", [\"ARG1\", \"ARG2\"]);\nARGS = [\"ARG1\", \"ARG2\"]\n\njulia> x\n2\n\njulia> rm(\"testfile.jl\")\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.esc","page":"Essentials","title":"Base.esc","text":"esc(e)\n\nOnly valid in the context of an Expr returned from a macro. Prevents the macro hygiene pass from turning embedded variables into gensym variables. See the Macros section of the Metaprogramming chapter of the manual for more details and examples.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@inbounds","page":"Essentials","title":"Base.@inbounds","text":"@inbounds(blk)\n\nEliminates array bounds checking within expressions.\n\nIn the example below the in-range check for referencing element i of array A is skipped to improve performance.\n\nfunction sum(A::AbstractArray)\n r = zero(eltype(A))\n for i in eachindex(A)\n @inbounds r += A[i]\n end\n return r\nend\n\nwarning: Warning\nUsing @inbounds may return incorrect results/crashes/corruption for out-of-bounds indices. The user is responsible for checking it manually. Only use @inbounds when it is certain from the information locally available that all accesses are in bounds. In particular, using 1:length(A) instead of eachindex(A) in a function like the one above is not safely inbounds because the first index of A may not be 1 for all user defined types that subtype AbstractArray.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@boundscheck","page":"Essentials","title":"Base.@boundscheck","text":"@boundscheck(blk)\n\nAnnotates the expression blk as a bounds checking block, allowing it to be elided by @inbounds.\n\nnote: Note\nThe function in which @boundscheck is written must be inlined into its caller in order for @inbounds to have effect.\n\nExamples\n\njulia> @inline function g(A, i)\n @boundscheck checkbounds(A, i)\n return \"accessing ($A)[$i]\"\n end;\n\njulia> f1() = return g(1:2, -1);\n\njulia> f2() = @inbounds return g(1:2, -1);\n\njulia> f1()\nERROR: BoundsError: attempt to access 2-element UnitRange{Int64} at index [-1]\nStacktrace:\n [1] throw_boundserror(::UnitRange{Int64}, ::Tuple{Int64}) at ./abstractarray.jl:455\n [2] checkbounds at ./abstractarray.jl:420 [inlined]\n [3] g at ./none:2 [inlined]\n [4] f1() at ./none:1\n [5] top-level scope\n\njulia> f2()\n\"accessing (1:2)[-1]\"\n\nwarning: Warning\nThe @boundscheck annotation allows you, as a library writer, to opt-in to allowing other code to remove your bounds checks with @inbounds. As noted there, the caller must verify—using information they can access—that their accesses are valid before using @inbounds. For indexing into your AbstractArray subclasses, for example, this involves checking the indices against its axes. Therefore, @boundscheck annotations should only be added to a getindex or setindex! implementation after you are certain its behavior is correct.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@propagate_inbounds","page":"Essentials","title":"Base.@propagate_inbounds","text":"@propagate_inbounds\n\nTells the compiler to inline a function while retaining the caller's inbounds context.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@inline","page":"Essentials","title":"Base.@inline","text":"@inline\n\nGive a hint to the compiler that this function is worth inlining.\n\nSmall functions typically do not need the @inline annotation, as the compiler does it automatically. By using @inline on bigger functions, an extra nudge can be given to the compiler to inline it.\n\n@inline can be applied immediately before a function definition or within a function body.\n\n# annotate long-form definition\n@inline function longdef(x)\n ...\nend\n\n# annotate short-form definition\n@inline shortdef(x) = ...\n\n# annotate anonymous function that a `do` block creates\nf() do\n @inline\n ...\nend\n\ncompat: Julia 1.8\nThe usage within a function body requires at least Julia 1.8.\n\n\n\n@inline block\n\nGive a hint to the compiler that calls within block are worth inlining.\n\n# The compiler will try to inline `f`\n@inline f(...)\n\n# The compiler will try to inline `f`, `g` and `+`\n@inline f(...) + g(...)\n\nnote: Note\nA callsite annotation always has the precedence over the annotation applied to the definition of the called function:@noinline function explicit_noinline(args...)\n # body\nend\n\nlet\n @inline explicit_noinline(args...) # will be inlined\nend\n\nnote: Note\nWhen there are nested callsite annotations, the innermost annotation has the precedence:@noinline let a0, b0 = ...\n a = @inline f(a0) # the compiler will try to inline this call\n b = f(b0) # the compiler will NOT try to inline this call\n return a, b\nend\n\nwarning: Warning\nAlthough a callsite annotation will try to force inlining in regardless of the cost model, there are still chances it can't succeed in it. Especially, recursive calls can not be inlined even if they are annotated as @inlined.\n\ncompat: Julia 1.8\nThe callsite annotation requires at least Julia 1.8.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@noinline","page":"Essentials","title":"Base.@noinline","text":"@noinline\n\nGive a hint to the compiler that it should not inline a function.\n\nSmall functions are typically inlined automatically. By using @noinline on small functions, auto-inlining can be prevented.\n\n@noinline can be applied immediately before a function definition or within a function body.\n\n# annotate long-form definition\n@noinline function longdef(x)\n ...\nend\n\n# annotate short-form definition\n@noinline shortdef(x) = ...\n\n# annotate anonymous function that a `do` block creates\nf() do\n @noinline\n ...\nend\n\ncompat: Julia 1.8\nThe usage within a function body requires at least Julia 1.8.\n\n\n\n@noinline block\n\nGive a hint to the compiler that it should not inline the calls within block.\n\n# The compiler will try to not inline `f`\n@noinline f(...)\n\n# The compiler will try to not inline `f`, `g` and `+`\n@noinline f(...) + g(...)\n\nnote: Note\nA callsite annotation always has the precedence over the annotation applied to the definition of the called function:@inline function explicit_inline(args...)\n # body\nend\n\nlet\n @noinline explicit_inline(args...) # will not be inlined\nend\n\nnote: Note\nWhen there are nested callsite annotations, the innermost annotation has the precedence:@inline let a0, b0 = ...\n a = @noinline f(a0) # the compiler will NOT try to inline this call\n b = f(b0) # the compiler will try to inline this call\n return a, b\nend\n\ncompat: Julia 1.8\nThe callsite annotation requires at least Julia 1.8.\n\n\n\nnote: Note\nIf the function is trivial (for example returning a constant) it might get inlined anyway.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@nospecialize","page":"Essentials","title":"Base.@nospecialize","text":"@nospecialize\n\nApplied to a function argument name, hints to the compiler that the method implementation should not be specialized for different types of that argument, but instead use the declared type for that argument. It can be applied to an argument within a formal argument list, or in the function body. When applied to an argument, the macro must wrap the entire argument expression, e.g., @nospecialize(x::Real) or @nospecialize(i::Integer...) rather than wrapping just the argument name. When used in a function body, the macro must occur in statement position and before any code.\n\nWhen used without arguments, it applies to all arguments of the parent scope. In local scope, this means all arguments of the containing function. In global (top-level) scope, this means all methods subsequently defined in the current module.\n\nSpecialization can reset back to the default by using @specialize.\n\nfunction example_function(@nospecialize x)\n ...\nend\n\nfunction example_function(x, @nospecialize(y = 1))\n ...\nend\n\nfunction example_function(x, y, z)\n @nospecialize x y\n ...\nend\n\n@nospecialize\nf(y) = [x for x in y]\n@specialize\n\nnote: Note\n@nospecialize affects code generation but not inference: it limits the diversity of the resulting native code, but it does not impose any limitations (beyond the standard ones) on type-inference. Use Base.@nospecializeinfer together with @nospecialize to additionally suppress inference.\n\nExamples\n\njulia> f(A::AbstractArray) = g(A)\nf (generic function with 1 method)\n\njulia> @noinline g(@nospecialize(A::AbstractArray)) = A[1]\ng (generic function with 1 method)\n\njulia> @code_typed f([1.0])\nCodeInfo(\n1 ─ %1 = invoke Main.g(_2::AbstractArray)::Float64\n└── return %1\n) => Float64\n\nHere, the @nospecialize annotation results in the equivalent of\n\nf(A::AbstractArray) = invoke(g, Tuple{AbstractArray}, A)\n\nensuring that only one version of native code will be generated for g, one that is generic for any AbstractArray. However, the specific return type is still inferred for both g and f, and this is still used in optimizing the callers of f and g.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@specialize","page":"Essentials","title":"Base.@specialize","text":"@specialize\n\nReset the specialization hint for an argument back to the default. For details, see @nospecialize.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@nospecializeinfer","page":"Essentials","title":"Base.@nospecializeinfer","text":"Base.@nospecializeinfer function f(args...)\n @nospecialize ...\n ...\nend\nBase.@nospecializeinfer f(@nospecialize args...) = ...\n\nTells the compiler to infer f using the declared types of @nospecialized arguments. This can be used to limit the number of compiler-generated specializations during inference.\n\nExamples\n\njulia> f(A::AbstractArray) = g(A)\nf (generic function with 1 method)\n\njulia> @noinline Base.@nospecializeinfer g(@nospecialize(A::AbstractArray)) = A[1]\ng (generic function with 1 method)\n\njulia> @code_typed f([1.0])\nCodeInfo(\n1 ─ %1 = invoke Main.g(_2::AbstractArray)::Any\n└── return %1\n) => Any\n\nIn this example, f will be inferred for each specific type of A, but g will only be inferred once with the declared argument type A::AbstractArray, meaning that the compiler will not likely see the excessive inference time on it while it can not infer the concrete return type of it. Without the @nospecializeinfer, f([1.0]) would infer the return type of g as Float64, indicating that inference ran for g(::Vector{Float64}) despite the prohibition on specialized code generation.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@constprop","page":"Essentials","title":"Base.@constprop","text":"Base.@constprop setting [ex]\n\nControl the mode of interprocedural constant propagation for the annotated function.\n\nTwo settings are supported:\n\nBase.@constprop :aggressive [ex]: apply constant propagation aggressively. For a method where the return type depends on the value of the arguments, this can yield improved inference results at the cost of additional compile time.\nBase.@constprop :none [ex]: disable constant propagation. This can reduce compile times for functions that Julia might otherwise deem worthy of constant-propagation. Common cases are for functions with Bool- or Symbol-valued arguments or keyword arguments.\n\nBase.@constprop can be applied immediately before a function definition or within a function body.\n\n# annotate long-form definition\nBase.@constprop :aggressive function longdef(x)\n ...\nend\n\n# annotate short-form definition\nBase.@constprop :aggressive shortdef(x) = ...\n\n# annotate anonymous function that a `do` block creates\nf() do\n Base.@constprop :aggressive\n ...\nend\n\ncompat: Julia 1.10\nThe usage within a function body requires at least Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.gensym","page":"Essentials","title":"Base.gensym","text":"gensym([tag])\n\nGenerates a symbol which will not conflict with other variable names (in the same module).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@gensym","page":"Essentials","title":"Base.@gensym","text":"@gensym\n\nGenerates a gensym symbol for a variable. For example, @gensym x y is transformed into x = gensym(\"x\"); y = gensym(\"y\").\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#var\"name\"","page":"Essentials","title":"var\"name\"","text":"var\n\nThe syntax var\"#example#\" refers to a variable named Symbol(\"#example#\"), even though #example# is not a valid Julia identifier name.\n\nThis can be useful for interoperability with programming languages which have different rules for the construction of valid identifiers. For example, to refer to the R variable draw.segments, you can use var\"draw.segments\" in your Julia code.\n\nIt is also used to show julia source code which has gone through macro hygiene or otherwise contains variable names which can't be parsed normally.\n\nNote that this syntax requires parser support so it is expanded directly by the parser rather than being implemented as a normal string macro @var_str.\n\ncompat: Julia 1.3\nThis syntax requires at least Julia 1.3.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.@goto","page":"Essentials","title":"Base.@goto","text":"@goto name\n\n@goto name unconditionally jumps to the statement at the location @label name.\n\n@label and @goto cannot create jumps to different top-level statements. Attempts cause an error. To still use @goto, enclose the @label and @goto in a block.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@label","page":"Essentials","title":"Base.@label","text":"@label name\n\nLabels a statement with the symbolic label name. The label marks the end-point of an unconditional jump with @goto name.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.SimdLoop.@simd","page":"Essentials","title":"Base.SimdLoop.@simd","text":"@simd\n\nAnnotate a for loop to allow the compiler to take extra liberties to allow loop re-ordering\n\nwarning: Warning\nThis feature is experimental and could change or disappear in future versions of Julia. Incorrect use of the @simd macro may cause unexpected results.\n\nThe object iterated over in a @simd for loop should be a one-dimensional range. By using @simd, you are asserting several properties of the loop:\n\nIt is safe to execute iterations in arbitrary or overlapping order, with special consideration for reduction variables.\nFloating-point operations on reduction variables can be reordered or contracted, possibly causing different results than without @simd.\n\nIn many cases, Julia is able to automatically vectorize inner for loops without the use of @simd. Using @simd gives the compiler a little extra leeway to make it possible in more situations. In either case, your inner loop should have the following properties to allow vectorization:\n\nThe loop must be an innermost loop\nThe loop body must be straight-line code. Therefore, @inbounds is currently needed for all array accesses. The compiler can sometimes turn short &&, ||, and ?: expressions into straight-line code if it is safe to evaluate all operands unconditionally. Consider using the ifelse function instead of ?: in the loop if it is safe to do so.\nAccesses must have a stride pattern and cannot be \"gathers\" (random-index reads) or \"scatters\" (random-index writes).\nThe stride should be unit stride.\n\nnote: Note\nThe @simd does not assert by default that the loop is completely free of loop-carried memory dependencies, which is an assumption that can easily be violated in generic code. If you are writing non-generic code, you can use @simd ivdep for ... end to also assert that:\n\nThere exists no loop-carried memory dependencies\nNo iteration ever waits on a previous iteration to make forward progress.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@polly","page":"Essentials","title":"Base.@polly","text":"@polly\n\nTells the compiler to apply the polyhedral optimizer Polly to a function.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@generated","page":"Essentials","title":"Base.@generated","text":"@generated f\n\n@generated is used to annotate a function which will be generated. In the body of the generated function, only types of arguments can be read (not the values). The function returns a quoted expression evaluated when the function is called. The @generated macro should not be used on functions mutating the global scope or depending on mutable elements.\n\nSee Metaprogramming for further details.\n\nExamples\n\njulia> @generated function bar(x)\n if x <: Integer\n return :(x ^ 2)\n else\n return :(x)\n end\n end\nbar (generic function with 1 method)\n\njulia> bar(4)\n16\n\njulia> bar(\"baz\")\n\"baz\"\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@assume_effects","page":"Essentials","title":"Base.@assume_effects","text":"Base.@assume_effects setting... [ex]\n\nOverride the compiler's effect modeling. This macro can be used in several contexts:\n\nImmediately before a method definition, to override the entire effect modeling of the applied method.\nWithin a function body without any arguments, to override the entire effect modeling of the enclosing method.\nApplied to a code block, to override the local effect modeling of the applied code block.\n\nExamples\n\njulia> Base.@assume_effects :terminates_locally function fact(x)\n # usage 1:\n # this :terminates_locally allows `fact` to be constant-folded\n res = 1\n 0 ≤ x < 20 || error(\"bad fact\")\n while x > 1\n res *= x\n x -= 1\n end\n return res\n end\nfact (generic function with 1 method)\n\njulia> code_typed() do\n fact(12)\n end |> only\nCodeInfo(\n1 ─ return 479001600\n) => Int64\n\njulia> code_typed() do\n map((2,3,4)) do x\n # usage 2:\n # this :terminates_locally allows this anonymous function to be constant-folded\n Base.@assume_effects :terminates_locally\n res = 1\n 0 ≤ x < 20 || error(\"bad fact\")\n while x > 1\n res *= x\n x -= 1\n end\n return res\n end\n end |> only\nCodeInfo(\n1 ─ return (2, 6, 24)\n) => Tuple{Int64, Int64, Int64}\n\njulia> code_typed() do\n map((2,3,4)) do x\n res = 1\n 0 ≤ x < 20 || error(\"bad fact\")\n # usage 3:\n # with this :terminates_locally annotation the compiler skips tainting\n # `:terminates` effect within this `while` block, allowing the parent\n # anonymous function to be constant-folded\n Base.@assume_effects :terminates_locally while x > 1\n res *= x\n x -= 1\n end\n return res\n end\n end |> only\nCodeInfo(\n1 ─ return (2, 6, 24)\n) => Tuple{Int64, Int64, Int64}\n\ncompat: Julia 1.8\nUsing Base.@assume_effects requires Julia version 1.8.\n\ncompat: Julia 1.10\nThe usage within a function body requires at least Julia 1.10.\n\ncompact: Julia 1.11\nThe code block annotation requires at least Julia 1.11.\n\nwarning: Warning\nImproper use of this macro causes undefined behavior (including crashes, incorrect answers, or other hard to track bugs). Use with care and only as a last resort if absolutely required. Even in such a case, you SHOULD take all possible steps to minimize the strength of the effect assertion (e.g., do not use :total if :nothrow would have been sufficient).\n\nIn general, each setting value makes an assertion about the behavior of the function, without requiring the compiler to prove that this behavior is indeed true. These assertions are made for all world ages. It is thus advisable to limit the use of generic functions that may later be extended to invalidate the assumption (which would cause undefined behavior).\n\nThe following settings are supported.\n\n:consistent\n:effect_free\n:nothrow\n:terminates_globally\n:terminates_locally\n:notaskstate\n:inaccessiblememonly\n:noub\n:noub_if_noinbounds\n:foldable\n:removable\n:total\n\nExtended help\n\n\n\n:consistent\n\nThe :consistent setting asserts that for egal (===) inputs:\n\nThe manner of termination (return value, exception, non-termination) will always be the same.\nIf the method returns, the results will always be egal.\n\nnote: Note\nThis in particular implies that the method must not return a freshly allocated mutable object. Multiple allocations of mutable objects (even with identical contents) are not egal.\n\nnote: Note\nThe :consistent-cy assertion is made world-age wise. More formally, write fᵢ for the evaluation of f in world-age i, then we require: i x y x y fᵢ(x) fᵢ(y)However, for two world ages i, j s.t. i j, we may have fᵢ(x) fⱼ(y).A further implication is that :consistent functions may not make their return value dependent on the state of the heap or any other global state that is not constant for a given world age.\n\nnote: Note\nThe :consistent-cy includes all legal rewrites performed by the optimizer. For example, floating-point fastmath operations are not considered :consistent, because the optimizer may rewrite them causing the output to not be :consistent, even for the same world age (e.g. because one ran in the interpreter, while the other was optimized).\n\nnote: Note\nIf :consistent functions terminate by throwing an exception, that exception itself is not required to meet the egality requirement specified above.\n\n\n\n:effect_free\n\nThe :effect_free setting asserts that the method is free of externally semantically visible side effects. The following is an incomplete list of externally semantically visible side effects:\n\nChanging the value of a global variable.\nMutating the heap (e.g. an array or mutable value), except as noted below\nChanging the method table (e.g. through calls to eval)\nFile/Network/etc. I/O\nTask switching\n\nHowever, the following are explicitly not semantically visible, even if they may be observable:\n\nMemory allocations (both mutable and immutable)\nElapsed time\nGarbage collection\nHeap mutations of objects whose lifetime does not exceed the method (i.e. were allocated in the method and do not escape).\nThe returned value (which is externally visible, but not a side effect)\n\nThe rule of thumb here is that an externally visible side effect is anything that would affect the execution of the remainder of the program if the function were not executed.\n\nnote: Note\nThe :effect_free assertion is made both for the method itself and any code that is executed by the method. Keep in mind that the assertion must be valid for all world ages and limit use of this assertion accordingly.\n\n\n\n:nothrow\n\nThe :nothrow settings asserts that this method does not throw an exception (i.e. will either always return a value or never return).\n\nnote: Note\nIt is permissible for :nothrow annotated methods to make use of exception handling internally as long as the exception is not rethrown out of the method itself.\n\nnote: Note\nIf the execution of a method may raise MethodErrors and similar exceptions, then the method is not considered as :nothrow. However, note that environment-dependent errors like StackOverflowError or InterruptException are not modeled by this effect and thus a method that may result in StackOverflowError does not necessarily need to be !:nothrow (although it should usually be !:terminates too).\n\n\n\n:terminates_globally\n\nThe :terminates_globally settings asserts that this method will eventually terminate (either normally or abnormally), i.e. does not loop indefinitely.\n\nnote: Note\nThis :terminates_globally assertion covers any other methods called by the annotated method.\n\nnote: Note\nThe compiler will consider this a strong indication that the method will terminate relatively quickly and may (if otherwise legal) call this method at compile time. I.e. it is a bad idea to annotate this setting on a method that technically, but not practically, terminates.\n\n\n\n:terminates_locally\n\nThe :terminates_locally setting is like :terminates_globally, except that it only applies to syntactic control flow within the annotated method. It is thus a much weaker (and thus safer) assertion that allows for the possibility of non-termination if the method calls some other method that does not terminate.\n\nnote: Note\n:terminates_globally implies :terminates_locally.\n\n\n\n:notaskstate\n\nThe :notaskstate setting asserts that the method does not use or modify the local task state (task local storage, RNG state, etc.) and may thus be safely moved between tasks without observable results.\n\nnote: Note\nThe implementation of exception handling makes use of state stored in the task object. However, this state is currently not considered to be within the scope of :notaskstate and is tracked separately using the :nothrow effect.\n\nnote: Note\nThe :notaskstate assertion concerns the state of the currently running task. If a reference to a Task object is obtained by some other means that does not consider which task is currently running, the :notaskstate effect need not be tainted. This is true, even if said task object happens to be === to the currently running task.\n\nnote: Note\nAccess to task state usually also results in the tainting of other effects, such as :effect_free (if task state is modified) or :consistent (if task state is used in the computation of the result). In particular, code that is not :notaskstate, but is :effect_free and :consistent may still be dead-code-eliminated and thus promoted to :total.\n\n\n\n:inaccessiblememonly\n\nThe :inaccessiblememonly setting asserts that the method does not access or modify externally accessible mutable memory. This means the method can access or modify mutable memory for newly allocated objects that is not accessible by other methods or top-level execution before return from the method, but it can not access or modify any mutable global state or mutable memory pointed to by its arguments.\n\nnote: Note\nBelow is an incomplete list of examples that invalidate this assumption:a global reference or getglobal call to access a mutable global variable\na global assignment or setglobal! call to perform assignment to a non-constant global variable\nsetfield! call that changes a field of a global mutable variable\n\nnote: Note\nThis :inaccessiblememonly assertion covers any other methods called by the annotated method.\n\n\n\n:noub\n\nThe :noub setting asserts that the method will not execute any undefined behavior (for any input). Note that undefined behavior may technically cause the method to violate any other effect assertions (such as :consistent or :effect_free) as well, but we do not model this, and they assume the absence of undefined behavior.\n\n\n\n:foldable\n\nThis setting is a convenient shortcut for the set of effects that the compiler requires to be guaranteed to constant fold a call at compile time. It is currently equivalent to the following settings:\n\n:consistent\n:effect_free\n:terminates_globally\n:noub\n\nnote: Note\nThis list in particular does not include :nothrow. The compiler will still attempt constant propagation and note any thrown error at compile time. Note however, that by the :consistent-cy requirements, any such annotated call must consistently throw given the same argument values.\n\nnote: Note\nAn explicit @inbounds annotation inside the function will also disable constant folding and not be overridden by :foldable.\n\n\n\n:removable\n\nThis setting is a convenient shortcut for the set of effects that the compiler requires to be guaranteed to delete a call whose result is unused at compile time. It is currently equivalent to the following settings:\n\n:effect_free\n:nothrow\n:terminates_globally\n\n\n\n:total\n\nThis setting is the maximum possible set of effects. It currently implies the following other settings:\n\n:consistent\n:effect_free\n:nothrow\n:terminates_globally\n:notaskstate\n:inaccessiblememonly\n:noub\n\nwarning: Warning\n:total is a very strong assertion and will likely gain additional semantics in future versions of Julia (e.g. if additional effects are added and included in the definition of :total). As a result, it should be used with care. Whenever possible, prefer to use the minimum possible set of specific effect assertions required for a particular application. In cases where a large number of effect overrides apply to a set of functions, a custom macro is recommended over the use of :total.\n\n\n\nNegated effects\n\nEffect names may be prefixed by ! to indicate that the effect should be removed from an earlier meta effect. For example, :total !:nothrow indicates that while the call is generally total, it may however throw.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@deprecate","page":"Essentials","title":"Base.@deprecate","text":"@deprecate old new [export_old=true]\n\nDeprecate method old and specify the replacement call new, defining a new method old with the specified signature in the process.\n\nTo prevent old from being exported, set export_old to false.\n\ncompat: Julia 1.5\nAs of Julia 1.5, functions defined by @deprecate do not print warning when julia is run without the --depwarn=yes flag set, as the default value of --depwarn option is no. The warnings are printed from tests run by Pkg.test().\n\nExamples\n\njulia> @deprecate old_export(x) new(x)\nold_export (generic function with 1 method)\n\njulia> @deprecate old_public(x) new(x) false\nold_public (generic function with 1 method)\n\nCalls to @deprecate without explicit type-annotations will define deprecated methods accepting any number of positional and keyword arguments of type Any.\n\ncompat: Julia 1.9\nKeyword arguments are forwarded when there is no explicit type annotation as of Julia 1.9. For older versions, you can manually forward positional and keyword arguments by doing @deprecate old(args...; kwargs...) new(args...; kwargs...).\n\nTo restrict deprecation to a specific signature, annotate the arguments of old. For example,\n\njulia> new(x::Int) = x;\n\njulia> new(x::Float64) = 2x;\n\njulia> @deprecate old(x::Int) new(x);\n\njulia> methods(old)\n# 1 method for generic function \"old\" from Main:\n [1] old(x::Int64)\n @ deprecated.jl:94\n\nwill define and deprecate a method old(x::Int) that mirrors new(x::Int) but will not define nor deprecate the method old(x::Float64).\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Missing-Values","page":"Essentials","title":"Missing Values","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.Missing\nBase.missing\nBase.coalesce\nBase.@coalesce\nBase.ismissing\nBase.skipmissing\nBase.nonmissingtype","category":"page"},{"location":"base/base/#Base.Missing","page":"Essentials","title":"Base.Missing","text":"Missing\n\nA type with no fields whose singleton instance missing is used to represent missing values.\n\nSee also: skipmissing, nonmissingtype, Nothing.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.missing","page":"Essentials","title":"Base.missing","text":"missing\n\nThe singleton instance of type Missing representing a missing value.\n\nSee also: NaN, skipmissing, nonmissingtype.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.coalesce","page":"Essentials","title":"Base.coalesce","text":"coalesce(x...)\n\nReturn the first value in the arguments which is not equal to missing, if any. Otherwise return missing.\n\nSee also skipmissing, something, @coalesce.\n\nExamples\n\njulia> coalesce(missing, 1)\n1\n\njulia> coalesce(1, missing)\n1\n\njulia> coalesce(nothing, 1) # returns `nothing`\n\njulia> coalesce(missing, missing)\nmissing\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@coalesce","page":"Essentials","title":"Base.@coalesce","text":"@coalesce(x...)\n\nShort-circuiting version of coalesce.\n\nExamples\n\njulia> f(x) = (println(\"f($x)\"); missing);\n\njulia> a = 1;\n\njulia> a = @coalesce a f(2) f(3) error(\"`a` is still missing\")\n1\n\njulia> b = missing;\n\njulia> b = @coalesce b f(2) f(3) error(\"`b` is still missing\")\nf(2)\nf(3)\nERROR: `b` is still missing\n[...]\n\ncompat: Julia 1.7\nThis macro is available as of Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.ismissing","page":"Essentials","title":"Base.ismissing","text":"ismissing(x)\n\nIndicate whether x is missing.\n\nSee also: skipmissing, isnothing, isnan.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.skipmissing","page":"Essentials","title":"Base.skipmissing","text":"skipmissing(itr)\n\nReturn an iterator over the elements in itr skipping missing values. The returned object can be indexed using indices of itr if the latter is indexable. Indices corresponding to missing values are not valid: they are skipped by keys and eachindex, and a MissingException is thrown when trying to use them.\n\nUse collect to obtain an Array containing the non-missing values in itr. Note that even if itr is a multidimensional array, the result will always be a Vector since it is not possible to remove missings while preserving dimensions of the input.\n\nSee also coalesce, ismissing, something.\n\nExamples\n\njulia> x = skipmissing([1, missing, 2])\nskipmissing(Union{Missing, Int64}[1, missing, 2])\n\njulia> sum(x)\n3\n\njulia> x[1]\n1\n\njulia> x[2]\nERROR: MissingException: the value at index (2,) is missing\n[...]\n\njulia> argmax(x)\n3\n\njulia> collect(keys(x))\n2-element Vector{Int64}:\n 1\n 3\n\njulia> collect(skipmissing([1, missing, 2]))\n2-element Vector{Int64}:\n 1\n 2\n\njulia> collect(skipmissing([1 missing; 2 missing]))\n2-element Vector{Int64}:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.nonmissingtype","page":"Essentials","title":"Base.nonmissingtype","text":"nonmissingtype(T::Type)\n\nIf T is a union of types containing Missing, return a new type with Missing removed.\n\nExamples\n\njulia> nonmissingtype(Union{Int64,Missing})\nInt64\n\njulia> nonmissingtype(Any)\nAny\n\ncompat: Julia 1.3\nThis function is exported as of Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#System","page":"Essentials","title":"System","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.run\nBase.devnull\nBase.success\nBase.process_running\nBase.process_exited\nBase.kill(::Base.Process, ::Integer)\nBase.Sys.set_process_title\nBase.Sys.get_process_title\nBase.ignorestatus\nBase.detach\nBase.Cmd\nBase.setenv\nBase.addenv\nBase.withenv\nBase.setcpuaffinity\nBase.pipeline(::Any, ::Any, ::Any, ::Any...)\nBase.pipeline(::Base.AbstractCmd)\nBase.Libc.gethostname\nBase.Libc.getpid\nBase.Libc.time()\nBase.time_ns\nBase.@time\nBase.@showtime\nBase.@timev\nBase.@timed\nBase.@elapsed\nBase.@allocated\nBase.@allocations\nBase.@lock_conflicts\nBase.EnvDict\nBase.ENV\nBase.Sys.STDLIB\nBase.Sys.isunix\nBase.Sys.isapple\nBase.Sys.islinux\nBase.Sys.isbsd\nBase.Sys.isfreebsd\nBase.Sys.isopenbsd\nBase.Sys.isnetbsd\nBase.Sys.isdragonfly\nBase.Sys.iswindows\nBase.Sys.windows_version\nBase.Sys.free_memory\nBase.Sys.total_memory\nBase.Sys.free_physical_memory\nBase.Sys.total_physical_memory\nBase.Sys.uptime\nBase.Sys.isjsvm\nBase.Sys.loadavg\nBase.Sys.isexecutable\nBase.Sys.isreadable\nBase.Sys.iswritable\nBase.Sys.username\nBase.@static","category":"page"},{"location":"base/base/#Base.run","page":"Essentials","title":"Base.run","text":"run(command, args...; wait::Bool = true)\n\nRun a command object, constructed with backticks (see the Running External Programs section in the manual). Throws an error if anything goes wrong, including the process exiting with a non-zero status (when wait is true).\n\nThe args... allow you to pass through file descriptors to the command, and are ordered like regular unix file descriptors (eg stdin, stdout, stderr, FD(3), FD(4)...).\n\nIf wait is false, the process runs asynchronously. You can later wait for it and check its exit status by calling success on the returned process object.\n\nWhen wait is false, the process' I/O streams are directed to devnull. When wait is true, I/O streams are shared with the parent process. Use pipeline to control I/O redirection.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.devnull","page":"Essentials","title":"Base.devnull","text":"devnull\n\nUsed in a stream redirect to discard all data written to it. Essentially equivalent to /dev/null on Unix or NUL on Windows. Usage:\n\nrun(pipeline(`cat test.txt`, devnull))\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.success","page":"Essentials","title":"Base.success","text":"success(command)\n\nRun a command object, constructed with backticks (see the Running External Programs section in the manual), and tell whether it was successful (exited with a code of 0). An exception is raised if the process cannot be started.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.process_running","page":"Essentials","title":"Base.process_running","text":"process_running(p::Process)\n\nDetermine whether a process is currently running.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.process_exited","page":"Essentials","title":"Base.process_exited","text":"process_exited(p::Process)\n\nDetermine whether a process has exited.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.kill-Tuple{Base.Process, Integer}","page":"Essentials","title":"Base.kill","text":"kill(p::Process, signum=Base.SIGTERM)\n\nSend a signal to a process. The default is to terminate the process. Returns successfully if the process has already exited, but throws an error if killing the process failed for other reasons (e.g. insufficient permissions).\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Sys.set_process_title","page":"Essentials","title":"Base.Sys.set_process_title","text":"Sys.set_process_title(title::AbstractString)\n\nSet the process title. No-op on some operating systems.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.get_process_title","page":"Essentials","title":"Base.Sys.get_process_title","text":"Sys.get_process_title()\n\nGet the process title. On some systems, will always return an empty string.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ignorestatus","page":"Essentials","title":"Base.ignorestatus","text":"ignorestatus(command)\n\nMark a command object so that running it will not throw an error if the result code is non-zero.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.detach","page":"Essentials","title":"Base.detach","text":"detach(command)\n\nMark a command object so that it will be run in a new process group, allowing it to outlive the julia process, and not have Ctrl-C interrupts passed to it.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Cmd","page":"Essentials","title":"Base.Cmd","text":"Cmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)\nCmd(exec::Vector{String})\n\nConstruct a new Cmd object, representing an external program and arguments, from cmd, while changing the settings of the optional keyword arguments:\n\nignorestatus::Bool: If true (defaults to false), then the Cmd will not throw an error if the return code is nonzero.\ndetach::Bool: If true (defaults to false), then the Cmd will be run in a new process group, allowing it to outlive the julia process and not have Ctrl-C passed to it.\nwindows_verbatim::Bool: If true (defaults to false), then on Windows the Cmd will send a command-line string to the process with no quoting or escaping of arguments, even arguments containing spaces. (On Windows, arguments are sent to a program as a single \"command-line\" string, and programs are responsible for parsing it into arguments. By default, empty arguments and arguments with spaces or tabs are quoted with double quotes \" in the command line, and \\ or \" are preceded by backslashes. windows_verbatim=true is useful for launching programs that parse their command line in nonstandard ways.) Has no effect on non-Windows systems.\nwindows_hide::Bool: If true (defaults to false), then on Windows no new console window is displayed when the Cmd is executed. This has no effect if a console is already open or on non-Windows systems.\nenv: Set environment variables to use when running the Cmd. env is either a dictionary mapping strings to strings, an array of strings of the form \"var=val\", an array or tuple of \"var\"=>val pairs. In order to modify (rather than replace) the existing environment, initialize env with copy(ENV) and then set env[\"var\"]=val as desired. To add to an environment block within a Cmd object without replacing all elements, use addenv() which will return a Cmd object with the updated environment.\ndir::AbstractString: Specify a working directory for the command (instead of the current directory).\n\nFor any keywords that are not specified, the current settings from cmd are used.\n\nNote that the Cmd(exec) constructor does not create a copy of exec. Any subsequent changes to exec will be reflected in the Cmd object.\n\nThe most common way to construct a Cmd object is with command literals (backticks), e.g.\n\n`ls -l`\n\nThis can then be passed to the Cmd constructor to modify its settings, e.g.\n\nCmd(`echo \"Hello world\"`, ignorestatus=true, detach=false)\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.setenv","page":"Essentials","title":"Base.setenv","text":"setenv(command::Cmd, env; dir)\n\nSet environment variables to use when running the given command. env is either a dictionary mapping strings to strings, an array of strings of the form \"var=val\", or zero or more \"var\"=>val pair arguments. In order to modify (rather than replace) the existing environment, create env through copy(ENV) and then setting env[\"var\"]=val as desired, or use addenv.\n\nThe dir keyword argument can be used to specify a working directory for the command. dir defaults to the currently set dir for command (which is the current working directory if not specified already).\n\nSee also Cmd, addenv, ENV, pwd.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.addenv","page":"Essentials","title":"Base.addenv","text":"addenv(command::Cmd, env...; inherit::Bool = true)\n\nMerge new environment mappings into the given Cmd object, returning a new Cmd object. Duplicate keys are replaced. If command does not contain any environment values set already, it inherits the current environment at time of addenv() call if inherit is true. Keys with value nothing are deleted from the env.\n\nSee also Cmd, setenv, ENV.\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.withenv","page":"Essentials","title":"Base.withenv","text":"withenv(f, kv::Pair...)\n\nExecute f in an environment that is temporarily modified (not replaced as in setenv) by zero or more \"var\"=>val arguments kv. withenv is generally used via the withenv(kv...) do ... end syntax. A value of nothing can be used to temporarily unset an environment variable (if it is set). When withenv returns, the original environment has been restored.\n\nwarning: Warning\nChanging the environment is not thread-safe. For running external commands with a different environment from the parent process, prefer using addenv over withenv.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.setcpuaffinity","page":"Essentials","title":"Base.setcpuaffinity","text":"setcpuaffinity(original_command::Cmd, cpus) -> command::Cmd\n\nSet the CPU affinity of the command by a list of CPU IDs (1-based) cpus. Passing cpus = nothing means to unset the CPU affinity if the original_command has any.\n\nThis function is supported only in Linux and Windows. It is not supported in macOS because libuv does not support affinity setting.\n\ncompat: Julia 1.8\nThis function requires at least Julia 1.8.\n\nExamples\n\nIn Linux, the taskset command line program can be used to see how setcpuaffinity works.\n\njulia> run(setcpuaffinity(`sh -c 'taskset -p $$'`, [1, 2, 5]));\npid 2273's current affinity mask: 13\n\nNote that the mask value 13 reflects that the first, second, and the fifth bits (counting from the least significant position) are turned on:\n\njulia> 0b010011\n0x13\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.pipeline-Tuple{Any, Any, Any, Vararg{Any}}","page":"Essentials","title":"Base.pipeline","text":"pipeline(from, to, ...)\n\nCreate a pipeline from a data source to a destination. The source and destination can be commands, I/O streams, strings, or results of other pipeline calls. At least one argument must be a command. Strings refer to filenames. When called with more than two arguments, they are chained together from left to right. For example, pipeline(a,b,c) is equivalent to pipeline(pipeline(a,b),c). This provides a more concise way to specify multi-stage pipelines.\n\nExamples:\n\nrun(pipeline(`ls`, `grep xyz`))\nrun(pipeline(`ls`, \"out.txt\"))\nrun(pipeline(\"out.txt\", `grep xyz`))\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.pipeline-Tuple{Base.AbstractCmd}","page":"Essentials","title":"Base.pipeline","text":"pipeline(command; stdin, stdout, stderr, append=false)\n\nRedirect I/O to or from the given command. Keyword arguments specify which of the command's streams should be redirected. append controls whether file output appends to the file. This is a more general version of the 2-argument pipeline function. pipeline(from, to) is equivalent to pipeline(from, stdout=to) when from is a command, and to pipeline(to, stdin=from) when from is another kind of data source.\n\nExamples:\n\nrun(pipeline(`dothings`, stdout=\"out.txt\", stderr=\"errs.txt\"))\nrun(pipeline(`update`, stdout=\"log.txt\", append=true))\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Libc.gethostname","page":"Essentials","title":"Base.Libc.gethostname","text":"gethostname() -> String\n\nGet the local machine's host name.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Libc.getpid","page":"Essentials","title":"Base.Libc.getpid","text":"getpid() -> Int32\n\nGet Julia's process ID.\n\n\n\n\n\ngetpid(process) -> Int32\n\nGet the child process ID, if it still exists.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Libc.time-Tuple{}","page":"Essentials","title":"Base.Libc.time","text":"time() -> Float64\n\nGet the system time in seconds since the epoch, with fairly high (typically, microsecond) resolution.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.time_ns","page":"Essentials","title":"Base.time_ns","text":"time_ns() -> UInt64\n\nGet the time in nanoseconds. The time corresponding to 0 is undefined, and wraps every 5.8 years.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@time","page":"Essentials","title":"Base.@time","text":"@time expr\n@time \"description\" expr\n\nA macro to execute an expression, printing the time it took to execute, the number of allocations, and the total number of bytes its execution caused to be allocated, before returning the value of the expression. Any time spent garbage collecting (gc), compiling new code, or recompiling invalidated code is shown as a percentage. Any lock conflicts where a ReentrantLock had to wait are shown as a count.\n\nOptionally provide a description string to print before the time report.\n\nIn some cases the system will look inside the @time expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @time @eval ....\n\nSee also @showtime, @timev, @timed, @elapsed, @allocated, and @allocations.\n\nnote: Note\nFor more serious benchmarking, consider the @btime macro from the BenchmarkTools.jl package which among other things evaluates the function multiple times in order to reduce noise.\n\ncompat: Julia 1.8\nThe option to add a description was introduced in Julia 1.8.Recompilation time being shown separately from compilation time was introduced in Julia 1.8\n\ncompat: Julia 1.11\nThe reporting of any lock conflicts was added in Julia 1.11.\n\njulia> x = rand(10,10);\n\njulia> @time x * x;\n 0.606588 seconds (2.19 M allocations: 116.555 MiB, 3.75% gc time, 99.94% compilation time)\n\njulia> @time x * x;\n 0.000009 seconds (1 allocation: 896 bytes)\n\njulia> @time begin\n sleep(0.3)\n 1+1\n end\n 0.301395 seconds (8 allocations: 336 bytes)\n2\n\njulia> @time \"A one second sleep\" sleep(1)\nA one second sleep: 1.005750 seconds (5 allocations: 144 bytes)\n\njulia> for loop in 1:3\n @time loop sleep(1)\n end\n1: 1.006760 seconds (5 allocations: 144 bytes)\n2: 1.001263 seconds (5 allocations: 144 bytes)\n3: 1.003676 seconds (5 allocations: 144 bytes)\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@showtime","page":"Essentials","title":"Base.@showtime","text":"@showtime expr\n\nLike @time but also prints the expression being evaluated for reference.\n\ncompat: Julia 1.8\nThis macro was added in Julia 1.8.\n\nSee also @time.\n\njulia> @showtime sleep(1)\nsleep(1): 1.002164 seconds (4 allocations: 128 bytes)\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@timev","page":"Essentials","title":"Base.@timev","text":"@timev expr\n@timev \"description\" expr\n\nThis is a verbose version of the @time macro. It first prints the same information as @time, then any non-zero memory allocation counters, and then returns the value of the expression.\n\nOptionally provide a description string to print before the time report.\n\ncompat: Julia 1.8\nThe option to add a description was introduced in Julia 1.8.\n\nSee also @time, @timed, @elapsed, @allocated, and @allocations.\n\njulia> x = rand(10,10);\n\njulia> @timev x * x;\n 0.546770 seconds (2.20 M allocations: 116.632 MiB, 4.23% gc time, 99.94% compilation time)\nelapsed time (ns): 546769547\ngc time (ns): 23115606\nbytes allocated: 122297811\npool allocs: 2197930\nnon-pool GC allocs:1327\nmalloc() calls: 36\nrealloc() calls: 5\nGC pauses: 3\n\njulia> @timev x * x;\n 0.000010 seconds (1 allocation: 896 bytes)\nelapsed time (ns): 9848\nbytes allocated: 896\npool allocs: 1\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@timed","page":"Essentials","title":"Base.@timed","text":"@timed\n\nA macro to execute an expression, and return the value of the expression, elapsed time in seconds, total bytes allocated, garbage collection time, an object with various memory allocation counters, compilation time in seconds, and recompilation time in seconds. Any lock conflicts where a ReentrantLock had to wait are shown as a count.\n\nIn some cases the system will look inside the @timed expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @timed @eval ....\n\nSee also @time, @timev, @elapsed, @allocated, @allocations, and @lock_conflicts.\n\njulia> stats = @timed rand(10^6);\n\njulia> stats.time\n0.006634834\n\njulia> stats.bytes\n8000256\n\njulia> stats.gctime\n0.0055765\n\njulia> propertynames(stats.gcstats)\n(:allocd, :malloc, :realloc, :poolalloc, :bigalloc, :freecall, :total_time, :pause, :full_sweep)\n\njulia> stats.gcstats.total_time\n5576500\n\njulia> stats.compile_time\n0.0\n\njulia> stats.recompile_time\n0.0\n\n\ncompat: Julia 1.5\nThe return type of this macro was changed from Tuple to NamedTuple in Julia 1.5.\n\ncompat: Julia 1.11\nThe lock_conflicts, compile_time, and recompile_time fields were added in Julia 1.11.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@elapsed","page":"Essentials","title":"Base.@elapsed","text":"@elapsed\n\nA macro to evaluate an expression, discarding the resulting value, instead returning the number of seconds it took to execute as a floating-point number.\n\nIn some cases the system will look inside the @elapsed expression and compile some of the called code before execution of the top-level expression begins. When that happens, some compilation time will not be counted. To include this time you can run @elapsed @eval ....\n\nSee also @time, @timev, @timed, @allocated, and @allocations.\n\njulia> @elapsed sleep(0.3)\n0.301391426\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@allocated","page":"Essentials","title":"Base.@allocated","text":"@allocated\n\nA macro to evaluate an expression, discarding the resulting value, instead returning the total number of bytes allocated during evaluation of the expression.\n\nSee also @allocations, @time, @timev, @timed, and @elapsed.\n\njulia> @allocated rand(10^6)\n8000080\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@allocations","page":"Essentials","title":"Base.@allocations","text":"@allocations\n\nA macro to evaluate an expression, discard the resulting value, and instead return the total number of allocations during evaluation of the expression.\n\nSee also @allocated, @time, @timev, @timed, and @elapsed.\n\njulia> @allocations rand(10^6)\n2\n\ncompat: Julia 1.9\nThis macro was added in Julia 1.9.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@lock_conflicts","page":"Essentials","title":"Base.@lock_conflicts","text":"@lock_conflicts\n\nA macro to evaluate an expression, discard the resulting value, and instead return the total number of lock conflicts during evaluation, where a lock attempt on a ReentrantLock resulted in a wait because the lock was already held.\n\nSee also @time, @timev and @timed.\n\njulia> @lock_conflicts begin\n l = ReentrantLock()\n Threads.@threads for i in 1:Threads.nthreads()\n lock(l) do\n sleep(1)\n end\n end\nend\n5\n\ncompat: Julia 1.11\nThis macro was added in Julia 1.11.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.EnvDict","page":"Essentials","title":"Base.EnvDict","text":"EnvDict() -> EnvDict\n\nA singleton of this type provides a hash table interface to environment variables.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.ENV","page":"Essentials","title":"Base.ENV","text":"ENV\n\nReference to the singleton EnvDict, providing a dictionary interface to system environment variables.\n\n(On Windows, system environment variables are case-insensitive, and ENV correspondingly converts all keys to uppercase for display, iteration, and copying. Portable code should not rely on the ability to distinguish variables by case, and should beware that setting an ostensibly lowercase variable may result in an uppercase ENV key.)\n\nwarning: Warning\nMutating the environment is not thread-safe.\n\nExamples\n\njulia> ENV\nBase.EnvDict with \"50\" entries:\n \"SECURITYSESSIONID\" => \"123\"\n \"USER\" => \"username\"\n \"MallocNanoZone\" => \"0\"\n ⋮ => ⋮\n\njulia> ENV[\"JULIA_EDITOR\"] = \"vim\"\n\"vim\"\n\njulia> ENV[\"JULIA_EDITOR\"]\n\"vim\"\n\nSee also: withenv, addenv.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.Sys.STDLIB","page":"Essentials","title":"Base.Sys.STDLIB","text":"Sys.STDLIB::String\n\nA string containing the full path to the directory containing the stdlib packages.\n\n\n\n\n\n","category":"constant"},{"location":"base/base/#Base.Sys.isunix","page":"Essentials","title":"Base.Sys.isunix","text":"Sys.isunix([os])\n\nPredicate for testing if the OS provides a Unix-like interface. See documentation in Handling Operating System Variation.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isapple","page":"Essentials","title":"Base.Sys.isapple","text":"Sys.isapple([os])\n\nPredicate for testing if the OS is a derivative of Apple Macintosh OS X or Darwin. See documentation in Handling Operating System Variation.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.islinux","page":"Essentials","title":"Base.Sys.islinux","text":"Sys.islinux([os])\n\nPredicate for testing if the OS is a derivative of Linux. See documentation in Handling Operating System Variation.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isbsd","page":"Essentials","title":"Base.Sys.isbsd","text":"Sys.isbsd([os])\n\nPredicate for testing if the OS is a derivative of BSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nThe Darwin kernel descends from BSD, which means that Sys.isbsd() is true on macOS systems. To exclude macOS from a predicate, use Sys.isbsd() && !Sys.isapple().\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isfreebsd","page":"Essentials","title":"Base.Sys.isfreebsd","text":"Sys.isfreebsd([os])\n\nPredicate for testing if the OS is a derivative of FreeBSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nNot to be confused with Sys.isbsd(), which is true on FreeBSD but also on other BSD-based systems. Sys.isfreebsd() refers only to FreeBSD.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isopenbsd","page":"Essentials","title":"Base.Sys.isopenbsd","text":"Sys.isopenbsd([os])\n\nPredicate for testing if the OS is a derivative of OpenBSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nNot to be confused with Sys.isbsd(), which is true on OpenBSD but also on other BSD-based systems. Sys.isopenbsd() refers only to OpenBSD.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isnetbsd","page":"Essentials","title":"Base.Sys.isnetbsd","text":"Sys.isnetbsd([os])\n\nPredicate for testing if the OS is a derivative of NetBSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nNot to be confused with Sys.isbsd(), which is true on NetBSD but also on other BSD-based systems. Sys.isnetbsd() refers only to NetBSD.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isdragonfly","page":"Essentials","title":"Base.Sys.isdragonfly","text":"Sys.isdragonfly([os])\n\nPredicate for testing if the OS is a derivative of DragonFly BSD. See documentation in Handling Operating System Variation.\n\nnote: Note\nNot to be confused with Sys.isbsd(), which is true on DragonFly but also on other BSD-based systems. Sys.isdragonfly() refers only to DragonFly.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.iswindows","page":"Essentials","title":"Base.Sys.iswindows","text":"Sys.iswindows([os])\n\nPredicate for testing if the OS is a derivative of Microsoft Windows NT. See documentation in Handling Operating System Variation.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.windows_version","page":"Essentials","title":"Base.Sys.windows_version","text":"Sys.windows_version()\n\nReturn the version number for the Windows NT Kernel as a VersionNumber, i.e. v\"major.minor.build\", or v\"0.0.0\" if this is not running on Windows.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.free_memory","page":"Essentials","title":"Base.Sys.free_memory","text":"Sys.free_memory()\n\nGet the total free memory in RAM in bytes.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.total_memory","page":"Essentials","title":"Base.Sys.total_memory","text":"Sys.total_memory()\n\nGet the total memory in RAM (including that which is currently used) in bytes. This amount may be constrained, e.g., by Linux control groups. For the unconstrained amount, see Sys.total_physical_memory().\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.free_physical_memory","page":"Essentials","title":"Base.Sys.free_physical_memory","text":"Sys.free_physical_memory()\n\nGet the free memory of the system in bytes. The entire amount may not be available to the current process; use Sys.free_memory() for the actually available amount.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.total_physical_memory","page":"Essentials","title":"Base.Sys.total_physical_memory","text":"Sys.total_physical_memory()\n\nGet the total memory in RAM (including that which is currently used) in bytes. The entire amount may not be available to the current process; see Sys.total_memory().\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.uptime","page":"Essentials","title":"Base.Sys.uptime","text":"Sys.uptime()\n\nGets the current system uptime in seconds.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isjsvm","page":"Essentials","title":"Base.Sys.isjsvm","text":"Sys.isjsvm([os])\n\nPredicate for testing if Julia is running in a JavaScript VM (JSVM), including e.g. a WebAssembly JavaScript embedding in a web browser.\n\ncompat: Julia 1.2\nThis function requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.loadavg","page":"Essentials","title":"Base.Sys.loadavg","text":"Sys.loadavg()\n\nGet the load average. See: https://en.wikipedia.org/wiki/Load_(computing).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isexecutable","page":"Essentials","title":"Base.Sys.isexecutable","text":"isexecutable(path::String)\n\nReturn true if the given path has executable permissions.\n\nnote: Note\nThis permission may change before the user executes path, so it is recommended to execute the file and handle the error if that fails, rather than calling isexecutable first.\n\nnote: Note\nPrior to Julia 1.6, this did not correctly interrogate filesystem ACLs on Windows, therefore it would return true for any file. From Julia 1.6 on, it correctly determines whether the file is marked as executable or not.\n\nSee also ispath, isreadable, iswritable.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.isreadable","page":"Essentials","title":"Base.Sys.isreadable","text":"isreadable(path::String)\n\nReturn true if the access permissions for the given path permitted reading by the current user.\n\nnote: Note\nThis permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling isreadable first.\n\nnote: Note\nCurrently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also ispath, isexecutable, iswritable.\n\n\n\n\n\nisreadable(io) -> Bool\n\nReturn false if the specified IO object is not readable.\n\nExamples\n\njulia> open(\"myfile.txt\", \"w\") do io\n print(io, \"Hello world!\");\n isreadable(io)\n end\nfalse\n\njulia> open(\"myfile.txt\", \"r\") do io\n isreadable(io)\n end\ntrue\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.iswritable","page":"Essentials","title":"Base.Sys.iswritable","text":"iswritable(path::String)\n\nReturn true if the access permissions for the given path permitted writing by the current user.\n\nnote: Note\nThis permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling iswritable first.\n\nnote: Note\nCurrently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also ispath, isexecutable, isreadable.\n\n\n\n\n\niswritable(io) -> Bool\n\nReturn false if the specified IO object is not writable.\n\nExamples\n\njulia> open(\"myfile.txt\", \"w\") do io\n print(io, \"Hello world!\");\n iswritable(io)\n end\ntrue\n\njulia> open(\"myfile.txt\", \"r\") do io\n iswritable(io)\n end\nfalse\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Sys.username","page":"Essentials","title":"Base.Sys.username","text":"Sys.username() -> String\n\nReturn the username for the current user. If the username cannot be determined or is empty, this function throws an error.\n\nTo retrieve a username that is overridable via an environment variable, e.g., USER, consider using\n\nuser = get(Sys.username, ENV, \"USER\")\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also homedir.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@static","page":"Essentials","title":"Base.@static","text":"@static\n\nPartially evaluate an expression at parse time.\n\nFor example, @static Sys.iswindows() ? foo : bar will evaluate Sys.iswindows() and insert either foo or bar into the expression. This is useful in cases where a construct would be invalid on other platforms, such as a ccall to a non-existent function. @static if Sys.isapple() foo end and @static foo <&&,||> bar are also valid syntax.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Versioning","page":"Essentials","title":"Versioning","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.VersionNumber\nBase.@v_str","category":"page"},{"location":"base/base/#Base.VersionNumber","page":"Essentials","title":"Base.VersionNumber","text":"VersionNumber\n\nVersion number type which follows the specifications of semantic versioning (semver), composed of major, minor and patch numeric values, followed by pre-release and build alphanumeric annotations.\n\nVersionNumber objects can be compared with all of the standard comparison operators (==, <, <=, etc.), with the result following semver v2.0.0-rc.2 rules.\n\nVersionNumber has the following public fields:\n\nv.major::Integer\nv.minor::Integer\nv.patch::Integer\nv.prerelease::Tuple{Vararg{Union{Integer, AbstractString}}}\nv.build::Tuple{Vararg{Union{Integer, AbstractString}}}\n\nSee also @v_str to efficiently construct VersionNumber objects from semver-format literal strings, VERSION for the VersionNumber of Julia itself, and Version Number Literals in the manual.\n\nExamples\n\njulia> a = VersionNumber(1, 2, 3)\nv\"1.2.3\"\n\njulia> a >= v\"1.2\"\ntrue\n\njulia> b = VersionNumber(\"2.0.1-rc1\")\nv\"2.0.1-rc1\"\n\njulia> b >= v\"2.0.1\"\nfalse\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.@v_str","page":"Essentials","title":"Base.@v_str","text":"@v_str\n\nString macro used to parse a string to a VersionNumber.\n\nExamples\n\njulia> v\"1.2.3\"\nv\"1.2.3\"\n\njulia> v\"2.0.1-rc1\"\nv\"2.0.1-rc1\"\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Errors","page":"Essentials","title":"Errors","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.error\nCore.throw\nBase.rethrow\nBase.backtrace\nBase.catch_backtrace\nBase.current_exceptions\nBase.@assert\nBase.Experimental.register_error_hint\nBase.Experimental.show_error_hints\nBase.ArgumentError\nBase.AssertionError\nCore.BoundsError\nBase.CompositeException\nBase.DimensionMismatch\nCore.DivideError\nCore.DomainError\nBase.EOFError\nCore.ErrorException\nCore.InexactError\nCore.InterruptException\nBase.KeyError\nBase.LoadError\nBase.MethodError\nBase.MissingException\nCore.OutOfMemoryError\nCore.ReadOnlyMemoryError\nCore.OverflowError\nBase.ProcessFailedException\nBase.TaskFailedException\nCore.StackOverflowError\nBase.SystemError\nCore.TypeError\nCore.UndefKeywordError\nCore.UndefRefError\nCore.UndefVarError\nBase.StringIndexError\nBase.InitError\nBase.retry\nBase.ExponentialBackOff","category":"page"},{"location":"base/base/#Base.error","page":"Essentials","title":"Base.error","text":"error(message::AbstractString)\n\nRaise an ErrorException with the given message.\n\n\n\n\n\nerror(msg...)\n\nRaise an ErrorException with a message constructed by string(msg...).\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.throw","page":"Essentials","title":"Core.throw","text":"throw(e)\n\nThrow an object as an exception.\n\nSee also: rethrow, error.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.rethrow","page":"Essentials","title":"Base.rethrow","text":"rethrow()\n\nRethrow the current exception from within a catch block. The rethrown exception will continue propagation as if it had not been caught.\n\nnote: Note\nThe alternative form rethrow(e) allows you to associate an alternative exception object e with the current backtrace. However this misrepresents the program state at the time of the error so you're encouraged to instead throw a new exception using throw(e). In Julia 1.1 and above, using throw(e) will preserve the root cause exception on the stack, as described in current_exceptions.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.backtrace","page":"Essentials","title":"Base.backtrace","text":"backtrace()\n\nGet a backtrace object for the current program point.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.catch_backtrace","page":"Essentials","title":"Base.catch_backtrace","text":"catch_backtrace()\n\nGet the backtrace of the current exception, for use within catch blocks.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.current_exceptions","page":"Essentials","title":"Base.current_exceptions","text":"current_exceptions(task::Task=current_task(); [backtrace::Bool=true])\n\nGet the stack of exceptions currently being handled. For nested catch blocks there may be more than one current exception in which case the most recently thrown exception is last in the stack. The stack is returned as an ExceptionStack which is an AbstractVector of named tuples (exception,backtrace). If backtrace is false, the backtrace in each pair will be set to nothing.\n\nExplicitly passing task will return the current exception stack on an arbitrary task. This is useful for inspecting tasks which have failed due to uncaught exceptions.\n\ncompat: Julia 1.7\nThis function went by the experimental name catch_stack() in Julia 1.1–1.6, and had a plain Vector-of-tuples as a return type.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@assert","page":"Essentials","title":"Base.@assert","text":"@assert cond [text]\n\nThrow an AssertionError if cond is false. This is the preferred syntax for writing assertions, which are conditions that are assumed to be true, but that the user might decide to check anyways, as an aid to debugging if they fail. The optional message text is displayed upon assertion failure.\n\nwarning: Warning\nAn assert might be disabled at some optimization levels. Assert should therefore only be used as a debugging tool and not used for authentication verification (e.g., verifying passwords or checking array bounds). The code must not rely on the side effects of running cond for the correct behavior of a function.\n\nExamples\n\njulia> @assert iseven(3) \"3 is an odd number!\"\nERROR: AssertionError: 3 is an odd number!\n\njulia> @assert isodd(3) \"What even are numbers?\"\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Experimental.register_error_hint","page":"Essentials","title":"Base.Experimental.register_error_hint","text":"Experimental.register_error_hint(handler, exceptiontype)\n\nRegister a \"hinting\" function handler(io, exception) that can suggest potential ways for users to circumvent errors. handler should examine exception to see whether the conditions appropriate for a hint are met, and if so generate output to io. Packages should call register_error_hint from within their __init__ function.\n\nFor specific exception types, handler is required to accept additional arguments:\n\nMethodError: provide handler(io, exc::MethodError, argtypes, kwargs), which splits the combined arguments into positional and keyword arguments.\n\nWhen issuing a hint, the output should typically start with \\n.\n\nIf you define custom exception types, your showerror method can support hints by calling Experimental.show_error_hints.\n\nExamples\n\njulia> module Hinter\n\n only_int(x::Int) = 1\n any_number(x::Number) = 2\n\n function __init__()\n Base.Experimental.register_error_hint(MethodError) do io, exc, argtypes, kwargs\n if exc.f == only_int\n # Color is not necessary, this is just to show it's possible.\n print(io, \"\\nDid you mean to call \")\n printstyled(io, \"`any_number`?\", color=:cyan)\n end\n end\n end\n\n end\n\nThen if you call Hinter.only_int on something that isn't an Int (thereby triggering a MethodError), it issues the hint:\n\njulia> Hinter.only_int(1.0)\nERROR: MethodError: no method matching only_int(::Float64)\nThe function `only_int` exists, but no method is defined for this combination of argument types.\nDid you mean to call `any_number`?\nClosest candidates are:\n ...\n\ncompat: Julia 1.5\nCustom error hints are available as of Julia 1.5.\n\nwarning: Warning\nThis interface is experimental and subject to change or removal without notice. To insulate yourself against changes, consider putting any registrations inside an if isdefined(Base.Experimental, :register_error_hint) ... end block.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Experimental.show_error_hints","page":"Essentials","title":"Base.Experimental.show_error_hints","text":"Experimental.show_error_hints(io, ex, args...)\n\nInvoke all handlers from Experimental.register_error_hint for the particular exception type typeof(ex). args must contain any other arguments expected by the handler for that type.\n\ncompat: Julia 1.5\nCustom error hints are available as of Julia 1.5.\n\nwarning: Warning\nThis interface is experimental and subject to change or removal without notice.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.ArgumentError","page":"Essentials","title":"Core.ArgumentError","text":"ArgumentError(msg)\n\nThe arguments passed to a function are invalid. msg is a descriptive error message.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.AssertionError","page":"Essentials","title":"Core.AssertionError","text":"AssertionError([msg])\n\nThe asserted condition did not evaluate to true. Optional argument msg is a descriptive error string.\n\nExamples\n\njulia> @assert false \"this is not true\"\nERROR: AssertionError: this is not true\n\nAssertionError is usually thrown from @assert.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.BoundsError","page":"Essentials","title":"Core.BoundsError","text":"BoundsError([a],[i])\n\nAn indexing operation into an array, a, tried to access an out-of-bounds element at index i.\n\nExamples\n\njulia> A = fill(1.0, 7);\n\njulia> A[8]\nERROR: BoundsError: attempt to access 7-element Vector{Float64} at index [8]\n\n\njulia> B = fill(1.0, (2,3));\n\njulia> B[2, 4]\nERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [2, 4]\n\n\njulia> B[9]\nERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [9]\n\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.CompositeException","page":"Essentials","title":"Base.CompositeException","text":"CompositeException\n\nWrap a Vector of exceptions thrown by a Task (e.g. generated from a remote worker over a channel or an asynchronously executing local I/O write or a remote worker under pmap) with information about the series of exceptions. For example, if a group of workers are executing several tasks, and multiple workers fail, the resulting CompositeException will contain a \"bundle\" of information from each worker indicating where and why the exception(s) occurred.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.DimensionMismatch","page":"Essentials","title":"Base.DimensionMismatch","text":"DimensionMismatch([msg])\n\nThe objects called do not have matching dimensionality. Optional argument msg is a descriptive error string.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.DivideError","page":"Essentials","title":"Core.DivideError","text":"DivideError()\n\nInteger division was attempted with a denominator value of 0.\n\nExamples\n\njulia> 2/0\nInf\n\njulia> div(2, 0)\nERROR: DivideError: integer division error\nStacktrace:\n[...]\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.DomainError","page":"Essentials","title":"Core.DomainError","text":"DomainError(val)\nDomainError(val, msg)\n\nThe argument val to a function or constructor is outside the valid domain.\n\nExamples\n\njulia> sqrt(-1)\nERROR: DomainError with -1.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.EOFError","page":"Essentials","title":"Base.EOFError","text":"EOFError()\n\nNo more data was available to read from a file or stream.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.ErrorException","page":"Essentials","title":"Core.ErrorException","text":"ErrorException(msg)\n\nGeneric error type. The error message, in the .msg field, may provide more specific details.\n\nExamples\n\njulia> ex = ErrorException(\"I've done a bad thing\");\n\njulia> ex.msg\n\"I've done a bad thing\"\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.InexactError","page":"Essentials","title":"Core.InexactError","text":"InexactError(name::Symbol, T, val)\n\nCannot exactly convert val to type T in a method of function name.\n\nExamples\n\njulia> convert(Float64, 1+2im)\nERROR: InexactError: Float64(1 + 2im)\nStacktrace:\n[...]\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.InterruptException","page":"Essentials","title":"Core.InterruptException","text":"InterruptException()\n\nThe process was stopped by a terminal interrupt (CTRL+C).\n\nNote that, in Julia script started without -i (interactive) option, InterruptException is not thrown by default. Calling Base.exit_on_sigint(false) in the script can recover the behavior of the REPL. Alternatively, a Julia script can be started with\n\njulia -e \"include(popfirst!(ARGS))\" script.jl\n\nto let InterruptException be thrown by CTRL+C during the execution.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.KeyError","page":"Essentials","title":"Base.KeyError","text":"KeyError(key)\n\nAn indexing operation into an AbstractDict (Dict) or Set like object tried to access or delete a non-existent element.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.LoadError","page":"Essentials","title":"Core.LoadError","text":"LoadError(file::AbstractString, line::Int, error)\n\nAn error occurred while includeing, requireing, or using a file. The error specifics should be available in the .error field.\n\ncompat: Julia 1.7\nLoadErrors are no longer emitted by @macroexpand, @macroexpand1, and macroexpand as of Julia 1.7.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.MethodError","page":"Essentials","title":"Core.MethodError","text":"MethodError(f, args)\n\nA method with the required type signature does not exist in the given generic function. Alternatively, there is no unique most-specific method.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.MissingException","page":"Essentials","title":"Base.MissingException","text":"MissingException(msg)\n\nException thrown when a missing value is encountered in a situation where it is not supported. The error message, in the msg field may provide more specific details.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.OutOfMemoryError","page":"Essentials","title":"Core.OutOfMemoryError","text":"OutOfMemoryError()\n\nAn operation allocated too much memory for either the system or the garbage collector to handle properly.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.ReadOnlyMemoryError","page":"Essentials","title":"Core.ReadOnlyMemoryError","text":"ReadOnlyMemoryError()\n\nAn operation tried to write to memory that is read-only.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.OverflowError","page":"Essentials","title":"Core.OverflowError","text":"OverflowError(msg)\n\nThe result of an expression is too large for the specified type and will cause a wraparound.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.ProcessFailedException","page":"Essentials","title":"Base.ProcessFailedException","text":"ProcessFailedException\n\nIndicates problematic exit status of a process. When running commands or pipelines, this is thrown to indicate a nonzero exit code was returned (i.e. that the invoked process failed).\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.TaskFailedException","page":"Essentials","title":"Base.TaskFailedException","text":"TaskFailedException\n\nThis exception is thrown by a wait(t) call when task t fails. TaskFailedException wraps the failed task t.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.StackOverflowError","page":"Essentials","title":"Core.StackOverflowError","text":"StackOverflowError()\n\nThe function call grew beyond the size of the call stack. This usually happens when a call recurses infinitely.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.SystemError","page":"Essentials","title":"Base.SystemError","text":"SystemError(prefix::AbstractString, [errno::Int32])\n\nA system call failed with an error code (in the errno global variable).\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.TypeError","page":"Essentials","title":"Core.TypeError","text":"TypeError(func::Symbol, context::AbstractString, expected::Type, got)\n\nA type assertion failure, or calling an intrinsic function with an incorrect argument type.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.UndefKeywordError","page":"Essentials","title":"Core.UndefKeywordError","text":"UndefKeywordError(var::Symbol)\n\nThe required keyword argument var was not assigned in a function call.\n\nExamples\n\njulia> function my_func(;my_arg)\n return my_arg + 1\n end\nmy_func (generic function with 1 method)\n\njulia> my_func()\nERROR: UndefKeywordError: keyword argument `my_arg` not assigned\nStacktrace:\n [1] my_func() at ./REPL[1]:2\n [2] top-level scope at REPL[2]:1\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.UndefRefError","page":"Essentials","title":"Core.UndefRefError","text":"UndefRefError()\n\nThe item or field is not defined for the given object.\n\nExamples\n\njulia> struct MyType\n a::Vector{Int}\n MyType() = new()\n end\n\njulia> A = MyType()\nMyType(#undef)\n\njulia> A.a\nERROR: UndefRefError: access to undefined reference\nStacktrace:\n[...]\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.UndefVarError","page":"Essentials","title":"Core.UndefVarError","text":"UndefVarError(var::Symbol, [scope])\n\nA symbol in the current scope is not defined.\n\nExamples\n\njulia> a\nERROR: UndefVarError: `a` not defined in `Main`\n\njulia> a = 1;\n\njulia> a\n1\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.StringIndexError","page":"Essentials","title":"Base.StringIndexError","text":"StringIndexError(str, i)\n\nAn error occurred when trying to access str at index i that is not valid.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.InitError","page":"Essentials","title":"Core.InitError","text":"InitError(mod::Symbol, error)\n\nAn error occurred when running a module's __init__ function. The actual error thrown is available in the .error field.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.retry","page":"Essentials","title":"Base.retry","text":"retry(f; delays=ExponentialBackOff(), check=nothing) -> Function\n\nReturn an anonymous function that calls function f. If an exception arises, f is repeatedly called again, each time check returns true, after waiting the number of seconds specified in delays. check should input delays's current state and the Exception.\n\ncompat: Julia 1.2\nBefore Julia 1.2 this signature was restricted to f::Function.\n\nExamples\n\nretry(f, delays=fill(5.0, 3))\nretry(f, delays=rand(5:10, 2))\nretry(f, delays=Base.ExponentialBackOff(n=3, first_delay=5, max_delay=1000))\nretry(http_get, check=(s,e)->e.status == \"503\")(url)\nretry(read, check=(s,e)->isa(e, IOError))(io, 128; all=false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ExponentialBackOff","page":"Essentials","title":"Base.ExponentialBackOff","text":"ExponentialBackOff(; n=1, first_delay=0.05, max_delay=10.0, factor=5.0, jitter=0.1)\n\nA Float64 iterator of length n whose elements exponentially increase at a rate in the interval factor * (1 ± jitter). The first element is first_delay and all elements are clamped to max_delay.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Events","page":"Essentials","title":"Events","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.Timer(::Function, ::Real)\nBase.Timer\nBase.AsyncCondition\nBase.AsyncCondition(::Function)","category":"page"},{"location":"base/base/#Base.Timer-Tuple{Function, Real}","page":"Essentials","title":"Base.Timer","text":"Timer(callback::Function, delay; interval = 0)\n\nCreate a timer that runs the function callback at each timer expiration.\n\nWaiting tasks are woken and the function callback is called after an initial delay of delay seconds, and then repeating with the given interval in seconds. If interval is equal to 0, the callback is only run once. The function callback is called with a single argument, the timer itself. Stop a timer by calling close. The callback may still be run one final time, if the timer has already expired.\n\nExamples\n\nHere the first number is printed after a delay of two seconds, then the following numbers are printed quickly.\n\njulia> begin\n i = 0\n cb(timer) = (global i += 1; println(i))\n t = Timer(cb, 2, interval=0.2)\n wait(t)\n sleep(0.5)\n close(t)\n end\n1\n2\n3\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Timer","page":"Essentials","title":"Base.Timer","text":"Timer(delay; interval = 0)\n\nCreate a timer that wakes up tasks waiting for it (by calling wait on the timer object).\n\nWaiting tasks are woken after an initial delay of at least delay seconds, and then repeating after at least interval seconds again elapse. If interval is equal to 0, the timer is only triggered once. When the timer is closed (by close) waiting tasks are woken with an error. Use isopen to check whether a timer is still active.\n\nnote: Note\ninterval is subject to accumulating time skew. If you need precise events at a particular absolute time, create a new timer at each expiration with the difference to the next time computed.\n\nnote: Note\nA Timer requires yield points to update its state. For instance, isopen(t::Timer) cannot be used to timeout a non-yielding while loop.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.AsyncCondition","page":"Essentials","title":"Base.AsyncCondition","text":"AsyncCondition()\n\nCreate a async condition that wakes up tasks waiting for it (by calling wait on the object) when notified from C by a call to uv_async_send. Waiting tasks are woken with an error when the object is closed (by close). Use isopen to check whether it is still active.\n\nThis provides an implicit acquire & release memory ordering between the sending and waiting threads.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.AsyncCondition-Tuple{Function}","page":"Essentials","title":"Base.AsyncCondition","text":"AsyncCondition(callback::Function)\n\nCreate a async condition that calls the given callback function. The callback is passed one argument, the async condition object itself.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Reflection","page":"Essentials","title":"Reflection","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.nameof(::Module)\nBase.parentmodule\nBase.pathof(::Module)\nBase.pkgdir(::Module)\nBase.pkgversion(::Module)\nBase.moduleroot\n__module__\n__source__\nBase.@__MODULE__\nBase.@__FILE__\nBase.@__DIR__\nBase.@__LINE__\nBase.fullname\nBase.names\nBase.isexported\nBase.ispublic\nBase.nameof(::Function)\nBase.functionloc(::Any, ::Any)\nBase.functionloc(::Method)\nBase.@locals\nCore.getglobal\nCore.setglobal!\nCore.modifyglobal!\nCore.swapglobal!\nCore.setglobalonce!\nCore.replaceglobal!","category":"page"},{"location":"base/base/#Base.nameof-Tuple{Module}","page":"Essentials","title":"Base.nameof","text":"nameof(m::Module) -> Symbol\n\nGet the name of a Module as a Symbol.\n\nExamples\n\njulia> nameof(Base.Broadcast)\n:Broadcast\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.parentmodule","page":"Essentials","title":"Base.parentmodule","text":"parentmodule(m::Module) -> Module\n\nGet a module's enclosing Module. Main is its own parent.\n\nSee also: names, nameof, fullname, @__MODULE__.\n\nExamples\n\njulia> parentmodule(Main)\nMain\n\njulia> parentmodule(Base.Broadcast)\nBase\n\n\n\n\n\nparentmodule(t::DataType) -> Module\n\nDetermine the module containing the definition of a (potentially UnionAll-wrapped) DataType.\n\nExamples\n\njulia> module Foo\n struct Int end\n end\nFoo\n\njulia> parentmodule(Int)\nCore\n\njulia> parentmodule(Foo.Int)\nFoo\n\n\n\n\n\nparentmodule(f::Function) -> Module\n\nDetermine the module containing the (first) definition of a generic function.\n\n\n\n\n\nparentmodule(f::Function, types) -> Module\n\nDetermine the module containing the first method of a generic function f matching the specified types.\n\n\n\n\n\nparentmodule(m::Method) -> Module\n\nReturn the module in which the given method m is defined.\n\ncompat: Julia 1.9\nPassing a Method as an argument requires Julia 1.9 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.pathof-Tuple{Module}","page":"Essentials","title":"Base.pathof","text":"pathof(m::Module)\n\nReturn the path of the m.jl file that was used to import module m, or nothing if m was not imported from a package.\n\nUse dirname to get the directory part and basename to get the file name part of the path.\n\nSee also pkgdir.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.pkgdir-Tuple{Module}","page":"Essentials","title":"Base.pkgdir","text":"pkgdir(m::Module[, paths::String...])\n\nReturn the root directory of the package that declared module m, or nothing if m was not declared in a package. Optionally further path component strings can be provided to construct a path within the package root.\n\nTo get the root directory of the package that implements the current module the form pkgdir(@__MODULE__) can be used.\n\njulia> pkgdir(Foo)\n\"/path/to/Foo.jl\"\n\njulia> pkgdir(Foo, \"src\", \"file.jl\")\n\"/path/to/Foo.jl/src/file.jl\"\n\nSee also pathof.\n\ncompat: Julia 1.7\nThe optional argument paths requires at least Julia 1.7.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.pkgversion-Tuple{Module}","page":"Essentials","title":"Base.pkgversion","text":"pkgversion(m::Module)\n\nReturn the version of the package that imported module m, or nothing if m was not imported from a package, or imported from a package without a version field set.\n\nThe version is read from the package's Project.toml during package load.\n\nTo get the version of the package that imported the current module the form pkgversion(@__MODULE__) can be used.\n\ncompat: Julia 1.9\nThis function was introduced in Julia 1.9.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.moduleroot","page":"Essentials","title":"Base.moduleroot","text":"moduleroot(m::Module) -> Module\n\nFind the root module of a given module. This is the first module in the chain of parent modules of m which is either a registered root module or which is its own parent module.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#__module__","page":"Essentials","title":"__module__","text":"__module__\n\nThe argument __module__ is only visible inside the macro, and it provides information (in the form of a Module object) about the expansion context of the macro invocation. See the manual section on Macro invocation for more information.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#__source__","page":"Essentials","title":"__source__","text":"__source__\n\nThe argument __source__ is only visible inside the macro, and it provides information (in the form of a LineNumberNode object) about the parser location of the @ sign from the macro invocation. See the manual section on Macro invocation for more information.\n\n\n\n\n\n","category":"keyword"},{"location":"base/base/#Base.@__MODULE__","page":"Essentials","title":"Base.@__MODULE__","text":"@__MODULE__ -> Module\n\nGet the Module of the toplevel eval, which is the Module code is currently being read from.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@__FILE__","page":"Essentials","title":"Base.@__FILE__","text":"@__FILE__ -> String\n\nExpand to a string with the path to the file containing the macrocall, or an empty string if evaluated by julia -e . Return nothing if the macro was missing parser source information. Alternatively see PROGRAM_FILE.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@__DIR__","page":"Essentials","title":"Base.@__DIR__","text":"@__DIR__ -> String\n\nMacro to obtain the absolute path of the current directory as a string.\n\nIf in a script, returns the directory of the script containing the @__DIR__ macrocall. If run from a REPL or if evaluated by julia -e , returns the current working directory.\n\nExamples\n\nThe example illustrates the difference in the behaviors of @__DIR__ and pwd(), by creating a simple script in a different directory than the current working one and executing both commands:\n\njulia> cd(\"/home/JuliaUser\") # working directory\n\njulia> # create script at /home/JuliaUser/Projects\n open(\"/home/JuliaUser/Projects/test.jl\",\"w\") do io\n print(io, \"\"\"\n println(\"@__DIR__ = \", @__DIR__)\n println(\"pwd() = \", pwd())\n \"\"\")\n end\n\njulia> # outputs script directory and current working directory\n include(\"/home/JuliaUser/Projects/test.jl\")\n@__DIR__ = /home/JuliaUser/Projects\npwd() = /home/JuliaUser\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@__LINE__","page":"Essentials","title":"Base.@__LINE__","text":"@__LINE__ -> Int\n\nExpand to the line number of the location of the macrocall. Return 0 if the line number could not be determined.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.fullname","page":"Essentials","title":"Base.fullname","text":"fullname(m::Module)\n\nGet the fully-qualified name of a module as a tuple of symbols. For example,\n\nExamples\n\njulia> fullname(Base.Iterators)\n(:Base, :Iterators)\n\njulia> fullname(Main)\n(:Main,)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.names","page":"Essentials","title":"Base.names","text":"names(x::Module; all::Bool = false, imported::Bool = false)\n\nGet a vector of the public names of a Module, excluding deprecated names. If all is true, then the list also includes non-public names defined in the module, deprecated names, and compiler-generated names. If imported is true, then names explicitly imported from other modules are also included. Names are returned in sorted order.\n\nAs a special case, all names defined in Main are considered \"public\", since it is not idiomatic to explicitly mark names from Main as public.\n\nnote: Note\nsym ∈ names(SomeModule) does not imply isdefined(SomeModule, sym). names will return symbols marked with public or export, even if they are not defined in the module.\n\nSee also: Base.isexported, Base.ispublic, Base.@locals, @__MODULE__.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isexported","page":"Essentials","title":"Base.isexported","text":"isexported(m::Module, s::Symbol) -> Bool\n\nReturns whether a symbol is exported from a module.\n\nSee also: ispublic, names\n\njulia> module Mod\n export foo\n public bar\n end\nMod\n\njulia> Base.isexported(Mod, :foo)\ntrue\n\njulia> Base.isexported(Mod, :bar)\nfalse\n\njulia> Base.isexported(Mod, :baz)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.ispublic","page":"Essentials","title":"Base.ispublic","text":"ispublic(m::Module, s::Symbol) -> Bool\n\nReturns whether a symbol is marked as public in a module.\n\nExported symbols are considered public.\n\ncompat: Julia 1.11\nThis function and the notion of publicity were added in Julia 1.11.\n\nSee also: isexported, names\n\njulia> module Mod\n export foo\n public bar\n end\nMod\n\njulia> Base.ispublic(Mod, :foo)\ntrue\n\njulia> Base.ispublic(Mod, :bar)\ntrue\n\njulia> Base.ispublic(Mod, :baz)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.nameof-Tuple{Function}","page":"Essentials","title":"Base.nameof","text":"nameof(f::Function) -> Symbol\n\nGet the name of a generic Function as a symbol. For anonymous functions, this is a compiler-generated name. For explicitly-declared subtypes of Function, it is the name of the function's type.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.functionloc-Tuple{Any, Any}","page":"Essentials","title":"Base.functionloc","text":"functionloc(f::Function, types)\n\nReturn a tuple (filename,line) giving the location of a generic Function definition.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.functionloc-Tuple{Method}","page":"Essentials","title":"Base.functionloc","text":"functionloc(m::Method)\n\nReturn a tuple (filename,line) giving the location of a Method definition.\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.@locals","page":"Essentials","title":"Base.@locals","text":"@locals()\n\nConstruct a dictionary of the names (as symbols) and values of all local variables defined as of the call site.\n\ncompat: Julia 1.1\nThis macro requires at least Julia 1.1.\n\nExamples\n\njulia> let x = 1, y = 2\n Base.@locals\n end\nDict{Symbol, Any} with 2 entries:\n :y => 2\n :x => 1\n\njulia> function f(x)\n local y\n show(Base.@locals); println()\n for i = 1:1\n show(Base.@locals); println()\n end\n y = 2\n show(Base.@locals); println()\n nothing\n end;\n\njulia> f(42)\nDict{Symbol, Any}(:x => 42)\nDict{Symbol, Any}(:i => 1, :x => 42)\nDict{Symbol, Any}(:y => 2, :x => 42)\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Core.getglobal","page":"Essentials","title":"Core.getglobal","text":"getglobal(module::Module, name::Symbol, [order::Symbol=:monotonic])\n\nRetrieve the value of the binding name from the module module. Optionally, an atomic ordering can be defined for the operation, otherwise it defaults to monotonic.\n\nWhile accessing module bindings using getfield is still supported to maintain compatibility, using getglobal should always be preferred since getglobal allows for control over atomic ordering (getfield is always monotonic) and better signifies the code's intent both to the user as well as the compiler.\n\nMost users should not have to call this function directly – The getproperty function or corresponding syntax (i.e. module.name) should be preferred in all but few very specific use cases.\n\ncompat: Julia 1.9\nThis function requires Julia 1.9 or later.\n\nSee also getproperty and setglobal!.\n\nExamples\n\njulia> a = 1\n1\n\njulia> module M\n a = 2\n end;\n\njulia> getglobal(@__MODULE__, :a)\n1\n\njulia> getglobal(M, :a)\n2\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.setglobal!","page":"Essentials","title":"Core.setglobal!","text":"setglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])\n\nSet or change the value of the binding name in the module module to x. No type conversion is performed, so if a type has already been declared for the binding, x must be of appropriate type or an error is thrown.\n\nAdditionally, an atomic ordering can be specified for this operation, otherwise it defaults to monotonic.\n\nUsers will typically access this functionality through the setproperty! function or corresponding syntax (i.e. module.name = x) instead, so this is intended only for very specific use cases.\n\ncompat: Julia 1.9\nThis function requires Julia 1.9 or later.\n\nSee also setproperty! and getglobal\n\nExamples\n\njulia> module M end;\n\njulia> M.a # same as `getglobal(M, :a)`\nERROR: UndefVarError: `a` not defined in `M`\nSuggestion: check for spelling errors or missing imports.\n\njulia> setglobal!(M, :a, 1)\n1\n\njulia> M.a\n1\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.modifyglobal!","page":"Essentials","title":"Core.modifyglobal!","text":"modifyglobal!(module::Module, name::Symbol, op, x, [order::Symbol=:monotonic]) -> Pair\n\nAtomically perform the operations to get and set a global after applying the function op.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also modifyproperty! and setglobal!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.swapglobal!","page":"Essentials","title":"Core.swapglobal!","text":"swapglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])\n\nAtomically perform the operations to simultaneously get and set a global.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also swapproperty! and setglobal!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.setglobalonce!","page":"Essentials","title":"Core.setglobalonce!","text":"setglobalonce!(module::Module, name::Symbol, value,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool\n\nAtomically perform the operations to set a global to a given value, only if it was previously not set.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also setpropertyonce! and setglobal!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Core.replaceglobal!","page":"Essentials","title":"Core.replaceglobal!","text":"replaceglobal!(module::Module, name::Symbol, expected, desired,\n [success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)\n\nAtomically perform the operations to get and conditionally set a global to a given value.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also replaceproperty! and setglobal!.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Documentation","page":"Essentials","title":"Documentation","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"(See also the documentation chapter.)","category":"page"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.@doc\nDocs.HTML\nDocs.Text\nDocs.hasdoc\nDocs.undocumented_names","category":"page"},{"location":"base/base/#Core.@doc","page":"Essentials","title":"Core.@doc","text":"Documentation\n\nFunctions, methods and types can be documented by placing a string before the definition:\n\n\"\"\"\n# The Foo Function\n`foo(x)`: Foo the living hell out of `x`.\n\"\"\"\nfoo(x) = ...\n\nThe @doc macro can be used directly to both set and retrieve documentation / metadata. The macro has special parsing so that the documented object may occur on the next line:\n\n@doc \"blah\"\nfunction foo() ...\n\nBy default, documentation is written as Markdown, but any object can be used as the first argument.\n\nDocumenting objects separately from their definitions\n\nYou can document an object before or after its definition with\n\n@doc \"foo\" function_to_doc\n@doc \"bar\" TypeToDoc\n\nFor macros, the syntax is @doc \"macro doc\" :(Module.@macro) or @doc \"macro doc\" :(string_macro\"\") for string macros. Without the quote :() the expansion of the macro will be documented.\n\nRetrieving Documentation\n\nYou can retrieve docs for functions, macros and other objects as follows:\n\n@doc foo\n@doc @time\n@doc md\"\"\n\nFunctions & Methods\n\nPlacing documentation before a method definition (e.g. function foo() ... or foo() = ...) will cause that specific method to be documented, as opposed to the whole function. Method docs are concatenated together in the order they were defined to provide docs for the function.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Docs.HTML","page":"Essentials","title":"Base.Docs.HTML","text":"HTML(s): Create an object that renders s as html.\n\nHTML(\"
    foo
    \")\n\nYou can also use a stream for large amounts of data:\n\nHTML() do io\n println(io, \"
    foo
    \")\nend\n\nwarning: Warning\nHTML is currently exported to maintain backwards compatibility, but this export is deprecated. It is recommended to use this type as Docs.HTML or to explicitly import it from Docs.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.Docs.Text","page":"Essentials","title":"Base.Docs.Text","text":"Text(s): Create an object that renders s as plain text.\n\nText(\"foo\")\n\nYou can also use a stream for large amounts of data:\n\nText() do io\n println(io, \"foo\")\nend\n\nwarning: Warning\nText is currently exported to maintain backwards compatibility, but this export is deprecated. It is recommended to use this type as Docs.Text or to explicitly import it from Docs.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.Docs.hasdoc","page":"Essentials","title":"Base.Docs.hasdoc","text":"Docs.hasdoc(mod::Module, sym::Symbol)::Bool\n\nReturn true if sym in mod has a docstring and false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Docs.undocumented_names","page":"Essentials","title":"Base.Docs.undocumented_names","text":"undocumented_names(mod::Module; private=false)\n\nReturn a sorted vector of undocumented symbols in module (that is, lacking docstrings). private=false (the default) returns only identifiers declared with public and/or export, whereas private=true returns all symbols in the module (excluding compiler-generated hidden symbols starting with #).\n\nSee also: names, Docs.hasdoc, Base.ispublic.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Code-loading","page":"Essentials","title":"Code loading","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.identify_package\nBase.locate_package\nBase.require\nBase.compilecache\nBase.isprecompiled\nBase.get_extension","category":"page"},{"location":"base/base/#Base.identify_package","page":"Essentials","title":"Base.identify_package","text":"Base.identify_package(name::String)::Union{PkgId, Nothing}\nBase.identify_package(where::Union{Module,PkgId}, name::String)::Union{PkgId, Nothing}\n\nIdentify the package by its name from the current environment stack, returning its PkgId, or nothing if it cannot be found.\n\nIf only the name argument is provided, it searches each environment in the stack and its named direct dependencies.\n\nThe where argument provides the context from where to search for the package: in this case it first checks if the name matches the context itself, otherwise it searches all recursive dependencies (from the resolved manifest of each environment) until it locates the context where, and from there identifies the dependency with the corresponding name.\n\njulia> Base.identify_package(\"Pkg\") # Pkg is a dependency of the default environment\nPkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]\n\njulia> using LinearAlgebra\n\njulia> Base.identify_package(LinearAlgebra, \"Pkg\") # Pkg is not a dependency of LinearAlgebra\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.locate_package","page":"Essentials","title":"Base.locate_package","text":"Base.locate_package(pkg::PkgId)::Union{String, Nothing}\n\nThe path to the entry-point file for the package corresponding to the identifier pkg, or nothing if not found. See also identify_package.\n\njulia> pkg = Base.identify_package(\"Pkg\")\nPkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]\n\njulia> Base.locate_package(pkg)\n\"/path/to/julia/stdlib/v1.12/Pkg/src/Pkg.jl\"\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.require","page":"Essentials","title":"Base.require","text":"require(into::Module, module::Symbol)\n\nThis function is part of the implementation of using / import, if a module is not already defined in Main. It can also be called directly to force reloading a module, regardless of whether it has been loaded before (for example, when interactively developing libraries).\n\nLoads a source file, in the context of the Main module, on every active node, searching standard locations for files. require is considered a top-level operation, so it sets the current include path but does not use it to search for files (see help for include). This function is typically used to load library code, and is implicitly called by using to load packages.\n\nWhen searching for files, require first looks for package code in the global array LOAD_PATH. require is case-sensitive on all platforms, including those with case-insensitive filesystems like macOS and Windows.\n\nFor more details regarding code loading, see the manual sections on modules and parallel computing.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.compilecache","page":"Essentials","title":"Base.compilecache","text":"Base.compilecache(module::PkgId)\n\nCreates a precompiled cache file for a module and all of its dependencies. This can be used to reduce package load times. Cache files are stored in DEPOT_PATH[1]/compiled. See Module initialization and precompilation for important notes.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isprecompiled","page":"Essentials","title":"Base.isprecompiled","text":"Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)\n\nReturns whether a given PkgId within the active project is precompiled.\n\nBy default this check observes the same approach that code loading takes with respect to when different versions of dependencies are currently loaded to that which is expected. To ignore loaded modules and answer as if in a fresh julia session specify ignore_loaded=true.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.get_extension","page":"Essentials","title":"Base.get_extension","text":"get_extension(parent::Module, extension::Symbol)\n\nReturn the module for extension of parent or return nothing if the extension is not loaded.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Internals","page":"Essentials","title":"Internals","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Base.GC.gc\nBase.GC.enable\nBase.GC.@preserve\nBase.GC.safepoint\nBase.GC.enable_logging\nBase.GC.logging_enabled\nMeta.lower\nMeta.@lower\nMeta.parse(::AbstractString, ::Int)\nMeta.parse(::AbstractString)\nMeta.ParseError\nCore.QuoteNode\nBase.macroexpand\nBase.@macroexpand\nBase.@macroexpand1\nBase.code_lowered\nBase.code_typed\nBase.precompile\nBase.jit_total_bytes","category":"page"},{"location":"base/base/#Base.GC.gc","page":"Essentials","title":"Base.GC.gc","text":"GC.gc([full=true])\n\nPerform garbage collection. The argument full determines the kind of collection: a full collection (default) traverses all live objects (i.e. full mark) and should reclaim memory from all unreachable objects. An incremental collection only reclaims memory from young objects which are not reachable.\n\nThe GC may decide to perform a full collection even if an incremental collection was requested.\n\nwarning: Warning\nExcessive use will likely lead to poor performance.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.GC.enable","page":"Essentials","title":"Base.GC.enable","text":"GC.enable(on::Bool)\n\nControl whether garbage collection is enabled using a boolean argument (true for enabled, false for disabled). Return previous GC state.\n\nwarning: Warning\nDisabling garbage collection should be used only with caution, as it can cause memory use to grow without bound.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.GC.@preserve","page":"Essentials","title":"Base.GC.@preserve","text":"GC.@preserve x1 x2 ... xn expr\n\nMark the objects x1, x2, ... as being in use during the evaluation of the expression expr. This is only required in unsafe code where expr implicitly uses memory or other resources owned by one of the xs.\n\nImplicit use of x covers any indirect use of resources logically owned by x which the compiler cannot see. Some examples:\n\nAccessing memory of an object directly via a Ptr\nPassing a pointer to x to ccall\nUsing resources of x which would be cleaned up in the finalizer.\n\n@preserve should generally not have any performance impact in typical use cases where it briefly extends object lifetime. In implementation, @preserve has effects such as protecting dynamically allocated objects from garbage collection.\n\nExamples\n\nWhen loading from a pointer with unsafe_load, the underlying object is implicitly used, for example x is implicitly used by unsafe_load(p) in the following:\n\njulia> let\n x = Ref{Int}(101)\n p = Base.unsafe_convert(Ptr{Int}, x)\n GC.@preserve x unsafe_load(p)\n end\n101\n\nWhen passing pointers to ccall, the pointed-to object is implicitly used and should be preserved. (Note however that you should normally just pass x directly to ccall which counts as an explicit use.)\n\njulia> let\n x = \"Hello\"\n p = pointer(x)\n Int(GC.@preserve x @ccall strlen(p::Cstring)::Csize_t)\n # Preferred alternative\n Int(@ccall strlen(x::Cstring)::Csize_t)\n end\n5\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.GC.safepoint","page":"Essentials","title":"Base.GC.safepoint","text":"GC.safepoint()\n\nInserts a point in the program where garbage collection may run. This can be useful in rare cases in multi-threaded programs where some threads are allocating memory (and hence may need to run GC) but other threads are doing only simple operations (no allocation, task switches, or I/O). Calling this function periodically in non-allocating threads allows garbage collection to run.\n\ncompat: Julia 1.4\nThis function is available as of Julia 1.4.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.GC.enable_logging","page":"Essentials","title":"Base.GC.enable_logging","text":"GC.enable_logging(on::Bool)\n\nWhen turned on, print statistics about each GC to stderr.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.GC.logging_enabled","page":"Essentials","title":"Base.GC.logging_enabled","text":"GC.logging_enabled()\n\nReturn whether GC logging has been enabled via GC.enable_logging.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Meta.lower","page":"Essentials","title":"Base.Meta.lower","text":"lower(m, x)\n\nTakes the expression x and returns an equivalent expression in lowered form for executing in module m. See also code_lowered.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Meta.@lower","page":"Essentials","title":"Base.Meta.@lower","text":"@lower [m] x\n\nReturn lowered form of the expression x in module m. By default m is the module in which the macro is called. See also lower.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.Meta.parse-Tuple{AbstractString, Int64}","page":"Essentials","title":"Base.Meta.parse","text":"parse(str, start; greedy=true, raise=true, depwarn=true, filename=\"none\")\n\nParse the expression string and return an expression (which could later be passed to eval for execution). start is the code unit index into str of the first character to start parsing at (as with all string indexing, these are not character indices). If greedy is true (default), parse will try to consume as much input as it can; otherwise, it will stop as soon as it has parsed a valid expression. Incomplete but otherwise syntactically valid expressions will return Expr(:incomplete, \"(error message)\"). If raise is true (default), syntax errors other than incomplete expressions will raise an error. If raise is false, parse will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be suppressed. The filename argument is used to display diagnostics when an error is raised.\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 1) # start of string\n(:((α, β) = (3, 5)), 16)\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 1, greedy=false)\n(:((α, β)), 9)\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 16) # end of string\n(nothing, 16)\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 11) # index of 3\n(:((3, 5)), 16)\n\njulia> Meta.parse(\"(α, β) = 3, 5\", 11, greedy=false)\n(3, 13)\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Meta.parse-Tuple{AbstractString}","page":"Essentials","title":"Base.Meta.parse","text":"parse(str; raise=true, depwarn=true, filename=\"none\")\n\nParse the expression string greedily, returning a single expression. An error is thrown if there are additional characters after the first expression. If raise is true (default), syntax errors will raise an error; otherwise, parse will return an expression that will raise an error upon evaluation. If depwarn is false, deprecation warnings will be suppressed. The filename argument is used to display diagnostics when an error is raised.\n\njulia> Meta.parse(\"x = 3\")\n:(x = 3)\n\njulia> Meta.parse(\"1.0.2\")\nERROR: ParseError:\n# Error @ none:1:1\n1.0.2\n└──┘ ── invalid numeric constant\n[...]\n\njulia> Meta.parse(\"1.0.2\"; raise = false)\n:($(Expr(:error, \"invalid numeric constant \"1.0.\"\")))\n\njulia> Meta.parse(\"x = \")\n:($(Expr(:incomplete, \"incomplete: premature end of input\")))\n\n\n\n\n\n","category":"method"},{"location":"base/base/#Base.Meta.ParseError","page":"Essentials","title":"Base.Meta.ParseError","text":"ParseError(msg)\n\nThe expression passed to the parse function could not be interpreted as a valid Julia expression.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Core.QuoteNode","page":"Essentials","title":"Core.QuoteNode","text":"QuoteNode\n\nA quoted piece of code, that does not support interpolation. See the manual section about QuoteNodes for details.\n\n\n\n\n\n","category":"type"},{"location":"base/base/#Base.macroexpand","page":"Essentials","title":"Base.macroexpand","text":"macroexpand(m::Module, x; recursive=true)\n\nTake the expression x and return an equivalent expression with all macros removed (expanded) for executing in module m. The recursive keyword controls whether deeper levels of nested macros are also expanded. This is demonstrated in the example below:\n\njulia> module M\n macro m1()\n 42\n end\n macro m2()\n :(@m1())\n end\n end\nM\n\njulia> macroexpand(M, :(@m2()), recursive=true)\n42\n\njulia> macroexpand(M, :(@m2()), recursive=false)\n:(#= REPL[16]:6 =# M.@m1)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.@macroexpand","page":"Essentials","title":"Base.@macroexpand","text":"@macroexpand [mod,] ex\n\nReturn equivalent expression with all macros removed (expanded). If two arguments are provided, the first is the module to evaluate in.\n\nThere are differences between @macroexpand and macroexpand.\n\nWhile macroexpand takes a keyword argument recursive, @macroexpand is always recursive. For a non recursive macro version, see @macroexpand1.\nWhile macroexpand has an explicit module argument, @macroexpand always expands with respect to the module in which it is called.\n\nThis is best seen in the following example:\n\njulia> module M\n macro m()\n 1\n end\n function f()\n (@macroexpand(@m),\n macroexpand(M, :(@m)),\n macroexpand(Main, :(@m))\n )\n end\n end\nM\n\njulia> macro m()\n 2\n end\n@m (macro with 1 method)\n\njulia> M.f()\n(1, 1, 2)\n\nWith @macroexpand the expression expands where @macroexpand appears in the code (module M in the example). With macroexpand the expression expands in the module given as the first argument.\n\ncompat: Julia 1.11\nThe two-argument form requires at least Julia 1.11.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.@macroexpand1","page":"Essentials","title":"Base.@macroexpand1","text":"@macroexpand1 [mod,] ex\n\nNon recursive version of @macroexpand.\n\n\n\n\n\n","category":"macro"},{"location":"base/base/#Base.code_lowered","page":"Essentials","title":"Base.code_lowered","text":"code_lowered(f, types; generated=true, debuginfo=:default)\n\nReturn an array of the lowered forms (IR) for the methods matching the given generic function and type signature.\n\nIf generated is false, the returned CodeInfo instances will correspond to fallback implementations. An error is thrown if no fallback implementation exists. If generated is true, these CodeInfo instances will correspond to the method bodies yielded by expanding the generators.\n\nThe keyword debuginfo controls the amount of code metadata present in the output.\n\nNote that an error will be thrown if types are not leaf types when generated is true and any of the corresponding methods are an @generated method.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.code_typed","page":"Essentials","title":"Base.code_typed","text":"code_typed(f, types; kw...)\n\nReturns an array of type-inferred lowered form (IR) for the methods matching the given generic function and type signature.\n\nKeyword Arguments\n\noptimize::Bool = true: optional, controls whether additional optimizations, such as inlining, are also applied.\ndebuginfo::Symbol = :default: optional, controls the amount of code metadata present in the output, possible options are :source or :none.\n\nInternal Keyword Arguments\n\nThis section should be considered internal, and is only for who understands Julia compiler internals.\n\nworld::UInt = Base.get_world_counter(): optional, controls the world age to use when looking up methods, use current world age if not specified.\ninterp::Core.Compiler.AbstractInterpreter = Core.Compiler.NativeInterpreter(world): optional, controls the abstract interpreter to use, use the native interpreter if not specified.\n\nExamples\n\nOne can put the argument types in a tuple to get the corresponding code_typed.\n\njulia> code_typed(+, (Float64, Float64))\n1-element Vector{Any}:\n CodeInfo(\n1 ─ %1 = Base.add_float(x, y)::Float64\n└── return %1\n) => Float64\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.precompile","page":"Essentials","title":"Base.precompile","text":"precompile(f, argtypes::Tuple{Vararg{Any}})\n\nCompile the given function f for the argument tuple (of types) argtypes, but do not execute it.\n\n\n\n\n\nprecompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)\n\nPrecompile a specific method for the given argument types. This may be used to precompile a different method than the one that would ordinarily be chosen by dispatch, thus mimicking invoke.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.jit_total_bytes","page":"Essentials","title":"Base.jit_total_bytes","text":"Base.jit_total_bytes()\n\nReturn the total amount (in bytes) allocated by the just-in-time compiler for e.g. native code and data.\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Meta","page":"Essentials","title":"Meta","text":"","category":"section"},{"location":"base/base/","page":"Essentials","title":"Essentials","text":"Meta.quot\nMeta.isexpr\nMeta.isidentifier\nMeta.isoperator\nMeta.isunaryoperator\nMeta.isbinaryoperator\nMeta.show_sexpr","category":"page"},{"location":"base/base/#Base.Meta.quot","page":"Essentials","title":"Base.Meta.quot","text":"Meta.quot(ex)::Expr\n\nQuote expression ex to produce an expression with head quote. This can for instance be used to represent objects of type Expr in the AST. See also the manual section about QuoteNode.\n\nExamples\n\njulia> eval(Meta.quot(:x))\n:x\n\njulia> dump(Meta.quot(:x))\nExpr\n head: Symbol quote\n args: Array{Any}((1,))\n 1: Symbol x\n\njulia> eval(Meta.quot(:(1+2)))\n:(1 + 2)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isexpr","page":"Essentials","title":"Base.isexpr","text":"Meta.isexpr(ex, head[, n])::Bool\n\nReturn true if ex is an Expr with the given type head and optionally that the argument list is of length n. head may be a Symbol or collection of Symbols. For example, to check that a macro was passed a function call expression, you might use isexpr(ex, :call).\n\nExamples\n\njulia> ex = :(f(x))\n:(f(x))\n\njulia> Meta.isexpr(ex, :block)\nfalse\n\njulia> Meta.isexpr(ex, :call)\ntrue\n\njulia> Meta.isexpr(ex, [:block, :call]) # multiple possible heads\ntrue\n\njulia> Meta.isexpr(ex, :call, 1)\nfalse\n\njulia> Meta.isexpr(ex, :call, 2)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isidentifier","page":"Essentials","title":"Base.isidentifier","text":" isidentifier(s) -> Bool\n\nReturn whether the symbol or string s contains characters that are parsed as a valid ordinary identifier (not a binary/unary operator) in Julia code; see also Base.isoperator.\n\nInternally Julia allows any sequence of characters in a Symbol (except \\0s), and macros automatically use variable names containing # in order to avoid naming collision with the surrounding code. In order for the parser to recognize a variable, it uses a limited set of characters (greatly extended by Unicode). isidentifier() makes it possible to query the parser directly whether a symbol contains valid characters.\n\nExamples\n\njulia> Meta.isidentifier(:x), Meta.isidentifier(\"1x\")\n(true, false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isoperator","page":"Essentials","title":"Base.isoperator","text":"isoperator(s::Symbol)\n\nReturn true if the symbol can be used as an operator, false otherwise.\n\nExamples\n\njulia> Meta.isoperator(:+), Meta.isoperator(:f)\n(true, false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isunaryoperator","page":"Essentials","title":"Base.isunaryoperator","text":"isunaryoperator(s::Symbol)\n\nReturn true if the symbol can be used as a unary (prefix) operator, false otherwise.\n\nExamples\n\njulia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)\n(true, true, false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.isbinaryoperator","page":"Essentials","title":"Base.isbinaryoperator","text":"isbinaryoperator(s::Symbol)\n\nReturn true if the symbol can be used as a binary (infix) operator, false otherwise.\n\nExamples\n\njulia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)\n(true, false, false)\n\n\n\n\n\n","category":"function"},{"location":"base/base/#Base.Meta.show_sexpr","page":"Essentials","title":"Base.Meta.show_sexpr","text":"Meta.show_sexpr([io::IO,], ex)\n\nShow expression ex as a lisp style S-expression.\n\nExamples\n\njulia> Meta.show_sexpr(:(f(x, g(y,z))))\n(:call, :f, :x, (:call, :g, :y, :z))\n\n\n\n\n\n","category":"function"},{"location":"manual/unicode-input/#Unicode-Input","page":"Unicode Input","title":"Unicode Input","text":"","category":"section"},{"location":"manual/unicode-input/","page":"Unicode Input","title":"Unicode Input","text":"The following table lists Unicode characters that can be entered via tab completion of LaTeX-like abbreviations in the Julia REPL (and in various other editing environments). You can also get information on how to type a symbol by entering it in the REPL help, i.e. by typing ? and then entering the symbol in the REPL (e.g., by copy-paste from somewhere you saw the symbol).","category":"page"},{"location":"manual/unicode-input/","page":"Unicode Input","title":"Unicode Input","text":"warning: Warning\nThis table may appear to contain missing characters in the second column, or even show characters that are inconsistent with the characters as they are rendered in the Julia REPL. In these cases, users are strongly advised to check their choice of fonts in their browser and REPL environment, as there are known issues with glyphs in many fonts.","category":"page"},{"location":"manual/unicode-input/","page":"Unicode Input","title":"Unicode Input","text":"#\n# Generate a table containing all LaTeX and Emoji tab completions available in the REPL.\n#\nimport REPL, Markdown\nconst NBSP = '\\u00A0'\n\nfunction tab_completions(symbols...)\n completions = Dict{String, Vector{String}}()\n for each in symbols, (k, v) in each\n completions[v] = push!(get!(completions, v, String[]), k)\n end\n return completions\nend\n\nfunction unicode_data()\n file = normpath(@__DIR__, \"..\", \"..\", \"..\", \"..\", \"..\", \"doc\", \"UnicodeData.txt\")\n names = Dict{UInt32, String}()\n open(file) do unidata\n for line in readlines(unidata)\n id, name, desc = split(line, \";\")[[1, 2, 11]]\n codepoint = parse(UInt32, \"0x$id\")\n names[codepoint] = titlecase(lowercase(\n name == \"\" ? desc : desc == \"\" ? name : \"$name / $desc\"))\n end\n end\n return names\nend\n\n# Surround combining characters with no-break spaces (i.e '\\u00A0'). Follows the same format\n# for how unicode is displayed on the unicode.org website:\n# https://util.unicode.org/UnicodeJsps/character.jsp?a=0300\nfunction fix_combining_chars(char)\n cat = Base.Unicode.category_code(char)\n return cat == 6 || cat == 8 ? \"$NBSP$char$NBSP\" : \"$char\"\nend\n\nfunction table_entries(completions, unicode_dict)\n entries = Any[Any[\n [\"Code point(s)\"],\n [\"Character(s)\"],\n [\"Tab completion sequence(s)\"],\n [\"Unicode name(s)\"],\n ]]\n for (chars, inputs) in sort!(collect(completions), by = first)\n code_points, unicode_names, characters = String[], String[], String[]\n for char in chars\n push!(code_points, \"U+$(uppercase(string(UInt32(char), base = 16, pad = 5)))\")\n push!(unicode_names, get(unicode_dict, UInt32(char), \"(No Unicode name)\"))\n push!(characters, isempty(characters) ? fix_combining_chars(char) : \"$char\")\n end\n inputs_md = []\n for (i, input) in enumerate(inputs)\n i > 1 && push!(inputs_md, \", \")\n push!(inputs_md, Markdown.Code(\"\", input))\n end\n push!(entries, [\n [join(code_points, \" + \")],\n [join(characters)],\n inputs_md,\n [join(unicode_names, \" + \")],\n ])\n end\n table = Markdown.Table(entries, [:l, :c, :l, :l])\n # We also need to wrap the Table in a Markdown.MD \"document\"\n return Markdown.MD([table])\nend\n\ntable_entries(\n tab_completions(\n REPL.REPLCompletions.latex_symbols,\n REPL.REPLCompletions.emoji_symbols\n ),\n unicode_data()\n)","category":"page"},{"location":"base/scopedvalues/#scoped-values","page":"Scoped Values","title":"Scoped Values","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Scoped values provide an implementation of dynamic scoping in Julia.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"note: Lexical scoping vs dynamic scoping\nLexical scoping is the default behavior in Julia. Under lexical scoping the scope of a variable is determined by the lexical (textual) structure of a program. Under dynamic scoping a variable is bound to the most recent assigned value during the program's execution.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"The state of a scoped value is dependent on the execution path of the program. This means that for a scoped value you may observe multiple different values concurrently.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"compat: Julia 1.11\nScoped values were introduced in Julia 1.11. In Julia 1.8+ a compatible implementation is available from the package ScopedValues.jl.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In its simplest form you can create a ScopedValue with a default value and then use with or @with to enter a new dynamic scope. The new scope will inherit all values from the parent scope (and recursively from all outer scopes) with the provided scoped value taking priority over previous definitions.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Let's first look at an example of lexical scope. A let statement begins a new lexical scope within which the outer definition of x is shadowed by it's inner definition.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"x = 1\nlet x = 5\n @show x # 5\nend\n@show x # 1","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In the following example, since Julia uses lexical scope, the variable x in the body of f refers to the x defined in the global scope, and entering a let scope does not change the value f observes.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"x = 1\nf() = @show x\nlet x = 5\n f() # 1\nend\nf() # 1","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Now using a ScopedValue we can use dynamic scoping.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\n\nx = ScopedValue(1)\nf() = @show x[]\nwith(x=>5) do\n f() # 5\nend\nf() # 1","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Note that the observed value of the ScopedValue is dependent on the execution path of the program.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"It often makes sense to use a const variable to point to a scoped value, and you can set the value of multiple ScopedValues with one call to with.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\n\nf() = @show a[]\ng() = @show b[]\n\nconst a = ScopedValue(1)\nconst b = ScopedValue(2)\n\nf() # a[] = 1\ng() # b[] = 2\n\n# Enter a new dynamic scope and set value.\nwith(a => 3) do\n f() # a[] = 3\n g() # b[] = 2\n with(a => 4, b => 5) do\n f() # a[] = 4\n g() # b[] = 5\n end\n f() # a[] = 3\n g() # b[] = 2\nend\n\nf() # a[] = 1\ng() # b[] = 2","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"ScopedValues provides a macro version of with. The expression @with var=>val expr evaluates expr in a new dynamic scope with var set to val. @with var=>val expr is equivalent to with(var=>val) do expr end. However, with requires a zero-argument closure or function, which results in an extra call-frame. As an example, consider the following function f:","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nconst a = ScopedValue(1)\nf(x) = a[] + x","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"If you wish to run f in a dynamic scope with a set to 2, then you can use with:","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"with(() -> f(10), a=>2)","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"However, this requires wrapping f in a zero-argument function. If you wish to avoid the extra call-frame, then you can use the @with macro:","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"@with a=>2 f(10)","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"note: Note\nDynamic scopes are inherited by Tasks, at the moment of task creation. Dynamic scopes are not propagated through Distributed.jl operations.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In the example below we open a new dynamic scope before launching a task. The parent task and the two child tasks observe independent values of the same scoped value at the same time.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nimport Base.Threads: @spawn\n\nconst scoped_val = ScopedValue(1)\n@sync begin\n with(scoped_val => 2)\n @spawn @show scoped_val[] # 2\n end\n with(scoped_val => 3)\n @spawn @show scoped_val[] # 3\n end\n @show scoped_val[] # 1\nend","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Scoped values are constant throughout a scope, but you can store mutable state in a scoped value. Just keep in mind that the usual caveats for global variables apply in the context of concurrent programming.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Care is also required when storing references to mutable state in scoped values. You might want to explicitly unshare mutable state when entering a new dynamic scope.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nimport Base.Threads: @spawn\n\nconst sval_dict = ScopedValue(Dict())\n\n# Example of using a mutable value wrongly\n@sync begin\n # `Dict` is not thread-safe the usage below is invalid\n @spawn (sval_dict[][:a] = 3)\n @spawn (sval_dict[][:b] = 3)\nend\n\n@sync begin\n # If we instead pass a unique dictionary to each\n # task we can access the dictionaries race free.\n with(sval_dict => Dict()) do\n @spawn (sval_dict[][:a] = 3)\n end\n with(sval_dict => Dict()) do\n @spawn (sval_dict[][:b] = 3)\n end\nend","category":"page"},{"location":"base/scopedvalues/#Example","page":"Scoped Values","title":"Example","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In the example below we use a scoped value to implement a permission check in a web-application. After determining the permissions of the request, a new dynamic scope is entered and the scoped value LEVEL is set. Other parts of the application can query the scoped value and will receive the appropriate value. Other alternatives like task-local storage and global variables are not well suited for this kind of propagation; our only alternative would have been to thread a value through the entire call-chain.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\n\nconst LEVEL = ScopedValue(:GUEST)\n\nfunction serve(request, response)\n level = isAdmin(request) ? :ADMIN : :GUEST\n with(LEVEL => level) do\n Threads.@spawn handle(request, response)\n end\nend\n\nfunction open(connection::Database)\n level = LEVEL[]\n if level !== :ADMIN\n error(\"Access disallowed\")\n end\n # ... open connection\nend\n\nfunction handle(request, response)\n # ...\n open(Database(#=...=#))\n # ...\nend","category":"page"},{"location":"base/scopedvalues/#Idioms","page":"Scoped Values","title":"Idioms","text":"","category":"section"},{"location":"base/scopedvalues/#unshare_mutable_state","page":"Scoped Values","title":"Unshare mutable state","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nimport Base.Threads: @spawn\n\nconst sval_dict = ScopedValue(Dict())\n\n# If you want to add new values to the dict, instead of replacing\n# it, unshare the values explicitly. In this example we use `merge`\n# to unshare the state of the dictionary in parent scope.\n@sync begin\n with(sval_dict => merge(sval_dict[], Dict(:a => 10))) do\n @spawn @show sval_dict[][:a]\n end\n @spawn sval_dict[][:a] = 3 # Not a race since they are unshared.\nend","category":"page"},{"location":"base/scopedvalues/#Scoped-values-as-globals","page":"Scoped Values","title":"Scoped values as globals","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"In order to access the value of a scoped value, the scoped value itself has to be in (lexical) scope. This means most often you likely want to use scoped values as constant globals.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nconst sval = ScopedValue(1)","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Indeed one can think of scoped values as hidden function arguments.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"This does not preclude their use as non-globals.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\nimport Base.Threads: @spawn\n\nfunction main()\n role = ScopedValue(:client)\n\n function launch()\n #...\n role[]\n end\n\n @with role => :server @spawn launch()\n launch()\nend","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"But it might have been simpler to just directly pass the function argument in these cases.","category":"page"},{"location":"base/scopedvalues/#Very-many-ScopedValues","page":"Scoped Values","title":"Very many ScopedValues","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"If you find yourself creating many ScopedValue's for one given module, it may be better to use a dedicated struct to hold them.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"using Base.ScopedValues\n\nBase.@kwdef struct Configuration\n color::Bool = false\n verbose::Bool = false\nend\n\nconst CONFIG = ScopedValue(Configuration(color=true))\n\n@with CONFIG => Configuration(color=CONFIG[].color, verbose=true) begin\n @show CONFIG[].color # true\n @show CONFIG[].verbose # true\nend","category":"page"},{"location":"base/scopedvalues/#API-docs","page":"Scoped Values","title":"API docs","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Base.ScopedValues.ScopedValue\nBase.ScopedValues.with\nBase.ScopedValues.@with\nBase.isassigned(::Base.ScopedValues.ScopedValue)\nBase.ScopedValues.get","category":"page"},{"location":"base/scopedvalues/#Base.ScopedValues.ScopedValue","page":"Scoped Values","title":"Base.ScopedValues.ScopedValue","text":"ScopedValue(x)\n\nCreate a container that propagates values across dynamic scopes. Use with to create and enter a new dynamic scope.\n\nValues can only be set when entering a new dynamic scope, and the value referred to will be constant during the execution of a dynamic scope.\n\nDynamic scopes are propagated across tasks.\n\nExamples\n\njulia> using Base.ScopedValues;\n\njulia> const sval = ScopedValue(1);\n\njulia> sval[]\n1\n\njulia> with(sval => 2) do\n sval[]\n end\n2\n\njulia> sval[]\n1\n\ncompat: Julia 1.11\nScoped values were introduced in Julia 1.11. In Julia 1.8+ a compatible implementation is available from the package ScopedValues.jl.\n\n\n\n\n\n","category":"type"},{"location":"base/scopedvalues/#Base.ScopedValues.with","page":"Scoped Values","title":"Base.ScopedValues.with","text":"with(f, (var::ScopedValue{T} => val)...)\n\nExecute f in a new dynamic scope with var set to val. val will be converted to type T.\n\nSee also: ScopedValues.@with, ScopedValues.ScopedValue, ScopedValues.get.\n\nExamples\n\njulia> using Base.ScopedValues\n\njulia> a = ScopedValue(1);\n\njulia> f(x) = a[] + x;\n\njulia> f(10)\n11\n\njulia> with(a=>2) do\n f(10)\n end\n12\n\njulia> f(10)\n11\n\njulia> b = ScopedValue(2);\n\njulia> g(x) = a[] + b[] + x;\n\njulia> with(a=>10, b=>20) do\n g(30)\n end\n60\n\njulia> with(() -> a[] * b[], a=>3, b=>4)\n12\n\n\n\n\n\n","category":"function"},{"location":"base/scopedvalues/#Base.ScopedValues.@with","page":"Scoped Values","title":"Base.ScopedValues.@with","text":"@with (var::ScopedValue{T} => val)... expr\n\nMacro version of with. The expression @with var=>val expr evaluates expr in a new dynamic scope with var set to val. val will be converted to type T. @with var=>val expr is equivalent to with(var=>val) do expr end, but @with avoids creating a closure.\n\nSee also: ScopedValues.with, ScopedValues.ScopedValue, ScopedValues.get.\n\nExamples\n\njulia> using Base.ScopedValues\n\njulia> const a = ScopedValue(1);\n\njulia> f(x) = a[] + x;\n\njulia> @with a=>2 f(10)\n12\n\njulia> @with a=>3 begin\n x = 100\n f(x)\n end\n103\n\n\n\n\n\n","category":"macro"},{"location":"base/scopedvalues/#Base.isassigned-Tuple{Base.ScopedValues.ScopedValue}","page":"Scoped Values","title":"Base.isassigned","text":"isassigned(val::ScopedValue)\n\nTest whether a ScopedValue has an assigned value.\n\nSee also: ScopedValues.with, ScopedValues.@with, ScopedValues.get.\n\nExamples\n\njulia> using Base.ScopedValues\n\njulia> a = ScopedValue(1); b = ScopedValue{Int}();\n\njulia> isassigned(a)\ntrue\n\njulia> isassigned(b)\nfalse\n\n\n\n\n\n","category":"method"},{"location":"base/scopedvalues/#Base.ScopedValues.get","page":"Scoped Values","title":"Base.ScopedValues.get","text":"get(val::ScopedValue{T})::Union{Nothing, Some{T}}\n\nIf the scoped value isn't set and doesn't have a default value, return nothing. Otherwise returns Some{T} with the current value.\n\nSee also: ScopedValues.with, ScopedValues.@with, ScopedValues.ScopedValue.\n\nExamples\n\njulia> using Base.ScopedValues\n\njulia> a = ScopedValue(42); b = ScopedValue{Int}();\n\njulia> ScopedValues.get(a)\nSome(42)\n\njulia> isnothing(ScopedValues.get(b))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/scopedvalues/#Implementation-notes-and-performance","page":"Scoped Values","title":"Implementation notes and performance","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"Scopes use a persistent dictionary. Lookup and insertion is O(log(32, n)), upon dynamic scope entry a small amount of data is copied and the unchanged data is shared among other scopes.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"The Scope object itself is not user-facing and may be changed in a future version of Julia.","category":"page"},{"location":"base/scopedvalues/#Design-inspiration","page":"Scoped Values","title":"Design inspiration","text":"","category":"section"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"This design was heavily inspired by JEPS-429, which in turn was inspired by dynamically scoped free variables in many Lisp dialects. In particular Interlisp-D and its deep binding strategy.","category":"page"},{"location":"base/scopedvalues/","page":"Scoped Values","title":"Scoped Values","text":"A prior design discussed was context variables ala PEPS-567 and implemented in Julia as ContextVariablesX.jl.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Integers-and-Floating-Point-Numbers","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Integers and floating-point values are the basic building blocks of arithmetic and computation. Built-in representations of such values are called numeric primitives, while representations of integers and floating-point numbers as immediate values in code are known as numeric literals. For example, 1 is an integer literal, while 1.0 is a floating-point literal; their binary in-memory representations as objects are numeric primitives.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia provides a broad range of primitive numeric types, and a full complement of arithmetic and bitwise operators as well as standard mathematical functions are defined over them. These map directly onto numeric types and operations that are natively supported on modern computers, thus allowing Julia to take full advantage of computational resources. Additionally, Julia provides software support for Arbitrary Precision Arithmetic, which can handle operations on numeric values that cannot be represented effectively in native hardware representations, but at the cost of relatively slower performance.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The following are Julia's primitive numeric types:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Integer types:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Type Signed? Number of bits Smallest value Largest value\nInt8 ✓ 8 -2^7 2^7 - 1\nUInt8 8 0 2^8 - 1\nInt16 ✓ 16 -2^15 2^15 - 1\nUInt16 16 0 2^16 - 1\nInt32 ✓ 32 -2^31 2^31 - 1\nUInt32 32 0 2^32 - 1\nInt64 ✓ 64 -2^63 2^63 - 1\nUInt64 64 0 2^64 - 1\nInt128 ✓ 128 -2^127 2^127 - 1\nUInt128 128 0 2^128 - 1\nBool N/A 8 false (0) true (1)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Floating-point types:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Type Precision Number of bits\nFloat16 half 16\nFloat32 single 32\nFloat64 double 64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Additionally, full support for Complex and Rational Numbers is built on top of these primitive numeric types. All numeric types interoperate naturally without explicit casting, thanks to a flexible, user-extensible type promotion system.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Integers","page":"Integers and Floating-Point Numbers","title":"Integers","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Literal integers are represented in the standard manner:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 1\n1\n\njulia> 1234\n1234","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The default type for an integer literal depends on whether the target system has a 32-bit architecture or a 64-bit architecture:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"# 32-bit system:\njulia> typeof(1)\nInt32\n\n# 64-bit system:\njulia> typeof(1)\nInt64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The Julia internal variable Sys.WORD_SIZE indicates whether the target system is 32-bit or 64-bit:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"# 32-bit system:\njulia> Sys.WORD_SIZE\n32\n\n# 64-bit system:\njulia> Sys.WORD_SIZE\n64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia also defines the types Int and UInt, which are aliases for the system's signed and unsigned native integer types respectively:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"# 32-bit system:\njulia> Int\nInt32\njulia> UInt\nUInt32\n\n# 64-bit system:\njulia> Int\nInt64\njulia> UInt\nUInt64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Larger integer literals that cannot be represented using only 32 bits but can be represented in 64 bits always create 64-bit integers, regardless of the system type:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"# 32-bit or 64-bit system:\njulia> typeof(3000000000)\nInt64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Unsigned integers are input and output using the 0x prefix and hexadecimal (base 16) digits 0-9a-f (the capitalized digits A-F also work for input). The size of the unsigned value is determined by the number of hex digits used:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 0x1\n0x01\n\njulia> typeof(x)\nUInt8\n\njulia> x = 0x123\n0x0123\n\njulia> typeof(x)\nUInt16\n\njulia> x = 0x1234567\n0x01234567\n\njulia> typeof(x)\nUInt32\n\njulia> x = 0x123456789abcdef\n0x0123456789abcdef\n\njulia> typeof(x)\nUInt64\n\njulia> x = 0x11112222333344445555666677778888\n0x11112222333344445555666677778888\n\njulia> typeof(x)\nUInt128","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"This behavior is based on the observation that when one uses unsigned hex literals for integer values, one typically is using them to represent a fixed numeric byte sequence, rather than just an integer value.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Binary and octal literals are also supported:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 0b10\n0x02\n\njulia> typeof(x)\nUInt8\n\njulia> x = 0o010\n0x08\n\njulia> typeof(x)\nUInt8\n\njulia> x = 0x00000000000000001111222233334444\n0x00000000000000001111222233334444\n\njulia> typeof(x)\nUInt128","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"As for hexadecimal literals, binary and octal literals produce unsigned integer types. The size of the binary data item is the minimal needed size, if the leading digit of the literal is not 0. In the case of leading zeros, the size is determined by the minimal needed size for a literal, which has the same length but leading digit 1. It means that:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"0x1 and 0x12 are UInt8 literals,\n0x123 and 0x1234 are UInt16 literals,\n0x12345 and 0x12345678 are UInt32 literals,\n0x123456789 and 0x1234567890adcdef are UInt64 literals, etc.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Even if there are leading zero digits which don’t contribute to the value, they count for determining storage size of a literal. So 0x01 is a UInt8 while 0x0001 is a UInt16.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"That allows the user to control the size.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Unsigned literals (starting with 0x) that encode integers too large to be represented as UInt128 values will construct BigInt values instead. This is not an unsigned type but it is the only built-in type big enough to represent such large integer values.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Binary, octal, and hexadecimal literals may be signed by a - immediately preceding the unsigned literal. They produce an unsigned integer of the same size as the unsigned literal would do, with the two's complement of the value:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> -0x2\n0xfe\n\njulia> -0x0002\n0xfffe","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The minimum and maximum representable values of primitive numeric types such as integers are given by the typemin and typemax functions:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> (typemin(Int32), typemax(Int32))\n(-2147483648, 2147483647)\n\njulia> for T in [Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128]\n println(\"$(lpad(T,7)): [$(typemin(T)),$(typemax(T))]\")\n end\n Int8: [-128,127]\n Int16: [-32768,32767]\n Int32: [-2147483648,2147483647]\n Int64: [-9223372036854775808,9223372036854775807]\n Int128: [-170141183460469231731687303715884105728,170141183460469231731687303715884105727]\n UInt8: [0,255]\n UInt16: [0,65535]\n UInt32: [0,4294967295]\n UInt64: [0,18446744073709551615]\nUInt128: [0,340282366920938463463374607431768211455]","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The values returned by typemin and typemax are always of the given argument type. (The above expression uses several features that have yet to be introduced, including for loops, Strings, and Interpolation, but should be easy enough to understand for users with some existing programming experience.)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Overflow-behavior","page":"Integers and Floating-Point Numbers","title":"Overflow behavior","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"In Julia, exceeding the maximum representable value of a given type results in a wraparound behavior:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = typemax(Int64)\n9223372036854775807\n\njulia> x + 1\n-9223372036854775808\n\njulia> x + 1 == typemin(Int64)\ntrue","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Arithmetic operations with Julia's integer types inherently perform modular arithmetic, mirroring the characteristics of integer arithmetic on modern computer hardware. In scenarios where overflow is a possibility, it is crucial to explicitly check for wraparound effects that can result from such overflows. The Base.Checked module provides a suite of arithmetic operations equipped with overflow checks, which trigger errors if an overflow occurs. For use cases where overflow cannot be tolerated under any circumstances, utilizing the BigInt type, as detailed in Arbitrary Precision Arithmetic, is advisable.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"An example of overflow behavior and how to potentially resolve it is as follows:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 10^19\n-8446744073709551616\n\njulia> big(10)^19\n10000000000000000000","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Division-errors","page":"Integers and Floating-Point Numbers","title":"Division errors","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Integer division (the div function) has two exceptional cases: dividing by zero, and dividing the lowest negative number (typemin) by -1. Both of these cases throw a DivideError. The remainder and modulus functions (rem and mod) throw a DivideError when their second argument is zero.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Floating-Point-Numbers","page":"Integers and Floating-Point Numbers","title":"Floating-Point Numbers","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Literal floating-point numbers are represented in the standard formats, using E-notation when necessary:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 1.0\n1.0\n\njulia> 1.\n1.0\n\njulia> 0.5\n0.5\n\njulia> .5\n0.5\n\njulia> -1.23\n-1.23\n\njulia> 1e10\n1.0e10\n\njulia> 2.5e-4\n0.00025","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The above results are all Float64 values. Literal Float32 values can be entered by writing an f in place of e:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 0.5f0\n0.5f0\n\njulia> typeof(x)\nFloat32\n\njulia> 2.5f-4\n0.00025f0","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Values can be converted to Float32 easily:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = Float32(-1.5)\n-1.5f0\n\njulia> typeof(x)\nFloat32","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Hexadecimal floating-point literals are also valid, but only as Float64 values, with p preceding the base-2 exponent:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 0x1p0\n1.0\n\njulia> 0x1.8p3\n12.0\n\njulia> x = 0x.4p-1\n0.125\n\njulia> typeof(x)\nFloat64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Half-precision floating-point numbers are also supported (Float16), but they are implemented in software and use Float32 for calculations.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> sizeof(Float16(4.))\n2\n\njulia> 2*Float16(4.)\nFloat16(8.0)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The underscore _ can be used as digit separator:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010\n(10000, 5.0e-9, 0xdeadbeef, 0xb2)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Floating-point-zero","page":"Integers and Floating-Point Numbers","title":"Floating-point zero","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Floating-point numbers have two zeros, positive zero and negative zero. They are equal to each other but have different binary representations, as can be seen using the bitstring function:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 0.0 == -0.0\ntrue\n\njulia> bitstring(0.0)\n\"0000000000000000000000000000000000000000000000000000000000000000\"\n\njulia> bitstring(-0.0)\n\"1000000000000000000000000000000000000000000000000000000000000000\"","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Special-floating-point-values","page":"Integers and Floating-Point Numbers","title":"Special floating-point values","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"There are three specified standard floating-point values that do not correspond to any point on the real number line:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Float16 Float32 Float64 Name Description\nInf16 Inf32 Inf positive infinity a value greater than all finite floating-point values\n-Inf16 -Inf32 -Inf negative infinity a value less than all finite floating-point values\nNaN16 NaN32 NaN not a number a value not == to any floating-point value (including itself)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"For further discussion of how these non-finite floating-point values are ordered with respect to each other and other floats, see Numeric Comparisons. By the IEEE 754 standard, these floating-point values are the results of certain arithmetic operations:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 1/Inf\n0.0\n\njulia> 1/0\nInf\n\njulia> -5/0\n-Inf\n\njulia> 0.000001/0\nInf\n\njulia> 0/0\nNaN\n\njulia> 500 + Inf\nInf\n\njulia> 500 - Inf\n-Inf\n\njulia> Inf + Inf\nInf\n\njulia> Inf - Inf\nNaN\n\njulia> Inf * Inf\nInf\n\njulia> Inf / Inf\nNaN\n\njulia> 0 * Inf\nNaN\n\njulia> NaN == NaN\nfalse\n\njulia> NaN != NaN\ntrue\n\njulia> NaN < NaN\nfalse\n\njulia> NaN > NaN\nfalse","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The typemin and typemax functions also apply to floating-point types:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> (typemin(Float16),typemax(Float16))\n(-Inf16, Inf16)\n\njulia> (typemin(Float32),typemax(Float32))\n(-Inf32, Inf32)\n\njulia> (typemin(Float64),typemax(Float64))\n(-Inf, Inf)","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Machine-epsilon","page":"Integers and Floating-Point Numbers","title":"Machine epsilon","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Most real numbers cannot be represented exactly with floating-point numbers, and so for many purposes it is important to know the distance between two adjacent representable floating-point numbers, which is often known as machine epsilon.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia provides eps, which gives the distance between 1.0 and the next larger representable floating-point value:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> eps(Float32)\n1.1920929f-7\n\njulia> eps(Float64)\n2.220446049250313e-16\n\njulia> eps() # same as eps(Float64)\n2.220446049250313e-16","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"These values are 2.0^-23 and 2.0^-52 as Float32 and Float64 values, respectively. The eps function can also take a floating-point value as an argument, and gives the absolute difference between that value and the next representable floating point value. That is, eps(x) yields a value of the same type as x such that x + eps(x) is the next representable floating-point value larger than x:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> eps(1.0)\n2.220446049250313e-16\n\njulia> eps(1000.)\n1.1368683772161603e-13\n\njulia> eps(1e-27)\n1.793662034335766e-43\n\njulia> eps(0.0)\n5.0e-324","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The distance between two adjacent representable floating-point numbers is not constant, but is smaller for smaller values and larger for larger values. In other words, the representable floating-point numbers are densest in the real number line near zero, and grow sparser exponentially as one moves farther away from zero. By definition, eps(1.0) is the same as eps(Float64) since 1.0 is a 64-bit floating-point value.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia also provides the nextfloat and prevfloat functions which return the next largest or smallest representable floating-point number to the argument respectively:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 1.25f0\n1.25f0\n\njulia> nextfloat(x)\n1.2500001f0\n\njulia> prevfloat(x)\n1.2499999f0\n\njulia> bitstring(prevfloat(x))\n\"00111111100111111111111111111111\"\n\njulia> bitstring(x)\n\"00111111101000000000000000000000\"\n\njulia> bitstring(nextfloat(x))\n\"00111111101000000000000000000001\"","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"This example highlights the general principle that the adjacent representable floating-point numbers also have adjacent binary integer representations.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Rounding-modes","page":"Integers and Floating-Point Numbers","title":"Rounding modes","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"If a number doesn't have an exact floating-point representation, it must be rounded to an appropriate representable value. However, the manner in which this rounding is done can be changed if required according to the rounding modes presented in the IEEE 754 standard.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The default mode used is always RoundNearest, which rounds to the nearest representable value, with ties rounded towards the nearest value with an even least significant bit.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Background-and-References","page":"Integers and Floating-Point Numbers","title":"Background and References","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Floating-point arithmetic entails many subtleties which can be surprising to users who are unfamiliar with the low-level implementation details. However, these subtleties are described in detail in most books on scientific computation, and also in the following references:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The definitive guide to floating point arithmetic is the IEEE 754-2008 Standard; however, it is not available for free online.\nFor a brief but lucid presentation of how floating-point numbers are represented, see John D. Cook's article on the subject as well as his introduction to some of the issues arising from how this representation differs in behavior from the idealized abstraction of real numbers.\nAlso recommended is Bruce Dawson's series of blog posts on floating-point numbers.\nFor an excellent, in-depth discussion of floating-point numbers and issues of numerical accuracy encountered when computing with them, see David Goldberg's paper What Every Computer Scientist Should Know About Floating-Point Arithmetic.\nFor even more extensive documentation of the history of, rationale for, and issues with floating-point numbers, as well as discussion of many other topics in numerical computing, see the collected writings of William Kahan, commonly known as the \"Father of Floating-Point\". Of particular interest may be An Interview with the Old Man of Floating-Point.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Arbitrary-Precision-Arithmetic","page":"Integers and Floating-Point Numbers","title":"Arbitrary Precision Arithmetic","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"To allow computations with arbitrary-precision integers and floating point numbers, Julia wraps the GNU Multiple Precision Arithmetic Library (GMP) and the GNU MPFR Library, respectively. The BigInt and BigFloat types are available in Julia for arbitrary precision integer and floating point numbers respectively.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Constructors exist to create these types from primitive numerical types, and the string literal @big_str or parse can be used to construct them from AbstractStrings. BigInts can also be input as integer literals when they are too big for other built-in integer types. Note that as there is no unsigned arbitrary-precision integer type in Base (BigInt is sufficient in most cases), hexadecimal, octal and binary literals can be used (in addition to decimal literals).","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Once created, they participate in arithmetic with all other numeric types thanks to Julia's type promotion and conversion mechanism:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> BigInt(typemax(Int64)) + 1\n9223372036854775808\n\njulia> big\"123456789012345678901234567890\" + 1\n123456789012345678901234567891\n\njulia> parse(BigInt, \"123456789012345678901234567890\") + 1\n123456789012345678901234567891\n\njulia> string(big\"2\"^200, base=16)\n\"100000000000000000000000000000000000000000000000000\"\n\njulia> 0x100000000000000000000000000000000-1 == typemax(UInt128)\ntrue\n\njulia> 0x000000000000000000000000000000000\n0\n\njulia> typeof(ans)\nBigInt\n\njulia> big\"1.23456789012345678901\"\n1.234567890123456789010000000000000000000000000000000000000000000000000000000004\n\njulia> parse(BigFloat, \"1.23456789012345678901\")\n1.234567890123456789010000000000000000000000000000000000000000000000000000000004\n\njulia> BigFloat(2.0^66) / 3\n2.459565876494606882133333333333333333333333333333333333333333333333333333333344e+19\n\njulia> factorial(BigInt(40))\n815915283247897734345611269596115894272000000000","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"However, type promotion between the primitive types above and BigInt/BigFloat is not automatic and must be explicitly stated.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = typemin(Int64)\n-9223372036854775808\n\njulia> x = x - 1\n9223372036854775807\n\njulia> typeof(x)\nInt64\n\njulia> y = BigInt(typemin(Int64))\n-9223372036854775808\n\njulia> y = y - 1\n-9223372036854775809\n\njulia> typeof(y)\nBigInt","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The default precision (in number of bits of the significand) and rounding mode of BigFloat operations can be changed globally by calling setprecision and setrounding, and all further calculations will take these changes in account. Alternatively, the precision or the rounding can be changed only within the execution of a particular block of code by using the same functions with a do block:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> setrounding(BigFloat, RoundUp) do\n BigFloat(1) + parse(BigFloat, \"0.1\")\n end\n1.100000000000000000000000000000000000000000000000000000000000000000000000000003\n\njulia> setrounding(BigFloat, RoundDown) do\n BigFloat(1) + parse(BigFloat, \"0.1\")\n end\n1.099999999999999999999999999999999999999999999999999999999999999999999999999986\n\njulia> setprecision(40) do\n BigFloat(1) + parse(BigFloat, \"0.1\")\n end\n1.1000000000004","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"warning: Warning\nThe relation between setprecision or setrounding and @big_str, the macro used for big string literals (such as big\"0.3\"), might not be intuitive, as a consequence of the fact that @big_str is a macro. See the @big_str documentation for details.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#man-numeric-literal-coefficients","page":"Integers and Floating-Point Numbers","title":"Numeric Literal Coefficients","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"To make common numeric formulae and expressions clearer, Julia allows variables to be immediately preceded by a numeric literal, implying multiplication. This makes writing polynomial expressions much cleaner:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> x = 3\n3\n\njulia> 2x^2 - 3x + 1\n10\n\njulia> 1.5x^2 - .5x + 1\n13.0","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"It also makes writing exponential functions more elegant:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 2^2x\n64","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The precedence of numeric literal coefficients is slightly lower than that of unary operators such as negation. So -2x is parsed as (-2) * x and √2x is parsed as (√2) * x. However, numeric literal coefficients parse similarly to unary operators when combined with exponentiation. For example 2^3x is parsed as 2^(3x), and 2x^3 is parsed as 2*(x^3).","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Numeric literals also work as coefficients to parenthesized expressions:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> 2(x-1)^2 - 3(x-1) + 1\n3","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"note: Note\nThe precedence of numeric literal coefficients used for implicit multiplication is higher than other binary operators such as multiplication (*), and division (/, \\, and //). This means, for example, that 1 / 2im equals -0.5im and 6 // 2(2 + 1) equals 1 // 1.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Additionally, parenthesized expressions can be used as coefficients to variables, implying multiplication of the expression by the variable:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> (x-1)x\n6","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Neither juxtaposition of two parenthesized expressions, nor placing a variable before a parenthesized expression, however, can be used to imply multiplication:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> (x-1)(x+1)\nERROR: MethodError: objects of type Int64 are not callable\n\njulia> x(x+1)\nERROR: MethodError: objects of type Int64 are not callable","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Both expressions are interpreted as function application: any expression that is not a numeric literal, when immediately followed by a parenthetical, is interpreted as a function applied to the values in parentheses (see Functions for more about functions). Thus, in both of these cases, an error occurs since the left-hand value is not a function.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The above syntactic enhancements significantly reduce the visual noise incurred when writing common mathematical formulae. Note that no whitespace may come between a numeric literal coefficient and the identifier or parenthesized expression which it multiplies.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Syntax-Conflicts","page":"Integers and Floating-Point Numbers","title":"Syntax Conflicts","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Juxtaposed literal coefficient syntax may conflict with some numeric literal syntaxes: hexadecimal, octal and binary integer literals and engineering notation for floating-point literals. Here are some situations where syntactic conflicts arise:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"The hexadecimal integer literal expression 0xff could be interpreted as the numeric literal 0 multiplied by the variable xff. Similar ambiguities arise with octal and binary literals like 0o777 or 0b01001010.\nThe floating-point literal expression 1e10 could be interpreted as the numeric literal 1 multiplied by the variable e10, and similarly with the equivalent E form.\nThe 32-bit floating-point literal expression 1.5f22 could be interpreted as the numeric literal 1.5 multiplied by the variable f22.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"In all cases the ambiguity is resolved in favor of interpretation as numeric literals:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Expressions starting with 0x/0o/0b are always hexadecimal/octal/binary literals.\nExpressions starting with a numeric literal followed by e or E are always floating-point literals.\nExpressions starting with a numeric literal followed by f are always 32-bit floating-point literals.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Unlike E, which is equivalent to e in numeric literals for historical reasons, F is just another letter and does not behave like f in numeric literals. Hence, expressions starting with a numeric literal followed by F are interpreted as the numerical literal multiplied by a variable, which means that, for example, 1.5F22 is equal to 1.5 * F22.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/#Literal-zero-and-one","page":"Integers and Floating-Point Numbers","title":"Literal zero and one","text":"","category":"section"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Julia provides functions which return literal 0 and 1 corresponding to a specified type or the type of a given variable.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Function Description\nzero(x) Literal zero of type x or type of variable x\none(x) Literal one of type x or type of variable x","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"These functions are useful in Numeric Comparisons to avoid overhead from unnecessary type conversion.","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"Examples:","category":"page"},{"location":"manual/integers-and-floating-point-numbers/","page":"Integers and Floating-Point Numbers","title":"Integers and Floating-Point Numbers","text":"julia> zero(Float32)\n0.0f0\n\njulia> zero(1.0)\n0.0\n\njulia> one(Int32)\n1\n\njulia> one(BigFloat)\n1.0","category":"page"},{"location":"stdlib/Statistics/#Statistics","page":"Statistics","title":"Statistics","text":"","category":"section"},{"location":"stdlib/Statistics/","page":"Statistics","title":"Statistics","text":"The Statistics standard library module contains basic statistics functionality.","category":"page"},{"location":"stdlib/Statistics/","page":"Statistics","title":"Statistics","text":"std\nstdm\nvar\nvarm\ncor\ncov\nmean!\nmean\nmedian!\nmedian\nmiddle\nquantile!\nquantile","category":"page"},{"location":"stdlib/Statistics/#Statistics.std","page":"Statistics","title":"Statistics.std","text":"std(itr; corrected::Bool=true, mean=nothing[, dims])\n\nCompute the sample standard deviation of collection itr.\n\nThe algorithm returns an estimator of the generative distribution's standard deviation under the assumption that each entry of itr is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating sqrt(sum((itr .- mean(itr)).^2) / (length(itr) - 1)). If corrected is true, then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false with n the number of elements in itr.\n\nIf itr is an AbstractArray, dims can be provided to compute the standard deviation over dimensions.\n\nA pre-computed mean may be provided. When dims is specified, mean must be an array with the same shape as mean(itr, dims=dims) (additional trailing singleton dimensions are allowed).\n\nnote: Note\nIf array contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the standard deviation of non-missing values.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.stdm","page":"Statistics","title":"Statistics.stdm","text":"stdm(itr, mean; corrected::Bool=true[, dims])\n\nCompute the sample standard deviation of collection itr, with known mean(s) mean.\n\nThe algorithm returns an estimator of the generative distribution's standard deviation under the assumption that each entry of itr is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating sqrt(sum((itr .- mean(itr)).^2) / (length(itr) - 1)). If corrected is true, then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false with n the number of elements in itr.\n\nIf itr is an AbstractArray, dims can be provided to compute the standard deviation over dimensions. In that case, mean must be an array with the same shape as mean(itr, dims=dims) (additional trailing singleton dimensions are allowed).\n\nnote: Note\nIf array contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the standard deviation of non-missing values.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.var","page":"Statistics","title":"Statistics.var","text":"var(itr; corrected::Bool=true, mean=nothing[, dims])\n\nCompute the sample variance of collection itr.\n\nThe algorithm returns an estimator of the generative distribution's variance under the assumption that each entry of itr is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating sum((itr .- mean(itr)).^2) / (length(itr) - 1). If corrected is true, then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false where n is the number of elements in itr.\n\nIf itr is an AbstractArray, dims can be provided to compute the variance over dimensions.\n\nA pre-computed mean may be provided. When dims is specified, mean must be an array with the same shape as mean(itr, dims=dims) (additional trailing singleton dimensions are allowed).\n\nnote: Note\nIf array contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the variance of non-missing values.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.varm","page":"Statistics","title":"Statistics.varm","text":"varm(itr, mean; dims, corrected::Bool=true)\n\nCompute the sample variance of collection itr, with known mean(s) mean.\n\nThe algorithm returns an estimator of the generative distribution's variance under the assumption that each entry of itr is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating sum((itr .- mean(itr)).^2) / (length(itr) - 1). If corrected is true, then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false with n the number of elements in itr.\n\nIf itr is an AbstractArray, dims can be provided to compute the variance over dimensions. In that case, mean must be an array with the same shape as mean(itr, dims=dims) (additional trailing singleton dimensions are allowed).\n\nnote: Note\nIf array contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the variance of non-missing values.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.cor","page":"Statistics","title":"Statistics.cor","text":"cor(x::AbstractVector)\n\nReturn the number one.\n\n\n\n\n\ncor(X::AbstractMatrix; dims::Int=1)\n\nCompute the Pearson correlation matrix of the matrix X along the dimension dims.\n\n\n\n\n\ncor(x::AbstractVector, y::AbstractVector)\n\nCompute the Pearson correlation between the vectors x and y.\n\n\n\n\n\ncor(X::AbstractVecOrMat, Y::AbstractVecOrMat; dims=1)\n\nCompute the Pearson correlation between the vectors or matrices X and Y along the dimension dims.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.cov","page":"Statistics","title":"Statistics.cov","text":"cov(x::AbstractVector; corrected::Bool=true)\n\nCompute the variance of the vector x. If corrected is true (the default) then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false where n = length(x).\n\n\n\n\n\ncov(X::AbstractMatrix; dims::Int=1, corrected::Bool=true)\n\nCompute the covariance matrix of the matrix X along the dimension dims. If corrected is true (the default) then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false where n = size(X, dims).\n\n\n\n\n\ncov(x::AbstractVector, y::AbstractVector; corrected::Bool=true)\n\nCompute the covariance between the vectors x and y. If corrected is true (the default), computes frac1n-1sum_i=1^n (x_i-bar x) (y_i-bar y)^* where * denotes the complex conjugate and n = length(x) = length(y). If corrected is false, computes frac1nsum_i=1^n (x_i-bar x) (y_i-bar y)^*.\n\n\n\n\n\ncov(X::AbstractVecOrMat, Y::AbstractVecOrMat; dims::Int=1, corrected::Bool=true)\n\nCompute the covariance between the vectors or matrices X and Y along the dimension dims. If corrected is true (the default) then the sum is scaled with n-1, whereas the sum is scaled with n if corrected is false where n = size(X, dims) = size(Y, dims).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.mean!","page":"Statistics","title":"Statistics.mean!","text":"mean!(r, v)\n\nCompute the mean of v over the singleton dimensions of r, and write results to r.\n\nExamples\n\njulia> using Statistics\n\njulia> v = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> mean!([1., 1.], v)\n2-element Vector{Float64}:\n 1.5\n 3.5\n\njulia> mean!([1. 1.], v)\n1×2 Matrix{Float64}:\n 2.0 3.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.mean","page":"Statistics","title":"Statistics.mean","text":"mean(itr)\n\nCompute the mean of all elements in a collection.\n\nnote: Note\nIf itr contains NaN or missing values, the result is also NaN or missing (missing takes precedence if array contains both). Use the skipmissing function to omit missing entries and compute the mean of non-missing values.\n\nExamples\n\njulia> using Statistics\n\njulia> mean(1:20)\n10.5\n\njulia> mean([1, missing, 3])\nmissing\n\njulia> mean(skipmissing([1, missing, 3]))\n2.0\n\n\n\n\n\nmean(f, itr)\n\nApply the function f to each element of collection itr and take the mean.\n\njulia> using Statistics\n\njulia> mean(√, [1, 2, 3])\n1.3820881233139908\n\njulia> mean([√1, √2, √3])\n1.3820881233139908\n\n\n\n\n\nmean(f, A::AbstractArray; dims)\n\nApply the function f to each element of array A and take the mean over dimensions dims.\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\njulia> using Statistics\n\njulia> mean(√, [1, 2, 3])\n1.3820881233139908\n\njulia> mean([√1, √2, √3])\n1.3820881233139908\n\njulia> mean(√, [1 2 3; 4 5 6], dims=2)\n2×1 Matrix{Float64}:\n 1.3820881233139908\n 2.2285192400943226\n\n\n\n\n\nmean(A::AbstractArray; dims)\n\nCompute the mean of an array over the given dimensions.\n\ncompat: Julia 1.1\nmean for empty arrays requires at least Julia 1.1.\n\nExamples\n\njulia> using Statistics\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> mean(A, dims=1)\n1×2 Matrix{Float64}:\n 2.0 3.0\n\njulia> mean(A, dims=2)\n2×1 Matrix{Float64}:\n 1.5\n 3.5\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.median!","page":"Statistics","title":"Statistics.median!","text":"median!(v)\n\nLike median, but may overwrite the input vector.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.median","page":"Statistics","title":"Statistics.median","text":"median(itr)\n\nCompute the median of all elements in a collection. For an even number of elements no exact median element exists, so the result is equivalent to calculating mean of two median elements.\n\nnote: Note\nIf itr contains NaN or missing values, the result is also NaN or missing (missing takes precedence if itr contains both). Use the skipmissing function to omit missing entries and compute the median of non-missing values.\n\nExamples\n\njulia> using Statistics\n\njulia> median([1, 2, 3])\n2.0\n\njulia> median([1, 2, 3, 4])\n2.5\n\njulia> median([1, 2, missing, 4])\nmissing\n\njulia> median(skipmissing([1, 2, missing, 4]))\n2.0\n\n\n\n\n\nmedian(A::AbstractArray; dims)\n\nCompute the median of an array along the given dimensions.\n\nExamples\n\njulia> using Statistics\n\njulia> median([1 2; 3 4], dims=1)\n1×2 Matrix{Float64}:\n 2.0 3.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.middle","page":"Statistics","title":"Statistics.middle","text":"middle(x)\n\nCompute the middle of a scalar value, which is equivalent to x itself, but of the type of middle(x, x) for consistency.\n\n\n\n\n\nmiddle(x, y)\n\nCompute the middle of two numbers x and y, which is equivalent in both value and type to computing their mean ((x + y) / 2).\n\n\n\n\n\nmiddle(a::AbstractArray)\n\nCompute the middle of an array a, which consists of finding its extrema and then computing their mean.\n\njulia> using Statistics\n\njulia> middle(1:10)\n5.5\n\njulia> a = [1,2,3.6,10.9]\n4-element Vector{Float64}:\n 1.0\n 2.0\n 3.6\n 10.9\n\njulia> middle(a)\n5.95\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.quantile!","page":"Statistics","title":"Statistics.quantile!","text":"quantile!([q::AbstractArray, ] v::AbstractVector, p; sorted=false, alpha::Real=1.0, beta::Real=alpha)\n\nCompute the quantile(s) of a vector v at a specified probability or vector or tuple of probabilities p on the interval [0,1]. If p is a vector, an optional output array q may also be specified. (If not provided, a new output array is created.) The keyword argument sorted indicates whether v can be assumed to be sorted; if false (the default), then the elements of v will be partially sorted in-place.\n\nSamples quantile are defined by Q(p) = (1-γ)*x[j] + γ*x[j+1], where x[j] is the j-th order statistic of v, j = floor(n*p + m), m = alpha + p*(1 - alpha - beta) and γ = n*p + m - j.\n\nBy default (alpha = beta = 1), quantiles are computed via linear interpolation between the points ((k-1)/(n-1), x[k]), for k = 1:n where n = length(v). This corresponds to Definition 7 of Hyndman and Fan (1996), and is the same as the R and NumPy default.\n\nThe keyword arguments alpha and beta correspond to the same parameters in Hyndman and Fan, setting them to different values allows to calculate quantiles with any of the methods 4-9 defined in this paper:\n\nDef. 4: alpha=0, beta=1\nDef. 5: alpha=0.5, beta=0.5 (MATLAB default)\nDef. 6: alpha=0, beta=0 (Excel PERCENTILE.EXC, Python default, Stata altdef)\nDef. 7: alpha=1, beta=1 (Julia, R and NumPy default, Excel PERCENTILE and PERCENTILE.INC, Python 'inclusive')\nDef. 8: alpha=1/3, beta=1/3\nDef. 9: alpha=3/8, beta=3/8\n\nnote: Note\nAn ArgumentError is thrown if v contains NaN or missing values.\n\nReferences\n\nHyndman, R.J and Fan, Y. (1996) \"Sample Quantiles in Statistical Packages\", The American Statistician, Vol. 50, No. 4, pp. 361-365\nQuantile on Wikipedia details the different quantile definitions\n\nExamples\n\njulia> using Statistics\n\njulia> x = [3, 2, 1];\n\njulia> quantile!(x, 0.5)\n2.0\n\njulia> x\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> y = zeros(3);\n\njulia> quantile!(y, x, [0.1, 0.5, 0.9]) === y\ntrue\n\njulia> y\n3-element Vector{Float64}:\n 1.2000000000000002\n 2.0\n 2.8000000000000003\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Statistics/#Statistics.quantile","page":"Statistics","title":"Statistics.quantile","text":"quantile(itr, p; sorted=false, alpha::Real=1.0, beta::Real=alpha)\n\nCompute the quantile(s) of a collection itr at a specified probability or vector or tuple of probabilities p on the interval [0,1]. The keyword argument sorted indicates whether itr can be assumed to be sorted.\n\nSamples quantile are defined by Q(p) = (1-γ)*x[j] + γ*x[j+1], where x[j] is the j-th order statistic of itr, j = floor(n*p + m), m = alpha + p*(1 - alpha - beta) and γ = n*p + m - j.\n\nBy default (alpha = beta = 1), quantiles are computed via linear interpolation between the points ((k-1)/(n-1), x[k]), for k = 1:n where n = length(itr). This corresponds to Definition 7 of Hyndman and Fan (1996), and is the same as the R and NumPy default.\n\nThe keyword arguments alpha and beta correspond to the same parameters in Hyndman and Fan, setting them to different values allows to calculate quantiles with any of the methods 4-9 defined in this paper:\n\nDef. 4: alpha=0, beta=1\nDef. 5: alpha=0.5, beta=0.5 (MATLAB default)\nDef. 6: alpha=0, beta=0 (Excel PERCENTILE.EXC, Python default, Stata altdef)\nDef. 7: alpha=1, beta=1 (Julia, R and NumPy default, Excel PERCENTILE and PERCENTILE.INC, Python 'inclusive')\nDef. 8: alpha=1/3, beta=1/3\nDef. 9: alpha=3/8, beta=3/8\n\nnote: Note\nAn ArgumentError is thrown if v contains NaN or missing values. Use the skipmissing function to omit missing entries and compute the quantiles of non-missing values.\n\nReferences\n\nHyndman, R.J and Fan, Y. (1996) \"Sample Quantiles in Statistical Packages\", The American Statistician, Vol. 50, No. 4, pp. 361-365\nQuantile on Wikipedia details the different quantile definitions\n\nExamples\n\njulia> using Statistics\n\njulia> quantile(0:20, 0.5)\n10.0\n\njulia> quantile(0:20, [0.1, 0.5, 0.9])\n3-element Vector{Float64}:\n 2.0\n 10.0\n 18.000000000000004\n\njulia> quantile(skipmissing([1, 10, missing]), 0.5)\n5.5\n\n\n\n\n\n","category":"function"},{"location":"devdocs/require/#Module-loading","page":"Module loading","title":"Module loading","text":"","category":"section"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"Base.require is responsible for loading modules and it also manages the precompilation cache. It is the implementation of the import statement.","category":"page"},{"location":"devdocs/require/#Experimental-features","page":"Module loading","title":"Experimental features","text":"","category":"section"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"The features below are experimental and not part of the stable Julia API. Before building upon them inform yourself about the current thinking and whether they might change soon.","category":"page"},{"location":"devdocs/require/#Package-loading-callbacks","page":"Module loading","title":"Package loading callbacks","text":"","category":"section"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"It is possible to listen to the packages loaded by Base.require, by registering a callback.","category":"page"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"loaded_packages = Base.PkgId[]\ncallback = (pkg::Base.PkgId) -> push!(loaded_packages, pkg)\npush!(Base.package_callbacks, callback)","category":"page"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"Using this would look something like:","category":"page"},{"location":"devdocs/require/","page":"Module loading","title":"Module loading","text":"julia> using Example\n\njulia> loaded_packages\n1-element Vector{Base.PkgId}:\n Example [7876af07-990d-54b4-ab0e-23690620f79a]","category":"page"},{"location":"manual/embedding/#Embedding-Julia","page":"Embedding Julia","title":"Embedding Julia","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As we have seen in Calling C and Fortran Code, Julia has a simple and efficient way to call functions written in C. But there are situations where the opposite is needed: calling Julia functions from C code. This can be used to integrate Julia code into a larger C/C++ project, without the need to rewrite everything in C/C++. Julia has a C API to make this possible. As almost all programming languages have some way to call C functions, the Julia C API can also be used to build further language bridges (e.g. calling Julia from Python, Rust or C#). Even though Rust and C++ can use the C embedding API directly, both have packages helping with it, for C++ Jluna is useful.","category":"page"},{"location":"manual/embedding/#High-Level-Embedding","page":"Embedding Julia","title":"High-Level Embedding","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Note: This section covers embedding Julia code in C on Unix-like operating systems. For doing this on Windows, please see the section following this, High-Level Embedding on Windows with Visual Studio.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"We start with a simple C program that initializes Julia and calls some Julia code:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"#include \nJULIA_DEFINE_FAST_TLS // only define this once, in an executable (not in a shared library) if you want fast code.\n\nint main(int argc, char *argv[])\n{\n /* required: setup the Julia context */\n jl_init();\n\n /* run Julia commands */\n jl_eval_string(\"print(sqrt(2.0))\");\n\n /* strongly recommended: notify Julia that the\n program is about to terminate. this allows\n Julia time to cleanup pending write requests\n and run all finalizers\n */\n jl_atexit_hook(0);\n return 0;\n}","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In order to build this program you must add the path to the Julia header to the include path and link against libjulia. For instance, when Julia is installed to $JULIA_DIR, one can compile the above test program test.c with gcc using:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"gcc -o test -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib -Wl,-rpath,$JULIA_DIR/lib test.c -ljulia","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Alternatively, look at the embedding.c program in the Julia source tree in the test/embedding/ folder. The file cli/loader_exe.c program is another simple example of how to set jl_options options while linking against libjulia.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The first thing that must be done before calling any other Julia C function is to initialize Julia. This is done by calling jl_init, which tries to automatically determine Julia's install location. If you need to specify a custom location, or specify which system image to load, use jl_init_with_image instead.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The second statement in the test program evaluates a Julia statement using a call to jl_eval_string.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Before the program terminates, it is strongly recommended that jl_atexit_hook is called. The above example program calls this just before returning from main.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"note: Note\nCurrently, dynamically linking with the libjulia shared library requires passing the RTLD_GLOBAL option. In Python, this looks like:>>> julia=CDLL('./libjulia.dylib',RTLD_GLOBAL)\n>>> julia.jl_init.argtypes = []\n>>> julia.jl_init()\n250593296","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"note: Note\nIf the julia program needs to access symbols from the main executable, it may be necessary to add the -Wl,--export-dynamic linker flag at compile time on Linux in addition to the ones generated by julia-config.jl described below. This is not necessary when compiling a shared library.","category":"page"},{"location":"manual/embedding/#Using-julia-config-to-automatically-determine-build-parameters","page":"Embedding Julia","title":"Using julia-config to automatically determine build parameters","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The script julia-config.jl was created to aid in determining what build parameters are required by a program that uses embedded Julia. This script uses the build parameters and system configuration of the particular Julia distribution it is invoked by to export the necessary compiler flags for an embedding program to interact with that distribution. This script is located in the Julia shared data directory.","category":"page"},{"location":"manual/embedding/#Example","page":"Embedding Julia","title":"Example","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"#include \n\nint main(int argc, char *argv[])\n{\n jl_init();\n (void)jl_eval_string(\"println(sqrt(2.0))\");\n jl_atexit_hook(0);\n return 0;\n}","category":"page"},{"location":"manual/embedding/#On-the-command-line","page":"Embedding Julia","title":"On the command line","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"A simple use of this script is from the command line. Assuming that julia-config.jl is located in /usr/local/julia/share/julia, it can be invoked on the command line directly and takes any combination of three flags:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"/usr/local/julia/share/julia/julia-config.jl\nUsage: julia-config [--cflags|--ldflags|--ldlibs]","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If the above example source is saved in the file embed_example.c, then the following command will compile it into an executable program on Linux and Windows (MSYS2 environment). On macOS, substitute clang for gcc.:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"/usr/local/julia/share/julia/julia-config.jl --cflags --ldflags --ldlibs | xargs gcc embed_example.c","category":"page"},{"location":"manual/embedding/#Use-in-Makefiles","page":"Embedding Julia","title":"Use in Makefiles","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In general, embedding projects will be more complicated than the above example, and so the following allows general makefile support as well – assuming GNU make because of the use of the shell macro expansions. Furthermore, although julia-config.jl is usually in the /usr/local directory, if it isn't, then Julia itself can be used to find julia-config.jl, and the makefile can take advantage of this. The above example is extended to use a makefile:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"JL_SHARE = $(shell julia -e 'print(joinpath(Sys.BINDIR, Base.DATAROOTDIR, \"julia\"))')\nCFLAGS += $(shell $(JL_SHARE)/julia-config.jl --cflags)\nCXXFLAGS += $(shell $(JL_SHARE)/julia-config.jl --cflags)\nLDFLAGS += $(shell $(JL_SHARE)/julia-config.jl --ldflags)\nLDLIBS += $(shell $(JL_SHARE)/julia-config.jl --ldlibs)\n\nall: embed_example","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Now the build command is simply make.","category":"page"},{"location":"manual/embedding/#High-Level-Embedding-on-Windows-with-Visual-Studio","page":"Embedding Julia","title":"High-Level Embedding on Windows with Visual Studio","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If the JULIA_DIR environment variable hasn't been setup, add it using the System panel before starting Visual Studio. The bin folder under JULIA_DIR should be on the system PATH.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"We start by opening Visual Studio and creating a new Console Application project. Open the 'stdafx.h' header file, and add the following lines at the end:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"#include ","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Then, replace the main() function in the project with this code:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"int main(int argc, char *argv[])\n{\n /* required: setup the Julia context */\n jl_init();\n\n /* run Julia commands */\n jl_eval_string(\"print(sqrt(2.0))\");\n\n /* strongly recommended: notify Julia that the\n program is about to terminate. this allows\n Julia time to cleanup pending write requests\n and run all finalizers\n */\n jl_atexit_hook(0);\n return 0;\n}","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The next step is to set up the project to find the Julia include files and the libraries. It's important to know whether the Julia installation is 32- or 64-bit. Remove any platform configuration that doesn't correspond to the Julia installation before proceeding.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Using the project Properties dialog, go to C/C++ | General and add $(JULIA_DIR)\\include\\julia\\ to the Additional Include Directories property. Then, go to the Linker | General section and add $(JULIA_DIR)\\lib to the Additional Library Directories property. Finally, under Linker | Input, add libjulia.dll.a;libopenlibm.dll.a; to the list of libraries.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"At this point, the project should build and run.","category":"page"},{"location":"manual/embedding/#Converting-Types","page":"Embedding Julia","title":"Converting Types","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Real applications will not only need to execute expressions, but also return their values to the host program. jl_eval_string returns a jl_value_t*, which is a pointer to a heap-allocated Julia object. Storing simple data types like Float64 in this way is called boxing, and extracting the stored primitive data is called unboxing. Our improved sample program that calculates the square root of 2 in Julia and reads back the result in C has a body that now contains this code:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *ret = jl_eval_string(\"sqrt(2.0)\");\n\nif (jl_typeis(ret, jl_float64_type)) {\n double ret_unboxed = jl_unbox_float64(ret);\n printf(\"sqrt(2.0) in C: %e \\n\", ret_unboxed);\n}\nelse {\n printf(\"ERROR: unexpected return type from sqrt(::Float64)\\n\");\n}","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In order to check whether ret is of a specific Julia type, we can use the jl_isa, jl_typeis, or jl_is_... functions. By typing typeof(sqrt(2.0)) into the Julia shell we can see that the return type is Float64 (double in C). To convert the boxed Julia value into a C double the jl_unbox_float64 function is used in the above code snippet.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Corresponding jl_box_... functions are used to convert the other way:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *a = jl_box_float64(3.0);\njl_value_t *b = jl_box_float32(3.0f);\njl_value_t *c = jl_box_int32(3);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As we will see next, boxing is required to call Julia functions with specific arguments.","category":"page"},{"location":"manual/embedding/#Calling-Julia-Functions","page":"Embedding Julia","title":"Calling Julia Functions","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"While jl_eval_string allows C to obtain the result of a Julia expression, it does not allow passing arguments computed in C to Julia. For this you will need to invoke Julia functions directly, using jl_call:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_function_t *func = jl_get_function(jl_base_module, \"sqrt\");\njl_value_t *argument = jl_box_float64(2.0);\njl_value_t *ret = jl_call1(func, argument);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In the first step, a handle to the Julia function sqrt is retrieved by calling jl_get_function. The first argument passed to jl_get_function is a pointer to the Base module in which sqrt is defined. Then, the double value is boxed using jl_box_float64. Finally, in the last step, the function is called using jl_call1. jl_call0, jl_call2, and jl_call3 functions also exist, to conveniently handle different numbers of arguments. To pass more arguments, use jl_call:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs)","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Its second argument args is an array of jl_value_t* arguments and nargs is the number of arguments.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"There is also an alternative, possibly simpler, way of calling Julia functions and that is via @cfunction. Using @cfunction allows you to do the type conversions on the Julia side, which is typically easier than doing it on the C side. The sqrt example above would with @cfunction be written as:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"double (*sqrt_jl)(double) = jl_unbox_voidpointer(jl_eval_string(\"@cfunction(sqrt, Float64, (Float64,))\"));\ndouble ret = sqrt_jl(2.0);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"where we first define a C callable function in Julia, extract the function pointer from it, and finally call it. In addition to simplifying type conversions by doing them in the higher-level language, calling Julia functions via @cfunction pointers eliminates the dynamic-dispatch overhead required by jl_call (for which all of the arguments are \"boxed\"), and should have performance equivalent to native C function pointers.","category":"page"},{"location":"manual/embedding/#Memory-Management","page":"Embedding Julia","title":"Memory Management","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As we have seen, Julia objects are represented in C as pointers of type jl_value_t*. This raises the question of who is responsible for freeing these objects.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Typically, Julia objects are freed by the garbage collector (GC), but the GC does not automatically know that we are holding a reference to a Julia value from C. This means the GC can free objects out from under you, rendering pointers invalid.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The GC will only run when new Julia objects are being allocated. Calls like jl_box_float64 perform allocation, but allocation might also happen at any point in running Julia code.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"When writing code that embeds Julia, it is generally safe to use jl_value_t* values in between jl_... calls (as GC will only get triggered by those calls). But in order to make sure that values can survive jl_... calls, we have to tell Julia that we still hold a reference to Julia root values, a process called \"GC rooting\". Rooting a value will ensure that the garbage collector does not accidentally identify this value as unused and free the memory backing that value. This can be done using the JL_GC_PUSH macros:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *ret = jl_eval_string(\"sqrt(2.0)\");\nJL_GC_PUSH1(&ret);\n// Do something with ret\nJL_GC_POP();","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The JL_GC_POP call releases the references established by the previous JL_GC_PUSH. Note that JL_GC_PUSH stores references on the C stack, so it must be exactly paired with a JL_GC_POP before the scope is exited. That is, before the function returns, or control flow otherwise leaves the block in which the JL_GC_PUSH was invoked.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Several Julia values can be pushed at once using the JL_GC_PUSH2 to JL_GC_PUSH6 macros:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"JL_GC_PUSH2(&ret1, &ret2);\n// ...\nJL_GC_PUSH6(&ret1, &ret2, &ret3, &ret4, &ret5, &ret6);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"To push an array of Julia values one can use the JL_GC_PUSHARGS macro, which can be used as follows:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t **args;\nJL_GC_PUSHARGS(args, 2); // args can now hold 2 `jl_value_t*` objects\nargs[0] = some_value;\nargs[1] = some_other_value;\n// Do something with args (e.g. call jl_... functions)\nJL_GC_POP();","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Each scope must have only one call to JL_GC_PUSH*, and should be paired with only a single JL_GC_POP call. If all necessary variables you want to root cannot be pushed by a one single call to JL_GC_PUSH*, or if there are more than 6 variables to be pushed and using an array of arguments is not an option, then one can use inner blocks:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *ret1 = jl_eval_string(\"sqrt(2.0)\");\nJL_GC_PUSH1(&ret1);\njl_value_t *ret2 = 0;\n{\n jl_function_t *func = jl_get_function(jl_base_module, \"exp\");\n ret2 = jl_call1(func, ret1);\n JL_GC_PUSH1(&ret2);\n // Do something with ret2.\n JL_GC_POP(); // This pops ret2.\n}\nJL_GC_POP(); // This pops ret1.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Note that it is not necessary to have valid jl_value_t* values before calling JL_GC_PUSH*. It is fine to have a number of them initialized to NULL, pass those to JL_GC_PUSH* and then create the actual Julia values. For example:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *ret1 = NULL, *ret2 = NULL;\nJL_GC_PUSH2(&ret1, &ret2);\nret1 = jl_eval_string(\"sqrt(2.0)\");\nret2 = jl_eval_string(\"sqrt(3.0)\");\n// Use ret1 and ret2\nJL_GC_POP();","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If it is required to hold the pointer to a variable between functions (or block scopes), then it is not possible to use JL_GC_PUSH*. In this case, it is necessary to create and keep a reference to the variable in the Julia global scope. One simple way to accomplish this is to use a global IdDict that will hold the references, avoiding deallocation by the GC. However, this method will only work properly with mutable types.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"// This functions shall be executed only once, during the initialization.\njl_value_t* refs = jl_eval_string(\"refs = IdDict()\");\njl_function_t* setindex = jl_get_function(jl_base_module, \"setindex!\");\n\n...\n\n// `var` is the variable we want to protect between function calls.\njl_value_t* var = 0;\n\n...\n\n// `var` is a `Vector{Float64}`, which is mutable.\nvar = jl_eval_string(\"[sqrt(2.0); sqrt(4.0); sqrt(6.0)]\");\n\n// To protect `var`, add its reference to `refs`.\njl_call3(setindex, refs, var, var);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If the variable is immutable, then it needs to be wrapped in an equivalent mutable container or, preferably, in a RefValue{Any} before it is pushed to IdDict. In this approach, the container has to be created or filled in via C code using, for example, the function jl_new_struct. If the container is created by jl_call*, then you will need to reload the pointer to be used in C code.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"// This functions shall be executed only once, during the initialization.\njl_value_t* refs = jl_eval_string(\"refs = IdDict()\");\njl_function_t* setindex = jl_get_function(jl_base_module, \"setindex!\");\njl_datatype_t* reft = (jl_datatype_t*)jl_eval_string(\"Base.RefValue{Any}\");\n\n...\n\n// `var` is the variable we want to protect between function calls.\njl_value_t* var = 0;\n\n...\n\n// `var` is a `Float64`, which is immutable.\nvar = jl_eval_string(\"sqrt(2.0)\");\n\n// Protect `var` until we add its reference to `refs`.\nJL_GC_PUSH1(&var);\n\n// Wrap `var` in `RefValue{Any}` and push to `refs` to protect it.\njl_value_t* rvar = jl_new_struct(reft, var);\nJL_GC_POP();\n\njl_call3(setindex, refs, rvar, rvar);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The GC can be allowed to deallocate a variable by removing the reference to it from refs using the function delete!, provided that no other reference to the variable is kept anywhere:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_function_t* delete = jl_get_function(jl_base_module, \"delete!\");\njl_call2(delete, refs, rvar);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As an alternative for very simple cases, it is possible to just create a global container of type Vector{Any} and fetch the elements from that when necessary, or even to create one global variable per pointer using","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_module_t *mod = jl_main_module;\njl_sym_t *var = jl_symbol(\"var\");\njl_binding_t *bp = jl_get_binding_wr(mod, var);\njl_checked_assignment(bp, mod, var, val);","category":"page"},{"location":"manual/embedding/#Updating-fields-of-GC-managed-objects","page":"Embedding Julia","title":"Updating fields of GC-managed objects","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The garbage collector also operates under the assumption that it is aware of every older-generation object pointing to a younger-generation one. Any time a pointer is updated breaking that assumption, it must be signaled to the collector with the jl_gc_wb (write barrier) function like so:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t *parent = some_old_value, *child = some_young_value;\n((some_specific_type*)parent)->field = child;\njl_gc_wb(parent, child);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"It is in general impossible to predict which values will be old at runtime, so the write barrier must be inserted after all explicit stores. One notable exception is if the parent object has just been allocated and no garbage collection has run since then. Note that most jl_... functions can sometimes invoke garbage collection.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The write barrier is also necessary for arrays of pointers when updating their data directly. Calling jl_array_ptr_set is usually much preferred. But direct updates can be done. For example:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_array_t *some_array = ...; // e.g. a Vector{Any}\nvoid **data = jl_array_data(some_array, void*);\njl_value_t *some_value = ...;\ndata[0] = some_value;\njl_gc_wb(jl_array_owner(some_array), some_value);","category":"page"},{"location":"manual/embedding/#Controlling-the-Garbage-Collector","page":"Embedding Julia","title":"Controlling the Garbage Collector","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"There are some functions to control the GC. In normal use cases, these should not be necessary.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Function Description\njl_gc_collect() Force a GC run\njl_gc_enable(0) Disable the GC, return previous state as int\njl_gc_enable(1) Enable the GC, return previous state as int\njl_gc_is_enabled() Return current state as int","category":"page"},{"location":"manual/embedding/#Working-with-Arrays","page":"Embedding Julia","title":"Working with Arrays","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Julia and C can share array data without copying. The next example will show how this works.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Julia arrays are represented in C by the datatype jl_array_t*. Basically, jl_array_t is a struct that contains:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Information about the datatype\nA pointer to the data block\nInformation about the sizes of the array","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"To keep things simple, we start with a 1D array. Creating an array containing Float64 elements of length 10 can be done like this:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1);\njl_array_t* x = jl_alloc_array_1d(array_type, 10);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Alternatively, if you have already allocated the array you can generate a thin wrapper around its data:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"double *existingArray = (double*)malloc(sizeof(double)*10);\njl_array_t *x = jl_ptr_to_array_1d(array_type, existingArray, 10, 0);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"The last argument is a boolean indicating whether Julia should take ownership of the data. If this argument is non-zero, the GC will call free on the data pointer when the array is no longer referenced.","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"In order to access the data of x, we can use jl_array_data:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"double *xData = jl_array_data(x, double);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Now we can fill the array:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"for (size_t i = 0; i < jl_array_nrows(x); i++)\n xData[i] = i;","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Now let us call a Julia function that performs an in-place operation on x:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_function_t *func = jl_get_function(jl_base_module, \"reverse!\");\njl_call1(func, (jl_value_t*)x);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"By printing the array, one can verify that the elements of x are now reversed.","category":"page"},{"location":"manual/embedding/#Accessing-Returned-Arrays","page":"Embedding Julia","title":"Accessing Returned Arrays","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If a Julia function returns an array, the return value of jl_eval_string and jl_call can be cast to a jl_array_t*:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"jl_function_t *func = jl_get_function(jl_base_module, \"reverse\");\njl_array_t *y = (jl_array_t*)jl_call1(func, (jl_value_t*)x);","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Now the content of y can be accessed as before using jl_array_data. As always, be sure to keep a reference to the array while it is in use.","category":"page"},{"location":"manual/embedding/#Multidimensional-Arrays","page":"Embedding Julia","title":"Multidimensional Arrays","text":"","category":"section"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"Julia's multidimensional arrays are stored in memory in column-major order. Here is some code that creates a 2D array and accesses its properties:","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"// Create 2D array of float64 type\njl_value_t *array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 2);\nint dims[] = {10,5};\njl_array_t *x = jl_alloc_array_nd(array_type, dims, 2);\n\n// Get array pointer\ndouble *p = jl_array_data(x, double);\n// Get number of dimensions\nint ndims = jl_array_ndims(x);\n// Get the size of the i-th dim\nsize_t size0 = jl_array_dim(x,0);\nsize_t size1 = jl_array_dim(x,1);\n\n// Fill array with data\nfor(size_t i=0; i\nJULIA_DEFINE_FAST_TLS\n\ndouble c_func(int i)\n{\n printf(\"[C %08x] i = %d\\n\", pthread_self(), i);\n\n // Call the Julia sqrt() function to compute the square root of i, and return it\n jl_function_t *sqrt = jl_get_function(jl_base_module, \"sqrt\");\n jl_value_t* arg = jl_box_int32(i);\n double ret = jl_unbox_float64(jl_call1(sqrt, arg));\n\n return ret;\n}\n\nint main()\n{\n jl_init();\n\n // Define a Julia function func() that calls our c_func() defined in C above\n jl_eval_string(\"func(i) = ccall(:c_func, Float64, (Int32,), i)\");\n\n // Call func() multiple times, using multiple threads to do so\n jl_eval_string(\"println(Threads.threadpoolsize())\");\n jl_eval_string(\"use(i) = println(\\\"[J $(Threads.threadid())] i = $(i) -> $(func(i))\\\")\");\n jl_eval_string(\"Threads.@threads for i in 1:5 use(i) end\");\n\n jl_atexit_hook(0);\n}","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"If we run this code with 2 Julia threads we get the following output (note: the output will vary per run and system):","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"$ JULIA_NUM_THREADS=2 ./thread_example\n2\n[C 3bfd9c00] i = 1\n[C 23938640] i = 4\n[J 1] i = 1 -> 1.0\n[C 3bfd9c00] i = 2\n[J 1] i = 2 -> 1.4142135623730951\n[C 3bfd9c00] i = 3\n[J 2] i = 4 -> 2.0\n[C 23938640] i = 5\n[J 1] i = 3 -> 1.7320508075688772\n[J 2] i = 5 -> 2.23606797749979","category":"page"},{"location":"manual/embedding/","page":"Embedding Julia","title":"Embedding Julia","text":"As can be seen, Julia thread 1 corresponds to pthread ID 3bfd9c00, and Julia thread 2 corresponds to ID 23938640, showing that indeed multiple threads are used at the C level, and that we can safely call Julia C API routines from those threads.","category":"page"},{"location":"devdocs/backtraces/#Reporting-and-analyzing-crashes-(segfaults)","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"So you managed to break Julia. Congratulations! Collected here are some general procedures you can undergo for common symptoms encountered when something goes awry. Including the information from these debugging steps can greatly help the maintainers when tracking down a segfault or trying to figure out why your script is running slower than expected.","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"If you've been directed to this page, find the symptom that best matches what you're experiencing and follow the instructions to generate the debugging information requested. Table of symptoms:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Segfaults during bootstrap (sysimg.jl)\nSegfaults when running a script\nErrors during Julia startup\nOther generic segfaults or unreachables reached","category":"page"},{"location":"devdocs/backtraces/#dev-version-info","page":"Reporting and analyzing crashes (segfaults)","title":"Version/Environment info","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"No matter the error, we will always need to know what version of Julia you are running. When Julia first starts up, a header is printed out with a version number and date. Please also include the output of versioninfo() (exported from the InteractiveUtils standard library) in any report you create:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"using InteractiveUtils\nversioninfo()","category":"page"},{"location":"devdocs/backtraces/#Segfaults-during-bootstrap-(sysimg.jl)","page":"Reporting and analyzing crashes (segfaults)","title":"Segfaults during bootstrap (sysimg.jl)","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Segfaults toward the end of the make process of building Julia are a common symptom of something going wrong while Julia is preparsing the corpus of code in the base/ folder. Many factors can contribute toward this process dying unexpectedly, however it is as often as not due to an error in the C-code portion of Julia, and as such must typically be debugged with a debug build inside of gdb. Explicitly:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Create a debug build of Julia:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"$ cd \n$ make debug","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Note that this process will likely fail with the same error as a normal make incantation, however this will create a debug executable that will offer gdb the debugging symbols needed to get accurate backtraces. Next, manually run the bootstrap process inside of gdb:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"$ cd base/\n$ gdb -x ../contrib/debug_bootstrap.gdb","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"This will start gdb, attempt to run the bootstrap process using the debug build of Julia, and print out a backtrace if (when) it segfaults. You may need to hit a few times to get the full backtrace. Create a gist with the backtrace, the version info, and any other pertinent information you can think of and open a new issue on Github with a link to the gist.","category":"page"},{"location":"devdocs/backtraces/#Segfaults-when-running-a-script","page":"Reporting and analyzing crashes (segfaults)","title":"Segfaults when running a script","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"The procedure is very similar to Segfaults during bootstrap (sysimg.jl). Create a debug build of Julia, and run your script inside of a debugged Julia process:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"$ cd \n$ make debug\n$ gdb --args usr/bin/julia-debug ","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Note that gdb will sit there, waiting for instructions. Type r to run the process, and bt to generate a backtrace once it segfaults:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"(gdb) r\nStarting program: /home/sabae/src/julia/usr/bin/julia-debug ./test.jl\n...\n(gdb) bt","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Create a gist with the backtrace, the version info, and any other pertinent information you can think of and open a new issue on Github with a link to the gist.","category":"page"},{"location":"devdocs/backtraces/#Errors-during-Julia-startup","page":"Reporting and analyzing crashes (segfaults)","title":"Errors during Julia startup","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Occasionally errors occur during Julia's startup process (especially when using binary distributions, as opposed to compiling from source) such as the following:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"$ julia\nexec: error -5","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"These errors typically indicate something is not getting loaded properly very early on in the bootup phase, and our best bet in determining what's going wrong is to use external tools to audit the disk activity of the julia process:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"On Linux, use strace:\n$ strace julia\nOn OSX, use dtruss:\n$ dtruss -f julia","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Create a gist with the strace/ dtruss output, the version info, and any other pertinent information and open a new issue on Github with a link to the gist.","category":"page"},{"location":"devdocs/backtraces/#Other-generic-segfaults-or-unreachables-reached","page":"Reporting and analyzing crashes (segfaults)","title":"Other generic segfaults or unreachables reached","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"As mentioned elsewhere, julia has good integration with rr for generating traces; this includes, on Linux, the ability to automatically run julia under rr and share the trace after a crash. This can be immensely helpful when debugging such crashes and is strongly encouraged when reporting crash issues to the JuliaLang/julia repo. To run julia under rr automatically, do:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"julia --bug-report=rr","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"To generate the rr trace locally, but not share, you can do:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"julia --bug-report=rr-local","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"Note that this is only works on Linux. The blog post on Time Travelling Bug Reporting has many more details.","category":"page"},{"location":"devdocs/backtraces/#Glossary","page":"Reporting and analyzing crashes (segfaults)","title":"Glossary","text":"","category":"section"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":"A few terms have been used as shorthand in this guide:","category":"page"},{"location":"devdocs/backtraces/","page":"Reporting and analyzing crashes (segfaults)","title":"Reporting and analyzing crashes (segfaults)","text":" refers to the root directory of the Julia source tree; e.g. it should contain folders such as base, deps, src, test, etc.....","category":"page"},{"location":"devdocs/init/#Initialization-of-the-Julia-runtime","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"How does the Julia runtime execute julia -e 'println(\"Hello World!\")' ?","category":"page"},{"location":"devdocs/init/#main()","page":"Initialization of the Julia runtime","title":"main()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Execution starts at main() in cli/loader_exe.c, which calls jl_load_repl() in cli/loader_lib.c which loads a few libraries, eventually calling jl_repl_entrypoint() in src/jlapi.c.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_repl_entrypoint() calls libsupport_init() to set the C library locale and to initialize the \"ios\" library (see ios_init_stdstreams() and Legacy ios.c library).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Next jl_parse_opts() is called to process command line options. Note that jl_parse_opts() only deals with options that affect code generation or early initialization. Other options are handled later by exec_options() in base/client.jl.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_parse_opts() stores command line options in the global jl_options struct.","category":"page"},{"location":"devdocs/init/#julia_init()","page":"Initialization of the Julia runtime","title":"julia_init()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"julia_init() in init.c is called by main() and calls _julia_init() in init.c.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"_julia_init() begins by calling libsupport_init() again (it does nothing the second time).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"restore_signals() is called to zero the signal handler mask.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_resolve_sysimg_location() searches configured paths for the base system image. See Building the Julia system image.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_gc_init() sets up allocation pools and lists for weak refs, preserved values and finalization.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_frontend() loads and initializes a pre-compiled femtolisp image containing the scanner/parser.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_types() creates jl_datatype_t type description objects for the built-in types defined in julia.h. e.g.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_any_type = jl_new_abstracttype(jl_symbol(\"Any\"), core, NULL, jl_emptysvec);\njl_any_type->super = jl_any_type;\n\njl_type_type = jl_new_abstracttype(jl_symbol(\"Type\"), core, jl_any_type, jl_emptysvec);\n\njl_int32_type = jl_new_primitivetype(jl_symbol(\"Int32\"), core,\n jl_any_type, jl_emptysvec, 32);","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_tasks() creates the jl_datatype_t* jl_task_type object; initializes the global jl_root_task struct; and sets jl_current_task to the root task.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_codegen() initializes the LLVM library.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_serializer() initializes 8-bit serialization tags for builtin jl_value_t values.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"If there is no sysimg file (!jl_options.image_file) then the Core and Main modules are created and boot.jl is evaluated:","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_core_module = jl_new_module(jl_symbol(\"Core\")) creates the Julia Core module.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_intrinsic_functions() creates a new Julia module Intrinsics containing constant jl_intrinsic_type symbols. These define an integer code for each intrinsic function. emit_intrinsic() translates these symbols into LLVM instructions during code generation.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_primitives() hooks C functions up to Julia function symbols. e.g. the symbol Core.:(===)() is bound to C function pointer jl_f_is() by calling add_builtin_func(\"===\", jl_f_is).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_new_main_module() creates the global \"Main\" module and sets jl_current_task->current_module = jl_main_module.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Note: _julia_init() then sets jl_root_task->current_module = jl_core_module. jl_root_task is an alias of jl_current_task at this point, so the current_module set by jl_new_main_module() above is overwritten.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_load(\"boot.jl\", sizeof(\"boot.jl\")) calls jl_parse_eval_all which repeatedly calls jl_toplevel_eval_flex() to execute boot.jl. ","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_get_builtin_hooks() initializes global C pointers to Julia globals defined in boot.jl.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_box_caches() pre-allocates global boxed integer value objects for values up to 1024. This speeds up allocation of boxed ints later on. e.g.:","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_value_t *jl_box_uint8(uint32_t x)\n{\n return boxed_uint8_cache[(uint8_t)x];\n}","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"_julia_init() iterates over the jl_core_module->bindings.table looking for jl_datatype_t values and sets the type name's module prefix to jl_core_module.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_add_standard_imports(jl_main_module) does \"using Base\" in the \"Main\" module.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Note: _julia_init() now reverts to jl_root_task->current_module = jl_main_module as it was before being set to jl_core_module above.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Platform specific signal handlers are initialized for SIGSEGV (OSX, Linux), and SIGFPE (Windows).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Other signals (SIGINFO, SIGBUS, SIGILL, SIGTERM, SIGABRT, SIGQUIT, SIGSYS and SIGPIPE) are hooked up to sigdie_handler() which prints a backtrace.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_init_restored_module() calls jl_module_run_initializer() for each deserialized module to run the __init__() function.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Finally sigint_handler() is hooked up to SIGINT and calls jl_throw(jl_interrupt_exception).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"_julia_init() then returns back to main() in cli/loader_exe.c and main() calls repl_entrypoint(argc, (char**)argv).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"sidebar: sysimg\nIf there is a sysimg file, it contains a pre-cooked image of the Core and Main modules (and whatever else is created by boot.jl). See Building the Julia system image.jl_restore_system_image() deserializes the saved sysimg into the current Julia runtime environment and initialization continues after jl_init_box_caches() below...Note: jl_restore_system_image() (and staticdata.c in general) uses the Legacy ios.c library.","category":"page"},{"location":"devdocs/init/#repl_entrypoint()","page":"Initialization of the Julia runtime","title":"repl_entrypoint()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"repl_entrypoint() loads the contents of argv[] into Base.ARGS.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"If a .jl \"program\" file was supplied on the command line, then exec_program() calls jl_load(program,len) which calls jl_parse_eval_all which repeatedly calls jl_toplevel_eval_flex() to execute the program.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"However, in our example (julia -e 'println(\"Hello World!\")'), jl_get_global(jl_base_module, jl_symbol(\"_start\")) looks up Base._start and jl_apply() executes it.","category":"page"},{"location":"devdocs/init/#Base._start","page":"Initialization of the Julia runtime","title":"Base._start","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Base._start calls Base.exec_options which calls jl_parse_input_line(\"println(\"Hello World!\")\") to create an expression object and Core.eval(Main, ex) to execute the parsed expression ex in the module context of Main.","category":"page"},{"location":"devdocs/init/#Core.eval","page":"Initialization of the Julia runtime","title":"Core.eval","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Core.eval(Main, ex) calls jl_toplevel_eval_in(m, ex), which calls jl_toplevel_eval_flex. jl_toplevel_eval_flex implements a simple heuristic to decide whether to compile a given code thunk or run it by interpreter. When given println(\"Hello World!\"), it would usually decide to run the code by interpreter, in which case it calls jl_interpret_toplevel_thunk, which then calls eval_body.","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"The stack dump below shows how the interpreter works its way through various methods of Base.println() and Base.print() before arriving at write(s::IO, a::Array{T}) where T which does ccall(jl_uv_write()).","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"jl_uv_write() calls uv_write() to write \"Hello World!\" to JL_STDOUT. See Libuv wrappers for stdio.:","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Hello World!","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Stack frame Source code Notes\njl_uv_write() jl_uv.c called though ccall\njulia_write_282942 stream.jl function write!(s::IO, a::Array{T}) where T\njulia_print_284639 ascii.jl print(io::IO, s::String) = (write(io, s); nothing)\njlcall_print_284639 \njl_apply() julia.h \njl_trampoline() builtins.c \njl_apply() julia.h \njl_apply_generic() gf.c Base.print(Base.TTY, String)\njl_apply() julia.h \njl_trampoline() builtins.c \njl_apply() julia.h \njl_apply_generic() gf.c Base.print(Base.TTY, String, Char, Char...)\njl_apply() julia.h \njl_f_apply() builtins.c \njl_apply() julia.h \njl_trampoline() builtins.c \njl_apply() julia.h \njl_apply_generic() gf.c Base.println(Base.TTY, String, String...)\njl_apply() julia.h \njl_trampoline() builtins.c \njl_apply() julia.h \njl_apply_generic() gf.c Base.println(String,)\njl_apply() julia.h \ndo_call() interpreter.c \neval_body() interpreter.c \njl_interpret_toplevel_thunk interpreter.c \njl_toplevel_eval_flex toplevel.c \njl_toplevel_eval_in toplevel.c \nCore.eval boot.jl ","category":"page"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Since our example has just one function call, which has done its job of printing \"Hello World!\", the stack now rapidly unwinds back to main().","category":"page"},{"location":"devdocs/init/#jl_atexit_hook()","page":"Initialization of the Julia runtime","title":"jl_atexit_hook()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"main() calls jl_atexit_hook(). This calls Base._atexit, then calls jl_gc_run_all_finalizers() and cleans up libuv handles.","category":"page"},{"location":"devdocs/init/#julia_save()","page":"Initialization of the Julia runtime","title":"julia_save()","text":"","category":"section"},{"location":"devdocs/init/","page":"Initialization of the Julia runtime","title":"Initialization of the Julia runtime","text":"Finally, main() calls julia_save(), which if requested on the command line, saves the runtime state to a new system image. See jl_compile_all() and jl_save_system_image().","category":"page"},{"location":"devdocs/build/distributing/#Binary-distributions","page":"Binary distributions","title":"Binary distributions","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"These notes are for those wishing to compile a binary distribution of Julia for distribution on various platforms. We love users spreading Julia as far and wide as they can, trying it out on as wide an array of operating systems and hardware configurations as possible. As each platform has specific gotchas and processes that must be followed in order to create a portable, working Julia distribution, we have separated most of the notes by OS.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Note that while the code for Julia is MIT-licensed, with a few exceptions, the distribution created by the techniques described herein will be GPL licensed, as various dependent libraries such as SuiteSparse are GPL licensed. We do hope to have a non-GPL distribution of Julia in the future.","category":"page"},{"location":"devdocs/build/distributing/#Versioning-and-Git","page":"Binary distributions","title":"Versioning and Git","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"The Makefile uses both the VERSION file and commit hashes and tags from the git repository to generate the base/version_git.jl with information we use to fill the splash screen and the versioninfo() output. If you for some reason don't want to have the git repository available when building you should pregenerate the base/version_git.jl file with:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"make -C base version_git.jl.phony","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia has lots of build dependencies where we use patched versions that has not yet been included by the popular package managers. These dependencies will usually be automatically downloaded when you build, but if you want to be able to build Julia on a computer without internet access you should create a full-source-dist archive with the special make target","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"make full-source-dist","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"that creates a julia-version-commit.tar.gz archive with all required dependencies.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"When compiling a tagged release in the git repository, we don't display the branch/commit hash info in the splash screen. You can use this line to show a release description of up to 45 characters. To set this line you have to create a Make.user file containing:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"override TAGGED_RELEASE_BANNER = \"my-package-repository build\"","category":"page"},{"location":"devdocs/build/distributing/#Target-Architectures","page":"Binary distributions","title":"Target Architectures","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"By default, Julia optimizes its system image to the native architecture of the build machine. This is usually not what you want when building packages, as it will make Julia fail at startup on any machine with incompatible CPUs (in particular older ones with more restricted instruction sets).","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"We therefore recommend that you pass the MARCH variable when calling make, setting it to the baseline target you intend to support. This will determine the target CPU for both the Julia executable and libraries, and the system image (the latter can also be set using JULIA_CPU_TARGET). Typically useful values for x86 CPUs are x86-64 and core2 (for 64-bit builds) and pentium4 (for 32-bit builds). Unfortunately, CPUs older than Pentium 4 are currently not supported (see this issue).","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"The full list of CPU targets supported by LLVM can be obtained by running llc -mattr=help.","category":"page"},{"location":"devdocs/build/distributing/#Linux","page":"Binary distributions","title":"Linux","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"On Linux, make binary-dist creates a tarball that contains a fully functional Julia installation. If you wish to create a distribution package such as a .deb, or .rpm, some extra effort is needed. See the julia-debian repository for an example of what metadata is needed for creating .deb packages for Debian and Ubuntu-based systems. See the Fedora package for RPM-based distributions. Although we have not yet experimented with it, Alien could be used to generate Julia packages for various Linux distributions.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia supports overriding standard installation directories via prefix and other environment variables you can pass when calling make and make install. See Make.inc for their list. DESTDIR can also be used to force the installation into a temporary directory.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"By default, Julia loads $prefix/etc/julia/startup.jl as an installation-wide initialization file. This file can be used by distribution managers to set up custom paths or initialization code. For Linux distribution packages, if $prefix is set to /usr, there is no /usr/etc to look into. This requires the path to Julia's private etc directory to be changed. This can be done via the sysconfdir make variable when building. Simply pass sysconfdir=/etc to make when building and Julia will first check /etc/julia/startup.jl before trying $prefix/etc/julia/startup.jl.","category":"page"},{"location":"devdocs/build/distributing/#OS-X","page":"Binary distributions","title":"OS X","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"To create a binary distribution on OSX, build Julia first, then cd to contrib/mac/app, and run make with the same makevars that were used with make when building Julia proper. This will then create a .dmg file in the contrib/mac/app directory holding a completely self-contained Julia.app.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Alternatively, Julia may be built as a framework by invoking make with the darwinframework target and DARWIN_FRAMEWORK=1 set. For example, make DARWIN_FRAMEWORK=1 darwinframework.","category":"page"},{"location":"devdocs/build/distributing/#Windows","page":"Binary distributions","title":"Windows","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Instructions for reating a Julia distribution on Windows are described in the build devdocs for Windows.","category":"page"},{"location":"devdocs/build/distributing/#Notes-on-BLAS-and-LAPACK","page":"Binary distributions","title":"Notes on BLAS and LAPACK","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia builds OpenBLAS by default, which includes the BLAS and LAPACK libraries. On 32-bit architectures, Julia builds OpenBLAS to use 32-bit integers, while on 64-bit architectures, Julia builds OpenBLAS to use 64-bit integers (ILP64). It is essential that all Julia functions that call BLAS and LAPACK API routines use integers of the correct width.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Most BLAS and LAPACK distributions provided on linux distributions, and even commercial implementations ship libraries that use 32-bit APIs. In many cases, a 64-bit API is provided as a separate library.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"When using vendor provided or OS provided libraries, a make option called USE_BLAS64 is available as part of the Julia build. When doing make USE_BLAS64=0, Julia will call BLAS and LAPACK assuming a 32-bit API, where all integers are 32-bit wide, even on a 64-bit architecture.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Other libraries that Julia uses, such as SuiteSparse also use BLAS and LAPACK internally. The APIs need to be consistent across all libraries that depend on BLAS and LAPACK. The Julia build process will build all these libraries correctly, but when overriding defaults and using system provided libraries, this consistency must be ensured.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Also note that Linux distributions sometimes ship several versions of OpenBLAS, some of which enable multithreading, and others only working in a serial fashion. For example, in Fedora, libopenblasp.so is threaded, but libopenblas.so is not. We recommend using the former for optimal performance. To choose an OpenBLAS library whose name is different from the default libopenblas.so, pass LIBBLAS=-l$(YOURBLAS) and LIBBLASNAME=lib$(YOURBLAS) to make, replacing $(YOURBLAS) with the name of your library. You can also add .so.0 to the name of the library if you want your package to work without requiring the unversioned .so symlink.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Finally, OpenBLAS includes its own optimized version of LAPACK. If you set USE_SYSTEM_BLAS=1 and USE_SYSTEM_LAPACK=1, you should also set LIBLAPACK=-l$(YOURBLAS) and LIBLAPACKNAME=lib$(YOURBLAS). Else, the reference LAPACK will be used and performance will typically be much lower.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Starting with Julia 1.7, Julia uses libblastrampoline to pick a different BLAS at runtime.","category":"page"},{"location":"devdocs/build/distributing/#Point-releasing-101","page":"Binary distributions","title":"Point releasing 101","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Creating a point/patch release consists of several distinct steps.","category":"page"},{"location":"devdocs/build/distributing/#Backporting-commits","page":"Binary distributions","title":"Backporting commits","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Some pull requests are labeled \"backport pending x.y\", e.g. \"backport pending 0.6\". This designates that the next subsequent release tagged from the release-x.y branch should include the commit(s) in that pull request. Once the pull request is merged into master, each of the commits should be cherry picked to a dedicated branch that will ultimately be merged into release-x.y.","category":"page"},{"location":"devdocs/build/distributing/#Creating-a-backports-branch","page":"Binary distributions","title":"Creating a backports branch","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"First, create a new branch based on release-x.y. The typical convention for Julia branches is to prefix the branch name with your initials if it's intended to be a personal branch. For the sake of example, we'll say that the author of the branch is Jane Smith.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git fetch origin\ngit checkout release-x.y\ngit rebase origin/release-x.y\ngit checkout -b js/backport-x.y","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This ensures that your local copy of release-x.y is up to date with origin before you create a new branch from it.","category":"page"},{"location":"devdocs/build/distributing/#Cherry-picking-commits","page":"Binary distributions","title":"Cherry picking commits","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Now we do the actual backporting. Find all merged pull requests labeled \"backport pending x.y\" in the GitHub web UI. For each of these, scroll to the bottom where it says \"someperson merged commit 123abc into master XX minutes ago\". Note that the commit name is a link; if you click it, you'll be shown the contents of the commit. If this page shows that 123abc is a merge commit, go back to the PR page–-we don't want merge commits, we want the actual commits. However, if this does not show a merge commit, it means that the PR was squash-merged. In that case, use the git SHA of the commit, listed next to commit on this page.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Once you have the SHA of the commit, cherry-pick it onto the backporting branch:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git cherry-pick -x -e ","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"There may be conflicts which need to be resolved manually. Once conflicts are resolved (if applicable), add a reference to the GitHub pull request that introduced the commit in the body of the commit message.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"After all of the relevant commits are on the backports branch, push the branch to GitHub.","category":"page"},{"location":"devdocs/build/distributing/#Checking-for-performance-regressions","page":"Binary distributions","title":"Checking for performance regressions","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Point releases should never introduce performance regressions. Luckily the Julia benchmarking bot, Nanosoldier, can run benchmarks against any branch, not just master. In this case we want to check the benchmark results of js/backport-x.y against release-x.y. To do this, awaken the Nanosoldier from his robotic slumber using a comment on your backporting pull request:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"@nanosoldier `runbenchmarks(ALL, vs=\":release-x.y\")`","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This will run all registered benchmarks on release-x.y and js/backport-x.y and produce a summary of results, marking all improvements and regressions.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"If Nanosoldier finds any regressions, try verifying locally and rerun Nanosoldier if necessary. If the regressions are deemed to be real rather than just noise, you'll have to find a commit on master to backport that fixes it if one exists, otherwise you should determine what caused the regression and submit a patch (or get someone who knows the code to submit a patch) to master, then backport the commit once that's merged. (Or submit a patch directly to the backport branch if appropriate.)","category":"page"},{"location":"devdocs/build/distributing/#Building-test-binaries","page":"Binary distributions","title":"Building test binaries","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"After the backport PR has been merged into the release-x.y branch, update your local clone of Julia, then get the SHA of the branch using","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git rev-parse origin/release-x.y","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Keep that handy, as it's what you'll enter in the \"Revision\" field in the buildbot UI.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"For now, all you need are binaries for Linux x86-64, since this is what's used for running PackageEvaluator. Go to https://buildog.julialang.org, submit a job for nuke_linux64, then queue up a job for package_linux64, providing the SHA as the revision. When the packaging job completes, it will upload the binary to the julialang2 bucket on AWS. Retrieve the URL, as it will be used for PackageEvaluator.","category":"page"},{"location":"devdocs/build/distributing/#Checking-for-package-breakages","page":"Binary distributions","title":"Checking for package breakages","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Point releases should never break packages, with the possible exception of packages that are doing some seriously questionable hacks using Base internals that are not intended to be user-facing. (In those cases, maybe have a word with the package author.)","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Checking whether changes made in the forthcoming new version will break packages can be accomplished using PackageEvaluator, often called \"PkgEval\" for short. PkgEval is what populates the status badges on GitHub repos and on pkg.julialang.org. It typically runs on one of the non-benchmarking nodes of Nanosoldier and uses Vagrant to perform its duties in separate, parallel VirtualBox virtual machines.","category":"page"},{"location":"devdocs/build/distributing/#Setting-up-PackageEvaluator","page":"Binary distributions","title":"Setting up PackageEvaluator","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Clone PackageEvaluator and create a branch called backport-x.y.z, and check it out. Note that the required changes are a little hacky and confusing, and hopefully that will be addressed in a future version of PackageEvaluator. The changes to make will be modeled off of this commit.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"The setup script takes its first argument as the version of Julia to run and the second as the range of package names (AK for packages named A-K, LZ for L-Z). The basic idea is that we're going to tweak that a bit to run only two versions of Julia, the current x.y release and our backport version, each with three ranges of packages.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"In the linked diff, we're saying that if the second argument is LZ, use the binaries built from our backport branch, otherwise (AK) use the release binaries. Then we're using the first argument to run a section of the package list: A-F for input 0.4, G-N for 0.5, and O-Z for 0.6.","category":"page"},{"location":"devdocs/build/distributing/#Running-PackageEvaluator","page":"Binary distributions","title":"Running PackageEvaluator","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"To run PkgEval, find a hefty enough machine (such as Nanosoldier node 1), then run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git clone https://github.com/JuliaCI/PackageEvaluator.jl.git\ncd PackageEvaluator.jl/scripts\ngit checkout backport-x.y.z\n./runvagrant.sh","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This produces some folders in the scripts/ directory. The folder names and their contents are decoded below:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Folder name Julia version Package range\n0.4AK Release A-F\n0.4LZ Backport A-F\n0.5AK Release G-N\n0.5LZ Backport G-N\n0.6AK Release O-Z\n0.6LZ Backport O-Z","category":"page"},{"location":"devdocs/build/distributing/#Investigating-results","page":"Binary distributions","title":"Investigating results","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Once that's done, you can use ./summary.sh from that same directory to produce a summary report of the findings. We'll do so for each of the folders to aggregate overall results by version.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"./summary.sh 0.4AK/*.json > summary_release.txt\n./summary.sh 0.5AK/*.json >> summary_release.txt\n./summary.sh 0.6AK/*.json >> summary_release.txt\n./summary.sh 0.4LZ/*.json > summary_backport.txt\n./summary.sh 0.5LZ/*.json >> summary_backport.txt\n./summary.sh 0.6LZ/*.json >> summary_backport.txt","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Now we have two files, summary_release.txt and summary_backport.txt, containing the PackageEvaluator test results (pass/fail) for each package for the two versions.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"To make these easier to ingest into a Julia, we'll convert them into CSV files then use the DataFrames package to process the results. To convert to CSV, copy each .txt file to a corresponding .csv file, then enter Vim and execute ggVGI\" then :%s/\\.json /\",/g. (You don't have to use Vim; this just is one way to do it.) Now process the results with Julia code similar to the following.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"using DataFrames\n\nrelease = readtable(\"summary_release.csv\", header=false, names=[:package, :release])\nbackport = readtable(\"summary_backport.csv\", header=false, names=[:package, :backport])\n\nresults = join(release, backport, on=:package, kind=:outer)\n\nfor result in eachrow(results)\n a = result[:release]\n b = result[:backport]\n if (isna(a) && !isna(b)) || (isna(b) && !isna(a))\n color = :yellow\n elseif a != b && occursin(\"pass\", b)\n color = :green\n elseif a != b\n color = :red\n else\n continue\n end\n printstyled(result[:package], \": Release \", a, \" -> Backport \", b, \"\\n\", color=color)\nend","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This will write color-coded lines to stdout. All lines in red must be investigated as they signify potential breakages caused by the backport version. Lines in yellow should be looked into since it means a package ran on one version but not on the other for some reason. If you find that your backported branch is causing breakages, use git bisect to identify the problematic commits, git revert those commits, and repeat the process.","category":"page"},{"location":"devdocs/build/distributing/#Merging-backports-into-the-release-branch","page":"Binary distributions","title":"Merging backports into the release branch","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"After you have ensured that","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"the backported commits pass all of Julia's unit tests,\nthere are no performance regressions introduced by the backported commits as compared to the release branch, and\nthe backported commits do not break any registered packages,","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"then the backport branch is ready to be merged into release-x.y. Once it's merged, go through and remove the \"backport pending x.y\" label from all pull requests containing the commits that have been backported. Do not remove the label from PRs that have not been backported.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"The release-x.y branch should now contain all of the new commits. The last thing we want to do to the branch is to adjust the version number. To do this, submit a PR against release-x.y that edits the VERSION file to remove -pre from the version number. Once that's merged, we're ready to tag.","category":"page"},{"location":"devdocs/build/distributing/#Tagging-the-release","page":"Binary distributions","title":"Tagging the release","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"It's time! Check out the release-x.y branch and make sure that your local copy of the branch is up to date with the remote branch. At the command line, run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"git tag v$(cat VERSION)\ngit push --tags","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This creates the tag locally and pushes it to GitHub.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"After tagging the release, submit another PR to release-x.y to bump the patch number and add -pre back to the end. This denotes that the branch state reflects a prerelease version of the next point release in the x.y series.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Follow the remaining directions in the Makefile.","category":"page"},{"location":"devdocs/build/distributing/#Signing-binaries","page":"Binary distributions","title":"Signing binaries","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Some of these steps will require secure passwords. To obtain the appropriate passwords, contact Elliot Saba (staticfloat) or Alex Arslan (ararslan). Note that code signing for each platform must be performed on that platform (e.g. Windows signing must be done on Windows, etc.).","category":"page"},{"location":"devdocs/build/distributing/#Linux-2","page":"Binary distributions","title":"Linux","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Code signing must be done manually on Linux, but it's quite simple. First obtain the file julia.key from the CodeSigning folder in the juliasecure AWS bucket. Add this to your GnuPG keyring using","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"gpg --import julia.key","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This will require entering a password that you must obtain from Elliot or Alex. Next, set the trust level for the key to maximum. Start by entering a gpg session:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"gpg --edit-key julia","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"At the prompt, type trust, then when asked for a trust level, provide the maximum available (likely 5). Exit GnuPG.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Now, for each of the Linux tarballs that were built on the buildbots, enter","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"gpg -u julia --armor --detach-sig julia-x.y.z-linux-.tar.gz","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This will produce a corresponding .asc file for each tarball. And that's it!","category":"page"},{"location":"devdocs/build/distributing/#macOS","page":"Binary distributions","title":"macOS","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Code signing should happen automatically on the macOS buildbots. However, it's important to verify that it was successful. On a system or virtual machine running macOS, download the .dmg file that was built on the buildbots. For the sake of example, say that the .dmg file is called julia-x.y.z-osx.dmg. Run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"mkdir ./jlmnt\nhdiutil mount -readonly -mountpoint ./jlmnt julia-x.y.z-osx.dmg\ncodesign -v jlmnt/Julia-x.y.app","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Be sure to note the name of the mounted disk listed when mounting! For the sake of example, we'll assume this is disk3. If the code signing verification exited successfully, there will be no output from the codesign step. If it was indeed successful, you can detach the .dmg now:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"hdiutil eject /dev/disk3\nrm -rf ./jlmnt","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"If you get a message like","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia-x.y.app: code object is not signed at all","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"then you'll need to sign manually.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"To sign manually, first retrieve the OS X certificates from the CodeSigning folder in the juliasecure bucket on AWS. Add the .p12 file to your keychain using Keychain.app. Ask Elliot Saba (staticfloat) or Alex Arslan (ararslan) for the password for the key. Now run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"hdiutil convert julia-x.y.z-osx.dmg -format UDRW -o julia-x.y.z-osx_writable.dmg\nmkdir ./jlmnt\nhdiutil mount -mountpoint julia-x.y.z-osx_writable.dmg\ncodesign -s \"AFB379C0B4CBD9DB9A762797FC2AB5460A2B0DBE\" --deep jlmnt/Julia-x.y.app","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"This may fail with a message like","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Julia-x.y.app: resource fork, Finder information, or similar detritus not allowed","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"If that's the case, you'll need to remove extraneous attributes:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"xattr -cr jlmnt/Julia-x.y.app","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Then retry code signing. If that produces no errors, retry verification. If all is now well, unmount the writable .dmg and convert it back to read-only:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"hdiutil eject /dev/disk3\nrm -rf ./jlmnt\nhdiutil convert julia-x.y.z-osx_writable.dmg -format UDZO -o julia-x.y.z-osx_fixed.dmg","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Verify that the resulting .dmg is in fact fixed by double clicking it. If everything looks good, eject it then drop the _fixed suffix from the name. And that's it!","category":"page"},{"location":"devdocs/build/distributing/#Windows-2","page":"Binary distributions","title":"Windows","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Signing must be performed manually on Windows. First obtain the Windows 10 SDK, which contains the necessary signing utilities, from the Microsoft website. We need the SignTool utility which should have been installed somewhere like C:\\Program Files (x86)\\Windows Kits\\10\\App Certification Kit. Grab the Windows certificate files from CodeSigning on juliasecure and put them in the same directory as the executables. Open a Windows CMD window, cd to where all the files are, and run","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"set PATH=%PATH%;C:\\Program Files (x86)\\Windows Kits\\10\\App Certification Kit;\nsigntool sign /f julia-windows-code-sign_2017.p12 /p \"PASSWORD\" ^\n /t http://timestamp.verisign.com/scripts/timstamp.dll ^\n /v julia-x.y.z-win32.exe","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Note that ^ is a line continuation character in Windows CMD and PASSWORD is a placeholder for the password for this certificate. As usual, contact Elliot or Alex for passwords. If there are no errors, we're all good!","category":"page"},{"location":"devdocs/build/distributing/#Uploading-binaries","page":"Binary distributions","title":"Uploading binaries","text":"","category":"section"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Now that everything is signed, we need to upload the binaries to AWS. You can use a program like Cyberduck or the aws command line utility. The binaries should go in the julialang2 bucket in the appropriate folders. For example, Linux x86-64 goes in julialang2/bin/linux/x.y. Be sure to delete the current julia-x.y-latest-linux-.tar.gz file and replace it with a duplicate of julia-x.y.z-linux-.tar.gz.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"We also need to upload the checksums for everything we've built, including the source tarballs and all release binaries. This is simple:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"shasum -a 256 julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.sha256\nmd5sum julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.md5","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Note that if you're running those commands on macOS, you'll get very slightly different output, which can be reformatted by looking at an existing file. Mac users will also need to use md5 -r instead of md5sum. Upload the .md5 and .sha256 files to julialang2/bin/checksums on AWS.","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Ensure that the permissions on AWS for all uploaded files are set to \"Everyone: READ.\"","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"For each file we've uploaded, we need to purge the Fastly cache so that the links on the website point to the updated files. As an example:","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"curl -X PURGE https://julialang-s3.julialang.org/bin/checksums/julia-x.y.z.sha256","category":"page"},{"location":"devdocs/build/distributing/","page":"Binary distributions","title":"Binary distributions","text":"Sometimes this isn't necessary but it's good to do anyway.","category":"page"},{"location":"manual/workflow-tips/#man-workflow-tips","page":"Workflow Tips","title":"Workflow Tips","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Here are some tips for working with Julia efficiently.","category":"page"},{"location":"manual/workflow-tips/#REPL-based-workflow","page":"Workflow Tips","title":"REPL-based workflow","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"As already elaborated in The Julia REPL, Julia's REPL provides rich functionality that facilitates an efficient interactive workflow. Here are some tips that might further enhance your experience at the command line.","category":"page"},{"location":"manual/workflow-tips/#A-basic-editor/REPL-workflow","page":"Workflow Tips","title":"A basic editor/REPL workflow","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"The most basic Julia workflows involve using a text editor in conjunction with the julia command line.","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Create a file, say Tmp.jl, and include within it","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"module Tmp\n\nsay_hello() = println(\"Hello!\")\n\n# Your other definitions here\n\nend # module\n\nusing .Tmp","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Then, in the same directory, start the Julia REPL (using the julia command). Run the new file as follows:","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"julia> include(\"Tmp.jl\")\n\njulia> Tmp.say_hello()\nHello!","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Explore ideas in the REPL. Save good ideas in Tmp.jl. To reload the file after it has been changed, just include it again.","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"The key in the above is that your code is encapsulated in a module. That allows you to edit struct definitions and remove methods, without restarting Julia.","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"(Explanation: structs cannot be edited after definition, nor can methods be deleted. But you can overwrite the definition of a module, which is what we do when we re-include(\"Tmp.jl\")).","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"In addition, the encapsulation of code in a module protects it from being influenced by previous state in the REPL, protecting you from hard-to-detect errors.","category":"page"},{"location":"manual/workflow-tips/#Browser-based-workflow","page":"Workflow Tips","title":"Browser-based workflow","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"There are a few ways to interact with Julia in a browser:","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Using Pluto notebooks through Pluto.jl\nUsing Jupyter notebooks through IJulia.jl","category":"page"},{"location":"manual/workflow-tips/#Revise-based-workflows","page":"Workflow Tips","title":"Revise-based workflows","text":"","category":"section"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Whether you're at the REPL or in IJulia, you can typically improve your development experience with Revise. It is common to configure Revise to start whenever julia is started, as per the instructions in the Revise documentation. Once configured, Revise will track changes to files in any loaded modules, and to any files loaded in to the REPL with includet (but not with plain include); you can then edit the files and the changes take effect without restarting your julia session. A standard workflow is similar to the REPL-based workflow above, with the following modifications:","category":"page"},{"location":"manual/workflow-tips/","page":"Workflow Tips","title":"Workflow Tips","text":"Put your code in a module somewhere on your load path. There are several options for achieving this, of which two recommended choices are:\nFor long-term projects, use PkgTemplates:\nusing PkgTemplates\nt = Template()\nt(\"MyPkg\")\nThis will create a blank package, \"MyPkg\", in your .julia/dev directory. Note that PkgTemplates allows you to control many different options through its Template constructor.\nIn step 2 below, edit MyPkg/src/MyPkg.jl to change the source code, and MyPkg/test/runtests.jl for the tests.\nFor \"throw-away\" projects, you can avoid any need for cleanup by doing your work in your temporary directory (e.g., /tmp).\nNavigate to your temporary directory and launch Julia, then do the following:\npkg> generate MyPkg # type ] to enter pkg mode\njulia> push!(LOAD_PATH, pwd()) # hit backspace to exit pkg mode\nIf you restart your Julia session you'll have to re-issue that command modifying LOAD_PATH.\nIn step 2 below, edit MyPkg/src/MyPkg.jl to change the source code, and create any test file of your choosing.\nDevelop your package\nBefore loading any code, make sure you're running Revise: say using Revise or follow its documentation on configuring it to run automatically.\nThen navigate to the directory containing your test file (here assumed to be \"runtests.jl\") and do the following:\njulia> using MyPkg\n\njulia> include(\"runtests.jl\")\nYou can iteratively modify the code in MyPkg in your editor and re-run the tests with include(\"runtests.jl\"). You generally should not need to restart your Julia session to see the changes take effect (subject to a few limitations).","category":"page"},{"location":"stdlib/LazyArtifacts/#Lazy-Artifacts","page":"Lazy Artifacts","title":"Lazy Artifacts","text":"","category":"section"},{"location":"stdlib/LazyArtifacts/","page":"Lazy Artifacts","title":"Lazy Artifacts","text":"DocTestSetup = :(using LazyArtifacts)","category":"page"},{"location":"stdlib/LazyArtifacts/","page":"Lazy Artifacts","title":"Lazy Artifacts","text":"In order for a package to download artifacts lazily, LazyArtifacts must be explicitly listed as a dependency of that package.","category":"page"},{"location":"stdlib/LazyArtifacts/","page":"Lazy Artifacts","title":"Lazy Artifacts","text":"For further information on artifacts, see Artifacts.","category":"page"},{"location":"base/numbers/#lib-numbers","page":"Numbers","title":"Numbers","text":"","category":"section"},{"location":"base/numbers/#Standard-Numeric-Types","page":"Numbers","title":"Standard Numeric Types","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"A type tree for all subtypes of Number in Base is shown below. Abstract types have been marked, the rest are concrete types.","category":"page"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Number (Abstract Type)\n├─ Complex\n└─ Real (Abstract Type)\n ├─ AbstractFloat (Abstract Type)\n │ ├─ Float16\n │ ├─ Float32\n │ ├─ Float64\n │ └─ BigFloat\n ├─ Integer (Abstract Type)\n │ ├─ Bool\n │ ├─ Signed (Abstract Type)\n │ │ ├─ Int8\n │ │ ├─ Int16\n │ │ ├─ Int32\n │ │ ├─ Int64\n │ │ ├─ Int128\n │ │ └─ BigInt\n │ └─ Unsigned (Abstract Type)\n │ ├─ UInt8\n │ ├─ UInt16\n │ ├─ UInt32\n │ ├─ UInt64\n │ └─ UInt128\n ├─ Rational\n └─ AbstractIrrational (Abstract Type)\n └─ Irrational","category":"page"},{"location":"base/numbers/#Abstract-number-types","page":"Numbers","title":"Abstract number types","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Core.Number\nCore.Real\nCore.AbstractFloat\nCore.Integer\nCore.Signed\nCore.Unsigned\nBase.AbstractIrrational","category":"page"},{"location":"base/numbers/#Core.Number","page":"Numbers","title":"Core.Number","text":"Number\n\nAbstract supertype for all number types.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Real","page":"Numbers","title":"Core.Real","text":"Real <: Number\n\nAbstract supertype for all real numbers.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.AbstractFloat","page":"Numbers","title":"Core.AbstractFloat","text":"AbstractFloat <: Real\n\nAbstract supertype for all floating point numbers.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Integer","page":"Numbers","title":"Core.Integer","text":"Integer <: Real\n\nAbstract supertype for all integers (e.g. Signed, Unsigned, and Bool).\n\nSee also isinteger, trunc, div.\n\nExamples\n\njulia> 42 isa Integer\ntrue\n\njulia> 1.0 isa Integer\nfalse\n\njulia> isinteger(1.0)\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Signed","page":"Numbers","title":"Core.Signed","text":"Signed <: Integer\n\nAbstract supertype for all signed integers.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Unsigned","page":"Numbers","title":"Core.Unsigned","text":"Unsigned <: Integer\n\nAbstract supertype for all unsigned integers.\n\nBuilt-in unsigned integers are printed in hexadecimal, with prefix 0x, and can be entered in the same way.\n\nExamples\n\njulia> typemax(UInt8)\n0xff\n\njulia> Int(0x00d)\n13\n\njulia> unsigned(true)\n0x0000000000000001\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.AbstractIrrational","page":"Numbers","title":"Base.AbstractIrrational","text":"AbstractIrrational <: Real\n\nNumber type representing an exact irrational value, which is automatically rounded to the correct precision in arithmetic operations with other numeric quantities.\n\nSubtypes MyIrrational <: AbstractIrrational should implement at least ==(::MyIrrational, ::MyIrrational), hash(x::MyIrrational, h::UInt), and convert(::Type{F}, x::MyIrrational) where {F <: Union{BigFloat,Float32,Float64}}.\n\nIf a subtype is used to represent values that may occasionally be rational (e.g. a square-root type that represents √n for integers n will give a rational result when n is a perfect square), then it should also implement isinteger, iszero, isone, and == with Real values (since all of these default to false for AbstractIrrational types), as well as defining hash to equal that of the corresponding Rational.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Concrete-number-types","page":"Numbers","title":"Concrete number types","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Core.Float16\nCore.Float32\nCore.Float64\nBase.BigFloat\nCore.Bool\nCore.Int8\nCore.UInt8\nCore.Int16\nCore.UInt16\nCore.Int32\nCore.UInt32\nCore.Int64\nCore.UInt64\nCore.Int128\nCore.UInt128\nBase.Int\nBase.UInt\nBase.BigInt\nBase.Complex\nBase.Rational\nBase.Irrational","category":"page"},{"location":"base/numbers/#Core.Float16","page":"Numbers","title":"Core.Float16","text":"Float16 <: AbstractFloat <: Real\n\n16-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 5 exponent, 10 fraction bits.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Float32","page":"Numbers","title":"Core.Float32","text":"Float32 <: AbstractFloat <: Real\n\n32-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 8 exponent, 23 fraction bits.\n\nThe exponent for scientific notation should be entered as lower-case f, thus 2f3 === 2.0f0 * 10^3 === Float32(2_000). For array literals and comprehensions, the element type can be specified before the square brackets: Float32[1,4,9] == Float32[i^2 for i in 1:3].\n\nSee also Inf32, NaN32, Float16, exponent, frexp.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Float64","page":"Numbers","title":"Core.Float64","text":"Float64 <: AbstractFloat <: Real\n\n64-bit floating point number type (IEEE 754 standard). Binary format is 1 sign, 11 exponent, 52 fraction bits. See bitstring, signbit, exponent, frexp, and significand to access various bits.\n\nThis is the default for floating point literals, 1.0 isa Float64, and for many operations such as 1/2, 2pi, log(2), range(0,90,length=4). Unlike integers, this default does not change with Sys.WORD_SIZE.\n\nThe exponent for scientific notation can be entered as e or E, thus 2e3 === 2.0E3 === 2.0 * 10^3. Doing so is strongly preferred over 10^n because integers overflow, thus 2.0 * 10^19 < 0 but 2e19 > 0.\n\nSee also Inf, NaN, floatmax, Float32, Complex.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.MPFR.BigFloat","page":"Numbers","title":"Base.MPFR.BigFloat","text":"BigFloat <: AbstractFloat\n\nArbitrary precision floating point number type.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Bool","page":"Numbers","title":"Core.Bool","text":"Bool <: Integer\n\nBoolean type, containing the values true and false.\n\nBool is a kind of number: false is numerically equal to 0 and true is numerically equal to 1. Moreover, false acts as a multiplicative \"strong zero\" against NaN and Inf:\n\njulia> [true, false] == [1, 0]\ntrue\n\njulia> 42.0 + true\n43.0\n\njulia> 0 .* (NaN, Inf, -Inf)\n(NaN, NaN, NaN)\n\njulia> false .* (NaN, Inf, -Inf)\n(0.0, 0.0, -0.0)\n\nBranches via if and other conditionals only accept Bool. There are no \"truthy\" values in Julia.\n\nComparisons typically return Bool, and broadcasted comparisons may return BitArray instead of an Array{Bool}.\n\njulia> [1 2 3 4 5] .< pi\n1×5 BitMatrix:\n 1 1 1 0 0\n\njulia> map(>(pi), [1 2 3 4 5])\n1×5 Matrix{Bool}:\n 0 0 0 1 1\n\nSee also trues, falses, ifelse.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int8","page":"Numbers","title":"Core.Int8","text":"Int8 <: Signed <: Integer\n\n8-bit signed integer type.\n\nRepresents numbers n ∈ -128:127. Note that such integers overflow without warning, thus typemax(Int8) + Int8(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt8","page":"Numbers","title":"Core.UInt8","text":"UInt8 <: Unsigned <: Integer\n\n8-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x07 == 7.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int16","page":"Numbers","title":"Core.Int16","text":"Int16 <: Signed <: Integer\n\n16-bit signed integer type.\n\nRepresents numbers n ∈ -32768:32767. Note that such integers overflow without warning, thus typemax(Int16) + Int16(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt16","page":"Numbers","title":"Core.UInt16","text":"UInt16 <: Unsigned <: Integer\n\n16-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x000f == 15.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int32","page":"Numbers","title":"Core.Int32","text":"Int32 <: Signed <: Integer\n\n32-bit signed integer type.\n\nNote that such integers overflow without warning, thus typemax(Int32) + Int32(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt32","page":"Numbers","title":"Core.UInt32","text":"UInt32 <: Unsigned <: Integer\n\n32-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x0000001f == 31.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int64","page":"Numbers","title":"Core.Int64","text":"Int64 <: Signed <: Integer\n\n64-bit signed integer type.\n\nNote that such integers overflow without warning, thus typemax(Int64) + Int64(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt64","page":"Numbers","title":"Core.UInt64","text":"UInt64 <: Unsigned <: Integer\n\n64-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x000000000000003f == 63.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int128","page":"Numbers","title":"Core.Int128","text":"Int128 <: Signed <: Integer\n\n128-bit signed integer type.\n\nNote that such integers overflow without warning, thus typemax(Int128) + Int128(1) < 0.\n\nSee also Int, widen, BigInt.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt128","page":"Numbers","title":"Core.UInt128","text":"UInt128 <: Unsigned <: Integer\n\n128-bit unsigned integer type.\n\nPrinted in hexadecimal, thus 0x0000000000000000000000000000007f == 127.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.Int","page":"Numbers","title":"Core.Int","text":"Int\n\nSys.WORD_SIZE-bit signed integer type, Int <: Signed <: Integer <: Real.\n\nThis is the default type of most integer literals and is an alias for either Int32 or Int64, depending on Sys.WORD_SIZE. It is the type returned by functions such as length, and the standard type for indexing arrays.\n\nNote that integers overflow without warning, thus typemax(Int) + 1 < 0 and 10^19 < 0. Overflow can be avoided by using BigInt. Very large integer literals will use a wider type, for instance 10_000_000_000_000_000_000 isa Int128.\n\nInteger division is div alias ÷, whereas / acting on integers returns Float64.\n\nSee also Int64, widen, typemax, bitstring.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Core.UInt","page":"Numbers","title":"Core.UInt","text":"UInt\n\nSys.WORD_SIZE-bit unsigned integer type, UInt <: Unsigned <: Integer.\n\nLike Int, the alias UInt may point to either UInt32 or UInt64, according to the value of Sys.WORD_SIZE on a given computer.\n\nPrinted and parsed in hexadecimal: UInt(15) === 0x000000000000000f.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.GMP.BigInt","page":"Numbers","title":"Base.GMP.BigInt","text":"BigInt <: Signed\n\nArbitrary precision integer type.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.Complex","page":"Numbers","title":"Base.Complex","text":"Complex{T<:Real} <: Number\n\nComplex number type with real and imaginary part of type T.\n\nComplexF16, ComplexF32 and ComplexF64 are aliases for Complex{Float16}, Complex{Float32} and Complex{Float64} respectively.\n\nSee also: Real, complex, real.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.Rational","page":"Numbers","title":"Base.Rational","text":"Rational{T<:Integer} <: Real\n\nRational number type, with numerator and denominator of type T. Rationals are checked for overflow.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Base.Irrational","page":"Numbers","title":"Base.Irrational","text":"Irrational{sym} <: AbstractIrrational\n\nNumber type representing an exact irrational value denoted by the symbol sym, such as π, ℯ and γ.\n\nSee also AbstractIrrational.\n\n\n\n\n\n","category":"type"},{"location":"base/numbers/#Data-Formats","page":"Numbers","title":"Data Formats","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Base.digits\nBase.digits!\nBase.bitstring\nBase.parse\nBase.tryparse\nBase.big\nBase.signed\nBase.unsigned\nBase.float(::Any)\nBase.Math.significand\nBase.Math.exponent\nBase.complex(::Complex)\nBase.bswap\nBase.hex2bytes\nBase.hex2bytes!\nBase.bytes2hex","category":"page"},{"location":"base/numbers/#Base.digits","page":"Numbers","title":"Base.digits","text":"digits([T<:Integer], n::Integer; base::T = 10, pad::Integer = 1)\n\nReturn an array with element type T (default Int) of the digits of n in the given base, optionally padded with zeros to a specified size. More significant digits are at higher indices, such that n == sum(digits[k]*base^(k-1) for k=1:length(digits)).\n\nSee also ndigits, digits!, and for base 2 also bitstring, count_ones.\n\nExamples\n\njulia> digits(10)\n2-element Vector{Int64}:\n 0\n 1\n\njulia> digits(10, base = 2)\n4-element Vector{Int64}:\n 0\n 1\n 0\n 1\n\njulia> digits(-256, base = 10, pad = 5)\n5-element Vector{Int64}:\n -6\n -5\n -2\n 0\n 0\n\njulia> n = rand(-999:999);\n\njulia> n == evalpoly(13, digits(n, base = 13))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.digits!","page":"Numbers","title":"Base.digits!","text":"digits!(array, n::Integer; base::Integer = 10)\n\nFills an array of the digits of n in the given base. More significant digits are at higher indices. If the array length is insufficient, the least significant digits are filled up to the array length. If the array length is excessive, the excess portion is filled with zeros.\n\nExamples\n\njulia> digits!([2, 2, 2, 2], 10, base = 2)\n4-element Vector{Int64}:\n 0\n 1\n 0\n 1\n\njulia> digits!([2, 2, 2, 2, 2, 2], 10, base = 2)\n6-element Vector{Int64}:\n 0\n 1\n 0\n 1\n 0\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.bitstring","page":"Numbers","title":"Base.bitstring","text":"bitstring(n)\n\nA string giving the literal bit representation of a primitive type.\n\nSee also count_ones, count_zeros, digits.\n\nExamples\n\njulia> bitstring(Int32(4))\n\"00000000000000000000000000000100\"\n\njulia> bitstring(2.2)\n\"0100000000000001100110011001100110011001100110011001100110011010\"\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.parse","page":"Numbers","title":"Base.parse","text":"parse(::Type{SimpleColor}, rgb::String)\n\nAn analogue of tryparse(SimpleColor, rgb::String) (which see), that raises an error instead of returning nothing.\n\n\n\n\n\nparse(::Type{Platform}, triplet::AbstractString)\n\nParses a string platform triplet back into a Platform object.\n\n\n\n\n\nparse(type, str; base)\n\nParse a string as a number. For Integer types, a base can be specified (the default is 10). For floating-point types, the string is parsed as a decimal floating-point number. Complex types are parsed from decimal strings of the form \"R±Iim\" as a Complex(R,I) of the requested type; \"i\" or \"j\" can also be used instead of \"im\", and \"R\" or \"Iim\" are also permitted. If the string does not contain a valid number, an error is raised.\n\ncompat: Julia 1.1\nparse(Bool, str) requires at least Julia 1.1.\n\nExamples\n\njulia> parse(Int, \"1234\")\n1234\n\njulia> parse(Int, \"1234\", base = 5)\n194\n\njulia> parse(Int, \"afc\", base = 16)\n2812\n\njulia> parse(Float64, \"1.2e-3\")\n0.0012\n\njulia> parse(Complex{Float64}, \"3.2e-1 + 4.5im\")\n0.32 + 4.5im\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.tryparse","page":"Numbers","title":"Base.tryparse","text":"tryparse(::Type{SimpleColor}, rgb::String)\n\nAttempt to parse rgb as a SimpleColor. If rgb starts with # and has a length of 7, it is converted into a RGBTuple-backed SimpleColor. If rgb starts with a-z, rgb is interpreted as a color name and converted to a Symbol-backed SimpleColor.\n\nOtherwise, nothing is returned.\n\nExamples\n\njulia> tryparse(SimpleColor, \"blue\")\nSimpleColor(blue)\n\njulia> tryparse(SimpleColor, \"#9558b2\")\nSimpleColor(#9558b2)\n\njulia> tryparse(SimpleColor, \"#nocolor\")\n\n\n\n\n\ntryparse(type, str; base)\n\nLike parse, but returns either a value of the requested type, or nothing if the string does not contain a valid number.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.big","page":"Numbers","title":"Base.big","text":"big(x)\n\nConvert a number to a maximum precision representation (typically BigInt or BigFloat). See BigFloat for information about some pitfalls with floating-point numbers.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.signed","page":"Numbers","title":"Base.signed","text":"signed(T::Integer)\n\nConvert an integer bitstype to the signed type of the same size.\n\nExamples\n\njulia> signed(UInt16)\nInt16\njulia> signed(UInt64)\nInt64\n\n\n\n\n\nsigned(x)\n\nConvert a number to a signed integer. If the argument is unsigned, it is reinterpreted as signed without checking for overflow.\n\nSee also: unsigned, sign, signbit.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.unsigned","page":"Numbers","title":"Base.unsigned","text":"unsigned(T::Integer)\n\nConvert an integer bitstype to the unsigned type of the same size.\n\nExamples\n\njulia> unsigned(Int16)\nUInt16\njulia> unsigned(UInt64)\nUInt64\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.float-Tuple{Any}","page":"Numbers","title":"Base.float","text":"float(x)\n\nConvert a number or array to a floating point data type.\n\nSee also: complex, oftype, convert.\n\nExamples\n\njulia> float(1:1000)\n1.0:1.0:1000.0\n\njulia> float(typemax(Int32))\n2.147483647e9\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.Math.significand","page":"Numbers","title":"Base.Math.significand","text":"significand(x)\n\nExtract the significand (a.k.a. mantissa) of a floating-point number. If x is a non-zero finite number, then the result will be a number of the same type and sign as x, and whose absolute value is on the interval 12). Otherwise x is returned.\n\nSee also frexp, exponent.\n\nExamples\n\njulia> significand(15.2)\n1.9\n\njulia> significand(-15.2)\n-1.9\n\njulia> significand(-15.2) * 2^3\n-15.2\n\njulia> significand(-Inf), significand(Inf), significand(NaN)\n(-Inf, Inf, NaN)\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.Math.exponent","page":"Numbers","title":"Base.Math.exponent","text":"exponent(x::Real) -> Int\n\nReturn the largest integer y such that 2^y ≤ abs(x). For a normalized floating-point number x, this corresponds to the exponent of x.\n\nThrows a DomainError when x is zero, infinite, or NaN. For any other non-subnormal floating-point number x, this corresponds to the exponent bits of x.\n\nSee also signbit, significand, frexp, issubnormal, log2, ldexp.\n\nExamples\n\njulia> exponent(8)\n3\n\njulia> exponent(6.5)\n2\n\njulia> exponent(-1//4)\n-2\n\njulia> exponent(3.142e-4)\n-12\n\njulia> exponent(floatmin(Float32)), exponent(nextfloat(0.0f0))\n(-126, -149)\n\njulia> exponent(0.0)\nERROR: DomainError with 0.0:\nCannot be ±0.0.\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.complex-Tuple{Complex}","page":"Numbers","title":"Base.complex","text":"complex(r, [i])\n\nConvert real numbers or arrays to complex. i defaults to zero.\n\nExamples\n\njulia> complex(7)\n7 + 0im\n\njulia> complex([1, 2, 3])\n3-element Vector{Complex{Int64}}:\n 1 + 0im\n 2 + 0im\n 3 + 0im\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.bswap","page":"Numbers","title":"Base.bswap","text":"bswap(n)\n\nReverse the byte order of n.\n\n(See also ntoh and hton to convert between the current native byte order and big-endian order.)\n\nExamples\n\njulia> a = bswap(0x10203040)\n0x40302010\n\njulia> bswap(a)\n0x10203040\n\njulia> string(1, base = 2)\n\"1\"\n\njulia> string(bswap(1), base = 2)\n\"100000000000000000000000000000000000000000000000000000000\"\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.hex2bytes","page":"Numbers","title":"Base.hex2bytes","text":"hex2bytes(itr)\n\nGiven an iterable itr of ASCII codes for a sequence of hexadecimal digits, returns a Vector{UInt8} of bytes corresponding to the binary representation: each successive pair of hexadecimal digits in itr gives the value of one byte in the return vector.\n\nThe length of itr must be even, and the returned array has half of the length of itr. See also hex2bytes! for an in-place version, and bytes2hex for the inverse.\n\ncompat: Julia 1.7\nCalling hex2bytes with iterators producing UInt8 values requires Julia 1.7 or later. In earlier versions, you can collect the iterator before calling hex2bytes.\n\nExamples\n\njulia> s = string(12345, base = 16)\n\"3039\"\n\njulia> hex2bytes(s)\n2-element Vector{UInt8}:\n 0x30\n 0x39\n\njulia> a = b\"01abEF\"\n6-element Base.CodeUnits{UInt8, String}:\n 0x30\n 0x31\n 0x61\n 0x62\n 0x45\n 0x46\n\njulia> hex2bytes(a)\n3-element Vector{UInt8}:\n 0x01\n 0xab\n 0xef\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.hex2bytes!","page":"Numbers","title":"Base.hex2bytes!","text":"hex2bytes!(dest::AbstractVector{UInt8}, itr)\n\nConvert an iterable itr of bytes representing a hexadecimal string to its binary representation, similar to hex2bytes except that the output is written in-place to dest. The length of dest must be half the length of itr.\n\ncompat: Julia 1.7\nCalling hex2bytes! with iterators producing UInt8 requires version 1.7. In earlier versions, you can collect the iterable before calling instead.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.bytes2hex","page":"Numbers","title":"Base.bytes2hex","text":"bytes2hex(itr) -> String\nbytes2hex(io::IO, itr)\n\nConvert an iterator itr of bytes to its hexadecimal string representation, either returning a String via bytes2hex(itr) or writing the string to an io stream via bytes2hex(io, itr). The hexadecimal characters are all lowercase.\n\ncompat: Julia 1.7\nCalling bytes2hex with arbitrary iterators producing UInt8 values requires Julia 1.7 or later. In earlier versions, you can collect the iterator before calling bytes2hex.\n\nExamples\n\njulia> a = string(12345, base = 16)\n\"3039\"\n\njulia> b = hex2bytes(a)\n2-element Vector{UInt8}:\n 0x30\n 0x39\n\njulia> bytes2hex(b)\n\"3039\"\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#General-Number-Functions-and-Constants","page":"Numbers","title":"General Number Functions and Constants","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Base.one\nBase.oneunit\nBase.zero\nBase.im\nBase.MathConstants.pi\nBase.MathConstants.ℯ\nBase.MathConstants.catalan\nBase.MathConstants.eulergamma\nBase.MathConstants.golden\nBase.Inf\nBase.Inf64\nBase.Inf32\nBase.Inf16\nBase.NaN\nBase.NaN64\nBase.NaN32\nBase.NaN16\nBase.issubnormal\nBase.isfinite\nBase.isinf\nBase.isnan\nBase.iszero\nBase.isone\nBase.nextfloat\nBase.prevfloat\nBase.isinteger\nBase.isreal\nCore.Float32(::Any)\nCore.Float64(::Any)\nBase.Rounding.rounding\nBase.Rounding.setrounding(::Type, ::Any)\nBase.Rounding.setrounding(::Function, ::Type, ::RoundingMode)\nBase.Rounding.get_zero_subnormals\nBase.Rounding.set_zero_subnormals","category":"page"},{"location":"base/numbers/#Base.one","page":"Numbers","title":"Base.one","text":"one(x)\none(T::type)\n\nReturn a multiplicative identity for x: a value such that one(x)*x == x*one(x) == x. If the multiplicative identity can be deduced from the type alone, then a type may be given as an argument to one (e.g. one(Int) will work because the multiplicative identity is the same for all instances of Int, but one(Matrix{Int}) is not defined because matrices of different shapes have different multiplicative identities.)\n\nIf possible, one(x) returns a value of the same type as x, and one(T) returns a value of type T. However, this may not be the case for types representing dimensionful quantities (e.g. time in days), since the multiplicative identity must be dimensionless. In that case, one(x) should return an identity value of the same precision (and shape, for matrices) as x.\n\nIf you want a quantity that is of the same type as x, or of type T, even if x is dimensionful, use oneunit instead.\n\nSee also the identity function, and I in LinearAlgebra for the identity matrix.\n\nExamples\n\njulia> one(3.7)\n1.0\n\njulia> one(Int)\n1\n\njulia> import Dates; one(Dates.Day(1))\n1\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.oneunit","page":"Numbers","title":"Base.oneunit","text":"oneunit(x::T)\noneunit(T::Type)\n\nReturn T(one(x)), where T is either the type of the argument, or the argument itself in cases where the oneunit can be deduced from the type alone. This differs from one for dimensionful quantities: one is dimensionless (a multiplicative identity) while oneunit is dimensionful (of the same type as x, or of type T).\n\nExamples\n\njulia> oneunit(3.7)\n1.0\n\njulia> import Dates; oneunit(Dates.Day)\n1 day\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.zero","page":"Numbers","title":"Base.zero","text":"zero(x)\nzero(::Type)\n\nGet the additive identity element for x. If the additive identity can be deduced from the type alone, then a type may be given as an argument to zero.\n\nFor example, zero(Int) will work because the additive identity is the same for all instances of Int, but zero(Vector{Int}) is not defined because vectors of different lengths have different additive identities.\n\nSee also iszero, one, oneunit, oftype.\n\nExamples\n\njulia> zero(1)\n0\n\njulia> zero(big\"2.0\")\n0.0\n\njulia> zero(rand(2,2))\n2×2 Matrix{Float64}:\n 0.0 0.0\n 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.im","page":"Numbers","title":"Base.im","text":"im\n\nThe imaginary unit.\n\nSee also: imag, angle, complex.\n\nExamples\n\njulia> im * im\n-1 + 0im\n\njulia> (2.0 + 3im)^2\n-5.0 + 12.0im\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.pi","page":"Numbers","title":"Base.MathConstants.pi","text":"π\npi\n\nThe constant pi.\n\nUnicode π can be typed by writing \\pi then pressing tab in the Julia REPL, and in many editors.\n\nSee also: sinpi, sincospi, deg2rad.\n\nExamples\n\njulia> pi\nπ = 3.1415926535897...\n\njulia> 1/2pi\n0.15915494309189535\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.ℯ","page":"Numbers","title":"Base.MathConstants.ℯ","text":"ℯ\ne\n\nThe constant ℯ.\n\nUnicode ℯ can be typed by writing \\euler and pressing tab in the Julia REPL, and in many editors.\n\nSee also: exp, cis, cispi.\n\nExamples\n\njulia> ℯ\nℯ = 2.7182818284590...\n\njulia> log(ℯ)\n1\n\njulia> ℯ^(im)π ≈ -1\ntrue\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.catalan","page":"Numbers","title":"Base.MathConstants.catalan","text":"catalan\n\nCatalan's constant.\n\nExamples\n\njulia> Base.MathConstants.catalan\ncatalan = 0.9159655941772...\n\njulia> sum(log(x)/(1+x^2) for x in 1:0.01:10^6) * 0.01\n0.9159466120554123\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.eulergamma","page":"Numbers","title":"Base.MathConstants.eulergamma","text":"γ\neulergamma\n\nEuler's constant.\n\nExamples\n\njulia> Base.MathConstants.eulergamma\nγ = 0.5772156649015...\n\njulia> dx = 10^-6;\n\njulia> sum(-exp(-x) * log(x) for x in dx:dx:100) * dx\n0.5772078382499133\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.MathConstants.golden","page":"Numbers","title":"Base.MathConstants.golden","text":"φ\ngolden\n\nThe golden ratio.\n\nExamples\n\njulia> Base.MathConstants.golden\nφ = 1.6180339887498...\n\njulia> (2ans - 1)^2 ≈ 5\ntrue\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.Inf","page":"Numbers","title":"Base.Inf","text":"Inf, Inf64\n\nPositive infinity of type Float64.\n\nSee also: isfinite, typemax, NaN, Inf32.\n\nExamples\n\njulia> π/0\nInf\n\njulia> +1.0 / -0.0\n-Inf\n\njulia> ℯ^-Inf\n0.0\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.Inf64","page":"Numbers","title":"Base.Inf64","text":"Inf, Inf64\n\nPositive infinity of type Float64.\n\nSee also: isfinite, typemax, NaN, Inf32.\n\nExamples\n\njulia> π/0\nInf\n\njulia> +1.0 / -0.0\n-Inf\n\njulia> ℯ^-Inf\n0.0\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.Inf32","page":"Numbers","title":"Base.Inf32","text":"Inf32\n\nPositive infinity of type Float32.\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.Inf16","page":"Numbers","title":"Base.Inf16","text":"Inf16\n\nPositive infinity of type Float16.\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.NaN","page":"Numbers","title":"Base.NaN","text":"NaN, NaN64\n\nA not-a-number value of type Float64.\n\nSee also: isnan, missing, NaN32, Inf.\n\nExamples\n\njulia> 0/0\nNaN\n\njulia> Inf - Inf\nNaN\n\njulia> NaN == NaN, isequal(NaN, NaN), isnan(NaN)\n(false, true, true)\n\nnote: Note\nAlways use isnan or isequal for checking for NaN. Using x === NaN may give unexpected results:julia> reinterpret(UInt32, NaN32)\n0x7fc00000\n\njulia> NaN32p1 = reinterpret(Float32, 0x7fc00001)\nNaN32\n\njulia> NaN32p1 === NaN32, isequal(NaN32p1, NaN32), isnan(NaN32p1)\n(false, true, true)\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.NaN64","page":"Numbers","title":"Base.NaN64","text":"NaN, NaN64\n\nA not-a-number value of type Float64.\n\nSee also: isnan, missing, NaN32, Inf.\n\nExamples\n\njulia> 0/0\nNaN\n\njulia> Inf - Inf\nNaN\n\njulia> NaN == NaN, isequal(NaN, NaN), isnan(NaN)\n(false, true, true)\n\nnote: Note\nAlways use isnan or isequal for checking for NaN. Using x === NaN may give unexpected results:julia> reinterpret(UInt32, NaN32)\n0x7fc00000\n\njulia> NaN32p1 = reinterpret(Float32, 0x7fc00001)\nNaN32\n\njulia> NaN32p1 === NaN32, isequal(NaN32p1, NaN32), isnan(NaN32p1)\n(false, true, true)\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.NaN32","page":"Numbers","title":"Base.NaN32","text":"NaN32\n\nA not-a-number value of type Float32.\n\nSee also: NaN.\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.NaN16","page":"Numbers","title":"Base.NaN16","text":"NaN16\n\nA not-a-number value of type Float16.\n\nSee also: NaN.\n\n\n\n\n\n","category":"constant"},{"location":"base/numbers/#Base.issubnormal","page":"Numbers","title":"Base.issubnormal","text":"issubnormal(f) -> Bool\n\nTest whether a floating point number is subnormal.\n\nAn IEEE floating point number is subnormal when its exponent bits are zero and its significand is not zero.\n\nExamples\n\njulia> floatmin(Float32)\n1.1754944f-38\n\njulia> issubnormal(1.0f-37)\nfalse\n\njulia> issubnormal(1.0f-38)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isfinite","page":"Numbers","title":"Base.isfinite","text":"isfinite(f) -> Bool\n\nTest whether a number is finite.\n\nExamples\n\njulia> isfinite(5)\ntrue\n\njulia> isfinite(NaN32)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isinf","page":"Numbers","title":"Base.isinf","text":"isinf(f) -> Bool\n\nTest whether a number is infinite.\n\nSee also: Inf, iszero, isfinite, isnan.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isnan","page":"Numbers","title":"Base.isnan","text":"isnan(f) -> Bool\n\nTest whether a number value is a NaN, an indeterminate value which is neither an infinity nor a finite number (\"not a number\").\n\nSee also: iszero, isone, isinf, ismissing.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.iszero","page":"Numbers","title":"Base.iszero","text":"iszero(x)\n\nReturn true if x == zero(x); if x is an array, this checks whether all of the elements of x are zero.\n\nSee also: isone, isinteger, isfinite, isnan.\n\nExamples\n\njulia> iszero(0.0)\ntrue\n\njulia> iszero([1, 9, 0])\nfalse\n\njulia> iszero([false, 0, 0])\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isone","page":"Numbers","title":"Base.isone","text":"isone(x)\n\nReturn true if x == one(x); if x is an array, this checks whether x is an identity matrix.\n\nExamples\n\njulia> isone(1.0)\ntrue\n\njulia> isone([1 0; 0 2])\nfalse\n\njulia> isone([1 0; 0 true])\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.nextfloat","page":"Numbers","title":"Base.nextfloat","text":"nextfloat(x::AbstractFloat, n::Integer)\n\nThe result of n iterative applications of nextfloat to x if n >= 0, or -n applications of prevfloat if n < 0.\n\n\n\n\n\nnextfloat(x::AbstractFloat)\n\nReturn the smallest floating point number y of the same type as x such x < y. If no such y exists (e.g. if x is Inf or NaN), then return x.\n\nSee also: prevfloat, eps, issubnormal.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.prevfloat","page":"Numbers","title":"Base.prevfloat","text":"prevfloat(x::AbstractFloat, n::Integer)\n\nThe result of n iterative applications of prevfloat to x if n >= 0, or -n applications of nextfloat if n < 0.\n\n\n\n\n\nprevfloat(x::AbstractFloat)\n\nReturn the largest floating point number y of the same type as x such y < x. If no such y exists (e.g. if x is -Inf or NaN), then return x.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isinteger","page":"Numbers","title":"Base.isinteger","text":"isinteger(x) -> Bool\n\nTest whether x is numerically equal to some integer.\n\nExamples\n\njulia> isinteger(4.0)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isreal","page":"Numbers","title":"Base.isreal","text":"isreal(x) -> Bool\n\nTest whether x or all its elements are numerically equal to some real number including infinities and NaNs. isreal(x) is true if isequal(x, real(x)) is true.\n\nExamples\n\njulia> isreal(5.)\ntrue\n\njulia> isreal(1 - 3im)\nfalse\n\njulia> isreal(Inf + 0im)\ntrue\n\njulia> isreal([4.; complex(0,1)])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Core.Float32-Tuple{Any}","page":"Numbers","title":"Core.Float32","text":"Float32(x [, mode::RoundingMode])\n\nCreate a Float32 from x. If x is not exactly representable then mode determines how x is rounded.\n\nExamples\n\njulia> Float32(1/3, RoundDown)\n0.3333333f0\n\njulia> Float32(1/3, RoundUp)\n0.33333334f0\n\nSee RoundingMode for available rounding modes.\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Core.Float64-Tuple{Any}","page":"Numbers","title":"Core.Float64","text":"Float64(x [, mode::RoundingMode])\n\nCreate a Float64 from x. If x is not exactly representable then mode determines how x is rounded.\n\nExamples\n\njulia> Float64(pi, RoundDown)\n3.141592653589793\n\njulia> Float64(pi, RoundUp)\n3.1415926535897936\n\nSee RoundingMode for available rounding modes.\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.Rounding.rounding","page":"Numbers","title":"Base.Rounding.rounding","text":"rounding(T)\n\nGet the current floating point rounding mode for type T, controlling the rounding of basic arithmetic functions (+, -, *, / and sqrt) and type conversion.\n\nSee RoundingMode for available modes.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.Rounding.setrounding-Tuple{Type, Any}","page":"Numbers","title":"Base.Rounding.setrounding","text":"setrounding(T, mode)\n\nSet the rounding mode of floating point type T, controlling the rounding of basic arithmetic functions (+, -, *, / and sqrt) and type conversion. Other numerical functions may give incorrect or invalid values when using rounding modes other than the default RoundNearest.\n\nNote that this is currently only supported for T == BigFloat.\n\nwarning: Warning\nThis function is not thread-safe. It will affect code running on all threads, but its behavior is undefined if called concurrently with computations that use the setting.\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.Rounding.setrounding-Tuple{Function, Type, RoundingMode}","page":"Numbers","title":"Base.Rounding.setrounding","text":"setrounding(f::Function, T, mode)\n\nChange the rounding mode of floating point type T for the duration of f. It is logically equivalent to:\n\nold = rounding(T)\nsetrounding(T, mode)\nf()\nsetrounding(T, old)\n\nSee RoundingMode for available rounding modes.\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.Rounding.get_zero_subnormals","page":"Numbers","title":"Base.Rounding.get_zero_subnormals","text":"get_zero_subnormals() -> Bool\n\nReturn false if operations on subnormal floating-point values (\"denormals\") obey rules for IEEE arithmetic, and true if they might be converted to zeros.\n\nwarning: Warning\nThis function only affects the current thread.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.Rounding.set_zero_subnormals","page":"Numbers","title":"Base.Rounding.set_zero_subnormals","text":"set_zero_subnormals(yes::Bool) -> Bool\n\nIf yes is false, subsequent floating-point operations follow rules for IEEE arithmetic on subnormal values (\"denormals\"). Otherwise, floating-point operations are permitted (but not required) to convert subnormal inputs or outputs to zero. Returns true unless yes==true but the hardware does not support zeroing of subnormal numbers.\n\nset_zero_subnormals(true) can speed up some computations on some hardware. However, it can break identities such as (x-y==0) == (x==y).\n\nwarning: Warning\nThis function only affects the current thread.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Integers","page":"Numbers","title":"Integers","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Base.count_ones\nBase.count_zeros\nBase.leading_zeros\nBase.leading_ones\nBase.trailing_zeros\nBase.trailing_ones\nBase.isodd\nBase.iseven\nBase.@int128_str\nBase.@uint128_str","category":"page"},{"location":"base/numbers/#Base.count_ones","page":"Numbers","title":"Base.count_ones","text":"count_ones(x::Integer) -> Integer\n\nNumber of ones in the binary representation of x.\n\nExamples\n\njulia> count_ones(7)\n3\n\njulia> count_ones(Int32(-1))\n32\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.count_zeros","page":"Numbers","title":"Base.count_zeros","text":"count_zeros(x::Integer) -> Integer\n\nNumber of zeros in the binary representation of x.\n\nExamples\n\njulia> count_zeros(Int32(2 ^ 16 - 1))\n16\n\njulia> count_zeros(-1)\n0\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.leading_zeros","page":"Numbers","title":"Base.leading_zeros","text":"leading_zeros(x::Integer) -> Integer\n\nNumber of zeros leading the binary representation of x.\n\nExamples\n\njulia> leading_zeros(Int32(1))\n31\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.leading_ones","page":"Numbers","title":"Base.leading_ones","text":"leading_ones(x::Integer) -> Integer\n\nNumber of ones leading the binary representation of x.\n\nExamples\n\njulia> leading_ones(UInt32(2 ^ 32 - 2))\n31\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.trailing_zeros","page":"Numbers","title":"Base.trailing_zeros","text":"trailing_zeros(x::Integer) -> Integer\n\nNumber of zeros trailing the binary representation of x.\n\nExamples\n\njulia> trailing_zeros(2)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.trailing_ones","page":"Numbers","title":"Base.trailing_ones","text":"trailing_ones(x::Integer) -> Integer\n\nNumber of ones trailing the binary representation of x.\n\nExamples\n\njulia> trailing_ones(3)\n2\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.isodd","page":"Numbers","title":"Base.isodd","text":"isodd(x::Number) -> Bool\n\nReturn true if x is an odd integer (that is, an integer not divisible by 2), and false otherwise.\n\ncompat: Julia 1.7\nNon-Integer arguments require Julia 1.7 or later.\n\nExamples\n\njulia> isodd(9)\ntrue\n\njulia> isodd(10)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.iseven","page":"Numbers","title":"Base.iseven","text":"iseven(x::Number) -> Bool\n\nReturn true if x is an even integer (that is, an integer divisible by 2), and false otherwise.\n\ncompat: Julia 1.7\nNon-Integer arguments require Julia 1.7 or later.\n\nExamples\n\njulia> iseven(9)\nfalse\n\njulia> iseven(10)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Core.@int128_str","page":"Numbers","title":"Core.@int128_str","text":"@int128_str str\n\nParse str as an Int128. Throw an ArgumentError if the string is not a valid integer.\n\nExamples\n\njulia> int128\"123456789123\"\n123456789123\n\njulia> int128\"123456789123.4\"\nERROR: LoadError: ArgumentError: invalid base 10 digit '.' in \"123456789123.4\"\n[...]\n\n\n\n\n\n","category":"macro"},{"location":"base/numbers/#Core.@uint128_str","page":"Numbers","title":"Core.@uint128_str","text":"@uint128_str str\n\nParse str as an UInt128. Throw an ArgumentError if the string is not a valid integer.\n\nExamples\n\njulia> uint128\"123456789123\"\n0x00000000000000000000001cbe991a83\n\njulia> uint128\"-123456789123\"\nERROR: LoadError: ArgumentError: invalid base 10 digit '-' in \"-123456789123\"\n[...]\n\n\n\n\n\n","category":"macro"},{"location":"base/numbers/#BigFloats-and-BigInts","page":"Numbers","title":"BigFloats and BigInts","text":"","category":"section"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"The BigFloat and BigInt types implements arbitrary-precision floating point and integer arithmetic, respectively. For BigFloat the GNU MPFR library is used, and for BigInt the GNU Multiple Precision Arithmetic Library (GMP) is used.","category":"page"},{"location":"base/numbers/","page":"Numbers","title":"Numbers","text":"Base.MPFR.BigFloat(::Any, rounding::RoundingMode)\nBase.precision\nBase.MPFR.setprecision\nBase.GMP.BigInt(::Any)\nBase.@big_str","category":"page"},{"location":"base/numbers/#Base.MPFR.BigFloat-Tuple{Any, RoundingMode}","page":"Numbers","title":"Base.MPFR.BigFloat","text":"BigFloat(x::Union{Real, AbstractString} [, rounding::RoundingMode=rounding(BigFloat)]; [precision::Integer=precision(BigFloat)])\n\nCreate an arbitrary precision floating point number from x, with precision precision. The rounding argument specifies the direction in which the result should be rounded if the conversion cannot be done exactly. If not provided, these are set by the current global values.\n\nBigFloat(x::Real) is the same as convert(BigFloat,x), except if x itself is already BigFloat, in which case it will return a value with the precision set to the current global precision; convert will always return x.\n\nBigFloat(x::AbstractString) is identical to parse. This is provided for convenience since decimal literals are converted to Float64 when parsed, so BigFloat(2.1) may not yield what you expect.\n\nSee also:\n\n@big_str\nrounding and setrounding\nprecision and setprecision\n\ncompat: Julia 1.1\nprecision as a keyword argument requires at least Julia 1.1. In Julia 1.0 precision is the second positional argument (BigFloat(x, precision)).\n\nExamples\n\njulia> BigFloat(2.1) # 2.1 here is a Float64\n2.100000000000000088817841970012523233890533447265625\n\njulia> BigFloat(\"2.1\") # the closest BigFloat to 2.1\n2.099999999999999999999999999999999999999999999999999999999999999999999999999986\n\njulia> BigFloat(\"2.1\", RoundUp)\n2.100000000000000000000000000000000000000000000000000000000000000000000000000021\n\njulia> BigFloat(\"2.1\", RoundUp, precision=128)\n2.100000000000000000000000000000000000007\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Base.precision","page":"Numbers","title":"Base.precision","text":"precision(num::AbstractFloat; base::Integer=2)\nprecision(T::Type; base::Integer=2)\n\nGet the precision of a floating point number, as defined by the effective number of bits in the significand, or the precision of a floating-point type T (its current default, if T is a variable-precision type like BigFloat).\n\nIf base is specified, then it returns the maximum corresponding number of significand digits in that base.\n\ncompat: Julia 1.8\nThe base keyword requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.MPFR.setprecision","page":"Numbers","title":"Base.MPFR.setprecision","text":"setprecision([T=BigFloat,] precision::Int; base=2)\n\nSet the precision (in bits, by default) to be used for T arithmetic. If base is specified, then the precision is the minimum required to give at least precision digits in the given base.\n\nwarning: Warning\nThis function is not thread-safe. It will affect code running on all threads, but its behavior is undefined if called concurrently with computations that use the setting.\n\ncompat: Julia 1.8\nThe base keyword requires at least Julia 1.8.\n\n\n\n\n\nsetprecision(f::Function, [T=BigFloat,] precision::Integer; base=2)\n\nChange the T arithmetic precision (in the given base) for the duration of f. It is logically equivalent to:\n\nold = precision(BigFloat)\nsetprecision(BigFloat, precision)\nf()\nsetprecision(BigFloat, old)\n\nOften used as setprecision(T, precision) do ... end\n\nNote: nextfloat(), prevfloat() do not use the precision mentioned by setprecision.\n\ncompat: Julia 1.8\nThe base keyword requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/numbers/#Base.GMP.BigInt-Tuple{Any}","page":"Numbers","title":"Base.GMP.BigInt","text":"BigInt(x)\n\nCreate an arbitrary precision integer. x may be an Int (or anything that can be converted to an Int). The usual mathematical operators are defined for this type, and results are promoted to a BigInt.\n\nInstances can be constructed from strings via parse, or using the big string literal.\n\nExamples\n\njulia> parse(BigInt, \"42\")\n42\n\njulia> big\"313\"\n313\n\njulia> BigInt(10)^19\n10000000000000000000\n\n\n\n\n\n","category":"method"},{"location":"base/numbers/#Core.@big_str","page":"Numbers","title":"Core.@big_str","text":"@big_str str\n\nParse a string into a BigInt or BigFloat, and throw an ArgumentError if the string is not a valid number. For integers _ is allowed in the string as a separator.\n\nExamples\n\njulia> big\"123_456\"\n123456\n\njulia> big\"7891.5\"\n7891.5\n\njulia> big\"_\"\nERROR: ArgumentError: invalid number format _ for BigInt or BigFloat\n[...]\n\nwarning: Warning\nUsing @big_str for constructing BigFloat values may not result in the behavior that might be naively expected: as a macro, @big_str obeys the global precision (setprecision) and rounding mode (setrounding) settings as they are at load time. Thus, a function like () -> precision(big\"0.3\") returns a constant whose value depends on the value of the precision at the point when the function is defined, not at the precision at the time when the function is called.\n\n\n\n\n\n","category":"macro"},{"location":"manual/missing/#missing","page":"Missing Values","title":"Missing Values","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Julia provides support for representing missing values in the statistical sense. This is for situations where no value is available for a variable in an observation, but a valid value theoretically exists. Missing values are represented via the missing object, which is the singleton instance of the type Missing. missing is equivalent to NULL in SQL and NA in R, and behaves like them in most situations.","category":"page"},{"location":"manual/missing/#Propagation-of-Missing-Values","page":"Missing Values","title":"Propagation of Missing Values","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"missing values propagate automatically when passed to standard mathematical operators and functions. For these functions, uncertainty about the value of one of the operands induces uncertainty about the result. In practice, this means a math operation involving a missing value generally returns missing:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> missing + 1\nmissing\n\njulia> \"a\" * missing\nmissing\n\njulia> abs(missing)\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Since missing is a normal Julia object, this propagation rule only works for functions which have opted in to implement this behavior. This can be achieved by:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"adding a specific method defined for arguments of type Missing,\naccepting arguments of this type, and passing them to functions which propagate them (like standard math operators).","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Packages should consider whether it makes sense to propagate missing values when defining new functions, and define methods appropriately if this is the case. Passing a missing value to a function which does not have a method accepting arguments of type Missing throws a MethodError, just like for any other type.","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Functions that do not propagate missing values can be made to do so by wrapping them in the passmissing function provided by the Missings.jl package. For example, f(x) becomes passmissing(f)(x).","category":"page"},{"location":"manual/missing/#Equality-and-Comparison-Operators","page":"Missing Values","title":"Equality and Comparison Operators","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Standard equality and comparison operators follow the propagation rule presented above: if any of the operands is missing, the result is missing. Here are a few examples:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> missing == 1\nmissing\n\njulia> missing == missing\nmissing\n\njulia> missing < 1\nmissing\n\njulia> 2 >= missing\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"In particular, note that missing == missing returns missing, so == cannot be used to test whether a value is missing. To test whether x is missing, use ismissing(x).","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Special comparison operators isequal and === are exceptions to the propagation rule. They will always return a Bool value, even in the presence of missing values, considering missing as equal to missing and as different from any other value. They can therefore be used to test whether a value is missing:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> missing === 1\nfalse\n\njulia> isequal(missing, 1)\nfalse\n\njulia> missing === missing\ntrue\n\njulia> isequal(missing, missing)\ntrue","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"The isless operator is another exception: missing is considered as greater than any other value. This operator is used by sort!, which therefore places missing values after all other values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> isless(1, missing)\ntrue\n\njulia> isless(missing, Inf)\nfalse\n\njulia> isless(missing, missing)\nfalse","category":"page"},{"location":"manual/missing/#Logical-operators","page":"Missing Values","title":"Logical operators","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Logical (or boolean) operators |, & and xor are another special case since they only propagate missing values when it is logically required. For these operators, whether or not the result is uncertain, depends on the particular operation. This follows the well-established rules of three-valued logic which are implemented by e.g. NULL in SQL and NA in R. This abstract definition corresponds to a relatively natural behavior which is best explained via concrete examples.","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Let us illustrate this principle with the logical \"or\" operator |. Following the rules of boolean logic, if one of the operands is true, the value of the other operand does not have an influence on the result, which will always be true:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> true | true\ntrue\n\njulia> true | false\ntrue\n\njulia> false | true\ntrue","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Based on this observation, we can conclude if one of the operands is true and the other missing, we know that the result is true in spite of the uncertainty about the actual value of one of the operands. If we had been able to observe the actual value of the second operand, it could only be true or false, and in both cases the result would be true. Therefore, in this particular case, missingness does not propagate:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> true | missing\ntrue\n\njulia> missing | true\ntrue","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"On the contrary, if one of the operands is false, the result could be either true or false depending on the value of the other operand. Therefore, if that operand is missing, the result has to be missing too:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> false | true\ntrue\n\njulia> true | false\ntrue\n\njulia> false | false\nfalse\n\njulia> false | missing\nmissing\n\njulia> missing | false\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"The behavior of the logical \"and\" operator & is similar to that of the | operator, with the difference that missingness does not propagate when one of the operands is false. For example, when that is the case of the first operand:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> false & false\nfalse\n\njulia> false & true\nfalse\n\njulia> false & missing\nfalse","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"On the other hand, missingness propagates when one of the operands is true, for example the first one:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> true & true\ntrue\n\njulia> true & false\nfalse\n\njulia> true & missing\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Finally, the \"exclusive or\" logical operator xor always propagates missing values, since both operands always have an effect on the result. Also note that the negation operator ! returns missing when the operand is missing, just like other unary operators.","category":"page"},{"location":"manual/missing/#Control-Flow-and-Short-Circuiting-Operators","page":"Missing Values","title":"Control Flow and Short-Circuiting Operators","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Control flow operators including if, while and the ternary operator x ? y : z do not allow for missing values. This is because of the uncertainty about whether the actual value would be true or false if we could observe it. This implies we do not know how the program should behave. In this case, a TypeError is thrown as soon as a missing value is encountered in this context:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> if missing\n println(\"here\")\n end\nERROR: TypeError: non-boolean (Missing) used in boolean context","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"For the same reason, contrary to logical operators presented above, the short-circuiting boolean operators && and || do not allow for missing values in situations where the value of the operand determines whether the next operand is evaluated or not. For example:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> missing || false\nERROR: TypeError: non-boolean (Missing) used in boolean context\n\njulia> missing && false\nERROR: TypeError: non-boolean (Missing) used in boolean context\n\njulia> true && missing && false\nERROR: TypeError: non-boolean (Missing) used in boolean context","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"In contrast, there is no error thrown when the result can be determined without the missing values. This is the case when the code short-circuits before evaluating the missing operand, and when the missing operand is the last one:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> true && missing\nmissing\n\njulia> false && missing\nfalse","category":"page"},{"location":"manual/missing/#Arrays-With-Missing-Values","page":"Missing Values","title":"Arrays With Missing Values","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Arrays containing missing values can be created like other arrays:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> [1, missing]\n2-element Vector{Union{Missing, Int64}}:\n 1\n missing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"As this example shows, the element type of such arrays is Union{Missing, T}, with T the type of the non-missing values. This reflects the fact that array entries can be either of type T (here, Int64) or of type Missing. This kind of array uses an efficient memory storage equivalent to an Array{T} holding the actual values combined with an Array{UInt8} indicating the type of the entry (i.e. whether it is Missing or T).","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Arrays allowing for missing values can be constructed with the standard syntax. Use Array{Union{Missing, T}}(missing, dims) to create arrays filled with missing values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> Array{Union{Missing, String}}(missing, 2, 3)\n2×3 Matrix{Union{Missing, String}}:\n missing missing missing\n missing missing missing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"note: Note\nUsing undef or similar may currently give an array filled with missing, but this is not the correct way to obtain such an array. Use a missing constructor as shown above instead.","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"An array with element type allowing missing entries (e.g. Vector{Union{Missing, T}}) which does not contain any missing entries can be converted to an array type that does not allow for missing entries (e.g. Vector{T}) using convert. If the array contains missing values, a MethodError is thrown during conversion:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> x = Union{Missing, String}[\"a\", \"b\"]\n2-element Vector{Union{Missing, String}}:\n \"a\"\n \"b\"\n\njulia> convert(Array{String}, x)\n2-element Vector{String}:\n \"a\"\n \"b\"\n\njulia> y = Union{Missing, String}[missing, \"b\"]\n2-element Vector{Union{Missing, String}}:\n missing\n \"b\"\n\njulia> convert(Array{String}, y)\nERROR: MethodError: Cannot `convert` an object of type Missing to an object of type String","category":"page"},{"location":"manual/missing/#Skipping-Missing-Values","page":"Missing Values","title":"Skipping Missing Values","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Since missing values propagate with standard mathematical operators, reduction functions return missing when called on arrays which contain missing values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> sum([1, missing])\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"In this situation, use the skipmissing function to skip missing values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> sum(skipmissing([1, missing]))\n1","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"This convenience function returns an iterator which filters out missing values efficiently. It can therefore be used with any function which supports iterators:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> x = skipmissing([3, missing, 2, 1])\nskipmissing(Union{Missing, Int64}[3, missing, 2, 1])\n\njulia> maximum(x)\n3\n\njulia> sum(x)\n6\n\njulia> mapreduce(sqrt, +, x)\n4.146264369941973","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Objects created by calling skipmissing on an array can be indexed using indices from the parent array. Indices corresponding to missing values are not valid for these objects, and an error is thrown when trying to use them (they are also skipped by keys and eachindex):","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> x[1]\n3\n\njulia> x[2]\nERROR: MissingException: the value at index (2,) is missing\n[...]","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"This allows functions which operate on indices to work in combination with skipmissing. This is notably the case for search and find functions. These functions return indices valid for the object returned by skipmissing, and are also the indices of the matching entries in the parent array:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> findall(==(1), x)\n1-element Vector{Int64}:\n 4\n\njulia> findfirst(!iszero, x)\n1\n\njulia> argmax(x)\n1","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Use collect to extract non-missing values and store them in an array:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> collect(x)\n3-element Vector{Int64}:\n 3\n 2\n 1","category":"page"},{"location":"manual/missing/#Logical-Operations-on-Arrays","page":"Missing Values","title":"Logical Operations on Arrays","text":"","category":"section"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"The three-valued logic described above for logical operators is also used by logical functions applied to arrays. Thus, array equality tests using the == operator return missing whenever the result cannot be determined without knowing the actual value of the missing entry. In practice, this means missing is returned if all non-missing values of the compared arrays are equal, but one or both arrays contain missing values (possibly at different positions):","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> [1, missing] == [2, missing]\nfalse\n\njulia> [1, missing] == [1, missing]\nmissing\n\njulia> [1, 2, missing] == [1, missing, 2]\nmissing","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"As for single values, use isequal to treat missing values as equal to other missing values, but different from non-missing values:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> isequal([1, missing], [1, missing])\ntrue\n\njulia> isequal([1, 2, missing], [1, missing, 2])\nfalse","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"Functions any and all also follow the rules of three-valued logic. Thus, returning missing when the result cannot be determined:","category":"page"},{"location":"manual/missing/","page":"Missing Values","title":"Missing Values","text":"julia> all([true, missing])\nmissing\n\njulia> all([false, missing])\nfalse\n\njulia> any([true, missing])\ntrue\n\njulia> any([false, missing])\nmissing","category":"page"},{"location":"base/multi-threading/#lib-multithreading","page":"Multi-Threading","title":"Multi-Threading","text":"","category":"section"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.Threads.@threads\nBase.Threads.foreach\nBase.Threads.@spawn\nBase.Threads.threadid\nBase.Threads.maxthreadid\nBase.Threads.nthreads\nBase.Threads.threadpool\nBase.Threads.nthreadpools\nBase.Threads.threadpoolsize\nBase.Threads.ngcthreads","category":"page"},{"location":"base/multi-threading/#Base.Threads.@threads","page":"Multi-Threading","title":"Base.Threads.@threads","text":"Threads.@threads [schedule] for ... end\n\nA macro to execute a for loop in parallel. The iteration space is distributed to coarse-grained tasks. This policy can be specified by the schedule argument. The execution of the loop waits for the evaluation of all iterations.\n\nSee also: @spawn and pmap in Distributed.\n\nExtended help\n\nSemantics\n\nUnless stronger guarantees are specified by the scheduling option, the loop executed by @threads macro have the following semantics.\n\nThe @threads macro executes the loop body in an unspecified order and potentially concurrently. It does not specify the exact assignments of the tasks and the worker threads. The assignments can be different for each execution. The loop body code (including any code transitively called from it) must not make any assumptions about the distribution of iterations to tasks or the worker thread in which they are executed. The loop body for each iteration must be able to make forward progress independent of other iterations and be free from data races. As such, invalid synchronizations across iterations may deadlock while unsynchronized memory accesses may result in undefined behavior.\n\nFor example, the above conditions imply that:\n\nA lock taken in an iteration must be released within the same iteration.\nCommunicating between iterations using blocking primitives like Channels is incorrect.\nWrite only to locations not shared across iterations (unless a lock or atomic operation is used).\nUnless the :static schedule is used, the value of threadid() may change even within a single iteration. See Task Migration.\n\nSchedulers\n\nWithout the scheduler argument, the exact scheduling is unspecified and varies across Julia releases. Currently, :dynamic is used when the scheduler is not specified.\n\ncompat: Julia 1.5\nThe schedule argument is available as of Julia 1.5.\n\n:dynamic (default)\n\n:dynamic scheduler executes iterations dynamically to available worker threads. Current implementation assumes that the workload for each iteration is uniform. However, this assumption may be removed in the future.\n\nThis scheduling option is merely a hint to the underlying execution mechanism. However, a few properties can be expected. The number of Tasks used by :dynamic scheduler is bounded by a small constant multiple of the number of available worker threads (Threads.threadpoolsize()). Each task processes contiguous regions of the iteration space. Thus, @threads :dynamic for x in xs; f(x); end is typically more efficient than @sync for x in xs; @spawn f(x); end if length(xs) is significantly larger than the number of the worker threads and the run-time of f(x) is relatively smaller than the cost of spawning and synchronizing a task (typically less than 10 microseconds).\n\ncompat: Julia 1.8\nThe :dynamic option for the schedule argument is available and the default as of Julia 1.8.\n\n:greedy\n\n:greedy scheduler spawns up to Threads.threadpoolsize() tasks, each greedily working on the given iterated values as they are produced. As soon as one task finishes its work, it takes the next value from the iterator. Work done by any individual task is not necessarily on contiguous values from the iterator. The given iterator may produce values forever, only the iterator interface is required (no indexing).\n\nThis scheduling option is generally a good choice if the workload of individual iterations is not uniform/has a large spread.\n\ncompat: Julia 1.11\nThe :greedy option for the schedule argument is available as of Julia 1.11.\n\n:static\n\n:static scheduler creates one task per thread and divides the iterations equally among them, assigning each task specifically to each thread. In particular, the value of threadid() is guaranteed to be constant within one iteration. Specifying :static is an error if used from inside another @threads loop or from a thread other than 1.\n\nnote: Note\n:static scheduling exists for supporting transition of code written before Julia 1.3. In newly written library functions, :static scheduling is discouraged because the functions using this option cannot be called from arbitrary worker threads.\n\nExamples\n\nTo illustrate of the different scheduling strategies, consider the following function busywait containing a non-yielding timed loop that runs for a given number of seconds.\n\njulia> function busywait(seconds)\n tstart = time_ns()\n while (time_ns() - tstart) / 1e9 < seconds\n end\n end\n\njulia> @time begin\n Threads.@spawn busywait(5)\n Threads.@threads :static for i in 1:Threads.threadpoolsize()\n busywait(1)\n end\n end\n6.003001 seconds (16.33 k allocations: 899.255 KiB, 0.25% compilation time)\n\njulia> @time begin\n Threads.@spawn busywait(5)\n Threads.@threads :dynamic for i in 1:Threads.threadpoolsize()\n busywait(1)\n end\n end\n2.012056 seconds (16.05 k allocations: 883.919 KiB, 0.66% compilation time)\n\nThe :dynamic example takes 2 seconds since one of the non-occupied threads is able to run two of the 1-second iterations to complete the for loop.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.Threads.foreach","page":"Multi-Threading","title":"Base.Threads.foreach","text":"Threads.foreach(f, channel::Channel;\n schedule::Threads.AbstractSchedule=Threads.FairSchedule(),\n ntasks=Threads.threadpoolsize())\n\nSimilar to foreach(f, channel), but iteration over channel and calls to f are split across ntasks tasks spawned by Threads.@spawn. This function will wait for all internally spawned tasks to complete before returning.\n\nIf schedule isa FairSchedule, Threads.foreach will attempt to spawn tasks in a manner that enables Julia's scheduler to more freely load-balance work items across threads. This approach generally has higher per-item overhead, but may perform better than StaticSchedule in concurrence with other multithreaded workloads.\n\nIf schedule isa StaticSchedule, Threads.foreach will spawn tasks in a manner that incurs lower per-item overhead than FairSchedule, but is less amenable to load-balancing. This approach thus may be more suitable for fine-grained, uniform workloads, but may perform worse than FairSchedule in concurrence with other multithreaded workloads.\n\nExamples\n\njulia> n = 20\n\njulia> c = Channel{Int}(ch -> foreach(i -> put!(ch, i), 1:n), 1)\n\njulia> d = Channel{Int}(n) do ch\n f = i -> put!(ch, i^2)\n Threads.foreach(f, c)\n end\n\njulia> collect(d)\ncollect(d) = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400]\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.@spawn","page":"Multi-Threading","title":"Base.Threads.@spawn","text":"Threads.@spawn [:default|:interactive] expr\n\nCreate a Task and schedule it to run on any available thread in the specified threadpool (:default if unspecified). The task is allocated to a thread once one becomes available. To wait for the task to finish, call wait on the result of this macro, or call fetch to wait and then obtain its return value.\n\nValues can be interpolated into @spawn via $, which copies the value directly into the constructed underlying closure. This allows you to insert the value of a variable, isolating the asynchronous code from changes to the variable's value in the current task.\n\nnote: Note\nThe thread that the task runs on may change if the task yields, therefore threadid() should not be treated as constant for a task. See Task Migration, and the broader multi-threading manual for further important caveats. See also the chapter on threadpools.\n\ncompat: Julia 1.3\nThis macro is available as of Julia 1.3.\n\ncompat: Julia 1.4\nInterpolating values via $ is available as of Julia 1.4.\n\ncompat: Julia 1.9\nA threadpool may be specified as of Julia 1.9.\n\nExamples\n\njulia> t() = println(\"Hello from \", Threads.threadid());\n\njulia> tasks = fetch.([Threads.@spawn t() for i in 1:4]);\nHello from 1\nHello from 1\nHello from 3\nHello from 4\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.Threads.threadid","page":"Multi-Threading","title":"Base.Threads.threadid","text":"Threads.threadid() -> Int\n\nGet the ID number of the current thread of execution. The master thread has ID 1.\n\nExamples\n\njulia> Threads.threadid()\n1\n\njulia> Threads.@threads for i in 1:4\n println(Threads.threadid())\n end\n4\n2\n5\n4\n\nnote: Note\nThe thread that a task runs on may change if the task yields, which is known as Task Migration. For this reason in most cases it is not safe to use threadid() to index into, say, a vector of buffer or stateful objects.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.maxthreadid","page":"Multi-Threading","title":"Base.Threads.maxthreadid","text":"Threads.maxthreadid() -> Int\n\nGet a lower bound on the number of threads (across all thread pools) available to the Julia process, with atomic-acquire semantics. The result will always be greater than or equal to threadid() as well as threadid(task) for any task you were able to observe before calling maxthreadid.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.nthreads","page":"Multi-Threading","title":"Base.Threads.nthreads","text":"Threads.nthreads(:default | :interactive) -> Int\n\nGet the current number of threads within the specified thread pool. The threads in :interactive have id numbers 1:nthreads(:interactive), and the threads in :default have id numbers in nthreads(:interactive) .+ (1:nthreads(:default)).\n\nSee also BLAS.get_num_threads and BLAS.set_num_threads in the LinearAlgebra standard library, and nprocs() in the Distributed standard library and Threads.maxthreadid().\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.threadpool","page":"Multi-Threading","title":"Base.Threads.threadpool","text":"Threads.threadpool(tid = threadid()) -> Symbol\n\nReturns the specified thread's threadpool; either :default, :interactive, or :foreign.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.nthreadpools","page":"Multi-Threading","title":"Base.Threads.nthreadpools","text":"Threads.nthreadpools() -> Int\n\nReturns the number of threadpools currently configured.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.threadpoolsize","page":"Multi-Threading","title":"Base.Threads.threadpoolsize","text":"Threads.threadpoolsize(pool::Symbol = :default) -> Int\n\nGet the number of threads available to the default thread pool (or to the specified thread pool).\n\nSee also: BLAS.get_num_threads and BLAS.set_num_threads in the LinearAlgebra standard library, and nprocs() in the Distributed standard library.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.ngcthreads","page":"Multi-Threading","title":"Base.Threads.ngcthreads","text":"Threads.ngcthreads() -> Int\n\nReturns the number of GC threads currently configured. This includes both mark threads and concurrent sweep threads.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"See also Multi-Threading.","category":"page"},{"location":"base/multi-threading/#Atomic-operations","page":"Multi-Threading","title":"Atomic operations","text":"","category":"section"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"atomic","category":"page"},{"location":"base/multi-threading/#atomic","page":"Multi-Threading","title":"atomic","text":"Unsafe pointer operations are compatible with loading and storing pointers declared with _Atomic and std::atomic type in C11 and C++23 respectively. An error may be thrown if there is not support for atomically loading the Julia type T.\n\nSee also: unsafe_load, unsafe_modify!, unsafe_replace!, unsafe_store!, unsafe_swap!\n\n\n\n\n\n","category":"keyword"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.@atomic\nBase.@atomicswap\nBase.@atomicreplace\nBase.@atomiconce\nBase.AtomicMemory","category":"page"},{"location":"base/multi-threading/#Base.@atomic","page":"Multi-Threading","title":"Base.@atomic","text":"@atomic var\n@atomic order ex\n\nMark var or ex as being performed atomically, if ex is a supported expression. If no order is specified it defaults to :sequentially_consistent.\n\n@atomic a.b.x = new\n@atomic a.b.x += addend\n@atomic :release a.b.x = new\n@atomic :acquire_release a.b.x += addend\n\nPerform the store operation expressed on the right atomically and return the new value.\n\nWith =, this operation translates to a setproperty!(a.b, :x, new) call. With any operator also, this operation translates to a modifyproperty!(a.b, :x, +, addend)[2] call.\n\n@atomic a.b.x max arg2\n@atomic a.b.x + arg2\n@atomic max(a.b.x, arg2)\n@atomic :acquire_release max(a.b.x, arg2)\n@atomic :acquire_release a.b.x + arg2\n@atomic :acquire_release a.b.x max arg2\n\nPerform the binary operation expressed on the right atomically. Store the result into the field in the first argument and return the values (old, new).\n\nThis operation translates to a modifyproperty!(a.b, :x, func, arg2) call.\n\nSee Per-field atomics section in the manual for more details.\n\nExamples\n\njulia> mutable struct Atomic{T}; @atomic x::T; end\n\njulia> a = Atomic(1)\nAtomic{Int64}(1)\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n1\n\njulia> @atomic :sequentially_consistent a.x = 2 # set field x of a, with sequential consistency\n2\n\njulia> @atomic a.x += 1 # increment field x of a, with sequential consistency\n3\n\njulia> @atomic a.x + 1 # increment field x of a, with sequential consistency\n3 => 4\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n4\n\njulia> @atomic max(a.x, 10) # change field x of a to the max value, with sequential consistency\n4 => 10\n\njulia> @atomic a.x max 5 # again change field x of a to the max value, with sequential consistency\n10 => 10\n\ncompat: Julia 1.7\nThis functionality requires at least Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.@atomicswap","page":"Multi-Threading","title":"Base.@atomicswap","text":"@atomicswap a.b.x = new\n@atomicswap :sequentially_consistent a.b.x = new\n\nStores new into a.b.x and returns the old value of a.b.x.\n\nThis operation translates to a swapproperty!(a.b, :x, new) call.\n\nSee Per-field atomics section in the manual for more details.\n\nExamples\n\njulia> mutable struct Atomic{T}; @atomic x::T; end\n\njulia> a = Atomic(1)\nAtomic{Int64}(1)\n\njulia> @atomicswap a.x = 2+2 # replace field x of a with 4, with sequential consistency\n1\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n4\n\ncompat: Julia 1.7\nThis functionality requires at least Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.@atomicreplace","page":"Multi-Threading","title":"Base.@atomicreplace","text":"@atomicreplace a.b.x expected => desired\n@atomicreplace :sequentially_consistent a.b.x expected => desired\n@atomicreplace :sequentially_consistent :monotonic a.b.x expected => desired\n\nPerform the conditional replacement expressed by the pair atomically, returning the values (old, success::Bool). Where success indicates whether the replacement was completed.\n\nThis operation translates to a replaceproperty!(a.b, :x, expected, desired) call.\n\nSee Per-field atomics section in the manual for more details.\n\nExamples\n\njulia> mutable struct Atomic{T}; @atomic x::T; end\n\njulia> a = Atomic(1)\nAtomic{Int64}(1)\n\njulia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency\n(old = 1, success = true)\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n2\n\njulia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency\n(old = 2, success = false)\n\njulia> xchg = 2 => 0; # replace field x of a with 0 if it was 2, with sequential consistency\n\njulia> @atomicreplace a.x xchg\n(old = 2, success = true)\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n0\n\ncompat: Julia 1.7\nThis functionality requires at least Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Base.@atomiconce","page":"Multi-Threading","title":"Base.@atomiconce","text":"@atomiconce a.b.x = value\n@atomiconce :sequentially_consistent a.b.x = value\n@atomiconce :sequentially_consistent :monotonic a.b.x = value\n\nPerform the conditional assignment of value atomically if it was previously unset, returning the value success::Bool. Where success indicates whether the assignment was completed.\n\nThis operation translates to a setpropertyonce!(a.b, :x, value) call.\n\nSee Per-field atomics section in the manual for more details.\n\nExamples\n\njulia> mutable struct AtomicOnce\n @atomic x\n AtomicOnce() = new()\n end\n\njulia> a = AtomicOnce()\nAtomicOnce(#undef)\n\njulia> @atomiconce a.x = 1 # set field x of a to 1, if unset, with sequential consistency\ntrue\n\njulia> @atomic a.x # fetch field x of a, with sequential consistency\n1\n\njulia> @atomiconce a.x = 1 # set field x of a to 1, if unset, with sequential consistency\nfalse\n\ncompat: Julia 1.11\nThis functionality requires at least Julia 1.11.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Core.AtomicMemory","page":"Multi-Threading","title":"Core.AtomicMemory","text":"AtomicMemory{T} == GenericMemory{:atomic, T, Core.CPU}\n\nOne-dimensional dense array with elements of type T, where each element is independently atomic when accessed, and cannot be set non-atomically.\n\ncompat: Julia 1.11\nThis type requires Julia 1.11 or later.\n\n\n\n\n\n","category":"type"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"There are also optional memory ordering parameters for the unsafe set of functions, that select the C/C++-compatible versions of these atomic operations, if that parameter is specified to unsafe_load, unsafe_store!, unsafe_swap!, unsafe_replace!, and unsafe_modify!.","category":"page"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"warning: Warning\nThe following APIs are deprecated, though support for them is likely to remain for several releases.","category":"page"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.Threads.Atomic\nBase.Threads.atomic_cas!\nBase.Threads.atomic_xchg!\nBase.Threads.atomic_add!\nBase.Threads.atomic_sub!\nBase.Threads.atomic_and!\nBase.Threads.atomic_nand!\nBase.Threads.atomic_or!\nBase.Threads.atomic_xor!\nBase.Threads.atomic_max!\nBase.Threads.atomic_min!\nBase.Threads.atomic_fence","category":"page"},{"location":"base/multi-threading/#Base.Threads.Atomic","page":"Multi-Threading","title":"Base.Threads.Atomic","text":"Threads.Atomic{T}\n\nHolds a reference to an object of type T, ensuring that it is only accessed atomically, i.e. in a thread-safe manner.\n\nOnly certain \"simple\" types can be used atomically, namely the primitive boolean, integer, and float-point types. These are Bool, Int8...Int128, UInt8...UInt128, and Float16...Float64.\n\nNew atomic objects can be created from a non-atomic values; if none is specified, the atomic object is initialized with zero.\n\nAtomic objects can be accessed using the [] notation:\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> x[] = 1\n1\n\njulia> x[]\n1\n\nAtomic operations use an atomic_ prefix, such as atomic_add!, atomic_xchg!, etc.\n\n\n\n\n\n","category":"type"},{"location":"base/multi-threading/#Base.Threads.atomic_cas!","page":"Multi-Threading","title":"Base.Threads.atomic_cas!","text":"Threads.atomic_cas!(x::Atomic{T}, cmp::T, newval::T) where T\n\nAtomically compare-and-set x\n\nAtomically compares the value in x with cmp. If equal, write newval to x. Otherwise, leaves x unmodified. Returns the old value in x. By comparing the returned value to cmp (via ===) one knows whether x was modified and now holds the new value newval.\n\nFor further details, see LLVM's cmpxchg instruction.\n\nThis function can be used to implement transactional semantics. Before the transaction, one records the value in x. After the transaction, the new value is stored only if x has not been modified in the mean time.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_cas!(x, 4, 2);\n\njulia> x\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_cas!(x, 3, 2);\n\njulia> x\nBase.Threads.Atomic{Int64}(2)\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_xchg!","page":"Multi-Threading","title":"Base.Threads.atomic_xchg!","text":"Threads.atomic_xchg!(x::Atomic{T}, newval::T) where T\n\nAtomically exchange the value in x\n\nAtomically exchanges the value in x with newval. Returns the old value.\n\nFor further details, see LLVM's atomicrmw xchg instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_xchg!(x, 2)\n3\n\njulia> x[]\n2\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_add!","page":"Multi-Threading","title":"Base.Threads.atomic_add!","text":"Threads.atomic_add!(x::Atomic{T}, val::T) where T <: ArithmeticTypes\n\nAtomically add val to x\n\nPerforms x[] += val atomically. Returns the old value. Not defined for Atomic{Bool}.\n\nFor further details, see LLVM's atomicrmw add instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_add!(x, 2)\n3\n\njulia> x[]\n5\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_sub!","page":"Multi-Threading","title":"Base.Threads.atomic_sub!","text":"Threads.atomic_sub!(x::Atomic{T}, val::T) where T <: ArithmeticTypes\n\nAtomically subtract val from x\n\nPerforms x[] -= val atomically. Returns the old value. Not defined for Atomic{Bool}.\n\nFor further details, see LLVM's atomicrmw sub instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_sub!(x, 2)\n3\n\njulia> x[]\n1\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_and!","page":"Multi-Threading","title":"Base.Threads.atomic_and!","text":"Threads.atomic_and!(x::Atomic{T}, val::T) where T\n\nAtomically bitwise-and x with val\n\nPerforms x[] &= val atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw and instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_and!(x, 2)\n3\n\njulia> x[]\n2\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_nand!","page":"Multi-Threading","title":"Base.Threads.atomic_nand!","text":"Threads.atomic_nand!(x::Atomic{T}, val::T) where T\n\nAtomically bitwise-nand (not-and) x with val\n\nPerforms x[] = ~(x[] & val) atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw nand instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(3)\nBase.Threads.Atomic{Int64}(3)\n\njulia> Threads.atomic_nand!(x, 2)\n3\n\njulia> x[]\n-3\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_or!","page":"Multi-Threading","title":"Base.Threads.atomic_or!","text":"Threads.atomic_or!(x::Atomic{T}, val::T) where T\n\nAtomically bitwise-or x with val\n\nPerforms x[] |= val atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw or instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(5)\nBase.Threads.Atomic{Int64}(5)\n\njulia> Threads.atomic_or!(x, 7)\n5\n\njulia> x[]\n7\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_xor!","page":"Multi-Threading","title":"Base.Threads.atomic_xor!","text":"Threads.atomic_xor!(x::Atomic{T}, val::T) where T\n\nAtomically bitwise-xor (exclusive-or) x with val\n\nPerforms x[] $= val atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw xor instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(5)\nBase.Threads.Atomic{Int64}(5)\n\njulia> Threads.atomic_xor!(x, 7)\n5\n\njulia> x[]\n2\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_max!","page":"Multi-Threading","title":"Base.Threads.atomic_max!","text":"Threads.atomic_max!(x::Atomic{T}, val::T) where T\n\nAtomically store the maximum of x and val in x\n\nPerforms x[] = max(x[], val) atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw max instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(5)\nBase.Threads.Atomic{Int64}(5)\n\njulia> Threads.atomic_max!(x, 7)\n5\n\njulia> x[]\n7\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_min!","page":"Multi-Threading","title":"Base.Threads.atomic_min!","text":"Threads.atomic_min!(x::Atomic{T}, val::T) where T\n\nAtomically store the minimum of x and val in x\n\nPerforms x[] = min(x[], val) atomically. Returns the old value.\n\nFor further details, see LLVM's atomicrmw min instruction.\n\nExamples\n\njulia> x = Threads.Atomic{Int}(7)\nBase.Threads.Atomic{Int64}(7)\n\njulia> Threads.atomic_min!(x, 5)\n7\n\njulia> x[]\n5\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#Base.Threads.atomic_fence","page":"Multi-Threading","title":"Base.Threads.atomic_fence","text":"Threads.atomic_fence()\n\nInsert a sequential-consistency memory fence\n\nInserts a memory fence with sequentially-consistent ordering semantics. There are algorithms where this is needed, i.e. where an acquire/release ordering is insufficient.\n\nThis is likely a very expensive operation. Given that all other atomic operations in Julia already have acquire/release semantics, explicit fences should not be necessary in most cases.\n\nFor further details, see LLVM's fence instruction.\n\n\n\n\n\n","category":"function"},{"location":"base/multi-threading/#ccall-using-a-libuv-threadpool-(Experimental)","page":"Multi-Threading","title":"ccall using a libuv threadpool (Experimental)","text":"","category":"section"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.@threadcall","category":"page"},{"location":"base/multi-threading/#Base.@threadcall","page":"Multi-Threading","title":"Base.@threadcall","text":"@threadcall((cfunc, clib), rettype, (argtypes...), argvals...)\n\nThe @threadcall macro is called in the same way as ccall but does the work in a different thread. This is useful when you want to call a blocking C function without causing the current julia thread to become blocked. Concurrency is limited by size of the libuv thread pool, which defaults to 4 threads but can be increased by setting the UV_THREADPOOL_SIZE environment variable and restarting the julia process.\n\nNote that the called function should never call back into Julia.\n\n\n\n\n\n","category":"macro"},{"location":"base/multi-threading/#Low-level-synchronization-primitives","page":"Multi-Threading","title":"Low-level synchronization primitives","text":"","category":"section"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"These building blocks are used to create the regular synchronization objects.","category":"page"},{"location":"base/multi-threading/","page":"Multi-Threading","title":"Multi-Threading","text":"Base.Threads.SpinLock","category":"page"},{"location":"base/multi-threading/#Base.Threads.SpinLock","page":"Multi-Threading","title":"Base.Threads.SpinLock","text":"SpinLock()\n\nCreate a non-reentrant, test-and-test-and-set spin lock. Recursive use will result in a deadlock. This kind of lock should only be used around code that takes little time to execute and does not block (e.g. perform I/O). In general, ReentrantLock should be used instead.\n\nEach lock must be matched with an unlock. If !islocked(lck::SpinLock) holds, trylock(lck) succeeds unless there are other tasks attempting to hold the lock \"at the same time.\"\n\nTest-and-test-and-set spin locks are quickest up to about 30ish contending threads. If you have more contention than that, different synchronization approaches should be considered.\n\n\n\n\n\n","category":"type"},{"location":"devdocs/llvm-passes/#Custom-LLVM-Passes","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Julia has a number of custom LLVM passes. Broadly, they can be classified into passes that are required to be run to maintain Julia semantics, and passes that take advantage of Julia semantics to optimize LLVM IR.","category":"page"},{"location":"devdocs/llvm-passes/#Semantic-Passes","page":"Custom LLVM Passes","title":"Semantic Passes","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"These passes are used to transform LLVM IR into code that is legal to be run on a CPU. Their main purpose is to enable simpler IR to be emitted by codegen, which then enables other LLVM passes to optimize common patterns.","category":"page"},{"location":"devdocs/llvm-passes/#CPUFeatures","page":"Custom LLVM Passes","title":"CPUFeatures","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-cpufeatures.cpp\nClass Name: CPUFeaturesPass\nOpt Name: module(CPUFeatures)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass lowers the julia.cpu.have_fma.(f32|f64) intrinsic to either true or false, depending on the target architecture and target features present on the function. This intrinsic is often used to determine if using algorithms dependent on fast fused multiply-add operations is better than using standard algorithms not dependent on such instructions.","category":"page"},{"location":"devdocs/llvm-passes/#DemoteFloat16","page":"Custom LLVM Passes","title":"DemoteFloat16","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-demote-float16.cpp\nClassName: DemoteFloat16Pass\nOpt Name function(DemoteFloat16)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass replaces float16 operations with float32 operations on architectures that do not natively support float16 operations. This is done by inserting fpext and fptrunc instructions around any float16 operation. On architectures that do support native float16 operations, this pass is a no-op.","category":"page"},{"location":"devdocs/llvm-passes/#LateGCLowering","page":"Custom LLVM Passes","title":"LateGCLowering","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-late-gc-lowering.cpp\nClass Name: LateLowerGCPass\nOpt Name: function(LateLowerGCFrame)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass performs most of the GC rooting work required to track pointers between GC safepoints. It also lowers several intrinsics to their corresponding instruction translation, and is permitted to violate the non-integral invariants previously established (pointer_from_objref is lowered to a ptrtoint instruction here). This pass typically occupies the most time out of all the custom Julia passes, due to its dataflow algorithm to minimize the number of objects live at any safepoint.","category":"page"},{"location":"devdocs/llvm-passes/#FinalGCLowering","page":"Custom LLVM Passes","title":"FinalGCLowering","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-final-gc-lowering.cpp\nClass Name: FinalLowerGCPass\nOpt Name: module(FinalLowerGC)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass lowers a few last intrinsics to their final form targeting functions in the libjulia library. Separating this from LateGCLowering enables other backends (GPU compilation) to supply their own custom lowerings for these intrinsics, enabling the Julia pipeline to be used on those backends as well.","category":"page"},{"location":"devdocs/llvm-passes/#LowerHandlers","page":"Custom LLVM Passes","title":"LowerHandlers","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-lower-handlers.cpp\nClass Name: LowerExcHandlersPass\nOpt Name: function(LowerExcHandlers)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass lowers exception handling intrinsics into calls to runtime functions that are actually called when handling exceptions.","category":"page"},{"location":"devdocs/llvm-passes/#RemoveNI","page":"Custom LLVM Passes","title":"RemoveNI","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-remove-ni.cpp\nClass Name: RemoveNIPass\nOpt Name: module(RemoveNI)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass removes the non-integral address spaces from the module's datalayout string. This enables the backend to lower Julia's custom address spaces directly to machine code, without a costly rewrite of every pointer operation to address space 0.","category":"page"},{"location":"devdocs/llvm-passes/#SIMDLoop","page":"Custom LLVM Passes","title":"SIMDLoop","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-simdloop.cpp\nClass Name: LowerSIMDLoopPass\nOpt Name: loop(LowerSIMDLoop)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass acts as the main driver of the @simd annotation. Codegen inserts a !llvm.loopid marker at the back branch of a loop, which this pass uses to identify loops that were originally marked with @simd. Then, this pass looks for a chain of floating point operations that form a reduce and adds the contract and reassoc fast math flags to allow reassociation (and thus vectorization). This pass does not preserve either loop information nor inference correctness, so it may violate Julia semantics in surprising ways. If the loop was annotated with ivdep as well, then the pass marks the loop as having no loop-carried dependencies (the resulting behavior is undefined if the user annotation was incorrect or gets applied to the wrong loop).","category":"page"},{"location":"devdocs/llvm-passes/#LowerPTLS","page":"Custom LLVM Passes","title":"LowerPTLS","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-ptls.cpp\nClass Name: LowerPTLSPass\nOpt Name: module(LowerPTLSPass)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass lowers thread-local Julia intrinsics to assembly instructions. Julia relies on thread-local storage for garbage collection and multithreading task scheduling. When compiling code for system images and package images, this pass replaces calls to intrinsics with loads from global variables that are initialized at load time.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"If codegen produces a function with a swiftself argument and calling convention, this pass assumes the swiftself argument is the pgcstack and will replace the intrinsics with that argument. Doing so provides speedups on architectures that have slow thread local storage accesses.","category":"page"},{"location":"devdocs/llvm-passes/#RemoveAddrspaces","page":"Custom LLVM Passes","title":"RemoveAddrspaces","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-remove-addrspaces.cpp\nClass Name: RemoveAddrspacesPass\nOpt Name: module(RemoveAddrspaces)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass renames pointers in one address space to another address space. This is used to remove Julia-specific address spaces from LLVM IR.","category":"page"},{"location":"devdocs/llvm-passes/#RemoveJuliaAddrspaces","page":"Custom LLVM Passes","title":"RemoveJuliaAddrspaces","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-remove-addrspaces.cpp\nClass Name: RemoveJuliaAddrspacesPass\nOpt Name: module(RemoveJuliaAddrspaces)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass removes Julia-specific address spaces from LLVM IR. It is mostly used for displaying LLVM IR in a less cluttered format. Internally, it is implemented off the RemoveAddrspaces pass.","category":"page"},{"location":"devdocs/llvm-passes/#Multiversioning","page":"Custom LLVM Passes","title":"Multiversioning","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-multiversioning.cpp\nClass Name: MultiVersioningPass\nOpt Name: module(JuliaMultiVersioning)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass performs modifications to a module to create functions that are optimized for running on different architectures (see sysimg.md and pkgimg.md for more details). Implementation-wise, it clones functions and applies different target-specific attributes to them to allow the optimizer to use advanced features such as vectorization and instruction scheduling for that platform. It also creates some infrastructure to enable the Julia image loader to select the appropriate version of the function to call based on the architecture the loader is running on. The target-specific attributes are controlled by the julia.mv.specs module flag, which during compilation is derived from the JULIA_CPU_TARGET environment variable. The pass must also be enabled by providing a julia.mv.enable module flag with a value of 1.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"warning: Warning\n","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Use of llvmcall with multiversioning is dangerous. llvmcall enables access to features not typically exposed by the Julia APIs, and are therefore usually not available on all architectures. If multiversioning is enabled and code generation is requested for a target architecture that does not support the feature required by an llvmcall expression, LLVM will probably error out, likely with an abort and the message LLVM ERROR: Do not know how to split the result of this operator!.","category":"page"},{"location":"devdocs/llvm-passes/#GCInvariantVerifier","page":"Custom LLVM Passes","title":"GCInvariantVerifier","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-gc-invariant-verifier.cpp\nClass Name: GCInvariantVerifierPass\nOpt Name: module(GCInvariantVerifier)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass is used to verify Julia's invariants about LLVM IR. This includes things such as the nonexistence of ptrtoint in Julia's non-integral address spaces [nislides] and the existence of only blessed addrspacecast instructions (Tracked -> Derived, 0 -> Tracked, etc). It performs no transformations on IR.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"[nislides]: https://llvm.org/devmtg/2015-02/slides/chisnall-pointers-not-int.pdf","category":"page"},{"location":"devdocs/llvm-passes/#Optimization-Passes","page":"Custom LLVM Passes","title":"Optimization Passes","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"These passes are used to perform transformations on LLVM IR that LLVM will not perform itself, e.g. fast math flag propagation, escape analysis, and optimizations on Julia-specific internal functions. They use knowledge about Julia's semantics to perform these optimizations.","category":"page"},{"location":"devdocs/llvm-passes/#CombineMulAdd","page":"Custom LLVM Passes","title":"CombineMulAdd","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-muladd.cpp\nClass Name: CombineMulAddPass\nOpt Name: function(CombineMulAdd)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass serves to optimize the particular combination of a regular fmul with a fast fadd into a contract fmul with a fast fadd. This is later optimized by the backend to a fused multiply-add instruction, which can provide significantly faster operations at the cost of more unpredictable semantics.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"note: Note\nThis optimization only occurs when the fmul has a single use, which is the fast fadd.","category":"page"},{"location":"devdocs/llvm-passes/#AllocOpt","page":"Custom LLVM Passes","title":"AllocOpt","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-alloc-opt.cpp\nClass Name: AllocOptPass\nOpt Name: function(AllocOpt)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Julia does not have the concept of a program stack as a place to allocate mutable objects. However, allocating objects on the stack reduces GC pressure and is critical for GPU compilation. Thus, AllocOpt performs heap to stack conversion of objects that it can prove do not escape the current function. It also performs a number of other optimizations on allocations, such as removing allocations that are never used, optimizing typeof calls to freshly allocated objects, and removing stores to allocations that are immediately overwritten. The escape analysis implementation is located in llvm-alloc-helpers.cpp. Currently, this pass does not use information from EscapeAnalysis.jl, though that may change in the future.","category":"page"},{"location":"devdocs/llvm-passes/#PropagateJuliaAddrspaces","page":"Custom LLVM Passes","title":"PropagateJuliaAddrspaces","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-propagate-addrspaces.cpp\nClass Name: PropagateJuliaAddrspacesPass\nOpt Name: function(PropagateJuliaAddrspaces)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass is used to propagate Julia-specific address spaces through operations on pointers. LLVM is not allowed to introduce or remove addrspacecast instructions by optimizations, so this pass acts to eliminate redundant addrspace casts by replacing operations with their equivalent in a Julia address space. For more information on Julia's address spaces, see (TODO link to llvm.md).","category":"page"},{"location":"devdocs/llvm-passes/#JuliaLICM","page":"Custom LLVM Passes","title":"JuliaLICM","text":"","category":"section"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Filename: llvm-julia-licm.cpp\nClass Name: JuliaLICMPass\nOpt Name: loop(JuliaLICM)","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass is used to hoist Julia-specific intrinsics out of loops. Specifically, it performs the following transformations:","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"Hoist gc_preserve_begin and sink gc_preserve_end out of loops when the preserved objects are loop-invariant.\nSince objects preserved within a loop are likely preserved for the duration of the loop, this transformation can reduce the number of gc_preserve_begin/gc_preserve_end pairs in the IR. This makes it easier for the LateLowerGCPass to identify where particular objects are preserved.\nHoist write barriers with invariant objects\nHere we assume that there are only two generations that an object can be a part of. Given that, a write barrier needs to only execute once for any pair of the same object. Thus, we can hoist write barriers out of loops when the object being written to is loop-invariant.\nHoist allocations out of loops when they do not escape the loop\nWe use a very conservative definition of escape here, the same as the one used in AllocOptPass. This transformation can reduce the number of allocations in the IR, even when an allocation escapes the function altogether.","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"!!!note","category":"page"},{"location":"devdocs/llvm-passes/","page":"Custom LLVM Passes","title":"Custom LLVM Passes","text":"This pass is required to preserve LLVM's [MemorySSA](https://llvm.org/docs/MemorySSA.html) ([Short Video](https://www.youtube.com/watch?v=bdxWmryoHak), [Longer Video](https://www.youtube.com/watch?v=1e5y6WDbXCQ)) and [ScalarEvolution](https://baziotis.cs.illinois.edu/compilers/introduction-to-scalar-evolution.html) ([Newer Slides](https://llvm.org/devmtg/2018-04/slides/Absar-ScalarEvolution.pdf) [Older Slides](https://llvm.org/devmtg/2009-10/ScalarEvolutionAndLoopOptimization.pdf)) analyses.","category":"page"},{"location":"devdocs/callconv/#Calling-Conventions","page":"Calling Conventions","title":"Calling Conventions","text":"","category":"section"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"Julia uses three calling conventions for four distinct purposes:","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"Name Prefix Purpose\nNative julia_ Speed via specialized signatures\nJL Call jlcall_ Wrapper for generic calls\nJL Call jl_ Builtins\nC ABI jlcapi_ Wrapper callable from C","category":"page"},{"location":"devdocs/callconv/#Julia-Native-Calling-Convention","page":"Calling Conventions","title":"Julia Native Calling Convention","text":"","category":"section"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"The native calling convention is designed for fast non-generic calls. It usually uses a specialized signature.","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"LLVM ghosts (zero-length types) are omitted.\nLLVM scalars and vectors are passed by value.\nLLVM aggregates (arrays and structs) are passed by reference.","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"A small return values is returned as LLVM return values. A large return values is returned via the \"structure return\" (sret) convention, where the caller provides a pointer to a return slot.","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"An argument or return values that is a homogeneous tuple is sometimes represented as an LLVM vector instead of an LLVM array.","category":"page"},{"location":"devdocs/callconv/#JL-Call-Convention","page":"Calling Conventions","title":"JL Call Convention","text":"","category":"section"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"The JL Call convention is for builtins and generic dispatch. Hand-written functions using this convention are declared via the macro JL_CALLABLE. The convention uses exactly 3 parameters:","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"F - Julia representation of function that is being applied\nargs - pointer to array of pointers to boxes\nnargs - length of the array","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"The return value is a pointer to a box.","category":"page"},{"location":"devdocs/callconv/#C-ABI","page":"Calling Conventions","title":"C ABI","text":"","category":"section"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"C ABI wrappers enable calling Julia from C. The wrapper calls a function using the native calling convention.","category":"page"},{"location":"devdocs/callconv/","page":"Calling Conventions","title":"Calling Conventions","text":"Tuples are always represented as C arrays.","category":"page"},{"location":"devdocs/compiler/#High-level-Overview-of-the-Native-Code-Generation-Process","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"","category":"section"},{"location":"devdocs/compiler/#Representation-of-Pointers","page":"High-level Overview of the Native-Code Generation Process","title":"Representation of Pointers","text":"","category":"section"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"When emitting code to an object file, pointers will be emitted as relocations. The deserialization code will ensure any object that pointed to one of these constants gets recreated and contains the right runtime pointer.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Otherwise, they will be emitted as literal constants.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"To emit one of these objects, call literal_pointer_val. It'll handle tracking the Julia value and the LLVM global, ensuring they are valid both for the current runtime and after deserialization.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"When emitted into the object file, these globals are stored as references in a large gvals table. This allows the deserializer to reference them by index, and implement a custom manual mechanism similar to a Global Offset Table (GOT) to restore them.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Function pointers are handled similarly. They are stored as values in a large fvals table. Like globals, this allows the deserializer to reference them by index.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Note that extern functions are handled separately, with names, via the usual symbol resolution mechanism in the linker.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Note too that ccall functions are also handled separately, via a manual GOT and Procedure Linkage Table (PLT).","category":"page"},{"location":"devdocs/compiler/#Representation-of-Intermediate-Values","page":"High-level Overview of the Native-Code Generation Process","title":"Representation of Intermediate Values","text":"","category":"section"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Values are passed around in a jl_cgval_t struct. This represents an R-value, and includes enough information to determine how to assign or pass it somewhere.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"They are created via one of the helper constructors, usually: mark_julia_type (for immediate values) and mark_julia_slot (for pointers to values).","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The function convert_julia_type can transform between any two types. It returns an R-value with cgval.typ set to typ. It'll cast the object to the requested representation, making heap boxes, allocating stack copies, and computing tagged unions as needed to change the representation.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"By contrast update_julia_type will change cgval.typ to typ, only if it can be done at zero-cost (i.e. without emitting any code).","category":"page"},{"location":"devdocs/compiler/#Union-representation","page":"High-level Overview of the Native-Code Generation Process","title":"Union representation","text":"","category":"section"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Inferred union types may be stack allocated via a tagged type representation.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The primitive routines that need to be able to handle tagged unions are:","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"mark-type\nload-local\nstore-local\nisa\nis\nemit_typeof\nemit_sizeof\nboxed\nunbox\nspecialized cc-ret","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Everything else should be possible to handle in inference by using these primitives to implement union-splitting.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The representation of the tagged-union is as a pair of < void* union, byte selector >. The selector is fixed-size as byte & 0x7f, and will union-tag the first 126 isbits. It records the one-based depth-first count into the type-union of the isbits objects inside. An index of zero indicates that the union* is actually a tagged heap-allocated jl_value_t*, and needs to be treated as normal for a boxed object rather than as a tagged union.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The high bit of the selector (byte & 0x80) can be tested to determine if the void* is actually a heap-allocated (jl_value_t*) box, thus avoiding the cost of re-allocating a box, while maintaining the ability to efficiently handle union-splitting based on the low bits.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"It is guaranteed that byte & 0x7f is an exact test for the type, if the value can be represented by a tag – it will never be marked byte = 0x80. It is not necessary to also test the type-tag when testing isa.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The union* memory region may be allocated at any size. The only constraint is that it is big enough to contain the data currently specified by selector. It might not be big enough to contain the union of all types that could be stored there according to the associated Union type field. Use appropriate care when copying.","category":"page"},{"location":"devdocs/compiler/#Specialized-Calling-Convention-Signature-Representation","page":"High-level Overview of the Native-Code Generation Process","title":"Specialized Calling Convention Signature Representation","text":"","category":"section"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"A jl_returninfo_t object describes the calling convention details of any callable.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"If any of the arguments or return type of a method can be represented unboxed, and the method is not varargs, it'll be given an optimized calling convention signature based on its specTypes and rettype fields.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The general principles are that:","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Primitive types get passed in int/float registers.\nTuples of VecElement types get passed in vector registers.\nStructs get passed on the stack.\nReturn values are handle similarly to arguments, with a size-cutoff at which they will instead be returned via a hidden sret argument.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"The total logic for this is implemented by get_specsig_function and deserves_sret.","category":"page"},{"location":"devdocs/compiler/","page":"High-level Overview of the Native-Code Generation Process","title":"High-level Overview of the Native-Code Generation Process","text":"Additionally, if the return type is a union, it may be returned as a pair of values (a pointer and a tag). If the union values can be stack-allocated, then sufficient space to store them will also be passed as a hidden first argument. It is up to the callee whether the returned pointer will point to this space, a boxed object, or even other constant memory.","category":"page"},{"location":"base/parallel/#Tasks","page":"Tasks","title":"Tasks","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"Core.Task\nBase.@task\nBase.@async\nBase.asyncmap\nBase.asyncmap!\nBase.current_task\nBase.istaskdone\nBase.istaskstarted\nBase.istaskfailed\nBase.task_local_storage(::Any)\nBase.task_local_storage(::Any, ::Any)\nBase.task_local_storage(::Function, ::Any, ::Any)","category":"page"},{"location":"base/parallel/#Core.Task","page":"Tasks","title":"Core.Task","text":"Task(func)\n\nCreate a Task (i.e. coroutine) to execute the given function func (which must be callable with no arguments). The task exits when this function returns. The task will run in the \"world age\" from the parent at construction when scheduled.\n\nwarning: Warning\nBy default tasks will have the sticky bit set to true t.sticky. This models the historic default for @async. Sticky tasks can only be run on the worker thread they are first scheduled on. To obtain the behavior of Threads.@spawn set the sticky bit manually to false.\n\nExamples\n\njulia> a() = sum(i for i in 1:1000);\n\njulia> b = Task(a);\n\nIn this example, b is a runnable Task that hasn't started yet.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.@task","page":"Tasks","title":"Base.@task","text":"@task\n\nWrap an expression in a Task without executing it, and return the Task. This only creates a task, and does not run it.\n\nExamples\n\njulia> a1() = sum(i for i in 1:1000);\n\njulia> b = @task a1();\n\njulia> istaskstarted(b)\nfalse\n\njulia> schedule(b);\n\njulia> yield();\n\njulia> istaskdone(b)\ntrue\n\n\n\n\n\n","category":"macro"},{"location":"base/parallel/#Base.@async","page":"Tasks","title":"Base.@async","text":"@async\n\nWrap an expression in a Task and add it to the local machine's scheduler queue.\n\nValues can be interpolated into @async via $, which copies the value directly into the constructed underlying closure. This allows you to insert the value of a variable, isolating the asynchronous code from changes to the variable's value in the current task.\n\nwarning: Warning\nIt is strongly encouraged to favor Threads.@spawn over @async always even when no parallelism is required especially in publicly distributed libraries. This is because a use of @async disables the migration of the parent task across worker threads in the current implementation of Julia. Thus, seemingly innocent use of @async in a library function can have a large impact on the performance of very different parts of user applications.\n\ncompat: Julia 1.4\nInterpolating values via $ is available as of Julia 1.4.\n\n\n\n\n\n","category":"macro"},{"location":"base/parallel/#Base.asyncmap","page":"Tasks","title":"Base.asyncmap","text":"asyncmap(f, c...; ntasks=0, batch_size=nothing)\n\nUses multiple concurrent tasks to map f over a collection (or multiple equal length collections). For multiple collection arguments, f is applied elementwise.\n\nntasks specifies the number of tasks to run concurrently. Depending on the length of the collections, if ntasks is unspecified, up to 100 tasks will be used for concurrent mapping.\n\nntasks can also be specified as a zero-arg function. In this case, the number of tasks to run in parallel is checked before processing every element and a new task started if the value of ntasks_func is greater than the current number of tasks.\n\nIf batch_size is specified, the collection is processed in batch mode. f must then be a function that must accept a Vector of argument tuples and must return a vector of results. The input vector will have a length of batch_size or less.\n\nThe following examples highlight execution in different tasks by returning the objectid of the tasks in which the mapping function is executed.\n\nFirst, with ntasks undefined, each element is processed in a different task.\n\njulia> tskoid() = objectid(current_task());\n\njulia> asyncmap(x->tskoid(), 1:5)\n5-element Array{UInt64,1}:\n 0x6e15e66c75c75853\n 0x440f8819a1baa682\n 0x9fb3eeadd0c83985\n 0xebd3e35fe90d4050\n 0x29efc93edce2b961\n\njulia> length(unique(asyncmap(x->tskoid(), 1:5)))\n5\n\nWith ntasks=2 all elements are processed in 2 tasks.\n\njulia> asyncmap(x->tskoid(), 1:5; ntasks=2)\n5-element Array{UInt64,1}:\n 0x027ab1680df7ae94\n 0xa23d2f80cd7cf157\n 0x027ab1680df7ae94\n 0xa23d2f80cd7cf157\n 0x027ab1680df7ae94\n\njulia> length(unique(asyncmap(x->tskoid(), 1:5; ntasks=2)))\n2\n\nWith batch_size defined, the mapping function needs to be changed to accept an array of argument tuples and return an array of results. map is used in the modified mapping function to achieve this.\n\njulia> batch_func(input) = map(x->string(\"args_tuple: \", x, \", element_val: \", x[1], \", task: \", tskoid()), input)\nbatch_func (generic function with 1 method)\n\njulia> asyncmap(batch_func, 1:5; ntasks=2, batch_size=2)\n5-element Array{String,1}:\n \"args_tuple: (1,), element_val: 1, task: 9118321258196414413\"\n \"args_tuple: (2,), element_val: 2, task: 4904288162898683522\"\n \"args_tuple: (3,), element_val: 3, task: 9118321258196414413\"\n \"args_tuple: (4,), element_val: 4, task: 4904288162898683522\"\n \"args_tuple: (5,), element_val: 5, task: 9118321258196414413\"\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.asyncmap!","page":"Tasks","title":"Base.asyncmap!","text":"asyncmap!(f, results, c...; ntasks=0, batch_size=nothing)\n\nLike asyncmap, but stores output in results rather than returning a collection.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.current_task","page":"Tasks","title":"Base.current_task","text":"current_task()\n\nGet the currently running Task.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.istaskdone","page":"Tasks","title":"Base.istaskdone","text":"istaskdone(t::Task) -> Bool\n\nDetermine whether a task has exited.\n\nExamples\n\njulia> a2() = sum(i for i in 1:1000);\n\njulia> b = Task(a2);\n\njulia> istaskdone(b)\nfalse\n\njulia> schedule(b);\n\njulia> yield();\n\njulia> istaskdone(b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.istaskstarted","page":"Tasks","title":"Base.istaskstarted","text":"istaskstarted(t::Task) -> Bool\n\nDetermine whether a task has started executing.\n\nExamples\n\njulia> a3() = sum(i for i in 1:1000);\n\njulia> b = Task(a3);\n\njulia> istaskstarted(b)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.istaskfailed","page":"Tasks","title":"Base.istaskfailed","text":"istaskfailed(t::Task) -> Bool\n\nDetermine whether a task has exited because an exception was thrown.\n\nExamples\n\njulia> a4() = error(\"task failed\");\n\njulia> b = Task(a4);\n\njulia> istaskfailed(b)\nfalse\n\njulia> schedule(b);\n\njulia> yield();\n\njulia> istaskfailed(b)\ntrue\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.task_local_storage-Tuple{Any}","page":"Tasks","title":"Base.task_local_storage","text":"task_local_storage(key)\n\nLook up the value of a key in the current task's task-local storage.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.task_local_storage-Tuple{Any, Any}","page":"Tasks","title":"Base.task_local_storage","text":"task_local_storage(key, value)\n\nAssign a value to a key in the current task's task-local storage.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.task_local_storage-Tuple{Function, Any, Any}","page":"Tasks","title":"Base.task_local_storage","text":"task_local_storage(body, key, value)\n\nCall the function body with a modified task-local storage, in which value is assigned to key; the previous value of key, or lack thereof, is restored afterwards. Useful for emulating dynamic scoping.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Scheduling","page":"Tasks","title":"Scheduling","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"Base.yield\nBase.yieldto\nBase.sleep\nBase.schedule","category":"page"},{"location":"base/parallel/#Base.yield","page":"Tasks","title":"Base.yield","text":"yield()\n\nSwitch to the scheduler to allow another scheduled task to run. A task that calls this function is still runnable, and will be restarted immediately if there are no other runnable tasks.\n\n\n\n\n\nyield(t::Task, arg = nothing)\n\nA fast, unfair-scheduling version of schedule(t, arg); yield() which immediately yields to t before calling the scheduler.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.yieldto","page":"Tasks","title":"Base.yieldto","text":"yieldto(t::Task, arg = nothing)\n\nSwitch to the given task. The first time a task is switched to, the task's function is called with no arguments. On subsequent switches, arg is returned from the task's last call to yieldto. This is a low-level call that only switches tasks, not considering states or scheduling in any way. Its use is discouraged.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.sleep","page":"Tasks","title":"Base.sleep","text":"sleep(seconds)\n\nBlock the current task for a specified number of seconds. The minimum sleep time is 1 millisecond or input of 0.001.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.schedule","page":"Tasks","title":"Base.schedule","text":"schedule(t::Task, [val]; error=false)\n\nAdd a Task to the scheduler's queue. This causes the task to run constantly when the system is otherwise idle, unless the task performs a blocking operation such as wait.\n\nIf a second argument val is provided, it will be passed to the task (via the return value of yieldto) when it runs again. If error is true, the value is raised as an exception in the woken task.\n\nwarning: Warning\nIt is incorrect to use schedule on an arbitrary Task that has already been started. See the API reference for more information.\n\nExamples\n\njulia> a5() = sum(i for i in 1:1000);\n\njulia> b = Task(a5);\n\njulia> istaskstarted(b)\nfalse\n\njulia> schedule(b);\n\njulia> yield();\n\njulia> istaskstarted(b)\ntrue\n\njulia> istaskdone(b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#lib-task-sync","page":"Tasks","title":"Synchronization","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"Base.errormonitor\nBase.@sync\nBase.wait\nBase.waitany\nBase.waitall\nBase.fetch(t::Task)\nBase.fetch(x::Any)\nBase.timedwait\n\nBase.Condition\nBase.Threads.Condition\nBase.Threads.Event\nBase.notify\nBase.reset(::Base.Threads.Event)\n\nBase.Semaphore\nBase.acquire\nBase.release\n\nBase.AbstractLock\nBase.lock\nBase.unlock\nBase.trylock\nBase.islocked\nBase.ReentrantLock\nBase.@lock\nBase.Lockable","category":"page"},{"location":"base/parallel/#Base.errormonitor","page":"Tasks","title":"Base.errormonitor","text":"errormonitor(t::Task)\n\nPrint an error log to stderr if task t fails.\n\nExamples\n\njulia> Base._wait(errormonitor(Threads.@spawn error(\"task failed\")))\nUnhandled Task ERROR: task failed\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.@sync","page":"Tasks","title":"Base.@sync","text":"@sync\n\nWait until all lexically-enclosed uses of @async, @spawn, Distributed.@spawnat and Distributed.@distributed are complete. All exceptions thrown by enclosed async operations are collected and thrown as a CompositeException.\n\nExamples\n\njulia> Threads.nthreads()\n4\n\njulia> @sync begin\n Threads.@spawn println(\"Thread-id $(Threads.threadid()), task 1\")\n Threads.@spawn println(\"Thread-id $(Threads.threadid()), task 2\")\n end;\nThread-id 3, task 1\nThread-id 1, task 2\n\n\n\n\n\n","category":"macro"},{"location":"base/parallel/#Base.wait","page":"Tasks","title":"Base.wait","text":"Special note for Threads.Condition:\n\nThe caller must be holding the lock that owns a Threads.Condition before calling this method. The calling task will be blocked until some other task wakes it, usually by calling notify on the same Threads.Condition object. The lock will be atomically released when blocking (even if it was locked recursively), and will be reacquired before returning.\n\n\n\n\n\nwait(r::Future)\n\nWait for a value to become available for the specified Future.\n\n\n\n\n\nwait(r::RemoteChannel, args...)\n\nWait for a value to become available on the specified RemoteChannel.\n\n\n\n\n\nwait([x])\n\nBlock the current task until some event occurs, depending on the type of the argument:\n\nChannel: Wait for a value to be appended to the channel.\nCondition: Wait for notify on a condition and return the val parameter passed to notify. Waiting on a condition additionally allows passing first=true which results in the waiter being put first in line to wake up on notify instead of the usual first-in-first-out behavior.\nProcess: Wait for a process or process chain to exit. The exitcode field of a process can be used to determine success or failure.\nTask: Wait for a Task to finish. If the task fails with an exception, a TaskFailedException (which wraps the failed task) is thrown. Waiting on a task additionally allows passing throw=false which prevents throwing a TaskFailedException when the task fails.\nRawFD: Wait for changes on a file descriptor (see the FileWatching package).\n\nIf no argument is passed, the task blocks for an undefined period. A task can only be restarted by an explicit call to schedule or yieldto.\n\nOften wait is called within a while loop to ensure a waited-for condition is met before proceeding.\n\n\n\n\n\nwait(c::Channel)\n\nBlocks until the Channel isready.\n\njulia> c = Channel(1);\n\njulia> isready(c)\nfalse\n\njulia> task = Task(() -> wait(c));\n\njulia> schedule(task);\n\njulia> istaskdone(task) # task is blocked because channel is not ready\nfalse\n\njulia> put!(c, 1);\n\njulia> istaskdone(task) # task is now unblocked\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.waitany","page":"Tasks","title":"Base.waitany","text":"waitany(tasks; throw=true) -> (done_tasks, remaining_tasks)\n\nWait until at least one of the given tasks have been completed.\n\nIf throw is true, throw CompositeException when one of the completed tasks completes with an exception.\n\nThe return value consists of two task vectors. The first one consists of completed tasks, and the other consists of uncompleted tasks.\n\nwarning: Warning\nThis may scale poorly compared to writing code that uses multiple individual tasks that each runs serially, since this needs to scan the list of tasks each time and synchronize with each one every time this is called. Or consider using waitall(tasks; failfast=true) instead.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.waitall","page":"Tasks","title":"Base.waitall","text":"waitall(tasks; failfast=true, throw=true) -> (done_tasks, remaining_tasks)\n\nWait until all the given tasks have been completed.\n\nIf failfast is true, the function will return when at least one of the given tasks is finished by exception. If throw is true, throw CompositeException when one of the completed tasks has failed.\n\nfailfast and throw keyword arguments work independently; when only throw=true is specified, this function waits for all the tasks to complete.\n\nThe return value consists of two task vectors. The first one consists of completed tasks, and the other consists of uncompleted tasks.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.fetch-Tuple{Task}","page":"Tasks","title":"Base.fetch","text":"fetch(t::Task)\n\nWait for a Task to finish, then return its result value. If the task fails with an exception, a TaskFailedException (which wraps the failed task) is thrown.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.fetch-Tuple{Any}","page":"Tasks","title":"Base.fetch","text":"fetch(x::Any)\n\nReturn x.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.timedwait","page":"Tasks","title":"Base.timedwait","text":"timedwait(testcb, timeout::Real; pollint::Real=0.1)\n\nWait until testcb() returns true or timeout seconds have passed, whichever is earlier. The test function is polled every pollint seconds. The minimum value for pollint is 0.001 seconds, that is, 1 millisecond.\n\nReturn :ok or :timed_out.\n\nExamples\n\njulia> cb() = (sleep(5); return);\n\njulia> t = @async cb();\n\njulia> timedwait(()->istaskdone(t), 1)\n:timed_out\n\njulia> timedwait(()->istaskdone(t), 6.5)\n:ok\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.Condition","page":"Tasks","title":"Base.Condition","text":"Condition()\n\nCreate an edge-triggered event source that tasks can wait for. Tasks that call wait on a Condition are suspended and queued. Tasks are woken up when notify is later called on the Condition. Waiting on a condition can return a value or raise an error if the optional arguments of notify are used. Edge triggering means that only tasks waiting at the time notify is called can be woken up. For level-triggered notifications, you must keep extra state to keep track of whether a notification has happened. The Channel and Threads.Event types do this, and can be used for level-triggered events.\n\nThis object is NOT thread-safe. See Threads.Condition for a thread-safe version.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.Threads.Condition","page":"Tasks","title":"Base.Threads.Condition","text":"Threads.Condition([lock])\n\nA thread-safe version of Base.Condition.\n\nTo call wait or notify on a Threads.Condition, you must first call lock on it. When wait is called, the lock is atomically released during blocking, and will be reacquired before wait returns. Therefore idiomatic use of a Threads.Condition c looks like the following:\n\nlock(c)\ntry\n while !thing_we_are_waiting_for\n wait(c)\n end\nfinally\n unlock(c)\nend\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.Event","page":"Tasks","title":"Base.Event","text":"Event([autoreset=false])\n\nCreate a level-triggered event source. Tasks that call wait on an Event are suspended and queued until notify is called on the Event. After notify is called, the Event remains in a signaled state and tasks will no longer block when waiting for it, until reset is called.\n\nIf autoreset is true, at most one task will be released from wait for each call to notify.\n\nThis provides an acquire & release memory ordering on notify/wait.\n\ncompat: Julia 1.1\nThis functionality requires at least Julia 1.1.\n\ncompat: Julia 1.8\nThe autoreset functionality and memory ordering guarantee requires at least Julia 1.8.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.notify","page":"Tasks","title":"Base.notify","text":"notify(condition, val=nothing; all=true, error=false)\n\nWake up tasks waiting for a condition, passing them val. If all is true (the default), all waiting tasks are woken, otherwise only one is. If error is true, the passed value is raised as an exception in the woken tasks.\n\nReturn the count of tasks woken up. Return 0 if no tasks are waiting on condition.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.reset-Tuple{Base.Event}","page":"Tasks","title":"Base.reset","text":"reset(::Event)\n\nReset an Event back into an un-set state. Then any future calls to wait will block until notify is called again.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.Semaphore","page":"Tasks","title":"Base.Semaphore","text":"Semaphore(sem_size)\n\nCreate a counting semaphore that allows at most sem_size acquires to be in use at any time. Each acquire must be matched with a release.\n\nThis provides a acquire & release memory ordering on acquire/release calls.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.acquire","page":"Tasks","title":"Base.acquire","text":"acquire(s::Semaphore)\n\nWait for one of the sem_size permits to be available, blocking until one can be acquired.\n\n\n\n\n\nacquire(f, s::Semaphore)\n\nExecute f after acquiring from Semaphore s, and release on completion or error.\n\nFor example, a do-block form that ensures only 2 calls of foo will be active at the same time:\n\ns = Base.Semaphore(2)\n@sync for _ in 1:100\n Threads.@spawn begin\n Base.acquire(s) do\n foo()\n end\n end\nend\n\ncompat: Julia 1.8\nThis method requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.release","page":"Tasks","title":"Base.release","text":"release(s::Semaphore)\n\nReturn one permit to the pool, possibly allowing another task to acquire it and resume execution.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.AbstractLock","page":"Tasks","title":"Base.AbstractLock","text":"AbstractLock\n\nAbstract supertype describing types that implement the synchronization primitives: lock, trylock, unlock, and islocked.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.lock","page":"Tasks","title":"Base.lock","text":"lock(lock)\n\nAcquire the lock when it becomes available. If the lock is already locked by a different task/thread, wait for it to become available.\n\nEach lock must be matched by an unlock.\n\n\n\n\n\nlock(f::Function, lock)\n\nAcquire the lock, execute f with the lock held, and release the lock when f returns. If the lock is already locked by a different task/thread, wait for it to become available.\n\nWhen this function returns, the lock has been released, so the caller should not attempt to unlock it.\n\nSee also: @lock.\n\ncompat: Julia 1.7\nUsing a Channel as the second argument requires Julia 1.7 or later.\n\n\n\n\n\nlock(f::Function, l::Lockable)\n\nAcquire the lock associated with l, execute f with the lock held, and release the lock when f returns. f will receive one positional argument: the value wrapped by l. If the lock is already locked by a different task/thread, wait for it to become available. When this function returns, the lock has been released, so the caller should not attempt to unlock it.\n\ncompat: Julia 1.11\nRequires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.unlock","page":"Tasks","title":"Base.unlock","text":"unlock(lock)\n\nReleases ownership of the lock.\n\nIf this is a recursive lock which has been acquired before, decrement an internal counter and return immediately.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.trylock","page":"Tasks","title":"Base.trylock","text":"trylock(lock) -> Success (Boolean)\n\nAcquire the lock if it is available, and return true if successful. If the lock is already locked by a different task/thread, return false.\n\nEach successful trylock must be matched by an unlock.\n\nFunction trylock combined with islocked can be used for writing the test-and-test-and-set or exponential backoff algorithms if it is supported by the typeof(lock) (read its documentation).\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.islocked","page":"Tasks","title":"Base.islocked","text":"islocked(lock) -> Status (Boolean)\n\nCheck whether the lock is held by any task/thread. This function alone should not be used for synchronization. However, islocked combined with trylock can be used for writing the test-and-test-and-set or exponential backoff algorithms if it is supported by the typeof(lock) (read its documentation).\n\nExtended help\n\nFor example, an exponential backoff can be implemented as follows if the lock implementation satisfied the properties documented below.\n\nnspins = 0\nwhile true\n while islocked(lock)\n GC.safepoint()\n nspins += 1\n nspins > LIMIT && error(\"timeout\")\n end\n trylock(lock) && break\n backoff()\nend\n\nImplementation\n\nA lock implementation is advised to define islocked with the following properties and note it in its docstring.\n\nislocked(lock) is data-race-free.\nIf islocked(lock) returns false, an immediate invocation of trylock(lock) must succeed (returns true) if there is no interference from other tasks.\n\n\n\n\n\n","category":"function"},{"location":"base/parallel/#Base.ReentrantLock","page":"Tasks","title":"Base.ReentrantLock","text":"ReentrantLock()\n\nCreates a re-entrant lock for synchronizing Tasks. The same task can acquire the lock as many times as required (this is what the \"Reentrant\" part of the name means). Each lock must be matched with an unlock.\n\nCalling lock will also inhibit running of finalizers on that thread until the corresponding unlock. Use of the standard lock pattern illustrated below should naturally be supported, but beware of inverting the try/lock order or missing the try block entirely (e.g. attempting to return with the lock still held):\n\nThis provides a acquire/release memory ordering on lock/unlock calls.\n\nlock(l)\ntry\n \nfinally\n unlock(l)\nend\n\nIf !islocked(lck::ReentrantLock) holds, trylock(lck) succeeds unless there are other tasks attempting to hold the lock \"at the same time.\"\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.@lock","page":"Tasks","title":"Base.@lock","text":"@lock l expr\n\nMacro version of lock(f, l::AbstractLock) but with expr instead of f function. Expands to:\n\nlock(l)\ntry\n expr\nfinally\n unlock(l)\nend\n\nThis is similar to using lock with a do block, but avoids creating a closure and thus can improve the performance.\n\ncompat: Compat\n@lock was added in Julia 1.3, and exported in Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"base/parallel/#Base.Lockable","page":"Tasks","title":"Base.Lockable","text":"Lockable(value, lock = ReentrantLock())\n\nCreates a Lockable object that wraps value and associates it with the provided lock. This object supports @lock, lock, trylock, unlock. To access the value, index the lockable object while holding the lock.\n\ncompat: Julia 1.11\nRequires at least Julia 1.11.\n\nExample\n\njulia> locked_list = Base.Lockable(Int[]);\n\njulia> @lock(locked_list, push!(locked_list[], 1)) # must hold the lock to access the value\n1-element Vector{Int64}:\n 1\n\njulia> lock(summary, locked_list)\n\"1-element Vector{Int64}\"\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Channels","page":"Tasks","title":"Channels","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"Base.AbstractChannel\nBase.Channel\nBase.Channel(::Function)\nBase.put!(::Channel, ::Any)\nBase.take!(::Channel)\nBase.isfull(::Channel)\nBase.isready(::Channel)\nBase.fetch(::Channel)\nBase.close(::Channel)\nBase.bind(c::Channel, task::Task)","category":"page"},{"location":"base/parallel/#Base.AbstractChannel","page":"Tasks","title":"Base.AbstractChannel","text":"AbstractChannel{T}\n\nRepresentation of a channel passing objects of type T.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.Channel","page":"Tasks","title":"Base.Channel","text":"Channel{T=Any}(size::Int=0)\n\nConstructs a Channel with an internal buffer that can hold a maximum of size objects of type T. put! calls on a full channel block until an object is removed with take!.\n\nChannel(0) constructs an unbuffered channel. put! blocks until a matching take! is called. And vice-versa.\n\nOther constructors:\n\nChannel(): default constructor, equivalent to Channel{Any}(0)\nChannel(Inf): equivalent to Channel{Any}(typemax(Int))\nChannel(sz): equivalent to Channel{Any}(sz)\n\ncompat: Julia 1.3\nThe default constructor Channel() and default size=0 were added in Julia 1.3.\n\n\n\n\n\n","category":"type"},{"location":"base/parallel/#Base.Channel-Tuple{Function}","page":"Tasks","title":"Base.Channel","text":"Channel{T=Any}(func::Function, size=0; taskref=nothing, spawn=false, threadpool=nothing)\n\nCreate a new task from func, bind it to a new channel of type T and size size, and schedule the task, all in a single call. The channel is automatically closed when the task terminates.\n\nfunc must accept the bound channel as its only argument.\n\nIf you need a reference to the created task, pass a Ref{Task} object via the keyword argument taskref.\n\nIf spawn=true, the Task created for func may be scheduled on another thread in parallel, equivalent to creating a task via Threads.@spawn.\n\nIf spawn=true and the threadpool argument is not set, it defaults to :default.\n\nIf the threadpool argument is set (to :default or :interactive), this implies that spawn=true and the new Task is spawned to the specified threadpool.\n\nReturn a Channel.\n\nExamples\n\njulia> chnl = Channel() do ch\n foreach(i -> put!(ch, i), 1:4)\n end;\n\njulia> typeof(chnl)\nChannel{Any}\n\njulia> for i in chnl\n @show i\n end;\ni = 1\ni = 2\ni = 3\ni = 4\n\nReferencing the created task:\n\njulia> taskref = Ref{Task}();\n\njulia> chnl = Channel(taskref=taskref) do ch\n println(take!(ch))\n end;\n\njulia> istaskdone(taskref[])\nfalse\n\njulia> put!(chnl, \"Hello\");\nHello\n\njulia> istaskdone(taskref[])\ntrue\n\ncompat: Julia 1.3\nThe spawn= parameter was added in Julia 1.3. This constructor was added in Julia 1.3. In earlier versions of Julia, Channel used keyword arguments to set size and T, but those constructors are deprecated.\n\ncompat: Julia 1.9\nThe threadpool= argument was added in Julia 1.9.\n\njulia> chnl = Channel{Char}(1, spawn=true) do ch\n for c in \"hello world\"\n put!(ch, c)\n end\n end\nChannel{Char}(1) (2 items available)\n\njulia> String(collect(chnl))\n\"hello world\"\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.put!-Tuple{Channel, Any}","page":"Tasks","title":"Base.put!","text":"put!(c::Channel, v)\n\nAppend an item v to the channel c. Blocks if the channel is full.\n\nFor unbuffered channels, blocks until a take! is performed by a different task.\n\ncompat: Julia 1.1\nv now gets converted to the channel's type with convert as put! is called.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.take!-Tuple{Channel}","page":"Tasks","title":"Base.take!","text":"take!(c::Channel)\n\nRemoves and returns a value from a Channel in order. Blocks until data is available. For unbuffered channels, blocks until a put! is performed by a different task.\n\nExamples\n\nBuffered channel:\n\njulia> c = Channel(1);\n\njulia> put!(c, 1);\n\njulia> take!(c)\n1\n\nUnbuffered channel:\n\njulia> c = Channel(0);\n\njulia> task = Task(() -> put!(c, 1));\n\njulia> schedule(task);\n\njulia> take!(c)\n1\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.isfull-Tuple{Channel}","page":"Tasks","title":"Base.isfull","text":"isfull(c::Channel)\n\nDetermines if a Channel is full, in the sense that calling put!(c, some_value) would have blocked. Returns immediately, does not block.\n\nNote that it may frequently be the case that put! will not block after this returns true. Users must take precautions not to accidentally create live-lock bugs in their code by calling this method, as these are generally harder to debug than deadlocks. It is also possible that put! will block after this call returns false, if there are multiple producer tasks calling put! in parallel.\n\nExamples\n\nBuffered channel:\n\njulia> c = Channel(1); # capacity = 1\n\njulia> isfull(c)\nfalse\n\njulia> put!(c, 1);\n\njulia> isfull(c)\ntrue\n\nUnbuffered channel:\n\njulia> c = Channel(); # capacity = 0\n\njulia> isfull(c) # unbuffered channel is always full\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.isready-Tuple{Channel}","page":"Tasks","title":"Base.isready","text":"isready(c::Channel)\n\nDetermines whether a Channel has a value stored in it. Returns immediately, does not block.\n\nFor unbuffered channels, return true if there are tasks waiting on a put!.\n\nExamples\n\nBuffered channel:\n\njulia> c = Channel(1);\n\njulia> isready(c)\nfalse\n\njulia> put!(c, 1);\n\njulia> isready(c)\ntrue\n\nUnbuffered channel:\n\njulia> c = Channel();\n\njulia> isready(c) # no tasks waiting to put!\nfalse\n\njulia> task = Task(() -> put!(c, 1));\n\njulia> schedule(task); # schedule a put! task\n\njulia> isready(c)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.fetch-Tuple{Channel}","page":"Tasks","title":"Base.fetch","text":"fetch(c::Channel)\n\nWaits for and returns (without removing) the first available item from the Channel. Note: fetch is unsupported on an unbuffered (0-size) Channel.\n\nExamples\n\nBuffered channel:\n\njulia> c = Channel(3) do ch\n foreach(i -> put!(ch, i), 1:3)\n end;\n\njulia> fetch(c)\n1\n\njulia> collect(c) # item is not removed\n3-element Vector{Any}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.close-Tuple{Channel}","page":"Tasks","title":"Base.close","text":"close(c::Channel[, excp::Exception])\n\nClose a channel. An exception (optionally given by excp), is thrown by:\n\nput! on a closed channel.\ntake! and fetch on an empty, closed channel.\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#Base.bind-Tuple{Channel, Task}","page":"Tasks","title":"Base.bind","text":"bind(chnl::Channel, task::Task)\n\nAssociate the lifetime of chnl with a task. Channel chnl is automatically closed when the task terminates. Any uncaught exception in the task is propagated to all waiters on chnl.\n\nThe chnl object can be explicitly closed independent of task termination. Terminating tasks have no effect on already closed Channel objects.\n\nWhen a channel is bound to multiple tasks, the first task to terminate will close the channel. When multiple channels are bound to the same task, termination of the task will close all of the bound channels.\n\nExamples\n\njulia> c = Channel(0);\n\njulia> task = @async foreach(i->put!(c, i), 1:4);\n\njulia> bind(c,task);\n\njulia> for i in c\n @show i\n end;\ni = 1\ni = 2\ni = 3\ni = 4\n\njulia> isopen(c)\nfalse\n\njulia> c = Channel(0);\n\njulia> task = @async (put!(c, 1); error(\"foo\"));\n\njulia> bind(c, task);\n\njulia> take!(c)\n1\n\njulia> put!(c, 1);\nERROR: TaskFailedException\nStacktrace:\n[...]\n nested task error: foo\n[...]\n\n\n\n\n\n","category":"method"},{"location":"base/parallel/#low-level-schedule-wait","page":"Tasks","title":"Low-level synchronization using schedule and wait","text":"","category":"section"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"The easiest correct use of schedule is on a Task that is not started (scheduled) yet. However, it is possible to use schedule and wait as a very low-level building block for constructing synchronization interfaces. A crucial pre-condition of calling schedule(task) is that the caller must \"own\" the task; i.e., it must know that the call to wait in the given task is happening at the locations known to the code calling schedule(task). One strategy for ensuring such pre-condition is to use atomics, as demonstrated in the following example:","category":"page"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"@enum OWEState begin\n OWE_EMPTY\n OWE_WAITING\n OWE_NOTIFYING\nend\n\nmutable struct OneWayEvent\n @atomic state::OWEState\n task::Task\n OneWayEvent() = new(OWE_EMPTY)\nend\n\nfunction Base.notify(ev::OneWayEvent)\n state = @atomic ev.state\n while state !== OWE_NOTIFYING\n # Spin until we successfully update the state to OWE_NOTIFYING:\n state, ok = @atomicreplace(ev.state, state => OWE_NOTIFYING)\n if ok\n if state == OWE_WAITING\n # OWE_WAITING -> OWE_NOTIFYING transition means that the waiter task is\n # already waiting or about to call `wait`. The notifier task must wake up\n # the waiter task.\n schedule(ev.task)\n else\n @assert state == OWE_EMPTY\n # Since we are assuming that there is only one notifier task (for\n # simplicity), we know that the other possible case here is OWE_EMPTY.\n # We do not need to do anything because we know that the waiter task has\n # not called `wait(ev::OneWayEvent)` yet.\n end\n break\n end\n end\n return\nend\n\nfunction Base.wait(ev::OneWayEvent)\n ev.task = current_task()\n state, ok = @atomicreplace(ev.state, OWE_EMPTY => OWE_WAITING)\n if ok\n # OWE_EMPTY -> OWE_WAITING transition means that the notifier task is guaranteed to\n # invoke OWE_WAITING -> OWE_NOTIFYING transition. The waiter task must call\n # `wait()` immediately. In particular, it MUST NOT invoke any function that may\n # yield to the scheduler at this point in code.\n wait()\n else\n @assert state == OWE_NOTIFYING\n # Otherwise, the `state` must have already been moved to OWE_NOTIFYING by the\n # notifier task.\n end\n return\nend\n\nev = OneWayEvent()\n@sync begin\n @async begin\n wait(ev)\n println(\"done\")\n end\n println(\"notifying...\")\n notify(ev)\nend\n\n# output\nnotifying...\ndone","category":"page"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"OneWayEvent lets one task to wait for another task's notify. It is a limited communication interface since wait can only be used once from a single task (note the non-atomic assignment of ev.task)","category":"page"},{"location":"base/parallel/","page":"Tasks","title":"Tasks","text":"In this example, notify(ev::OneWayEvent) is allowed to call schedule(ev.task) if and only if it modifies the state from OWE_WAITING to OWE_NOTIFYING. This lets us know that the task executing wait(ev::OneWayEvent) is now in the ok branch and that there cannot be other tasks that tries to schedule(ev.task) since their @atomicreplace(ev.state, state => OWE_NOTIFYING) will fail.","category":"page"},{"location":"manual/arrays/#man-multi-dim-arrays","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Julia, like most technical computing languages, provides a first-class array implementation. Most technical computing languages pay a lot of attention to their array implementation at the expense of other containers. Julia does not treat arrays in any special way. The array library is implemented almost completely in Julia itself, and derives its performance from the compiler, just like any other code written in Julia. As such, it's also possible to define custom array types by inheriting from AbstractArray. See the manual section on the AbstractArray interface for more details on implementing a custom array type.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"An array is a collection of objects stored in a multi-dimensional grid. Zero-dimensional arrays are allowed, see this FAQ entry. In the most general case, an array may contain objects of type Any. For most computational purposes, arrays should contain objects of a more specific type, such as Float64 or Int32.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In general, unlike many other technical computing languages, Julia does not expect programs to be written in a vectorized style for performance. Julia's compiler uses type inference and generates optimized code for scalar array indexing, allowing programs to be written in a style that is convenient and readable, without sacrificing performance, and using less memory at times.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In Julia, all arguments to functions are passed by sharing (i.e. by pointers). Some technical computing languages pass arrays by value, and while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a ! indicates that it will mutate or destroy the value of one or more of its arguments (compare, for example, sort and sort!). Callees must make explicit copies to ensure that they don't modify inputs that they don't intend to change. Many non-mutating functions are implemented by calling a function of the same name with an added ! at the end on an explicit copy of the input, and returning that copy.","category":"page"},{"location":"manual/arrays/#Basic-Functions","page":"Single- and multi-dimensional Arrays","title":"Basic Functions","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Function Description\neltype(A) the type of the elements contained in A\nlength(A) the number of elements in A\nndims(A) the number of dimensions of A\nsize(A) a tuple containing the dimensions of A\nsize(A,n) the size of A along dimension n\naxes(A) a tuple containing the valid indices of A\naxes(A,n) a range expressing the valid indices along dimension n\neachindex(A) an efficient iterator for visiting each position in A\nstride(A,k) the stride (linear index distance between adjacent elements) along dimension k\nstrides(A) a tuple of the strides in each dimension","category":"page"},{"location":"manual/arrays/#Construction-and-Initialization","page":"Single- and multi-dimensional Arrays","title":"Construction and Initialization","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Many functions for constructing and initializing arrays are provided. In the following list of such functions, calls with a dims... argument can either take a single tuple of dimension sizes or a series of dimension sizes passed as a variable number of arguments. Most of these functions also accept a first input T, which is the element type of the array. If the type T is omitted it will default to Float64.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Function Description\nArray{T}(undef, dims...) an uninitialized dense Array\nzeros(T, dims...) an Array of all zeros\nones(T, dims...) an Array of all ones\ntrues(dims...) a BitArray with all values true\nfalses(dims...) a BitArray with all values false\nreshape(A, dims...) an array containing the same data as A, but with different dimensions\ncopy(A) copy A\ndeepcopy(A) copy A, recursively copying its elements\nsimilar(A, T, dims...) an uninitialized array of the same type as A (dense, sparse, etc.), but with the specified element type and dimensions. The second and third arguments are both optional, defaulting to the element type and dimensions of A if omitted.\nreinterpret(T, A) an array with the same binary data as A, but with element type T\nrand(T, dims...) an Array with random, iid [1] and uniformly distributed values. For floating point types T, the values lie in the half-open interval 0 1).\nrandn(T, dims...) an Array with random, iid and standard normally distributed values\nMatrix{T}(I, m, n) m-by-n identity matrix. Requires using LinearAlgebra for I.\nrange(start, stop, n) a range of n linearly spaced elements from start to stop\nfill!(A, x) fill the array A with the value x\nfill(x, dims...) an Array filled with the value x. In particular, fill(x) constructs a zero-dimensional Array containing x.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"[1]: iid, independently and identically distributed.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"To see the various ways we can pass dimensions to these functions, consider the following examples:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> zeros(Int8, 2, 3)\n2×3 Matrix{Int8}:\n 0 0 0\n 0 0 0\n\njulia> zeros(Int8, (2, 3))\n2×3 Matrix{Int8}:\n 0 0 0\n 0 0 0\n\njulia> zeros((2, 3))\n2×3 Matrix{Float64}:\n 0.0 0.0 0.0\n 0.0 0.0 0.0","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Here, (2, 3) is a Tuple and the first argument — the element type — is optional, defaulting to Float64.","category":"page"},{"location":"manual/arrays/#man-array-literals","page":"Single- and multi-dimensional Arrays","title":"Array literals","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Arrays can also be directly constructed with square braces; the syntax [A, B, C, ...] creates a one-dimensional array (i.e., a vector) containing the comma-separated arguments as its elements. The element type (eltype) of the resulting array is automatically determined by the types of the arguments inside the braces. If all the arguments are the same type, then that is its eltype. If they all have a common promotion type then they get converted to that type using convert and that type is the array's eltype. Otherwise, a heterogeneous array that can hold anything — a Vector{Any} — is constructed; this includes the literal [] where no arguments are given. Array literal can be typed with the syntax T[A, B, C, ...] where T is a type.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1, 2, 3] # An array of `Int`s\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> promote(1, 2.3, 4//5) # This combination of Int, Float64 and Rational promotes to Float64\n(1.0, 2.3, 0.8)\n\njulia> [1, 2.3, 4//5] # Thus that's the element type of this Array\n3-element Vector{Float64}:\n 1.0\n 2.3\n 0.8\n\njulia> Float32[1, 2.3, 4//5] # Specify element type manually\n3-element Vector{Float32}:\n 1.0\n 2.3\n 0.8\n\njulia> []\nAny[]","category":"page"},{"location":"manual/arrays/#man-array-concatenation","page":"Single- and multi-dimensional Arrays","title":"Concatenation","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If the arguments inside the square brackets are separated by single semicolons (;) or newlines instead of commas, then their contents are vertically concatenated together instead of the arguments being used as elements themselves.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1:2, 4:5] # Has a comma, so no concatenation occurs. The ranges are themselves the elements\n2-element Vector{UnitRange{Int64}}:\n 1:2\n 4:5\n\njulia> [1:2; 4:5]\n4-element Vector{Int64}:\n 1\n 2\n 4\n 5\n\njulia> [1:2\n 4:5\n 6]\n5-element Vector{Int64}:\n 1\n 2\n 4\n 5\n 6","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Similarly, if the arguments are separated by tabs or spaces or double semicolons, then their contents are horizontally concatenated together.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1:2 4:5 7:8]\n2×3 Matrix{Int64}:\n 1 4 7\n 2 5 8\n\njulia> [[1,2] [4,5] [7,8]]\n2×3 Matrix{Int64}:\n 1 4 7\n 2 5 8\n\njulia> [1 2 3] # Numbers can also be horizontally concatenated\n1×3 Matrix{Int64}:\n 1 2 3\n\njulia> [1;; 2;; 3;; 4]\n1×4 Matrix{Int64}:\n 1 2 3 4","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Single semicolons (or newlines) and spaces (or tabs) can be combined to concatenate both horizontally and vertically at the same time.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1 2\n 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> [zeros(Int, 2, 2) [1; 2]\n [3 4] 5]\n3×3 Matrix{Int64}:\n 0 0 1\n 0 0 2\n 3 4 5\n\njulia> [[1 1]; 2 3; [4 4]]\n3×2 Matrix{Int64}:\n 1 1\n 2 3\n 4 4","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Spaces (and tabs) have a higher precedence than semicolons, performing any horizontal concatenations first and then concatenating the result. Using double semicolons for the horizontal concatenation, on the other hand, performs any vertical concatenations before horizontally concatenating the result.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [zeros(Int, 2, 2) ; [3 4] ;; [1; 2] ; 5]\n3×3 Matrix{Int64}:\n 0 0 1\n 0 0 2\n 3 4 5\n\njulia> [1:2; 4;; 1; 3:4]\n3×2 Matrix{Int64}:\n 1 1\n 2 3\n 4 4","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Just as ; and ;; concatenate in the first and second dimension, using more semicolons extends this same general scheme. The number of semicolons in the separator specifies the particular dimension, so ;;; concatenates in the third dimension, ;;;; in the 4th, and so on. Fewer semicolons take precedence, so the lower dimensions are generally concatenated first.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1; 2;; 3; 4;; 5; 6;;;\n 7; 8;; 9; 10;; 11; 12]\n2×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 3 5\n 2 4 6\n\n[:, :, 2] =\n 7 9 11\n 8 10 12","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Like before, spaces (and tabs) for horizontal concatenation have a higher precedence than any number of semicolons. Thus, higher-dimensional arrays can also be written by specifying their rows first, with their elements textually arranged in a manner similar to their layout:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1 3 5\n 2 4 6;;;\n 7 9 11\n 8 10 12]\n2×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 3 5\n 2 4 6\n\n[:, :, 2] =\n 7 9 11\n 8 10 12\n\njulia> [1 2;;; 3 4;;;; 5 6;;; 7 8]\n1×2×2×2 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 2\n\n[:, :, 2, 1] =\n 3 4\n\n[:, :, 1, 2] =\n 5 6\n\n[:, :, 2, 2] =\n 7 8\n\njulia> [[1 2;;; 3 4];;;; [5 6];;; [7 8]]\n1×2×2×2 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 2\n\n[:, :, 2, 1] =\n 3 4\n\n[:, :, 1, 2] =\n 5 6\n\n[:, :, 2, 2] =\n 7 8","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Although they both mean concatenation in the second dimension, spaces (or tabs) and ;; cannot appear in the same array expression unless the double semicolon is simply serving as a \"line continuation\" character. This allows a single horizontal concatenation to span multiple lines (without the line break being interpreted as a vertical concatenation).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1 2 ;;\n 3 4]\n1×4 Matrix{Int64}:\n 1 2 3 4","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Terminating semicolons may also be used to add trailing length 1 dimensions.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [1;;]\n1×1 Matrix{Int64}:\n 1\n\njulia> [2; 3;;;]\n2×1×1 Array{Int64, 3}:\n[:, :, 1] =\n 2\n 3","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"More generally, concatenation can be accomplished through the cat function. These syntaxes are shorthands for function calls that themselves are convenience functions:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Syntax Function Description\n cat concatenate input arrays along dimension(s) k\n[A; B; C; ...] vcat shorthand for cat(A...; dims=1)\n[A B C ...] hcat shorthand for cat(A...; dims=2)\n[A B; C D; ...] hvcat simultaneous vertical and horizontal concatenation\n[A; C;; B; D;;; ...] hvncat simultaneous n-dimensional concatenation, where number of semicolons indicate the dimension to concatenate","category":"page"},{"location":"manual/arrays/#man-array-typed-literal","page":"Single- and multi-dimensional Arrays","title":"Typed array literals","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"An array with a specific element type can be constructed using the syntax T[A, B, C, ...]. This will construct a 1-d array with element type T, initialized to contain elements A, B, C, etc. For example, Any[x, y, z] constructs a heterogeneous array that can contain any values.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Concatenation syntax can similarly be prefixed with a type to specify the element type of the result.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [[1 2] [3 4]]\n1×4 Matrix{Int64}:\n 1 2 3 4\n\njulia> Int8[[1 2] [3 4]]\n1×4 Matrix{Int8}:\n 1 2 3 4","category":"page"},{"location":"manual/arrays/#man-comprehensions","page":"Single- and multi-dimensional Arrays","title":"Comprehensions","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Comprehensions provide a general and powerful way to construct arrays. Comprehension syntax is similar to set construction notation in mathematics:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A = [ F(x, y, ...) for x=rx, y=ry, ... ]","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The meaning of this form is that F(x,y,...) is evaluated with the variables x, y, etc. taking on each value in their given list of values. Values can be specified as any iterable object, but will commonly be ranges like 1:n or 2:(n-1), or explicit arrays of values like [1.2, 3.4, 5.7]. The result is an N-d dense array with dimensions that are the concatenation of the dimensions of the variable ranges rx, ry, etc. and each F(x,y,...) evaluation returns a scalar.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The following example computes a weighted average of the current element and its left and right neighbor along a 1-d grid. :","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> x = rand(8)\n8-element Array{Float64,1}:\n 0.843025\n 0.869052\n 0.365105\n 0.699456\n 0.977653\n 0.994953\n 0.41084\n 0.809411\n\njulia> [ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ]\n6-element Array{Float64,1}:\n 0.736559\n 0.57468\n 0.685417\n 0.912429\n 0.8446\n 0.656511","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The resulting array type depends on the types of the computed elements just like array literals do. In order to control the type explicitly, a type can be prepended to the comprehension. For example, we could have requested the result in single precision by writing:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Float32[ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ]","category":"page"},{"location":"manual/arrays/#man-generators","page":"Single- and multi-dimensional Arrays","title":"Generator Expressions","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Comprehensions can also be written without the enclosing square brackets, producing an object known as a generator. This object can be iterated to produce values on demand, instead of allocating an array and storing them in advance (see Iteration). For example, the following expression sums a series without allocating memory:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> sum(1/n^2 for n=1:1000)\n1.6439345666815615","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"When writing a generator expression with multiple dimensions inside an argument list, parentheses are needed to separate the generator from subsequent arguments:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> map(tuple, 1/(i+j) for i=1:2, j=1:2, [1:4;])\nERROR: syntax: invalid iteration specification","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"All comma-separated expressions after for are interpreted as ranges. Adding parentheses lets us add a third argument to map:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4])\n2×2 Matrix{Tuple{Float64, Int64}}:\n (0.5, 1) (0.333333, 3)\n (0.333333, 2) (0.25, 4)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Generators are implemented via inner functions. Just like inner functions used elsewhere in the language, variables from the enclosing scope can be \"captured\" in the inner function. For example, sum(p[i] - q[i] for i=1:n) captures the three variables p, q and n from the enclosing scope. Captured variables can present performance challenges; see performance tips.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Ranges in generators and comprehensions can depend on previous ranges by writing multiple for keywords:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [(i, j) for i=1:3 for j=1:i]\n6-element Vector{Tuple{Int64, Int64}}:\n (1, 1)\n (2, 1)\n (2, 2)\n (3, 1)\n (3, 2)\n (3, 3)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In such cases, the result is always 1-d.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Generated values can be filtered using the if keyword:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> [(i, j) for i=1:3 for j=1:i if i+j == 4]\n2-element Vector{Tuple{Int64, Int64}}:\n (2, 2)\n (3, 1)","category":"page"},{"location":"manual/arrays/#man-array-indexing","page":"Single- and multi-dimensional Arrays","title":"Indexing","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The general syntax for indexing into an n-dimensional array A is:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"X = A[I_1, I_2, ..., I_n]","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"where each I_k may be a scalar integer, an array of integers, or any other supported index. This includes Colon (:) to select all indices within the entire dimension, ranges of the form a:c or a:b:c to select contiguous or strided subsections, and arrays of booleans to select elements at their true indices.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If all the indices are scalars, then the result X is a single element from the array A. Otherwise, X is an array with the same number of dimensions as the sum of the dimensionalities of all the indices.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If all indices I_k are vectors, for example, then the shape of X would be (length(I_1), length(I_2), ..., length(I_n)), with location i_1, i_2, ..., i_n of X containing the value A[I_1[i_1], I_2[i_2], ..., I_n[i_n]].","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(collect(1:16), (2, 2, 2, 2))\n2×2×2×2 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1 3\n 2 4\n\n[:, :, 2, 1] =\n 5 7\n 6 8\n\n[:, :, 1, 2] =\n 9 11\n 10 12\n\n[:, :, 2, 2] =\n 13 15\n 14 16\n\njulia> A[1, 2, 1, 1] # all scalar indices\n3\n\njulia> A[[1, 2], [1], [1, 2], [1]] # all vector indices\n2×1×2×1 Array{Int64, 4}:\n[:, :, 1, 1] =\n 1\n 2\n\n[:, :, 2, 1] =\n 5\n 6\n\njulia> A[[1, 2], [1], [1, 2], 1] # a mix of index types\n2×1×2 Array{Int64, 3}:\n[:, :, 1] =\n 1\n 2\n\n[:, :, 2] =\n 5\n 6","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Note how the size of the resulting array is different in the last two cases.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If I_1 is changed to a two-dimensional matrix, then X becomes an n+1-dimensional array of shape (size(I_1, 1), size(I_1, 2), length(I_2), ..., length(I_n)). The matrix adds a dimension.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(collect(1:16), (2, 2, 2, 2));\n\njulia> A[[1 2; 1 2]]\n2×2 Matrix{Int64}:\n 1 2\n 1 2\n\njulia> A[[1 2; 1 2], 1, 2, 1]\n2×2 Matrix{Int64}:\n 5 6\n 5 6","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The location i_1, i_2, i_3, ..., i_{n+1} contains the value at A[I_1[i_1, i_2], I_2[i_3], ..., I_n[i_{n+1}]]. All dimensions indexed with scalars are dropped. For example, if J is an array of indices, then the result of A[2, J, 3] is an array with size size(J). Its jth element is populated by A[2, J[j], 3].","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"As a special part of this syntax, the end keyword may be used to represent the last index of each dimension within the indexing brackets, as determined by the size of the innermost array being indexed. Indexing syntax without the end keyword is equivalent to a call to getindex:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"X = getindex(A, I_1, I_2, ..., I_n)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> x = reshape(1:16, 4, 4)\n4×4 reshape(::UnitRange{Int64}, 4, 4) with eltype Int64:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> x[2:3, 2:end-1]\n2×2 Matrix{Int64}:\n 6 10\n 7 11\n\njulia> x[1, [2 3; 4 1]]\n2×2 Matrix{Int64}:\n 5 9\n 13 1","category":"page"},{"location":"manual/arrays/#man-indexed-assignment","page":"Single- and multi-dimensional Arrays","title":"Indexed Assignment","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The general syntax for assigning values in an n-dimensional array A is:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A[I_1, I_2, ..., I_n] = X","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"where each I_k may be a scalar integer, an array of integers, or any other supported index. This includes Colon (:) to select all indices within the entire dimension, ranges of the form a:c or a:b:c to select contiguous or strided subsections, and arrays of booleans to select elements at their true indices.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If all indices I_k are integers, then the value in location I_1, I_2, ..., I_n of A is overwritten with the value of X, converting to the eltype of A if necessary.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If any index I_k is itself an array, then the right hand side X must also be an array with the same shape as the result of indexing A[I_1, I_2, ..., I_n] or a vector with the same number of elements. The value in location I_1[i_1], I_2[i_2], ..., I_n[i_n] of A is overwritten with the value X[i_1, i_2, ..., i_n], converting if necessary. The element-wise assignment operator .= may be used to broadcast X across the selected locations:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A[I_1, I_2, ..., I_n] .= X","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Just as in Indexing, the end keyword may be used to represent the last index of each dimension within the indexing brackets, as determined by the size of the array being assigned into. Indexed assignment syntax without the end keyword is equivalent to a call to setindex!:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"setindex!(A, X, I_1, I_2, ..., I_n)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> x = collect(reshape(1:9, 3, 3))\n3×3 Matrix{Int64}:\n 1 4 7\n 2 5 8\n 3 6 9\n\njulia> x[3, 3] = -9;\n\njulia> x[1:2, 1:2] = [-1 -4; -2 -5];\n\njulia> x\n3×3 Matrix{Int64}:\n -1 -4 7\n -2 -5 8\n 3 6 -9","category":"page"},{"location":"manual/arrays/#man-supported-index-types","page":"Single- and multi-dimensional Arrays","title":"Supported index types","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In the expression A[I_1, I_2, ..., I_n], each I_k may be a scalar index, an array of scalar indices, or an object that represents an array of scalar indices and can be converted to such by to_indices:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A scalar index. By default this includes:\nNon-boolean integers\nCartesianIndex{N}s, which behave like an N-tuple of integers spanning multiple dimensions (see below for more details)\nAn array of scalar indices. This includes:\nVectors and multidimensional arrays of integers\nEmpty arrays like [], which select no elements e.g. A[[]] (not to be confused with A[])\nRanges like a:c or a:b:c, which select contiguous or strided subsections from a to c (inclusive)\nAny custom array of scalar indices that is a subtype of AbstractArray\nArrays of CartesianIndex{N} (see below for more details)\nAn object that represents an array of scalar indices and can be converted to such by to_indices. By default this includes:\nColon() (:), which represents all indices within an entire dimension or across the entire array\nArrays of booleans, which select elements at their true indices (see below for more details)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Some examples:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(collect(1:2:18), (3, 3))\n3×3 Matrix{Int64}:\n 1 7 13\n 3 9 15\n 5 11 17\n\njulia> A[4]\n7\n\njulia> A[[2, 5, 8]]\n3-element Vector{Int64}:\n 3\n 9\n 15\n\njulia> A[[1 4; 3 8]]\n2×2 Matrix{Int64}:\n 1 7\n 5 15\n\njulia> A[[]]\nInt64[]\n\njulia> A[1:2:5]\n3-element Vector{Int64}:\n 1\n 5\n 9\n\njulia> A[2, :]\n3-element Vector{Int64}:\n 3\n 9\n 15\n\njulia> A[:, 3]\n3-element Vector{Int64}:\n 13\n 15\n 17\n\njulia> A[:, 3:3]\n3×1 Matrix{Int64}:\n 13\n 15\n 17","category":"page"},{"location":"manual/arrays/#Cartesian-indices","page":"Single- and multi-dimensional Arrays","title":"Cartesian indices","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The special CartesianIndex{N} object represents a scalar index that behaves like an N-tuple of integers spanning multiple dimensions. For example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(1:32, 4, 4, 2);\n\njulia> A[3, 2, 1]\n7\n\njulia> A[CartesianIndex(3, 2, 1)] == A[3, 2, 1] == 7\ntrue","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Considered alone, this may seem relatively trivial; CartesianIndex simply gathers multiple integers together into one object that represents a single multidimensional index. When combined with other indexing forms and iterators that yield CartesianIndexes, however, this can produce very elegant and efficient code. See Iteration below, and for some more advanced examples, see this blog post on multidimensional algorithms and iteration.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Arrays of CartesianIndex{N} are also supported. They represent a collection of scalar indices that each span N dimensions, enabling a form of indexing that is sometimes referred to as pointwise indexing. For example, it enables accessing the diagonal elements from the first \"page\" of A from above:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> page = A[:, :, 1]\n4×4 Matrix{Int64}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> page[[CartesianIndex(1, 1),\n CartesianIndex(2, 2),\n CartesianIndex(3, 3),\n CartesianIndex(4, 4)]]\n4-element Vector{Int64}:\n 1\n 6\n 11\n 16","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This can be expressed much more simply with dot broadcasting and by combining it with a normal integer index (instead of extracting the first page from A as a separate step). It can even be combined with a : to extract both diagonals from the two pages at the same time:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), 1]\n4-element Vector{Int64}:\n 1\n 6\n 11\n 16\n\njulia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), :]\n4×2 Matrix{Int64}:\n 1 17\n 6 22\n 11 27\n 16 32","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"warning: Warning\nCartesianIndex and arrays of CartesianIndex are not compatible with the end keyword to represent the last index of a dimension. Do not use end in indexing expressions that may contain either CartesianIndex or arrays thereof.","category":"page"},{"location":"manual/arrays/#Logical-indexing","page":"Single- and multi-dimensional Arrays","title":"Logical indexing","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Often referred to as logical indexing or indexing with a logical mask, indexing by a boolean array selects elements at the indices where its values are true. Indexing by a boolean vector B is effectively the same as indexing by the vector of integers that is returned by findall(B). Similarly, indexing by a N-dimensional boolean array is effectively the same as indexing by the vector of CartesianIndex{N}s where its values are true. A logical index must be a array of the same shape as the dimension(s) it indexes into, or it must be the only index provided and match the shape of the one-dimensional reshaped view of the array it indexes into. It is generally more efficient to use boolean arrays as indices directly instead of first calling findall.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> x = reshape(1:12, 2, 3, 2)\n2×3×2 reshape(::UnitRange{Int64}, 2, 3, 2) with eltype Int64:\n[:, :, 1] =\n 1 3 5\n 2 4 6\n\n[:, :, 2] =\n 7 9 11\n 8 10 12\n\njulia> x[:, [true false; false true; true false]]\n2×3 Matrix{Int64}:\n 1 5 9\n 2 6 10\n\njulia> mask = map(ispow2, x)\n2×3×2 Array{Bool, 3}:\n[:, :, 1] =\n 1 0 0\n 1 1 0\n\n[:, :, 2] =\n 0 0 0\n 1 0 0\n\njulia> x[mask]\n4-element Vector{Int64}:\n 1\n 2\n 4\n 8\n\njulia> x[vec(mask)] == x[mask] # we can also index with a single Boolean vector\ntrue","category":"page"},{"location":"manual/arrays/#Number-of-indices","page":"Single- and multi-dimensional Arrays","title":"Number of indices","text":"","category":"section"},{"location":"manual/arrays/#Cartesian-indexing","page":"Single- and multi-dimensional Arrays","title":"Cartesian indexing","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The ordinary way to index into an N-dimensional array is to use exactly N indices; each index selects the position(s) in its particular dimension. For example, in the three-dimensional array A = rand(4, 3, 2), A[2, 3, 1] will select the number in the second row of the third column in the first \"page\" of the array. This is often referred to as cartesian indexing.","category":"page"},{"location":"manual/arrays/#Linear-indexing","page":"Single- and multi-dimensional Arrays","title":"Linear indexing","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"When exactly one index i is provided, that index no longer represents a location in a particular dimension of the array. Instead, it selects the ith element using the column-major iteration order that linearly spans the entire array. This is known as linear indexing. It essentially treats the array as though it had been reshaped into a one-dimensional vector with vec.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = [2 6; 4 7; 3 1]\n3×2 Matrix{Int64}:\n 2 6\n 4 7\n 3 1\n\njulia> A[5]\n7\n\njulia> vec(A)[5]\n7","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"A linear index into the array A can be converted to a CartesianIndex for cartesian indexing with CartesianIndices(A)[i] (see CartesianIndices), and a set of N cartesian indices can be converted to a linear index with LinearIndices(A)[i_1, i_2, ..., i_N] (see LinearIndices).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> CartesianIndices(A)[5]\nCartesianIndex(2, 2)\n\njulia> LinearIndices(A)[2, 2]\n5","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"It's important to note that there's a very large asymmetry in the performance of these conversions. Converting a linear index to a set of cartesian indices requires dividing and taking the remainder, whereas going the other way is just multiplies and adds. In modern processors, integer division can be 10-50 times slower than multiplication. While some arrays — like Array itself — are implemented using a linear chunk of memory and directly use a linear index in their implementations, other arrays — like Diagonal — need the full set of cartesian indices to do their lookup (see IndexStyle to introspect which is which).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"warning: Warning\nWhen iterating over all the indices for an array, it is better to iterate over eachindex(A) instead of 1:length(A). Not only will this be faster in cases where A is IndexCartesian, but it will also support arrays with custom indexing, such as OffsetArrays. If only the values are needed, then is better to just iterate the array directly, i.e. for a in A.","category":"page"},{"location":"manual/arrays/#Omitted-and-extra-indices","page":"Single- and multi-dimensional Arrays","title":"Omitted and extra indices","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In addition to linear indexing, an N-dimensional array may be indexed with fewer or more than N indices in certain situations.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Indices may be omitted if the trailing dimensions that are not indexed into are all length one. In other words, trailing indices can be omitted only if there is only one possible value that those omitted indices could be for an in-bounds indexing expression. For example, a four-dimensional array with size (3, 4, 2, 1) may be indexed with only three indices as the dimension that gets skipped (the fourth dimension) has length one. Note that linear indexing takes precedence over this rule.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = reshape(1:24, 3, 4, 2, 1)\n3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64:\n[:, :, 1, 1] =\n 1 4 7 10\n 2 5 8 11\n 3 6 9 12\n\n[:, :, 2, 1] =\n 13 16 19 22\n 14 17 20 23\n 15 18 21 24\n\njulia> A[1, 3, 2] # Omits the fourth dimension (length 1)\n19\n\njulia> A[1, 3] # Attempts to omit dimensions 3 & 4 (lengths 2 and 1)\nERROR: BoundsError: attempt to access 3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64 at index [1, 3]\n\njulia> A[19] # Linear indexing\n19","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"When omitting all indices with A[], this semantic provides a simple idiom to retrieve the only element in an array and simultaneously ensure that there was only one element.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Similarly, more than N indices may be provided if all the indices beyond the dimensionality of the array are 1 (or more generally are the first and only element of axes(A, d) where d is that particular dimension number). This allows vectors to be indexed like one-column matrices, for example:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = [8, 6, 7]\n3-element Vector{Int64}:\n 8\n 6\n 7\n\njulia> A[2, 1]\n6","category":"page"},{"location":"manual/arrays/#Iteration","page":"Single- and multi-dimensional Arrays","title":"Iteration","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The recommended ways to iterate over a whole array are","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"for a in A\n # Do something with the element a\nend\n\nfor i in eachindex(A)\n # Do something with i and/or A[i]\nend","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The first construct is used when you need the value, but not index, of each element. In the second construct, i will be an Int if A is an array type with fast linear indexing; otherwise, it will be a CartesianIndex:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = rand(4, 3);\n\njulia> B = view(A, 1:3, 2:3);\n\njulia> for i in eachindex(B)\n @show i\n end\ni = CartesianIndex(1, 1)\ni = CartesianIndex(2, 1)\ni = CartesianIndex(3, 1)\ni = CartesianIndex(1, 2)\ni = CartesianIndex(2, 2)\ni = CartesianIndex(3, 2)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"note: Note\nIn contrast with for i = 1:length(A), iterating with eachindex provides an efficient way to iterate over any array type. Besides, this also supports generic arrays with custom indexing such as OffsetArrays.","category":"page"},{"location":"manual/arrays/#Array-traits","page":"Single- and multi-dimensional Arrays","title":"Array traits","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"If you write a custom AbstractArray type, you can specify that it has fast linear indexing using","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This setting will cause eachindex iteration over a MyArray to use integers. If you don't specify this trait, the default value IndexCartesian() is used.","category":"page"},{"location":"manual/arrays/#man-array-and-vectorized-operators-and-functions","page":"Single- and multi-dimensional Arrays","title":"Array and Vectorized Operators and Functions","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The following operators are supported for arrays:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Unary arithmetic – -, +\nBinary arithmetic – -, +, *, /, \\, ^\nComparison – ==, !=, ≈ (isapprox), ≉","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"To enable convenient vectorization of mathematical and other operations, Julia provides the dot syntax f.(args...), e.g. sin.(x) or min.(x, y), for elementwise operations over arrays or mixtures of arrays and scalars (a Broadcasting operation); these have the additional advantage of \"fusing\" into a single loop when combined with other dot calls, e.g. sin.(cos.(x)).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Also, every binary operator supports a dot version that can be applied to arrays (and combinations of arrays and scalars) in such fused broadcasting operations, e.g. z .== sin.(x .* y).","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Note that comparisons such as == operate on whole arrays, giving a single boolean answer. Use dot operators like .== for elementwise comparisons. (For comparison operations like <, only the elementwise .< version is applicable to arrays.)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Also notice the difference between max.(a,b), which broadcasts max elementwise over a and b, and maximum(a), which finds the largest value within a. The same relationship holds for min.(a, b) and minimum(a).","category":"page"},{"location":"manual/arrays/#Broadcasting","page":"Single- and multi-dimensional Arrays","title":"Broadcasting","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"It is sometimes useful to perform element-by-element binary operations on arrays of different sizes, such as adding a vector to each column of a matrix. An inefficient way to do this would be to replicate the vector to the size of the matrix:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> a = rand(2, 1); A = rand(2, 3);\n\njulia> repeat(a, 1, 3) + A\n2×3 Array{Float64,2}:\n 1.20813 1.82068 1.25387\n 1.56851 1.86401 1.67846","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This is wasteful when dimensions get large, so Julia provides broadcast, which expands singleton dimensions in array arguments to match the corresponding dimension in the other array without using extra memory, and applies the given function elementwise:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> broadcast(+, a, A)\n2×3 Array{Float64,2}:\n 1.20813 1.82068 1.25387\n 1.56851 1.86401 1.67846\n\njulia> b = rand(1,2)\n1×2 Array{Float64,2}:\n 0.867535 0.00457906\n\njulia> broadcast(+, a, b)\n2×2 Array{Float64,2}:\n 1.71056 0.847604\n 1.73659 0.873631","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Dotted operators such as .+ and .* are equivalent to broadcast calls (except that they fuse, as described above). There is also a broadcast! function to specify an explicit destination (which can also be accessed in a fusing fashion by .= assignment). In fact, f.(args...) is equivalent to broadcast(f, args...), providing a convenient syntax to broadcast any function (dot syntax). Nested \"dot calls\" f.(...) (including calls to .+ etcetera) automatically fuse into a single broadcast call.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Additionally, broadcast is not limited to arrays (see the function documentation); it also handles scalars, tuples and other collections. By default, only some argument types are considered scalars, including (but not limited to) Numbers, Strings, Symbols, Types, Functions and some common singletons like missing and nothing. All other arguments are iterated over or indexed into elementwise.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> convert.(Float32, [1, 2])\n2-element Vector{Float32}:\n 1.0\n 2.0\n\njulia> ceil.(UInt8, [1.2 3.4; 5.6 6.7])\n2×2 Matrix{UInt8}:\n 0x02 0x04\n 0x06 0x07\n\njulia> string.(1:3, \". \", [\"First\", \"Second\", \"Third\"])\n3-element Vector{String}:\n \"1. First\"\n \"2. Second\"\n \"3. Third\"","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"Sometimes, you want a container (like an array) that would normally participate in broadcast to be \"protected\" from broadcast's behavior of iterating over all of its elements. By placing it inside another container (like a single element Tuple) broadcast will treat it as a single value.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> ([1, 2, 3], [4, 5, 6]) .+ ([1, 2, 3],)\n([2, 4, 6], [5, 7, 9])\n\njulia> ([1, 2, 3], [4, 5, 6]) .+ tuple([1, 2, 3])\n([2, 4, 6], [5, 7, 9])","category":"page"},{"location":"manual/arrays/#Implementation","page":"Single- and multi-dimensional Arrays","title":"Implementation","text":"","category":"section"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The base array type in Julia is the abstract type AbstractArray{T,N}. It is parameterized by the number of dimensions N and the element type T. AbstractVector and AbstractMatrix are aliases for the 1-d and 2-d cases. Operations on AbstractArray objects are defined using higher level operators and functions, in a way that is independent of the underlying storage. These operations generally work correctly as a fallback for any specific array implementation.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The AbstractArray type includes anything vaguely array-like, and implementations of it might be quite different from conventional arrays. For example, elements might be computed on request rather than stored. However, any concrete AbstractArray{T,N} type should generally implement at least size(A) (returning an Int tuple), getindex(A, i) and getindex(A, i1, ..., iN); mutable arrays should also implement setindex!. It is recommended that these operations have nearly constant time complexity, as otherwise some array functions may be unexpectedly slow. Concrete types should also typically provide a similar(A, T=eltype(A), dims=size(A)) method, which is used to allocate a similar array for copy and other out-of-place operations. No matter how an AbstractArray{T,N} is represented internally, T is the type of object returned by integer indexing (A[1, ..., 1], when A is not empty) and N should be the length of the tuple returned by size. For more details on defining custom AbstractArray implementations, see the array interface guide in the interfaces chapter.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"DenseArray is an abstract subtype of AbstractArray intended to include all arrays where elements are stored contiguously in column-major order (see additional notes in Performance Tips). The Array type is a specific instance of DenseArray; Vector and Matrix are aliases for the 1-d and 2-d cases. Very few operations are implemented specifically for Array beyond those that are required for all AbstractArrays; much of the array library is implemented in a generic manner that allows all custom arrays to behave similarly.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"SubArray is a specialization of AbstractArray that performs indexing by sharing memory with the original array rather than by copying it. A SubArray is created with the view function, which is called the same way as getindex (with an array and a series of index arguments). The result of view looks the same as the result of getindex, except the data is left in place. view stores the input index vectors in a SubArray object, which can later be used to index the original array indirectly. By putting the @views macro in front of an expression or block of code, any array[...] slice in that expression will be converted to create a SubArray view instead.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"BitArrays are space-efficient \"packed\" boolean arrays, which store one bit per boolean value. They can be used similarly to Array{Bool} arrays (which store one byte per boolean value), and can be converted to/from the latter via Array(bitarray) and BitArray(array), respectively.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"An array is \"strided\" if it is stored in memory with well-defined spacings (strides) between its elements. A strided array with a supported element type may be passed to an external (non-Julia) library like BLAS or LAPACK by simply passing its pointer and the stride for each dimension. The stride(A, d) is the distance between elements along dimension d. For example, the builtin Array returned by rand(5,7,2) has its elements arranged contiguously in column major order. This means that the stride of the first dimension — the spacing between elements in the same column — is 1:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> A = rand(5, 7, 2);\n\njulia> stride(A, 1)\n1","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The stride of the second dimension is the spacing between elements in the same row, skipping as many elements as there are in a single column (5). Similarly, jumping between the two \"pages\" (in the third dimension) requires skipping 5*7 == 35 elements. The strides of this array is the tuple of these three numbers together:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> strides(A)\n(1, 5, 35)","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"In this particular case, the number of elements skipped in memory matches the number of linear indices skipped. This is only the case for contiguous arrays like Array (and other DenseArray subtypes) and is not true in general. Views with range indices are a good example of non-contiguous strided arrays; consider V = @view A[1:3:4, 2:2:6, 2:-1:1]. This view V refers to the same memory as A but is skipping and re-arranging some of its elements. The stride of the first dimension of V is 3 because we're only selecting every third row from our original array:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> V = @view A[1:3:4, 2:2:6, 2:-1:1];\n\njulia> stride(V, 1)\n3","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This view is similarly selecting every other column from our original A — and thus it needs to skip the equivalent of two five-element columns when moving between indices in the second dimension:","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> stride(V, 2)\n10","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"The third dimension is interesting because its order is reversed! Thus to get from the first \"page\" to the second one it must go backwards in memory, and so its stride in this dimension is negative!","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"julia> stride(V, 3)\n-35","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"This means that the pointer for V is actually pointing into the middle of A's memory block, and it refers to elements both backwards and forwards in memory. See the interface guide for strided arrays for more details on defining your own strided arrays. StridedVector and StridedMatrix are convenient aliases for many of the builtin array types that are considered strided arrays, allowing them to dispatch to select specialized implementations that call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides.","category":"page"},{"location":"manual/arrays/","page":"Single- and multi-dimensional Arrays","title":"Single- and multi-dimensional Arrays","text":"It is worth emphasizing that strides are about offsets in memory rather than indexing. If you are looking to convert between linear (single-index) indexing and cartesian (multi-index) indexing, see LinearIndices and CartesianIndices.","category":"page"},{"location":"base/file/#Filesystem","page":"Filesystem","title":"Filesystem","text":"","category":"section"},{"location":"base/file/","page":"Filesystem","title":"Filesystem","text":"Base.read(::String)\nBase.write(::String, ::Any)\nBase.Filesystem.pwd\nBase.Filesystem.cd(::AbstractString)\nBase.Filesystem.cd(::Function)\nBase.Filesystem.readdir\nBase.Filesystem.walkdir\nBase.Filesystem.mkdir\nBase.Filesystem.mkpath\nBase.Filesystem.hardlink\nBase.Filesystem.symlink\nBase.Filesystem.readlink\nBase.Filesystem.chmod\nBase.Filesystem.chown\nBase.RawFD\nBase.stat\nBase.Filesystem.diskstat\nBase.Filesystem.lstat\nBase.Filesystem.ctime\nBase.Filesystem.mtime\nBase.Filesystem.filemode\nBase.Filesystem.filesize\nBase.Filesystem.uperm\nBase.Filesystem.gperm\nBase.Filesystem.operm\nBase.Filesystem.cp\nBase.download\nBase.Filesystem.mv\nBase.Filesystem.rm\nBase.Filesystem.touch\nBase.Filesystem.tempname\nBase.Filesystem.tempdir\nBase.Filesystem.mktemp(::AbstractString)\nBase.Filesystem.mktemp(::Function, ::AbstractString)\nBase.Filesystem.mktempdir(::AbstractString)\nBase.Filesystem.mktempdir(::Function, ::AbstractString)\nBase.Filesystem.isblockdev\nBase.Filesystem.ischardev\nBase.Filesystem.isdir\nBase.Filesystem.isfifo\nBase.Filesystem.isfile\nBase.Filesystem.islink\nBase.Filesystem.ismount\nBase.Filesystem.ispath\nBase.Filesystem.issetgid\nBase.Filesystem.issetuid\nBase.Filesystem.issocket\nBase.Filesystem.issticky\nBase.Filesystem.homedir\nBase.Filesystem.dirname\nBase.Filesystem.basename\nBase.Filesystem.isabspath\nBase.Filesystem.isdirpath\nBase.Filesystem.joinpath\nBase.Filesystem.abspath\nBase.Filesystem.normpath\nBase.Filesystem.realpath\nBase.Filesystem.relpath\nBase.Filesystem.expanduser\nBase.Filesystem.contractuser\nBase.Filesystem.samefile\nBase.Filesystem.splitdir\nBase.Filesystem.splitdrive\nBase.Filesystem.splitext\nBase.Filesystem.splitpath","category":"page"},{"location":"base/file/#Base.read-Tuple{String}","page":"Filesystem","title":"Base.read","text":"read(filename::AbstractString)\n\nRead the entire contents of a file as a Vector{UInt8}.\n\nread(filename::AbstractString, String)\n\nRead the entire contents of a file as a string.\n\nread(filename::AbstractString, args...)\n\nOpen a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.write-Tuple{String, Any}","page":"Filesystem","title":"Base.write","text":"write(filename::AbstractString, content)\n\nWrite the canonical binary representation of content to a file, which will be created if it does not exist yet or overwritten if it does exist.\n\nReturn the number of bytes written into the file.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.pwd","page":"Filesystem","title":"Base.Filesystem.pwd","text":"pwd() -> String\n\nGet the current working directory.\n\nSee also: cd, tempdir.\n\nExamples\n\njulia> pwd()\n\"/home/JuliaUser\"\n\njulia> cd(\"/home/JuliaUser/Projects/julia\")\n\njulia> pwd()\n\"/home/JuliaUser/Projects/julia\"\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.cd-Tuple{AbstractString}","page":"Filesystem","title":"Base.Filesystem.cd","text":"cd(dir::AbstractString=homedir())\n\nSet the current working directory.\n\nSee also: pwd, mkdir, mkpath, mktempdir.\n\nExamples\n\njulia> cd(\"/home/JuliaUser/Projects/julia\")\n\njulia> pwd()\n\"/home/JuliaUser/Projects/julia\"\n\njulia> cd()\n\njulia> pwd()\n\"/home/JuliaUser\"\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.cd-Tuple{Function}","page":"Filesystem","title":"Base.Filesystem.cd","text":"cd(f::Function, dir::AbstractString=homedir())\n\nTemporarily change the current working directory to dir, apply function f and finally return to the original directory.\n\nExamples\n\njulia> pwd()\n\"/home/JuliaUser\"\n\njulia> cd(readdir, \"/home/JuliaUser/Projects/julia\")\n34-element Array{String,1}:\n \".circleci\"\n \".freebsdci.sh\"\n \".git\"\n \".gitattributes\"\n \".github\"\n ⋮\n \"test\"\n \"ui\"\n \"usr\"\n \"usr-staging\"\n\njulia> pwd()\n\"/home/JuliaUser\"\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.readdir","page":"Filesystem","title":"Base.Filesystem.readdir","text":"readdir(dir::AbstractString=pwd();\n join::Bool = false,\n sort::Bool = true,\n) -> Vector{String}\n\nReturn the names in the directory dir or the current working directory if not given. When join is false, readdir returns just the names in the directory as is; when join is true, it returns joinpath(dir, name) for each name so that the returned strings are full paths. If you want to get absolute paths back, call readdir with an absolute directory path and join set to true.\n\nBy default, readdir sorts the list of names it returns. If you want to skip sorting the names and get them in the order that the file system lists them, you can use readdir(dir, sort=false) to opt out of sorting.\n\nSee also: walkdir.\n\ncompat: Julia 1.4\nThe join and sort keyword arguments require at least Julia 1.4.\n\nExamples\n\njulia> cd(\"/home/JuliaUser/dev/julia\")\n\njulia> readdir()\n30-element Array{String,1}:\n \".appveyor.yml\"\n \".git\"\n \".gitattributes\"\n ⋮\n \"ui\"\n \"usr\"\n \"usr-staging\"\n\njulia> readdir(join=true)\n30-element Array{String,1}:\n \"/home/JuliaUser/dev/julia/.appveyor.yml\"\n \"/home/JuliaUser/dev/julia/.git\"\n \"/home/JuliaUser/dev/julia/.gitattributes\"\n ⋮\n \"/home/JuliaUser/dev/julia/ui\"\n \"/home/JuliaUser/dev/julia/usr\"\n \"/home/JuliaUser/dev/julia/usr-staging\"\n\njulia> readdir(\"base\")\n145-element Array{String,1}:\n \".gitignore\"\n \"Base.jl\"\n \"Enums.jl\"\n ⋮\n \"version_git.sh\"\n \"views.jl\"\n \"weakkeydict.jl\"\n\njulia> readdir(\"base\", join=true)\n145-element Array{String,1}:\n \"base/.gitignore\"\n \"base/Base.jl\"\n \"base/Enums.jl\"\n ⋮\n \"base/version_git.sh\"\n \"base/views.jl\"\n \"base/weakkeydict.jl\"\n\njulia> readdir(abspath(\"base\"), join=true)\n145-element Array{String,1}:\n \"/home/JuliaUser/dev/julia/base/.gitignore\"\n \"/home/JuliaUser/dev/julia/base/Base.jl\"\n \"/home/JuliaUser/dev/julia/base/Enums.jl\"\n ⋮\n \"/home/JuliaUser/dev/julia/base/version_git.sh\"\n \"/home/JuliaUser/dev/julia/base/views.jl\"\n \"/home/JuliaUser/dev/julia/base/weakkeydict.jl\"\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.walkdir","page":"Filesystem","title":"Base.Filesystem.walkdir","text":"walkdir(dir; topdown=true, follow_symlinks=false, onerror=throw)\n\nReturn an iterator that walks the directory tree of a directory. The iterator returns a tuple containing (rootpath, dirs, files). The directory tree can be traversed top-down or bottom-up. If walkdir or stat encounters a IOError it will rethrow the error by default. A custom error handling function can be provided through onerror keyword argument. onerror is called with a IOError as argument.\n\nSee also: readdir.\n\nExamples\n\nfor (root, dirs, files) in walkdir(\".\")\n println(\"Directories in $root\")\n for dir in dirs\n println(joinpath(root, dir)) # path to directories\n end\n println(\"Files in $root\")\n for file in files\n println(joinpath(root, file)) # path to files\n end\nend\n\njulia> mkpath(\"my/test/dir\");\n\njulia> itr = walkdir(\"my\");\n\njulia> (root, dirs, files) = first(itr)\n(\"my\", [\"test\"], String[])\n\njulia> (root, dirs, files) = first(itr)\n(\"my/test\", [\"dir\"], String[])\n\njulia> (root, dirs, files) = first(itr)\n(\"my/test/dir\", String[], String[])\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mkdir","page":"Filesystem","title":"Base.Filesystem.mkdir","text":"mkdir(path::AbstractString; mode::Unsigned = 0o777)\n\nMake a new directory with name path and permissions mode. mode defaults to 0o777, modified by the current file creation mask. This function never creates more than one directory. If the directory already exists, or some intermediate directories do not exist, this function throws an error. See mkpath for a function which creates all required intermediate directories. Return path.\n\nExamples\n\njulia> mkdir(\"testingdir\")\n\"testingdir\"\n\njulia> cd(\"testingdir\")\n\njulia> pwd()\n\"/home/JuliaUser/testingdir\"\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mkpath","page":"Filesystem","title":"Base.Filesystem.mkpath","text":"mkpath(path::AbstractString; mode::Unsigned = 0o777)\n\nCreate all intermediate directories in the path as required. Directories are created with the permissions mode which defaults to 0o777 and is modified by the current file creation mask. Unlike mkdir, mkpath does not error if path (or parts of it) already exists. However, an error will be thrown if path (or parts of it) points to an existing file. Return path.\n\nIf path includes a filename you will probably want to use mkpath(dirname(path)) to avoid creating a directory using the filename.\n\nExamples\n\njulia> cd(mktempdir())\n\njulia> mkpath(\"my/test/dir\") # creates three directories\n\"my/test/dir\"\n\njulia> readdir()\n1-element Array{String,1}:\n \"my\"\n\njulia> cd(\"my\")\n\njulia> readdir()\n1-element Array{String,1}:\n \"test\"\n\njulia> readdir(\"test\")\n1-element Array{String,1}:\n \"dir\"\n\njulia> mkpath(\"intermediate_dir/actually_a_directory.txt\") # creates two directories\n\"intermediate_dir/actually_a_directory.txt\"\n\njulia> isdir(\"intermediate_dir/actually_a_directory.txt\")\ntrue\n\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.hardlink","page":"Filesystem","title":"Base.Filesystem.hardlink","text":"hardlink(src::AbstractString, dst::AbstractString)\n\nCreates a hard link to an existing source file src with the name dst. The destination, dst, must not exist.\n\nSee also: symlink.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.symlink","page":"Filesystem","title":"Base.Filesystem.symlink","text":"symlink(target::AbstractString, link::AbstractString; dir_target = false)\n\nCreates a symbolic link to target with the name link.\n\nOn Windows, symlinks must be explicitly declared as referring to a directory or not. If target already exists, by default the type of link will be auto- detected, however if target does not exist, this function defaults to creating a file symlink unless dir_target is set to true. Note that if the user sets dir_target but target exists and is a file, a directory symlink will still be created, but dereferencing the symlink will fail, just as if the user creates a file symlink (by calling symlink() with dir_target set to false before the directory is created) and tries to dereference it to a directory.\n\nAdditionally, there are two methods of making a link on Windows; symbolic links and junction points. Junction points are slightly more efficient, but do not support relative paths, so if a relative directory symlink is requested (as denoted by isabspath(target) returning false) a symlink will be used, else a junction point will be used. Best practice for creating symlinks on Windows is to create them only after the files/directories they reference are already created.\n\nSee also: hardlink.\n\nnote: Note\nThis function raises an error under operating systems that do not support soft symbolic links, such as Windows XP.\n\ncompat: Julia 1.6\nThe dir_target keyword argument was added in Julia 1.6. Prior to this, symlinks to nonexistent paths on windows would always be file symlinks, and relative symlinks to directories were not supported.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.readlink","page":"Filesystem","title":"Base.Filesystem.readlink","text":"readlink(path::AbstractString) -> String\n\nReturn the target location a symbolic link path points to.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.chmod","page":"Filesystem","title":"Base.Filesystem.chmod","text":"chmod(path::AbstractString, mode::Integer; recursive::Bool=false)\n\nChange the permissions mode of path to mode. Only integer modes (e.g. 0o777) are currently supported. If recursive=true and the path is a directory all permissions in that directory will be recursively changed. Return path.\n\nnote: Note\nPrior to Julia 1.6, this did not correctly manipulate filesystem ACLs on Windows, therefore it would only set read-only bits on files. It now is able to manipulate ACLs.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.chown","page":"Filesystem","title":"Base.Filesystem.chown","text":"chown(path::AbstractString, owner::Integer, group::Integer=-1)\n\nChange the owner and/or group of path to owner and/or group. If the value entered for owner or group is -1 the corresponding ID will not change. Only integer owners and groups are currently supported. Return path.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Libc.RawFD","page":"Filesystem","title":"Base.Libc.RawFD","text":"RawFD\n\nPrimitive type which wraps the native OS file descriptor. RawFDs can be passed to methods like stat to discover information about the underlying file, and can also be used to open streams, with the RawFD describing the OS file backing the stream.\n\n\n\n\n\n","category":"type"},{"location":"base/file/#Base.stat","page":"Filesystem","title":"Base.stat","text":"stat(file)\n\nReturn a structure whose fields contain information about the file. The fields of the structure are:\n\nName Type Description\ndesc Union{String, Base.OS_HANDLE} The path or OS file descriptor\nsize Int64 The size (in bytes) of the file\ndevice UInt ID of the device that contains the file\ninode UInt The inode number of the file\nmode UInt The protection mode of the file\nnlink Int The number of hard links to the file\nuid UInt The user id of the owner of the file\ngid UInt The group id of the file owner\nrdev UInt If this file refers to a device, the ID of the device it refers to\nblksize Int64 The file-system preferred block size for the file\nblocks Int64 The number of 512-byte blocks allocated\nmtime Float64 Unix timestamp of when the file was last modified\nctime Float64 Unix timestamp of when the file's metadata was changed\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.diskstat","page":"Filesystem","title":"Base.Filesystem.diskstat","text":"diskstat(path=pwd())\n\nReturns statistics in bytes about the disk that contains the file or directory pointed at by path. If no argument is passed, statistics about the disk that contains the current working directory are returned.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.lstat","page":"Filesystem","title":"Base.Filesystem.lstat","text":"lstat(file)\n\nLike stat, but for symbolic links gets the info for the link itself rather than the file it refers to. This function must be called on a file path rather than a file object or a file descriptor.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.ctime","page":"Filesystem","title":"Base.Filesystem.ctime","text":"ctime(file)\n\nEquivalent to stat(file).ctime.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mtime","page":"Filesystem","title":"Base.Filesystem.mtime","text":"mtime(file)\n\nEquivalent to stat(file).mtime.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.filemode","page":"Filesystem","title":"Base.Filesystem.filemode","text":"filemode(file)\n\nEquivalent to stat(file).mode.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.filesize","page":"Filesystem","title":"Base.filesize","text":"filesize(path...)\n\nEquivalent to stat(file).size.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.uperm","page":"Filesystem","title":"Base.Filesystem.uperm","text":"uperm(file)\n\nGet the permissions of the owner of the file as a bitfield of\n\nValue Description\n01 Execute Permission\n02 Write Permission\n04 Read Permission\n\nFor allowed arguments, see stat.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.gperm","page":"Filesystem","title":"Base.Filesystem.gperm","text":"gperm(file)\n\nLike uperm but gets the permissions of the group owning the file.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.operm","page":"Filesystem","title":"Base.Filesystem.operm","text":"operm(file)\n\nLike uperm but gets the permissions for people who neither own the file nor are a member of the group owning the file\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.cp","page":"Filesystem","title":"Base.Filesystem.cp","text":"cp(src::AbstractString, dst::AbstractString; force::Bool=false, follow_symlinks::Bool=false)\n\nCopy the file, link, or directory from src to dst. force=true will first remove an existing dst.\n\nIf follow_symlinks=false, and src is a symbolic link, dst will be created as a symbolic link. If follow_symlinks=true and src is a symbolic link, dst will be a copy of the file or directory src refers to. Return dst.\n\nnote: Note\nThe cp function is different from the cp command. The cp function always operates on the assumption that dst is a file, while the command does different things depending on whether dst is a directory or a file. Using force=true when dst is a directory will result in loss of all the contents present in the dst directory, and dst will become a file that has the contents of src instead.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.download","page":"Filesystem","title":"Base.download","text":"download(url::AbstractString, [path::AbstractString = tempname()]) -> path\n\nDownload a file from the given url, saving it to the location path, or if not specified, a temporary path. Returns the path of the downloaded file.\n\nnote: Note\nSince Julia 1.6, this function is deprecated and is just a thin wrapper around Downloads.download. In new code, you should use that function directly instead of calling this.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mv","page":"Filesystem","title":"Base.Filesystem.mv","text":"mv(src::AbstractString, dst::AbstractString; force::Bool=false)\n\nMove the file, link, or directory from src to dst. force=true will first remove an existing dst. Return dst.\n\nExamples\n\njulia> write(\"hello.txt\", \"world\");\n\njulia> mv(\"hello.txt\", \"goodbye.txt\")\n\"goodbye.txt\"\n\njulia> \"hello.txt\" in readdir()\nfalse\n\njulia> readline(\"goodbye.txt\")\n\"world\"\n\njulia> write(\"hello.txt\", \"world2\");\n\njulia> mv(\"hello.txt\", \"goodbye.txt\")\nERROR: ArgumentError: 'goodbye.txt' exists. `force=true` is required to remove 'goodbye.txt' before moving.\nStacktrace:\n [1] #checkfor_mv_cp_cptree#10(::Bool, ::Function, ::String, ::String, ::String) at ./file.jl:293\n[...]\n\njulia> mv(\"hello.txt\", \"goodbye.txt\", force=true)\n\"goodbye.txt\"\n\njulia> rm(\"goodbye.txt\");\n\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.rm","page":"Filesystem","title":"Base.Filesystem.rm","text":"rm(path::AbstractString; force::Bool=false, recursive::Bool=false)\n\nDelete the file, link, or empty directory at the given path. If force=true is passed, a non-existing path is not treated as error. If recursive=true is passed and the path is a directory, then all contents are removed recursively.\n\nExamples\n\njulia> mkpath(\"my/test/dir\");\n\njulia> rm(\"my\", recursive=true)\n\njulia> rm(\"this_file_does_not_exist\", force=true)\n\njulia> rm(\"this_file_does_not_exist\")\nERROR: IOError: unlink(\"this_file_does_not_exist\"): no such file or directory (ENOENT)\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.touch","page":"Filesystem","title":"Base.Filesystem.touch","text":"Base.touch(::Pidfile.LockMonitor)\n\nUpdate the mtime on the lock, to indicate it is still fresh.\n\nSee also the refresh keyword in the mkpidlock constructor.\n\n\n\n\n\ntouch(path::AbstractString)\ntouch(fd::File)\n\nUpdate the last-modified timestamp on a file to the current time.\n\nIf the file does not exist a new file is created.\n\nReturn path.\n\nExamples\n\njulia> write(\"my_little_file\", 2);\n\njulia> mtime(\"my_little_file\")\n1.5273815391135583e9\n\njulia> touch(\"my_little_file\");\n\njulia> mtime(\"my_little_file\")\n1.527381559163435e9\n\nWe can see the mtime has been modified by touch.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.tempname","page":"Filesystem","title":"Base.Filesystem.tempname","text":"tempname(parent=tempdir(); cleanup=true, suffix=\"\") -> String\n\nGenerate a temporary file path. This function only returns a path; no file is created. The path is likely to be unique, but this cannot be guaranteed due to the very remote possibility of two simultaneous calls to tempname generating the same file name. The name is guaranteed to differ from all files already existing at the time of the call to tempname.\n\nWhen called with no arguments, the temporary name will be an absolute path to a temporary name in the system temporary directory as given by tempdir(). If a parent directory argument is given, the temporary path will be in that directory instead. If a suffix is given the tempname will end with that suffix and be tested for uniqueness with that suffix.\n\nThe cleanup option controls whether the process attempts to delete the returned path automatically when the process exits. Note that the tempname function does not create any file or directory at the returned location, so there is nothing to cleanup unless you create a file or directory there. If you do and cleanup is true it will be deleted upon process termination.\n\ncompat: Julia 1.4\nThe parent and cleanup arguments were added in 1.4. Prior to Julia 1.4 the path tempname would never be cleaned up at process termination.\n\ncompat: Julia 1.12\nThe suffix keyword argument was added in Julia 1.12.\n\nwarning: Warning\nThis can lead to security holes if another process obtains the same file name and creates the file before you are able to. Open the file with JL_O_EXCL if this is a concern. Using mktemp() is also recommended instead.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.tempdir","page":"Filesystem","title":"Base.Filesystem.tempdir","text":"tempdir()\n\nGets the path of the temporary directory. On Windows, tempdir() uses the first environment variable found in the ordered list TMP, TEMP, USERPROFILE. On all other operating systems, tempdir() uses the first environment variable found in the ordered list TMPDIR, TMP, TEMP, and TEMPDIR. If none of these are found, the path \"/tmp\" is used.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.mktemp-Tuple{AbstractString}","page":"Filesystem","title":"Base.Filesystem.mktemp","text":"mktemp(parent=tempdir(); cleanup=true) -> (path, io)\n\nReturn (path, io), where path is the path of a new temporary file in parent and io is an open file object for this path. The cleanup option controls whether the temporary file is automatically deleted when the process exits.\n\ncompat: Julia 1.3\nThe cleanup keyword argument was added in Julia 1.3. Relatedly, starting from 1.3, Julia will remove the temporary paths created by mktemp when the Julia process exits, unless cleanup is explicitly set to false.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.mktemp-Tuple{Function, AbstractString}","page":"Filesystem","title":"Base.Filesystem.mktemp","text":"mktemp(f::Function, parent=tempdir())\n\nApply the function f to the result of mktemp(parent) and remove the temporary file upon completion.\n\nSee also: mktempdir.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.mktempdir-Tuple{AbstractString}","page":"Filesystem","title":"Base.Filesystem.mktempdir","text":"mktempdir(parent=tempdir(); prefix=\"jl_\", cleanup=true) -> path\n\nCreate a temporary directory in the parent directory with a name constructed from the given prefix and a random suffix, and return its path. Additionally, on some platforms, any trailing 'X' characters in prefix may be replaced with random characters. If parent does not exist, throw an error. The cleanup option controls whether the temporary directory is automatically deleted when the process exits.\n\ncompat: Julia 1.2\nThe prefix keyword argument was added in Julia 1.2.\n\ncompat: Julia 1.3\nThe cleanup keyword argument was added in Julia 1.3. Relatedly, starting from 1.3, Julia will remove the temporary paths created by mktempdir when the Julia process exits, unless cleanup is explicitly set to false.\n\nSee also: mktemp, mkdir.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.mktempdir-Tuple{Function, AbstractString}","page":"Filesystem","title":"Base.Filesystem.mktempdir","text":"mktempdir(f::Function, parent=tempdir(); prefix=\"jl_\")\n\nApply the function f to the result of mktempdir(parent; prefix) and remove the temporary directory all of its contents upon completion.\n\nSee also: mktemp, mkdir.\n\ncompat: Julia 1.2\nThe prefix keyword argument was added in Julia 1.2.\n\n\n\n\n\n","category":"method"},{"location":"base/file/#Base.Filesystem.isblockdev","page":"Filesystem","title":"Base.Filesystem.isblockdev","text":"isblockdev(path) -> Bool\n\nReturn true if path is a block device, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.ischardev","page":"Filesystem","title":"Base.Filesystem.ischardev","text":"ischardev(path) -> Bool\n\nReturn true if path is a character device, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isdir","page":"Filesystem","title":"Base.Filesystem.isdir","text":"isdir(path) -> Bool\n\nReturn true if path is a directory, false otherwise.\n\nExamples\n\njulia> isdir(homedir())\ntrue\n\njulia> isdir(\"not/a/directory\")\nfalse\n\nSee also isfile and ispath.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isfifo","page":"Filesystem","title":"Base.Filesystem.isfifo","text":"isfifo(path) -> Bool\n\nReturn true if path is a FIFO, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isfile","page":"Filesystem","title":"Base.Filesystem.isfile","text":"isfile(path) -> Bool\n\nReturn true if path is a regular file, false otherwise.\n\nExamples\n\njulia> isfile(homedir())\nfalse\n\njulia> filename = \"test_file.txt\";\n\njulia> write(filename, \"Hello world!\");\n\njulia> isfile(filename)\ntrue\n\njulia> rm(filename);\n\njulia> isfile(filename)\nfalse\n\nSee also isdir and ispath.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.islink","page":"Filesystem","title":"Base.Filesystem.islink","text":"islink(path) -> Bool\n\nReturn true if path is a symbolic link, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.ismount","page":"Filesystem","title":"Base.Filesystem.ismount","text":"ismount(path) -> Bool\n\nReturn true if path is a mount point, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.ispath","page":"Filesystem","title":"Base.Filesystem.ispath","text":"ispath(path) -> Bool\n\nReturn true if a valid filesystem entity exists at path, otherwise returns false. This is the generalization of isfile, isdir etc.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.issetgid","page":"Filesystem","title":"Base.Filesystem.issetgid","text":"issetgid(path) -> Bool\n\nReturn true if path has the setgid flag set, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.issetuid","page":"Filesystem","title":"Base.Filesystem.issetuid","text":"issetuid(path) -> Bool\n\nReturn true if path has the setuid flag set, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.issocket","page":"Filesystem","title":"Base.Filesystem.issocket","text":"issocket(path) -> Bool\n\nReturn true if path is a socket, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.issticky","page":"Filesystem","title":"Base.Filesystem.issticky","text":"issticky(path) -> Bool\n\nReturn true if path has the sticky bit set, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.homedir","page":"Filesystem","title":"Base.Filesystem.homedir","text":"homedir() -> String\n\nReturn the current user's home directory.\n\nnote: Note\nhomedir determines the home directory via libuv's uv_os_homedir. For details (for example on how to specify the home directory via environment variables), see the uv_os_homedir documentation.\n\nSee also Sys.username.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.dirname","page":"Filesystem","title":"Base.Filesystem.dirname","text":"dirname(path::AbstractString) -> String\n\nGet the directory part of a path. Trailing characters ('/' or '\\') in the path are counted as part of the path.\n\nExamples\n\njulia> dirname(\"/home/myuser\")\n\"/home\"\n\njulia> dirname(\"/home/myuser/\")\n\"/home/myuser\"\n\nSee also basename.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.basename","page":"Filesystem","title":"Base.Filesystem.basename","text":"basename(path::AbstractString) -> String\n\nGet the file name part of a path.\n\nnote: Note\nThis function differs slightly from the Unix basename program, where trailing slashes are ignored, i.e. $ basename /foo/bar/ returns bar, whereas basename in Julia returns an empty string \"\".\n\nExamples\n\njulia> basename(\"/home/myuser/example.jl\")\n\"example.jl\"\n\njulia> basename(\"/home/myuser/\")\n\"\"\n\nSee also dirname.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isabspath","page":"Filesystem","title":"Base.Filesystem.isabspath","text":"isabspath(path::AbstractString) -> Bool\n\nDetermine whether a path is absolute (begins at the root directory).\n\nExamples\n\njulia> isabspath(\"/home\")\ntrue\n\njulia> isabspath(\"home\")\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.isdirpath","page":"Filesystem","title":"Base.Filesystem.isdirpath","text":"isdirpath(path::AbstractString) -> Bool\n\nDetermine whether a path refers to a directory (for example, ends with a path separator).\n\nExamples\n\njulia> isdirpath(\"/home\")\nfalse\n\njulia> isdirpath(\"/home/\")\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.joinpath","page":"Filesystem","title":"Base.Filesystem.joinpath","text":"joinpath(parts::AbstractString...) -> String\njoinpath(parts::Vector{AbstractString}) -> String\njoinpath(parts::Tuple{AbstractString}) -> String\n\nJoin path components into a full path. If some argument is an absolute path or (on Windows) has a drive specification that doesn't match the drive computed for the join of the preceding paths, then prior components are dropped.\n\nNote on Windows since there is a current directory for each drive, joinpath(\"c:\", \"foo\") represents a path relative to the current directory on drive \"c:\" so this is equal to \"c:foo\", not \"c:\\foo\". Furthermore, joinpath treats this as a non-absolute path and ignores the drive letter casing, hence joinpath(\"C:\\A\",\"c:b\") = \"C:\\A\\b\".\n\nExamples\n\njulia> joinpath(\"/home/myuser\", \"example.jl\")\n\"/home/myuser/example.jl\"\n\njulia> joinpath([\"/home/myuser\", \"example.jl\"])\n\"/home/myuser/example.jl\"\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.abspath","page":"Filesystem","title":"Base.Filesystem.abspath","text":"abspath(path::AbstractString) -> String\n\nConvert a path to an absolute path by adding the current directory if necessary. Also normalizes the path as in normpath.\n\nExamples\n\nIf you are in a directory called JuliaExample and the data you are using is two levels up relative to the JuliaExample directory, you could write:\n\nabspath(\"../../data\")\n\nWhich gives a path like \"/home/JuliaUser/data/\".\n\nSee also joinpath, pwd, expanduser.\n\n\n\n\n\nabspath(path::AbstractString, paths::AbstractString...) -> String\n\nConvert a set of paths to an absolute path by joining them together and adding the current directory if necessary. Equivalent to abspath(joinpath(path, paths...)).\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.normpath","page":"Filesystem","title":"Base.Filesystem.normpath","text":"normpath(path::AbstractString) -> String\n\nNormalize a path, removing \".\" and \"..\" entries and changing \"/\" to the canonical path separator for the system.\n\nExamples\n\njulia> normpath(\"/home/myuser/../example.jl\")\n\"/home/example.jl\"\n\njulia> normpath(\"Documents/Julia\") == joinpath(\"Documents\", \"Julia\")\ntrue\n\n\n\n\n\nnormpath(path::AbstractString, paths::AbstractString...) -> String\n\nConvert a set of paths to a normalized path by joining them together and removing \".\" and \"..\" entries. Equivalent to normpath(joinpath(path, paths...)).\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.realpath","page":"Filesystem","title":"Base.Filesystem.realpath","text":"realpath(path::AbstractString) -> String\n\nCanonicalize a path by expanding symbolic links and removing \".\" and \"..\" entries. On case-insensitive case-preserving filesystems (typically Mac and Windows), the filesystem's stored case for the path is returned.\n\n(This function throws an exception if path does not exist in the filesystem.)\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.relpath","page":"Filesystem","title":"Base.Filesystem.relpath","text":"relpath(path::AbstractString, startpath::AbstractString = \".\") -> String\n\nReturn a relative filepath to path either from the current directory or from an optional start directory. This is a path computation: the filesystem is not accessed to confirm the existence or nature of path or startpath.\n\nOn Windows, case sensitivity is applied to every part of the path except drive letters. If path and startpath refer to different drives, the absolute path of path is returned.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.expanduser","page":"Filesystem","title":"Base.Filesystem.expanduser","text":"expanduser(path::AbstractString) -> AbstractString\n\nOn Unix systems, replace a tilde character at the start of a path with the current user's home directory.\n\nSee also: contractuser.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.contractuser","page":"Filesystem","title":"Base.Filesystem.contractuser","text":"contractuser(path::AbstractString) -> AbstractString\n\nOn Unix systems, if the path starts with homedir(), replace it with a tilde character.\n\nSee also: expanduser.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.samefile","page":"Filesystem","title":"Base.Filesystem.samefile","text":"samefile(path_a::AbstractString, path_b::AbstractString)\n\nCheck if the paths path_a and path_b refer to the same existing file or directory.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.splitdir","page":"Filesystem","title":"Base.Filesystem.splitdir","text":"splitdir(path::AbstractString) -> (AbstractString, AbstractString)\n\nSplit a path into a tuple of the directory name and file name.\n\nExamples\n\njulia> splitdir(\"/home/myuser\")\n(\"/home\", \"myuser\")\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.splitdrive","page":"Filesystem","title":"Base.Filesystem.splitdrive","text":"splitdrive(path::AbstractString) -> (AbstractString, AbstractString)\n\nOn Windows, split a path into the drive letter part and the path part. On Unix systems, the first component is always the empty string.\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.splitext","page":"Filesystem","title":"Base.Filesystem.splitext","text":"splitext(path::AbstractString) -> (String, String)\n\nIf the last component of a path contains one or more dots, split the path into everything before the last dot and everything including and after the dot. Otherwise, return a tuple of the argument unmodified and the empty string. \"splitext\" is short for \"split extension\".\n\nExamples\n\njulia> splitext(\"/home/myuser/example.jl\")\n(\"/home/myuser/example\", \".jl\")\n\njulia> splitext(\"/home/myuser/example.tar.gz\")\n(\"/home/myuser/example.tar\", \".gz\")\n\njulia> splitext(\"/home/my.user/example\")\n(\"/home/my.user/example\", \"\")\n\n\n\n\n\n","category":"function"},{"location":"base/file/#Base.Filesystem.splitpath","page":"Filesystem","title":"Base.Filesystem.splitpath","text":"splitpath(path::AbstractString) -> Vector{String}\n\nSplit a file path into all its path components. This is the opposite of joinpath. Returns an array of substrings, one for each directory or file in the path, including the root directory if present.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nExamples\n\njulia> splitpath(\"/home/myuser/example.jl\")\n4-element Vector{String}:\n \"/\"\n \"home\"\n \"myuser\"\n \"example.jl\"\n\n\n\n\n\n","category":"function"},{"location":"manual/functions/#man-functions","page":"Functions","title":"Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In Julia, a function is an object that maps a tuple of argument values to a return value. Julia functions are not pure mathematical functions, because they can alter and be affected by the global state of the program. The basic syntax for defining functions in Julia is:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> function f(x, y)\n x + y\n end\nf (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This function accepts two arguments x and y and returns the value of the last expression evaluated, which is x + y.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"There is a second, more terse syntax for defining a function in Julia. The traditional function declaration syntax demonstrated above is equivalent to the following compact \"assignment form\":","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(x, y) = x + y\nf (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In the assignment form, the body of the function must be a single expression, although it can be a compound expression (see Compound Expressions). Short, simple function definitions are common in Julia. The short function syntax is accordingly quite idiomatic, considerably reducing both typing and visual noise.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A function is called using the traditional parenthesis syntax:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(2, 3)\n5","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Without parentheses, the expression f refers to the function object, and can be passed around like any other value:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> g = f;\n\njulia> g(2, 3)\n5","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"As with variables, Unicode can also be used for function names:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> ∑(x, y) = x + y\n∑ (generic function with 1 method)\n\njulia> ∑(2, 3)\n5","category":"page"},{"location":"manual/functions/#man-argument-passing","page":"Functions","title":"Argument Passing Behavior","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Julia function arguments follow a convention sometimes called \"pass-by-sharing\", which means that values are not copied when they are passed to functions. Function arguments themselves act as new variable bindings (new \"names\" that can refer to values), much like assignments argument_name = argument_value, so that the objects they refer to are identical to the passed values. Modifications to mutable values (such as Arrays) made within a function will be visible to the caller. (This is the same behavior found in Scheme, most Lisps, Python, Ruby and Perl, among other dynamic languages.)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For example, in the function","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(x, y)\n x[1] = 42 # mutates x\n y = 7 + y # new binding for y, no mutation\n return y\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The statement x[1] = 42 mutates the object x, and hence this change will be visible in the array passed by the caller for this argument. On the other hand, the assignment y = 7 + y changes the binding (\"name\") y to refer to a new value 7 + y, rather than mutating the original object referred to by y, and hence does not change the corresponding argument passed by the caller. This can be seen if we call f(x, y):","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> a = [4, 5, 6]\n3-element Vector{Int64}:\n 4\n 5\n 6\n\njulia> b = 3\n3\n\njulia> f(a, b) # returns 7 + b == 10\n10\n\njulia> a # a[1] is changed to 42 by f\n3-element Vector{Int64}:\n 42\n 5\n 6\n\njulia> b # not changed\n3","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"As a common convention in Julia (not a syntactic requirement), such a function would typically be named f!(x, y) rather than f(x, y), as a visual reminder at the call site that at least one of the arguments (often the first one) is being mutated.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"warning: Shared memory between arguments\nThe behavior of a mutating function can be unexpected when a mutated argument shares memory with another argument, a situation known as aliasing (e.g. when one is a view of the other). Unless the function docstring explicitly indicates that aliasing produces the expected result, it is the responsibility of the caller to ensure proper behavior on such inputs.","category":"page"},{"location":"manual/functions/#Argument-type-declarations","page":"Functions","title":"Argument-type declarations","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"You can declare the types of function arguments by appending ::TypeName to the argument name, as usual for Type Declarations in Julia. For example, the following function computes Fibonacci numbers recursively:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"fib(n::Integer) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"and the ::Integer specification means that it will only be callable when n is a subtype of the abstract Integer type.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Argument-type declarations normally have no impact on performance: regardless of what argument types (if any) are declared, Julia compiles a specialized version of the function for the actual argument types passed by the caller. For example, calling fib(1) will trigger the compilation of specialized version of fib optimized specifically for Int arguments, which is then re-used if fib(7) or fib(15) are called. (There are rare exceptions when an argument-type declaration can trigger additional compiler specializations; see: Be aware of when Julia avoids specializing.) The most common reasons to declare argument types in Julia are, instead:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Dispatch: As explained in Methods, you can have different versions (\"methods\") of a function for different argument types, in which case the argument types are used to determine which implementation is called for which arguments. For example, you might implement a completely different algorithm fib(x::Number) = ... that works for any Number type by using Binet's formula to extend it to non-integer values.\nCorrectness: Type declarations can be useful if your function only returns correct results for certain argument types. For example, if we omitted argument types and wrote fib(n) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2), then fib(1.5) would silently give us the nonsensical answer 1.0.\nClarity: Type declarations can serve as a form of documentation about the expected arguments.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"However, it is a common mistake to overly restrict the argument types, which can unnecessarily limit the applicability of the function and prevent it from being re-used in circumstances you did not anticipate. For example, the fib(n::Integer) function above works equally well for Int arguments (machine integers) and BigInt arbitrary-precision integers (see BigFloats and BigInts), which is especially useful because Fibonacci numbers grow exponentially rapidly and will quickly overflow any fixed-precision type like Int (see Overflow behavior). If we had declared our function as fib(n::Int), however, the application to BigInt would have been prevented for no reason. In general, you should use the most general applicable abstract types for arguments, and when in doubt, omit the argument types. You can always add argument-type specifications later if they become necessary, and you don't sacrifice performance or functionality by omitting them.","category":"page"},{"location":"manual/functions/#The-return-Keyword","page":"Functions","title":"The return Keyword","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The value returned by a function is the value of the last expression evaluated, which, by default, is the last expression in the body of the function definition. In the example function, f, from the previous section this is the value of the expression x + y. As an alternative, as in many other languages, the return keyword causes a function to return immediately, providing an expression whose value is returned:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function g(x, y)\n return x * y\n x + y\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Since function definitions can be entered into interactive sessions, it is easy to compare these definitions:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(x, y) = x + y\nf (generic function with 1 method)\n\njulia> function g(x, y)\n return x * y\n x + y\n end\ng (generic function with 1 method)\n\njulia> f(2, 3)\n5\n\njulia> g(2, 3)\n6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Of course, in a purely linear function body like g, the usage of return is pointless since the expression x + y is never evaluated and we could simply make x * y the last expression in the function and omit the return. In conjunction with other control flow, however, return is of real use. Here, for example, is a function that computes the hypotenuse length of a right triangle with sides of length x and y, avoiding overflow:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> function hypot(x, y)\n x = abs(x)\n y = abs(y)\n if x > y\n r = y/x\n return x*sqrt(1 + r*r)\n end\n if y == 0\n return zero(x)\n end\n r = x/y\n return y*sqrt(1 + r*r)\n end\nhypot (generic function with 1 method)\n\njulia> hypot(3, 4)\n5.0","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"There are three possible points of return from this function, returning the values of three different expressions, depending on the values of x and y. The return on the last line could be omitted since it is the last expression.","category":"page"},{"location":"manual/functions/#man-functions-return-type","page":"Functions","title":"Return type","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A return type can be specified in the function declaration using the :: operator. This converts the return value to the specified type.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> function g(x, y)::Int8\n return x * y\n end;\n\njulia> typeof(g(1, 2))\nInt8","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This function will always return an Int8 regardless of the types of x and y. See Type Declarations for more on return types.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Return type declarations are rarely used in Julia: in general, you should instead write \"type-stable\" functions in which Julia's compiler can automatically infer the return type. For more information, see the Performance Tips chapter.","category":"page"},{"location":"manual/functions/#Returning-nothing","page":"Functions","title":"Returning nothing","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For functions that do not need to return a value (functions used only for some side effects), the Julia convention is to return the value nothing:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function printx(x)\n println(\"x = $x\")\n return nothing\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This is a convention in the sense that nothing is not a Julia keyword but only a singleton object of type Nothing. Also, you may notice that the printx function example above is contrived, because println already returns nothing, so that the return line is redundant.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"There are two possible shortened forms for the return nothing expression. On the one hand, the return keyword implicitly returns nothing, so it can be used alone. On the other hand, since functions implicitly return their last expression evaluated, nothing can be used alone when it's the last expression. The preference for the expression return nothing as opposed to return or nothing alone is a matter of coding style.","category":"page"},{"location":"manual/functions/#Operators-Are-Functions","page":"Functions","title":"Operators Are Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In Julia, most operators are just functions with support for special syntax. (The exceptions are operators with special evaluation semantics like && and ||. These operators cannot be functions since Short-Circuit Evaluation requires that their operands are not evaluated before evaluation of the operator.) Accordingly, you can also apply them using parenthesized argument lists, just as you would any other function:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> 1 + 2 + 3\n6\n\njulia> +(1, 2, 3)\n6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The infix form is exactly equivalent to the function application form – in fact the former is parsed to produce the function call internally. This also means that you can assign and pass around operators such as + and * just like you would with other function values:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f = +;\n\njulia> f(1, 2, 3)\n6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Under the name f, the function does not support infix notation, however.","category":"page"},{"location":"manual/functions/#Operators-With-Special-Names","page":"Functions","title":"Operators With Special Names","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A few special expressions correspond to calls to functions with non-obvious names. These are:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Expression Calls\n[A B C ...] hcat\n[A; B; C; ...] vcat\n[A B; C D; ...] hvcat\n[A; B;; C; D;; ...] hvncat\nA' adjoint\nA[i] getindex\nA[i] = x setindex!\nA.n getproperty\nA.n = x setproperty!","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Note that expressions similar to [A; B;; C; D;; ...] but with more than two consecutive ; also correspond to hvncat calls.","category":"page"},{"location":"manual/functions/#man-anonymous-functions","page":"Functions","title":"Anonymous Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Functions in Julia are first-class objects: they can be assigned to variables, and called using the standard function call syntax from the variable they have been assigned to. They can be used as arguments, and they can be returned as values. They can also be created anonymously, without being given a name, using either of these syntaxes:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x -> x^2 + 2x - 1\n#1 (generic function with 1 method)\n\njulia> function (x)\n x^2 + 2x - 1\n end\n#3 (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Each statement creates a function taking one argument x and returning the value of the polynomial x^2 + 2x - 1 at that value. Notice that the result is a generic function, but with a compiler-generated name based on consecutive numbering.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The primary use for anonymous functions is passing them to functions which take other functions as arguments. A classic example is map, which applies a function to each value of an array and returns a new array containing the resulting values:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> map(round, [1.2, 3.5, 1.7])\n3-element Vector{Float64}:\n 1.0\n 4.0\n 2.0","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This is fine if a named function effecting the transform already exists to pass as the first argument to map. Often, however, a ready-to-use, named function does not exist. In these situations, the anonymous function construct allows easy creation of a single-use function object without needing a name:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> map(x -> x^2 + 2x - 1, [1, 3, -1])\n3-element Vector{Int64}:\n 2\n 14\n -2","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"An anonymous function accepting multiple arguments can be written using the syntax (x,y,z)->2x+y-z.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Argument-type declarations for anonymous functions work as for named functions, for example x::Integer->2x. The return type of an anonymous function cannot be specified.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A zero-argument anonymous function can be written as ()->2+2. The idea of a function with no arguments may seem strange, but is useful in cases where a result cannot (or should not) be precomputed. For example, Julia has a zero-argument time function that returns the current time in seconds, and thus seconds = ()->round(Int, time()) is an anonymous function that returns this time rounded to the nearest integer assigned to the variable seconds. Each time this anonymous function is called as seconds() the current time will be calculated and returned.","category":"page"},{"location":"manual/functions/#Tuples","page":"Functions","title":"Tuples","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Julia has a built-in data structure called a tuple that is closely related to function arguments and return values. A tuple is a fixed-length container that can hold any values, but cannot be modified (it is immutable). Tuples are constructed with commas and parentheses, and can be accessed via indexing:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (1, 1+1)\n(1, 2)\n\njulia> (1,)\n(1,)\n\njulia> x = (0.0, \"hello\", 6*7)\n(0.0, \"hello\", 42)\n\njulia> x[2]\n\"hello\"","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Notice that a length-1 tuple must be written with a comma, (1,), since (1) would just be a parenthesized value. () represents the empty (length-0) tuple.","category":"page"},{"location":"manual/functions/#Named-Tuples","page":"Functions","title":"Named Tuples","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The components of tuples can optionally be named, in which case a named tuple is constructed:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x = (a=2, b=1+2)\n(a = 2, b = 3)\n\njulia> x[1]\n2\n\njulia> x.a\n2","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The fields of named tuples can be accessed by name using dot syntax (x.a) in addition to the regular indexing syntax (x[1] or x[:a]).","category":"page"},{"location":"manual/functions/#destructuring-assignment","page":"Functions","title":"Destructuring Assignment and Multiple Return Values","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A comma-separated list of variables (optionally wrapped in parentheses) can appear on the left side of an assignment: the value on the right side is destructured by iterating over and assigning to each variable in turn:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (a, b, c) = 1:3\n1:3\n\njulia> b\n2","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The value on the right should be an iterator (see Iteration interface) at least as long as the number of variables on the left (any excess elements of the iterator are ignored).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This can be used to return multiple values from functions by returning a tuple or other iterable value. For example, the following function returns two values:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> function foo(a, b)\n a+b, a*b\n end\nfoo (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"If you call it in an interactive session without assigning the return value anywhere, you will see the tuple returned:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> foo(2, 3)\n(5, 6)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Destructuring assignment extracts each value into a variable:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x, y = foo(2, 3)\n(5, 6)\n\njulia> x\n5\n\njulia> y\n6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Another common use is for swapping variables:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> y, x = x, y\n(5, 6)\n\njulia> x\n6\n\njulia> y\n5","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"If only a subset of the elements of the iterator are required, a common convention is to assign ignored elements to a variable consisting of only underscores _ (which is an otherwise invalid variable name, see Allowed Variable Names):","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> _, _, _, d = 1:10\n1:10\n\njulia> d\n4","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Other valid left-hand side expressions can be used as elements of the assignment list, which will call setindex! or setproperty!, or recursively destructure individual elements of the iterator:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> X = zeros(3);\n\njulia> X[1], (a, b) = (1, (2, 3))\n(1, (2, 3))\n\njulia> X\n3-element Vector{Float64}:\n 1.0\n 0.0\n 0.0\n\njulia> a\n2\n\njulia> b\n3","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"compat: Julia 1.6\n... with assignment requires Julia 1.6","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"If the last symbol in the assignment list is suffixed by ... (known as slurping), then it will be assigned a collection or lazy iterator of the remaining elements of the right-hand side iterator:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> a, b... = \"hello\"\n\"hello\"\n\njulia> a\n'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)\n\njulia> b\n\"ello\"\n\njulia> a, b... = Iterators.map(abs2, 1:4)\nBase.Generator{UnitRange{Int64}, typeof(abs2)}(abs2, 1:4)\n\njulia> a\n1\n\njulia> b\nBase.Iterators.Rest{Base.Generator{UnitRange{Int64}, typeof(abs2)}, Int64}(Base.Generator{UnitRange{Int64}, typeof(abs2)}(abs2, 1:4), 1)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"See Base.rest for details on the precise handling and customization for specific iterators.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"compat: Julia 1.9\n... in non-final position of an assignment requires Julia 1.9","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Slurping in assignments can also occur in any other position. As opposed to slurping the end of a collection however, this will always be eager.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> a, b..., c = 1:5\n1:5\n\njulia> a\n1\n\njulia> b\n3-element Vector{Int64}:\n 2\n 3\n 4\n\njulia> c\n5\n\njulia> front..., tail = \"Hi!\"\n\"Hi!\"\n\njulia> front\n\"Hi\"\n\njulia> tail\n'!': ASCII/Unicode U+0021 (category Po: Punctuation, other)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This is implemented in terms of the function Base.split_rest.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Note that for variadic function definitions, slurping is still only allowed in final position. This does not apply to single argument destructuring though, as that does not affect method dispatch:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(x..., y) = x\nERROR: syntax: invalid \"...\" on non-final argument\nStacktrace:\n[...]\n\njulia> f((x..., y)) = x\nf (generic function with 1 method)\n\njulia> f((1, 2, 3))\n(1, 2)","category":"page"},{"location":"manual/functions/#Property-destructuring","page":"Functions","title":"Property destructuring","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Instead of destructuring based on iteration, the right side of assignments can also be destructured using property names. This follows the syntax for NamedTuples, and works by assigning to each variable on the left a property of the right side of the assignment with the same name using getproperty:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (; b, a) = (a=1, b=2, c=3)\n(a = 1, b = 2, c = 3)\n\njulia> a\n1\n\njulia> b\n2","category":"page"},{"location":"manual/functions/#man-argument-destructuring","page":"Functions","title":"Argument destructuring","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The destructuring feature can also be used within a function argument. If a function argument name is written as a tuple (e.g. (x, y)) instead of just a symbol, then an assignment (x, y) = argument will be inserted for you:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> minmax(x, y) = (y < x) ? (y, x) : (x, y)\n\njulia> gap((min, max)) = max - min\n\njulia> gap(minmax(10, 2))\n8","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Notice the extra set of parentheses in the definition of gap. Without those, gap would be a two-argument function, and this example would not work.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Similarly, property destructuring can also be used for function arguments:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> foo((; x, y)) = x + y\nfoo (generic function with 1 method)\n\njulia> foo((x=1, y=2))\n3\n\njulia> struct A\n x\n y\n end\n\njulia> foo(A(3, 4))\n7","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For anonymous functions, destructuring a single argument requires an extra comma:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> map(((x, y),) -> x + y, [(1, 2), (3, 4)])\n2-element Array{Int64,1}:\n 3\n 7","category":"page"},{"location":"manual/functions/#Varargs-Functions","page":"Functions","title":"Varargs Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"It is often convenient to be able to write functions taking an arbitrary number of arguments. Such functions are traditionally known as \"varargs\" functions, which is short for \"variable number of arguments\". You can define a varargs function by following the last positional argument with an ellipsis:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> bar(a, b, x...) = (a, b, x)\nbar (generic function with 1 method)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The variables a and b are bound to the first two argument values as usual, and the variable x is bound to an iterable collection of the zero or more values passed to bar after its first two arguments:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> bar(1, 2)\n(1, 2, ())\n\njulia> bar(1, 2, 3)\n(1, 2, (3,))\n\njulia> bar(1, 2, 3, 4)\n(1, 2, (3, 4))\n\njulia> bar(1, 2, 3, 4, 5, 6)\n(1, 2, (3, 4, 5, 6))","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In all these cases, x is bound to a tuple of the trailing values passed to bar.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"It is possible to constrain the number of values passed as a variable argument; this will be discussed later in Parametrically-constrained Varargs methods.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"On the flip side, it is often handy to \"splat\" the values contained in an iterable collection into a function call as individual arguments. To do this, one also uses ... but in the function call instead:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x = (3, 4)\n(3, 4)\n\njulia> bar(1, 2, x...)\n(1, 2, (3, 4))","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In this case a tuple of values is spliced into a varargs call precisely where the variable number of arguments go. This need not be the case, however:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x = (2, 3, 4)\n(2, 3, 4)\n\njulia> bar(1, x...)\n(1, 2, (3, 4))\n\njulia> x = (1, 2, 3, 4)\n(1, 2, 3, 4)\n\njulia> bar(x...)\n(1, 2, (3, 4))","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Furthermore, the iterable object splatted into a function call need not be a tuple:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> x = [3, 4]\n2-element Vector{Int64}:\n 3\n 4\n\njulia> bar(1, 2, x...)\n(1, 2, (3, 4))\n\njulia> x = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> bar(x...)\n(1, 2, (3, 4))","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Also, the function that arguments are splatted into need not be a varargs function (although it often is):","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> baz(a, b) = a + b;\n\njulia> args = [1, 2]\n2-element Vector{Int64}:\n 1\n 2\n\njulia> baz(args...)\n3\n\njulia> args = [1, 2, 3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> baz(args...)\nERROR: MethodError: no method matching baz(::Int64, ::Int64, ::Int64)\nThe function `baz` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n baz(::Any, ::Any)\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"As you can see, if the wrong number of elements are in the splatted container, then the function call will fail, just as it would if too many arguments were given explicitly.","category":"page"},{"location":"manual/functions/#Optional-Arguments","page":"Functions","title":"Optional Arguments","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"It is often possible to provide sensible default values for function arguments. This can save users from having to pass every argument on every call. For example, the function Date(y, [m, d]) from Dates module constructs a Date type for a given year y, month m and day d. However, m and d arguments are optional and their default value is 1. This behavior can be expressed concisely as:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> using Dates\n\njulia> function date(y::Int64, m::Int64=1, d::Int64=1)\n err = Dates.validargs(Date, y, m, d)\n err === nothing || throw(err)\n return Date(Dates.UTD(Dates.totaldays(y, m, d)))\n end\ndate (generic function with 3 methods)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Observe, that this definition calls another method of the Date function that takes one argument of type UTInstant{Day}.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"With this definition, the function can be called with either one, two or three arguments, and 1 is automatically passed when only one or two of the arguments are specified:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> date(2000, 12, 12)\n2000-12-12\n\njulia> date(2000, 12)\n2000-12-01\n\njulia> date(2000)\n2000-01-01","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Optional arguments are actually just a convenient syntax for writing multiple method definitions with different numbers of arguments (see Note on Optional and keyword Arguments). This can be checked for our date function example by calling the methods function:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> methods(date)\n# 3 methods for generic function \"date\":\n[1] date(y::Int64) in Main at REPL[1]:1\n[2] date(y::Int64, m::Int64) in Main at REPL[1]:1\n[3] date(y::Int64, m::Int64, d::Int64) in Main at REPL[1]:1","category":"page"},{"location":"manual/functions/#Keyword-Arguments","page":"Functions","title":"Keyword Arguments","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Some functions need a large number of arguments, or have a large number of behaviors. Remembering how to call such functions can be difficult. Keyword arguments can make these complex interfaces easier to use and extend by allowing arguments to be identified by name instead of only by position.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For example, consider a function plot that plots a line. This function might have many options, for controlling line style, width, color, and so on. If it accepts keyword arguments, a possible call might look like plot(x, y, width=2), where we have chosen to specify only line width. Notice that this serves two purposes. The call is easier to read, since we can label an argument with its meaning. It also becomes possible to pass any subset of a large number of arguments, in any order.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Functions with keyword arguments are defined using a semicolon in the signature:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function plot(x, y; style=\"solid\", width=1, color=\"black\")\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"When the function is called, the semicolon is optional: one can either call plot(x, y, width=2) or plot(x, y; width=2), but the former style is more common. An explicit semicolon is required only for passing varargs or computed keywords as described below.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Keyword argument default values are evaluated only when necessary (when a corresponding keyword argument is not passed), and in left-to-right order. Therefore default expressions may refer to prior keyword arguments.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The types of keyword arguments can be made explicit as follows:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(; x::Int=1)\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Keyword arguments can also be used in varargs functions:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function plot(x...; style=\"solid\")\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Extra keyword arguments can be collected using ..., as in varargs functions:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(x; y=0, kwargs...)\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Inside f, kwargs will be an immutable key-value iterator over a named tuple. Named tuples (as well as dictionaries with keys of Symbol, and other iterators yielding two-value collections with symbol as first values) can be passed as keyword arguments using a semicolon in a call, e.g. f(x, z=1; kwargs...).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"If a keyword argument is not assigned a default value in the method definition, then it is required: an UndefKeywordError exception will be thrown if the caller does not assign it a value:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(x; y)\n ###\nend\nf(3, y=5) # ok, y is assigned\nf(3) # throws UndefKeywordError(:y)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"One can also pass key => value expressions after a semicolon. For example, plot(x, y; :width => 2) is equivalent to plot(x, y, width=2). This is useful in situations where the keyword name is computed at runtime.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"When a bare identifier or dot expression occurs after a semicolon, the keyword argument name is implied by the identifier or field name. For example plot(x, y; width) is equivalent to plot(x, y; width=width) and plot(x, y; options.width) is equivalent to plot(x, y; width=options.width).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The nature of keyword arguments makes it possible to specify the same argument more than once. For example, in the call plot(x, y; options..., width=2) it is possible that the options structure also contains a value for width. In such a case the rightmost occurrence takes precedence; in this example, width is certain to have the value 2. However, explicitly specifying the same keyword argument multiple times, for example plot(x, y, width=2, width=3), is not allowed and results in a syntax error.","category":"page"},{"location":"manual/functions/#Evaluation-Scope-of-Default-Values","page":"Functions","title":"Evaluation Scope of Default Values","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"When optional and keyword argument default expressions are evaluated, only previous arguments are in scope. For example, given this definition:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function f(x, a=b, b=1)\n ###\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"the b in a=b refers to a b in an outer scope, not the subsequent argument b.","category":"page"},{"location":"manual/functions/#Do-Block-Syntax-for-Function-Arguments","page":"Functions","title":"Do-Block Syntax for Function Arguments","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Passing functions as arguments to other functions is a powerful technique, but the syntax for it is not always convenient. Such calls are especially awkward to write when the function argument requires multiple lines. As an example, consider calling map on a function with several cases:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"map(x->begin\n if x < 0 && iseven(x)\n return 0\n elseif x == 0\n return 1\n else\n return x\n end\n end,\n [A, B, C])","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Julia provides a reserved word do for rewriting this code more clearly:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"map([A, B, C]) do x\n if x < 0 && iseven(x)\n return 0\n elseif x == 0\n return 1\n else\n return x\n end\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The do x syntax creates an anonymous function with argument x and passes the anonymous function as the first argument to the \"outer\" function - map in this example. Similarly, do a,b would create a two-argument anonymous function. Note that do (a,b) would create a one-argument anonymous function, whose argument is a tuple to be deconstructed. A plain do would declare that what follows is an anonymous function of the form () -> ....","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"How these arguments are initialized depends on the \"outer\" function; here, map will sequentially set x to A, B, C, calling the anonymous function on each, just as would happen in the syntax map(func, [A, B, C]).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This syntax makes it easier to use functions to effectively extend the language, since calls look like normal code blocks. There are many possible uses quite different from map, such as managing system state. For example, there is a version of open that runs code ensuring that the opened file is eventually closed:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"open(\"outfile\", \"w\") do io\n write(io, data)\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This is accomplished by the following definition:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"function open(f::Function, args...)\n io = open(args...)\n try\n f(io)\n finally\n close(io)\n end\nend","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Here, open first opens the file for writing and then passes the resulting output stream to the anonymous function you defined in the do ... end block. After your function exits, open will make sure that the stream is properly closed, regardless of whether your function exited normally or threw an exception. (The try/finally construct will be described in Control Flow.)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"With the do block syntax, it helps to check the documentation or implementation to know how the arguments of the user function are initialized.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"A do block, like any other inner function, can \"capture\" variables from its enclosing scope. For example, the variable data in the above example of open...do is captured from the outer scope. Captured variables can create performance challenges as discussed in performance tips.","category":"page"},{"location":"manual/functions/#Function-composition-and-piping","page":"Functions","title":"Function composition and piping","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Functions in Julia can be combined by composing or piping (chaining) them together.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Function composition is when you combine functions together and apply the resulting composition to arguments. You use the function composition operator (∘) to compose the functions, so (f ∘ g)(args...; kw...) is the same as f(g(args...; kw...)).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"You can type the composition operator at the REPL and suitably-configured editors using \\circ.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"For example, the sqrt and + functions can be composed like this:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (sqrt ∘ +)(3, 6)\n3.0","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"This adds the numbers first, then finds the square root of the result.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The next example composes three functions and maps the result over an array of strings:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> map(first ∘ reverse ∘ uppercase, split(\"you can compose functions like this\"))\n6-element Vector{Char}:\n 'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)\n 'N': ASCII/Unicode U+004E (category Lu: Letter, uppercase)\n 'E': ASCII/Unicode U+0045 (category Lu: Letter, uppercase)\n 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)\n 'E': ASCII/Unicode U+0045 (category Lu: Letter, uppercase)\n 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Function chaining (sometimes called \"piping\" or \"using a pipe\" to send data to a subsequent function) is when you apply a function to the previous function's output:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> 1:10 |> sum |> sqrt\n7.416198487095663","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Here, the total produced by sum is passed to the sqrt function. The equivalent composition would be:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> (sqrt ∘ sum)(1:10)\n7.416198487095663","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"The pipe operator can also be used with broadcasting, as .|>, to provide a useful combination of the chaining/piping and dot vectorization syntax (described below).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> [\"a\", \"list\", \"of\", \"strings\"] .|> [uppercase, reverse, titlecase, length]\n4-element Vector{Any}:\n \"A\"\n \"tsil\"\n \"Of\"\n 7","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"When combining pipes with anonymous functions, parentheses must be used if subsequent pipes are not to be parsed as part of the anonymous function's body. Compare:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> 1:3 .|> (x -> x^2) |> sum |> sqrt\n3.7416573867739413\n\njulia> 1:3 .|> x -> x^2 |> sum |> sqrt\n3-element Vector{Float64}:\n 1.0\n 2.0\n 3.0","category":"page"},{"location":"manual/functions/#man-vectorized","page":"Functions","title":"Dot Syntax for Vectorizing Functions","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"In technical-computing languages, it is common to have \"vectorized\" versions of functions, which simply apply a given function f(x) to each element of an array A to yield a new array via f(A). This kind of syntax is convenient for data processing, but in other languages vectorization is also often required for performance: if loops are slow, the \"vectorized\" version of a function can call fast library code written in a low-level language. In Julia, vectorized functions are not required for performance, and indeed it is often beneficial to write your own loops (see Performance Tips), but they can still be convenient. Therefore, any Julia function f can be applied elementwise to any array (or other collection) with the syntax f.(A). For example, sin can be applied to all elements in the vector A like so:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> A = [1.0, 2.0, 3.0]\n3-element Vector{Float64}:\n 1.0\n 2.0\n 3.0\n\njulia> sin.(A)\n3-element Vector{Float64}:\n 0.8414709848078965\n 0.9092974268256817\n 0.1411200080598672","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Of course, you can omit the dot if you write a specialized \"vector\" method of f, e.g. via f(A::AbstractArray) = map(f, A), and this is just as efficient as f.(A). The advantage of the f.(A) syntax is that which functions are vectorizable need not be decided upon in advance by the library writer.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"More generally, f.(args...) is actually equivalent to broadcast(f, args...), which allows you to operate on multiple arrays (even of different shapes), or a mix of arrays and scalars (see Broadcasting). For example, if you have f(x, y) = 3x + 4y, then f.(pi, A) will return a new array consisting of f(pi,a) for each a in A, and f.(vector1, vector2) will return a new vector consisting of f(vector1[i], vector2[i]) for each index i (throwing an exception if the vectors have different length).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> f(x, y) = 3x + 4y;\n\njulia> A = [1.0, 2.0, 3.0];\n\njulia> B = [4.0, 5.0, 6.0];\n\njulia> f.(pi, A)\n3-element Vector{Float64}:\n 13.42477796076938\n 17.42477796076938\n 21.42477796076938\n\njulia> f.(A, B)\n3-element Vector{Float64}:\n 19.0\n 26.0\n 33.0","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Keyword arguments are not broadcasted over, but are simply passed through to each call of the function. For example, round.(x, digits=3) is equivalent to broadcast(x -> round(x, digits=3), x).","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Moreover, nested f.(args...) calls are fused into a single broadcast loop. For example, sin.(cos.(X)) is equivalent to broadcast(x -> sin(cos(x)), X), similar to [sin(cos(x)) for x in X]: there is only a single loop over X, and a single array is allocated for the result. [In contrast, sin(cos(X)) in a typical \"vectorized\" language would first allocate one temporary array for tmp=cos(X), and then compute sin(tmp) in a separate loop, allocating a second array.] This loop fusion is not a compiler optimization that may or may not occur, it is a syntactic guarantee whenever nested f.(args...) calls are encountered. Technically, the fusion stops as soon as a \"non-dot\" function call is encountered; for example, in sin.(sort(cos.(X))) the sin and cos loops cannot be merged because of the intervening sort function.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Finally, the maximum efficiency is typically achieved when the output array of a vectorized operation is pre-allocated, so that repeated calls do not allocate new arrays over and over again for the results (see Pre-allocating outputs). A convenient syntax for this is X .= ..., which is equivalent to broadcast!(identity, X, ...) except that, as above, the broadcast! loop is fused with any nested \"dot\" calls. For example, X .= sin.(Y) is equivalent to broadcast!(sin, X, Y), overwriting X with sin.(Y) in-place. If the left-hand side is an array-indexing expression, e.g. X[begin+1:end] .= sin.(Y), then it translates to broadcast! on a view, e.g. broadcast!(sin, view(X, firstindex(X)+1:lastindex(X)), Y), so that the left-hand side is updated in-place.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Since adding dots to many operations and function calls in an expression can be tedious and lead to code that is difficult to read, the macro @. is provided to convert every function call, operation, and assignment in an expression into the \"dotted\" version.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> Y = [1.0, 2.0, 3.0, 4.0];\n\njulia> X = similar(Y); # pre-allocate output array\n\njulia> @. X = sin(cos(Y)) # equivalent to X .= sin.(cos.(Y))\n4-element Vector{Float64}:\n 0.5143952585235492\n -0.4042391538522658\n -0.8360218615377305\n -0.6080830096407656","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"Binary (or unary) operators like .+ are handled with the same mechanism: they are equivalent to broadcast calls and are fused with other nested \"dot\" calls. X .+= Y etcetera is equivalent to X .= X .+ Y and results in a fused in-place assignment; see also dot operators.","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"You can also combine dot operations with function chaining using |>, as in this example:","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"julia> 1:5 .|> [x->x^2, inv, x->2*x, -, isodd]\n5-element Vector{Real}:\n 1\n 0.5\n 6\n -4\n true","category":"page"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"All functions in the fused broadcast are always called for every element of the result. Thus X .+ σ .* randn.() will add a mask of independent and identically sampled random values to each element of the array X, but X .+ σ .* randn() will add the same random sample to each element. In cases where the fused computation is constant along one or more axes of the broadcast iteration, it may be possible to leverage a space-time tradeoff and allocate intermediate values to reduce the number of computations. See more at performance tips.","category":"page"},{"location":"manual/functions/#Further-Reading","page":"Functions","title":"Further Reading","text":"","category":"section"},{"location":"manual/functions/","page":"Functions","title":"Functions","text":"We should mention here that this is far from a complete picture of defining functions. Julia has a sophisticated type system and allows multiple dispatch on argument types. None of the examples given here provide any type annotations on their arguments, meaning that they are applicable to all types of arguments. The type system is described in Types and defining a function in terms of methods chosen by multiple dispatch on run-time argument types is described in Methods.","category":"page"},{"location":"stdlib/Mmap/","page":"Memory-mapped I/O","title":"Memory-mapped I/O","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Mmap/docs/src/index.md\"","category":"page"},{"location":"stdlib/Mmap/#Memory-mapped-I/O","page":"Memory-mapped I/O","title":"Memory-mapped I/O","text":"","category":"section"},{"location":"stdlib/Mmap/","page":"Memory-mapped I/O","title":"Memory-mapped I/O","text":"Low level module for mmap (memory mapping of files).","category":"page"},{"location":"stdlib/Mmap/","page":"Memory-mapped I/O","title":"Memory-mapped I/O","text":"Mmap.Anonymous\nMmap.mmap\nMmap.sync!","category":"page"},{"location":"stdlib/Mmap/#Mmap.Anonymous","page":"Memory-mapped I/O","title":"Mmap.Anonymous","text":"Mmap.Anonymous(name::AbstractString=\"\", readonly::Bool=false, create::Bool=true)\n\nCreate an IO-like object for creating zeroed-out mmapped-memory that is not tied to a file for use in mmap. Used by SharedArray for creating shared memory arrays.\n\nExamples\n\njulia> using Mmap\n\njulia> anon = Mmap.Anonymous();\n\njulia> isreadable(anon)\ntrue\n\njulia> iswritable(anon)\ntrue\n\njulia> isopen(anon)\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Mmap/#Mmap.mmap","page":"Memory-mapped I/O","title":"Mmap.mmap","text":"mmap(io::Union{IOStream,AbstractString,Mmap.AnonymousMmap}[, type::Type{Array{T,N}}, dims, offset]; grow::Bool=true, shared::Bool=true)\nmmap(type::Type{Array{T,N}}, dims)\n\nCreate an Array whose values are linked to a file, using memory-mapping. This provides a convenient way of working with data too large to fit in the computer's memory.\n\nThe type is an Array{T,N} with a bits-type element of T and dimension N that determines how the bytes of the array are interpreted. Note that the file must be stored in binary format, and no format conversions are possible (this is a limitation of operating systems, not Julia).\n\ndims is a tuple or single Integer specifying the size or length of the array.\n\nThe file is passed via the stream argument, either as an open IOStream or filename string. When you initialize the stream, use \"r\" for a \"read-only\" array, and \"w+\" to create a new array used to write values to disk.\n\nIf no type argument is specified, the default is Vector{UInt8}.\n\nOptionally, you can specify an offset (in bytes) if, for example, you want to skip over a header in the file. The default value for the offset is the current stream position for an IOStream.\n\nThe grow keyword argument specifies whether the disk file should be grown to accommodate the requested size of array (if the total file size is < requested array size). Write privileges are required to grow the file.\n\nThe shared keyword argument specifies whether the resulting Array and changes made to it will be visible to other processes mapping the same file.\n\nFor example, the following code\n\n# Create a file for mmapping\n# (you could alternatively use mmap to do this step, too)\nusing Mmap\nA = rand(1:20, 5, 30)\ns = open(\"/tmp/mmap.bin\", \"w+\")\n# We'll write the dimensions of the array as the first two Ints in the file\nwrite(s, size(A,1))\nwrite(s, size(A,2))\n# Now write the data\nwrite(s, A)\nclose(s)\n\n# Test by reading it back in\ns = open(\"/tmp/mmap.bin\") # default is read-only\nm = read(s, Int)\nn = read(s, Int)\nA2 = mmap(s, Matrix{Int}, (m,n))\n\ncreates a m-by-n Matrix{Int}, linked to the file associated with stream s.\n\nA more portable file would need to encode the word size – 32 bit or 64 bit – and endianness information in the header. In practice, consider encoding binary data using standard formats like HDF5 (which can be used with memory-mapping).\n\n\n\n\n\nmmap(io, BitArray, [dims, offset])\n\nCreate a BitArray whose values are linked to a file, using memory-mapping; it has the same purpose, works in the same way, and has the same arguments, as mmap, but the byte representation is different.\n\nExamples\n\njulia> using Mmap\n\njulia> io = open(\"mmap.bin\", \"w+\");\n\njulia> B = mmap(io, BitArray, (25,30000));\n\njulia> B[3, 4000] = true;\n\njulia> Mmap.sync!(B);\n\njulia> close(io);\n\njulia> io = open(\"mmap.bin\", \"r+\");\n\njulia> C = mmap(io, BitArray, (25,30000));\n\njulia> C[3, 4000]\ntrue\n\njulia> C[2, 4000]\nfalse\n\njulia> close(io)\n\njulia> rm(\"mmap.bin\")\n\nThis creates a 25-by-30000 BitArray, linked to the file associated with stream io.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Mmap/#Mmap.sync!","page":"Memory-mapped I/O","title":"Mmap.sync!","text":"Mmap.sync!(array)\n\nForces synchronization between the in-memory version of a memory-mapped Array or BitArray and the on-disk version.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/sysimg/#System-Image-Building","page":"System Image Building","title":"System Image Building","text":"","category":"section"},{"location":"devdocs/sysimg/#Building-the-Julia-system-image","page":"System Image Building","title":"Building the Julia system image","text":"","category":"section"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"Julia ships with a preparsed system image containing the contents of the Base module, named sys.ji. This file is also precompiled into a shared library called sys.{so,dll,dylib} on as many platforms as possible, so as to give vastly improved startup times. On systems that do not ship with a precompiled system image file, one can be generated from the source files shipped in Julia's DATAROOTDIR/julia/base folder.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"Julia will by default generate its system image on half of the available system threads. This may be controlled by the JULIA_IMAGE_THREADS environment variable.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"This operation is useful for multiple reasons. A user may:","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"Build a precompiled shared library system image on a platform that did not ship with one, thereby improving startup times.\nModify Base, rebuild the system image and use the new Base next time Julia is started.\nInclude a userimg.jl file that includes packages into the system image, thereby creating a system image that has packages embedded into the startup environment.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"The PackageCompiler.jl package contains convenient wrapper functions to automate this process.","category":"page"},{"location":"devdocs/sysimg/#sysimg-multi-versioning","page":"System Image Building","title":"System image optimized for multiple microarchitectures","text":"","category":"section"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"The system image can be compiled simultaneously for multiple CPU microarchitectures under the same instruction set architecture (ISA). Multiple versions of the same function may be created with minimum dispatch point inserted into shared functions in order to take advantage of different ISA extensions or other microarchitecture features. The version that offers the best performance will be selected automatically at runtime based on available CPU features.","category":"page"},{"location":"devdocs/sysimg/#Specifying-multiple-system-image-targets","page":"System Image Building","title":"Specifying multiple system image targets","text":"","category":"section"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"A multi-microarchitecture system image can be enabled by passing multiple targets during system image compilation. This can be done either with the JULIA_CPU_TARGET make option or with the -C command line option when running the compilation command manually. Multiple targets are separated by ; in the option string. The syntax for each target is a CPU name followed by multiple features separated by ,. All features supported by LLVM are supported and a feature can be disabled with a - prefix. (+ prefix is also allowed and ignored to be consistent with LLVM syntax). Additionally, a few special features are supported to control the function cloning behavior.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"note: Note\nIt is good practice to specify either clone_all or base() for every target apart from the first one. This makes it explicit which targets have all functions cloned, and which targets are based on other targets. If this is not done, the default behavior is to not clone every function, and to use the first target's function definition as the fallback when not cloning a function.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"clone_all\nBy default, only functions that are the most likely to benefit from the microarchitecture features will be cloned. When clone_all is specified for a target, however, all functions in the system image will be cloned for the target. The negative form -clone_all can be used to prevent the built-in heuristic from cloning all functions.\nbase()\nWhere is a placeholder for a non-negative number (e.g. base(0), base(1)). By default, a partially cloned (i.e. not clone_all) target will use functions from the default target (first one specified) if a function is not cloned. This behavior can be changed by specifying a different base with the base() option. The nth target (0-based) will be used as the base target instead of the default (0th) one. The base target has to be either 0 or another clone_all target. Specifying a non-clone_all target as the base target will cause an error.\nopt_size\nThis causes the function for the target to be optimized for size when there isn't a significant runtime performance impact. This corresponds to -Os GCC and Clang option.\nmin_size\nThis causes the function for the target to be optimized for size that might have a significant runtime performance impact. This corresponds to -Oz Clang option.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"As an example, at the time of this writing, the following string is used in the creation of the official x86_64 Julia binaries downloadable from julialang.org:","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"This creates a system image with three separate targets; one for a generic x86_64 processor, one with a sandybridge ISA (explicitly excluding xsaveopt) that explicitly clones all functions, and one targeting the haswell ISA, based off of the sandybridge sysimg version, and also excluding rdrnd. When a Julia implementation loads the generated sysimg, it will check the host processor for matching CPU capability flags, enabling the highest ISA level possible. Note that the base level (generic) requires the cx16 instruction, which is disabled in some virtualization software and must be enabled for the generic target to be loaded. Alternatively, a sysimg could be generated with the target generic,-cx16 for greater compatibility, however note that this may cause performance and stability problems in some code.","category":"page"},{"location":"devdocs/sysimg/#Implementation-overview","page":"System Image Building","title":"Implementation overview","text":"","category":"section"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"This is a brief overview of different part involved in the implementation. See code comments for each components for more implementation details.","category":"page"},{"location":"devdocs/sysimg/","page":"System Image Building","title":"System Image Building","text":"System image compilation\nThe parsing and cloning decision are done in src/processor*. We currently support cloning of function based on the present of loops, simd instructions, or other math operations (e.g. fastmath, fma, muladd). This information is passed on to src/llvm-multiversioning.cpp which does the actual cloning. In addition to doing the cloning and insert dispatch slots (see comments in MultiVersioning::runOnModule for how this is done), the pass also generates metadata so that the runtime can load and initialize the system image correctly. A detailed description of the metadata is available in src/processor.h.\nSystem image loading\nThe loading and initialization of the system image is done in src/processor* by parsing the metadata saved during system image generation. Host feature detection and selection decision are done in src/processor_*.cpp depending on the ISA. The target selection will prefer exact CPU name match, larger vector register size, and larger number of features. An overview of this process is in src/processor.cpp.","category":"page"},{"location":"devdocs/functions/#Julia-Functions","page":"Julia Functions","title":"Julia Functions","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This document will explain how functions, method definitions, and method tables work.","category":"page"},{"location":"devdocs/functions/#Method-Tables","page":"Julia Functions","title":"Method Tables","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Every function in Julia is a generic function. A generic function is conceptually a single function, but consists of many definitions, or methods. The methods of a generic function are stored in a method table. Method tables (type MethodTable) are associated with TypeNames. A TypeName describes a family of parameterized types. For example Complex{Float32} and Complex{Float64} share the same Complex type name object.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"All objects in Julia are potentially callable, because every object has a type, which in turn has a TypeName.","category":"page"},{"location":"devdocs/functions/#Function-calls","page":"Julia Functions","title":"Function calls","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Given the call f(x, y), the following steps are performed: first, the method table to use is accessed as typeof(f).name.mt. Second, an argument tuple type is formed, Tuple{typeof(f), typeof(x), typeof(y)}. Note that the type of the function itself is the first element. This is because the type might have parameters, and so needs to take part in dispatch. This tuple type is looked up in the method table.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This dispatch process is performed by jl_apply_generic, which takes two arguments: a pointer to an array of the values f, x, and y, and the number of values (in this case 3).","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Throughout the system, there are two kinds of APIs that handle functions and argument lists: those that accept the function and arguments separately, and those that accept a single argument structure. In the first kind of API, the \"arguments\" part does not contain information about the function, since that is passed separately. In the second kind of API, the function is the first element of the argument structure.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"For example, the following function for performing a call accepts just an args pointer, so the first element of the args array will be the function to call:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"jl_value_t *jl_apply(jl_value_t **args, uint32_t nargs)","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This entry point for the same functionality accepts the function separately, so the args array does not contain the function:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs);","category":"page"},{"location":"devdocs/functions/#Adding-methods","page":"Julia Functions","title":"Adding methods","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Given the above dispatch process, conceptually all that is needed to add a new method is (1) a tuple type, and (2) code for the body of the method. jl_method_def implements this operation. jl_method_table_for is called to extract the relevant method table from what would be the type of the first argument. This is much more complicated than the corresponding procedure during dispatch, since the argument tuple type might be abstract. For example, we can define:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"(::Union{Foo{Int},Foo{Int8}})(x) = 0","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"which works since all possible matching methods would belong to the same method table.","category":"page"},{"location":"devdocs/functions/#Creating-generic-functions","page":"Julia Functions","title":"Creating generic functions","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Since every object is callable, nothing special is needed to create a generic function. Therefore jl_new_generic_function simply creates a new singleton (0 size) subtype of Function and returns its instance. A function can have a mnemonic \"display name\" which is used in debug info and when printing objects. For example the name of Base.sin is sin. By convention, the name of the created type is the same as the function name, with a # prepended. So typeof(sin) is Base.#sin.","category":"page"},{"location":"devdocs/functions/#Closures","page":"Julia Functions","title":"Closures","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"A closure is simply a callable object with field names corresponding to captured variables. For example, the following code:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function adder(x)\n return y->x+y\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"is lowered to (roughly):","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"struct ##1{T}\n x::T\nend\n\n(_::##1)(y) = _.x + y\n\nfunction adder(x)\n return ##1(x)\nend","category":"page"},{"location":"devdocs/functions/#Constructors","page":"Julia Functions","title":"Constructors","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"A constructor call is just a call to a type. The method table for Type contains all constructor definitions. All subtypes of Type (Type, UnionAll, Union, and DataType) currently share a method table via special arrangement.","category":"page"},{"location":"devdocs/functions/#Builtins","page":"Julia Functions","title":"Builtins","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The \"builtin\" functions, defined in the Core module, are:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function lines(words)\n io = IOBuffer()\n n = 0\n for w in words\n if n+length(w) > 80\n print(io, '\\n', w)\n n = length(w)\n elseif n == 0\n print(io, w);\n n += length(w)\n else\n print(io, ' ', w);\n n += length(w)+1\n end\n end\n String(take!(io))\nend\nimport Markdown\n[string(n) for n in names(Core;all=true)\n if getfield(Core,n) isa Core.Builtin && nameof(getfield(Core,n)) === n] |>\n lines |>\n s -> \"```\\n$s\\n```\" |>\n Markdown.parse","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"These are all singleton objects whose types are subtypes of Builtin, which is a subtype of Function. Their purpose is to expose entry points in the run time that use the \"jlcall\" calling convention:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"jl_value_t *(jl_value_t*, jl_value_t**, uint32_t)","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The method tables of builtins are empty. Instead, they have a single catch-all method cache entry (Tuple{Vararg{Any}}) whose jlcall fptr points to the correct function. This is kind of a hack but works reasonably well.","category":"page"},{"location":"devdocs/functions/#Keyword-arguments","page":"Julia Functions","title":"Keyword arguments","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Keyword arguments work by adding methods to the kwcall function. This function is usually the \"keyword argument sorter\" or \"keyword sorter\", which then calls the inner body of the function (defined anonymously). Every definition in the kwsorter function has the same arguments as some definition in the normal method table, except with a single NamedTuple argument prepended, which gives the names and values of passed keyword arguments. The kwsorter's job is to move keyword arguments into their canonical positions based on name, plus evaluate and substitute any needed default value expressions. The result is a normal positional argument list, which is then passed to yet another compiler-generated function.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The easiest way to understand the process is to look at how a keyword argument method definition is lowered. The code:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function circle(center, radius; color = black, fill::Bool = true, options...)\n # draw\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"actually produces three method definitions. The first is a function that accepts all arguments (including keyword arguments) as positional arguments, and includes the code for the method body. It has an auto-generated name:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function #circle#1(color, fill::Bool, options, circle, center, radius)\n # draw\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The second method is an ordinary definition for the original circle function, which handles the case where no keyword arguments are passed:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function circle(center, radius)\n #circle#1(black, true, pairs(NamedTuple()), circle, center, radius)\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This simply dispatches to the first method, passing along default values. pairs is applied to the named tuple of rest arguments to provide key-value pair iteration. Note that if the method doesn't accept rest keyword arguments then this argument is absent.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Finally there is the kwsorter definition:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"function (::Core.kwftype(typeof(circle)))(kws, circle, center, radius)\n if haskey(kws, :color)\n color = kws.color\n else\n color = black\n end\n # etc.\n\n # put remaining kwargs in `options`\n options = structdiff(kws, NamedTuple{(:color, :fill)})\n\n # if the method doesn't accept rest keywords, throw an error\n # unless `options` is empty\n\n #circle#1(color, fill, pairs(options), circle, center, radius)\nend","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The function Core.kwftype(t) creates the field t.name.mt.kwsorter (if it hasn't been created yet), and returns the type of that function.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"This design has the feature that call sites that don't use keyword arguments require no special handling; everything works as if they were not part of the language at all. Call sites that do use keyword arguments are dispatched directly to the called function's kwsorter. For example the call:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"circle((0, 0), 1.0, color = red; other...)","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"is lowered to:","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"kwcall(merge((color = red,), other), circle, (0, 0), 1.0)","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"kwcall (also inCore) denotes a kwcall signature and dispatch. The keyword splatting operation (written as other...) calls the named tuple merge function. This function further unpacks each element of other, expecting each one to contain two values (a symbol and a value). Naturally, a more efficient implementation is available if all splatted arguments are named tuples. Notice that the original circle function is passed through, to handle closures.","category":"page"},{"location":"devdocs/functions/#compiler-efficiency-issues","page":"Julia Functions","title":"Compiler efficiency issues","text":"","category":"section"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"Generating a new type for every function has potentially serious consequences for compiler resource use when combined with Julia's \"specialize on all arguments by default\" design. Indeed, the initial implementation of this design suffered from much longer build and test times, higher memory use, and a system image nearly 2x larger than the baseline. In a naive implementation, the problem is bad enough to make the system nearly unusable. Several significant optimizations were needed to make the design practical.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The first issue is excessive specialization of functions for different values of function-valued arguments. Many functions simply \"pass through\" an argument to somewhere else, e.g. to another function or to a storage location. Such functions do not need to be specialized for every closure that might be passed in. Fortunately this case is easy to distinguish by simply considering whether a function calls one of its arguments (i.e. the argument appears in \"head position\" somewhere). Performance-critical higher-order functions like map certainly call their argument function and so will still be specialized as expected. This optimization is implemented by recording which arguments are called during the analyze-variables pass in the front end. When cache_method sees an argument in the Function type hierarchy passed to a slot declared as Any or Function, it behaves as if the @nospecialize annotation were applied. This heuristic seems to be extremely effective in practice.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The next issue concerns the structure of method cache hash tables. Empirical studies show that the vast majority of dynamically-dispatched calls involve one or two arguments. In turn, many of these cases can be resolved by considering only the first argument. (Aside: proponents of single dispatch would not be surprised by this at all. However, this argument means \"multiple dispatch is easy to optimize in practice\", and that we should therefore use it, not \"we should use single dispatch\"!) So the method cache uses the type of the first argument as its primary key. Note, however, that this corresponds to the second element of the tuple type for a function call (the first element being the type of the function itself). Typically, type variation in head position is extremely low – indeed, the majority of functions belong to singleton types with no parameters. However, this is not the case for constructors, where a single method table holds constructors for every type. Therefore the Type method table is special-cased to use the first tuple type element instead of the second.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The front end generates type declarations for all closures. Initially, this was implemented by generating normal type declarations. However, this produced an extremely large number of constructors, all of which were trivial (simply passing all arguments through to new). Since methods are partially ordered, inserting all of these methods is O(n²), plus there are just too many of them to keep around. This was optimized by generating struct_type expressions directly (bypassing default constructor generation), and using new directly to create closure instances. Not the prettiest thing ever, but you do what you gotta do.","category":"page"},{"location":"devdocs/functions/","page":"Julia Functions","title":"Julia Functions","text":"The next problem was the @test macro, which generated a 0-argument closure for each test case. This is not really necessary, since each test case is simply run once in place. Therefore, @test was modified to expand to a try-catch block that records the test result (true, false, or exception raised) and calls the test suite handler on it.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Profile/docs/src/index.md\"","category":"page"},{"location":"stdlib/Profile/#lib-profiling","page":"Profiling","title":"Profiling","text":"","category":"section"},{"location":"stdlib/Profile/#CPU-Profiling","page":"Profiling","title":"CPU Profiling","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"There are two main approaches to CPU profiling julia code:","category":"page"},{"location":"stdlib/Profile/#Via-@profile","page":"Profiling","title":"Via @profile","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Where profiling is enabled for a given call via the @profile macro.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> @profile foo()\n\njulia> Profile.print()\nOverhead ╎ [+additional indent] Count File:Line; Function\n=========================================================\n ╎147 @Base/client.jl:506; _start()\n ╎ 147 @Base/client.jl:318; exec_options(opts::Base.JLOptions)\n...","category":"page"},{"location":"stdlib/Profile/#Triggered-During-Execution","page":"Profiling","title":"Triggered During Execution","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Tasks that are already running can also be profiled for a fixed time period at any user-triggered time.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"To trigger the profiling:","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"MacOS & FreeBSD (BSD-based platforms): Use ctrl-t or pass a SIGINFO signal to the julia process i.e. % kill -INFO $julia_pid\nLinux: Pass a SIGUSR1 signal to the julia process i.e. % kill -USR1 $julia_pid\nWindows: Not currently supported.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"First, a single stack trace at the instant that the signal was thrown is shown, then a 1 second profile is collected, followed by the profile report at the next yield point, which may be at task completion for code without yield points e.g. tight loops.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Optionally set environment variable JULIA_PROFILE_PEEK_HEAP_SNAPSHOT to 1 to also automatically collect a heap snapshot.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> foo()\n##== the user sends a trigger while foo is running ==##\nload: 2.53 cmd: julia 88903 running 6.16u 0.97s\n\n======================================================================================\nInformation request received. A stacktrace will print followed by a 1.0 second profile\n======================================================================================\n\nsignal (29): Information request: 29\n__psynch_cvwait at /usr/lib/system/libsystem_kernel.dylib (unknown line)\n_pthread_cond_wait at /usr/lib/system/libsystem_pthread.dylib (unknown line)\n...\n\n======================================================================\nProfile collected. A report will print if the Profile module is loaded\n======================================================================\n\nOverhead ╎ [+additional indent] Count File:Line; Function\n=========================================================\nThread 1 Task 0x000000011687c010 Total snapshots: 572. Utilization: 100%\n ╎147 @Base/client.jl:506; _start()\n ╎ 147 @Base/client.jl:318; exec_options(opts::Base.JLOptions)\n...\n\nThread 2 Task 0x0000000116960010 Total snapshots: 572. Utilization: 0%\n ╎572 @Base/task.jl:587; task_done_hook(t::Task)\n ╎ 572 @Base/task.jl:879; wait()\n...","category":"page"},{"location":"stdlib/Profile/#Customization","page":"Profiling","title":"Customization","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The duration of the profiling can be adjusted via Profile.set_peek_duration","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The profile report is broken down by thread and task. Pass a no-arg function to Profile.peek_report[] to override this. i.e. Profile.peek_report[] = () -> Profile.print() to remove any grouping. This could also be overridden by an external profile data consumer.","category":"page"},{"location":"stdlib/Profile/#Reference","page":"Profiling","title":"Reference","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.@profile","category":"page"},{"location":"stdlib/Profile/#Profile.@profile","page":"Profiling","title":"Profile.@profile","text":"@profile\n\n@profile runs your expression while taking periodic backtraces. These are appended to an internal buffer of backtraces.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The methods in Profile are not exported and need to be called e.g. as Profile.print().","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.clear\nProfile.print\nProfile.init\nProfile.fetch\nProfile.retrieve\nProfile.callers\nProfile.clear_malloc_data\nProfile.get_peek_duration\nProfile.set_peek_duration","category":"page"},{"location":"stdlib/Profile/#Profile.clear","page":"Profiling","title":"Profile.clear","text":"clear()\n\nClear any existing backtraces from the internal buffer.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.print","page":"Profiling","title":"Profile.print","text":"print([io::IO = stdout,] [data::Vector = fetch()], [lidict::Union{LineInfoDict, LineInfoFlatDict} = getdict(data)]; kwargs...)\n\nPrints profiling results to io (by default, stdout). If you do not supply a data vector, the internal buffer of accumulated backtraces will be used.\n\nThe keyword arguments can be any combination of:\n\nformat – Determines whether backtraces are printed with (default, :tree) or without (:flat) indentation indicating tree structure.\nC – If true, backtraces from C and Fortran code are shown (normally they are excluded).\ncombine – If true (default), instruction pointers are merged that correspond to the same line of code.\nmaxdepth – Limits the depth higher than maxdepth in the :tree format.\nsortedby – Controls the order in :flat format. :filefuncline (default) sorts by the source line, :count sorts in order of number of collected samples, and :overhead sorts by the number of samples incurred by each function by itself.\ngroupby – Controls grouping over tasks and threads, or no grouping. Options are :none (default), :thread, :task, [:thread, :task], or [:task, :thread] where the last two provide nested grouping.\nnoisefloor – Limits frames that exceed the heuristic noise floor of the sample (only applies to format :tree). A suggested value to try for this is 2.0 (the default is 0). This parameter hides samples for which n <= noisefloor * √N, where n is the number of samples on this line, and N is the number of samples for the callee.\nmincount – Limits the printout to only those lines with at least mincount occurrences.\nrecur – Controls the recursion handling in :tree format. :off (default) prints the tree as normal. :flat instead compresses any recursion (by ip), showing the approximate effect of converting any self-recursion into an iterator. :flatc does the same but also includes collapsing of C frames (may do odd things around jl_apply).\nthreads::Union{Int,AbstractVector{Int}} – Specify which threads to include snapshots from in the report. Note that this does not control which threads samples are collected on (which may also have been collected on another machine).\ntasks::Union{Int,AbstractVector{Int}} – Specify which tasks to include snapshots from in the report. Note that this does not control which tasks samples are collected within.\n\ncompat: Julia 1.8\nThe groupby, threads, and tasks keyword arguments were introduced in Julia 1.8.\n\nnote: Note\nProfiling on windows is limited to the main thread. Other threads have not been sampled and will not show in the report.\n\n\n\n\n\nprint([io::IO = stdout,] data::Vector, lidict::LineInfoDict; kwargs...)\n\nPrints profiling results to io. This variant is used to examine results exported by a previous call to retrieve. Supply the vector data of backtraces and a dictionary lidict of line information.\n\nSee Profile.print([io], data) for an explanation of the valid keyword arguments.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.init","page":"Profiling","title":"Profile.init","text":"init(; n::Integer, delay::Real)\n\nConfigure the delay between backtraces (measured in seconds), and the number n of instruction pointers that may be stored per thread. Each instruction pointer corresponds to a single line of code; backtraces generally consist of a long list of instruction pointers. Note that 6 spaces for instruction pointers per backtrace are used to store metadata and two NULL end markers. Current settings can be obtained by calling this function with no arguments, and each can be set independently using keywords or in the order (n, delay).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.fetch","page":"Profiling","title":"Profile.fetch","text":"fetch(;include_meta = true) -> data\n\nReturn a copy of the buffer of profile backtraces. Note that the values in data have meaning only on this machine in the current session, because it depends on the exact memory addresses used in JIT-compiling. This function is primarily for internal use; retrieve may be a better choice for most users. By default metadata such as threadid and taskid is included. Set include_meta to false to strip metadata.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.retrieve","page":"Profiling","title":"Profile.retrieve","text":"retrieve(; kwargs...) -> data, lidict\n\n\"Exports\" profiling results in a portable format, returning the set of all backtraces (data) and a dictionary that maps the (session-specific) instruction pointers in data to LineInfo values that store the file name, function name, and line number. This function allows you to save profiling results for future analysis.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.callers","page":"Profiling","title":"Profile.callers","text":"callers(funcname, [data, lidict], [filename=], [linerange=]) -> Vector{Tuple{count, lineinfo}}\n\nGiven a previous profiling run, determine who called a particular function. Supplying the filename (and optionally, range of line numbers over which the function is defined) allows you to disambiguate an overloaded method. The returned value is a vector containing a count of the number of calls and line information about the caller. One can optionally supply backtrace data obtained from retrieve; otherwise, the current internal profile buffer is used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.clear_malloc_data","page":"Profiling","title":"Profile.clear_malloc_data","text":"clear_malloc_data()\n\nClears any stored memory allocation data when running julia with --track-allocation. Execute the command(s) you want to test (to force JIT-compilation), then call clear_malloc_data. Then execute your command(s) again, quit Julia, and examine the resulting *.mem files.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.get_peek_duration","page":"Profiling","title":"Profile.get_peek_duration","text":"get_peek_duration()\n\nGet the duration in seconds of the profile \"peek\" that is triggered via SIGINFO or SIGUSR1, depending on platform.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.set_peek_duration","page":"Profiling","title":"Profile.set_peek_duration","text":"set_peek_duration(t::Float64)\n\nSet the duration in seconds of the profile \"peek\" that is triggered via SIGINFO or SIGUSR1, depending on platform.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Memory-profiling","page":"Profiling","title":"Memory profiling","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.Allocs.@profile","category":"page"},{"location":"stdlib/Profile/#Profile.Allocs.@profile","page":"Profiling","title":"Profile.Allocs.@profile","text":"Profile.Allocs.@profile [sample_rate=0.1] expr\n\nProfile allocations that happen during expr, returning both the result and AllocResults struct.\n\nA sample rate of 1.0 will record everything; 0.0 will record nothing.\n\njulia> Profile.Allocs.@profile sample_rate=0.01 peakflops()\n1.03733270279065e11\n\njulia> results = Profile.Allocs.fetch()\n\njulia> last(sort(results.allocs, by=x->x.size))\nProfile.Allocs.Alloc(Vector{Any}, Base.StackTraces.StackFrame[_new_array_ at array.c:127, ...], 5576)\n\nThe best way to visualize these is currently with the PProf.jl package, by invoking PProf.Allocs.pprof.\n\nnote: Note\nThe current implementation of the Allocations Profiler does not capture types for all allocations. Allocations for which the profiler could not capture the type are represented as having type Profile.Allocs.UnknownType.You can read more about the missing types and the plan to improve this, here: https://github.com/JuliaLang/julia/issues/43688.\n\ncompat: Julia 1.8\nThe allocation profiler was added in Julia 1.8.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The methods in Profile.Allocs are not exported and need to be called e.g. as Profile.Allocs.fetch().","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.Allocs.clear\nProfile.Allocs.print\nProfile.Allocs.fetch\nProfile.Allocs.start\nProfile.Allocs.stop","category":"page"},{"location":"stdlib/Profile/#Profile.Allocs.clear","page":"Profiling","title":"Profile.Allocs.clear","text":"Profile.Allocs.clear()\n\nClear all previously profiled allocation information from memory.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.Allocs.print","page":"Profiling","title":"Profile.Allocs.print","text":"Profile.Allocs.print([io::IO = stdout,] [data::AllocResults = fetch()]; kwargs...)\n\nPrints profiling results to io (by default, stdout). If you do not supply a data vector, the internal buffer of accumulated backtraces will be used.\n\nSee Profile.print for an explanation of the valid keyword arguments.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.Allocs.fetch","page":"Profiling","title":"Profile.Allocs.fetch","text":"Profile.Allocs.fetch()\n\nRetrieve the recorded allocations, and decode them into Julia objects which can be analyzed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.Allocs.start","page":"Profiling","title":"Profile.Allocs.start","text":"Profile.Allocs.start(sample_rate::Real)\n\nBegin recording allocations with the given sample rate A sample rate of 1.0 will record everything; 0.0 will record nothing.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Profile.Allocs.stop","page":"Profiling","title":"Profile.Allocs.stop","text":"Profile.Allocs.stop()\n\nStop recording allocations.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/#Heap-Snapshots","page":"Profiling","title":"Heap Snapshots","text":"","category":"section"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Profile.take_heap_snapshot","category":"page"},{"location":"stdlib/Profile/#Profile.take_heap_snapshot","page":"Profiling","title":"Profile.take_heap_snapshot","text":"Profile.take_heap_snapshot(filepath::String, all_one::Bool=false, streaming=false)\nProfile.take_heap_snapshot(all_one::Bool=false; dir::String, streaming=false)\n\nWrite a snapshot of the heap, in the JSON format expected by the Chrome Devtools Heap Snapshot viewer (.heapsnapshot extension) to a file ($pid_$timestamp.heapsnapshot) in the current directory by default (or tempdir if the current directory is unwritable), or in dir if given, or the given full file path, or IO stream.\n\nIf all_one is true, then report the size of every object as one so they can be easily counted. Otherwise, report the actual size.\n\nIf streaming is true, we will stream the snapshot data out into four files, using filepath as the prefix, to avoid having to hold the entire snapshot in memory. This option should be used for any setting where your memory is constrained. These files can then be reassembled by calling Profile.HeapSnapshot.assemble_snapshot(), which can be done offline.\n\nNOTE: We strongly recommend setting streaming=true for performance reasons. Reconstructing the snapshot from the parts requires holding the entire snapshot in memory, so if the snapshot is large, you can run out of memory while processing it. Streaming allows you to reconstruct the snapshot offline, after your workload is done running. If you do attempt to collect a snapshot with streaming=false (the default, for backwards-compatibility) and your process is killed, note that this will always save the parts in the same directory as your provided filepath, so you can still reconstruct the snapshot after the fact, via assemble_snapshot().\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The methods in Profile are not exported and need to be called e.g. as Profile.take_heap_snapshot().","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> Profile.take_heap_snapshot(\"snapshot.heapsnapshot\")","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Traces and records julia objects on the heap. This only records objects known to the Julia garbage collector. Memory allocated by external libraries not managed by the garbage collector will not show up in the snapshot.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"To avoid OOMing while recording the snapshot, we added a streaming option to stream out the heap snapshot into four files,","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> Profile.take_heap_snapshot(\"snapshot\"; streaming=true)","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"where \"snapshot\" is the filepath as the prefix for the generated files.","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"Once the snapshot files are generated, they could be assembled offline with the following command:","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> Profile.HeapSnapshot.assemble_snapshot(\"snapshot\", \"snapshot.heapsnapshot\")","category":"page"},{"location":"stdlib/Profile/","page":"Profiling","title":"Profiling","text":"The resulting heap snapshot file can be uploaded to chrome devtools to be viewed. For more information, see the chrome devtools docs.","category":"page"},{"location":"stdlib/UUIDs/","page":"UUIDs","title":"UUIDs","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/UUIDs/docs/src/index.md\"","category":"page"},{"location":"stdlib/UUIDs/#UUIDs","page":"UUIDs","title":"UUIDs","text":"","category":"section"},{"location":"stdlib/UUIDs/","page":"UUIDs","title":"UUIDs","text":"UUIDs.uuid1\nUUIDs.uuid4\nUUIDs.uuid5\nUUIDs.uuid_version","category":"page"},{"location":"stdlib/UUIDs/#UUIDs.uuid1","page":"UUIDs","title":"UUIDs.uuid1","text":"uuid1([rng::AbstractRNG]) -> UUID\n\nGenerates a version 1 (time-based) universally unique identifier (UUID), as specified by RFC 4122. Note that the Node ID is randomly generated (does not identify the host) according to section 4.5 of the RFC.\n\nThe default rng used by uuid1 is not Random.default_rng() and every invocation of uuid1() without an argument should be expected to return a unique identifier. Importantly, the outputs of uuid1 do not repeat even when Random.seed!(seed) is called. Currently (as of Julia 1.6), uuid1 uses Random.RandomDevice as the default rng. However, this is an implementation detail that may change in the future.\n\ncompat: Julia 1.6\nThe output of uuid1 does not depend on Random.default_rng() as of Julia 1.6.\n\nExamples\n\njulia> using Random\n\njulia> rng = MersenneTwister(1234);\n\njulia> uuid1(rng)\nUUID(\"cfc395e8-590f-11e8-1f13-43a2532b2fa8\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/UUIDs/#UUIDs.uuid4","page":"UUIDs","title":"UUIDs.uuid4","text":"uuid4([rng::AbstractRNG]) -> UUID\n\nGenerates a version 4 (random or pseudo-random) universally unique identifier (UUID), as specified by RFC 4122.\n\nThe default rng used by uuid4 is not Random.default_rng() and every invocation of uuid4() without an argument should be expected to return a unique identifier. Importantly, the outputs of uuid4 do not repeat even when Random.seed!(seed) is called. Currently (as of Julia 1.6), uuid4 uses Random.RandomDevice as the default rng. However, this is an implementation detail that may change in the future.\n\ncompat: Julia 1.6\nThe output of uuid4 does not depend on Random.default_rng() as of Julia 1.6.\n\nExamples\n\njulia> using Random\n\njulia> rng = Xoshiro(123);\n\njulia> uuid4(rng)\nUUID(\"856e446e-0c6a-472a-9638-f7b8557cd282\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/UUIDs/#UUIDs.uuid5","page":"UUIDs","title":"UUIDs.uuid5","text":"uuid5(ns::UUID, name::String) -> UUID\n\nGenerates a version 5 (namespace and domain-based) universally unique identifier (UUID), as specified by RFC 4122.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1.\n\nExamples\n\njulia> using Random\n\njulia> rng = Xoshiro(123);\n\njulia> u4 = uuid4(rng)\nUUID(\"856e446e-0c6a-472a-9638-f7b8557cd282\")\n\njulia> u5 = uuid5(u4, \"julia\")\nUUID(\"2df91e3f-da06-5362-a6fe-03772f2e14c9\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/UUIDs/#UUIDs.uuid_version","page":"UUIDs","title":"UUIDs.uuid_version","text":"uuid_version(u::UUID) -> Int\n\nInspects the given UUID and returns its version (see RFC 4122).\n\nExamples\n\njulia> uuid_version(uuid4())\n4\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Iteration-utilities","page":"Iteration utilities","title":"Iteration utilities","text":"","category":"section"},{"location":"base/iterators/","page":"Iteration utilities","title":"Iteration utilities","text":"Base.Iterators.Stateful\nBase.Iterators.zip\nBase.Iterators.enumerate\nBase.Iterators.rest\nBase.Iterators.countfrom\nBase.Iterators.take\nBase.Iterators.takewhile\nBase.Iterators.drop\nBase.Iterators.dropwhile\nBase.Iterators.cycle\nBase.Iterators.repeated\nBase.Iterators.product\nBase.Iterators.flatten\nBase.Iterators.flatmap\nBase.Iterators.partition\nBase.Iterators.map\nBase.Iterators.filter\nBase.Iterators.accumulate\nBase.Iterators.reverse\nBase.Iterators.only\nBase.Iterators.peel","category":"page"},{"location":"base/iterators/#Base.Iterators.Stateful","page":"Iteration utilities","title":"Base.Iterators.Stateful","text":"Stateful(itr)\n\nThere are several different ways to think about this iterator wrapper:\n\nIt provides a mutable wrapper around an iterator and its iteration state.\nIt turns an iterator-like abstraction into a Channel-like abstraction.\nIt's an iterator that mutates to become its own rest iterator whenever an item is produced.\n\nStateful provides the regular iterator interface. Like other mutable iterators (e.g. Base.Channel), if iteration is stopped early (e.g. by a break in a for loop), iteration can be resumed from the same spot by continuing to iterate over the same iterator object (in contrast, an immutable iterator would restart from the beginning).\n\nExamples\n\njulia> a = Iterators.Stateful(\"abcdef\");\n\njulia> isempty(a)\nfalse\n\njulia> popfirst!(a)\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> collect(Iterators.take(a, 3))\n3-element Vector{Char}:\n 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)\n 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)\n 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)\n\njulia> collect(a)\n2-element Vector{Char}:\n 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)\n 'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)\n\njulia> Iterators.reset!(a); popfirst!(a)\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> Iterators.reset!(a, \"hello\"); popfirst!(a)\n'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)\n\njulia> a = Iterators.Stateful([1,1,1,2,3,4]);\n\njulia> for x in a; x == 1 || break; end\n\njulia> peek(a)\n3\n\njulia> sum(a) # Sum the remaining elements\n7\n\n\n\n\n\n","category":"type"},{"location":"base/iterators/#Base.Iterators.zip","page":"Iteration utilities","title":"Base.Iterators.zip","text":"zip(iters...)\n\nRun multiple iterators at the same time, until any of them is exhausted. The value type of the zip iterator is a tuple of values of its subiterators.\n\nnote: Note\nzip orders the calls to its subiterators in such a way that stateful iterators will not advance when another iterator finishes in the current iteration.\n\nnote: Note\nzip() with no arguments yields an infinite iterator of empty tuples.\n\nSee also: enumerate, Base.splat.\n\nExamples\n\njulia> a = 1:5\n1:5\n\njulia> b = [\"e\",\"d\",\"b\",\"c\",\"a\"]\n5-element Vector{String}:\n \"e\"\n \"d\"\n \"b\"\n \"c\"\n \"a\"\n\njulia> c = zip(a,b)\nzip(1:5, [\"e\", \"d\", \"b\", \"c\", \"a\"])\n\njulia> length(c)\n5\n\njulia> first(c)\n(1, \"e\")\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.enumerate","page":"Iteration utilities","title":"Base.Iterators.enumerate","text":"enumerate(iter)\n\nAn iterator that yields (i, x) where i is a counter starting at 1, and x is the ith value from the given iterator. It's useful when you need not only the values x over which you are iterating, but also the number of iterations so far.\n\nNote that i may not be valid for indexing iter, or may index a different element. This will happen if iter has indices that do not start at 1, and may happen for strings, dictionaries, etc. See the pairs(IndexLinear(), iter) method if you want to ensure that i is an index.\n\nExamples\n\njulia> a = [\"a\", \"b\", \"c\"];\n\njulia> for (index, value) in enumerate(a)\n println(\"$index $value\")\n end\n1 a\n2 b\n3 c\n\njulia> str = \"naïve\";\n\njulia> for (i, val) in enumerate(str)\n print(\"i = \", i, \", val = \", val, \", \")\n try @show(str[i]) catch e println(e) end\n end\ni = 1, val = n, str[i] = 'n'\ni = 2, val = a, str[i] = 'a'\ni = 3, val = ï, str[i] = 'ï'\ni = 4, val = v, StringIndexError(\"naïve\", 4)\ni = 5, val = e, str[i] = 'v'\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.rest","page":"Iteration utilities","title":"Base.Iterators.rest","text":"rest(iter, state)\n\nAn iterator that yields the same elements as iter, but starting at the given state.\n\nSee also: Iterators.drop, Iterators.peel, Base.rest.\n\nExamples\n\njulia> collect(Iterators.rest([1,2,3,4], 2))\n3-element Vector{Int64}:\n 2\n 3\n 4\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.countfrom","page":"Iteration utilities","title":"Base.Iterators.countfrom","text":"countfrom(start=1, step=1)\n\nAn iterator that counts forever, starting at start and incrementing by step.\n\nExamples\n\njulia> for v in Iterators.countfrom(5, 2)\n v > 10 && break\n println(v)\n end\n5\n7\n9\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.take","page":"Iteration utilities","title":"Base.Iterators.take","text":"take(iter, n)\n\nAn iterator that generates at most the first n elements of iter.\n\nSee also: drop, peel, first, Base.take!.\n\nExamples\n\njulia> a = 1:2:11\n1:2:11\n\njulia> collect(a)\n6-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n 11\n\njulia> collect(Iterators.take(a,3))\n3-element Vector{Int64}:\n 1\n 3\n 5\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.takewhile","page":"Iteration utilities","title":"Base.Iterators.takewhile","text":"takewhile(pred, iter)\n\nAn iterator that generates element from iter as long as predicate pred is true, afterwards, drops every element.\n\ncompat: Julia 1.4\nThis function requires at least Julia 1.4.\n\nExamples\n\njulia> s = collect(1:5)\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n\njulia> collect(Iterators.takewhile(<(3),s))\n2-element Vector{Int64}:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.drop","page":"Iteration utilities","title":"Base.Iterators.drop","text":"drop(iter, n)\n\nAn iterator that generates all but the first n elements of iter.\n\nExamples\n\njulia> a = 1:2:11\n1:2:11\n\njulia> collect(a)\n6-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n 11\n\njulia> collect(Iterators.drop(a,4))\n2-element Vector{Int64}:\n 9\n 11\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.dropwhile","page":"Iteration utilities","title":"Base.Iterators.dropwhile","text":"dropwhile(pred, iter)\n\nAn iterator that drops element from iter as long as predicate pred is true, afterwards, returns every element.\n\ncompat: Julia 1.4\nThis function requires at least Julia 1.4.\n\nExamples\n\njulia> s = collect(1:5)\n5-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n\njulia> collect(Iterators.dropwhile(<(3),s))\n3-element Vector{Int64}:\n 3\n 4\n 5\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.cycle","page":"Iteration utilities","title":"Base.Iterators.cycle","text":"cycle(iter[, n::Int])\n\nAn iterator that cycles through iter forever. If n is specified, then it cycles through iter that many times. When iter is empty, so are cycle(iter) and cycle(iter, n).\n\nIterators.cycle(iter, n) is the lazy equivalent of Base.repeat(vector, n), while Iterators.repeated(iter, n) is the lazy Base.fill(item, n).\n\ncompat: Julia 1.11\nThe method cycle(iter, n) was added in Julia 1.11.\n\nExamples\n\njulia> for (i, v) in enumerate(Iterators.cycle(\"hello\"))\n print(v)\n i > 10 && break\n end\nhellohelloh\n\njulia> foreach(print, Iterators.cycle(['j', 'u', 'l', 'i', 'a'], 3))\njuliajuliajulia\n\njulia> repeat([1,2,3], 4) == collect(Iterators.cycle([1,2,3], 4))\ntrue\n\njulia> fill([1,2,3], 4) == collect(Iterators.repeated([1,2,3], 4))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.repeated","page":"Iteration utilities","title":"Base.Iterators.repeated","text":"repeated(x[, n::Int])\n\nAn iterator that generates the value x forever. If n is specified, generates x that many times (equivalent to take(repeated(x), n)).\n\nSee also fill, and compare Iterators.cycle.\n\nExamples\n\njulia> a = Iterators.repeated([1 2], 4);\n\njulia> collect(a)\n4-element Vector{Matrix{Int64}}:\n [1 2]\n [1 2]\n [1 2]\n [1 2]\n\njulia> ans == fill([1 2], 4)\ntrue\n\njulia> Iterators.cycle([1 2], 4) |> collect |> println\n[1, 2, 1, 2, 1, 2, 1, 2]\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.product","page":"Iteration utilities","title":"Base.Iterators.product","text":"product(iters...)\n\nReturn an iterator over the product of several iterators. Each generated element is a tuple whose ith element comes from the ith argument iterator. The first iterator changes the fastest.\n\nSee also: zip, Iterators.flatten.\n\nExamples\n\njulia> collect(Iterators.product(1:2, 3:5))\n2×3 Matrix{Tuple{Int64, Int64}}:\n (1, 3) (1, 4) (1, 5)\n (2, 3) (2, 4) (2, 5)\n\njulia> ans == [(x,y) for x in 1:2, y in 3:5] # collects a generator involving Iterators.product\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.flatten","page":"Iteration utilities","title":"Base.Iterators.flatten","text":"flatten(iter)\n\nGiven an iterator that yields iterators, return an iterator that yields the elements of those iterators. Put differently, the elements of the argument iterator are concatenated.\n\nExamples\n\njulia> collect(Iterators.flatten((1:2, 8:9)))\n4-element Vector{Int64}:\n 1\n 2\n 8\n 9\n\njulia> [(x,y) for x in 0:1 for y in 'a':'c'] # collects generators involving Iterators.flatten\n6-element Vector{Tuple{Int64, Char}}:\n (0, 'a')\n (0, 'b')\n (0, 'c')\n (1, 'a')\n (1, 'b')\n (1, 'c')\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.flatmap","page":"Iteration utilities","title":"Base.Iterators.flatmap","text":"Iterators.flatmap(f, iterators...)\n\nEquivalent to flatten(map(f, iterators...)).\n\nSee also Iterators.flatten, Iterators.map.\n\ncompat: Julia 1.9\nThis function was added in Julia 1.9.\n\nExamples\n\njulia> Iterators.flatmap(n -> -n:2:n, 1:3) |> collect\n9-element Vector{Int64}:\n -1\n 1\n -2\n 0\n 2\n -3\n -1\n 1\n 3\n\njulia> stack(n -> -n:2:n, 1:3)\nERROR: DimensionMismatch: stack expects uniform slices, got axes(x) == (1:3,) while first had (1:2,)\n[...]\n\njulia> Iterators.flatmap(n -> (-n, 10n), 1:2) |> collect\n4-element Vector{Int64}:\n -1\n 10\n -2\n 20\n\njulia> ans == vec(stack(n -> (-n, 10n), 1:2))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.partition","page":"Iteration utilities","title":"Base.Iterators.partition","text":"partition(collection, n)\n\nIterate over a collection n elements at a time.\n\nExamples\n\njulia> collect(Iterators.partition([1,2,3,4,5], 2))\n3-element Vector{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}:\n [1, 2]\n [3, 4]\n [5]\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.map","page":"Iteration utilities","title":"Base.Iterators.map","text":"Iterators.map(f, iterators...)\n\nCreate a lazy mapping. This is another syntax for writing (f(args...) for args in zip(iterators...)).\n\ncompat: Julia 1.6\nThis function requires at least Julia 1.6.\n\nExamples\n\njulia> collect(Iterators.map(x -> x^2, 1:3))\n3-element Vector{Int64}:\n 1\n 4\n 9\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.filter","page":"Iteration utilities","title":"Base.Iterators.filter","text":"Iterators.filter(flt, itr)\n\nGiven a predicate function flt and an iterable object itr, return an iterable object which upon iteration yields the elements x of itr that satisfy flt(x). The order of the original iterator is preserved.\n\nThis function is lazy; that is, it is guaranteed to return in Θ(1) time and use Θ(1) additional space, and flt will not be called by an invocation of filter. Calls to flt will be made when iterating over the returned iterable object. These calls are not cached and repeated calls will be made when reiterating.\n\nwarning: Warning\nSubsequent lazy transformations on the iterator returned from filter, such as those performed by Iterators.reverse or cycle, will also delay calls to flt until collecting or iterating over the returned iterable object. If the filter predicate is nondeterministic or its return values depend on the order of iteration over the elements of itr, composition with lazy transformations may result in surprising behavior. If this is undesirable, either ensure that flt is a pure function or collect intermediate filter iterators before further transformations.\n\nSee Base.filter for an eager implementation of filtering for arrays.\n\nExamples\n\njulia> f = Iterators.filter(isodd, [1, 2, 3, 4, 5])\nBase.Iterators.Filter{typeof(isodd), Vector{Int64}}(isodd, [1, 2, 3, 4, 5])\n\njulia> foreach(println, f)\n1\n3\n5\n\njulia> [x for x in [1, 2, 3, 4, 5] if isodd(x)] # collects a generator over Iterators.filter\n3-element Vector{Int64}:\n 1\n 3\n 5\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.accumulate","page":"Iteration utilities","title":"Base.Iterators.accumulate","text":"Iterators.accumulate(f, itr; [init])\n\nGiven a 2-argument function f and an iterator itr, return a new iterator that successively applies f to the previous value and the next element of itr.\n\nThis is effectively a lazy version of Base.accumulate.\n\ncompat: Julia 1.5\nKeyword argument init is added in Julia 1.5.\n\nExamples\n\njulia> a = Iterators.accumulate(+, [1,2,3,4]);\n\njulia> foreach(println, a)\n1\n3\n6\n10\n\njulia> b = Iterators.accumulate(/, (2, 5, 2, 5); init = 100);\n\njulia> collect(b)\n4-element Vector{Float64}:\n 50.0\n 10.0\n 5.0\n 1.0\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.reverse","page":"Iteration utilities","title":"Base.Iterators.reverse","text":"Iterators.reverse(itr)\n\nGiven an iterator itr, then reverse(itr) is an iterator over the same collection but in the reverse order. This iterator is \"lazy\" in that it does not make a copy of the collection in order to reverse it; see Base.reverse for an eager implementation.\n\n(By default, this returns an Iterators.Reverse object wrapping itr, which is iterable if the corresponding iterate methods are defined, but some itr types may implement more specialized Iterators.reverse behaviors.)\n\nNot all iterator types T support reverse-order iteration. If T doesn't, then iterating over Iterators.reverse(itr::T) will throw a MethodError because of the missing iterate methods for Iterators.Reverse{T}. (To implement these methods, the original iterator itr::T can be obtained from an r::Iterators.Reverse{T} object by r.itr; more generally, one can use Iterators.reverse(r).)\n\nExamples\n\njulia> foreach(println, Iterators.reverse(1:5))\n5\n4\n3\n2\n1\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.only","page":"Iteration utilities","title":"Base.Iterators.only","text":"only(x)\n\nReturn the one and only element of collection x, or throw an ArgumentError if the collection has zero or multiple elements.\n\nSee also first, last.\n\ncompat: Julia 1.4\nThis method requires at least Julia 1.4.\n\nExamples\n\njulia> only([\"a\"])\n\"a\"\n\njulia> only(\"a\")\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> only(())\nERROR: ArgumentError: Tuple contains 0 elements, must contain exactly 1 element\nStacktrace:\n[...]\n\njulia> only(('a', 'b'))\nERROR: ArgumentError: Tuple contains 2 elements, must contain exactly 1 element\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/iterators/#Base.Iterators.peel","page":"Iteration utilities","title":"Base.Iterators.peel","text":"peel(iter)\n\nReturns the first element and an iterator over the remaining elements.\n\nIf the iterator is empty return nothing (like iterate).\n\ncompat: Julia 1.7\nPrior versions throw a BoundsError if the iterator is empty.\n\nSee also: Iterators.drop, Iterators.take.\n\nExamples\n\njulia> (a, rest) = Iterators.peel(\"abc\");\n\njulia> a\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> collect(rest)\n2-element Vector{Char}:\n 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)\n 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"function"},{"location":"devdocs/isbitsunionarrays/#isbits-Union-Optimizations","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"","category":"section"},{"location":"devdocs/isbitsunionarrays/","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"In Julia, the Array type holds both \"bits\" values as well as heap-allocated \"boxed\" values. The distinction is whether the value itself is stored inline (in the direct allocated memory of the array), or if the memory of the array is simply a collection of pointers to objects allocated elsewhere. In terms of performance, accessing values inline is clearly an advantage over having to follow a pointer to the actual value. The definition of \"isbits\" generally means any Julia type with a fixed, determinate size, meaning no \"pointer\" fields, see ?isbitstype.","category":"page"},{"location":"devdocs/isbitsunionarrays/","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"Julia also supports Union types, quite literally the union of a set of types. Custom Union type definitions can be extremely handy for applications wishing to \"cut across\" the nominal type system (i.e. explicit subtype relationships) and define methods or functionality on these, otherwise unrelated, set of types. A compiler challenge, however, is in determining how to treat these Union types. The naive approach (and indeed, what Julia itself did pre-0.7), is to simply make a \"box\" and then a pointer in the box to the actual value, similar to the previously mentioned \"boxed\" values. This is unfortunate, however, because of the number of small, primitive \"bits\" types (think UInt8, Int32, Float64, etc.) that would easily fit themselves inline in this \"box\" without needing any indirection for value access. There are two main ways Julia can take advantage of this optimization as of 0.7: isbits Union fields in types, and isbits Union Arrays.","category":"page"},{"location":"devdocs/isbitsunionarrays/#isbits-Union-Structs","page":"isbits Union Optimizations","title":"isbits Union Structs","text":"","category":"section"},{"location":"devdocs/isbitsunionarrays/","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"Julia now includes an optimization wherein \"isbits Union\" fields in types (mutable struct, struct, etc.) will be stored inline. This is accomplished by determining the \"inline size\" of the Union type (e.g. Union{UInt8, Int16} will have a size of two bytes, which represents the size needed of the largest Union type Int16), and in addition, allocating an extra \"type tag byte\" (UInt8), whose value signals the type of the actual value stored inline of the \"Union bytes\". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of 0x02 for a field with type Union{Nothing, UInt8, Int16} would indicate that an Int16 value is stored in the 16 bits of the field in the structure's memory; a 0x01 value would indicate that a UInt8 value was stored in the first 8 bits of the 16 bits of the field's memory. Lastly, a value of 0x00 signals that the nothing value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory.","category":"page"},{"location":"devdocs/isbitsunionarrays/#isbits-Union-Memory","page":"isbits Union Optimizations","title":"isbits Union Memory","text":"","category":"section"},{"location":"devdocs/isbitsunionarrays/","page":"isbits Union Optimizations","title":"isbits Union Optimizations","text":"Julia can now also store \"isbits Union\" values inline in a Memory, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra \"type tag memory\" of bytes, one byte per element, alongside the bytes of the actual data. This type tag memory serves the same function as the type field case: its value signals the type of the actual stored Union value. The \"type tag memory\" directly follows the regular data space. So the formula to access an isbits Union Array's type tag bytes is a->data + a->length * a->elsize.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"io = IOBuffer()\nrelease = isempty(VERSION.prerelease)\nv = \"$(VERSION.major).$(VERSION.minor)\"\n!release && (v = v*\"-$(first(VERSION.prerelease))\")\nprint(io, \"\"\"\n # Julia $(v) Documentation\n\n Welcome to the documentation for Julia $(v).\n\n \"\"\")\nif !release\n print(io,\"\"\"\n !!! warning \"Work in progress!\"\n This documentation is for an unreleased, in-development, version of Julia.\n \"\"\")\nend\nimport Markdown\nMarkdown.parse(String(take!(io)))","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Please read the release notes to see what has changed since the last release.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"release = isempty(VERSION.prerelease)\nfile = release ? \"julia-$(VERSION).pdf\" :\n \"julia-$(VERSION.major).$(VERSION.minor).$(VERSION.patch)-$(first(VERSION.prerelease)).pdf\"\nurl = \"https://raw.githubusercontent.com/JuliaLang/docs.julialang.org/assets/$(file)\"\nimport Markdown\nMarkdown.parse(\"\"\"\n!!! note\n The documentation is also available in PDF format: [$file]($url).\n\"\"\")","category":"page"},{"location":"#man-important-links","page":"Julia Documentation","title":"Important Links","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Below is a non-exhaustive list of links that will be useful as you learn and use the Julia programming language.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Julia Homepage\nDownload Julia\nDiscussion forum\nJulia YouTube\nFind Julia Packages\nLearning Resources\nRead and write blogs on Julia","category":"page"},{"location":"#man-introduction","page":"Julia Documentation","title":"Introduction","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Scientific computing has traditionally required the highest performance, yet domain experts have largely moved to slower dynamic languages for daily work. We believe there are many good reasons to prefer dynamic languages for these applications, and we do not expect their use to diminish. Fortunately, modern language design and compiler techniques make it possible to mostly eliminate the performance trade-off and provide a single environment productive enough for prototyping and efficient enough for deploying performance-intensive applications. The Julia programming language fills this role: it is a flexible dynamic language, appropriate for scientific and numerical computing, with performance comparable to traditional statically-typed languages.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Because Julia's compiler is different from the interpreters used for languages like Python or R, you may find that Julia's performance is unintuitive at first. If you find that something is slow, we highly recommend reading through the Performance Tips section before trying anything else. Once you understand how Julia works, it is easy to write code that is nearly as fast as C.","category":"page"},{"location":"#man-julia-compared-other-languages","page":"Julia Documentation","title":"Julia Compared to Other Languages","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Julia features optional typing, multiple dispatch, and good performance, achieved using type inference and just-in-time (JIT) compilation (and optional ahead-of-time compilation), implemented using LLVM. It is multi-paradigm, combining features of imperative, functional, and object-oriented programming. Julia provides ease and expressiveness for high-level numerical computing, in the same way as languages such as R, MATLAB, and Python, but also supports general programming. To achieve this, Julia builds upon the lineage of mathematical programming languages, but also borrows much from popular dynamic languages, including Lisp, Perl, Python, Lua, and Ruby.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"The most significant departures of Julia from typical dynamic languages are:","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"The core language imposes very little; Julia Base and the standard library are written in Julia itself, including primitive operations like integer arithmetic\nA rich language of types for constructing and describing objects, that can also optionally be used to make type declarations\nThe ability to define function behavior across many combinations of argument types via multiple dispatch\nAutomatic generation of efficient, specialized code for different argument types\nGood performance, approaching that of statically-compiled languages like C","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Although one sometimes speaks of dynamic languages as being \"typeless\", they are definitely not. Every object, whether primitive or user-defined, has a type. The lack of type declarations in most dynamic languages, however, means that one cannot instruct the compiler about the types of values, and often cannot explicitly talk about types at all. In static languages, on the other hand, while one can – and usually must – annotate types for the compiler, types exist only at compile time and cannot be manipulated or expressed at run time. In Julia, types are themselves run-time objects, and can also be used to convey information to the compiler.","category":"page"},{"location":"#man-what-makes-julia","page":"Julia Documentation","title":"What Makes Julia, Julia?","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"While the casual programmer need not explicitly use types or multiple dispatch, they are the core unifying features of Julia: functions are defined on different combinations of argument types, and applied by dispatching to the most specific matching definition. This model is a good fit for mathematical programming, where it is unnatural for the first argument to \"own\" an operation as in traditional object-oriented dispatch. Operators are just functions with special notation – to extend addition to new user-defined data types, you define new methods for the + function. Existing code then seamlessly applies to the new data types.","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Partly because of run-time type inference (augmented by optional type annotations), and partly because of a strong focus on performance from the inception of the project, Julia's computational efficiency exceeds that of other dynamic languages, and even rivals that of statically-compiled languages. For large scale numerical problems, speed always has been, continues to be, and probably always will be crucial: the amount of data being processed has easily kept pace with Moore's Law over the past decades.","category":"page"},{"location":"#man-advantages-of-julia","page":"Julia Documentation","title":"Advantages of Julia","text":"","category":"section"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Julia aims to create an unprecedented combination of ease-of-use, power, and efficiency in a single language. In addition to the above, some advantages of Julia over comparable systems include:","category":"page"},{"location":"","page":"Julia Documentation","title":"Julia Documentation","text":"Free and open source (MIT licensed)\nUser-defined types are as fast and compact as built-ins\nNo need to vectorize code for performance; devectorized code is fast\nDesigned for parallelism and distributed computation\nLightweight \"green\" threading (coroutines)\nUnobtrusive yet powerful type system\nElegant and extensible conversions and promotions for numeric and other types\nEfficient support for Unicode, including but not limited to UTF-8\nCall C functions directly (no wrappers or special APIs needed)\nPowerful shell-like capabilities for managing other processes\nLisp-like macros and other metaprogramming facilities","category":"page"},{"location":"manual/environment-variables/#Environment-Variables","page":"Environment Variables","title":"Environment Variables","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Julia can be configured with a number of environment variables, set either in the usual way for each operating system, or in a portable way from within Julia. Supposing that you want to set the environment variable JULIA_EDITOR to vim, you can type ENV[\"JULIA_EDITOR\"] = \"vim\" (for instance, in the REPL) to make this change on a case by case basis, or add the same to the user configuration file ~/.julia/config/startup.jl in the user's home directory to have a permanent effect. The current value of the same environment variable can be determined by evaluating ENV[\"JULIA_EDITOR\"].","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The environment variables that Julia uses generally start with JULIA. If InteractiveUtils.versioninfo is called with the keyword verbose=true, then the output will list any defined environment variables relevant for Julia, including those which include JULIA in their names.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nIt is recommended to avoid changing environment variables during runtime, such as within a ~/.julia/config/startup.jl.One reason is that some julia language variables, such as JULIA_NUM_THREADS and JULIA_PROJECT, need to be set before Julia starts.Similarly, __init__() functions of user modules in the sysimage (via PackageCompiler) are run before startup.jl, so setting environment variables in a startup.jl may be too late for user code.Further, changing environment variables during runtime can introduce data races into otherwise benign code.In Bash, environment variables can either be set manually by running, e.g., export JULIA_NUM_THREADS=4 before starting Julia, or by adding the same command to ~/.bashrc or ~/.bash_profile to set the variable each time Bash is started.","category":"page"},{"location":"manual/environment-variables/#File-locations","page":"Environment Variables","title":"File locations","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_BINDIR","page":"Environment Variables","title":"JULIA_BINDIR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The absolute path of the directory containing the Julia executable, which sets the global variable Sys.BINDIR. If $JULIA_BINDIR is not set, then Julia determines the value Sys.BINDIR at run-time.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The executable itself is one of","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$JULIA_BINDIR/julia\n$JULIA_BINDIR/julia-debug","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"by default.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The global variable Base.DATAROOTDIR determines a relative path from Sys.BINDIR to the data directory associated with Julia. Then the path","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$JULIA_BINDIR/$DATAROOTDIR/julia/base","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"determines the directory in which Julia initially searches for source files (via Base.find_source_file()).","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Likewise, the global variable Base.SYSCONFDIR determines a relative path to the configuration file directory. Then Julia searches for a startup.jl file at","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$JULIA_BINDIR/$SYSCONFDIR/julia/startup.jl\n$JULIA_BINDIR/../etc/julia/startup.jl","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"by default (via Base.load_julia_startup()).","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"For example, a Linux installation with a Julia executable located at /bin/julia, a DATAROOTDIR of ../share, and a SYSCONFDIR of ../etc will have JULIA_BINDIR set to /bin, a source-file search path of","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"/share/julia/base","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"and a global configuration search path of","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"/etc/julia/startup.jl","category":"page"},{"location":"manual/environment-variables/#JULIA_PROJECT","page":"Environment Variables","title":"JULIA_PROJECT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"A directory path that indicates which project should be the initial active project. Setting this environment variable has the same effect as specifying the --project start-up option, but --project has higher precedence. If the variable is set to @. (note the trailing dot) then Julia tries to find a project directory that contains Project.toml or JuliaProject.toml file from the current directory and its parents. See also the chapter on Code Loading.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nJULIA_PROJECT must be defined before starting julia; defining it in startup.jl is too late in the startup process.","category":"page"},{"location":"manual/environment-variables/#JULIA_LOAD_PATH","page":"Environment Variables","title":"JULIA_LOAD_PATH","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The JULIA_LOAD_PATH environment variable is used to populate the global Julia LOAD_PATH variable, which determines which packages can be loaded via import and using (see Code Loading).","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Unlike the shell PATH variable, empty entries in JULIA_LOAD_PATH are expanded to the default value of LOAD_PATH, [\"@\", \"@v#.#\", \"@stdlib\"] when populating LOAD_PATH. This allows easy appending, prepending, etc. of the load path value in shell scripts regardless of whether JULIA_LOAD_PATH is already set or not. For example, to prepend the directory /foo/bar to LOAD_PATH just do","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"export JULIA_LOAD_PATH=\"/foo/bar:$JULIA_LOAD_PATH\"","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If the JULIA_LOAD_PATH environment variable is already set, its old value will be prepended with /foo/bar. On the other hand, if JULIA_LOAD_PATH is not set, then it will be set to /foo/bar: which will expand to a LOAD_PATH value of [\"/foo/bar\", \"@\", \"@v#.#\", \"@stdlib\"]. If JULIA_LOAD_PATH is set to the empty string, it expands to an empty LOAD_PATH array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty load path via the environment variable. If you want the default load path, either unset the environment variable or if it must have a value, set it to the string :.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nOn Windows, path elements are separated by the ; character, as is the case with most path lists on Windows. Replace : with ; in the above paragraph.","category":"page"},{"location":"manual/environment-variables/#JULIA_DEPOT_PATH","page":"Environment Variables","title":"JULIA_DEPOT_PATH","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The JULIA_DEPOT_PATH environment variable is used to populate the global Julia DEPOT_PATH variable, which controls where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, configuration files, and the default location of the REPL's history file.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Unlike the shell PATH variable but similar to JULIA_LOAD_PATH, empty entries in JULIA_DEPOT_PATH are expanded to the default value of DEPOT_PATH, excluding the user depot. This allows easy overriding of the user depot, while still retaining access to resources that are bundled with Julia, like cache files, artifacts, etc. For example, to switch the user depot to /foo/bar just do","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"export JULIA_DEPOT_PATH=\"/foo/bar:\"","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"All package operations, like cloning registrise or installing packages, will now write to /foo/bar, but since the empty entry is expanded to the default system depot, any bundled resources will still be available. If you really only want to use the depot at /foo/bar, and not load any bundled resources, simply set the environment variable to /foo/bar without the trailing colon.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"There are two exceptions to the above rule. First, if JULIA_DEPOT_PATH is set to the empty string, it expands to an empty DEPOT_PATH array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty depot path via the environment variable.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Second, if no user depot is specified in JULIA_DEPOT_PATH, then the empty entry is expanded to the default depot including the user depot. This makes it possible to use the default depot, as if the environment variable was unset, by setting it to the string :.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nOn Windows, path elements are separated by the ; character, as is the case with most path lists on Windows. Replace : with ; in the above paragraph.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nJULIA_DEPOT_PATH must be defined before starting julia; defining it in startup.jl is too late in the startup process; at that point you can instead directly modify the DEPOT_PATH array, which is populated from the environment variable.","category":"page"},{"location":"manual/environment-variables/#JULIA_HISTORY","page":"Environment Variables","title":"JULIA_HISTORY","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The absolute path REPL.find_hist_file() of the REPL's history file. If $JULIA_HISTORY is not set, then REPL.find_hist_file() defaults to","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$(DEPOT_PATH[1])/logs/repl_history.jl","category":"page"},{"location":"manual/environment-variables/#JULIA_MAX_NUM_PRECOMPILE_FILES","page":"Environment Variables","title":"JULIA_MAX_NUM_PRECOMPILE_FILES","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Sets the maximum number of different instances of a single package that are to be stored in the precompile cache (default = 10).","category":"page"},{"location":"manual/environment-variables/#JULIA_VERBOSE_LINKING","page":"Environment Variables","title":"JULIA_VERBOSE_LINKING","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, linker commands will be displayed during precompilation.","category":"page"},{"location":"manual/environment-variables/#Pkg.jl","page":"Environment Variables","title":"Pkg.jl","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_CI","page":"Environment Variables","title":"JULIA_CI","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, this indicates to the package server that any package operations are part of a continuous integration (CI) system for the purposes of gathering package usage statistics.","category":"page"},{"location":"manual/environment-variables/#JULIA_NUM_PRECOMPILE_TASKS","page":"Environment Variables","title":"JULIA_NUM_PRECOMPILE_TASKS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The number of parallel tasks to use when precompiling packages. See Pkg.precompile.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_DEVDIR","page":"Environment Variables","title":"JULIA_PKG_DEVDIR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The default directory used by Pkg.develop for downloading packages.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_IGNORE_HASHES","page":"Environment Variables","title":"JULIA_PKG_IGNORE_HASHES","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to 1, this will ignore incorrect hashes in artifacts. This should be used carefully, as it disables verification of downloads, but can resolve issues when moving files across different types of file systems. See Pkg.jl issue #2317 for more details.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.6\nThis is only supported in Julia 1.6 and above.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_OFFLINE","page":"Environment Variables","title":"JULIA_PKG_OFFLINE","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, this will enable offline mode: see Pkg.offline.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.5\nPkg's offline mode requires Julia 1.5 or later.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_PRECOMPILE_AUTO","page":"Environment Variables","title":"JULIA_PKG_PRECOMPILE_AUTO","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to 0, this will disable automatic precompilation by package actions which change the manifest. See Pkg.precompile.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_SERVER","page":"Environment Variables","title":"JULIA_PKG_SERVER","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Specifies the URL of the package registry to use. By default, Pkg uses https://pkg.julialang.org to fetch Julia packages. In addition, you can disable the use of the PkgServer protocol, and instead access the packages directly from their hosts (GitHub, GitLab, etc.) by setting: export JULIA_PKG_SERVER=\"\"","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_SERVER_REGISTRY_PREFERENCE","page":"Environment Variables","title":"JULIA_PKG_SERVER_REGISTRY_PREFERENCE","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Specifies the preferred registry flavor. Currently supported values are conservative (the default), which will only publish resources that have been processed by the storage server (and thereby have a higher probability of being available from the PkgServers), whereas eager will publish registries whose resources have not necessarily been processed by the storage servers. Users behind restrictive firewalls that do not allow downloading from arbitrary servers should not use the eager flavor.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.7\nThis only affects Julia 1.7 and above.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_UNPACK_REGISTRY","page":"Environment Variables","title":"JULIA_PKG_UNPACK_REGISTRY","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, this will unpack the registry instead of storing it as a compressed tarball.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.7\nThis only affects Julia 1.7 and above. Earlier versions will always unpack the registry.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_USE_CLI_GIT","page":"Environment Variables","title":"JULIA_PKG_USE_CLI_GIT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to true, Pkg operations which use the git protocol will use an external git executable instead of the default libgit2 library.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.7\nUse of the git executable is only supported on Julia 1.7 and above.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKGRESOLVE_ACCURACY","page":"Environment Variables","title":"JULIA_PKGRESOLVE_ACCURACY","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The accuracy of the package resolver. This should be a positive integer, the default is 1.","category":"page"},{"location":"manual/environment-variables/#JULIA_PKG_PRESERVE_TIERED_INSTALLED","page":"Environment Variables","title":"JULIA_PKG_PRESERVE_TIERED_INSTALLED","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Change the default package installation strategy to Pkg.PRESERVE_TIERED_INSTALLED to let the package manager try to install versions of packages while keeping as many versions of packages already installed as possible.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.9\nThis only affects Julia 1.9 and above.","category":"page"},{"location":"manual/environment-variables/#Network-transport","page":"Environment Variables","title":"Network transport","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_NO_VERIFY_HOSTS","page":"Environment Variables","title":"JULIA_NO_VERIFY_HOSTS","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_SSL_NO_VERIFY_HOSTS","page":"Environment Variables","title":"JULIA_SSL_NO_VERIFY_HOSTS","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_SSH_NO_VERIFY_HOSTS","page":"Environment Variables","title":"JULIA_SSH_NO_VERIFY_HOSTS","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_ALWAYS_VERIFY_HOSTS","page":"Environment Variables","title":"JULIA_ALWAYS_VERIFY_HOSTS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Specify hosts whose identity should or should not be verified for specific transport layers. See NetworkOptions.verify_host","category":"page"},{"location":"manual/environment-variables/#JULIA_SSL_CA_ROOTS_PATH","page":"Environment Variables","title":"JULIA_SSL_CA_ROOTS_PATH","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Specify the file or directory containing the certificate authority roots. See NetworkOptions.ca_roots","category":"page"},{"location":"manual/environment-variables/#External-applications","page":"Environment Variables","title":"External applications","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_SHELL","page":"Environment Variables","title":"JULIA_SHELL","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The absolute path of the shell with which Julia should execute external commands (via Base.repl_cmd()). Defaults to the environment variable $SHELL, and falls back to /bin/sh if $SHELL is unset.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nOn Windows, this environment variable is ignored, and external commands are executed directly.","category":"page"},{"location":"manual/environment-variables/#JULIA_EDITOR","page":"Environment Variables","title":"JULIA_EDITOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The editor returned by InteractiveUtils.editor() and used in, e.g., InteractiveUtils.edit, referring to the command of the preferred editor, for instance vim.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"$JULIA_EDITOR takes precedence over $VISUAL, which in turn takes precedence over $EDITOR. If none of these environment variables is set, then the editor is taken to be open on Windows and OS X, or /etc/alternatives/editor if it exists, or emacs otherwise.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"To use Visual Studio Code on Windows, set $JULIA_EDITOR to code.cmd.","category":"page"},{"location":"manual/environment-variables/#Parallelization","page":"Environment Variables","title":"Parallelization","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_CPU_THREADS","page":"Environment Variables","title":"JULIA_CPU_THREADS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Overrides the global variable Base.Sys.CPU_THREADS, the number of logical CPU cores available.","category":"page"},{"location":"manual/environment-variables/#JULIA_WORKER_TIMEOUT","page":"Environment Variables","title":"JULIA_WORKER_TIMEOUT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"A Float64 that sets the value of Distributed.worker_timeout() (default: 60.0). This function gives the number of seconds a worker process will wait for a master process to establish a connection before dying.","category":"page"},{"location":"manual/environment-variables/#JULIA_NUM_THREADS","page":"Environment Variables","title":"JULIA_NUM_THREADS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"An unsigned 64-bit integer (uint64_t) that sets the maximum number of threads available to Julia. If $JULIA_NUM_THREADS is not positive or is not set, or if the number of CPU threads cannot be determined through system calls, then the number of threads is set to 1.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If $JULIA_NUM_THREADS is set to auto, then the number of threads will be set to the number of CPU threads.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nJULIA_NUM_THREADS must be defined before starting julia; defining it in startup.jl is too late in the startup process.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.5\nIn Julia 1.5 and above the number of threads can also be specified on startup using the -t/--threads command line argument.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.7\nThe auto value for $JULIA_NUM_THREADS requires Julia 1.7 or above.","category":"page"},{"location":"manual/environment-variables/#JULIA_THREAD_SLEEP_THRESHOLD","page":"Environment Variables","title":"JULIA_THREAD_SLEEP_THRESHOLD","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to a string that starts with the case-insensitive substring \"infinite\", then spinning threads never sleep. Otherwise, $JULIA_THREAD_SLEEP_THRESHOLD is interpreted as an unsigned 64-bit integer (uint64_t) and gives, in nanoseconds, the amount of time after which spinning threads should sleep.","category":"page"},{"location":"manual/environment-variables/#JULIA_NUM_GC_THREADS","page":"Environment Variables","title":"JULIA_NUM_GC_THREADS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Sets the number of threads used by Garbage Collection. If unspecified is set to half of the number of worker threads.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"compat: Julia 1.10\nThe environment variable was added in 1.10","category":"page"},{"location":"manual/environment-variables/#JULIA_IMAGE_THREADS","page":"Environment Variables","title":"JULIA_IMAGE_THREADS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"An unsigned 32-bit integer that sets the number of threads used by image compilation in this Julia process. The value of this variable may be ignored if the module is a small module. If left unspecified, the smaller of the value of JULIA_CPU_THREADS or half the number of logical CPU cores is used in its place.","category":"page"},{"location":"manual/environment-variables/#JULIA_IMAGE_TIMINGS","page":"Environment Variables","title":"JULIA_IMAGE_TIMINGS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"A boolean value that determines if detailed timing information is printed during during image compilation. Defaults to 0.","category":"page"},{"location":"manual/environment-variables/#JULIA_EXCLUSIVE","page":"Environment Variables","title":"JULIA_EXCLUSIVE","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0, then Julia's thread policy is consistent with running on a dedicated machine: the master thread is on proc 0, and threads are affinitized. Otherwise, Julia lets the operating system handle thread policy.","category":"page"},{"location":"manual/environment-variables/#REPL-formatting","page":"Environment Variables","title":"REPL formatting","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Environment variables that determine how REPL output should be formatted at the terminal. Generally, these variables should be set to ANSI terminal escape sequences. Julia provides a high-level interface with much of the same functionality; see the section on The Julia REPL.","category":"page"},{"location":"manual/environment-variables/#JULIA_ERROR_COLOR","page":"Environment Variables","title":"JULIA_ERROR_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.error_color() (default: light red, \"\\033[91m\") that errors should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#JULIA_WARN_COLOR","page":"Environment Variables","title":"JULIA_WARN_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.warn_color() (default: yellow, \"\\033[93m\") that warnings should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#JULIA_INFO_COLOR","page":"Environment Variables","title":"JULIA_INFO_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.info_color() (default: cyan, \"\\033[36m\") that info should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#JULIA_INPUT_COLOR","page":"Environment Variables","title":"JULIA_INPUT_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.input_color() (default: normal, \"\\033[0m\") that input should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#JULIA_ANSWER_COLOR","page":"Environment Variables","title":"JULIA_ANSWER_COLOR","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The formatting Base.answer_color() (default: normal, \"\\033[0m\") that output should have at the terminal.","category":"page"},{"location":"manual/environment-variables/#System-and-Package-Image-Building","page":"Environment Variables","title":"System and Package Image Building","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_CPU_TARGET","page":"Environment Variables","title":"JULIA_CPU_TARGET","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Modify the target machine architecture for (pre)compiling system and package images. JULIA_CPU_TARGET only affects machine code image generation being output to a disk cache. Unlike the --cpu-target, or -C, command line option, it does not influence just-in-time (JIT) code generation within a Julia session where machine code is only stored in memory.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Valid values for JULIA_CPU_TARGET can be obtained by executing julia -C help.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Setting JULIA_CPU_TARGET is important for heterogeneous compute systems where processors of distinct types or features may be present. This is commonly encountered in high performance computing (HPC) clusters since the component nodes may be using distinct processors.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"The CPU target string is a list of strings separated by ; each string starts with a CPU or architecture name and followed by an optional list of features separated by ,. A generic or empty CPU name means the basic required feature set of the target ISA which is at least the architecture the C/C++ runtime is compiled with. Each string is interpreted by LLVM.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"A few special features are supported:","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"clone_all\nThis forces the target to have all functions in sysimg cloned. When used in negative form (i.e. -clone_all), this disables full clone that's enabled by default for certain targets.\nbase([0-9]*)\nThis specifies the (0-based) base target index. The base target is the target that the current target is based on, i.e. the functions that are not being cloned will use the version in the base target. This option causes the base target to be fully cloned (as if clone_all is specified for it) if it is not the default target (0). The index can only be smaller than the current index.\nopt_size\nOptimize for size with minimum performance impact. Clang/GCC's -Os.\nmin_size\nOptimize only for size. Clang's -Oz.","category":"page"},{"location":"manual/environment-variables/#Debugging-and-profiling","page":"Environment Variables","title":"Debugging and profiling","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_DEBUG","page":"Environment Variables","title":"JULIA_DEBUG","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Enable debug logging for a file or module, see Logging for more information.","category":"page"},{"location":"manual/environment-variables/#JULIA_PROFILE_PEEK_HEAP_SNAPSHOT","page":"Environment Variables","title":"JULIA_PROFILE_PEEK_HEAP_SNAPSHOT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Enable collecting of a heap snapshot during execution via the profiling peek mechanism. See Triggered During Execution.","category":"page"},{"location":"manual/environment-variables/#JULIA_TIMING_SUBSYSTEMS","page":"Environment Variables","title":"JULIA_TIMING_SUBSYSTEMS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Allows you to enable or disable zones for a specific Julia run. For instance, setting the variable to +GC,-INFERENCE will enable the GC zones and disable the INFERENCE zones. See Dynamically Enabling and Disabling Zones.","category":"page"},{"location":"manual/environment-variables/#JULIA_GC_ALLOC_POOL","page":"Environment Variables","title":"JULIA_GC_ALLOC_POOL","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_GC_ALLOC_OTHER","page":"Environment Variables","title":"JULIA_GC_ALLOC_OTHER","text":"","category":"section"},{"location":"manual/environment-variables/#JULIA_GC_ALLOC_PRINT","page":"Environment Variables","title":"JULIA_GC_ALLOC_PRINT","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set, these environment variables take strings that optionally start with the character 'r', followed by a string interpolation of a colon-separated list of three signed 64-bit integers (int64_t). This triple of integers a:b:c represents the arithmetic sequence a, a + b, a + 2*b, ... c.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If it's the nth time that jl_gc_pool_alloc() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_POOL, then garbage collection is forced.\nIf it's the nth time that maybe_collect() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_OTHER, then garbage collection is forced.\nIf it's the nth time that jl_gc_collect() has been called, and n belongs to the arithmetic sequence represented by $JULIA_GC_ALLOC_PRINT, then counts for the number of calls to jl_gc_pool_alloc() and maybe_collect() are printed.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If the value of the environment variable begins with the character 'r', then the interval between garbage collection events is randomized.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nThese environment variables only have an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).","category":"page"},{"location":"manual/environment-variables/#JULIA_GC_NO_GENERATIONAL","page":"Environment Variables","title":"JULIA_GC_NO_GENERATIONAL","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0, then the Julia garbage collector never performs \"quick sweeps\" of memory.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nThis environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).","category":"page"},{"location":"manual/environment-variables/#JULIA_GC_WAIT_FOR_DEBUGGER","page":"Environment Variables","title":"JULIA_GC_WAIT_FOR_DEBUGGER","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0, then the Julia garbage collector will wait for a debugger to attach instead of aborting whenever there's a critical error.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nThis environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if WITH_GC_DEBUG_ENV is set to 1 in the build configuration).","category":"page"},{"location":"manual/environment-variables/#ENABLE_JITPROFILING","page":"Environment Variables","title":"ENABLE_JITPROFILING","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0, then the compiler will create and register an event listener for just-in-time (JIT) profiling.","category":"page"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"note: Note\nThis environment variable only has an effect if Julia was compiled with JIT profiling support, using eitherIntel's VTune™ Amplifier (USE_INTEL_JITEVENTS set to 1 in the build configuration), or\nOProfile (USE_OPROFILE_JITEVENTS set to 1 in the build configuration).\nPerf (USE_PERF_JITEVENTS set to 1 in the build configuration). This integration is enabled by default.","category":"page"},{"location":"manual/environment-variables/#ENABLE_GDBLISTENER","page":"Environment Variables","title":"ENABLE_GDBLISTENER","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"If set to anything besides 0 enables GDB registration of Julia code on release builds. On debug builds of Julia this is always enabled. Recommended to use with -g 2.","category":"page"},{"location":"manual/environment-variables/#JULIA_LLVM_ARGS","page":"Environment Variables","title":"JULIA_LLVM_ARGS","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Arguments to be passed to the LLVM backend.","category":"page"},{"location":"manual/environment-variables/#JULIA_FALLBACK_REPL","page":"Environment Variables","title":"JULIA_FALLBACK_REPL","text":"","category":"section"},{"location":"manual/environment-variables/","page":"Environment Variables","title":"Environment Variables","text":"Forces the fallback repl instead of REPL.jl.","category":"page"},{"location":"manual/faq/#Frequently-Asked-Questions","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"section"},{"location":"manual/faq/#General","page":"Frequently Asked Questions","title":"General","text":"","category":"section"},{"location":"manual/faq/#Is-Julia-named-after-someone-or-something?","page":"Frequently Asked Questions","title":"Is Julia named after someone or something?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"No.","category":"page"},{"location":"manual/faq/#Why-don't-you-compile-Matlab/Python/R/…-code-to-Julia?","page":"Frequently Asked Questions","title":"Why don't you compile Matlab/Python/R/… code to Julia?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Since many people are familiar with the syntax of other dynamic languages, and lots of code has already been written in those languages, it is natural to wonder why we didn't just plug a Matlab or Python front-end into a Julia back-end (or “transpile” code to Julia) in order to get all the performance benefits of Julia without requiring programmers to learn a new language. Simple, right?","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The basic issue is that there is nothing special about Julia's compiler: we use a commonplace compiler (LLVM) with no “secret sauce” that other language developers don't know about. Indeed, Julia's compiler is in many ways much simpler than those of other dynamic languages (e.g. PyPy or LuaJIT). Julia's performance advantage derives almost entirely from its front-end: its language semantics allow a well-written Julia program to give more opportunities to the compiler to generate efficient code and memory layouts. If you tried to compile Matlab or Python code to Julia, our compiler would be limited by the semantics of Matlab or Python to producing code no better than that of existing compilers for those languages (and probably worse). The key role of semantics is also why several existing Python compilers (like Numba and Pythran) only attempt to optimize a small subset of the language (e.g. operations on Numpy arrays and scalars), and for this subset they are already doing at least as well as we could for the same semantics. The people working on those projects are incredibly smart and have accomplished amazing things, but retrofitting a compiler onto a language that was designed to be interpreted is a very difficult problem.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia's advantage is that good performance is not limited to a small subset of “built-in” types and operations, and one can write high-level type-generic code that works on arbitrary user-defined types while remaining fast and memory-efficient. Types in languages like Python simply don't provide enough information to the compiler for similar capabilities, so as soon as you used those languages as a Julia front-end you would be stuck.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"For similar reasons, automated translation to Julia would also typically generate unreadable, slow, non-idiomatic code that would not be a good starting point for a native Julia port from another language.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"On the other hand, language interoperability is extremely useful: we want to exploit existing high-quality code in other languages from Julia (and vice versa)! The best way to enable this is not a transpiler, but rather via easy inter-language calling facilities. We have worked hard on this, from the built-in ccall intrinsic (to call C and Fortran libraries) to JuliaInterop packages that connect Julia to Python, Matlab, C++, and more.","category":"page"},{"location":"manual/faq/#man-api","page":"Frequently Asked Questions","title":"Public API","text":"","category":"section"},{"location":"manual/faq/#How-does-Julia-define-its-public-API?","page":"Frequently Asked Questions","title":"How does Julia define its public API?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia's public API is the behavior described in documentation of public symbols from Base and the standard libraries. Functions, types, and constants are not part of the public API if they are not public, even if they have docstrings or are described in the documentation. Further, only the documented behavior of public symbols is part of the public API. Undocumented behavior of public symbols is internal.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Public symbols are those marked with either public foo or export foo.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In other words:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Documented behavior of public symbols is part of the public API.\nUndocumented behavior of public symbols is not part of the public API.\nDocumented behavior of private symbols is not part of the public API.\nUndocumented behavior of private symbols is not part of the public API.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can get a complete list of the public symbols from a module with names(MyModule).","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Package authors are encouraged to define their public API similarly.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Anything in Julia's Public API is covered by SemVer and therefore will not be removed or receive meaningful breaking changes before Julia 2.0.","category":"page"},{"location":"manual/faq/#There-is-a-useful-undocumented-function/type/constant.-Can-I-use-it?","page":"Frequently Asked Questions","title":"There is a useful undocumented function/type/constant. Can I use it?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Updating Julia may break your code if you use non-public API. If the code is self-contained, it may be a good idea to copy it into your project. If you want to rely on a complex non-public API, especially when using it from a stable package, it is a good idea to open an issue or pull request to start a discussion for turning it into a public API. However, we do not discourage the attempt to create packages that expose stable public interfaces while relying on non-public implementation details of Julia and buffering the differences across different Julia versions.","category":"page"},{"location":"manual/faq/#The-documentation-is-not-accurate-enough.-Can-I-rely-on-the-existing-behavior?","page":"Frequently Asked Questions","title":"The documentation is not accurate enough. Can I rely on the existing behavior?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Please open an issue or pull request to start a discussion for turning the existing behavior into a public API.","category":"page"},{"location":"manual/faq/#Sessions-and-the-REPL","page":"Frequently Asked Questions","title":"Sessions and the REPL","text":"","category":"section"},{"location":"manual/faq/#How-do-I-delete-an-object-in-memory?","page":"Frequently Asked Questions","title":"How do I delete an object in memory?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia does not have an analog of MATLAB's clear function; once a name is defined in a Julia session (technically, in module Main), it is always present.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If memory usage is your concern, you can always replace objects with ones that consume less memory. For example, if A is a gigabyte-sized array that you no longer need, you can free the memory with A = nothing. The memory will be released the next time the garbage collector runs; you can force this to happen with GC.gc(). Moreover, an attempt to use A will likely result in an error, because most methods are not defined on type Nothing.","category":"page"},{"location":"manual/faq/#How-can-I-modify-the-declaration-of-a-type-in-my-session?","page":"Frequently Asked Questions","title":"How can I modify the declaration of a type in my session?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Perhaps you've defined a type and then realize you need to add a new field. If you try this at the REPL, you get the error:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"ERROR: invalid redefinition of constant MyType","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Types in module Main cannot be redefined.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"While this can be inconvenient when you are developing new code, there's an excellent workaround. Modules can be replaced by redefining them, and so if you wrap all your new code inside a module you can redefine types and constants. You can't import the type names into Main and then expect to be able to redefine them there, but you can use the module name to resolve the scope. In other words, while developing you might use a workflow something like this:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"include(\"mynewcode.jl\") # this defines a module MyModule\nobj1 = MyModule.ObjConstructor(a, b)\nobj2 = MyModule.somefunction(obj1)\n# Got an error. Change something in \"mynewcode.jl\"\ninclude(\"mynewcode.jl\") # reload the module\nobj1 = MyModule.ObjConstructor(a, b) # old objects are no longer valid, must reconstruct\nobj2 = MyModule.somefunction(obj1) # this time it worked!\nobj3 = MyModule.someotherfunction(obj2, c)\n...","category":"page"},{"location":"manual/faq/#man-scripting","page":"Frequently Asked Questions","title":"Scripting","text":"","category":"section"},{"location":"manual/faq/#How-do-I-check-if-the-current-file-is-being-run-as-the-main-script?","page":"Frequently Asked Questions","title":"How do I check if the current file is being run as the main script?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"When a file is run as the main script using julia file.jl one might want to activate extra functionality like command line argument handling. A way to determine that a file is run in this fashion is to check if abspath(PROGRAM_FILE) == @__FILE__ is true.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"However, it is recommended to not write files that double as a script and as an importable library. If one needs functionality both available as a library and a script, it is better to write is as a library, then import the functionality into a distinct script.","category":"page"},{"location":"manual/faq/#catch-ctrl-c","page":"Frequently Asked Questions","title":"How do I catch CTRL-C in a script?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Running a Julia script using julia file.jl does not throw InterruptException when you try to terminate it with CTRL-C (SIGINT). To run a certain code before terminating a Julia script, which may or may not be caused by CTRL-C, use atexit. Alternatively, you can use julia -e 'include(popfirst!(ARGS))' file.jl to execute a script while being able to catch InterruptException in the try block. Note that with this strategy PROGRAM_FILE will not be set.","category":"page"},{"location":"manual/faq/#How-do-I-pass-options-to-julia-using-#!/usr/bin/env?","page":"Frequently Asked Questions","title":"How do I pass options to julia using #!/usr/bin/env?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Passing options to julia in a so-called shebang line, as in #!/usr/bin/env julia --startup-file=no, will not work on many platforms (BSD, macOS, Linux) where the kernel, unlike the shell, does not split arguments at space characters. The option env -S, which splits a single argument string into multiple arguments at spaces, similar to a shell, offers a simple workaround:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"#!/usr/bin/env -S julia --color=yes --startup-file=no\n@show ARGS # put any Julia code here","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"note: Note\nOption env -S appeared in FreeBSD 6.0 (2005), macOS Sierra (2016) and GNU/Linux coreutils 8.30 (2018).","category":"page"},{"location":"manual/faq/#Why-doesn't-run-support-*-or-pipes-for-scripting-external-programs?","page":"Frequently Asked Questions","title":"Why doesn't run support * or pipes for scripting external programs?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia's run function launches external programs directly, without invoking an operating-system shell (unlike the system(\"...\") function in other languages like Python, R, or C). That means that run does not perform wildcard expansion of * (\"globbing\"), nor does it interpret shell pipelines like | or >.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can still do globbing and pipelines using Julia features, however. For example, the built-in pipeline function allows you to chain external programs and files, similar to shell pipes, and the Glob.jl package implements POSIX-compatible globbing.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can, of course, run programs through the shell by explicitly passing a shell and a command string to run, e.g. run(`sh -c \"ls > files.txt\"`) to use the Unix Bourne shell, but you should generally prefer pure-Julia scripting like run(pipeline(`ls`, \"files.txt\")). The reason why we avoid the shell by default is that shelling out sucks: launching processes via the shell is slow, fragile to quoting of special characters, has poor error handling, and is problematic for portability. (The Python developers came to a similar conclusion.)","category":"page"},{"location":"manual/faq/#Variables-and-Assignments","page":"Frequently Asked Questions","title":"Variables and Assignments","text":"","category":"section"},{"location":"manual/faq/#Why-am-I-getting-UndefVarError-from-a-simple-loop?","page":"Frequently Asked Questions","title":"Why am I getting UndefVarError from a simple loop?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You might have something like:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"x = 0\nwhile x < 10\n x += 1\nend","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"and notice that it works fine in an interactive environment (like the Julia REPL), but gives UndefVarError: `x` not defined when you try to run it in script or other file. What is going on is that Julia generally requires you to be explicit about assigning to global variables in a local scope.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Here, x is a global variable, while defines a local scope, and x += 1 is an assignment to a global in that local scope.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As mentioned above, Julia (version 1.5 or later) allows you to omit the global keyword for code in the REPL (and many other interactive environments), to simplify exploration (e.g. copy-pasting code from a function to run interactively). However, once you move to code in files, Julia requires a more disciplined approach to global variables. You have least three options:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Put the code into a function (so that x is a local variable in a function). In general, it is good software engineering to use functions rather than global scripts (search online for \"why global variables bad\" to see many explanations). In Julia, global variables are also slow.\nWrap the code in a let block. (This makes x a local variable within the let ... end statement, again eliminating the need for global).\nExplicitly mark x as global inside the local scope before assigning to it, e.g. write global x += 1.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"More explanation can be found in the manual section on soft scope.","category":"page"},{"location":"manual/faq/#Functions","page":"Frequently Asked Questions","title":"Functions","text":"","category":"section"},{"location":"manual/faq/#I-passed-an-argument-x-to-a-function,-modified-it-inside-that-function,-but-on-the-outside,-the-variable-x-is-still-unchanged.-Why?","page":"Frequently Asked Questions","title":"I passed an argument x to a function, modified it inside that function, but on the outside, the variable x is still unchanged. Why?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Suppose you call a function like this:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> x = 10\n10\n\njulia> function change_value!(y)\n y = 17\n end\nchange_value! (generic function with 1 method)\n\njulia> change_value!(x)\n17\n\njulia> x # x is unchanged!\n10","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In Julia, the binding of a variable x cannot be changed by passing x as an argument to a function. When calling change_value!(x) in the above example, y is a newly created variable, bound initially to the value of x, i.e. 10; then y is rebound to the constant 17, while the variable x of the outer scope is left untouched.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"However, if x is bound to an object of type Array (or any other mutable type). From within the function, you cannot \"unbind\" x from this Array, but you can change its content. For example:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> x = [1,2,3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> function change_array!(A)\n A[1] = 5\n end\nchange_array! (generic function with 1 method)\n\njulia> change_array!(x)\n5\n\njulia> x\n3-element Vector{Int64}:\n 5\n 2\n 3","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Here we created a function change_array!, that assigns 5 to the first element of the passed array (bound to x at the call site, and bound to A within the function). Notice that, after the function call, x is still bound to the same array, but the content of that array changed: the variables A and x were distinct bindings referring to the same mutable Array object.","category":"page"},{"location":"manual/faq/#Can-I-use-using-or-import-inside-a-function?","page":"Frequently Asked Questions","title":"Can I use using or import inside a function?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"No, you are not allowed to have a using or import statement inside a function. If you want to import a module but only use its symbols inside a specific function or set of functions, you have two options:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Use import:\nimport Foo\nfunction bar(...)\n # ... refer to Foo symbols via Foo.baz ...\nend\nThis loads the module Foo and defines a variable Foo that refers to the module, but does not import any of the other symbols from the module into the current namespace. You refer to the Foo symbols by their qualified names Foo.bar etc.\nWrap your function in a module:\nmodule Bar\nexport bar\nusing Foo\nfunction bar(...)\n # ... refer to Foo.baz as simply baz ....\nend\nend\nusing Bar\nThis imports all the symbols from Foo, but only inside the module Bar.","category":"page"},{"location":"manual/faq/#What-does-the-...-operator-do?","page":"Frequently Asked Questions","title":"What does the ... operator do?","text":"","category":"section"},{"location":"manual/faq/#The-two-uses-of-the-...-operator:-slurping-and-splatting","page":"Frequently Asked Questions","title":"The two uses of the ... operator: slurping and splatting","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Many newcomers to Julia find the use of ... operator confusing. Part of what makes the ... operator confusing is that it means two different things depending on context.","category":"page"},{"location":"manual/faq/#...-combines-many-arguments-into-one-argument-in-function-definitions","page":"Frequently Asked Questions","title":"... combines many arguments into one argument in function definitions","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In the context of function definitions, the ... operator is used to combine many different arguments into a single argument. This use of ... for combining many different arguments into a single argument is called slurping:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function printargs(args...)\n println(typeof(args))\n for (i, arg) in enumerate(args)\n println(\"Arg #$i = $arg\")\n end\n end\nprintargs (generic function with 1 method)\n\njulia> printargs(1, 2, 3)\nTuple{Int64, Int64, Int64}\nArg #1 = 1\nArg #2 = 2\nArg #3 = 3","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If Julia were a language that made more liberal use of ASCII characters, the slurping operator might have been written as <-... instead of ....","category":"page"},{"location":"manual/faq/#...-splits-one-argument-into-many-different-arguments-in-function-calls","page":"Frequently Asked Questions","title":"... splits one argument into many different arguments in function calls","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In contrast to the use of the ... operator to denote slurping many different arguments into one argument when defining a function, the ... operator is also used to cause a single function argument to be split apart into many different arguments when used in the context of a function call. This use of ... is called splatting:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function threeargs(a, b, c)\n println(\"a = $a::$(typeof(a))\")\n println(\"b = $b::$(typeof(b))\")\n println(\"c = $c::$(typeof(c))\")\n end\nthreeargs (generic function with 1 method)\n\njulia> x = [1, 2, 3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> threeargs(x...)\na = 1::Int64\nb = 2::Int64\nc = 3::Int64","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If Julia were a language that made more liberal use of ASCII characters, the splatting operator might have been written as ...-> instead of ....","category":"page"},{"location":"manual/faq/#What-is-the-return-value-of-an-assignment?","page":"Frequently Asked Questions","title":"What is the return value of an assignment?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The operator = always returns the right-hand side, therefore:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function threeint()\n x::Int = 3.0\n x # returns variable x\n end\nthreeint (generic function with 1 method)\n\njulia> function threefloat()\n x::Int = 3.0 # returns 3.0\n end\nthreefloat (generic function with 1 method)\n\njulia> threeint()\n3\n\njulia> threefloat()\n3.0","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"and similarly:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function twothreetup()\n x, y = [2, 3] # assigns 2 to x and 3 to y\n x, y # returns a tuple\n end\ntwothreetup (generic function with 1 method)\n\njulia> function twothreearr()\n x, y = [2, 3] # returns an array\n end\ntwothreearr (generic function with 1 method)\n\njulia> twothreetup()\n(2, 3)\n\njulia> twothreearr()\n2-element Vector{Int64}:\n 2\n 3","category":"page"},{"location":"manual/faq/#Types,-type-declarations,-and-constructors","page":"Frequently Asked Questions","title":"Types, type declarations, and constructors","text":"","category":"section"},{"location":"manual/faq/#man-type-stability","page":"Frequently Asked Questions","title":"What does \"type-stable\" mean?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"It means that the type of the output is predictable from the types of the inputs. In particular, it means that the type of the output cannot vary depending on the values of the inputs. The following code is not type-stable:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function unstable(flag::Bool)\n if flag\n return 1\n else\n return 1.0\n end\n end\nunstable (generic function with 1 method)","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"It returns either an Int or a Float64 depending on the value of its argument. Since Julia can't predict the return type of this function at compile-time, any computation that uses it must be able to cope with values of both types, which makes it hard to produce fast machine code.","category":"page"},{"location":"manual/faq/#faq-domain-errors","page":"Frequently Asked Questions","title":"Why does Julia give a DomainError for certain seemingly-sensible operations?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Certain operations make mathematical sense but result in errors:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> sqrt(-2.0)\nERROR: DomainError with -2.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This behavior is an inconvenient consequence of the requirement for type-stability. In the case of sqrt, most users want sqrt(2.0) to give a real number, and would be unhappy if it produced the complex number 1.4142135623730951 + 0.0im. One could write the sqrt function to switch to a complex-valued output only when passed a negative number (which is what sqrt does in some other languages), but then the result would not be type-stable and the sqrt function would have poor performance.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In these and other cases, you can get the result you want by choosing an input type that conveys your willingness to accept an output type in which the result can be represented:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> sqrt(-2.0+0im)\n0.0 + 1.4142135623730951im","category":"page"},{"location":"manual/faq/#How-can-I-constrain-or-compute-type-parameters?","page":"Frequently Asked Questions","title":"How can I constrain or compute type parameters?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The parameters of a parametric type can hold either types or bits values, and the type itself chooses how it makes use of these parameters. For example, Array{Float64, 2} is parameterized by the type Float64 to express its element type and the integer value 2 to express its number of dimensions. When defining your own parametric type, you can use subtype constraints to declare that a certain parameter must be a subtype (<:) of some abstract type or a previous type parameter. There is not, however, a dedicated syntax to declare that a parameter must be a value of a given type — that is, you cannot directly declare that a dimensionality-like parameter isa Int within the struct definition, for example. Similarly, you cannot do computations (including simple things like addition or subtraction) on type parameters. Instead, these sorts of constraints and relationships may be expressed through additional type parameters that are computed and enforced within the type's constructors.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As an example, consider","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"struct ConstrainedType{T,N,N+1} # NOTE: INVALID SYNTAX\n A::Array{T,N}\n B::Array{T,N+1}\nend","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"where the user would like to enforce that the third type parameter is always the second plus one. This can be implemented with an explicit type parameter that is checked by an inner constructor method (where it can be combined with other checks):","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"struct ConstrainedType{T,N,M}\n A::Array{T,N}\n B::Array{T,M}\n function ConstrainedType(A::Array{T,N}, B::Array{T,M}) where {T,N,M}\n N + 1 == M || throw(ArgumentError(\"second argument should have one more axis\" ))\n new{T,N,M}(A, B)\n end\nend","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This check is usually costless, as the compiler can elide the check for valid concrete types. If the second argument is also computed, it may be advantageous to provide an outer constructor method that performs this calculation:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"ConstrainedType(A) = ConstrainedType(A, compute_B(A))","category":"page"},{"location":"manual/faq/#faq-integer-arithmetic","page":"Frequently Asked Questions","title":"Why does Julia use native machine integer arithmetic?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia uses machine arithmetic for integer computations. This means that the range of Int values is bounded and wraps around at either end so that adding, subtracting and multiplying integers can overflow or underflow, leading to some results that can be unsettling at first:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> x = typemax(Int)\n9223372036854775807\n\njulia> y = x+1\n-9223372036854775808\n\njulia> z = -y\n-9223372036854775808\n\njulia> 2*z\n0","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Clearly, this is far from the way mathematical integers behave, and you might think it less than ideal for a high-level programming language to expose this to the user. For numerical work where efficiency and transparency are at a premium, however, the alternatives are worse.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"One alternative to consider would be to check each integer operation for overflow and promote results to bigger integer types such as Int128 or BigInt in the case of overflow. Unfortunately, this introduces major overhead on every integer operation (think incrementing a loop counter) – it requires emitting code to perform run-time overflow checks after arithmetic instructions and branches to handle potential overflows. Worse still, this would cause every computation involving integers to be type-unstable. As we mentioned above, type-stability is crucial for effective generation of efficient code. If you can't count on the results of integer operations being integers, it's impossible to generate fast, simple code the way C and Fortran compilers do.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"A variation on this approach, which avoids the appearance of type instability is to merge the Int and BigInt types into a single hybrid integer type, that internally changes representation when a result no longer fits into the size of a machine integer. While this superficially avoids type-instability at the level of Julia code, it just sweeps the problem under the rug by foisting all of the same difficulties onto the C code implementing this hybrid integer type. This approach can be made to work and can even be made quite fast in many cases, but has several drawbacks. One problem is that the in-memory representation of integers and arrays of integers no longer match the natural representation used by C, Fortran and other languages with native machine integers. Thus, to interoperate with those languages, we would ultimately need to introduce native integer types anyway. Any unbounded representation of integers cannot have a fixed number of bits, and thus cannot be stored inline in an array with fixed-size slots – large integer values will always require separate heap-allocated storage. And of course, no matter how clever a hybrid integer implementation one uses, there are always performance traps – situations where performance degrades unexpectedly. Complex representation, lack of interoperability with C and Fortran, the inability to represent integer arrays without additional heap storage, and unpredictable performance characteristics make even the cleverest hybrid integer implementations a poor choice for high-performance numerical work.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"An alternative to using hybrid integers or promoting to BigInts is to use saturating integer arithmetic, where adding to the largest integer value leaves it unchanged and likewise for subtracting from the smallest integer value. This is precisely what Matlab™ does:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":">> int64(9223372036854775807)\n\nans =\n\n 9223372036854775807\n\n>> int64(9223372036854775807) + 1\n\nans =\n\n 9223372036854775807\n\n>> int64(-9223372036854775808)\n\nans =\n\n -9223372036854775808\n\n>> int64(-9223372036854775808) - 1\n\nans =\n\n -9223372036854775808","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"At first blush, this seems reasonable enough since 9223372036854775807 is much closer to 9223372036854775808 than -9223372036854775808 is and integers are still represented with a fixed size in a natural way that is compatible with C and Fortran. Saturated integer arithmetic, however, is deeply problematic. The first and most obvious issue is that this is not the way machine integer arithmetic works, so implementing saturated operations requires emitting instructions after each machine integer operation to check for underflow or overflow and replace the result with typemin(Int) or typemax(Int) as appropriate. This alone expands each integer operation from a single, fast instruction into half a dozen instructions, probably including branches. Ouch. But it gets worse – saturating integer arithmetic isn't associative. Consider this Matlab computation:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":">> n = int64(2)^62\n4611686018427387904\n\n>> n + (n - 1)\n9223372036854775807\n\n>> (n + n) - 1\n9223372036854775806","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This makes it hard to write many basic integer algorithms since a lot of common techniques depend on the fact that machine addition with overflow is associative. Consider finding the midpoint between integer values lo and hi in Julia using the expression (lo + hi) >>> 1:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> n = 2^62\n4611686018427387904\n\njulia> (n + 2n) >>> 1\n6917529027641081856","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"See? No problem. That's the correct midpoint between 2^62 and 2^63, despite the fact that n + 2n is -4611686018427387904. Now try it in Matlab:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":">> (n + 2*n)/2\n\nans =\n\n 4611686018427387904","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Oops. Adding a >>> operator to Matlab wouldn't help, because saturation that occurs when adding n and 2n has already destroyed the information necessary to compute the correct midpoint.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Not only is lack of associativity unfortunate for programmers who cannot rely it for techniques like this, but it also defeats almost anything compilers might want to do to optimize integer arithmetic. For example, since Julia integers use normal machine integer arithmetic, LLVM is free to aggressively optimize simple little functions like f(k) = 5k-1. The machine code for this function is just this:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> code_native(f, Tuple{Int})\n .text\nFilename: none\n pushq %rbp\n movq %rsp, %rbp\nSource line: 1\n leaq -1(%rdi,%rdi,4), %rax\n popq %rbp\n retq\n nopl (%rax,%rax)","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The actual body of the function is a single leaq instruction, which computes the integer multiply and add at once. This is even more beneficial when f gets inlined into another function:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function g(k, n)\n for i = 1:n\n k = f(k)\n end\n return k\n end\ng (generic function with 1 methods)\n\njulia> code_native(g, Tuple{Int,Int})\n .text\nFilename: none\n pushq %rbp\n movq %rsp, %rbp\nSource line: 2\n testq %rsi, %rsi\n jle L26\n nopl (%rax)\nSource line: 3\nL16:\n leaq -1(%rdi,%rdi,4), %rdi\nSource line: 2\n decq %rsi\n jne L16\nSource line: 5\nL26:\n movq %rdi, %rax\n popq %rbp\n retq\n nop","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Since the call to f gets inlined, the loop body ends up being just a single leaq instruction. Next, consider what happens if we make the number of loop iterations fixed:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> function g(k)\n for i = 1:10\n k = f(k)\n end\n return k\n end\ng (generic function with 2 methods)\n\njulia> code_native(g,(Int,))\n .text\nFilename: none\n pushq %rbp\n movq %rsp, %rbp\nSource line: 3\n imulq $9765625, %rdi, %rax # imm = 0x9502F9\n addq $-2441406, %rax # imm = 0xFFDABF42\nSource line: 5\n popq %rbp\n retq\n nopw %cs:(%rax,%rax)","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Because the compiler knows that integer addition and multiplication are associative and that multiplication distributes over addition – neither of which is true of saturating arithmetic – it can optimize the entire loop down to just a multiply and an add. Saturated arithmetic completely defeats this kind of optimization since associativity and distributivity can fail at each loop iteration, causing different outcomes depending on which iteration the failure occurs in. The compiler can unroll the loop, but it cannot algebraically reduce multiple operations into fewer equivalent operations.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The most reasonable alternative to having integer arithmetic silently overflow is to do checked arithmetic everywhere, raising errors when adds, subtracts, and multiplies overflow, producing values that are not value-correct. In this blog post, Dan Luu analyzes this and finds that rather than the trivial cost that this approach should in theory have, it ends up having a substantial cost due to compilers (LLVM and GCC) not gracefully optimizing around the added overflow checks. If this improves in the future, we could consider defaulting to checked integer arithmetic in Julia, but for now, we have to live with the possibility of overflow.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In the meantime, overflow-safe integer operations can be achieved through the use of external libraries such as SaferIntegers.jl. Note that, as stated previously, the use of these libraries significantly increases the execution time of code using the checked integer types. However, for limited usage, this is far less of an issue than if it were used for all integer operations. You can follow the status of the discussion here.","category":"page"},{"location":"manual/faq/#What-are-the-possible-causes-of-an-UndefVarError-during-remote-execution?","page":"Frequently Asked Questions","title":"What are the possible causes of an UndefVarError during remote execution?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As the error states, an immediate cause of an UndefVarError on a remote node is that a binding by that name does not exist. Let us explore some of the possible causes.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> module Foo\n foo() = remotecall_fetch(x->x, 2, \"Hello\")\n end\n\njulia> Foo.foo()\nERROR: On worker 2:\nUndefVarError: `Foo` not defined in `Main`\nStacktrace:\n[...]","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The closure x->x carries a reference to Foo, and since Foo is unavailable on node 2, an UndefVarError is thrown.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Globals under modules other than Main are not serialized by value to the remote node. Only a reference is sent. Functions which create global bindings (except under Main) may cause an UndefVarError to be thrown later.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> @everywhere module Foo\n function foo()\n global gvar = \"Hello\"\n remotecall_fetch(()->gvar, 2)\n end\n end\n\njulia> Foo.foo()\nERROR: On worker 2:\nUndefVarError: `gvar` not defined in `Main.Foo`\nStacktrace:\n[...]","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In the above example, @everywhere module Foo defined Foo on all nodes. However the call to Foo.foo() created a new global binding gvar on the local node, but this was not found on node 2 resulting in an UndefVarError error.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Note that this does not apply to globals created under module Main. Globals under module Main are serialized and new bindings created under Main on the remote node.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> gvar_self = \"Node1\"\n\"Node1\"\n\njulia> remotecall_fetch(()->gvar_self, 2)\n\"Node1\"\n\njulia> remotecall_fetch(varinfo, 2)\nname size summary\n––––––––– –––––––– –––––––\nBase Module\nCore Module\nMain Module\ngvar_self 13 bytes String","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This does not apply to function or struct declarations. However, anonymous functions bound to global variables are serialized as can be seen below.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> bar() = 1\nbar (generic function with 1 method)\n\njulia> remotecall_fetch(bar, 2)\nERROR: On worker 2:\nUndefVarError: `#bar` not defined in `Main`\n[...]\n\njulia> anon_bar = ()->1\n(::#21) (generic function with 1 method)\n\njulia> remotecall_fetch(anon_bar, 2)\n1","category":"page"},{"location":"manual/faq/#Troubleshooting-\"method-not-matched\":-parametric-type-invariance-and-MethodErrors","page":"Frequently Asked Questions","title":"Troubleshooting \"method not matched\": parametric type invariance and MethodErrors","text":"","category":"section"},{"location":"manual/faq/#Why-doesn't-it-work-to-declare-foo(bar::Vector{Real})-42-and-then-call-foo([1])?","page":"Frequently Asked Questions","title":"Why doesn't it work to declare foo(bar::Vector{Real}) = 42 and then call foo([1])?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"As you'll see if you try this, the result is a MethodError:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> foo(x::Vector{Real}) = 42\nfoo (generic function with 1 method)\n\njulia> foo([1])\nERROR: MethodError: no method matching foo(::Vector{Int64})\nThe function `foo` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n foo(!Matched::Vector{Real})\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This is because Vector{Real} is not a supertype of Vector{Int}! You can solve this problem with something like foo(bar::Vector{T}) where {T<:Real} (or the short form foo(bar::Vector{<:Real}) if the static parameter T is not needed in the body of the function). The T is a wild card: you first specify that it must be a subtype of Real, then specify the function takes a Vector of with elements of that type.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This same issue goes for any composite type Comp, not just Vector. If Comp has a parameter declared of type Y, then another type Comp2 with a parameter of type X<:Y is not a subtype of Comp. This is type-invariance (by contrast, Tuple is type-covariant in its parameters). See Parametric Composite Types for more explanation of these.","category":"page"},{"location":"manual/faq/#Why-does-Julia-use-*-for-string-concatenation?-Why-not-or-something-else?","page":"Frequently Asked Questions","title":"Why does Julia use * for string concatenation? Why not + or something else?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The main argument against + is that string concatenation is not commutative, while + is generally used as a commutative operator. While the Julia community recognizes that other languages use different operators and * may be unfamiliar for some users, it communicates certain algebraic properties.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Note that you can also use string(...) to concatenate strings (and other values converted to strings); similarly, repeat can be used instead of ^ to repeat strings. The interpolation syntax is also useful for constructing strings.","category":"page"},{"location":"manual/faq/#Packages-and-Modules","page":"Frequently Asked Questions","title":"Packages and Modules","text":"","category":"section"},{"location":"manual/faq/#What-is-the-difference-between-\"using\"-and-\"import\"?","page":"Frequently Asked Questions","title":"What is the difference between \"using\" and \"import\"?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"There are several differences between using and import (see the Modules section), but there is an important difference that may not seem intuitive at first glance, and on the surface (i.e. syntax-wise) it may seem very minor. When loading modules with using, you need to say function Foo.bar(... to extend module Foo's function bar with a new method, but with import Foo.bar, you only need to say function bar(... and it automatically extends module Foo's function bar.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The reason this is important enough to have been given separate syntax is that you don't want to accidentally extend a function that you didn't know existed, because that could easily cause a bug. This is most likely to happen with a method that takes a common type like a string or integer, because both you and the other module could define a method to handle such a common type. If you use import, then you'll replace the other module's implementation of bar(s::AbstractString) with your new implementation, which could easily do something completely different (and break all/many future usages of the other functions in module Foo that depend on calling bar).","category":"page"},{"location":"manual/faq/#Nothingness-and-missing-values","page":"Frequently Asked Questions","title":"Nothingness and missing values","text":"","category":"section"},{"location":"manual/faq/#faq-nothing","page":"Frequently Asked Questions","title":"How does \"null\", \"nothingness\" or \"missingness\" work in Julia?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Unlike many languages (for example, C and Java), Julia objects cannot be \"null\" by default. When a reference (variable, object field, or array element) is uninitialized, accessing it will immediately throw an error. This situation can be detected using the isdefined or isassigned functions.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Some functions are used only for their side effects, and do not need to return a value. In these cases, the convention is to return the value nothing, which is just a singleton object of type Nothing. This is an ordinary type with no fields; there is nothing special about it except for this convention, and that the REPL does not print anything for it. Some language constructs that would not otherwise have a value also yield nothing, for example if false; end.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"For situations where a value x of type T exists only sometimes, the Union{T, Nothing} type can be used for function arguments, object fields and array element types as the equivalent of Nullable, Option or Maybe in other languages. If the value itself can be nothing (notably, when T is Any), the Union{Some{T}, Nothing} type is more appropriate since x == nothing then indicates the absence of a value, and x == Some(nothing) indicates the presence of a value equal to nothing. The something function allows unwrapping Some objects and using a default value instead of nothing arguments. Note that the compiler is able to generate efficient code when working with Union{T, Nothing} arguments or fields.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"To represent missing data in the statistical sense (NA in R or NULL in SQL), use the missing object. See the Missing Values section for more details.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In some languages, the empty tuple (()) is considered the canonical form of nothingness. However, in julia it is best thought of as just a regular tuple that happens to contain zero values.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The empty (or \"bottom\") type, written as Union{} (an empty union type), is a type with no values and no subtypes (except itself). You will generally not need to use this type.","category":"page"},{"location":"manual/faq/#Memory","page":"Frequently Asked Questions","title":"Memory","text":"","category":"section"},{"location":"manual/faq/#Why-does-x-y-allocate-memory-when-x-and-y-are-arrays?","page":"Frequently Asked Questions","title":"Why does x += y allocate memory when x and y are arrays?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In Julia, x += y gets replaced during lowering by x = x + y. For arrays, this has the consequence that, rather than storing the result in the same location in memory as x, it allocates a new array to store the result. If you prefer to mutate x, use x .+= y to update each element individually.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"While this behavior might surprise some, the choice is deliberate. The main reason is the presence of immutable objects within Julia, which cannot change their value once created. Indeed, a number is an immutable object; the statements x = 5; x += 1 do not modify the meaning of 5, they modify the value bound to x. For an immutable, the only way to change the value is to reassign it.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"To amplify a bit further, consider the following function:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"function power_by_squaring(x, n::Int)\n ispow2(n) || error(\"This implementation only works for powers of 2\")\n while n >= 2\n x *= x\n n >>= 1\n end\n x\nend","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"After a call like x = 5; y = power_by_squaring(x, 4), you would get the expected result: x == 5 && y == 625. However, now suppose that *=, when used with matrices, instead mutated the left hand side. There would be two problems:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"For general square matrices, A = A*B cannot be implemented without temporary storage: A[1,1] gets computed and stored on the left hand side before you're done using it on the right hand side.\nSuppose you were willing to allocate a temporary for the computation (which would eliminate most of the point of making *= work in-place); if you took advantage of the mutability of x, then this function would behave differently for mutable vs. immutable inputs. In particular, for immutable x, after the call you'd have (in general) y != x, but for mutable x you'd have y == x.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Because supporting generic programming is deemed more important than potential performance optimizations that can be achieved by other means (e.g., using broadcasting or explicit loops), operators like += and *= work by rebinding new values.","category":"page"},{"location":"manual/faq/#faq-async-io","page":"Frequently Asked Questions","title":"Asynchronous IO and concurrent synchronous writes","text":"","category":"section"},{"location":"manual/faq/#Why-do-concurrent-writes-to-the-same-stream-result-in-inter-mixed-output?","page":"Frequently Asked Questions","title":"Why do concurrent writes to the same stream result in inter-mixed output?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"While the streaming I/O API is synchronous, the underlying implementation is fully asynchronous.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Consider the printed output from the following:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> @sync for i in 1:3\n @async write(stdout, string(i), \" Foo \", \" Bar \")\n end\n123 Foo Foo Foo Bar Bar Bar","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This is happening because, while the write call is synchronous, the writing of each argument yields to other tasks while waiting for that part of the I/O to complete.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"print and println \"lock\" the stream during a call. Consequently changing write to println in the above example results in:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> @sync for i in 1:3\n @async println(stdout, string(i), \" Foo \", \" Bar \")\n end\n1 Foo Bar\n2 Foo Bar\n3 Foo Bar","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You can lock your writes with a ReentrantLock like this:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> l = ReentrantLock();\n\njulia> @sync for i in 1:3\n @async begin\n lock(l)\n try\n write(stdout, string(i), \" Foo \", \" Bar \")\n finally\n unlock(l)\n end\n end\n end\n1 Foo Bar 2 Foo Bar 3 Foo Bar","category":"page"},{"location":"manual/faq/#Arrays","page":"Frequently Asked Questions","title":"Arrays","text":"","category":"section"},{"location":"manual/faq/#faq-array-0dim","page":"Frequently Asked Questions","title":"What are the differences between zero-dimensional arrays and scalars?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Zero-dimensional arrays are arrays of the form Array{T,0}. They behave similar to scalars, but there are important differences. They deserve a special mention because they are a special case which makes logical sense given the generic definition of arrays, but might be a bit unintuitive at first. The following line defines a zero-dimensional array:","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"julia> A = zeros()\n0-dimensional Array{Float64,0}:\n0.0","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In this example, A is a mutable container that contains one element, which can be set by A[] = 1.0 and retrieved with A[]. All zero-dimensional arrays have the same size (size(A) == ()), and length (length(A) == 1). In particular, zero-dimensional arrays are not empty. If you find this unintuitive, here are some ideas that might help to understand Julia's definition.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Zero-dimensional arrays are the \"point\" to vector's \"line\" and matrix's \"plane\". Just as a line has no area (but still represents a set of things), a point has no length or any dimensions at all (but still represents a thing).\nWe define prod(()) to be 1, and the total number of elements in an array is the product of the size. The size of a zero-dimensional array is (), and therefore its length is 1.\nZero-dimensional arrays don't natively have any dimensions into which you index – they’re just A[]. We can apply the same \"trailing one\" rule for them as for all other array dimensionalities, so you can indeed index them as A[1], A[1,1], etc; see Omitted and extra indices.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"It is also important to understand the differences to ordinary scalars. Scalars are not mutable containers (even though they are iterable and define things like length, getindex, e.g. 1[] == 1). In particular, if x = 0.0 is defined as a scalar, it is an error to attempt to change its value via x[] = 1.0. A scalar x can be converted into a zero-dimensional array containing it via fill(x), and conversely, a zero-dimensional array a can be converted to the contained scalar via a[]. Another difference is that a scalar can participate in linear algebra operations such as 2 * rand(2,2), but the analogous operation with a zero-dimensional array fill(2) * rand(2,2) is an error.","category":"page"},{"location":"manual/faq/#Why-are-my-Julia-benchmarks-for-linear-algebra-operations-different-from-other-languages?","page":"Frequently Asked Questions","title":"Why are my Julia benchmarks for linear algebra operations different from other languages?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You may find that simple benchmarks of linear algebra building blocks like","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using BenchmarkTools\nA = randn(1000, 1000)\nB = randn(1000, 1000)\n@btime $A \\ $B\n@btime $A * $B","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"can be different when compared to other languages like Matlab or R.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Since operations like this are very thin wrappers over the relevant BLAS functions, the reason for the discrepancy is very likely to be","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"the BLAS library each language is using,\nthe number of concurrent threads.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Julia compiles and uses its own copy of OpenBLAS, with threads currently capped at 8 (or the number of your cores).","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg Intel MKL, may provide performance improvements. You can use MKL.jl, a package that makes Julia's linear algebra use Intel MKL BLAS and LAPACK instead of OpenBLAS, or search the discussion forum for suggestions on how to set this up manually. Note that Intel MKL cannot be bundled with Julia, as it is not open source.","category":"page"},{"location":"manual/faq/#Computing-cluster","page":"Frequently Asked Questions","title":"Computing cluster","text":"","category":"section"},{"location":"manual/faq/#How-do-I-manage-precompilation-caches-in-distributed-file-systems?","page":"Frequently Asked Questions","title":"How do I manage precompilation caches in distributed file systems?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"When using Julia in high-performance computing (HPC) facilities with shared filesystems, it is recommended to use a shared depot (via the JULIA_DEPOT_PATH environment variable). Since Julia v1.10, multiple Julia processes on functionally similar workers and using the same depot will coordinate via pidfile locks to only spend effort precompiling on one process while the others wait. The precompilation process will indicate when the process is precompiling or waiting for another that is precompiling. If non-interactive the messages are via @debug.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"However, due to caching of binary code, the cache rejection since v1.9 is more strict and users may need to set the JULIA_CPU_TARGET environment variable appropriately to get a single cache that is usable throughout the HPC environment.","category":"page"},{"location":"manual/faq/#Julia-Releases","page":"Frequently Asked Questions","title":"Julia Releases","text":"","category":"section"},{"location":"manual/faq/#Do-I-want-to-use-the-Stable,-LTS,-or-nightly-version-of-Julia?","page":"Frequently Asked Questions","title":"Do I want to use the Stable, LTS, or nightly version of Julia?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The Stable version of Julia is the latest released version of Julia, this is the version most people will want to run. It has the latest features, including improved performance. The Stable version of Julia is versioned according to SemVer as v1.x.y. A new minor release of Julia corresponding to a new Stable version is made approximately every 4-5 months after a few weeks of testing as a release candidate. Unlike the LTS version the Stable version will not normally receive bugfixes after another Stable version of Julia has been released. However, upgrading to the next Stable release will always be possible as each release of Julia v1.x will continue to run code written for earlier versions.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You may prefer the LTS (Long Term Support) version of Julia if you are looking for a very stable code base. The current LTS version of Julia is versioned according to SemVer as v1.6.x; this branch will continue to receive bugfixes until a new LTS branch is chosen, at which point the v1.6.x series will no longer received regular bug fixes and all but the most conservative users will be advised to upgrade to the new LTS version series. As a package developer, you may prefer to develop for the LTS version, to maximize the number of users who can use your package. As per SemVer, code written for v1.0 will continue to work for all future LTS and Stable versions. In general, even if targeting the LTS, one can develop and run code in the latest Stable version, to take advantage of the improved performance; so long as one avoids using new features (such as added library functions or new methods).","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"You may prefer the nightly version of Julia if you want to take advantage of the latest updates to the language, and don't mind if the version available today occasionally doesn't actually work. As the name implies, releases to the nightly version are made roughly every night (depending on build infrastructure stability). In general nightly released are fairly safe to use—your code will not catch on fire. However, they may be occasional regressions and or issues that will not be found until more thorough pre-release testing. You may wish to test against the nightly version to ensure that such regressions that affect your use case are caught before a release is made.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Finally, you may also consider building Julia from source for yourself. This option is mainly for those individuals who are comfortable at the command line, or interested in learning. If this describes you, you may also be interested in reading our guidelines for contributing.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Links to each of these download types can be found on the download page at https://julialang.org/downloads/. Note that not all versions of Julia are available for all platforms.","category":"page"},{"location":"manual/faq/#How-can-I-transfer-the-list-of-installed-packages-after-updating-my-version-of-Julia?","page":"Frequently Asked Questions","title":"How can I transfer the list of installed packages after updating my version of Julia?","text":"","category":"section"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Each minor version of julia has its own default environment. As a result, upon installing a new minor version of Julia, the packages you added using the previous minor version will not be available by default. The environment for a given julia version is defined by the files Project.toml and Manifest.toml in a folder matching the version number in .julia/environments/, for instance, .julia/environments/v1.3.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If you install a new minor version of Julia, say 1.4, and want to use in its default environment the same packages as in a previous version (e.g. 1.3), you can copy the contents of the file Project.toml from the 1.3 folder to 1.4. Then, in a session of the new Julia version, enter the \"package management mode\" by typing the key ], and run the command instantiate.","category":"page"},{"location":"manual/faq/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"This operation will resolve a set of feasible packages from the copied file that are compatible with the target Julia version, and will install or update them if suitable. If you want to reproduce not only the set of packages, but also the versions you were using in the previous Julia version, you should also copy the Manifest.toml file before running the Pkg command instantiate. However, note that packages may define compatibility constraints that may be affected by changing the version of Julia, so the exact set of versions you had in 1.3 may not work for 1.4.","category":"page"},{"location":"devdocs/eval/#Eval-of-Julia-code","page":"Eval of Julia code","title":"Eval of Julia code","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"One of the hardest parts about learning how the Julia Language runs code is learning how all of the pieces work together to execute a block of code.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Each chunk of code typically makes a trip through many steps with potentially unfamiliar names, such as (in no particular order): flisp, AST, C++, LLVM, eval, typeinf, macroexpand, sysimg (or system image), bootstrapping, compile, parse, execute, JIT, interpret, box, unbox, intrinsic function, and primitive function, before turning into the desired result (hopefully).","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"sidebar: Definitions\nREPL\nREPL stands for Read-Eval-Print Loop. It's just what we call the command line environment for short.\nAST\nAbstract Syntax Tree The AST is the digital representation of the code structure. In this form the code has been tokenized for meaning so that it is more suitable for manipulation and execution.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"(Image: Diagram of the compiler flow)","category":"page"},{"location":"devdocs/eval/#Julia-Execution","page":"Eval of Julia code","title":"Julia Execution","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The 10,000 foot view of the whole process is as follows:","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The user starts julia.\nThe C function main() from cli/loader_exe.c gets called. This function processes the command line arguments, filling in the jl_options struct and setting the variable ARGS. It then initializes Julia (by calling julia_init in init.c, which may load a previously compiled sysimg). Finally, it passes off control to Julia by calling Base._start().\nWhen _start() takes over control, the subsequent sequence of commands depends on the command line arguments given. For example, if a filename was supplied, it will proceed to execute that file. Otherwise, it will start an interactive REPL.\nSkipping the details about how the REPL interacts with the user, let's just say the program ends up with a block of code that it wants to run.\nIf the block of code to run is in a file, jl_load(char *filename) gets invoked to load the file and parse it. Each fragment of code is then passed to eval to execute.\nEach fragment of code (or AST), is handed off to eval() to turn into results.\neval() takes each code fragment and tries to run it in jl_toplevel_eval_flex().\njl_toplevel_eval_flex() decides whether the code is a \"toplevel\" action (such as using or module), which would be invalid inside a function. If so, it passes off the code to the toplevel interpreter.\njl_toplevel_eval_flex() then expands the code to eliminate any macros and to \"lower\" the AST to make it simpler to execute.\njl_toplevel_eval_flex() then uses some simple heuristics to decide whether to JIT compile the AST or to interpret it directly.\nThe bulk of the work to interpret code is handled by eval in interpreter.c.\nIf instead, the code is compiled, the bulk of the work is handled by codegen.cpp. Whenever a Julia function is called for the first time with a given set of argument types, type inference will be run on that function. This information is used by the codegen step to generate faster code.\nEventually, the user quits the REPL, or the end of the program is reached, and the _start() method returns.\nJust before exiting, main() calls jl_atexit_hook(exit_code). This calls Base._atexit() (which calls any functions registered to atexit() inside Julia). Then it calls jl_gc_run_all_finalizers(). Finally, it gracefully cleans up all libuv handles and waits for them to flush and close.","category":"page"},{"location":"devdocs/eval/#dev-parsing","page":"Eval of Julia code","title":"Parsing","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The Julia parser is a small lisp program written in femtolisp, the source-code for which is distributed inside Julia in src/flisp.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The interface functions for this are primarily defined in jlfrontend.scm. The code in ast.c handles this handoff on the Julia side.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The other relevant files at this stage are julia-parser.scm, which handles tokenizing Julia code and turning it into an AST, and julia-syntax.scm, which handles transforming complex AST representations into simpler, \"lowered\" AST representations which are more suitable for analysis and execution.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"If you want to test the parser without re-building Julia in its entirety, you can run the frontend on its own as follows:","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"$ cd src\n$ flisp/flisp\n> (load \"jlfrontend.scm\")\n> (jl-parse-file \"\")","category":"page"},{"location":"devdocs/eval/#dev-macro-expansion","page":"Eval of Julia code","title":"Macro Expansion","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"When eval() encounters a macro, it expands that AST node before attempting to evaluate the expression. Macro expansion involves a handoff from eval() (in Julia), to the parser function jl_macroexpand() (written in flisp) to the Julia macro itself (written in - what else - Julia) via fl_invoke_julia_macro(), and back.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Typically, macro expansion is invoked as a first step during a call to Meta.lower()/jl_expand(), although it can also be invoked directly by a call to macroexpand()/jl_macroexpand().","category":"page"},{"location":"devdocs/eval/#dev-type-inference","page":"Eval of Julia code","title":"Type Inference","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Type inference is implemented in Julia by typeinf() in compiler/typeinfer.jl. Type inference is the process of examining a Julia function and determining bounds for the types of each of its variables, as well as bounds on the type of the return value from the function. This enables many future optimizations, such as unboxing of known immutable values, and compile-time hoisting of various run-time operations such as computing field offsets and function pointers. Type inference may also include other steps such as constant propagation and inlining.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"sidebar: More Definitions\nJIT\nJust-In-Time Compilation The process of generating native-machine code into memory right when it is needed.\nLLVM\nLow-Level Virtual Machine (a compiler) The Julia JIT compiler is a program/library called libLLVM. Codegen in Julia refers both to the process of taking a Julia AST and turning it into LLVM instructions, and the process of LLVM optimizing that and turning it into native assembly instructions.\nC++\nThe programming language that LLVM is implemented in, which means that codegen is also implemented in this language. The rest of Julia's library is implemented in C, in part because its smaller feature set makes it more usable as a cross-language interface layer.\nbox\nThis term is used to describe the process of taking a value and allocating a wrapper around the data that is tracked by the garbage collector (gc) and is tagged with the object's type.\nunbox\nThe reverse of boxing a value. This operation enables more efficient manipulation of data when the type of that data is fully known at compile-time (through type inference).\ngeneric function\nA Julia function composed of multiple \"methods\" that are selected for dynamic dispatch based on the argument type-signature\nanonymous function or \"method\"\nA Julia function without a name and without type-dispatch capabilities\nprimitive function\nA function implemented in C but exposed in Julia as a named function \"method\" (albeit without generic function dispatch capabilities, similar to a anonymous function)\nintrinsic function\nA low-level operation exposed as a function in Julia. These pseudo-functions implement operations on raw bits such as add and sign extend that cannot be expressed directly in any other way. Since they operate on bits directly, they must be compiled into a function and surrounded by a call to Core.Intrinsics.box(T, ...) to reassign type information to the value.","category":"page"},{"location":"devdocs/eval/#dev-codegen","page":"Eval of Julia code","title":"JIT Code Generation","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Codegen is the process of turning a Julia AST into native machine code.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The JIT environment is initialized by an early call to jl_init_codegen in codegen.cpp.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"On demand, a Julia method is converted into a native function by the function emit_function(jl_method_instance_t*). (note, when using the MCJIT (in LLVM v3.4+), each function must be JIT into a new module.) This function recursively calls emit_expr() until the entire function has been emitted.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Much of the remaining bulk of this file is devoted to various manual optimizations of specific code patterns. For example, emit_known_call() knows how to inline many of the primitive functions (defined in builtins.c) for various combinations of argument types.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"Other parts of codegen are handled by various helper files:","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"debuginfo.cpp\nHandles backtraces for JIT functions\nccall.cpp\nHandles the ccall and llvmcall FFI, along with various abi_*.cpp files\nintrinsics.cpp\nHandles the emission of various low-level intrinsic functions","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"sidebar: Bootstrapping\nThe process of creating a new system image is called \"bootstrapping\".The etymology of this word comes from the phrase \"pulling oneself up by the bootstraps\", and refers to the idea of starting from a very limited set of available functions and definitions and ending with the creation of a full-featured environment.","category":"page"},{"location":"devdocs/eval/#dev-sysimg","page":"Eval of Julia code","title":"System Image","text":"","category":"section"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"The system image is a precompiled archive of a set of Julia files. The sys.ji file distributed with Julia is one such system image, generated by executing the file sysimg.jl, and serializing the resulting environment (including Types, Functions, Modules, and all other defined values) into a file. Therefore, it contains a frozen version of the Main, Core, and Base modules (and whatever else was in the environment at the end of bootstrapping). This serializer/deserializer is implemented by jl_save_system_image/jl_restore_system_image in staticdata.c.","category":"page"},{"location":"devdocs/eval/","page":"Eval of Julia code","title":"Eval of Julia code","text":"If there is no sysimg file (jl_options.image_file == NULL), this also implies that --build was given on the command line, so the final result should be a new sysimg file. During Julia initialization, minimal Core and Main modules are created. Then a file named boot.jl is evaluated from the current directory. Julia then evaluates any file given as a command line argument until it reaches the end. Finally, it saves the resulting environment to a \"sysimg\" file for use as a starting point for a future Julia run.","category":"page"},{"location":"devdocs/gc-sa/#Static-analyzer-annotations-for-GC-correctness-in-C-code","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"","category":"section"},{"location":"devdocs/gc-sa/#Running-the-analysis","page":"Static analyzer annotations for GC correctness in C code","title":"Running the analysis","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The analyzer plugin that drives the analysis ships with julia. Its source code can be found in src/clangsa. Running it requires the clang dependency to be build. Set the BUILD_LLVM_CLANG variable in your Make.user in order to build an appropriate version of clang. You may also want to use the prebuilt binaries using the USE_BINARYBUILDER_LLVM options.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Alternatively (or if these do not suffice), try","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"make -C src install-analysis-deps","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"from Julia's toplevel directory.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Afterwards, running the analysis over the source tree is as simple as running make -C src analyzegc.","category":"page"},{"location":"devdocs/gc-sa/#General-Overview","page":"Static analyzer annotations for GC correctness in C code","title":"General Overview","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Since Julia's GC is precise, it needs to maintain correct rooting information for any value that may be referenced at any time GC may occur. These places are known as safepoints and in the function local context, we extend this designation to any function call that may recursively end up at a safepoint.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"In generated code, this is taken care of automatically by the GC root placement pass (see the chapter on GC rooting in the LLVM codegen devdocs). However, in C code, we need to inform the runtime of any GC roots manually. This is done using the following macros:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"// The value assigned to any slot passed as an argument to these\n// is rooted for the duration of this GC frame.\nJL_GC_PUSH{1,...,6}(args...)\n// The values assigned into the size `n` array `rts` are rooted\n// for the duration of this GC frame.\nJL_GC_PUSHARGS(rts, n)\n// Pop a GC frame\nJL_GC_POP","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"If these macros are not used where they need to be, or they are used incorrectly, the result is silent memory corruption. As such it is very important that they are placed correctly in all applicable code.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"As such, we employ static analysis (and in particular the clang static analyzer) to help ensure that these macros are used correctly. The remainder of this document gives an overview of this static analysis and describes the support needed in the julia code base to make things work.","category":"page"},{"location":"devdocs/gc-sa/#GC-Invariants","page":"Static analyzer annotations for GC correctness in C code","title":"GC Invariants","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"There is two simple invariants correctness:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"All GC_PUSH calls need to be followed by an appropriate GC_POP (in practice we enforce this at the function level)\nIf a value was previously not rooted at any safepoint, it may no longer be referenced afterwards","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Of course the devil is in the details here. In particular to satisfy the second of the above conditions, we need to know:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Which calls are safepoints and which are not\nWhich values are rooted at any given safepoint and which are not\nWhen is a value referenced","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"For the second point in particular, we need to know which memory locations will be considered rooting at runtime (i.e. values assigned to such locations are rooted). This includes locations explicitly designated as such by passing them to one of the GC_PUSH macros, globally rooted locations and values, as well as any location recursively reachable from one of those locations.","category":"page"},{"location":"devdocs/gc-sa/#Static-Analysis-Algorithm","page":"Static analyzer annotations for GC correctness in C code","title":"Static Analysis Algorithm","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The idea itself is very simple, although the implementation is quite a bit more complicated (mainly due to a large number of special cases and intricacies of C and C++). In essence, we keep track of all locations that are rooting, all values that are rootable and any expression (assignments, allocations, etc) affect the rootedness of any rootable values. Then, at any safepoint, we perform a \"symbolic GC\" and poison any values that are not rooted at said location. If these values are later referenced, we emit an error.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The clang static analyzer works by constructing a graph of states and exploring this graph for sources of errors. Several nodes in this graph are generated by the analyzer itself (e.g. for control flow), but the definitions above augment this graph with our own state.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The static analyzer is interprocedural and can analyze control flow across function boundaries. However, the static analyzer is not fully recursive and makes heuristic decisions about which calls to explore (additionally some calls are cross-translation unit and invisible to the analyzer). In our case, our definition of correctness requires total information. As such, we need to annotate the prototypes of all function calls with whatever information the analysis required, even if that information would otherwise be available by interprocedural static analysis.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Luckily however, we can still use this interprocedural analysis to ensure that the annotations we place on a given function are indeed correct given the implementation of said function.","category":"page"},{"location":"devdocs/gc-sa/#The-analyzer-annotations","page":"Static analyzer annotations for GC correctness in C code","title":"The analyzer annotations","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"These annotations are found in src/support/analyzer_annotations.h. The are only active when the analyzer is being used and expand either to nothing (for prototype annotations) or to no-ops (for function like annotations).","category":"page"},{"location":"devdocs/gc-sa/#JL_NOTSAFEPOINT","page":"Static analyzer annotations for GC correctness in C code","title":"JL_NOTSAFEPOINT","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This is perhaps the most common annotation, and should be placed on any function that is known not to possibly lead to reaching a GC safepoint. In general, it is only safe for such a function to perform arithmetic, memory accesses and calls to functions either annotated JL_NOTSAFEPOINT or otherwise known not to be safepoints (e.g. function in the C standard library, which are hardcoded as such in the analyzer)","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"It is valid to keep values unrooted across calls to any function annotated with this attribute:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage Example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void jl_get_one() JL_NOTSAFEPOINT {\n return 1;\n}\n\njl_value_t *example() {\n jl_value_t *val = jl_alloc_whatever();\n // This is valid, even though `val` is unrooted, because\n // jl_get_one is not a safepoint\n jl_get_one();\n return val;\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY","page":"Static analyzer annotations for GC correctness in C code","title":"JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"When JL_MAYBE_UNROOTED is annotated as an argument on a function, indicates that said argument may be passed, even if it is not rooted. In the ordinary course of events, the julia ABI guarantees that callers root values before passing them to callees. However, some functions do not follow this ABI and allow values to be passed to them even though they are not rooted. Note however, that this does not automatically imply that said argument will be preserved. The ROOTS_TEMPORARILY annotation provides the stronger guarantee that, not only may the value be unrooted when passed, it will also be preserved across any internal safepoints by the callee.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Note that JL_NOTSAFEPOINT essentially implies JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY, because the rootedness of an argument is irrelevant if the function contains no safepoints.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"One additional point to note is that these annotations apply on both the caller and the callee side. On the caller side, they lift rootedness restrictions that are normally required for julia ABI functions. On the callee side, they have the reverse effect of preventing these arguments from being considered implicitly rooted.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"If either of these annotations is applied to the function as a whole, it applies to all arguments of the function. This should generally only be necessary for varargs functions.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"JL_DLLEXPORT void JL_NORETURN jl_throw(jl_value_t *e JL_MAYBE_UNROOTED);\njl_value_t *jl_alloc_error();\n\nvoid example() {\n // The return value of the allocation is unrooted. This would normally\n // be an error, but is allowed because of the above annotation.\n jl_throw(jl_alloc_error());\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_PROPAGATES_ROOT","page":"Static analyzer annotations for GC correctness in C code","title":"JL_PROPAGATES_ROOT","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotation is commonly found on accessor functions that return one rootable object stored within another. When annotated on a function argument, it tells the analyzer that the root for that argument also applies to the value returned by the function.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage Example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"jl_value_t *jl_svecref(jl_svec_t *t JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT;\n\nsize_t example(jl_svec_t *svec) {\n jl_value_t *val = jl_svecref(svec, 1)\n // This is valid, because, as annotated by the PROPAGATES_ROOT annotation,\n // jl_svecref propagates the rooted-ness from `svec` to `val`\n jl_gc_safepoint();\n return jl_unbox_long(val);\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_ROOTING_ARGUMENT/JL_ROOTED_ARGUMENT","page":"Static analyzer annotations for GC correctness in C code","title":"JL_ROOTING_ARGUMENT/JL_ROOTED_ARGUMENT","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This is essentially the assignment counterpart to JL_PROPAGATES_ROOT. When assigning a value to a field of another value that is already rooted, the assigned value will inherit the root of the value it is assigned into.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage Example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void jl_svecset(void *t JL_ROOTING_ARGUMENT, size_t i, void *x JL_ROOTED_ARGUMENT) JL_NOTSAFEPOINT\n\n\nsize_t example(jl_svec_t *svec) {\n jl_value_t *val = jl_box_long(10000);\n jl_svecset(svec, val);\n // This is valid, because the annotations imply that the\n // jl_svecset propagates the rooted-ness from `svec` to `val`\n jl_gc_safepoint();\n return jl_unbox_long(val);\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_GC_DISABLED","page":"Static analyzer annotations for GC correctness in C code","title":"JL_GC_DISABLED","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotation implies that this function is only called with the GC runtime-disabled. Functions of this kind are most often encountered during startup and in the GC code itself. Note that this annotation is checked against the runtime enable/disable calls, so clang will know if you lie. This is not a good way to disable processing of a given function if the GC is not actually disabled (use ifdef __clang_analyzer__ for that if you must).","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void jl_do_magic() JL_GC_DISABLED {\n // Wildly allocate here with no regard for roots\n}\n\nvoid example() {\n int en = jl_gc_enable(0);\n jl_do_magic();\n jl_gc_enable(en);\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_REQUIRE_ROOTED_SLOT","page":"Static analyzer annotations for GC correctness in C code","title":"JL_REQUIRE_ROOTED_SLOT","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotation requires the caller to pass in a slot that is rooted (i.e. values assigned to this slot will be rooted).","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void jl_do_processing(jl_value_t **slot JL_REQUIRE_ROOTED_SLOT) {\n *slot = jl_box_long(1);\n // Ok, only, because the slot was annotated as rooting\n jl_gc_safepoint();\n}\n\nvoid example() {\n jl_value_t *slot = NULL;\n JL_GC_PUSH1(&slot);\n jl_do_processing(&slot);\n JL_GC_POP();\n}","category":"page"},{"location":"devdocs/gc-sa/#JL_GLOBALLY_ROOTED","page":"Static analyzer annotations for GC correctness in C code","title":"JL_GLOBALLY_ROOTED","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotation implies that a given value is always globally rooted. It can be applied to global variable declarations, in which case it will apply to the value of those variables (or values if the declaration if for an array), or to functions, in which case it will apply to the return value of such functions (e.g. for functions that always return some private, globally rooted value).","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"Usage example:","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"extern JL_DLLEXPORT jl_datatype_t *jl_any_type JL_GLOBALLY_ROOTED;\njl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED;","category":"page"},{"location":"devdocs/gc-sa/#JL_ALWAYS_LEAFTYPE","page":"Static analyzer annotations for GC correctness in C code","title":"JL_ALWAYS_LEAFTYPE","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that is should only be used if those values are globally rooted by virtue of being a leaftype. The rooting of leaftypes is a bit complicated. They are generally rooted through cache field of the corresponding TypeName, which itself is rooted by the containing module (so they're rooted as long as the containing module is ok) and we can generally assume that leaftypes are rooted where they are used, but we may refine this property in the future, so the separate annotation helps split out the reason for being globally rooted.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The analyzer also automatically detects checks for leaftype-ness and will not complain about missing GC roots on these paths.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"JL_DLLEXPORT jl_value_t *jl_apply_array_type(jl_value_t *type, size_t dim) JL_ALWAYS_LEAFTYPE;","category":"page"},{"location":"devdocs/gc-sa/#JL_GC_PROMISE_ROOTED","page":"Static analyzer annotations for GC correctness in C code","title":"JL_GC_PROMISE_ROOTED","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"This is a function-like annotation. Any value passed to this annotation will be considered rooted for the scope of the current function. It is designed as an escape hatch for analyzer inadequacy or complicated situations. However, it should be used sparingly, in favor of improving the analyzer itself.","category":"page"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"void example() {\n jl_value_t *val = jl_alloc_something();\n if (some_condition) {\n // We happen to know for complicated external reasons\n // that val is rooted under these conditions\n JL_GC_PROMISE_ROOTED(val);\n }\n}","category":"page"},{"location":"devdocs/gc-sa/#Completeness-of-analysis","page":"Static analyzer annotations for GC correctness in C code","title":"Completeness of analysis","text":"","category":"section"},{"location":"devdocs/gc-sa/","page":"Static analyzer annotations for GC correctness in C code","title":"Static analyzer annotations for GC correctness in C code","text":"The analyzer only looks at local information. In particular, e.g. in the PROPAGATES_ROOT case above, it assumes that such memory is only modified in ways it can see, not in any called functions (unless it happens to decide to consider them in its analysis) and not in any concurrently running threads. As such, it may miss a few problematic cases, though in practice such concurrent modification is fairly rare. Improving the analyzer to handle more such cases may be an interesting topic for future work.","category":"page"},{"location":"devdocs/llvm/#Working-with-LLVM","page":"Working with LLVM","title":"Working with LLVM","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"This is not a replacement for the LLVM documentation, but a collection of tips for working on LLVM for Julia.","category":"page"},{"location":"devdocs/llvm/#Overview-of-Julia-to-LLVM-Interface","page":"Working with LLVM","title":"Overview of Julia to LLVM Interface","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Julia dynamically links against LLVM by default. Build with USE_LLVM_SHLIB=0 to link statically.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The code for lowering Julia AST to LLVM IR or interpreting it directly is in directory src/.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"File Description\naotcompile.cpp Compiler C-interface entry and object file emission\nbuiltins.c Builtin functions\nccall.cpp Lowering ccall\ncgutils.cpp Lowering utilities, notably for array and tuple accesses\ncodegen.cpp Top-level of code generation, pass list, lowering builtins\ndebuginfo.cpp Tracks debug information for JIT code\ndisasm.cpp Handles native object file and JIT code diassembly\ngf.c Generic functions\nintrinsics.cpp Lowering intrinsics\njitlayers.cpp JIT-specific code, ORC compilation layers/utilities\nllvm-alloc-helpers.cpp Julia-specific escape analysis\nllvm-alloc-opt.cpp Custom LLVM pass to demote heap allocations to the stack\nllvm-cpufeatures.cpp Custom LLVM pass to lower CPU-based functions (e.g. haveFMA)\nllvm-demote-float16.cpp Custom LLVM pass to lower 16b float ops to 32b float ops\nllvm-final-gc-lowering.cpp Custom LLVM pass to lower GC calls to their final form\nllvm-gc-invariant-verifier.cpp Custom LLVM pass to verify Julia GC invariants\nllvm-julia-licm.cpp Custom LLVM pass to hoist/sink Julia-specific intrinsics\nllvm-late-gc-lowering.cpp Custom LLVM pass to root GC-tracked values\nllvm-lower-handlers.cpp Custom LLVM pass to lower try-catch blocks\nllvm-muladd.cpp Custom LLVM pass for fast-match FMA\nllvm-multiversioning.cpp Custom LLVM pass to generate sysimg code on multiple architectures\nllvm-propagate-addrspaces.cpp Custom LLVM pass to canonicalize addrspaces\nllvm-ptls.cpp Custom LLVM pass to lower TLS operations\nllvm-remove-addrspaces.cpp Custom LLVM pass to remove Julia addrspaces\nllvm-remove-ni.cpp Custom LLVM pass to remove Julia non-integral addrspaces\nllvm-simdloop.cpp Custom LLVM pass for @simd\npipeline.cpp New pass manager pipeline, pass pipeline parsing\nsys.c I/O and operating system utility functions","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Some of the .cpp files form a group that compile to a single object.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The difference between an intrinsic and a builtin is that a builtin is a first class function that can be used like any other Julia function. An intrinsic can operate only on unboxed data, and therefore its arguments must be statically typed.","category":"page"},{"location":"devdocs/llvm/#LLVM-Alias-Analysis","page":"Working with LLVM","title":"Alias Analysis","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Julia currently uses LLVM's Type Based Alias Analysis. To find the comments that document the inclusion relationships, look for static MDNode* in src/codegen.cpp.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The -O option enables LLVM's Basic Alias Analysis.","category":"page"},{"location":"devdocs/llvm/#Building-Julia-with-a-different-version-of-LLVM","page":"Working with LLVM","title":"Building Julia with a different version of LLVM","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The default version of LLVM is specified in deps/llvm.version. You can override it by creating a file called Make.user in the top-level directory and adding a line to it such as:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"LLVM_VER = 13.0.0","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Besides the LLVM release numerals, you can also use DEPS_GIT = llvm in combination with USE_BINARYBUILDER_LLVM = 0 to build against the latest development version of LLVM.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"You can also specify to build a debug version of LLVM, by setting either LLVM_DEBUG = 1 or LLVM_DEBUG = Release in your Make.user file. The former will be a fully unoptimized build of LLVM and the latter will produce an optimized build of LLVM. Depending on your needs the latter will suffice and it quite a bit faster. If you use LLVM_DEBUG = Release you will also want to set LLVM_ASSERTIONS = 1 to enable diagnostics for different passes. Only LLVM_DEBUG = 1 implies that option by default.","category":"page"},{"location":"devdocs/llvm/#Passing-options-to-LLVM","page":"Working with LLVM","title":"Passing options to LLVM","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"You can pass options to LLVM via the environment variable JULIA_LLVM_ARGS. Here are example settings using bash syntax:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"export JULIA_LLVM_ARGS=-print-after-all dumps IR after each pass.\nexport JULIA_LLVM_ARGS=-debug-only=loop-vectorize dumps LLVM DEBUG(...) diagnostics for loop vectorizer. If you get warnings about \"Unknown command line argument\", rebuild LLVM with LLVM_ASSERTIONS = 1.\nexport JULIA_LLVM_ARGS=-help shows a list of available options. export JULIA_LLVM_ARGS=-help-hidden shows even more.\nexport JULIA_LLVM_ARGS=\"-fatal-warnings -print-options\" is an example how to use multiple options.","category":"page"},{"location":"devdocs/llvm/#Useful-JULIA_LLVM_ARGS-parameters","page":"Working with LLVM","title":"Useful JULIA_LLVM_ARGS parameters","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"-print-after=PASS: prints the IR after any execution of PASS, useful for checking changes done by a pass.\n-print-before=PASS: prints the IR before any execution of PASS, useful for checking the input to a pass.\n-print-changed: prints the IR whenever a pass changes the IR, useful for narrowing down which passes are causing problems.\n-print-(before|after)=MARKER-PASS: the Julia pipeline ships with a number of marker passes in the pipeline, which can be used to identify where problems or optimizations are occurring. A marker pass is defined as a pass which appears once in the pipeline and performs no transformations on the IR, and is only useful for targeting print-before/print-after. Currently, the following marker passes exist in the pipeline:\nBeforeOptimization\nBeforeEarlySimplification\nAfterEarlySimplification\nBeforeEarlyOptimization\nAfterEarlyOptimization\nBeforeLoopOptimization\nBeforeLICM\nAfterLICM\nBeforeLoopSimplification\nAfterLoopSimplification\nAfterLoopOptimization\nBeforeScalarOptimization\nAfterScalarOptimization\nBeforeVectorization\nAfterVectorization\nBeforeIntrinsicLowering\nAfterIntrinsicLowering\nBeforeCleanup\nAfterCleanup\nAfterOptimization\n-time-passes: prints the time spent in each pass, useful for identifying which passes are taking a long time.\n-print-module-scope: used in conjunction with -print-(before|after), gets the entire module rather than the IR unit received by the pass\n-debug: prints out a lot of debugging information throughout LLVM\n-debug-only=NAME, prints out debugging statements from files with DEBUG_TYPE defined to NAME, useful for getting additional context about a problem","category":"page"},{"location":"devdocs/llvm/#Debugging-LLVM-transformations-in-isolation","page":"Working with LLVM","title":"Debugging LLVM transformations in isolation","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"On occasion, it can be useful to debug LLVM's transformations in isolation from the rest of the Julia system, e.g. because reproducing the issue inside julia would take too long, or because one wants to take advantage of LLVM's tooling (e.g. bugpoint).","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"To start with, you can install the developer tools to work with LLVM via:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"make -C deps install-llvm-tools","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"To get unoptimized IR for the entire system image, pass the --output-unopt-bc unopt.bc option to the system image build process, which will output the unoptimized IR to an unopt.bc file. This file can then be passed to LLVM tools as usual. libjulia can function as an LLVM pass plugin and can be loaded into LLVM tools, to make julia-specific passes available in this environment. In addition, it exposes the -julia meta-pass, which runs the entire Julia pass-pipeline over the IR. As an example, to generate a system image with the old pass manager, one could do:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"\nllc -o sys.o opt.bc\ncc -shared -o sys.so sys.o","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"To generate a system image with the new pass manager, one could do:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"opt -load-pass-plugin=libjulia-codegen.so --passes='julia' -o opt.bc unopt.bc\nllc -o sys.o opt.bc\ncc -shared -o sys.so sys.o","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"This system image can then be loaded by julia as usual.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"It is also possible to dump an LLVM IR module for just one Julia function, using:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"fun, T = +, Tuple{Int,Int} # Substitute your function of interest here\noptimize = false\nopen(\"plus.ll\", \"w\") do file\n println(file, InteractiveUtils._dump_function(fun, T, false, false, false, true, :att, optimize, :default, false))\nend","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"These files can be processed the same way as the unoptimized sysimg IR shown above.","category":"page"},{"location":"devdocs/llvm/#Running-the-LLVM-test-suite","page":"Working with LLVM","title":"Running the LLVM test suite","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"To run the llvm tests locally, you need to first install the tools, build julia, then you can run the tests:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"make -C deps install-llvm-tools\nmake -j julia-src-release\nmake -C test/llvmpasses","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"If you want to run the individual test files directly, via the commands at the top of each test file, the first step here will have installed the tools into ./usr/tools/opt. Then you'll want to manually replace %s with the name of the test file.","category":"page"},{"location":"devdocs/llvm/#Improving-LLVM-optimizations-for-Julia","page":"Working with LLVM","title":"Improving LLVM optimizations for Julia","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Improving LLVM code generation usually involves either changing Julia lowering to be more friendly to LLVM's passes, or improving a pass.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"If you are planning to improve a pass, be sure to read the LLVM developer policy. The best strategy is to create a code example in a form where you can use LLVM's opt tool to study it and the pass of interest in isolation.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Create an example Julia code of interest.\nUse JULIA_LLVM_ARGS=-print-after-all to dump the IR.\nPick out the IR at the point just before the pass of interest runs.\nStrip the debug metadata and fix up the TBAA metadata by hand.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The last step is labor intensive. Suggestions on a better way would be appreciated.","category":"page"},{"location":"devdocs/llvm/#The-jlcall-calling-convention","page":"Working with LLVM","title":"The jlcall calling convention","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Julia has a generic calling convention for unoptimized code, which looks somewhat as follows:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"jl_value_t *any_unoptimized_call(jl_value_t *, jl_value_t **, int);","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"where the first argument is the boxed function object, the second argument is an on-stack array of arguments and the third is the number of arguments. Now, we could perform a straightforward lowering and emit an alloca for the argument array. However, this would betray the SSA nature of the uses at the call site, making optimizations (including GC root placement), significantly harder. Instead, we emit it as follows:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"call %jl_value_t *@julia.call(jl_value_t *(*)(...) @any_unoptimized_call, %jl_value_t *%arg1, %jl_value_t *%arg2)","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"This allows us to retain the SSA-ness of the uses throughout the optimizer. GC root placement will later lower this call to the original C ABI.","category":"page"},{"location":"devdocs/llvm/#GC-root-placement","page":"Working with LLVM","title":"GC root placement","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"GC root placement is done by an LLVM pass late in the pass pipeline. Doing GC root placement this late enables LLVM to make more aggressive optimizations around code that requires GC roots, as well as allowing us to reduce the number of required GC roots and GC root store operations (since LLVM doesn't understand our GC, it wouldn't otherwise know what it is and is not allowed to do with values stored to the GC frame, so it'll conservatively do very little). As an example, consider an error path","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"if some_condition()\n #= Use some variables maybe =#\n error(\"An error occurred\")\nend","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"During constant folding, LLVM may discover that the condition is always false, and can remove the basic block. However, if GC root lowering is done early, the GC root slots used in the deleted block, as well as any values kept alive in those slots only because they were used in the error path, would be kept alive by LLVM. By doing GC root lowering late, we give LLVM the license to do any of its usual optimizations (constant folding, dead code elimination, etc.), without having to worry (too much) about which values may or may not be GC tracked.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"However, in order to be able to do late GC root placement, we need to be able to identify a) which pointers are GC tracked and b) all uses of such pointers. The goal of the GC placement pass is thus simple:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Minimize the number of needed GC roots/stores to them subject to the constraint that at every safepoint, any live GC-tracked pointer (i.e. for which there is a path after this point that contains a use of this pointer) is in some GC slot.","category":"page"},{"location":"devdocs/llvm/#Representation","page":"Working with LLVM","title":"Representation","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The primary difficulty is thus choosing an IR representation that allows us to identify GC-tracked pointers and their uses, even after the program has been run through the optimizer. Our design makes use of three LLVM features to achieve this:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Custom address spaces\nOperand Bundles\nNon-integral pointers","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Custom address spaces allow us to tag every point with an integer that needs to be preserved through optimizations. The compiler may not insert casts between address spaces that did not exist in the original program and it must never change the address space of a pointer on a load/store/etc operation. This allows us to annotate which pointers are GC-tracked in an optimizer-resistant way. Note that metadata would not be able to achieve the same purpose. Metadata is supposed to always be discardable without altering the semantics of the program. However, failing to identify a GC-tracked pointer alters the resulting program behavior dramatically - it'll probably crash or return wrong results. We currently use three different address spaces (their numbers are defined in src/codegen_shared.cpp):","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"GC Tracked Pointers (currently 10): These are pointers to boxed values that may be put into a GC frame. It is loosely equivalent to a jl_value_t* pointer on the C side. N.B. It is illegal to ever have a pointer in this address space that may not be stored to a GC slot.\nDerived Pointers (currently 11): These are pointers that are derived from some GC tracked pointer. Uses of these pointers generate uses of the original pointer. However, they need not themselves be known to the GC. The GC root placement pass MUST always find the GC tracked pointer from which this pointer is derived and use that as the pointer to root.\nCallee Rooted Pointers (currently 12): This is a utility address space to express the notion of a callee rooted value. All values of this address space MUST be storable to a GC root (though it is possible to relax this condition in the future), but unlike the other pointers need not be rooted if passed to a call (they do still need to be rooted if they are live across another safepoint between the definition and the call).\nPointers loaded from tracked object (currently 13): This is used by arrays, which themselves contain a pointer to the managed data. This data area is owned by the array, but is not a GC-tracked object by itself. The compiler guarantees that as long as this pointer is live, the object that this pointer was loaded from will keep being live.","category":"page"},{"location":"devdocs/llvm/#Invariants","page":"Working with LLVM","title":"Invariants","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The GC root placement pass makes use of several invariants, which need to be observed by the frontend and are preserved by the optimizer.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"First, only the following address space casts are allowed:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"0->{Tracked,Derived,CalleeRooted}: It is allowable to decay an untracked pointer to any of the others. However, do note that the optimizer has broad license to not root such a value. It is never safe to have a value in address space 0 in any part of the program if it is (or is derived from) a value that requires a GC root.\nTracked->Derived: This is the standard decay route for interior values. The placement pass will look for these to identify the base pointer for any use.\nTracked->CalleeRooted: Addrspace CalleeRooted serves merely as a hint that a GC root is not required. However, do note that the Derived->CalleeRooted decay is prohibited, since pointers should generally be storable to a GC slot, even in this address space.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Now let us consider what constitutes a use:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Loads whose loaded values is in one of the address spaces\nStores of a value in one of the address spaces to a location\nStores to a pointer in one of the address spaces\nCalls for which a value in one of the address spaces is an operand\nCalls in jlcall ABI, for which the argument array contains a value\nReturn instructions.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"We explicitly allow load/stores and simple calls in address spaces Tracked/Derived. Elements of jlcall argument arrays must always be in address space Tracked (it is required by the ABI that they are valid jl_value_t* pointers). The same is true for return instructions (though note that struct return arguments are allowed to have any of the address spaces). The only allowable use of an address space CalleeRooted pointer is to pass it to a call (which must have an appropriately typed operand).","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Further, we disallow getelementptr in addrspace Tracked. This is because unless the operation is a noop, the resulting pointer will not be validly storable to a GC slot and may thus not be in this address space. If such a pointer is required, it should be decayed to addrspace Derived first.","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"Lastly, we disallow inttoptr/ptrtoint instructions in these address spaces. Having these instructions would mean that some i64 values are really GC tracked. This is problematic, because it breaks that stated requirement that we're able to identify GC-relevant pointers. This invariant is accomplished using the LLVM \"non-integral pointers\" feature, which is new in LLVM 5.0. It prohibits the optimizer from making optimizations that would introduce these operations. Note we can still insert static constants at JIT time by using inttoptr in address space 0 and then decaying to the appropriate address space afterwards.","category":"page"},{"location":"devdocs/llvm/#Supporting-[ccall](@ref)","page":"Working with LLVM","title":"Supporting ccall","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"One important aspect missing from the discussion so far is the handling of ccall. ccall has the peculiar feature that the location and scope of a use do not coincide. As an example consider:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"A = randn(1024)\nccall(:foo, Cvoid, (Ptr{Float64},), A)","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"In lowering, the compiler will insert a conversion from the array to the pointer which drops the reference to the array value. However, we of course need to make sure that the array does stay alive while we're doing the ccall. To understand how this is done, lets look at a hypothetical approximate possible lowering of the above code:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"return $(Expr(:foreigncall, :(:foo), Cvoid, svec(Ptr{Float64}), 0, :(:ccall), Expr(:foreigncall, :(:jl_array_ptr), Ptr{Float64}, svec(Any), 0, :(:ccall), :(A)), :(A)))","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The last :(A), is an extra argument list inserted during lowering that informs the code generator which Julia level values need to be kept alive for the duration of this ccall. We then take this information and represent it in an \"operand bundle\" at the IR level. An operand bundle is essentially a fake use that is attached to the call site. At the IR level, this looks like so:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"call void inttoptr (i64 ... to void (double*)*)(double* %5) [ \"jl_roots\"(%jl_value_t addrspace(10)* %A) ]","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"The GC root placement pass will treat the jl_roots operand bundle as if it were a regular operand. However, as a final step, after the GC roots are inserted, it will drop the operand bundle to avoid confusing instruction selection.","category":"page"},{"location":"devdocs/llvm/#Supporting-[pointer_from_objref](@ref)","page":"Working with LLVM","title":"Supporting pointer_from_objref","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"pointer_from_objref is special because it requires the user to take explicit control of GC rooting. By our above invariants, this function is illegal, because it performs an address space cast from 10 to 0. However, it can be useful, in certain situations, so we provide a special intrinsic:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"declared %jl_value_t *julia.pointer_from_objref(%jl_value_t addrspace(10)*)","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"which is lowered to the corresponding address space cast after GC root lowering. Do note however that by using this intrinsic, the caller assumes all responsibility for making sure that the value in question is rooted. Further this intrinsic is not considered a use, so the GC root placement pass will not provide a GC root for the function. As a result, the external rooting must be arranged while the value is still tracked by the system. I.e. it is not valid to attempt to use the result of this operation to establish a global root - the optimizer may have already dropped the value.","category":"page"},{"location":"devdocs/llvm/#Keeping-values-alive-in-the-absence-of-uses","page":"Working with LLVM","title":"Keeping values alive in the absence of uses","text":"","category":"section"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"In certain cases it is necessary to keep an object alive, even though there is no compiler-visible use of said object. This may be case for low level code that operates on the memory-representation of an object directly or code that needs to interface with C code. In order to allow this, we provide the following intrinsics at the LLVM level:","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"token @llvm.julia.gc_preserve_begin(...)\nvoid @llvm.julia.gc_preserve_end(token)","category":"page"},{"location":"devdocs/llvm/","page":"Working with LLVM","title":"Working with LLVM","text":"(The llvm. in the name is required in order to be able to use the token type). The semantics of these intrinsics are as follows: At any safepoint that is dominated by a gc_preserve_begin call, but that is not not dominated by a corresponding gc_preserve_end call (i.e. a call whose argument is the token returned by a gc_preserve_begin call), the values passed as arguments to that gc_preserve_begin will be kept live. Note that the gc_preserve_begin still counts as a regular use of those values, so the standard lifetime semantics will ensure that the values will be kept alive before entering the preserve region.","category":"page"},{"location":"manual/variables-and-scoping/#scope-of-variables","page":"Scope of Variables","title":"Scope of Variables","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The scope of a variable is the region of code within which a variable is accessible. Variable scoping helps avoid variable naming conflicts. The concept is intuitive: two functions can both have arguments called x without the two x's referring to the same thing. Similarly, there are many other cases where different blocks of code can use the same name without referring to the same thing. The rules for when the same variable name does or doesn't refer to the same thing are called scope rules; this section spells them out in detail.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Certain constructs in the language introduce scope blocks, which are regions of code that are eligible to be the scope of some set of variables. The scope of a variable cannot be an arbitrary set of source lines; instead, it will always line up with one of these blocks. There are two main types of scopes in Julia, global scope and local scope. The latter can be nested. There is also a distinction in Julia between constructs which introduce a \"hard scope\" and those which only introduce a \"soft scope\", which affects whether shadowing a global variable by the same name is allowed or not.","category":"page"},{"location":"manual/variables-and-scoping/#man-scope-table","page":"Scope of Variables","title":"Scope constructs","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The constructs introducing scope blocks are:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Construct Scope type Allowed within\nmodule, baremodule global global\nstruct local (soft) global\nfor, while, try local (soft) global, local\nmacro local (hard) global\nfunctions, do blocks, let blocks, comprehensions, generators local (hard) global, local","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Notably missing from this table are begin blocks and if blocks which do not introduce new scopes. The three types of scopes follow somewhat different rules which will be explained below.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Julia uses lexical scoping, meaning that a function's scope does not inherit from its caller's scope, but from the scope in which the function was defined. For example, in the following code the x inside foo refers to the x in the global scope of its module Bar:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> module Bar\n x = 1\n foo() = x\n end;","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"and not a x in the scope where foo is used:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> import .Bar\n\njulia> x = -1;\n\njulia> Bar.foo()\n1","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Thus lexical scope means that what a variable in a particular piece of code refers to can be deduced from the code in which it appears alone and does not depend on how the program executes. A scope nested inside another scope can \"see\" variables in all the outer scopes in which it is contained. Outer scopes, on the other hand, cannot see variables in inner scopes.","category":"page"},{"location":"manual/variables-and-scoping/#Global-Scope","page":"Scope of Variables","title":"Global Scope","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Each module introduces a new global scope, separate from the global scope of all other modules—there is no all-encompassing global scope. Modules can introduce variables of other modules into their scope through the using or import statements or through qualified access using the dot-notation, i.e. each module is a so-called namespace as well as a first-class data structure associating names with values.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"If a top-level expression contains a variable declaration with keyword local, then that variable is not accessible outside that expression. The variable inside the expression does not affect global variables of the same name. An example is to declare local x in a begin or if block at the top-level:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x = 1\n begin\n local x = 0\n @show x\n end\n @show x;\nx = 0\nx = 1","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Note that the interactive prompt (aka REPL) is in the global scope of the module Main.","category":"page"},{"location":"manual/variables-and-scoping/#local-scope","page":"Scope of Variables","title":"Local Scope","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"A new local scope is introduced by most code blocks (see above table for a complete list). If such a block is syntactically nested inside of another local scope, the scope it creates is nested inside of all the local scopes that it appears within, which are all ultimately nested inside of the global scope of the module in which the code is evaluated. Variables in outer scopes are visible from any scope they contain — meaning that they can be read and written in inner scopes — unless there is a local variable with the same name that \"shadows\" the outer variable of the same name. This is true even if the outer local is declared after (in the sense of textually below) an inner block. When we say that a variable \"exists\" in a given scope, this means that a variable by that name exists in any of the scopes that the current scope is nested inside of, including the current one.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Some programming languages require explicitly declaring new variables before using them. Explicit declaration works in Julia too: in any local scope, writing local x declares a new local variable in that scope, regardless of whether there is already a variable named x in an outer scope or not. Declaring each new variable like this is somewhat verbose and tedious, however, so Julia, like many other languages, considers assignment to a variable name that doesn't already exist to implicitly declare that variable. If the current scope is global, the new variable is global; if the current scope is local, the new variable is local to the innermost local scope and will be visible inside of that scope but not outside of it. If you assign to an existing local, it always updates that existing local: you can only shadow a local by explicitly declaring a new local in a nested scope with the local keyword. In particular, this applies to variables assigned in inner functions, which may surprise users coming from Python where assignment in an inner function creates a new local unless the variable is explicitly declared to be non-local.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Mostly this is pretty intuitive, but as with many things that behave intuitively, the details are more subtle than one might naïvely imagine.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"When x = occurs in a local scope, Julia applies the following rules to decide what the expression means based on where the assignment expression occurs and what x already refers to at that location:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Existing local: If x is already a local variable, then the existing local x is assigned;\nHard scope: If x is not already a local variable and assignment occurs inside of any hard scope construct (i.e. within a let block, function or macro body, comprehension, or generator), a new local named x is created in the scope of the assignment;\nSoft scope: If x is not already a local variable and all of the scope constructs containing the assignment are soft scopes (loops, try/catch blocks, or struct blocks), the behavior depends on whether the global variable x is defined:\nif global x is undefined, a new local named x is created in the scope of the assignment;\nif global x is defined, the assignment is considered ambiguous:\nin non-interactive contexts (files, eval), an ambiguity warning is printed and a new local is created;\nin interactive contexts (REPL, notebooks), the global variable x is assigned.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"You may note that in non-interactive contexts the hard and soft scope behaviors are identical except that a warning is printed when an implicitly local variable (i.e. not declared with local x) shadows a global. In interactive contexts, the rules follow a more complex heuristic for the sake of convenience. This is covered in depth in examples that follow.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Now that you know the rules, let's look at some examples. Each example is assumed to be evaluated in a fresh REPL session so that the only globals in each snippet are the ones that are assigned in that block of code.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"We'll begin with a nice and clear-cut situation—assignment inside of a hard scope, in this case a function body, when no local variable by that name already exists:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function greet()\n x = \"hello\" # new local\n println(x)\n end\ngreet (generic function with 1 method)\n\njulia> greet()\nhello\n\njulia> x # global\nERROR: UndefVarError: `x` not defined in `Main`","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Inside of the greet function, the assignment x = \"hello\" causes x to be a new local variable in the function's scope. There are two relevant facts: the assignment occurs in local scope and there is no existing local x variable. Since x is local, it doesn't matter if there is a global named x or not. Here for example we define x = 123 before defining and calling greet:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x = 123 # global\n123\n\njulia> function greet()\n x = \"hello\" # new local\n println(x)\n end\ngreet (generic function with 1 method)\n\njulia> greet()\nhello\n\njulia> x # global\n123","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since the x in greet is local, the value (or lack thereof) of the global x is unaffected by calling greet. The hard scope rule doesn't care whether a global named x exists or not: assignment to x in a hard scope is local (unless x is declared global).","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The next clear cut situation we'll consider is when there is already a local variable named x, in which case x = always assigns to this existing local x. This is true whether the assignment occurs in the same local scope, an inner local scope in the same function body, or in the body of a function nested inside of another function, also known as a closure.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"We'll use the sum_to function, which computes the sum of integers from one up to n, as an example:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"function sum_to(n)\n s = 0 # new local\n for i = 1:n\n s = s + i # assign existing local\n end\n return s # same local\nend","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"As in the previous example, the first assignment to s at the top of sum_to causes s to be a new local variable in the body of the function. The for loop has its own inner local scope within the function scope. At the point where s = s + i occurs, s is already a local variable, so the assignment updates the existing s instead of creating a new local. We can test this out by calling sum_to in the REPL:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function sum_to(n)\n s = 0 # new local\n for i = 1:n\n s = s + i # assign existing local\n end\n return s # same local\n end\nsum_to (generic function with 1 method)\n\njulia> sum_to(10)\n55\n\njulia> s # global\nERROR: UndefVarError: `s` not defined in `Main`","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since s is local to the function sum_to, calling the function has no effect on the global variable s. We can also see that the update s = s + i in the for loop must have updated the same s created by the initialization s = 0 since we get the correct sum of 55 for the integers 1 through 10.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Let's dig into the fact that the for loop body has its own scope for a second by writing a slightly more verbose variation which we'll call sum_to_def, in which we save the sum s + i in a variable t before updating s:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function sum_to_def(n)\n s = 0 # new local\n for i = 1:n\n t = s + i # new local `t`\n s = t # assign existing local `s`\n end\n return s, @isdefined(t)\n end\nsum_to_def (generic function with 1 method)\n\njulia> sum_to_def(10)\n(55, false)","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This version returns s as before but it also uses the @isdefined macro to return a boolean indicating whether there is a local variable named t defined in the function's outermost local scope. As you can see, there is no t defined outside of the for loop body. This is because of the hard scope rule again: since the assignment to t occurs inside of a function, which introduces a hard scope, the assignment causes t to become a new local variable in the local scope where it appears, i.e. inside of the loop body. Even if there were a global named t, it would make no difference—the hard scope rule isn't affected by anything in global scope.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Note that the local scope of a for loop body is no different from the local scope of an inner function. This means that we could rewrite this example so that the loop body is implemented as a call to an inner helper function and it behaves the same way:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function sum_to_def_closure(n)\n function loop_body(i)\n t = s + i # new local `t`\n s = t # assign same local `s` as below\n end\n s = 0 # new local\n for i = 1:n\n loop_body(i)\n end\n return s, @isdefined(t)\n end\nsum_to_def_closure (generic function with 1 method)\n\njulia> sum_to_def_closure(10)\n(55, false)","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This example illustrates a couple of key points:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Inner function scopes are just like any other nested local scope. In particular, if a variable is already a local outside of an inner function and you assign to it in the inner function, the outer local variable is updated.\nIt doesn't matter if the definition of an outer local happens below where it is updated, the rule remains the same. The entire enclosing local scope is parsed and its locals determined before inner local meanings are resolved.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This design means that you can generally move code in or out of an inner function without changing its meaning, which facilitates a number of common idioms in the language using closures (see do blocks).","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Let's move onto some more ambiguous cases covered by the soft scope rule. We'll explore this by extracting the bodies of the greet and sum_to_def functions into soft scope contexts. First, let's put the body of greet in a for loop—which is soft, rather than hard—and evaluate it in the REPL:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> for i = 1:3\n x = \"hello\" # new local\n println(x)\n end\nhello\nhello\nhello\n\njulia> x\nERROR: UndefVarError: `x` not defined in `Main`","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since the global x is not defined when the for loop is evaluated, the first clause of the soft scope rule applies and x is created as local to the for loop and therefore global x remains undefined after the loop executes. Next, let's consider the body of sum_to_def extracted into global scope, fixing its argument to n = 10","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"s = 0\nfor i = 1:10\n t = s + i\n s = t\nend\ns\n@isdefined(t)","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"What does this code do? Hint: it's a trick question. The answer is \"it depends.\" If this code is entered interactively, it behaves the same way it does in a function body. But if the code appears in a file, it prints an ambiguity warning and throws an undefined variable error. Let's see it working in the REPL first:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> s = 0 # global\n0\n\njulia> for i = 1:10\n t = s + i # new local `t`\n s = t # assign global `s`\n end\n\njulia> s # global\n55\n\njulia> @isdefined(t) # global\nfalse","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The REPL approximates being in the body of a function by deciding whether assignment inside the loop assigns to a global or creates new local based on whether a global variable by that name is defined or not. If a global by the name exists, then the assignment updates it. If no global exists, then the assignment creates a new local variable. In this example we see both cases in action:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"There is no global named t, so t = s + i creates a new t that is local to the for loop;\nThere is a global named s, so s = t assigns to it.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The second fact is why execution of the loop changes the global value of s and the first fact is why t is still undefined after the loop executes. Now, let's try evaluating this same code as though it were in a file instead:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> code = \"\"\"\n s = 0 # global\n for i = 1:10\n t = s + i # new local `t`\n s = t # new local `s` with warning\n end\n s, # global\n @isdefined(t) # global\n \"\"\";\n\njulia> include_string(Main, code)\n┌ Warning: Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or `global s` to assign to the existing global variable.\n└ @ string:4\nERROR: LoadError: UndefVarError: `s` not defined in local scope","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Here we use include_string, to evaluate code as though it were the contents of a file. We could also save code to a file and then call include on that file—the result would be the same. As you can see, this behaves quite different from evaluating the same code in the REPL. Let's break down what's happening here:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"global s is defined with the value 0 before the loop is evaluated\nthe assignment s = t occurs in a soft scope—a for loop outside of any function body or other hard scope construct\ntherefore the second clause of the soft scope rule applies, and the assignment is ambiguous so a warning is emitted\nexecution continues, making s local to the for loop body\nsince s is local to the for loop, it is undefined when t = s + i is evaluated, causing an error\nevaluation stops there, but if it got to s and @isdefined(t), it would return 0 and false.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This demonstrates some important aspects of scope: in a scope, each variable can only have one meaning, and that meaning is determined regardless of the order of expressions. The presence of the expression s = t in the loop causes s to be local to the loop, which means that it is also local when it appears on the right hand side of t = s + i, even though that expression appears first and is evaluated first. One might imagine that the s on the first line of the loop could be global while the s on the second line of the loop is local, but that's not possible since the two lines are in the same scope block and each variable can only mean one thing in a given scope.","category":"page"},{"location":"manual/variables-and-scoping/#on-soft-scope","page":"Scope of Variables","title":"On Soft Scope","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"We have now covered all the local scope rules, but before wrapping up this section, perhaps a few words should be said about why the ambiguous soft scope case is handled differently in interactive and non-interactive contexts. There are two obvious questions one could ask:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Why doesn't it just work like the REPL everywhere?\nWhy doesn't it just work like in files everywhere? And maybe skip the warning?","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"In Julia ≤ 0.6, all global scopes did work like the current REPL: when x = occurred in a loop (or try/catch, or struct body) but outside of a function body (or let block or comprehension), it was decided based on whether a global named x was defined or not whether x should be local to the loop. This behavior has the advantage of being intuitive and convenient since it approximates the behavior inside of a function body as closely as possible. In particular, it makes it easy to move code back and forth between a function body and the REPL when trying to debug the behavior of a function. However, it has some downsides. First, it's quite a complex behavior: many people over the years were confused about this behavior and complained that it was complicated and hard both to explain and understand. Fair point. Second, and arguably worse, is that it's bad for programming \"at scale.\" When you see a small piece of code in one place like this, it's quite clear what's going on:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"s = 0\nfor i = 1:10\n s += i\nend","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Obviously the intention is to modify the existing global variable s. What else could it mean? However, not all real world code is so short or so clear. We found that code like the following often occurs in the wild:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"x = 123\n\n# much later\n# maybe in a different file\n\nfor i = 1:10\n x = \"hello\"\n println(x)\nend\n\n# much later\n# maybe in yet another file\n# or maybe back in the first one where `x = 123`\n\ny = x + 234","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"It's far less clear what should happen here. Since x + \"hello\" is a method error, it seems probable that the intention is for x to be local to the for loop. But runtime values and what methods happen to exist cannot be used to determine the scopes of variables. With the Julia ≤ 0.6 behavior, it's especially concerning that someone might have written the for loop first, had it working just fine, but later when someone else adds a new global far away—possibly in a different file—the code suddenly changes meaning and either breaks noisily or, worse still, silently does the wrong thing. This kind of \"spooky action at a distance\" is something that good programming language designs should prevent.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"So in Julia 1.0, we simplified the rules for scope: in any local scope, assignment to a name that wasn't already a local variable created a new local variable. This eliminated the notion of soft scope entirely as well as removing the potential for spooky action. We uncovered and fixed a significant number of bugs due to the removal of soft scope, vindicating the choice to get rid of it. And there was much rejoicing! Well, no, not really. Because some people were angry that they now had to write:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"s = 0\nfor i = 1:10\n global s += i\nend","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Do you see that global annotation in there? Hideous. Obviously this situation could not be tolerated. But seriously, there are two main issues with requiring global for this kind of top-level code:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"It's no longer convenient to copy and paste the code from inside a function body into the REPL to debug it—you have to add global annotations and then remove them again to go back;\nBeginners will write this kind of code without the global and have no idea why their code doesn't work—the error that they get is that s is undefined, which does not seem to enlighten anyone who happens to make this mistake.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"As of Julia 1.5, this code works without the global annotation in interactive contexts like the REPL or Jupyter notebooks (just like Julia 0.6) and in files and other non-interactive contexts, it prints this very direct warning:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Assignment to s in soft scope is ambiguous because a global variable by the same name exists: s will be treated as a new local. Disambiguate by using local s to suppress this warning or global s to assign to the existing global variable.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"This addresses both issues while preserving the \"programming at scale\" benefits of the 1.0 behavior: global variables have no spooky effect on the meaning of code that may be far away; in the REPL copy-and-paste debugging works and beginners don't have any issues; any time someone either forgets a global annotation or accidentally shadows an existing global with a local in a soft scope, which would be confusing anyway, they get a nice clear warning.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"An important property of this design is that any code that executes in a file without a warning will behave the same way in a fresh REPL. And on the flip side, if you take a REPL session and save it to file, if it behaves differently than it did in the REPL, then you will get a warning.","category":"page"},{"location":"manual/variables-and-scoping/#Let-Blocks","page":"Scope of Variables","title":"Let Blocks","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"let statements create a new hard scope block (see above) and introduce new variable bindings each time they run. The variable need not be immediately assigned:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> var1 = let x\n for i in 1:5\n (i == 4) && (x = i; break)\n end\n x\n end\n4","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Whereas assignments might reassign a new value to an existing value location, let always creates a new location. This difference is usually not important, and is only detectable in the case of variables that outlive their scope via closures. The let syntax accepts a comma-separated series of assignments and variable names:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x, y, z = -1, -1, -1;\n\njulia> let x = 1, z\n println(\"x: $x, y: $y\") # x is local variable, y the global\n println(\"z: $z\") # errors as z has not been assigned yet but is local\n end\nx: 1, y: -1\nERROR: UndefVarError: `z` not defined in local scope","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The assignments are evaluated in order, with each right-hand side evaluated in the scope before the new variable on the left-hand side has been introduced. Therefore it makes sense to write something like let x = x since the two x variables are distinct and have separate storage. Here is an example where the behavior of let is needed:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> Fs = Vector{Any}(undef, 2); i = 1;\n\njulia> while i <= 2\n Fs[i] = ()->i\n global i += 1\n end\n\njulia> Fs[1]()\n3\n\njulia> Fs[2]()\n3","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Here we create and store two closures that return variable i. However, it is always the same variable i, so the two closures behave identically. We can use let to create a new binding for i:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> Fs = Vector{Any}(undef, 2); i = 1;\n\njulia> while i <= 2\n let i = i\n Fs[i] = ()->i\n end\n global i += 1\n end\n\njulia> Fs[1]()\n1\n\njulia> Fs[2]()\n2","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since the begin construct does not introduce a new scope, it can be useful to use a zero-argument let to just introduce a new scope block without creating any new bindings immediately:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> let\n local x = 1\n let\n local x = 2\n end\n x\n end\n1","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Since let introduces a new scope block, the inner local x is a different variable than the outer local x. This particular example is equivalent to:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> let x = 1\n let x = 2\n end\n x\n end\n1","category":"page"},{"location":"manual/variables-and-scoping/#Loops-and-Comprehensions","page":"Scope of Variables","title":"Loops and Comprehensions","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"In loops and comprehensions, new variables introduced in their body scopes are freshly allocated for each loop iteration, as if the loop body were surrounded by a let block, as demonstrated by this example:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> Fs = Vector{Any}(undef, 2);\n\njulia> for j = 1:2\n Fs[j] = ()->j\n end\n\njulia> Fs[1]()\n1\n\njulia> Fs[2]()\n2","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"A for loop or comprehension iteration variable is always a new variable:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function f()\n i = 0\n for i = 1:3\n # empty\n end\n return i\n end;\n\njulia> f()\n0","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"However, it is occasionally useful to reuse an existing local variable as the iteration variable. This can be done conveniently by adding the keyword outer:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> function f()\n i = 0\n for outer i = 1:3\n # empty\n end\n return i\n end;\n\njulia> f()\n3","category":"page"},{"location":"manual/variables-and-scoping/#Constants","page":"Scope of Variables","title":"Constants","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"A common use of variables is giving names to specific, unchanging values. Such variables are only assigned once. This intent can be conveyed to the compiler using the const keyword:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const e = 2.71828182845904523536;\n\njulia> const pi = 3.14159265358979323846;","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Multiple variables can be declared in a single const statement:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const a, b = 1, 2\n(1, 2)","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The const declaration should only be used in global scope on globals. It is difficult for the compiler to optimize code involving global variables, since their values (or even their types) might change at almost any time. If a global variable will not change, adding a const declaration solves this performance problem.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Local constants are quite different. The compiler is able to determine automatically when a local variable is constant, so local constant declarations are not necessary, and in fact are currently not supported.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Special top-level assignments, such as those performed by the function and struct keywords, are constant by default.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Note that const only affects the variable binding; the variable may be bound to a mutable object (such as an array), and that object may still be modified. Additionally when one tries to assign a value to a variable that is declared constant the following scenarios are possible:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"if a new value has a different type than the type of the constant then an error is thrown:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const x = 1.0\n1.0\n\njulia> x = 1\nERROR: invalid redefinition of constant x","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"if a new value has the same type as the constant then a warning is printed:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const y = 1.0\n1.0\n\njulia> y = 2.0\nWARNING: redefinition of constant y. This may fail, cause incorrect answers, or produce other errors.\n2.0","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"if an assignment would not result in the change of variable value no message is given:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const z = 100\n100\n\njulia> z = 100\n100","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The last rule applies to immutable objects even if the variable binding would change, e.g.:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const s1 = \"1\"\n\"1\"\n\njulia> s2 = \"1\"\n\"1\"\n\njulia> pointer.([s1, s2], 1)\n2-element Array{Ptr{UInt8},1}:\n Ptr{UInt8} @0x00000000132c9638\n Ptr{UInt8} @0x0000000013dd3d18\n\njulia> s1 = s2\n\"1\"\n\njulia> pointer.([s1, s2], 1)\n2-element Array{Ptr{UInt8},1}:\n Ptr{UInt8} @0x0000000013dd3d18\n Ptr{UInt8} @0x0000000013dd3d18","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"However, for mutable objects the warning is printed as expected:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const a = [1]\n1-element Vector{Int64}:\n 1\n\njulia> a = [1]\nWARNING: redefinition of constant a. This may fail, cause incorrect answers, or produce other errors.\n1-element Vector{Int64}:\n 1","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Note that although sometimes possible, changing the value of a const variable is strongly discouraged, and is intended only for convenience during interactive use. Changing constants can cause various problems or unexpected behaviors. For instance, if a method references a constant and is already compiled before the constant is changed, then it might keep using the old value:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> const x = 1\n1\n\njulia> f() = x\nf (generic function with 1 method)\n\njulia> f()\n1\n\njulia> x = 2\nWARNING: redefinition of constant x. This may fail, cause incorrect answers, or produce other errors.\n2\n\njulia> f()\n1","category":"page"},{"location":"manual/variables-and-scoping/#man-typed-globals","page":"Scope of Variables","title":"Typed Globals","text":"","category":"section"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"compat: Julia 1.8\nSupport for typed globals was added in Julia 1.8","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Similar to being declared as constants, global bindings can also be declared to always be of a constant type. This can either be done without assigning an actual value using the syntax global x::T or upon assignment as x::T = 123.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x::Float64 = 2.718\n2.718\n\njulia> f() = x\nf (generic function with 1 method)\n\njulia> Base.return_types(f)\n1-element Vector{Any}:\n Float64","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"For any assignment to a global, Julia will first try to convert it to the appropriate type using convert:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> global y::Int\n\njulia> y = 1.0\n1.0\n\njulia> y\n1\n\njulia> y = 3.14\nERROR: InexactError: Int64(3.14)\nStacktrace:\n[...]","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"The type does not need to be concrete, but annotations with abstract types typically have little performance benefit.","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"Once a global has either been assigned to or its type has been set, the binding type is not allowed to change:","category":"page"},{"location":"manual/variables-and-scoping/","page":"Scope of Variables","title":"Scope of Variables","text":"julia> x = 1\n1\n\njulia> global x::Int\nERROR: cannot set type for global x. It already has a value or is already set to a different type.\nStacktrace:\n[...]","category":"page"},{"location":"base/simd-types/#SIMD-Support","page":"SIMD Support","title":"SIMD Support","text":"","category":"section"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"Type VecElement{T} is intended for building libraries of SIMD operations. Practical use of it requires using llvmcall. The type is defined as:","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"struct VecElement{T}\n value::T\nend","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"It has a special compilation rule: a homogeneous tuple of VecElement{T} maps to an LLVM vector type when T is a primitive bits type.","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"At -O3, the compiler might automatically vectorize operations on such tuples. For example, the following program, when compiled with julia -O3 generates two SIMD addition instructions (addps) on x86 systems:","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"const m128 = NTuple{4,VecElement{Float32}}\n\nfunction add(a::m128, b::m128)\n (VecElement(a[1].value+b[1].value),\n VecElement(a[2].value+b[2].value),\n VecElement(a[3].value+b[3].value),\n VecElement(a[4].value+b[4].value))\nend\n\ntriple(c::m128) = add(add(c,c),c)\n\ncode_native(triple,(m128,))","category":"page"},{"location":"base/simd-types/","page":"SIMD Support","title":"SIMD Support","text":"However, since the automatic vectorization cannot be relied upon, future use will mostly be via libraries that use llvmcall.","category":"page"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Artifacts/docs/src/index.md\"","category":"page"},{"location":"stdlib/Artifacts/#Artifacts","page":"Artifacts","title":"Artifacts","text":"","category":"section"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"DocTestSetup = :(using Artifacts)","category":"page"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"Starting with Julia 1.6, the artifacts support has moved from Pkg.jl to Julia itself. Until proper documentation can be added here, you can learn more about artifacts in the Pkg.jl manual at https://julialang.github.io/Pkg.jl/v1/artifacts/.","category":"page"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"compat: Julia 1.6\nJulia's artifacts API requires at least Julia 1.6. In Julia versions 1.3 to 1.5, you can use Pkg.Artifacts instead.","category":"page"},{"location":"stdlib/Artifacts/","page":"Artifacts","title":"Artifacts","text":"Artifacts.artifact_meta\nArtifacts.artifact_hash\nArtifacts.find_artifacts_toml\nArtifacts.@artifact_str\nArtifacts.artifact_exists\nArtifacts.artifact_path\nArtifacts.select_downloadable_artifacts","category":"page"},{"location":"stdlib/Artifacts/#Artifacts.artifact_meta","page":"Artifacts","title":"Artifacts.artifact_meta","text":"artifact_meta(name::String, artifacts_toml::String;\n platform::AbstractPlatform = HostPlatform(),\n pkg_uuid::Union{Base.UUID,Nothing}=nothing)\n\nGet metadata about a given artifact (identified by name) stored within the given (Julia)Artifacts.toml file. If the artifact is platform-specific, use platform to choose the most appropriate mapping. If none is found, return nothing.\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.artifact_hash","page":"Artifacts","title":"Artifacts.artifact_hash","text":"artifact_hash(name::String, artifacts_toml::String;\n platform::AbstractPlatform = HostPlatform())\n\nThin wrapper around artifact_meta() to return the hash of the specified, platform- collapsed artifact. Returns nothing if no mapping can be found.\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.find_artifacts_toml","page":"Artifacts","title":"Artifacts.find_artifacts_toml","text":"find_artifacts_toml(path::String)\n\nGiven the path to a .jl file, (such as the one returned by __source__.file in a macro context), find the (Julia)Artifacts.toml that is contained within the containing project (if it exists), otherwise return nothing.\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.@artifact_str","page":"Artifacts","title":"Artifacts.@artifact_str","text":"macro artifact_str(name)\n\nReturn the on-disk path to an artifact. Automatically looks the artifact up by name in the project's (Julia)Artifacts.toml file. Throws an error on if the requested artifact is not present. If run in the REPL, searches for the toml file starting in the current directory, see find_artifacts_toml() for more.\n\nIf the artifact is marked \"lazy\" and the package has using LazyArtifacts defined, the artifact will be downloaded on-demand with Pkg the first time this macro tries to compute the path. The files will then be left installed locally for later.\n\nIf name contains a forward or backward slash, all elements after the first slash will be taken to be path names indexing into the artifact, allowing for an easy one-liner to access a single file/directory within an artifact. Example:\n\nffmpeg_path = @artifact\"FFMPEG/bin/ffmpeg\"\n\ncompat: Julia 1.3\nThis macro requires at least Julia 1.3.\n\ncompat: Julia 1.6\nSlash-indexing requires at least Julia 1.6.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Artifacts/#Artifacts.artifact_exists","page":"Artifacts","title":"Artifacts.artifact_exists","text":"artifact_exists(hash::SHA1; honor_overrides::Bool=true)\n\nReturn whether or not the given artifact (identified by its sha1 git tree hash) exists on-disk. Note that it is possible that the given artifact exists in multiple locations (e.g. within multiple depots).\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.artifact_path","page":"Artifacts","title":"Artifacts.artifact_path","text":"artifact_path(hash::SHA1; honor_overrides::Bool=true)\n\nGiven an artifact (identified by SHA1 git tree hash), return its installation path. If the artifact does not exist, returns the location it would be installed to.\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Artifacts/#Artifacts.select_downloadable_artifacts","page":"Artifacts","title":"Artifacts.select_downloadable_artifacts","text":"select_downloadable_artifacts(artifacts_toml::String;\n platform = HostPlatform,\n include_lazy = false,\n pkg_uuid = nothing)\n\nReturn a dictionary where every entry is an artifact from the given Artifacts.toml that should be downloaded for the requested platform. Lazy artifacts are included if include_lazy is set.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/inference/#Inference","page":"Inference","title":"Inference","text":"","category":"section"},{"location":"devdocs/inference/#How-inference-works","page":"Inference","title":"How inference works","text":"","category":"section"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"In Julia compiler, \"type inference\" refers to the process of deducing the types of later values from the types of input values. Julia's approach to inference has been described in the blog posts below:","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"Shows a simplified implementation of the data-flow analysis algorithm, that Julia's type inference routine is based on.\nGives a high level view of inference with a focus on its inter-procedural convergence guarantee.\nExplains a refinement on the algorithm introduced in 2.","category":"page"},{"location":"devdocs/inference/#Debugging-compiler.jl","page":"Inference","title":"Debugging compiler.jl","text":"","category":"section"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"You can start a Julia session, edit compiler/*.jl (for example to insert print statements), and then replace Core.Compiler in your running session by navigating to base and executing include(\"compiler/compiler.jl\"). This trick typically leads to much faster development than if you rebuild Julia for each change.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"Alternatively, you can use the Revise.jl package to track the compiler changes by using the command Revise.track(Core.Compiler) at the beginning of your Julia session. As explained in the Revise documentation, the modifications to the compiler will be reflected when the modified files are saved.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"A convenient entry point into inference is typeinf_code. Here's a demo running inference on convert(Int, UInt(1)):","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"# Get the method\natypes = Tuple{Type{Int}, UInt} # argument types\nmths = methods(convert, atypes) # worth checking that there is only one\nm = first(mths)\n\n# Create variables needed to call `typeinf_code`\ninterp = Core.Compiler.NativeInterpreter()\nsparams = Core.svec() # this particular method doesn't have type-parameters\nrun_optimizer = true # run all inference optimizations\ntypes = Tuple{typeof(convert), atypes.parameters...} # Tuple{typeof(convert), Type{Int}, UInt}\nCore.Compiler.typeinf_code(interp, m, types, sparams, run_optimizer)","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"If your debugging adventures require a MethodInstance, you can look it up by calling Core.Compiler.specialize_method using many of the variables above. A CodeInfo object may be obtained with","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"# Returns the CodeInfo object for `convert(Int, ::UInt)`:\nci = (@code_typed convert(Int, UInt(1)))[1]","category":"page"},{"location":"devdocs/inference/#The-inlining-algorithm-(inline_worthy)","page":"Inference","title":"The inlining algorithm (inline_worthy)","text":"","category":"section"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"Much of the hardest work for inlining runs in ssa_inlining_pass!. However, if your question is \"why didn't my function inline?\" then you will most likely be interested in inline_worthy, which makes a decision to inline the function call or not.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"inline_worthy implements a cost-model, where \"cheap\" functions get inlined; more specifically, we inline functions if their anticipated run-time is not large compared to the time it would take to issue a call to them if they were not inlined. The cost-model is extremely simple and ignores many important details: for example, all for loops are analyzed as if they will be executed once, and the cost of an if...else...end includes the summed cost of all branches. It's also worth acknowledging that we currently lack a suite of functions suitable for testing how well the cost model predicts the actual run-time cost, although BaseBenchmarks provides a great deal of indirect information about the successes and failures of any modification to the inlining algorithm.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"The foundation of the cost-model is a lookup table, implemented in add_tfunc and its callers, that assigns an estimated cost (measured in CPU cycles) to each of Julia's intrinsic functions. These costs are based on standard ranges for common architectures (see Agner Fog's analysis for more detail).","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"We supplement this low-level lookup table with a number of special cases. For example, an :invoke expression (a call for which all input and output types were inferred in advance) is assigned a fixed cost (currently 20 cycles). In contrast, a :call expression, for functions other than intrinsics/builtins, indicates that the call will require dynamic dispatch, in which case we assign a cost set by Params.inline_nonleaf_penalty (currently set at 1000). Note that this is not a \"first-principles\" estimate of the raw cost of dynamic dispatch, but a mere heuristic indicating that dynamic dispatch is extremely expensive.","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"Each statement gets analyzed for its total cost in a function called statement_cost. You can display the cost associated with each statement as follows:","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"julia> Base.print_statement_costs(stdout, map, (typeof(sqrt), Tuple{Int},)) # map(sqrt, (2,))\nmap(f, t::Tuple{Any}) @ Base tuple.jl:281\n 0 1 ─ %1 = $(Expr(:boundscheck, true))::Bool\n 0 │ %2 = Base.getfield(_3, 1, %1)::Int64\n 1 │ %3 = Base.sitofp(Float64, %2)::Float64\n 0 │ %4 = Base.lt_float(%3, 0.0)::Bool\n 0 └── goto #3 if not %4\n 0 2 ─ invoke Base.Math.throw_complex_domainerror(:sqrt::Symbol, %3::Float64)::Union{}\n 0 └── unreachable\n 20 3 ─ %8 = Base.Math.sqrt_llvm(%3)::Float64\n 0 └── goto #4\n 0 4 ─ goto #5\n 0 5 ─ %11 = Core.tuple(%8)::Tuple{Float64}\n 0 └── return %11\n","category":"page"},{"location":"devdocs/inference/","page":"Inference","title":"Inference","text":"The line costs are in the left column. This includes the consequences of inlining and other forms of optimization.","category":"page"},{"location":"manual/complex-and-rational-numbers/#Complex-and-Rational-Numbers","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"","category":"section"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Julia includes predefined types for both complex and rational numbers, and supports all the standard Mathematical Operations and Elementary Functions on them. Conversion and Promotion are defined so that operations on any combination of predefined numeric types, whether primitive or composite, behave as expected.","category":"page"},{"location":"manual/complex-and-rational-numbers/#Complex-Numbers","page":"Complex and Rational Numbers","title":"Complex Numbers","text":"","category":"section"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"The global constant im is bound to the complex number i, representing the principal square root of -1. (Using mathematicians' i or engineers' j for this global constant was rejected since they are such popular index variable names.) Since Julia allows numeric literals to be juxtaposed with identifiers as coefficients, this binding suffices to provide convenient syntax for complex numbers, similar to the traditional mathematical notation:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 1+2im\n1 + 2im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"You can perform all the standard arithmetic operations with complex numbers:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> (1 + 2im)*(2 - 3im)\n8 + 1im\n\njulia> (1 + 2im)/(1 - 2im)\n-0.6 + 0.8im\n\njulia> (1 + 2im) + (1 - 2im)\n2 + 0im\n\njulia> (-3 + 2im) - (5 - 1im)\n-8 + 3im\n\njulia> (-1 + 2im)^2\n-3 - 4im\n\njulia> (-1 + 2im)^2.5\n2.729624464784009 - 6.9606644595719im\n\njulia> (-1 + 2im)^(1 + 1im)\n-0.27910381075826657 + 0.08708053414102428im\n\njulia> 3(2 - 5im)\n6 - 15im\n\njulia> 3(2 - 5im)^2\n-63 - 60im\n\njulia> 3(2 - 5im)^-1.0\n0.20689655172413793 + 0.5172413793103449im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"The promotion mechanism ensures that combinations of operands of different types just work:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 2(1 - 1im)\n2 - 2im\n\njulia> (2 + 3im) - 1\n1 + 3im\n\njulia> (1 + 2im) + 0.5\n1.5 + 2.0im\n\njulia> (2 + 3im) - 0.5im\n2.0 + 2.5im\n\njulia> 0.75(1 + 2im)\n0.75 + 1.5im\n\njulia> (2 + 3im) / 2\n1.0 + 1.5im\n\njulia> (1 - 3im) / (2 + 2im)\n-0.5 - 1.0im\n\njulia> 2im^2\n-2 + 0im\n\njulia> 1 + 3/4im\n1.0 - 0.75im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Note that 3/4im == 3/(4*im) == -(3/4*im), since a literal coefficient binds more tightly than division.","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Standard functions to manipulate complex values are provided:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> z = 1 + 2im\n1 + 2im\n\njulia> real(1 + 2im) # real part of z\n1\n\njulia> imag(1 + 2im) # imaginary part of z\n2\n\njulia> conj(1 + 2im) # complex conjugate of z\n1 - 2im\n\njulia> abs(1 + 2im) # absolute value of z\n2.23606797749979\n\njulia> abs2(1 + 2im) # squared absolute value\n5\n\njulia> angle(1 + 2im) # phase angle in radians\n1.1071487177940904","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"As usual, the absolute value (abs) of a complex number is its distance from zero. abs2 gives the square of the absolute value, and is of particular use for complex numbers since it avoids taking a square root. angle returns the phase angle in radians (also known as the argument or arg function). The full gamut of other Elementary Functions is also defined for complex numbers:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> sqrt(1im)\n0.7071067811865476 + 0.7071067811865475im\n\njulia> sqrt(1 + 2im)\n1.272019649514069 + 0.7861513777574233im\n\njulia> cos(1 + 2im)\n2.0327230070196656 - 3.0518977991517997im\n\njulia> exp(1 + 2im)\n-1.1312043837568135 + 2.4717266720048188im\n\njulia> sinh(1 + 2im)\n-0.4890562590412937 + 1.4031192506220405im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Note that mathematical functions typically return real values when applied to real numbers and complex values when applied to complex numbers. For example, sqrt behaves differently when applied to -1 versus -1 + 0im even though -1 == -1 + 0im:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> sqrt(-1)\nERROR: DomainError with -1.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]\n\njulia> sqrt(-1 + 0im)\n0.0 + 1.0im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"The literal numeric coefficient notation does not work when constructing a complex number from variables. Instead, the multiplication must be explicitly written out:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> a = 1; b = 2; a + b*im\n1 + 2im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"However, this is not recommended. Instead, use the more efficient complex function to construct a complex value directly from its real and imaginary parts:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> a = 1; b = 2; complex(a, b)\n1 + 2im","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"This construction avoids the multiplication and addition operations.","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Inf and NaN propagate through complex numbers in the real and imaginary parts of a complex number as described in the Special floating-point values section:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 1 + Inf*im\n1.0 + Inf*im\n\njulia> 1 + NaN*im\n1.0 + NaN*im","category":"page"},{"location":"manual/complex-and-rational-numbers/#Rational-Numbers","page":"Complex and Rational Numbers","title":"Rational Numbers","text":"","category":"section"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Julia has a rational number type to represent exact ratios of integers. Rationals are constructed using the // operator:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 2//3\n2//3","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"If the numerator and denominator of a rational have common factors, they are reduced to lowest terms such that the denominator is non-negative:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 6//9\n2//3\n\njulia> -4//8\n-1//2\n\njulia> 5//-15\n-1//3\n\njulia> -4//-12\n1//3","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"This normalized form for a ratio of integers is unique, so equality of rational values can be tested by checking for equality of the numerator and denominator. The standardized numerator and denominator of a rational value can be extracted using the numerator and denominator functions:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> numerator(2//3)\n2\n\njulia> denominator(2//3)\n3","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Direct comparison of the numerator and denominator is generally not necessary, since the standard arithmetic and comparison operations are defined for rational values:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 2//3 == 6//9\ntrue\n\njulia> 2//3 == 9//27\nfalse\n\njulia> 3//7 < 1//2\ntrue\n\njulia> 3//4 > 2//3\ntrue\n\njulia> 2//4 + 1//6\n2//3\n\njulia> 5//12 - 1//4\n1//6\n\njulia> 5//8 * 3//12\n5//32\n\njulia> 6//5 / 10//7\n21//25","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Rationals can easily be converted to floating-point numbers:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> float(3//4)\n0.75","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Conversion from rational to floating-point respects the following identity for any integral values of a and b, with the exception of the two cases b == 0 and a == 0 && b < 0:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> a = 1; b = 2;\n\njulia> isequal(float(a//b), a/b)\ntrue","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Constructing infinite rational values is acceptable:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 5//0\n1//0\n\njulia> x = -3//0\n-1//0\n\njulia> typeof(x)\nRational{Int64}","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"Trying to construct a NaN rational value, however, is invalid:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 0//0\nERROR: ArgumentError: invalid rational: zero(Int64)//zero(Int64)\nStacktrace:\n[...]","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"As usual, the promotion system makes interactions with other numeric types effortless:","category":"page"},{"location":"manual/complex-and-rational-numbers/","page":"Complex and Rational Numbers","title":"Complex and Rational Numbers","text":"julia> 3//5 + 1\n8//5\n\njulia> 3//5 - 0.5\n0.09999999999999998\n\njulia> 2//7 * (1 + 2im)\n2//7 + 4//7*im\n\njulia> 2//7 * (1.5 + 2im)\n0.42857142857142855 + 0.5714285714285714im\n\njulia> 3//2 / (1 + 2im)\n3//10 - 3//5*im\n\njulia> 1//2 + 2im\n1//2 + 2//1*im\n\njulia> 1 + 2//3im\n1//1 - 2//3*im\n\njulia> 0.5 == 1//2\ntrue\n\njulia> 0.33 == 1//3\nfalse\n\njulia> 0.33 < 1//3\ntrue\n\njulia> 1//3 - 0.33\n0.0033333333333332993","category":"page"},{"location":"devdocs/types/#More-about-types","page":"More about types","title":"More about types","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"If you've used Julia for a while, you understand the fundamental role that types play. Here we try to get under the hood, focusing particularly on Parametric Types.","category":"page"},{"location":"devdocs/types/#Types-and-sets-(and-Any-and-Union{}/Bottom)","page":"More about types","title":"Types and sets (and Any and Union{}/Bottom)","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"It's perhaps easiest to conceive of Julia's type system in terms of sets. While programs manipulate individual values, a type refers to a set of values. This is not the same thing as a collection; for example a Set of values is itself a single Set value. Rather, a type describes a set of possible values, expressing uncertainty about which value we have.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"A concrete type T describes the set of values whose direct tag, as returned by the typeof function, is T. An abstract type describes some possibly-larger set of values.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Any describes the entire universe of possible values. Integer is a subset of Any that includes Int, Int8, and other concrete types. Internally, Julia also makes heavy use of another type known as Bottom, which can also be written as Union{}. This corresponds to the empty set.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Julia's types support the standard operations of set theory: you can ask whether T1 is a \"subset\" (subtype) of T2 with T1 <: T2. Likewise, you intersect two types using typeintersect, take their union with Union, and compute a type that contains their union with typejoin:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> typeintersect(Int, Float64)\nUnion{}\n\njulia> Union{Int, Float64}\nUnion{Float64, Int64}\n\njulia> typejoin(Int, Float64)\nReal\n\njulia> typeintersect(Signed, Union{UInt8, Int8})\nInt8\n\njulia> Union{Signed, Union{UInt8, Int8}}\nUnion{UInt8, Signed}\n\njulia> typejoin(Signed, Union{UInt8, Int8})\nInteger\n\njulia> typeintersect(Tuple{Integer, Float64}, Tuple{Int, Real})\nTuple{Int64, Float64}\n\njulia> Union{Tuple{Integer, Float64}, Tuple{Int, Real}}\nUnion{Tuple{Int64, Real}, Tuple{Integer, Float64}}\n\njulia> typejoin(Tuple{Integer, Float64}, Tuple{Int, Real})\nTuple{Integer, Real}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"While these operations may seem abstract, they lie at the heart of Julia. For example, method dispatch is implemented by stepping through the items in a method list until reaching one for which the type of the argument tuple is a subtype of the method signature. For this algorithm to work, it's important that methods be sorted by their specificity, and that the search begins with the most specific methods. Consequently, Julia also implements a partial order on types; this is achieved by functionality that is similar to <:, but with differences that will be discussed below.","category":"page"},{"location":"devdocs/types/#UnionAll-types","page":"More about types","title":"UnionAll types","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Julia's type system can also express an iterated union of types: a union of types over all values of some variable. This is needed to describe parametric types where the values of some parameters are not known.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"For example, Array has two parameters as in Array{Int,2}. If we did not know the element type, we could write Array{T,2} where T, which is the union of Array{T,2} for all values of T: Union{Array{Int8,2}, Array{Int16,2}, ...}.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Such a type is represented by a UnionAll object, which contains a variable (T in this example, of type TypeVar), and a wrapped type (Array{T,2} in this example).","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Consider the following methods:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f1(A::Array) = 1\nf2(A::Array{Int}) = 2\nf3(A::Array{T}) where {T<:Any} = 3\nf4(A::Array{Any}) = 4","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The signature - as described in Function calls - of f3 is a UnionAll type wrapping a tuple type: Tuple{typeof(f3), Array{T}} where T. All but f4 can be called with a = [1,2]; all but f2 can be called with b = Any[1,2].","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Let's look at these types a little more closely:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> dump(Array)\nUnionAll\n var: TypeVar\n name: Symbol T\n lb: Union{}\n ub: abstract type Any\n body: UnionAll\n var: TypeVar\n name: Symbol N\n lb: Union{}\n ub: abstract type Any\n body: mutable struct Array{T, N} <: DenseArray{T, N}\n ref::MemoryRef{T}\n size::NTuple{N, Int64}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"This indicates that Array actually names a UnionAll type. There is one UnionAll type for each parameter, nested. The syntax Array{Int,2} is equivalent to Array{Int}{2}; internally each UnionAll is instantiated with a particular variable value, one at a time, outermost-first. This gives a natural meaning to the omission of trailing type parameters; Array{Int} gives a type equivalent to Array{Int,N} where N.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"A TypeVar is not itself a type, but rather should be considered part of the structure of a UnionAll type. Type variables have lower and upper bounds on their values (in the fields lb and ub). The symbol name is purely cosmetic. Internally, TypeVars are compared by address, so they are defined as mutable types to ensure that \"different\" type variables can be distinguished. However, by convention they should not be mutated.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"One can construct TypeVars manually:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> TypeVar(:V, Signed, Real)\nSigned<:V<:Real","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"There are convenience versions that allow you to omit any of these arguments except the name symbol.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The syntax Array{T} where T<:Integer is lowered to","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"let T = TypeVar(:T,Integer)\n UnionAll(T, Array{T})\nend","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"so it is seldom necessary to construct a TypeVar manually (indeed, this is to be avoided).","category":"page"},{"location":"devdocs/types/#Free-variables","page":"More about types","title":"Free variables","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The concept of a free type variable is extremely important in the type system. We say that a variable V is free in type T if T does not contain the UnionAll that introduces variable V. For example, the type Array{Array{V} where V<:Integer} has no free variables, but the Array{V} part inside of it does have a free variable, V.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"A type with free variables is, in some sense, not really a type at all. Consider the type Array{Array{T}} where T, which refers to all homogeneous arrays of arrays. The inner type Array{T}, seen by itself, might seem to refer to any kind of array. However, every element of the outer array must have the same array type, so Array{T} cannot refer to just any old array. One could say that Array{T} effectively \"occurs\" multiple times, and T must have the same value each \"time\".","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"For this reason, the function jl_has_free_typevars in the C API is very important. Types for which it returns true will not give meaningful answers in subtyping and other type functions.","category":"page"},{"location":"devdocs/types/#TypeNames","page":"More about types","title":"TypeNames","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The following two Array types are functionally equivalent, yet print differently:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> TV, NV = TypeVar(:T), TypeVar(:N)\n(T, N)\n\njulia> Array\nArray\n\njulia> Array{TV, NV}\nArray{T, N}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"These can be distinguished by examining the name field of the type, which is an object of type TypeName:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> dump(Array{Int,1}.name)\nTypeName\n name: Symbol Array\n module: Module Core\n names: empty SimpleVector\n wrapper: UnionAll\n var: TypeVar\n name: Symbol T\n lb: Union{}\n ub: abstract type Any\n body: UnionAll\n var: TypeVar\n name: Symbol N\n lb: Union{}\n ub: abstract type Any\n body: mutable struct Array{T, N} <: DenseArray{T, N}\n cache: SimpleVector\n ...\n\n linearcache: SimpleVector\n ...\n\n hash: Int64 -7900426068641098781\n mt: MethodTable\n name: Symbol Array\n defs: Nothing nothing\n cache: Nothing nothing\n max_args: Int64 0\n module: Module Core\n : Int64 0\n : Int64 0","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"In this case, the relevant field is wrapper, which holds a reference to the top-level type used to make new Array types.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> pointer_from_objref(Array)\nPtr{Cvoid} @0x00007fcc7de64850\n\njulia> pointer_from_objref(Array.body.body.name.wrapper)\nPtr{Cvoid} @0x00007fcc7de64850\n\njulia> pointer_from_objref(Array{TV,NV})\nPtr{Cvoid} @0x00007fcc80c4d930\n\njulia> pointer_from_objref(Array{TV,NV}.name.wrapper)\nPtr{Cvoid} @0x00007fcc7de64850","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The wrapper field of Array points to itself, but for Array{TV,NV} it points back to the original definition of the type.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"What about the other fields? hash assigns an integer to each type. To examine the cache field, it's helpful to pick a type that is less heavily used than Array. Let's first create our own type:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> struct MyType{T,N} end\n\njulia> MyType{Int,2}\nMyType{Int64, 2}\n\njulia> MyType{Float32, 5}\nMyType{Float32, 5}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"When you instantiate a parametric type, each concrete type gets saved in a type cache (MyType.body.body.name.cache). However, instances containing free type variables are not cached.","category":"page"},{"location":"devdocs/types/#Tuple-types","page":"More about types","title":"Tuple types","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Tuple types constitute an interesting special case. For dispatch to work on declarations like x::Tuple, the type has to be able to accommodate any tuple. Let's check the parameters:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> Tuple\nTuple\n\njulia> Tuple.parameters\nsvec(Vararg{Any})","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Unlike other types, tuple types are covariant in their parameters, so this definition permits Tuple to match any type of tuple:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> typeintersect(Tuple, Tuple{Int,Float64})\nTuple{Int64, Float64}\n\njulia> typeintersect(Tuple{Vararg{Any}}, Tuple{Int,Float64})\nTuple{Int64, Float64}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"However, if a variadic (Vararg) tuple type has free variables it can describe different kinds of tuples:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> typeintersect(Tuple{Vararg{T} where T}, Tuple{Int,Float64})\nTuple{Int64, Float64}\n\njulia> typeintersect(Tuple{Vararg{T}} where T, Tuple{Int,Float64})\nUnion{}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Notice that when T is free with respect to the Tuple type (i.e. its binding UnionAll type is outside the Tuple type), only one T value must work over the whole type. Therefore a heterogeneous tuple does not match.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Finally, it's worth noting that Tuple{} is distinct:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> Tuple{}\nTuple{}\n\njulia> Tuple{}.parameters\nsvec()\n\njulia> typeintersect(Tuple{}, Tuple{Int})\nUnion{}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"What is the \"primary\" tuple-type?","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> pointer_from_objref(Tuple)\nPtr{Cvoid} @0x00007f5998a04370\n\njulia> pointer_from_objref(Tuple{})\nPtr{Cvoid} @0x00007f5998a570d0\n\njulia> pointer_from_objref(Tuple.name.wrapper)\nPtr{Cvoid} @0x00007f5998a04370\n\njulia> pointer_from_objref(Tuple{}.name.wrapper)\nPtr{Cvoid} @0x00007f5998a04370","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"so Tuple == Tuple{Vararg{Any}} is indeed the primary type.","category":"page"},{"location":"devdocs/types/#Diagonal-types","page":"More about types","title":"Diagonal types","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Consider the type Tuple{T,T} where T. A method with this signature would look like:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(x::T, y::T) where {T} = ...","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"According to the usual interpretation of a UnionAll type, this T ranges over all types, including Any, so this type should be equivalent to Tuple{Any,Any}. However, this interpretation causes some practical problems.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"First, a value of T needs to be available inside the method definition. For a call like f(1, 1.0), it's not clear what T should be. It could be Union{Int,Float64}, or perhaps Real. Intuitively, we expect the declaration x::T to mean T === typeof(x). To make sure that invariant holds, we need typeof(x) === typeof(y) === T in this method. That implies the method should only be called for arguments of the exact same type.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"It turns out that being able to dispatch on whether two values have the same type is very useful (this is used by the promotion system for example), so we have multiple reasons to want a different interpretation of Tuple{T,T} where T. To make this work we add the following rule to subtyping: if a variable occurs more than once in covariant position, it is restricted to ranging over only concrete types. (\"Covariant position\" means that only Tuple and Union types occur between an occurrence of a variable and the UnionAll type that introduces it.) Such variables are called \"diagonal variables\" or \"concrete variables\".","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"So for example, Tuple{T,T} where T can be seen as Union{Tuple{Int8,Int8}, Tuple{Int16,Int16}, ...}, where T ranges over all concrete types. This gives rise to some interesting subtyping results. For example Tuple{Real,Real} is not a subtype of Tuple{T,T} where T, because it includes some types like Tuple{Int8,Int16} where the two elements have different types. Tuple{Real,Real} and Tuple{T,T} where T have the non-trivial intersection Tuple{T,T} where T<:Real. However, Tuple{Real} is a subtype of Tuple{T} where T, because in that case T occurs only once and so is not diagonal.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Next consider a signature like the following:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(a::Array{T}, x::T, y::T) where {T} = ...","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"In this case, T occurs in invariant position inside Array{T}. That means whatever type of array is passed unambiguously determines the value of T – we say T has an equality constraint on it. Therefore in this case the diagonal rule is not really necessary, since the array determines T and we can then allow x and y to be of any subtypes of T. So variables that occur in invariant position are never considered diagonal. This choice of behavior is slightly controversial – some feel this definition should be written as","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(a::Array{T}, x::S, y::S) where {T, S<:T} = ...","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"to clarify whether x and y need to have the same type. In this version of the signature they would, or we could introduce a third variable for the type of y if x and y can have different types.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The next complication is the interaction of unions and diagonal variables, e.g.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(x::Union{Nothing,T}, y::T) where {T} = ...","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Consider what this declaration means. y has type T. x then can have either the same type T, or else be of type Nothing. So all of the following calls should match:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"f(1, 1)\nf(\"\", \"\")\nf(2.0, 2.0)\nf(nothing, 1)\nf(nothing, \"\")\nf(nothing, 2.0)","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"These examples are telling us something: when x is nothing::Nothing, there are no extra constraints on y. It is as if the method signature had y::Any. Indeed, we have the following type equivalence:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"(Tuple{Union{Nothing,T},T} where T) == Union{Tuple{Nothing,Any}, Tuple{T,T} where T}","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The general rule is: a concrete variable in covariant position acts like it's not concrete if the subtyping algorithm only uses it once. When x has type Nothing, we don't need to use the T in Union{Nothing,T}; we only use it in the second slot. This arises naturally from the observation that in Tuple{T} where T restricting T to concrete types makes no difference; the type is equal to Tuple{Any} either way.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"However, appearing in invariant position disqualifies a variable from being concrete whether that appearance of the variable is used or not. Otherwise types can behave differently depending on which other types they are compared to, making subtyping not transitive. For example, consider","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Tuple{Int,Int8,Vector{Integer}} <: Tuple{T,T,Vector{Union{Integer,T}}} where T","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"If the T inside the Union is ignored, then T is concrete and the answer is \"false\" since the first two types aren't the same. But consider instead","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Tuple{Int,Int8,Vector{Any}} <: Tuple{T,T,Vector{Union{Integer,T}}} where T","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Now we cannot ignore the T in the Union (we must have T == Any), so T is not concrete and the answer is \"true\". That would make the concreteness of T depend on the other type, which is not acceptable since a type must have a clear meaning on its own. Therefore the appearance of T inside Vector is considered in both cases.","category":"page"},{"location":"devdocs/types/#Subtyping-diagonal-variables","page":"More about types","title":"Subtyping diagonal variables","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The subtyping algorithm for diagonal variables has two components: (1) identifying variable occurrences, and (2) ensuring that diagonal variables range over concrete types only.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The first task is accomplished by keeping counters occurs_inv and occurs_cov (in src/subtype.c) for each variable in the environment, tracking the number of invariant and covariant occurrences, respectively. A variable is diagonal when occurs_inv == 0 && occurs_cov > 1.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The second task is accomplished by imposing a condition on a variable's lower bound. As the subtyping algorithm runs, it narrows the bounds of each variable (raising lower bounds and lowering upper bounds) to keep track of the range of variable values for which the subtype relation would hold. When we are done evaluating the body of a UnionAll type whose variable is diagonal, we look at the final values of the bounds. Since the variable must be concrete, a contradiction occurs if its lower bound could not be a subtype of a concrete type. For example, an abstract type like AbstractArray cannot be a subtype of a concrete type, but a concrete type like Int can be, and the empty type Bottom can be as well. If a lower bound fails this test the algorithm stops with the answer false.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"For example, in the problem Tuple{Int,String} <: Tuple{T,T} where T, we derive that this would be true if T were a supertype of Union{Int,String}. However, Union{Int,String} is an abstract type, so the relation does not hold.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"This concreteness test is done by the function is_leaf_bound. Note that this test is slightly different from jl_is_leaf_type, since it also returns true for Bottom. Currently this function is heuristic, and does not catch all possible concrete types. The difficulty is that whether a lower bound is concrete might depend on the values of other type variable bounds. For example, Vector{T} is equivalent to the concrete type Vector{Int} only if both the upper and lower bounds of T equal Int. We have not yet worked out a complete algorithm for this.","category":"page"},{"location":"devdocs/types/#Introduction-to-the-internal-machinery","page":"More about types","title":"Introduction to the internal machinery","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Most operations for dealing with types are found in the files jltypes.c and subtype.c. A good way to start is to watch subtyping in action. Build Julia with make debug and fire up Julia within a debugger. gdb debugging tips has some tips which may be useful.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Because the subtyping code is used heavily in the REPL itself – and hence breakpoints in this code get triggered often – it will be easiest if you make the following definition:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"julia> function mysubtype(a,b)\n ccall(:jl_breakpoint, Cvoid, (Any,), nothing)\n a <: b\n end","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"and then set a breakpoint in jl_breakpoint. Once this breakpoint gets triggered, you can set breakpoints in other functions.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"As a warm-up, try the following:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"mysubtype(Tuple{Int, Float64}, Tuple{Integer, Real})","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"We can make it more interesting by trying a more complex case:","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"mysubtype(Tuple{Array{Int,2}, Int8}, Tuple{Array{T}, T} where T)","category":"page"},{"location":"devdocs/types/#Subtyping-and-method-sorting","page":"More about types","title":"Subtyping and method sorting","text":"","category":"section"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"The type_morespecific functions are used for imposing a partial order on functions in method tables (from most-to-least specific). Specificity is strict; if a is more specific than b, then a does not equal b and b is not more specific than a.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"If a is a strict subtype of b, then it is automatically considered more specific. From there, type_morespecific employs some less formal rules. For example, subtype is sensitive to the number of arguments, but type_morespecific may not be. In particular, Tuple{Int,AbstractFloat} is more specific than Tuple{Integer}, even though it is not a subtype. (Of Tuple{Int,AbstractFloat} and Tuple{Integer,Float64}, neither is more specific than the other.) Likewise, Tuple{Int,Vararg{Int}} is not a subtype of Tuple{Integer}, but it is considered more specific. However, morespecific does get a bonus for length: in particular, Tuple{Int,Int} is more specific than Tuple{Int,Vararg{Int}}.","category":"page"},{"location":"devdocs/types/","page":"More about types","title":"More about types","text":"Additionally, if 2 methods are defined with identical signatures, per type-equal, then they will instead by compared by order of addition, such that the later method is more specific than the earlier one.","category":"page"},{"location":"devdocs/locks/#Proper-maintenance-and-care-of-multi-threading-locks","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"","category":"section"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following strategies are used to ensure that the code is dead-lock free (generally by addressing the 4th Coffman condition: circular wait).","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"structure code such that only one lock will need to be acquired at a time\nalways acquire shared locks in the same order, as given by the table below\navoid constructs that expect to need unrestricted recursion","category":"page"},{"location":"devdocs/locks/#Locks","page":"Proper maintenance and care of multi-threading locks","title":"Locks","text":"","category":"section"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Below are all of the locks that exist in the system and the mechanisms for using them that avoid the potential for deadlocks (no Ostrich algorithm allowed here):","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following are definitely leaf locks (level 1), and must not try to acquire any other lock:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"safepoint\nNote that this lock is acquired implicitly by JL_LOCK and JL_UNLOCK. use the _NOGC variants to avoid that for level 1 locks.While holding this lock, the code must not do any allocation or hit any safepoints. Note that there are safepoints when doing allocation, enabling / disabling GC, entering / restoring exception frames, and taking / releasing locks.\nshared_map\nfinalizers\npagealloc\ngcpermlock\nflisp\njlinstackwalk (Win32)\nResourcePool::mutex\nRLST_mutex\nllvmprintingmutex\njllockedstream::mutex\ndebuginfo_asyncsafe\ninferencetimingmutex\nExecutionEngine::SessionLock\nflisp itself is already threadsafe, this lock only protects the jl_ast_context_list_t pool likewise, the ResourcePool::mutexes just protect the associated resource pool","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is a leaf lock (level 2), and only acquires level 1 locks (safepoint) internally:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"globalrootslock\nModule->lock\nJLDebuginfoPlugin::PluginMutex\nnewlyinferredmutex","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is a level 3 lock, which can only acquire level 1 or level 2 locks internally:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Method->writelock\ntypecache","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is a level 4 lock, which can only recurse to acquire level 1, 2, or 3 locks:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"MethodTable->writelock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"No Julia code may be called while holding a lock above this point.","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"orc::ThreadSafeContext (TSCtx) locks occupy a special spot in the locking hierarchy. They are used to protect LLVM's global non-threadsafe state, but there may be an arbitrary number of them. By default, all of these locks may be treated as level 5 locks for the purposes of comparing with the rest of the hierarchy. Acquiring a TSCtx should only be done from the JIT's pool of TSCtx's, and all locks on that TSCtx should be released prior to returning it to the pool. If multiple TSCtx locks must be acquired at the same time (due to recursive compilation), then locks should be acquired in the order that the TSCtxs were borrowed from the pool.","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is a level 5 lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"JuliaOJIT::EmissionMutex","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following are a level 6 lock, which can only recurse to acquire locks at lower levels:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"codegen\njlmodulesmutex","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is an almost root lock (level end-1), meaning only the root look may be held when trying to acquire it:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"typeinf\nthis one is perhaps one of the most tricky ones, since type-inference can be invoked from many pointscurrently the lock is merged with the codegen lock, since they call each other recursively","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following lock synchronizes IO operation. Be aware that doing any I/O (for example, printing warning messages or debug information) while holding any other lock listed above may result in pernicious and hard-to-find deadlocks. BE VERY CAREFUL!","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"iolock\nIndividual ThreadSynchronizers locks\nthis may continue to be held after releasing the iolock, or acquired without it, but be very careful to never attempt to acquire the iolock while holding it\nLibdl.LazyLibrary lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following is the root lock, meaning no other lock shall be held when trying to acquire it:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"toplevel\nthis should be held while attempting a top-level action (such as making a new type or defining a new method): trying to obtain this lock inside a staged function will cause a deadlock condition!additionally, it's unclear if any code can safely run in parallel with an arbitrary toplevel expression, so it may require all threads to get to a safepoint first","category":"page"},{"location":"devdocs/locks/#Broken-Locks","page":"Proper maintenance and care of multi-threading locks","title":"Broken Locks","text":"","category":"section"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"The following locks are broken:","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"toplevel\ndoesn't exist right nowfix: create it\nModule->lock\nThis is vulnerable to deadlocks since it can't be certain it is acquired in sequence. Some operations (such as import_module) are missing a lock.fix: replace with jl_modules_mutex?\nloading.jl: require and register_root_module\nThis file potentially has numerous problems.fix: needs locks","category":"page"},{"location":"devdocs/locks/#Shared-Global-Data-Structures","page":"Proper maintenance and care of multi-threading locks","title":"Shared Global Data Structures","text":"","category":"section"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"These data structures each need locks due to being shared mutable global state. It is the inverse list for the above lock priority list. This list does not include level 1 leaf resources due to their simplicity.","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"MethodTable modifications (def, cache) : MethodTable->writelock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Type declarations : toplevel lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Type application : typecache lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Global variable tables : Module->lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Module serializer : toplevel lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"JIT & type-inference : codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"MethodInstance/CodeInstance updates : Method->writelock, codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"These are set at construction and immutable:\nspecTypes\nsparam_vals\ndef\nowner","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"These are set by jl_type_infer (while holding codegen lock):\ncache\nrettype\ninferred","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":" * valid ages","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"inInference flag:\noptimization to quickly avoid recurring into jl_type_infer while it is already running\nactual state (of setting inferred, then fptr) is protected by codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Function pointers:\nthese transition once, from NULL to a value, while the codegen lock is held\nCode-generator cache (the contents of functionObjectsDecls):\nthese can transition multiple times, but only while the codegen lock is held\nit is valid to use old version of this, or block for new versions of this, so races are benign, as long as the code is careful not to reference other data in the method instance (such as rettype) and assume it is coordinated, unless also holding the codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"LLVMContext : codegen lock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"Method : Method->writelock","category":"page"},{"location":"devdocs/locks/","page":"Proper maintenance and care of multi-threading locks","title":"Proper maintenance and care of multi-threading locks","text":"roots array (serializer and codegen)\ninvoke / specializations / tfunc modifications","category":"page"},{"location":"manual/parallel-computing/#Parallel-Computing","page":"Parallel Computing","title":"Parallel Computing","text":"","category":"section"},{"location":"manual/parallel-computing/","page":"Parallel Computing","title":"Parallel Computing","text":"Julia supports these four categories of concurrent and parallel programming:","category":"page"},{"location":"manual/parallel-computing/","page":"Parallel Computing","title":"Parallel Computing","text":"Asynchronous \"tasks\", or coroutines:\nJulia Tasks allow suspending and resuming computations for I/O, event handling, producer-consumer processes, and similar patterns. Tasks can synchronize through operations like wait and fetch, and communicate via Channels. While strictly not parallel computing by themselves, Julia lets you schedule Tasks on several threads.\nMulti-threading:\nJulia's multi-threading provides the ability to schedule Tasks simultaneously on more than one thread or CPU core, sharing memory. This is usually the easiest way to get parallelism on one's PC or on a single large multi-core server. Julia's multi-threading is composable. When one multi-threaded function calls another multi-threaded function, Julia will schedule all the threads globally on available resources, without oversubscribing.\nDistributed computing:\nDistributed computing runs multiple Julia processes with separate memory spaces. These can be on the same computer or multiple computers. The Distributed standard library provides the capability for remote execution of a Julia function. With this basic building block, it is possible to build many different kinds of distributed computing abstractions. Packages like DistributedArrays.jl are an example of such an abstraction. On the other hand, packages like MPI.jl and Elemental.jl provide access to the existing MPI ecosystem of libraries.\nGPU computing:\nThe Julia GPU compiler provides the ability to run Julia code natively on GPUs. There is a rich ecosystem of Julia packages that target GPUs. The JuliaGPU.org website provides a list of capabilities, supported GPUs, related packages and documentation.","category":"page"},{"location":"manual/style-guide/#Style-Guide","page":"Style Guide","title":"Style Guide","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The following sections explain a few aspects of idiomatic Julia coding style. None of these rules are absolute; they are only suggestions to help familiarize you with the language and to help you choose among alternative designs.","category":"page"},{"location":"manual/style-guide/#Indentation","page":"Style Guide","title":"Indentation","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Use 4 spaces per indentation level.","category":"page"},{"location":"manual/style-guide/#Write-functions,-not-just-scripts","page":"Style Guide","title":"Write functions, not just scripts","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Writing code as a series of steps at the top level is a quick way to get started solving a problem, but you should try to divide a program into functions as soon as possible. Functions are more reusable and testable, and clarify what steps are being done and what their inputs and outputs are. Furthermore, code inside functions tends to run much faster than top level code, due to how Julia's compiler works.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"It is also worth emphasizing that functions should take arguments, instead of operating directly on global variables (aside from constants like pi).","category":"page"},{"location":"manual/style-guide/#Avoid-writing-overly-specific-types","page":"Style Guide","title":"Avoid writing overly-specific types","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Code should be as generic as possible. Instead of writing:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Complex{Float64}(x)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"it's better to use available generic functions:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"complex(float(x))","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The second version will convert x to an appropriate type, instead of always the same type.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"This style point is especially relevant to function arguments. For example, don't declare an argument to be of type Int or Int32 if it really could be any integer, expressed with the abstract type Integer. In fact, in many cases you can omit the argument type altogether, unless it is needed to disambiguate from other method definitions, since a MethodError will be thrown anyway if a type is passed that does not support any of the requisite operations. (This is known as duck typing.)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"For example, consider the following definitions of a function addone that returns one plus its argument:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"addone(x::Int) = x + 1 # works only for Int\naddone(x::Integer) = x + oneunit(x) # any integer type\naddone(x::Number) = x + oneunit(x) # any numeric type\naddone(x) = x + oneunit(x) # any type supporting + and oneunit","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The last definition of addone handles any type supporting oneunit (which returns 1 in the same type as x, which avoids unwanted type promotion) and the + function with those arguments. The key thing to realize is that there is no performance penalty to defining only the general addone(x) = x + oneunit(x), because Julia will automatically compile specialized versions as needed. For example, the first time you call addone(12), Julia will automatically compile a specialized addone function for x::Int arguments, with the call to oneunit replaced by its inlined value 1. Therefore, the first three definitions of addone above are completely redundant with the fourth definition.","category":"page"},{"location":"manual/style-guide/#Handle-excess-argument-diversity-in-the-caller","page":"Style Guide","title":"Handle excess argument diversity in the caller","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Instead of:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"function foo(x, y)\n x = Int(x); y = Int(y)\n ...\nend\nfoo(x, y)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"use:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"function foo(x::Int, y::Int)\n ...\nend\nfoo(Int(x), Int(y))","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"This is better style because foo does not really accept numbers of all types; it really needs Int s.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"One issue here is that if a function inherently requires integers, it might be better to force the caller to decide how non-integers should be converted (e.g. floor or ceiling). Another issue is that declaring more specific types leaves more \"space\" for future method definitions.","category":"page"},{"location":"manual/style-guide/#bang-convention","page":"Style Guide","title":"Append ! to names of functions that modify their arguments","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Instead of:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"function double(a::AbstractArray{<:Number})\n for i in eachindex(a)\n a[i] *= 2\n end\n return a\nend","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"use:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"function double!(a::AbstractArray{<:Number})\n for i in eachindex(a)\n a[i] *= 2\n end\n return a\nend","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Julia Base uses this convention throughout and contains examples of functions with both copying and modifying forms (e.g., sort and sort!), and others which are just modifying (e.g., push!, pop!, splice!). It is typical for such functions to also return the modified array for convenience.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Functions related to IO or making use of random number generators (RNG) are notable exceptions: Since these functions almost invariably must mutate the IO or RNG, functions ending with ! are used to signify a mutation other than mutating the IO or advancing the RNG state. For example, rand(x) mutates the RNG, whereas rand!(x) mutates both the RNG and x; similarly, read(io) mutates io, whereas read!(io, x) mutates both arguments.","category":"page"},{"location":"manual/style-guide/#Avoid-strange-type-Unions","page":"Style Guide","title":"Avoid strange type Unions","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Types such as Union{Function,AbstractString} are often a sign that some design could be cleaner.","category":"page"},{"location":"manual/style-guide/#Avoid-elaborate-container-types","page":"Style Guide","title":"Avoid elaborate container types","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"It is usually not much help to construct arrays like the following:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"In this case Vector{Any}(undef, n) is better. It is also more helpful to the compiler to annotate specific uses (e.g. a[i]::Int) than to try to pack many alternatives into one type.","category":"page"},{"location":"manual/style-guide/#Prefer-exported-methods-over-direct-field-access","page":"Style Guide","title":"Prefer exported methods over direct field access","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Idiomatic Julia code should generally treat a module's exported methods as the interface to its types. An object's fields are generally considered implementation details and user code should only access them directly if this is stated to be the API. This has several benefits:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Package developers are freer to change the implementation without breaking user code.\nMethods can be passed to higher-order constructs like map (e.g. map(imag, zs)) rather than [z.im for z in zs]).\nMethods can be defined on abstract types.\nMethods can describe a conceptual operation that can be shared across disparate types (e.g. real(z) works on Complex numbers or Quaternions).","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Julia's dispatch system encourages this style because play(x::MyType) only defines the play method on that particular type, leaving other types to have their own implementation.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Similarly, non-exported functions are typically internal and subject to change, unless the documentations states otherwise. Names sometimes are given a _ prefix (or suffix) to further suggest that something is \"internal\" or an implementation-detail, but it is not a rule.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Counter-examples to this rule include NamedTuple, RegexMatch, StatStruct.","category":"page"},{"location":"manual/style-guide/#Use-naming-conventions-consistent-with-Julia-base/","page":"Style Guide","title":"Use naming conventions consistent with Julia base/","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"modules and type names use capitalization and camel case: module SparseArrays, struct UnitRange.\nfunctions are lowercase (maximum, convert) and, when readable, with multiple words squashed together (isequal, haskey). When necessary, use underscores as word separators. Underscores are also used to indicate a combination of concepts (remotecall_fetch as a more efficient implementation of fetch(remotecall(...))) or as modifiers.\nfunctions mutating at least one of their arguments end in !.\nconciseness is valued, but avoid abbreviation (indexin rather than indxin) as it becomes difficult to remember whether and how particular words are abbreviated.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"If a function name requires multiple words, consider whether it might represent more than one concept and might be better split into pieces.","category":"page"},{"location":"manual/style-guide/#Write-functions-with-argument-ordering-similar-to-Julia-Base","page":"Style Guide","title":"Write functions with argument ordering similar to Julia Base","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"As a general rule, the Base library uses the following order of arguments to functions, as applicable:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Function argument. Putting a function argument first permits the use of do blocks for passing multiline anonymous functions.\nI/O stream. Specifying the IO object first permits passing the function to functions such as sprint, e.g. sprint(show, x).\nInput being mutated. For example, in fill!(x, v), x is the object being mutated and it appears before the value to be inserted into x.\nType. Passing a type typically means that the output will have the given type. In parse(Int, \"1\"), the type comes before the string to parse. There are many such examples where the type appears first, but it's useful to note that in read(io, String), the IO argument appears before the type, which is in keeping with the order outlined here.\nInput not being mutated. In fill!(x, v), v is not being mutated and it comes after x.\nKey. For associative collections, this is the key of the key-value pair(s). For other indexed collections, this is the index.\nValue. For associative collections, this is the value of the key-value pair(s). In cases like fill!(x, v), this is v.\nEverything else. Any other arguments.\nVarargs. This refers to arguments that can be listed indefinitely at the end of a function call. For example, in Matrix{T}(undef, dims), the dimensions can be given as a Tuple, e.g. Matrix{T}(undef, (1,2)), or as Varargs, e.g. Matrix{T}(undef, 1, 2).\nKeyword arguments. In Julia keyword arguments have to come last anyway in function definitions; they're listed here for the sake of completeness.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The vast majority of functions will not take every kind of argument listed above; the numbers merely denote the precedence that should be used for any applicable arguments to a function.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"There are of course a few exceptions. For example, in convert, the type should always come first. In setindex!, the value comes before the indices so that the indices can be provided as varargs.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"When designing APIs, adhering to this general order as much as possible is likely to give users of your functions a more consistent experience.","category":"page"},{"location":"manual/style-guide/#Don't-overuse-try-catch","page":"Style Guide","title":"Don't overuse try-catch","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"It is better to avoid errors than to rely on catching them.","category":"page"},{"location":"manual/style-guide/#Don't-parenthesize-conditions","page":"Style Guide","title":"Don't parenthesize conditions","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Julia doesn't require parens around conditions in if and while. Write:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"if a == b","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"instead of:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"if (a == b)","category":"page"},{"location":"manual/style-guide/#Don't-overuse-...","page":"Style Guide","title":"Don't overuse ...","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Splicing function arguments can be addictive. Instead of [a..., b...], use simply [a; b], which already concatenates arrays. collect(a) is better than [a...], but since a is already iterable it is often even better to leave it alone, and not convert it to an array.","category":"page"},{"location":"manual/style-guide/#Ensure-constructors-return-an-instance-of-their-own-type","page":"Style Guide","title":"Ensure constructors return an instance of their own type","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"When a method T(x) is called on a type T, it is generally expected to return a value of type T. Defining a constructor that returns an unexpected type can lead to confusing and unpredictable behavior:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"julia> struct Foo{T}\n x::T\n end\n\njulia> Base.Float64(foo::Foo) = Foo(Float64(foo.x)) # Do not define methods like this\n\njulia> Float64(Foo(3)) # Should return `Float64`\nFoo{Float64}(3.0)\n\njulia> Foo{Int}(x) = Foo{Float64}(x) # Do not define methods like this\n\njulia> Foo{Int}(3) # Should return `Foo{Int}`\nFoo{Float64}(3.0)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"To maintain code clarity and ensure type consistency, always design constructors to return an instance of the type they are supposed to construct.","category":"page"},{"location":"manual/style-guide/#Don't-use-unnecessary-static-parameters","page":"Style Guide","title":"Don't use unnecessary static parameters","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"A function signature:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"foo(x::T) where {T<:Real} = ...","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"should be written as:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"foo(x::Real) = ...","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"instead, especially if T is not used in the function body. Even if T is used, it can be replaced with typeof(x) if convenient. There is no performance difference. Note that this is not a general caution against static parameters, just against uses where they are not needed.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Note also that container types, specifically may need type parameters in function calls. See the FAQ Avoid fields with abstract containers for more information.","category":"page"},{"location":"manual/style-guide/#Avoid-confusion-about-whether-something-is-an-instance-or-a-type","page":"Style Guide","title":"Avoid confusion about whether something is an instance or a type","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Sets of definitions like the following are confusing:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"foo(::Type{MyType}) = ...\nfoo(::MyType) = foo(MyType)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Decide whether the concept in question will be written as MyType or MyType(), and stick to it.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The preferred style is to use instances by default, and only add methods involving Type{MyType} later if they become necessary to solve some problems.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"If a type is effectively an enumeration, it should be defined as a single (ideally immutable struct or primitive) type, with the enumeration values being instances of it. Constructors and conversions can check whether values are valid. This design is preferred over making the enumeration an abstract type, with the \"values\" as subtypes.","category":"page"},{"location":"manual/style-guide/#Don't-overuse-macros","page":"Style Guide","title":"Don't overuse macros","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Be aware of when a macro could really be a function instead.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Calling eval inside a macro is a particularly dangerous warning sign; it means the macro will only work when called at the top level. If such a macro is written as a function instead, it will naturally have access to the run-time values it needs.","category":"page"},{"location":"manual/style-guide/#Don't-expose-unsafe-operations-at-the-interface-level","page":"Style Guide","title":"Don't expose unsafe operations at the interface level","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"If you have a type that uses a native pointer:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"mutable struct NativeType\n p::Ptr{UInt8}\n ...\nend","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"don't write definitions like the following:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"getindex(x::NativeType, i) = unsafe_load(x.p, i)","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The problem is that users of this type can write x[i] without realizing that the operation is unsafe, and then be susceptible to memory bugs.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Such a function should either check the operation to ensure it is safe, or have unsafe somewhere in its name to alert callers.","category":"page"},{"location":"manual/style-guide/#Don't-overload-methods-of-base-container-types","page":"Style Guide","title":"Don't overload methods of base container types","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"It is possible to write definitions like the following:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"show(io::IO, v::Vector{MyType}) = ...","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"This would provide custom showing of vectors with a specific new element type. While tempting, this should be avoided. The trouble is that users will expect a well-known type like Vector() to behave in a certain way, and overly customizing its behavior can make it harder to work with.","category":"page"},{"location":"manual/style-guide/#avoid-type-piracy","page":"Style Guide","title":"Avoid type piracy","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"\"Type piracy\" refers to the practice of extending or redefining methods in Base or other packages on types that you have not defined. In extreme cases, you can crash Julia (e.g. if your method extension or redefinition causes invalid input to be passed to a ccall). Type piracy can complicate reasoning about code, and may introduce incompatibilities that are hard to predict and diagnose.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"As an example, suppose you wanted to define multiplication on symbols in a module:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"module A\nimport Base.*\n*(x::Symbol, y::Symbol) = Symbol(x,y)\nend","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"The problem is that now any other module that uses Base.* will also see this definition. Since Symbol is defined in Base and is used by other modules, this can change the behavior of unrelated code unexpectedly. There are several alternatives here, including using a different function name, or wrapping the Symbols in another type that you define.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Sometimes, coupled packages may engage in type piracy to separate features from definitions, especially when the packages were designed by collaborating authors, and when the definitions are reusable. For example, one package might provide some types useful for working with colors; another package could define methods for those types that enable conversions between color spaces. Another example might be a package that acts as a thin wrapper for some C code, which another package might then pirate to implement a higher-level, Julia-friendly API.","category":"page"},{"location":"manual/style-guide/#Be-careful-with-type-equality","page":"Style Guide","title":"Be careful with type equality","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"You generally want to use isa and <: for testing types, not ==. Checking types for exact equality typically only makes sense when comparing to a known concrete type (e.g. T == Float64), or if you really, really know what you're doing.","category":"page"},{"location":"manual/style-guide/#Don't-write-a-trivial-anonymous-function-x-f(x)-for-a-named-function-f","page":"Style Guide","title":"Don't write a trivial anonymous function x->f(x) for a named function f","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Since higher-order functions are often called with anonymous functions, it is easy to conclude that this is desirable or even necessary. But any function can be passed directly, without being \"wrapped\" in an anonymous function. Instead of writing map(x->f(x), a), write map(f, a).","category":"page"},{"location":"manual/style-guide/#Avoid-using-floats-for-numeric-literals-in-generic-code-when-possible","page":"Style Guide","title":"Avoid using floats for numeric literals in generic code when possible","text":"","category":"section"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"If you write generic code which handles numbers, and which can be expected to run with many different numeric type arguments, try using literals of a numeric type that will affect the arguments as little as possible through promotion.","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"For example,","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"julia> f(x) = 2.0 * x\nf (generic function with 1 method)\n\njulia> f(1//2)\n1.0\n\njulia> f(1/2)\n1.0\n\njulia> f(1)\n2.0","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"while","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"julia> g(x) = 2 * x\ng (generic function with 1 method)\n\njulia> g(1//2)\n1//1\n\njulia> g(1/2)\n1.0\n\njulia> g(1)\n2","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"As you can see, the second version, where we used an Int literal, preserved the type of the input argument, while the first didn't. This is because e.g. promote_type(Int, Float64) == Float64, and promotion happens with the multiplication. Similarly, Rational literals are less type disruptive than Float64 literals, but more disruptive than Ints:","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"julia> h(x) = 2//1 * x\nh (generic function with 1 method)\n\njulia> h(1//2)\n1//1\n\njulia> h(1/2)\n1.0\n\njulia> h(1)\n2//1","category":"page"},{"location":"manual/style-guide/","page":"Style Guide","title":"Style Guide","text":"Thus, use Int literals when possible, with Rational{Int} for literal non-integer numbers, in order to make it easier to use your code.","category":"page"},{"location":"base/math/#Mathematics","page":"Mathematics","title":"Mathematics","text":"","category":"section"},{"location":"base/math/#math-ops","page":"Mathematics","title":"Mathematical Operators","text":"","category":"section"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Base.:-(::Any)\nBase.:(+)\nBase.:-(::Any, ::Any)\nBase.:*(::Any, ::Any...)\nBase.:(/)\nBase.:\\(::Any, ::Any)\nBase.:^(::Number, ::Number)\nBase.fma\nBase.muladd\nBase.inv(::Number)\nBase.div\nBase.div(::Any, ::Any, ::RoundingMode)\nBase.fld\nBase.cld\nBase.mod\nBase.rem\nBase.rem(::Any, ::Any, ::RoundingMode)\nBase.rem2pi\nBase.Math.mod2pi\nBase.divrem\nBase.fldmod\nBase.fld1\nBase.mod1\nBase.fldmod1\nBase.:(//)\nBase.rationalize\nBase.numerator\nBase.denominator\nBase.:(<<)\nBase.:(>>)\nBase.:(>>>)\nBase.bitrotate\nBase.:(:)\nBase.range\nBase.OneTo\nBase.StepRangeLen\nBase.logrange\nBase.LogRange\nBase.:(==)\nBase.:(!=)\nBase.:(!==)\nBase.:(<)\nBase.:(<=)\nBase.:(>)\nBase.:(>=)\nBase.cmp\nBase.:(~)\nBase.:(&)\nBase.:(|)\nBase.xor\nBase.nand\nBase.nor\nBase.:(!)\n&&\n||","category":"page"},{"location":"base/math/#Base.:--Tuple{Any}","page":"Mathematics","title":"Base.:-","text":"-(x)\n\nUnary minus operator.\n\nSee also: abs, flipsign.\n\nExamples\n\njulia> -1\n-1\n\njulia> -(2)\n-2\n\njulia> -[1 2; 3 4]\n2×2 Matrix{Int64}:\n -1 -2\n -3 -4\n\njulia> -(true) # promotes to Int\n-1\n\njulia> -(0x003)\n0xfffd\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.:+","page":"Mathematics","title":"Base.:+","text":"dt::Date + t::Time -> DateTime\n\nThe addition of a Date with a Time produces a DateTime. The hour, minute, second, and millisecond parts of the Time are used along with the year, month, and day of the Date to create the new DateTime. Non-zero microseconds or nanoseconds in the Time type will result in an InexactError being thrown.\n\n\n\n\n\n+(x, y...)\n\nAddition operator.\n\nInfix x+y+z+... calls this function with all arguments, i.e. +(x, y, z, ...), which by default then calls (x+y) + z + ... starting from the left.\n\nNote that overflow is possible for most integer types, including the default Int, when adding large numbers.\n\nExamples\n\njulia> 1 + 20 + 4\n25\n\njulia> +(1, 20, 4)\n25\n\njulia> [1,2] + [3,4]\n2-element Vector{Int64}:\n 4\n 6\n\njulia> typemax(Int) + 1 < 0\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:--Tuple{Any, Any}","page":"Mathematics","title":"Base.:-","text":"-(x, y)\n\nSubtraction operator.\n\nExamples\n\njulia> 2 - 3\n-1\n\njulia> -(2, 4.5)\n-2.5\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.:*-Tuple{Any, Vararg{Any}}","page":"Mathematics","title":"Base.:*","text":"*(x, y...)\n\nMultiplication operator.\n\nInfix x*y*z*... calls this function with all arguments, i.e. *(x, y, z, ...), which by default then calls (x*y) * z * ... starting from the left.\n\nJuxtaposition such as 2pi also calls *(2, pi). Note that this operation has higher precedence than a literal *. Note also that juxtaposition \"0x...\" (integer zero times a variable whose name starts with x) is forbidden as it clashes with unsigned integer literals: 0x01 isa UInt8.\n\nNote that overflow is possible for most integer types, including the default Int, when multiplying large numbers.\n\nExamples\n\njulia> 2 * 7 * 8\n112\n\njulia> *(2, 7, 8)\n112\n\njulia> [2 0; 0 3] * [1, 10] # matrix * vector\n2-element Vector{Int64}:\n 2\n 30\n\njulia> 1/2pi, 1/2*pi # juxtaposition has higher precedence\n(0.15915494309189535, 1.5707963267948966)\n\njulia> x = [1, 2]; x'x # adjoint vector * vector\n5\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.:/","page":"Mathematics","title":"Base.:/","text":"/(x, y)\n\nRight division operator: multiplication of x by the inverse of y on the right.\n\nGives floating-point results for integer arguments. See ÷ for integer division, or // for Rational results.\n\nExamples\n\njulia> 1/2\n0.5\n\njulia> 4/2\n2.0\n\njulia> 4.5/2\n2.25\n\n\n\n\n\nA / B\n\nMatrix right-division: A / B is equivalent to (B' \\ A')' where \\ is the left-division operator. For square matrices, the result X is such that A == X*B.\n\nSee also: rdiv!.\n\nExamples\n\njulia> A = Float64[1 4 5; 3 9 2]; B = Float64[1 4 2; 3 4 2; 8 7 1];\n\njulia> X = A / B\n2×3 Matrix{Float64}:\n -0.65 3.75 -1.2\n 3.25 -2.75 1.0\n\njulia> isapprox(A, X*B)\ntrue\n\njulia> isapprox(X, A*pinv(B))\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:\\-Tuple{Any, Any}","page":"Mathematics","title":"Base.:\\","text":"\\(x, y)\n\nLeft division operator: multiplication of y by the inverse of x on the left. Gives floating-point results for integer arguments.\n\nExamples\n\njulia> 3 \\ 6\n2.0\n\njulia> inv(3) * 6\n2.0\n\njulia> A = [4 3; 2 1]; x = [5, 6];\n\njulia> A \\ x\n2-element Vector{Float64}:\n 6.5\n -7.0\n\njulia> inv(A) * x\n2-element Vector{Float64}:\n 6.5\n -7.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.:^-Tuple{Number, Number}","page":"Mathematics","title":"Base.:^","text":"^(x, y)\n\nExponentiation operator.\n\nIf x and y are integers, the result may overflow. To enter numbers in scientific notation, use Float64 literals such as 1.2e3 rather than 1.2 * 10^3.\n\nIf y is an Int literal (e.g. 2 in x^2 or -3 in x^-3), the Julia code x^y is transformed by the compiler to Base.literal_pow(^, x, Val(y)), to enable compile-time specialization on the value of the exponent. (As a default fallback we have Base.literal_pow(^, x, Val(y)) = ^(x,y), where usually ^ == Base.^ unless ^ has been defined in the calling namespace.) If y is a negative integer literal, then Base.literal_pow transforms the operation to inv(x)^-y by default, where -y is positive.\n\nSee also exp2, <<.\n\nExamples\n\njulia> 3^5\n243\n\njulia> 3^-1 # uses Base.literal_pow\n0.3333333333333333\n\njulia> p = -1;\n\njulia> 3^p\nERROR: DomainError with -1:\nCannot raise an integer x to a negative power -1.\n[...]\n\njulia> 3.0^p\n0.3333333333333333\n\njulia> 10^19 > 0 # integer overflow\nfalse\n\njulia> big(10)^19 == 1e19\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.fma","page":"Mathematics","title":"Base.fma","text":"fma(x, y, z)\n\nComputes x*y+z without rounding the intermediate result x*y. On some systems this is significantly more expensive than x*y+z. fma is used to improve accuracy in certain algorithms. See muladd.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.muladd","page":"Mathematics","title":"Base.muladd","text":"muladd(x, y, z)\n\nCombined multiply-add: computes x*y+z, but allowing the add and multiply to be merged with each other or with surrounding operations for performance. For example, this may be implemented as an fma if the hardware supports it efficiently. The result can be different on different machines and can also be different on the same machine due to constant propagation or other optimizations. See fma.\n\nExamples\n\njulia> muladd(3, 2, 1)\n7\n\njulia> 3 * 2 + 1\n7\n\n\n\n\n\nmuladd(A, y, z)\n\nCombined multiply-add, A*y .+ z, for matrix-matrix or matrix-vector multiplication. The result is always the same size as A*y, but z may be smaller, or a scalar.\n\ncompat: Julia 1.6\nThese methods require Julia 1.6 or later.\n\nExamples\n\njulia> A=[1.0 2.0; 3.0 4.0]; B=[1.0 1.0; 1.0 1.0]; z=[0, 100];\n\njulia> muladd(A, B, z)\n2×2 Matrix{Float64}:\n 3.0 3.0\n 107.0 107.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.inv-Tuple{Number}","page":"Mathematics","title":"Base.inv","text":"inv(x)\n\nReturn the multiplicative inverse of x, such that x*inv(x) or inv(x)*x yields one(x) (the multiplicative identity) up to roundoff errors.\n\nIf x is a number, this is essentially the same as one(x)/x, but for some types inv(x) may be slightly more efficient.\n\nExamples\n\njulia> inv(2)\n0.5\n\njulia> inv(1 + 2im)\n0.2 - 0.4im\n\njulia> inv(1 + 2im) * (1 + 2im)\n1.0 + 0.0im\n\njulia> inv(2//3)\n3//2\n\ncompat: Julia 1.2\ninv(::Missing) requires at least Julia 1.2.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.div","page":"Mathematics","title":"Base.div","text":"div(x, y)\n÷(x, y)\n\nThe quotient from Euclidean (integer) division. Generally equivalent to a mathematical operation x/y without a fractional part.\n\nSee also: cld, fld, rem, divrem.\n\nExamples\n\njulia> 9 ÷ 4\n2\n\njulia> -5 ÷ 3\n-1\n\njulia> 5.0 ÷ 2\n2.0\n\njulia> div.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n -1 -1 -1 0 0 0 0 0 1 1 1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.div-Tuple{Any, Any, RoundingMode}","page":"Mathematics","title":"Base.div","text":"div(x, y, r::RoundingMode=RoundToZero)\n\nThe quotient from Euclidean (integer) division. Computes x / y, rounded to an integer according to the rounding mode r. In other words, the quantity\n\nround(x / y, r)\n\nwithout any intermediate rounding.\n\ncompat: Julia 1.4\nThe three-argument method taking a RoundingMode requires Julia 1.4 or later.\n\nSee also fld and cld, which are special cases of this function.\n\ncompat: Julia 1.9\nRoundFromZero requires at least Julia 1.9.\n\nExamples:\n\njulia> div(4, 3, RoundToZero) # Matches div(4, 3)\n1\njulia> div(4, 3, RoundDown) # Matches fld(4, 3)\n1\njulia> div(4, 3, RoundUp) # Matches cld(4, 3)\n2\njulia> div(5, 2, RoundNearest)\n2\njulia> div(5, 2, RoundNearestTiesAway)\n3\njulia> div(-5, 2, RoundNearest)\n-2\njulia> div(-5, 2, RoundNearestTiesAway)\n-3\njulia> div(-5, 2, RoundNearestTiesUp)\n-2\njulia> div(4, 3, RoundFromZero)\n2\njulia> div(-4, 3, RoundFromZero)\n-2\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.fld","page":"Mathematics","title":"Base.fld","text":"fld(x, y)\n\nLargest integer less than or equal to x / y. Equivalent to div(x, y, RoundDown).\n\nSee also div, cld, fld1.\n\nExamples\n\njulia> fld(7.3, 5.5)\n1.0\n\njulia> fld.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n -2 -2 -1 -1 -1 0 0 0 1 1 1\n\nBecause fld(x, y) implements strictly correct floored rounding based on the true value of floating-point numbers, unintuitive situations can arise. For example:\n\njulia> fld(6.0, 0.1)\n59.0\njulia> 6.0 / 0.1\n60.0\njulia> 6.0 / big(0.1)\n59.99999999999999666933092612453056361837965690217069245739573412231113406246995\n\nWhat is happening here is that the true value of the floating-point number written as 0.1 is slightly larger than the numerical value 1/10 while 6.0 represents the number 6 precisely. Therefore the true value of 6.0 / 0.1 is slightly less than 60. When doing division, this is rounded to precisely 60.0, but fld(6.0, 0.1) always takes the floor of the true value, so the result is 59.0.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.cld","page":"Mathematics","title":"Base.cld","text":"cld(x, y)\n\nSmallest integer larger than or equal to x / y. Equivalent to div(x, y, RoundUp).\n\nSee also div, fld.\n\nExamples\n\njulia> cld(5.5, 2.2)\n3.0\n\njulia> cld.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n -1 -1 -1 0 0 0 1 1 1 2 2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.mod","page":"Mathematics","title":"Base.mod","text":"mod(x::Integer, r::AbstractUnitRange)\n\nFind y in the range r such that x y (mod n), where n = length(r), i.e. y = mod(x - first(r), n) + first(r).\n\nSee also mod1.\n\nExamples\n\njulia> mod(0, Base.OneTo(3)) # mod1(0, 3)\n3\n\njulia> mod(3, 0:2) # mod(3, 3)\n0\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\n\n\n\n\nmod(x, y)\nrem(x, y, RoundDown)\n\nThe reduction of x modulo y, or equivalently, the remainder of x after floored division by y, i.e. x - y*fld(x,y) if computed without intermediate rounding.\n\nThe result will have the same sign as y, and magnitude less than abs(y) (with some exceptions, see note below).\n\nnote: Note\nWhen used with floating point values, the exact result may not be representable by the type, and so rounding error may occur. In particular, if the exact result is very close to y, then it may be rounded to y.\n\nSee also: rem, div, fld, mod1, invmod.\n\njulia> mod(8, 3)\n2\n\njulia> mod(9, 3)\n0\n\njulia> mod(8.9, 3)\n2.9000000000000004\n\njulia> mod(eps(), 3)\n2.220446049250313e-16\n\njulia> mod(-eps(), 3)\n3.0\n\njulia> mod.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n 1 2 0 1 2 0 1 2 0 1 2\n\n\n\n\n\nrem(x::Integer, T::Type{<:Integer}) -> T\nmod(x::Integer, T::Type{<:Integer}) -> T\n%(x::Integer, T::Type{<:Integer}) -> T\n\nFind y::T such that x ≡ y (mod n), where n is the number of integers representable in T, and y is an integer in [typemin(T),typemax(T)]. If T can represent any integer (e.g. T == BigInt), then this operation corresponds to a conversion to T.\n\nExamples\n\njulia> x = 129 % Int8\n-127\n\njulia> typeof(x)\nInt8\n\njulia> x = 129 % BigInt\n129\n\njulia> typeof(x)\nBigInt\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.rem","page":"Mathematics","title":"Base.rem","text":"rem(x, y)\n%(x, y)\n\nRemainder from Euclidean division, returning a value of the same sign as x, and smaller in magnitude than y. This value is always exact.\n\nSee also: div, mod, mod1, divrem.\n\nExamples\n\njulia> x = 15; y = 4;\n\njulia> x % y\n3\n\njulia> x == div(x, y) * y + rem(x, y)\ntrue\n\njulia> rem.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n -2 -1 0 -2 -1 0 1 2 0 1 2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.rem-Tuple{Any, Any, RoundingMode}","page":"Mathematics","title":"Base.rem","text":"rem(x, y, r::RoundingMode=RoundToZero)\n\nCompute the remainder of x after integer division by y, with the quotient rounded according to the rounding mode r. In other words, the quantity\n\nx - y * round(x / y, r)\n\nwithout any intermediate rounding.\n\nif r == RoundNearest, then the result is exact, and in the interval -y 2 y 2. See also RoundNearest.\nif r == RoundToZero (default), then the result is exact, and in the interval 0 y) if x is positive, or (-y 0 otherwise. See also RoundToZero.\nif r == RoundDown, then the result is in the interval 0 y) if y is positive, or (y 0 otherwise. The result may not be exact if x and y have different signs, and abs(x) < abs(y). See also RoundDown.\nif r == RoundUp, then the result is in the interval (-y 0 if y is positive, or 0 -y) otherwise. The result may not be exact if x and y have the same sign, and abs(x) < abs(y). See also RoundUp.\nif r == RoundFromZero, then the result is in the interval (-y 0 if y is positive, or 0 -y) otherwise. The result may not be exact if x and y have the same sign, and abs(x) < abs(y). See also RoundFromZero.\n\ncompat: Julia 1.9\nRoundFromZero requires at least Julia 1.9.\n\nExamples:\n\njulia> x = 9; y = 4;\n\njulia> x % y # same as rem(x, y)\n1\n\njulia> x ÷ y # same as div(x, y)\n2\n\njulia> x == div(x, y) * y + rem(x, y)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.rem2pi","page":"Mathematics","title":"Base.Math.rem2pi","text":"rem2pi(x, r::RoundingMode)\n\nCompute the remainder of x after integer division by 2π, with the quotient rounded according to the rounding mode r. In other words, the quantity\n\nx - 2π*round(x/(2π),r)\n\nwithout any intermediate rounding. This internally uses a high precision approximation of 2π, and so will give a more accurate result than rem(x,2π,r)\n\nif r == RoundNearest, then the result is in the interval -π π. This will generally be the most accurate result. See also RoundNearest.\nif r == RoundToZero, then the result is in the interval 0 2π if x is positive,. or -2π 0 otherwise. See also RoundToZero.\nif r == RoundDown, then the result is in the interval 0 2π. See also RoundDown.\nif r == RoundUp, then the result is in the interval -2π 0. See also RoundUp.\n\nExamples\n\njulia> rem2pi(7pi/4, RoundNearest)\n-0.7853981633974485\n\njulia> rem2pi(7pi/4, RoundDown)\n5.497787143782138\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.mod2pi","page":"Mathematics","title":"Base.Math.mod2pi","text":"mod2pi(x)\n\nModulus after division by 2π, returning in the range 02π).\n\nThis function computes a floating point representation of the modulus after division by numerically exact 2π, and is therefore not exactly the same as mod(x,2π), which would compute the modulus of x relative to division by the floating-point number 2π.\n\nnote: Note\nDepending on the format of the input value, the closest representable value to 2π may be less than 2π. For example, the expression mod2pi(2π) will not return 0, because the intermediate value of 2*π is a Float64 and 2*Float64(π) < 2*big(π). See rem2pi for more refined control of this behavior.\n\nExamples\n\njulia> mod2pi(9*pi/4)\n0.7853981633974481\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.divrem","page":"Mathematics","title":"Base.divrem","text":"divrem(x, y, r::RoundingMode=RoundToZero)\n\nThe quotient and remainder from Euclidean division. Equivalent to (div(x, y, r), rem(x, y, r)). Equivalently, with the default value of r, this call is equivalent to (x ÷ y, x % y).\n\nSee also: fldmod, cld.\n\nExamples\n\njulia> divrem(3, 7)\n(0, 3)\n\njulia> divrem(7, 3)\n(2, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.fldmod","page":"Mathematics","title":"Base.fldmod","text":"fldmod(x, y)\n\nThe floored quotient and modulus after division. A convenience wrapper for divrem(x, y, RoundDown). Equivalent to (fld(x, y), mod(x, y)).\n\nSee also: fld, cld, fldmod1.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.fld1","page":"Mathematics","title":"Base.fld1","text":"fld1(x, y)\n\nFlooring division, returning a value consistent with mod1(x,y)\n\nSee also mod1, fldmod1.\n\nExamples\n\njulia> x = 15; y = 4;\n\njulia> fld1(x, y)\n4\n\njulia> x == fld(x, y) * y + mod(x, y)\ntrue\n\njulia> x == (fld1(x, y) - 1) * y + mod1(x, y)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.mod1","page":"Mathematics","title":"Base.mod1","text":"mod1(x, y)\n\nModulus after flooring division, returning a value r such that mod(r, y) == mod(x, y) in the range (0 y for positive y and in the range y0) for negative y.\n\nWith integer arguments and positive y, this is equal to mod(x, 1:y), and hence natural for 1-based indexing. By comparison, mod(x, y) == mod(x, 0:y-1) is natural for computations with offsets or strides.\n\nSee also mod, fld1, fldmod1.\n\nExamples\n\njulia> mod1(4, 2)\n2\n\njulia> mod1.(-5:5, 3)'\n1×11 adjoint(::Vector{Int64}) with eltype Int64:\n 1 2 3 1 2 3 1 2 3 1 2\n\njulia> mod1.([-0.1, 0, 0.1, 1, 2, 2.9, 3, 3.1]', 3)\n1×8 Matrix{Float64}:\n 2.9 3.0 0.1 1.0 2.0 2.9 3.0 0.1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.fldmod1","page":"Mathematics","title":"Base.fldmod1","text":"fldmod1(x, y)\n\nReturn (fld1(x,y), mod1(x,y)).\n\nSee also fld1, mod1.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.://","page":"Mathematics","title":"Base.://","text":"//(num, den)\n\nDivide two integers or rational numbers, giving a Rational result. More generally, // can be used for exact rational division of other numeric types with integer or rational components, such as complex numbers with integer components.\n\nNote that floating-point (AbstractFloat) arguments are not permitted by // (even if the values are rational). The arguments must be subtypes of Integer, Rational, or composites thereof.\n\nExamples\n\njulia> 3 // 5\n3//5\n\njulia> (3 // 5) // (2 // 1)\n3//10\n\njulia> (1+2im) // (3+4im)\n11//25 + 2//25*im\n\njulia> 1.0 // 2\nERROR: MethodError: no method matching //(::Float64, ::Int64)\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.rationalize","page":"Mathematics","title":"Base.rationalize","text":"rationalize([T<:Integer=Int,] x; tol::Real=eps(x))\n\nApproximate floating point number x as a Rational number with components of the given integer type. The result will differ from x by no more than tol.\n\nExamples\n\njulia> rationalize(5.6)\n28//5\n\njulia> a = rationalize(BigInt, 10.3)\n103//10\n\njulia> typeof(numerator(a))\nBigInt\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.numerator","page":"Mathematics","title":"Base.numerator","text":"numerator(x)\n\nNumerator of the rational representation of x.\n\nExamples\n\njulia> numerator(2//3)\n2\n\njulia> numerator(4)\n4\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.denominator","page":"Mathematics","title":"Base.denominator","text":"denominator(x)\n\nDenominator of the rational representation of x.\n\nExamples\n\njulia> denominator(2//3)\n3\n\njulia> denominator(4)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:<<","page":"Mathematics","title":"Base.:<<","text":"<<(x, n)\n\nLeft bit shift operator, x << n. For n >= 0, the result is x shifted left by n bits, filling with 0s. This is equivalent to x * 2^n. For n < 0, this is equivalent to x >> -n.\n\nExamples\n\njulia> Int8(3) << 2\n12\n\njulia> bitstring(Int8(3))\n\"00000011\"\n\njulia> bitstring(Int8(12))\n\"00001100\"\n\nSee also >>, >>>, exp2, ldexp.\n\n\n\n\n\n<<(B::BitVector, n) -> BitVector\n\nLeft bit shift operator, B << n. For n >= 0, the result is B with elements shifted n positions backwards, filling with false values. If n < 0, elements are shifted forwards. Equivalent to B >> -n.\n\nExamples\n\njulia> B = BitVector([true, false, true, false, false])\n5-element BitVector:\n 1\n 0\n 1\n 0\n 0\n\njulia> B << 1\n5-element BitVector:\n 0\n 1\n 0\n 0\n 0\n\njulia> B << -1\n5-element BitVector:\n 0\n 1\n 0\n 1\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:>>","page":"Mathematics","title":"Base.:>>","text":">>(x, n)\n\nRight bit shift operator, x >> n. For n >= 0, the result is x shifted right by n bits, filling with 0s if x >= 0, 1s if x < 0, preserving the sign of x. This is equivalent to fld(x, 2^n). For n < 0, this is equivalent to x << -n.\n\nExamples\n\njulia> Int8(13) >> 2\n3\n\njulia> bitstring(Int8(13))\n\"00001101\"\n\njulia> bitstring(Int8(3))\n\"00000011\"\n\njulia> Int8(-14) >> 2\n-4\n\njulia> bitstring(Int8(-14))\n\"11110010\"\n\njulia> bitstring(Int8(-4))\n\"11111100\"\n\nSee also >>>, <<.\n\n\n\n\n\n>>(B::BitVector, n) -> BitVector\n\nRight bit shift operator, B >> n. For n >= 0, the result is B with elements shifted n positions forward, filling with false values. If n < 0, elements are shifted backwards. Equivalent to B << -n.\n\nExamples\n\njulia> B = BitVector([true, false, true, false, false])\n5-element BitVector:\n 1\n 0\n 1\n 0\n 0\n\njulia> B >> 1\n5-element BitVector:\n 0\n 1\n 0\n 1\n 0\n\njulia> B >> -1\n5-element BitVector:\n 0\n 1\n 0\n 0\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:>>>","page":"Mathematics","title":"Base.:>>>","text":">>>(x, n)\n\nUnsigned right bit shift operator, x >>> n. For n >= 0, the result is x shifted right by n bits, filling with 0s. For n < 0, this is equivalent to x << -n.\n\nFor Unsigned integer types, this is equivalent to >>. For Signed integer types, this is equivalent to signed(unsigned(x) >> n).\n\nExamples\n\njulia> Int8(-14) >>> 2\n60\n\njulia> bitstring(Int8(-14))\n\"11110010\"\n\njulia> bitstring(Int8(60))\n\"00111100\"\n\nBigInts are treated as if having infinite size, so no filling is required and this is equivalent to >>.\n\nSee also >>, <<.\n\n\n\n\n\n>>>(B::BitVector, n) -> BitVector\n\nUnsigned right bitshift operator, B >>> n. Equivalent to B >> n. See >> for details and examples.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.bitrotate","page":"Mathematics","title":"Base.bitrotate","text":"bitrotate(x::Base.BitInteger, k::Integer)\n\nbitrotate(x, k) implements bitwise rotation. It returns the value of x with its bits rotated left k times. A negative value of k will rotate to the right instead.\n\ncompat: Julia 1.5\nThis function requires Julia 1.5 or later.\n\nSee also: <<, circshift, BitArray.\n\njulia> bitrotate(UInt8(114), 2)\n0xc9\n\njulia> bitstring(bitrotate(0b01110010, 2))\n\"11001001\"\n\njulia> bitstring(bitrotate(0b01110010, -2))\n\"10011100\"\n\njulia> bitstring(bitrotate(0b01110010, 8))\n\"01110010\"\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.::","page":"Mathematics","title":"Base.::","text":":expr\n\nQuote an expression expr, returning the abstract syntax tree (AST) of expr. The AST may be of type Expr, Symbol, or a literal value. The syntax :identifier evaluates to a Symbol.\n\nSee also: Expr, Symbol, Meta.parse\n\nExamples\n\njulia> expr = :(a = b + 2*x)\n:(a = b + 2x)\n\njulia> sym = :some_identifier\n:some_identifier\n\njulia> value = :0xff\n0xff\n\njulia> typeof((expr, sym, value))\nTuple{Expr, Symbol, UInt8}\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.range","page":"Mathematics","title":"Base.range","text":"range(start, stop, length)\nrange(start, stop; length, step)\nrange(start; length, stop, step)\nrange(;start, length, stop, step)\n\nConstruct a specialized array with evenly spaced elements and optimized storage (an AbstractRange) from the arguments. Mathematically a range is uniquely determined by any three of start, step, stop and length. Valid invocations of range are:\n\nCall range with any three of start, step, stop, length.\nCall range with two of start, stop, length. In this case step will be assumed to be one. If both arguments are Integers, a UnitRange will be returned.\nCall range with one of stop or length. start and step will be assumed to be one.\n\nSee Extended Help for additional details on the returned type. See also logrange for logarithmically spaced points.\n\nExamples\n\njulia> range(1, length=100)\n1:100\n\njulia> range(1, stop=100)\n1:100\n\njulia> range(1, step=5, length=100)\n1:5:496\n\njulia> range(1, step=5, stop=100)\n1:5:96\n\njulia> range(1, 10, length=101)\n1.0:0.09:10.0\n\njulia> range(1, 100, step=5)\n1:5:96\n\njulia> range(stop=10, length=5)\n6:10\n\njulia> range(stop=10, step=1, length=5)\n6:1:10\n\njulia> range(start=1, step=1, stop=10)\n1:1:10\n\njulia> range(; length = 10)\nBase.OneTo(10)\n\njulia> range(; stop = 6)\nBase.OneTo(6)\n\njulia> range(; stop = 6.5)\n1.0:1.0:6.0\n\nIf length is not specified and stop - start is not an integer multiple of step, a range that ends before stop will be produced.\n\njulia> range(1, 3.5, step=2)\n1.0:2.0:3.0\n\nSpecial care is taken to ensure intermediate values are computed rationally. To avoid this induced overhead, see the LinRange constructor.\n\ncompat: Julia 1.1\nstop as a positional argument requires at least Julia 1.1.\n\ncompat: Julia 1.7\nThe versions without keyword arguments and start as a keyword argument require at least Julia 1.7.\n\ncompat: Julia 1.8\nThe versions with stop as a sole keyword argument, or length as a sole keyword argument require at least Julia 1.8.\n\nExtended Help\n\nrange will produce a Base.OneTo when the arguments are Integers and\n\nOnly length is provided\nOnly stop is provided\n\nrange will produce a UnitRange when the arguments are Integers and\n\nOnly start and stop are provided\nOnly length and stop are provided\n\nA UnitRange is not produced if step is provided even if specified as one.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.OneTo","page":"Mathematics","title":"Base.OneTo","text":"Base.OneTo(n)\n\nDefine an AbstractUnitRange that behaves like 1:n, with the added distinction that the lower limit is guaranteed (by the type system) to be 1.\n\n\n\n\n\n","category":"type"},{"location":"base/math/#Base.StepRangeLen","page":"Mathematics","title":"Base.StepRangeLen","text":"StepRangeLen( ref::R, step::S, len, [offset=1]) where { R,S}\nStepRangeLen{T,R,S}( ref::R, step::S, len, [offset=1]) where {T,R,S}\nStepRangeLen{T,R,S,L}(ref::R, step::S, len, [offset=1]) where {T,R,S,L}\n\nA range r where r[i] produces values of type T (in the first form, T is deduced automatically), parameterized by a reference value, a step, and the length. By default ref is the starting value r[1], but alternatively you can supply it as the value of r[offset] for some other index 1 <= offset <= len. The syntax a:b or a:b:c, where any of a, b, or c are floating-point numbers, creates a StepRangeLen.\n\ncompat: Julia 1.7\nThe 4th type parameter L requires at least Julia 1.7.\n\n\n\n\n\n","category":"type"},{"location":"base/math/#Base.logrange","page":"Mathematics","title":"Base.logrange","text":"logrange(start, stop, length)\nlogrange(start, stop; length)\n\nConstruct a specialized array whose elements are spaced logarithmically between the given endpoints. That is, the ratio of successive elements is a constant, calculated from the length.\n\nThis is similar to geomspace in Python. Unlike PowerRange in Mathematica, you specify the number of elements not the ratio. Unlike logspace in Python and Matlab, the start and stop arguments are always the first and last elements of the result, not powers applied to some base.\n\nExamples\n\njulia> logrange(10, 4000, length=3)\n3-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}:\n 10.0, 200.0, 4000.0\n\njulia> ans[2] ≈ sqrt(10 * 4000) # middle element is the geometric mean\ntrue\n\njulia> range(10, 40, length=3)[2] ≈ (10 + 40)/2 # arithmetic mean\ntrue\n\njulia> logrange(1f0, 32f0, 11)\n11-element Base.LogRange{Float32, Float64}:\n 1.0, 1.41421, 2.0, 2.82843, 4.0, 5.65685, 8.0, 11.3137, 16.0, 22.6274, 32.0\n\njulia> logrange(1, 1000, length=4) ≈ 10 .^ (0:3)\ntrue\n\nSee the LogRange type for further details.\n\nSee also range for linearly spaced points.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.LogRange","page":"Mathematics","title":"Base.LogRange","text":"LogRange{T}(start, stop, len) <: AbstractVector{T}\n\nA range whose elements are spaced logarithmically between start and stop, with spacing controlled by len. Returned by logrange.\n\nLike LinRange, the first and last elements will be exactly those provided, but intermediate values may have small floating-point errors. These are calculated using the logs of the endpoints, which are stored on construction, often in higher precision than T.\n\nExamples\n\njulia> logrange(1, 4, length=5)\n5-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}:\n 1.0, 1.41421, 2.0, 2.82843, 4.0\n\njulia> Base.LogRange{Float16}(1, 4, 5)\n5-element Base.LogRange{Float16, Float64}:\n 1.0, 1.414, 2.0, 2.828, 4.0\n\njulia> logrange(1e-310, 1e-300, 11)[1:2:end]\n6-element Vector{Float64}:\n 1.0e-310\n 9.999999999999974e-309\n 9.999999999999981e-307\n 9.999999999999988e-305\n 9.999999999999994e-303\n 1.0e-300\n\njulia> prevfloat(1e-308, 5) == ans[2]\ntrue\n\nNote that integer eltype T is not allowed. Use for instance round.(Int, xs), or explicit powers of some integer base:\n\njulia> xs = logrange(1, 512, 4)\n4-element Base.LogRange{Float64, Base.TwicePrecision{Float64}}:\n 1.0, 8.0, 64.0, 512.0\n\njulia> 2 .^ (0:3:9) |> println\n[1, 8, 64, 512]\n\ncompat: Julia 1.11\nThis type requires at least Julia 1.11.\n\n\n\n\n\n","category":"type"},{"location":"base/math/#Base.:==","page":"Mathematics","title":"Base.:==","text":"==(x, y)\n\nGeneric equality operator. Falls back to ===. Should be implemented for all types with a notion of equality, based on the abstract value that an instance represents. For example, all numeric types are compared by numeric value, ignoring type. Strings are compared as sequences of characters, ignoring encoding. Collections of the same type generally compare their key sets, and if those are ==, then compare the values for each of those keys, returning true if all such pairs are ==. Other properties are typically not taken into account (such as the exact type).\n\nThis operator follows IEEE semantics for floating-point numbers: 0.0 == -0.0 and NaN != NaN.\n\nThe result is of type Bool, except when one of the operands is missing, in which case missing is returned (three-valued logic). Collections generally implement three-valued logic akin to all, returning missing if any operands contain missing values and all other pairs are equal. Use isequal or === to always get a Bool result.\n\nImplementation\n\nNew numeric types should implement this function for two arguments of the new type, and handle comparison to other types via promotion rules where possible.\n\nisequal falls back to ==, so new methods of == will be used by the Dict type to compare keys. If your type will be used as a dictionary key, it should therefore also implement hash.\n\nIf some type defines ==, isequal, and isless then it should also implement < to ensure consistency of comparisons.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:!=","page":"Mathematics","title":"Base.:!=","text":"!=(x, y)\n≠(x,y)\n\nNot-equals comparison operator. Always gives the opposite answer as ==.\n\nImplementation\n\nNew types should generally not implement this, and rely on the fallback definition !=(x,y) = !(x==y) instead.\n\nExamples\n\njulia> 3 != 2\ntrue\n\njulia> \"foo\" ≠ \"foo\"\nfalse\n\n\n\n\n\n!=(x)\n\nCreate a function that compares its argument to x using !=, i.e. a function equivalent to y -> y != x. The returned function is of type Base.Fix2{typeof(!=)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:!==","page":"Mathematics","title":"Base.:!==","text":"!==(x, y)\n≢(x,y)\n\nAlways gives the opposite answer as ===.\n\nExamples\n\njulia> a = [1, 2]; b = [1, 2];\n\njulia> a ≢ b\ntrue\n\njulia> a ≢ a\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:<","page":"Mathematics","title":"Base.:<","text":"<(x, y)\n\nLess-than comparison operator. Falls back to isless. Because of the behavior of floating-point NaN values, this operator implements a partial order.\n\nImplementation\n\nNew types with a canonical partial order should implement this function for two arguments of the new type. Types with a canonical total order should implement isless instead.\n\nSee also isunordered.\n\nExamples\n\njulia> 'a' < 'b'\ntrue\n\njulia> \"abc\" < \"abd\"\ntrue\n\njulia> 5 < 3\nfalse\n\n\n\n\n\n<(x)\n\nCreate a function that compares its argument to x using <, i.e. a function equivalent to y -> y < x. The returned function is of type Base.Fix2{typeof(<)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:<=","page":"Mathematics","title":"Base.:<=","text":"<=(x, y)\n≤(x,y)\n\nLess-than-or-equals comparison operator. Falls back to (x < y) | (x == y).\n\nExamples\n\njulia> 'a' <= 'b'\ntrue\n\njulia> 7 ≤ 7 ≤ 9\ntrue\n\njulia> \"abc\" ≤ \"abc\"\ntrue\n\njulia> 5 <= 3\nfalse\n\n\n\n\n\n<=(x)\n\nCreate a function that compares its argument to x using <=, i.e. a function equivalent to y -> y <= x. The returned function is of type Base.Fix2{typeof(<=)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:>","page":"Mathematics","title":"Base.:>","text":">(x, y)\n\nGreater-than comparison operator. Falls back to y < x.\n\nImplementation\n\nGenerally, new types should implement < instead of this function, and rely on the fallback definition >(x, y) = y < x.\n\nExamples\n\njulia> 'a' > 'b'\nfalse\n\njulia> 7 > 3 > 1\ntrue\n\njulia> \"abc\" > \"abd\"\nfalse\n\njulia> 5 > 3\ntrue\n\n\n\n\n\n>(x)\n\nCreate a function that compares its argument to x using >, i.e. a function equivalent to y -> y > x. The returned function is of type Base.Fix2{typeof(>)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:>=","page":"Mathematics","title":"Base.:>=","text":">=(x, y)\n≥(x,y)\n\nGreater-than-or-equals comparison operator. Falls back to y <= x.\n\nExamples\n\njulia> 'a' >= 'b'\nfalse\n\njulia> 7 ≥ 7 ≥ 3\ntrue\n\njulia> \"abc\" ≥ \"abc\"\ntrue\n\njulia> 5 >= 3\ntrue\n\n\n\n\n\n>=(x)\n\nCreate a function that compares its argument to x using >=, i.e. a function equivalent to y -> y >= x. The returned function is of type Base.Fix2{typeof(>=)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.2\nThis functionality requires at least Julia 1.2.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.cmp","page":"Mathematics","title":"Base.cmp","text":"cmp(x,y)\n\nReturn -1, 0, or 1 depending on whether x is less than, equal to, or greater than y, respectively. Uses the total order implemented by isless.\n\nExamples\n\njulia> cmp(1, 2)\n-1\n\njulia> cmp(2, 1)\n1\n\njulia> cmp(2+im, 3-im)\nERROR: MethodError: no method matching isless(::Complex{Int64}, ::Complex{Int64})\n[...]\n\n\n\n\n\ncmp(<, x, y)\n\nReturn -1, 0, or 1 depending on whether x is less than, equal to, or greater than y, respectively. The first argument specifies a less-than comparison function to use.\n\n\n\n\n\ncmp(a::AbstractString, b::AbstractString) -> Int\n\nCompare two strings. Return 0 if both strings have the same length and the character at each index is the same in both strings. Return -1 if a is a prefix of b, or if a comes before b in alphabetical order. Return 1 if b is a prefix of a, or if b comes before a in alphabetical order (technically, lexicographical order by Unicode code points).\n\nExamples\n\njulia> cmp(\"abc\", \"abc\")\n0\n\njulia> cmp(\"ab\", \"abc\")\n-1\n\njulia> cmp(\"abc\", \"ab\")\n1\n\njulia> cmp(\"ab\", \"ac\")\n-1\n\njulia> cmp(\"ac\", \"ab\")\n1\n\njulia> cmp(\"α\", \"a\")\n1\n\njulia> cmp(\"b\", \"β\")\n-1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:~","page":"Mathematics","title":"Base.:~","text":"~(x)\n\nBitwise not.\n\nSee also: !, &, |.\n\nExamples\n\njulia> ~4\n-5\n\njulia> ~10\n-11\n\njulia> ~true\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:&","page":"Mathematics","title":"Base.:&","text":"x & y\n\nBitwise and. Implements three-valued logic, returning missing if one operand is missing and the other is true. Add parentheses for function application form: (&)(x, y).\n\nSee also: |, xor, &&.\n\nExamples\n\njulia> 4 & 10\n0\n\njulia> 4 & 12\n4\n\njulia> true & missing\nmissing\n\njulia> false & missing\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:|","page":"Mathematics","title":"Base.:|","text":"x | y\n\nBitwise or. Implements three-valued logic, returning missing if one operand is missing and the other is false.\n\nSee also: &, xor, ||.\n\nExamples\n\njulia> 4 | 10\n14\n\njulia> 4 | 1\n5\n\njulia> true | missing\ntrue\n\njulia> false | missing\nmissing\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.xor","page":"Mathematics","title":"Base.xor","text":"xor(x, y)\n⊻(x, y)\n\nBitwise exclusive or of x and y. Implements three-valued logic, returning missing if one of the arguments is missing.\n\nThe infix operation a ⊻ b is a synonym for xor(a,b), and ⊻ can be typed by tab-completing \\xor or \\veebar in the Julia REPL.\n\nExamples\n\njulia> xor(true, false)\ntrue\n\njulia> xor(true, true)\nfalse\n\njulia> xor(true, missing)\nmissing\n\njulia> false ⊻ false\nfalse\n\njulia> [true; true; false] .⊻ [true; false; false]\n3-element BitVector:\n 0\n 1\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.nand","page":"Mathematics","title":"Base.nand","text":"nand(x, y)\n⊼(x, y)\n\nBitwise nand (not and) of x and y. Implements three-valued logic, returning missing if one of the arguments is missing.\n\nThe infix operation a ⊼ b is a synonym for nand(a,b), and ⊼ can be typed by tab-completing \\nand or \\barwedge in the Julia REPL.\n\nExamples\n\njulia> nand(true, false)\ntrue\n\njulia> nand(true, true)\nfalse\n\njulia> nand(true, missing)\nmissing\n\njulia> false ⊼ false\ntrue\n\njulia> [true; true; false] .⊼ [true; false; false]\n3-element BitVector:\n 0\n 1\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.nor","page":"Mathematics","title":"Base.nor","text":"nor(x, y)\n⊽(x, y)\n\nBitwise nor (not or) of x and y. Implements three-valued logic, returning missing if one of the arguments is missing and the other is not true.\n\nThe infix operation a ⊽ b is a synonym for nor(a,b), and ⊽ can be typed by tab-completing \\nor or \\barvee in the Julia REPL.\n\nExamples\n\njulia> nor(true, false)\nfalse\n\njulia> nor(true, true)\nfalse\n\njulia> nor(true, missing)\nfalse\n\njulia> false ⊽ false\ntrue\n\njulia> false ⊽ missing\nmissing\n\njulia> [true; true; false] .⊽ [true; false; false]\n3-element BitVector:\n 0\n 0\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.:!","page":"Mathematics","title":"Base.:!","text":"!(x)\n\nBoolean not. Implements three-valued logic, returning missing if x is missing.\n\nSee also ~ for bitwise not.\n\nExamples\n\njulia> !true\nfalse\n\njulia> !false\ntrue\n\njulia> !missing\nmissing\n\njulia> .![true false true]\n1×3 BitMatrix:\n 0 1 0\n\n\n\n\n\n!f::Function\n\nPredicate function negation: when the argument of ! is a function, it returns a composed function which computes the boolean negation of f.\n\nSee also ∘.\n\nExamples\n\njulia> str = \"∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε\"\n\"∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε\"\n\njulia> filter(isletter, str)\n\"εδxyδfxfyε\"\n\njulia> filter(!isletter, str)\n\"∀ > 0, ∃ > 0: |-| < ⇒ |()-()| < \"\n\ncompat: Julia 1.9\nStarting with Julia 1.9, !f returns a ComposedFunction instead of an anonymous function.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#&&","page":"Mathematics","title":"&&","text":"x && y\n\nShort-circuiting boolean AND.\n\nSee also &, the ternary operator ? :, and the manual section on control flow.\n\nExamples\n\njulia> x = 3;\n\njulia> x > 1 && x < 10 && x isa Int\ntrue\n\njulia> x < 0 && error(\"expected positive x\")\nfalse\n\n\n\n\n\n","category":"keyword"},{"location":"base/math/#||","page":"Mathematics","title":"||","text":"x || y\n\nShort-circuiting boolean OR.\n\nSee also: |, xor, &&.\n\nExamples\n\njulia> pi < 3 || ℯ < 3\ntrue\n\njulia> false || true || println(\"neither is true!\")\ntrue\n\n\n\n\n\n","category":"keyword"},{"location":"base/math/#Mathematical-Functions","page":"Mathematics","title":"Mathematical Functions","text":"","category":"section"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Base.isapprox\nBase.sin(::Number)\nBase.cos(::Number)\nBase.sincos(::Float64)\nBase.tan(::Number)\nBase.Math.sind\nBase.Math.cosd\nBase.Math.tand\nBase.Math.sincosd\nBase.Math.sinpi\nBase.Math.cospi\nBase.Math.sincospi\nBase.sinh(::Number)\nBase.cosh(::Number)\nBase.tanh(::Number)\nBase.asin(::Number)\nBase.acos(::Number)\nBase.atan(::Number)\nBase.Math.asind\nBase.Math.acosd\nBase.Math.atand\nBase.Math.sec(::Number)\nBase.Math.csc(::Number)\nBase.Math.cot(::Number)\nBase.Math.secd\nBase.Math.cscd\nBase.Math.cotd\nBase.Math.asec(::Number)\nBase.Math.acsc(::Number)\nBase.Math.acot(::Number)\nBase.Math.asecd\nBase.Math.acscd\nBase.Math.acotd\nBase.Math.sech(::Number)\nBase.Math.csch(::Number)\nBase.Math.coth(::Number)\nBase.asinh(::Number)\nBase.acosh(::Number)\nBase.atanh(::Number)\nBase.Math.asech(::Number)\nBase.Math.acsch(::Number)\nBase.Math.acoth(::Number)\nBase.Math.sinc\nBase.Math.cosc\nBase.Math.deg2rad\nBase.Math.rad2deg\nBase.Math.hypot\nBase.log(::Number)\nBase.log(::Number, ::Number)\nBase.log2\nBase.log10\nBase.log1p\nBase.Math.frexp\nBase.exp(::Float64)\nBase.exp2\nBase.exp10\nBase.Math.ldexp\nBase.Math.modf\nBase.expm1\nBase.round\nBase.Rounding.RoundingMode\nBase.Rounding.RoundNearest\nBase.Rounding.RoundNearestTiesAway\nBase.Rounding.RoundNearestTiesUp\nBase.Rounding.RoundToZero\nBase.Rounding.RoundFromZero\nBase.Rounding.RoundUp\nBase.Rounding.RoundDown\nBase.round(::Complex{<: AbstractFloat}, ::RoundingMode, ::RoundingMode)\nBase.ceil\nBase.floor\nBase.trunc\nBase.unsafe_trunc\nBase.min\nBase.max\nBase.minmax\nBase.Math.clamp\nBase.Math.clamp!\nBase.abs\nBase.Checked\nBase.Checked.checked_abs\nBase.Checked.checked_neg\nBase.Checked.checked_add\nBase.Checked.checked_sub\nBase.Checked.checked_mul\nBase.Checked.checked_div\nBase.Checked.checked_rem\nBase.Checked.checked_fld\nBase.Checked.checked_mod\nBase.Checked.checked_cld\nBase.Checked.checked_pow\nBase.Checked.add_with_overflow\nBase.Checked.sub_with_overflow\nBase.Checked.mul_with_overflow\nBase.abs2\nBase.copysign\nBase.sign\nBase.signbit\nBase.flipsign\nBase.sqrt(::Number)\nBase.isqrt\nBase.Math.cbrt(::AbstractFloat)\nBase.real\nBase.imag\nBase.reim\nBase.conj\nBase.angle\nBase.cis\nBase.cispi\nBase.binomial\nBase.factorial\nBase.gcd\nBase.lcm\nBase.gcdx\nBase.ispow2\nBase.nextpow\nBase.prevpow\nBase.nextprod\nBase.invmod\nBase.powermod\nBase.ndigits\nBase.add_sum\nBase.widemul\nBase.Math.evalpoly\nBase.Math.@evalpoly\nBase.FastMath.@fastmath","category":"page"},{"location":"base/math/#Base.isapprox","page":"Mathematics","title":"Base.isapprox","text":"isapprox(x, y; atol::Real=0, rtol::Real=atol>0 ? 0 : √eps, nans::Bool=false[, norm::Function])\n\nInexact equality comparison. Two numbers compare equal if their relative distance or their absolute distance is within tolerance bounds: isapprox returns true if norm(x-y) <= max(atol, rtol*max(norm(x), norm(y))). The default atol (absolute tolerance) is zero and the default rtol (relative tolerance) depends on the types of x and y. The keyword argument nans determines whether or not NaN values are considered equal (defaults to false).\n\nFor real or complex floating-point values, if an atol > 0 is not specified, rtol defaults to the square root of eps of the type of x or y, whichever is bigger (least precise). This corresponds to requiring equality of about half of the significant digits. Otherwise, e.g. for integer arguments or if an atol > 0 is supplied, rtol defaults to zero.\n\nThe norm keyword defaults to abs for numeric (x,y) and to LinearAlgebra.norm for arrays (where an alternative norm choice is sometimes useful). When x and y are arrays, if norm(x-y) is not finite (i.e. ±Inf or NaN), the comparison falls back to checking whether all elements of x and y are approximately equal component-wise.\n\nThe binary operator ≈ is equivalent to isapprox with the default arguments, and x ≉ y is equivalent to !isapprox(x,y).\n\nNote that x ≈ 0 (i.e., comparing to zero with the default tolerances) is equivalent to x == 0 since the default atol is 0. In such cases, you should either supply an appropriate atol (or use norm(x) ≤ atol) or rearrange your code (e.g. use x ≈ y rather than x - y ≈ 0). It is not possible to pick a nonzero atol automatically because it depends on the overall scaling (the \"units\") of your problem: for example, in x - y ≈ 0, atol=1e-9 is an absurdly small tolerance if x is the radius of the Earth in meters, but an absurdly large tolerance if x is the radius of a Hydrogen atom in meters.\n\ncompat: Julia 1.6\nPassing the norm keyword argument when comparing numeric (non-array) arguments requires Julia 1.6 or later.\n\nExamples\n\njulia> isapprox(0.1, 0.15; atol=0.05)\ntrue\n\njulia> isapprox(0.1, 0.15; rtol=0.34)\ntrue\n\njulia> isapprox(0.1, 0.15; rtol=0.33)\nfalse\n\njulia> 0.1 + 1e-10 ≈ 0.1\ntrue\n\njulia> 1e-10 ≈ 0\nfalse\n\njulia> isapprox(1e-10, 0, atol=1e-8)\ntrue\n\njulia> isapprox([10.0^9, 1.0], [10.0^9, 2.0]) # using `norm`\ntrue\n\n\n\n\n\nisapprox(x; kwargs...) / ≈(x; kwargs...)\n\nCreate a function that compares its argument to x using ≈, i.e. a function equivalent to y -> y ≈ x.\n\nThe keyword arguments supported here are the same as those in the 2-argument isapprox.\n\ncompat: Julia 1.5\nThis method requires Julia 1.5 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.sin-Tuple{Number}","page":"Mathematics","title":"Base.sin","text":"sin(x::T) where {T <: Number} -> float(T)\n\nCompute sine of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also sind, sinpi, sincos, cis, asin.\n\nExamples\n\njulia> round.(sin.(range(0, 2pi, length=9)'), digits=3)\n1×9 Matrix{Float64}:\n 0.0 0.707 1.0 0.707 0.0 -0.707 -1.0 -0.707 -0.0\n\njulia> sind(45)\n0.7071067811865476\n\njulia> sinpi(1/4)\n0.7071067811865475\n\njulia> round.(sincos(pi/6), digits=3)\n(0.5, 0.866)\n\njulia> round(cis(pi/6), digits=3)\n0.866 + 0.5im\n\njulia> round(exp(im*pi/6), digits=3)\n0.866 + 0.5im\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.cos-Tuple{Number}","page":"Mathematics","title":"Base.cos","text":"cos(x::T) where {T <: Number} -> float(T)\n\nCompute cosine of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also cosd, cospi, sincos, cis.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.sincos-Tuple{Float64}","page":"Mathematics","title":"Base.Math.sincos","text":"sincos(x::T) where T -> float(T)\n\nSimultaneously compute the sine and cosine of x, where x is in radians, returning a tuple (sine, cosine).\n\nThrow a DomainError if isinf(x), return a (T(NaN), T(NaN)) if isnan(x).\n\nSee also cis, sincospi, sincosd.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.tan-Tuple{Number}","page":"Mathematics","title":"Base.tan","text":"tan(x::T) where {T <: Number} -> float(T)\n\nCompute tangent of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also tanh.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.sind","page":"Mathematics","title":"Base.Math.sind","text":"sind(x::T) where T -> float(T)\n\nCompute sine of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cosd","page":"Mathematics","title":"Base.Math.cosd","text":"cosd(x::T) where T -> float(T)\n\nCompute cosine of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.tand","page":"Mathematics","title":"Base.Math.tand","text":"tand(x::T) where T -> float(T)\n\nCompute tangent of x, where x is in degrees. If x is a matrix, x needs to be a square matrix.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sincosd","page":"Mathematics","title":"Base.Math.sincosd","text":"sincosd(x::T) where T -> float(T)\n\nSimultaneously compute the sine and cosine of x, where x is in degrees.\n\nThrow a DomainError if isinf(x), return a (T(NaN), T(NaN)) tuple if isnan(x).\n\ncompat: Julia 1.3\nThis function requires at least Julia 1.3.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sinpi","page":"Mathematics","title":"Base.Math.sinpi","text":"sinpi(x::T) where T -> float(T)\n\nCompute sin(pi x) more accurately than sin(pi*x), especially for large x.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also sind, cospi, sincospi.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cospi","page":"Mathematics","title":"Base.Math.cospi","text":"cospi(x::T) where T -> float(T)\n\nCompute cos(pi x) more accurately than cos(pi*x), especially for large x.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\nSee also: cispi, sincosd, cospi.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sincospi","page":"Mathematics","title":"Base.Math.sincospi","text":"sincospi(x::T) where T -> float(T)\n\nSimultaneously compute sinpi(x) and cospi(x) (the sine and cosine of π*x, where x is in radians), returning a tuple (sine, cosine).\n\nThrow a DomainError if isinf(x), return a (T(NaN), T(NaN)) tuple if isnan(x).\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\nSee also: cispi, sincosd, sinpi.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.sinh-Tuple{Number}","page":"Mathematics","title":"Base.sinh","text":"sinh(x)\n\nCompute hyperbolic sine of x.\n\nSee also sin.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.cosh-Tuple{Number}","page":"Mathematics","title":"Base.cosh","text":"cosh(x)\n\nCompute hyperbolic cosine of x.\n\nSee also cos.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.tanh-Tuple{Number}","page":"Mathematics","title":"Base.tanh","text":"tanh(x)\n\nCompute hyperbolic tangent of x.\n\nSee also tan, atanh.\n\nExamples\n\njulia> tanh.(-3:3f0) # Here 3f0 isa Float32\n7-element Vector{Float32}:\n -0.9950548\n -0.9640276\n -0.7615942\n 0.0\n 0.7615942\n 0.9640276\n 0.9950548\n\njulia> tan.(im .* (1:3))\n3-element Vector{ComplexF64}:\n 0.0 + 0.7615941559557649im\n 0.0 + 0.9640275800758169im\n 0.0 + 0.9950547536867306im\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.asin-Tuple{Number}","page":"Mathematics","title":"Base.asin","text":"asin(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse sine of x, where the output is in radians.\n\nReturn a T(NaN) if isnan(x).\n\nSee also asind for output in degrees.\n\nExamples\n\njulia> asin.((0, 1/2, 1))\n(0.0, 0.5235987755982989, 1.5707963267948966)\n\njulia> asind.((0, 1/2, 1))\n(0.0, 30.000000000000004, 90.0)\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.acos-Tuple{Number}","page":"Mathematics","title":"Base.acos","text":"acos(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse cosine of x, where the output is in radians\n\nReturn a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.atan-Tuple{Number}","page":"Mathematics","title":"Base.atan","text":"atan(y)\natan(y, x)\n\nCompute the inverse tangent of y or y/x, respectively.\n\nFor one real argument, this is the angle in radians between the positive x-axis and the point (1, y), returning a value in the interval -pi2 pi2.\n\nFor two arguments, this is the angle in radians between the positive x-axis and the point (x, y), returning a value in the interval -pi pi. This corresponds to a standard atan2 function. Note that by convention atan(0.0,x) is defined as pi and atan(-0.0,x) is defined as -pi when x < 0.\n\nSee also atand for degrees.\n\nExamples\n\njulia> rad2deg(atan(-1/√3))\n-30.000000000000004\n\njulia> rad2deg(atan(-1, √3))\n-30.000000000000004\n\njulia> rad2deg(atan(1, -√3))\n150.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.asind","page":"Mathematics","title":"Base.Math.asind","text":"asind(x)\n\nCompute the inverse sine of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.acosd","page":"Mathematics","title":"Base.Math.acosd","text":"acosd(x)\n\nCompute the inverse cosine of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.atand","page":"Mathematics","title":"Base.Math.atand","text":"atand(y::T) where T -> float(T)\natand(y::T, x::S) where {T,S} -> promote_type(T,S)\natand(y::AbstractMatrix{T}) where T -> AbstractMatrix{Complex{float(T)}}\n\nCompute the inverse tangent of y or y/x, respectively, where the output is in degrees.\n\nReturn a NaN if isnan(y) or isnan(x). The returned NaN is either a T in the single argument version, or a promote_type(T,S) in the two argument version.\n\ncompat: Julia 1.7\nThe one-argument method supports square matrix arguments as of Julia 1.7.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sec-Tuple{Number}","page":"Mathematics","title":"Base.Math.sec","text":"sec(x::T) where {T <: Number} -> float(T)\n\nCompute the secant of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.csc-Tuple{Number}","page":"Mathematics","title":"Base.Math.csc","text":"csc(x::T) where {T <: Number} -> float(T)\n\nCompute the cosecant of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.cot-Tuple{Number}","page":"Mathematics","title":"Base.Math.cot","text":"cot(x::T) where {T <: Number} -> float(T)\n\nCompute the cotangent of x, where x is in radians.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.secd","page":"Mathematics","title":"Base.Math.secd","text":"secd(x::T) where {T <: Number} -> float(T)\n\nCompute the secant of x, where x is in degrees.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cscd","page":"Mathematics","title":"Base.Math.cscd","text":"cscd(x::T) where {T <: Number} -> float(T)\n\nCompute the cosecant of x, where x is in degrees.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cotd","page":"Mathematics","title":"Base.Math.cotd","text":"cotd(x::T) where {T <: Number} -> float(T)\n\nCompute the cotangent of x, where x is in degrees.\n\nThrow a DomainError if isinf(x), return a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.asec-Tuple{Number}","page":"Mathematics","title":"Base.Math.asec","text":"asec(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse secant of x, where the output is in radians.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.acsc-Tuple{Number}","page":"Mathematics","title":"Base.Math.acsc","text":"acsc(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse cosecant of x, where the output is in radians.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.acot-Tuple{Number}","page":"Mathematics","title":"Base.Math.acot","text":"acot(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse cotangent of x, where the output is in radians.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.asecd","page":"Mathematics","title":"Base.Math.asecd","text":"asecd(x)\n\nCompute the inverse secant of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.acscd","page":"Mathematics","title":"Base.Math.acscd","text":"acscd(x)\n\nCompute the inverse cosecant of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.acotd","page":"Mathematics","title":"Base.Math.acotd","text":"acotd(x)\n\nCompute the inverse cotangent of x, where the output is in degrees. If x is a matrix, x needs to be a square matrix.\n\ncompat: Julia 1.7\nMatrix arguments require Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.sech-Tuple{Number}","page":"Mathematics","title":"Base.Math.sech","text":"sech(x::T) where {T <: Number} -> float(T)\n\nCompute the hyperbolic secant of x.\n\nReturn a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.csch-Tuple{Number}","page":"Mathematics","title":"Base.Math.csch","text":"csch(x::T) where {T <: Number} -> float(T)\n\nCompute the hyperbolic cosecant of x.\n\nReturn a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.coth-Tuple{Number}","page":"Mathematics","title":"Base.Math.coth","text":"coth(x::T) where {T <: Number} -> float(T)\n\nCompute the hyperbolic cotangent of x.\n\nReturn a T(NaN) if isnan(x).\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.asinh-Tuple{Number}","page":"Mathematics","title":"Base.asinh","text":"asinh(x)\n\nCompute the inverse hyperbolic sine of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.acosh-Tuple{Number}","page":"Mathematics","title":"Base.acosh","text":"acosh(x)\n\nCompute the inverse hyperbolic cosine of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.atanh-Tuple{Number}","page":"Mathematics","title":"Base.atanh","text":"atanh(x)\n\nCompute the inverse hyperbolic tangent of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.asech-Tuple{Number}","page":"Mathematics","title":"Base.Math.asech","text":"asech(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse hyperbolic secant of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.acsch-Tuple{Number}","page":"Mathematics","title":"Base.Math.acsch","text":"acsch(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse hyperbolic cosecant of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.acoth-Tuple{Number}","page":"Mathematics","title":"Base.Math.acoth","text":"acoth(x::T) where {T <: Number} -> float(T)\n\nCompute the inverse hyperbolic cotangent of x.\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.Math.sinc","page":"Mathematics","title":"Base.Math.sinc","text":"sinc(x::T) where {T <: Number} -> float(T)\n\nCompute normalized sinc function operatornamesinc(x) = sin(pi x) (pi x) if x neq 0, and 1 if x = 0.\n\nReturn a T(NaN) if isnan(x).\n\nSee also cosc, its derivative.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cosc","page":"Mathematics","title":"Base.Math.cosc","text":"cosc(x::T) where {T <: Number} -> float(T)\n\nCompute cos(pi x) x - sin(pi x) (pi x^2) if x neq 0, and 0 if x = 0. This is the derivative of sinc(x).\n\nReturn a T(NaN) if isnan(x).\n\nSee also sinc.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.deg2rad","page":"Mathematics","title":"Base.Math.deg2rad","text":"deg2rad(x)\n\nConvert x from degrees to radians.\n\nSee also rad2deg, sind, pi.\n\nExamples\n\njulia> deg2rad(90)\n1.5707963267948966\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.rad2deg","page":"Mathematics","title":"Base.Math.rad2deg","text":"rad2deg(x)\n\nConvert x from radians to degrees.\n\nSee also deg2rad.\n\nExamples\n\njulia> rad2deg(pi)\n180.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.hypot","page":"Mathematics","title":"Base.Math.hypot","text":"hypot(x, y)\n\nCompute the hypotenuse sqrtx^2+y^2 avoiding overflow and underflow.\n\nThis code is an implementation of the algorithm described in: An Improved Algorithm for hypot(a,b) by Carlos F. Borges The article is available online at arXiv at the link https://arxiv.org/abs/1904.09481\n\nhypot(x...)\n\nCompute the hypotenuse sqrtsum x_i^2 avoiding overflow and underflow.\n\nSee also norm in the LinearAlgebra standard library.\n\nExamples\n\njulia> a = Int64(10)^10;\n\njulia> hypot(a, a)\n1.4142135623730951e10\n\njulia> √(a^2 + a^2) # a^2 overflows\nERROR: DomainError with -2.914184810805068e18:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]\n\njulia> hypot(3, 4im)\n5.0\n\njulia> hypot(-5.7)\n5.7\n\njulia> hypot(3, 4im, 12.0)\n13.0\n\njulia> using LinearAlgebra\n\njulia> norm([a, a, a, a]) == hypot(a, a, a, a)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.log-Tuple{Number}","page":"Mathematics","title":"Base.log","text":"log(x)\n\nCompute the natural logarithm of x.\n\nThrow a DomainError for negative Real arguments. Use Complex arguments to obtain Complex results.\n\nnote: Branch cut\nlog has a branch cut along the negative real axis; -0.0im is taken to be below the axis.\n\nSee also ℯ, log1p, log2, log10.\n\nExamples\n\njulia> log(2)\n0.6931471805599453\n\njulia> log(-3)\nERROR: DomainError with -3.0:\nlog was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31\n[...]\n\njulia> log(-3 + 0im)\n1.0986122886681098 + 3.141592653589793im\n\njulia> log(-3 - 0.0im)\n1.0986122886681098 - 3.141592653589793im\n\njulia> log.(exp.(-1:1))\n3-element Vector{Float64}:\n -1.0\n 0.0\n 1.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.log-Tuple{Number, Number}","page":"Mathematics","title":"Base.log","text":"log(b,x)\n\nCompute the base b logarithm of x. Throw a DomainError for negative Real arguments.\n\nExamples\n\njulia> log(4,8)\n1.5\n\njulia> log(4,2)\n0.5\n\njulia> log(-2, 3)\nERROR: DomainError with -2.0:\nlog was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31\n[...]\n\njulia> log(2, -3)\nERROR: DomainError with -3.0:\nlog was called with a negative real argument but will only return a complex result if called with a complex argument. Try log(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31\n[...]\n\nnote: Note\nIf b is a power of 2 or 10, log2 or log10 should be used, as these will typically be faster and more accurate. For example,julia> log(100,1000000)\n2.9999999999999996\n\njulia> log10(1000000)/2\n3.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.log2","page":"Mathematics","title":"Base.log2","text":"log2(x)\n\nCompute the logarithm of x to base 2. Throw a DomainError for negative Real arguments.\n\nSee also: exp2, ldexp, ispow2.\n\nExamples\n\njulia> log2(4)\n2.0\n\njulia> log2(10)\n3.321928094887362\n\njulia> log2(-2)\nERROR: DomainError with -2.0:\nlog2 was called with a negative real argument but will only return a complex result if called with a complex argument. Try log2(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(f::Symbol, x::Float64) at ./math.jl:31\n[...]\n\njulia> log2.(2.0 .^ (-1:1))\n3-element Vector{Float64}:\n -1.0\n 0.0\n 1.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.log10","page":"Mathematics","title":"Base.log10","text":"log10(x)\n\nCompute the logarithm of x to base 10. Throw a DomainError for negative Real arguments.\n\nExamples\n\njulia> log10(100)\n2.0\n\njulia> log10(2)\n0.3010299956639812\n\njulia> log10(-2)\nERROR: DomainError with -2.0:\nlog10 was called with a negative real argument but will only return a complex result if called with a complex argument. Try log10(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(f::Symbol, x::Float64) at ./math.jl:31\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.log1p","page":"Mathematics","title":"Base.log1p","text":"log1p(x)\n\nAccurate natural logarithm of 1+x. Throw a DomainError for Real arguments less than -1.\n\nExamples\n\njulia> log1p(-0.5)\n-0.6931471805599453\n\njulia> log1p(0)\n0.0\n\njulia> log1p(-2)\nERROR: DomainError with -2.0:\nlog1p was called with a real argument < -1 but will only return a complex result if called with a complex argument. Try log1p(Complex(x)).\nStacktrace:\n [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.frexp","page":"Mathematics","title":"Base.Math.frexp","text":"frexp(val)\n\nReturn (x,exp) such that x has a magnitude in the interval 12 1) or 0, and val is equal to x times 2^exp.\n\nSee also significand, exponent, ldexp.\n\nExamples\n\njulia> frexp(6.0)\n(0.75, 3)\n\njulia> significand(6.0), exponent(6.0) # interval [1, 2) instead\n(1.5, 2)\n\njulia> frexp(0.0), frexp(NaN), frexp(-Inf) # exponent would give an error\n((0.0, 0), (NaN, 0), (-Inf, 0))\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.exp-Tuple{Float64}","page":"Mathematics","title":"Base.exp","text":"exp(x)\n\nCompute the natural base exponential of x, in other words ℯ^x.\n\nSee also exp2, exp10 and cis.\n\nExamples\n\njulia> exp(1.0)\n2.718281828459045\n\njulia> exp(im * pi) ≈ cis(pi)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.exp2","page":"Mathematics","title":"Base.exp2","text":"exp2(x)\n\nCompute the base 2 exponential of x, in other words 2^x.\n\nSee also ldexp, <<.\n\nExamples\n\njulia> exp2(5)\n32.0\n\njulia> 2^5\n32\n\njulia> exp2(63) > typemax(Int)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.exp10","page":"Mathematics","title":"Base.exp10","text":"exp10(x)\n\nCompute the base 10 exponential of x, in other words 10^x.\n\nExamples\n\njulia> exp10(2)\n100.0\n\njulia> 10^2\n100\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.ldexp","page":"Mathematics","title":"Base.Math.ldexp","text":"ldexp(x, n)\n\nCompute x times 2^n.\n\nSee also frexp, exponent.\n\nExamples\n\njulia> ldexp(5.0, 2)\n20.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.modf","page":"Mathematics","title":"Base.Math.modf","text":"modf(x)\n\nReturn a tuple (fpart, ipart) of the fractional and integral parts of a number. Both parts have the same sign as the argument.\n\nExamples\n\njulia> modf(3.5)\n(0.5, 3.0)\n\njulia> modf(-3.5)\n(-0.5, -3.0)\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.expm1","page":"Mathematics","title":"Base.expm1","text":"expm1(x)\n\nAccurately compute e^x-1. It avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small values of x.\n\nExamples\n\njulia> expm1(1e-16)\n1.0e-16\n\njulia> exp(1e-16) - 1\n0.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.round","page":"Mathematics","title":"Base.round","text":"round([T,] x, [r::RoundingMode])\nround(x, [r::RoundingMode]; digits::Integer=0, base = 10)\nround(x, [r::RoundingMode]; sigdigits::Integer, base = 10)\n\nRounds the number x.\n\nWithout keyword arguments, x is rounded to an integer value, returning a value of type T, or of the same type of x if no T is provided. An InexactError will be thrown if the value is not representable by T, similar to convert.\n\nIf the digits keyword argument is provided, it rounds to the specified number of digits after the decimal place (or before if negative), in base base.\n\nIf the sigdigits keyword argument is provided, it rounds to the specified number of significant digits, in base base.\n\nThe RoundingMode r controls the direction of the rounding; the default is RoundNearest, which rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer. Note that round may give incorrect results if the global rounding mode is changed (see rounding).\n\nExamples\n\njulia> round(1.7)\n2.0\n\njulia> round(Int, 1.7)\n2\n\njulia> round(1.5)\n2.0\n\njulia> round(2.5)\n2.0\n\njulia> round(pi; digits=2)\n3.14\n\njulia> round(pi; digits=3, base=2)\n3.125\n\njulia> round(123.456; sigdigits=2)\n120.0\n\njulia> round(357.913; sigdigits=4, base=2)\n352.0\n\nnote: Note\nRounding to specified digits in bases other than 2 can be inexact when operating on binary floating point numbers. For example, the Float64 value represented by 1.15 is actually less than 1.15, yet will be rounded to 1.2. For example:julia> x = 1.15\n1.15\n\njulia> big(1.15)\n1.149999999999999911182158029987476766109466552734375\n\njulia> x < 115//100\ntrue\n\njulia> round(x, digits=1)\n1.2\n\nExtensions\n\nTo extend round to new numeric types, it is typically sufficient to define Base.round(x::NewType, r::RoundingMode).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Rounding.RoundingMode","page":"Mathematics","title":"Base.Rounding.RoundingMode","text":"RoundingMode\n\nA type used for controlling the rounding mode of floating point operations (via rounding/setrounding functions), or as optional arguments for rounding to the nearest integer (via the round function).\n\nCurrently supported rounding modes are:\n\nRoundNearest (default)\nRoundNearestTiesAway\nRoundNearestTiesUp\nRoundToZero\nRoundFromZero\nRoundUp\nRoundDown\n\ncompat: Julia 1.9\nRoundFromZero requires at least Julia 1.9. Prior versions support RoundFromZero for BigFloats only.\n\n\n\n\n\n","category":"type"},{"location":"base/math/#Base.Rounding.RoundNearest","page":"Mathematics","title":"Base.Rounding.RoundNearest","text":"RoundNearest\n\nThe default rounding mode. Rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer.\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundNearestTiesAway","page":"Mathematics","title":"Base.Rounding.RoundNearestTiesAway","text":"RoundNearestTiesAway\n\nRounds to nearest integer, with ties rounded away from zero (C/C++ round behaviour).\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundNearestTiesUp","page":"Mathematics","title":"Base.Rounding.RoundNearestTiesUp","text":"RoundNearestTiesUp\n\nRounds to nearest integer, with ties rounded toward positive infinity (Java/JavaScript round behaviour).\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundToZero","page":"Mathematics","title":"Base.Rounding.RoundToZero","text":"RoundToZero\n\nround using this rounding mode is an alias for trunc.\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundFromZero","page":"Mathematics","title":"Base.Rounding.RoundFromZero","text":"RoundFromZero\n\nRounds away from zero.\n\ncompat: Julia 1.9\nRoundFromZero requires at least Julia 1.9. Prior versions support RoundFromZero for BigFloats only.\n\nExamples\n\njulia> BigFloat(\"1.0000000000000001\", 5, RoundFromZero)\n1.06\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundUp","page":"Mathematics","title":"Base.Rounding.RoundUp","text":"RoundUp\n\nround using this rounding mode is an alias for ceil.\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.Rounding.RoundDown","page":"Mathematics","title":"Base.Rounding.RoundDown","text":"RoundDown\n\nround using this rounding mode is an alias for floor.\n\n\n\n\n\n","category":"constant"},{"location":"base/math/#Base.round-Tuple{Complex{<:AbstractFloat}, RoundingMode, RoundingMode}","page":"Mathematics","title":"Base.round","text":"round(z::Complex[, RoundingModeReal, [RoundingModeImaginary]])\nround(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]; digits=0, base=10)\nround(z::Complex[, RoundingModeReal, [RoundingModeImaginary]]; sigdigits, base=10)\n\nReturn the nearest integral value of the same type as the complex-valued z to z, breaking ties using the specified RoundingModes. The first RoundingMode is used for rounding the real components while the second is used for rounding the imaginary components.\n\nRoundingModeReal and RoundingModeImaginary default to RoundNearest, which rounds to the nearest integer, with ties (fractional values of 0.5) being rounded to the nearest even integer.\n\nExamples\n\njulia> round(3.14 + 4.5im)\n3.0 + 4.0im\n\njulia> round(3.14 + 4.5im, RoundUp, RoundNearestTiesUp)\n4.0 + 5.0im\n\njulia> round(3.14159 + 4.512im; digits = 1)\n3.1 + 4.5im\n\njulia> round(3.14159 + 4.512im; sigdigits = 3)\n3.14 + 4.51im\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.ceil","page":"Mathematics","title":"Base.ceil","text":"ceil([T,] x)\nceil(x; digits::Integer= [, base = 10])\nceil(x; sigdigits::Integer= [, base = 10])\n\nceil(x) returns the nearest integral value of the same type as x that is greater than or equal to x.\n\nceil(T, x) converts the result to type T, throwing an InexactError if the ceiled value is not representable as a T.\n\nKeywords digits, sigdigits and base work as for round.\n\nTo support ceil for a new type, define Base.round(x::NewType, ::RoundingMode{:Up}).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.floor","page":"Mathematics","title":"Base.floor","text":"floor([T,] x)\nfloor(x; digits::Integer= [, base = 10])\nfloor(x; sigdigits::Integer= [, base = 10])\n\nfloor(x) returns the nearest integral value of the same type as x that is less than or equal to x.\n\nfloor(T, x) converts the result to type T, throwing an InexactError if the floored value is not representable a T.\n\nKeywords digits, sigdigits and base work as for round.\n\nTo support floor for a new type, define Base.round(x::NewType, ::RoundingMode{:Down}).\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.trunc","page":"Mathematics","title":"Base.trunc","text":"trunc([T,] x)\ntrunc(x; digits::Integer= [, base = 10])\ntrunc(x; sigdigits::Integer= [, base = 10])\n\ntrunc(x) returns the nearest integral value of the same type as x whose absolute value is less than or equal to the absolute value of x.\n\ntrunc(T, x) converts the result to type T, throwing an InexactError if the truncated value is not representable a T.\n\nKeywords digits, sigdigits and base work as for round.\n\nTo support trunc for a new type, define Base.round(x::NewType, ::RoundingMode{:ToZero}).\n\nSee also: %, floor, unsigned, unsafe_trunc.\n\nExamples\n\njulia> trunc(2.22)\n2.0\n\njulia> trunc(-2.22, digits=1)\n-2.2\n\njulia> trunc(Int, -2.22)\n-2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.unsafe_trunc","page":"Mathematics","title":"Base.unsafe_trunc","text":"unsafe_trunc(T, x)\n\nReturn the nearest integral value of type T whose absolute value is less than or equal to the absolute value of x. If the value is not representable by T, an arbitrary value will be returned. See also trunc.\n\nExamples\n\njulia> unsafe_trunc(Int, -2.2)\n-2\n\njulia> unsafe_trunc(Int, NaN)\n-9223372036854775808\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.min","page":"Mathematics","title":"Base.min","text":"min(x, y, ...)\n\nReturn the minimum of the arguments, with respect to isless. If any of the arguments is missing, return missing. See also the minimum function to take the minimum element from a collection.\n\nExamples\n\njulia> min(2, 5, 1)\n1\n\njulia> min(4, missing, 6)\nmissing\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.max","page":"Mathematics","title":"Base.max","text":"max(x, y, ...)\n\nReturn the maximum of the arguments, with respect to isless. If any of the arguments is missing, return missing. See also the maximum function to take the maximum element from a collection.\n\nExamples\n\njulia> max(2, 5, 1)\n5\n\njulia> max(5, missing, 6)\nmissing\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.minmax","page":"Mathematics","title":"Base.minmax","text":"minmax(x, y)\n\nReturn (min(x,y), max(x,y)).\n\nSee also extrema that returns (minimum(x), maximum(x)).\n\nExamples\n\njulia> minmax('c','b')\n('b', 'c')\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.clamp","page":"Mathematics","title":"Base.Math.clamp","text":"clamp(x, lo, hi)\n\nReturn x if lo <= x <= hi. If x > hi, return hi. If x < lo, return lo. Arguments are promoted to a common type.\n\nSee also clamp!, min, max.\n\ncompat: Julia 1.3\nmissing as the first argument requires at least Julia 1.3.\n\nExamples\n\njulia> clamp.([pi, 1.0, big(10)], 2.0, 9.0)\n3-element Vector{BigFloat}:\n 3.141592653589793238462643383279502884197169399375105820974944592307816406286198\n 2.0\n 9.0\n\njulia> clamp.([11, 8, 5], 10, 6) # an example where lo > hi\n3-element Vector{Int64}:\n 6\n 6\n 10\n\n\n\n\n\nclamp(x, T)::T\n\nClamp x between typemin(T) and typemax(T) and convert the result to type T.\n\nSee also trunc.\n\nExamples\n\njulia> clamp(200, Int8)\n127\n\njulia> clamp(-200, Int8)\n-128\n\njulia> trunc(Int, 4pi^2)\n39\n\n\n\n\n\nclamp(x::Integer, r::AbstractUnitRange)\n\nClamp x to lie within range r.\n\ncompat: Julia 1.6\nThis method requires at least Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.clamp!","page":"Mathematics","title":"Base.Math.clamp!","text":"clamp!(array::AbstractArray, lo, hi)\n\nRestrict values in array to the specified range, in-place. See also clamp.\n\ncompat: Julia 1.3\nmissing entries in array require at least Julia 1.3.\n\nExamples\n\njulia> row = collect(-4:4)';\n\njulia> clamp!(row, 0, Inf)\n1×9 adjoint(::Vector{Int64}) with eltype Int64:\n 0 0 0 0 0 1 2 3 4\n\njulia> clamp.((-4:4)', 0, Inf)\n1×9 Matrix{Float64}:\n 0.0 0.0 0.0 0.0 0.0 1.0 2.0 3.0 4.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.abs","page":"Mathematics","title":"Base.abs","text":"abs(x)\n\nThe absolute value of x.\n\nWhen abs is applied to signed integers, overflow may occur, resulting in the return of a negative value. This overflow occurs only when abs is applied to the minimum representable value of a signed integer. That is, when x == typemin(typeof(x)), abs(x) == x < 0, not -x as might be expected.\n\nSee also: abs2, unsigned, sign.\n\nExamples\n\njulia> abs(-3)\n3\n\njulia> abs(1 + im)\n1.4142135623730951\n\njulia> abs.(Int8[-128 -127 -126 0 126 127]) # overflow at typemin(Int8)\n1×6 Matrix{Int8}:\n -128 127 126 0 126 127\n\njulia> maximum(abs, [1, -2, 3, -4])\n4\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked","page":"Mathematics","title":"Base.Checked","text":"Checked\n\nThe Checked module provides arithmetic functions for the built-in signed and unsigned Integer types which throw an error when an overflow occurs. They are named like checked_sub, checked_div, etc. In addition, add_with_overflow, sub_with_overflow, mul_with_overflow return both the unchecked results and a boolean value denoting the presence of an overflow.\n\n\n\n\n\n","category":"module"},{"location":"base/math/#Base.Checked.checked_abs","page":"Mathematics","title":"Base.Checked.checked_abs","text":"Base.checked_abs(x)\n\nCalculates abs(x), checking for overflow errors where applicable. For example, standard two's complement signed integers (e.g. Int) cannot represent abs(typemin(Int)), thus leading to an overflow.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_neg","page":"Mathematics","title":"Base.Checked.checked_neg","text":"Base.checked_neg(x)\n\nCalculates -x, checking for overflow errors where applicable. For example, standard two's complement signed integers (e.g. Int) cannot represent -typemin(Int), thus leading to an overflow.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_add","page":"Mathematics","title":"Base.Checked.checked_add","text":"Base.checked_add(x, y)\n\nCalculates x+y, checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_sub","page":"Mathematics","title":"Base.Checked.checked_sub","text":"Base.checked_sub(x, y)\n\nCalculates x-y, checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_mul","page":"Mathematics","title":"Base.Checked.checked_mul","text":"Base.checked_mul(x, y)\n\nCalculates x*y, checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_div","page":"Mathematics","title":"Base.Checked.checked_div","text":"Base.checked_div(x, y)\n\nCalculates div(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_rem","page":"Mathematics","title":"Base.Checked.checked_rem","text":"Base.checked_rem(x, y)\n\nCalculates x%y, checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_fld","page":"Mathematics","title":"Base.Checked.checked_fld","text":"Base.checked_fld(x, y)\n\nCalculates fld(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_mod","page":"Mathematics","title":"Base.Checked.checked_mod","text":"Base.checked_mod(x, y)\n\nCalculates mod(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_cld","page":"Mathematics","title":"Base.Checked.checked_cld","text":"Base.checked_cld(x, y)\n\nCalculates cld(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.checked_pow","page":"Mathematics","title":"Base.Checked.checked_pow","text":"Base.checked_pow(x, y)\n\nCalculates ^(x,y), checking for overflow errors where applicable.\n\nThe overflow protection may impose a perceptible performance penalty.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.add_with_overflow","page":"Mathematics","title":"Base.Checked.add_with_overflow","text":"Base.add_with_overflow(x, y) -> (r, f)\n\nCalculates r = x+y, with the flag f indicating whether overflow has occurred.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.sub_with_overflow","page":"Mathematics","title":"Base.Checked.sub_with_overflow","text":"Base.sub_with_overflow(x, y) -> (r, f)\n\nCalculates r = x-y, with the flag f indicating whether overflow has occurred.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Checked.mul_with_overflow","page":"Mathematics","title":"Base.Checked.mul_with_overflow","text":"Base.mul_with_overflow(x, y) -> (r, f)\n\nCalculates r = x*y, with the flag f indicating whether overflow has occurred.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.abs2","page":"Mathematics","title":"Base.abs2","text":"abs2(x)\n\nSquared absolute value of x.\n\nThis can be faster than abs(x)^2, especially for complex numbers where abs(x) requires a square root via hypot.\n\nSee also abs, conj, real.\n\nExamples\n\njulia> abs2(-3)\n9\n\njulia> abs2(3.0 + 4.0im)\n25.0\n\njulia> sum(abs2, [1+2im, 3+4im]) # LinearAlgebra.norm(x)^2\n30\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.copysign","page":"Mathematics","title":"Base.copysign","text":"copysign(x, y) -> z\n\nReturn z which has the magnitude of x and the same sign as y.\n\nExamples\n\njulia> copysign(1, -2)\n-1\n\njulia> copysign(-1, 2)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.sign","page":"Mathematics","title":"Base.sign","text":"sign(x)\n\nReturn zero if x==0 and xx otherwise (i.e., ±1 for real x).\n\nSee also signbit, zero, copysign, flipsign.\n\nExamples\n\njulia> sign(-4.0)\n-1.0\n\njulia> sign(99)\n1\n\njulia> sign(-0.0)\n-0.0\n\njulia> sign(0 + im)\n0.0 + 1.0im\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.signbit","page":"Mathematics","title":"Base.signbit","text":"signbit(x)\n\nReturn true if the value of the sign of x is negative, otherwise false.\n\nSee also sign and copysign.\n\nExamples\n\njulia> signbit(-4)\ntrue\n\njulia> signbit(5)\nfalse\n\njulia> signbit(5.5)\nfalse\n\njulia> signbit(-4.1)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.flipsign","page":"Mathematics","title":"Base.flipsign","text":"flipsign(x, y)\n\nReturn x with its sign flipped if y is negative. For example abs(x) = flipsign(x,x).\n\nExamples\n\njulia> flipsign(5, 3)\n5\n\njulia> flipsign(5, -3)\n-5\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.sqrt-Tuple{Number}","page":"Mathematics","title":"Base.sqrt","text":"sqrt(x)\n\nReturn sqrtx.\n\nThrow a DomainError for negative Real arguments. Use Complex negative arguments instead to obtain a Complex result.\n\nThe prefix operator √ is equivalent to sqrt.\n\nnote: Branch cut\nsqrt has a branch cut along the negative real axis; -0.0im is taken to be below the axis.\n\nSee also: hypot.\n\nExamples\n\njulia> sqrt(big(81))\n9.0\n\njulia> sqrt(big(-81))\nERROR: DomainError with -81.0:\nNaN result for non-NaN input.\nStacktrace:\n [1] sqrt(::BigFloat) at ./mpfr.jl:501\n[...]\n\njulia> sqrt(big(complex(-81)))\n0.0 + 9.0im\n\njulia> sqrt(-81 - 0.0im) # -0.0im is below the branch cut\n0.0 - 9.0im\n\njulia> .√(1:4)\n4-element Vector{Float64}:\n 1.0\n 1.4142135623730951\n 1.7320508075688772\n 2.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.isqrt","page":"Mathematics","title":"Base.isqrt","text":"isqrt(n::Integer)\n\nInteger square root: the largest integer m such that m*m <= n.\n\njulia> isqrt(5)\n2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.cbrt-Tuple{AbstractFloat}","page":"Mathematics","title":"Base.Math.cbrt","text":"cbrt(x::Real)\n\nReturn the cube root of x, i.e. x^13. Negative values are accepted (returning the negative real root when x 0).\n\nThe prefix operator ∛ is equivalent to cbrt.\n\nExamples\n\njulia> cbrt(big(27))\n3.0\n\njulia> cbrt(big(-27))\n-3.0\n\n\n\n\n\n","category":"method"},{"location":"base/math/#Base.real","page":"Mathematics","title":"Base.real","text":"real(z)\n\nReturn the real part of the complex number z.\n\nSee also: imag, reim, complex, isreal, Real.\n\nExamples\n\njulia> real(1 + 3im)\n1\n\n\n\n\n\nreal(T::Type)\n\nReturn the type that represents the real part of a value of type T. e.g: for T == Complex{R}, returns R. Equivalent to typeof(real(zero(T))).\n\nExamples\n\njulia> real(Complex{Int})\nInt64\n\njulia> real(Float64)\nFloat64\n\n\n\n\n\nreal(A::AbstractArray)\n\nReturn an array containing the real part of each entry in array A.\n\nEquivalent to real.(A), except that when eltype(A) <: Real A is returned without copying, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).\n\nExamples\n\njulia> real([1, 2im, 3 + 4im])\n3-element Vector{Int64}:\n 1\n 0\n 3\n\njulia> real(fill(2 - im))\n0-dimensional Array{Int64, 0}:\n2\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.imag","page":"Mathematics","title":"Base.imag","text":"imag(z)\n\nReturn the imaginary part of the complex number z.\n\nSee also: conj, reim, adjoint, angle.\n\nExamples\n\njulia> imag(1 + 3im)\n3\n\n\n\n\n\nimag(A::AbstractArray)\n\nReturn an array containing the imaginary part of each entry in array A.\n\nEquivalent to imag.(A), except that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).\n\nExamples\n\njulia> imag([1, 2im, 3 + 4im])\n3-element Vector{Int64}:\n 0\n 2\n 4\n\njulia> imag(fill(2 - im))\n0-dimensional Array{Int64, 0}:\n-1\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.reim","page":"Mathematics","title":"Base.reim","text":"reim(z)\n\nReturn a tuple of the real and imaginary parts of the complex number z.\n\nExamples\n\njulia> reim(1 + 3im)\n(1, 3)\n\n\n\n\n\nreim(A::AbstractArray)\n\nReturn a tuple of two arrays containing respectively the real and the imaginary part of each entry in A.\n\nEquivalent to (real.(A), imag.(A)), except that when eltype(A) <: Real A is returned without copying to represent the real part, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).\n\nExamples\n\njulia> reim([1, 2im, 3 + 4im])\n([1, 0, 3], [0, 2, 4])\n\njulia> reim(fill(2 - im))\n(fill(2), fill(-1))\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.conj","page":"Mathematics","title":"Base.conj","text":"conj(z)\n\nCompute the complex conjugate of a complex number z.\n\nSee also: angle, adjoint.\n\nExamples\n\njulia> conj(1 + 3im)\n1 - 3im\n\n\n\n\n\nconj(A::AbstractArray)\n\nReturn an array containing the complex conjugate of each entry in array A.\n\nEquivalent to conj.(A), except that when eltype(A) <: Real A is returned without copying, and that when A has zero dimensions, a 0-dimensional array is returned (rather than a scalar).\n\nExamples\n\njulia> conj([1, 2im, 3 + 4im])\n3-element Vector{Complex{Int64}}:\n 1 + 0im\n 0 - 2im\n 3 - 4im\n\njulia> conj(fill(2 - im))\n0-dimensional Array{Complex{Int64}, 0}:\n2 + 1im\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.angle","page":"Mathematics","title":"Base.angle","text":"angle(z)\n\nCompute the phase angle in radians of a complex number z.\n\nReturns a number -pi ≤ angle(z) ≤ pi, and is thus discontinuous along the negative real axis.\n\nSee also: atan, cis, rad2deg.\n\nExamples\n\njulia> rad2deg(angle(1 + im))\n45.0\n\njulia> rad2deg(angle(1 - im))\n-45.0\n\njulia> rad2deg(angle(-1 + 1e-20im))\n180.0\n\njulia> rad2deg(angle(-1 - 1e-20im))\n-180.0\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.cis","page":"Mathematics","title":"Base.cis","text":"cis(x)\n\nMore efficient method for exp(im*x) by using Euler's formula: cos(x) + i sin(x) = exp(i x).\n\nSee also cispi, sincos, exp, angle.\n\nExamples\n\njulia> cis(π) ≈ -1\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.cispi","page":"Mathematics","title":"Base.cispi","text":"cispi(x)\n\nMore accurate method for cis(pi*x) (especially for large x).\n\nSee also cis, sincospi, exp, angle.\n\nExamples\n\njulia> cispi(10000)\n1.0 + 0.0im\n\njulia> cispi(0.25 + 1im)\n0.030556854645954562 + 0.03055685464595456im\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.binomial","page":"Mathematics","title":"Base.binomial","text":"binomial(n::Integer, k::Integer)\n\nThe binomial coefficient binomnk, being the coefficient of the kth term in the polynomial expansion of (1+x)^n.\n\nIf n is non-negative, then it is the number of ways to choose k out of n items:\n\nbinomnk = fracnk (n-k)\n\nwhere n is the factorial function.\n\nIf n is negative, then it is defined in terms of the identity\n\nbinomnk = (-1)^k binomk-n-1k\n\nSee also factorial.\n\nExamples\n\njulia> binomial(5, 3)\n10\n\njulia> factorial(5) ÷ (factorial(5-3) * factorial(3))\n10\n\njulia> binomial(-5, 3)\n-35\n\nExternal links\n\nBinomial coefficient on Wikipedia.\n\n\n\n\n\nbinomial(x::Number, k::Integer)\n\nThe generalized binomial coefficient, defined for k ≥ 0 by the polynomial\n\nfrac1k prod_j=0^k-1 (x - j)\n\nWhen k < 0 it returns zero.\n\nFor the case of integer x, this is equivalent to the ordinary integer binomial coefficient\n\nbinomnk = fracnk (n-k)\n\nFurther generalizations to non-integer k are mathematically possible, but involve the Gamma function and/or the beta function, which are not provided by the Julia standard library but are available in external packages such as SpecialFunctions.jl.\n\nExternal links\n\nBinomial coefficient on Wikipedia.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.factorial","page":"Mathematics","title":"Base.factorial","text":"factorial(n::Integer)\n\nFactorial of n. If n is an Integer, the factorial is computed as an integer (promoted to at least 64 bits). Note that this may overflow if n is not small, but you can use factorial(big(n)) to compute the result exactly in arbitrary precision.\n\nSee also binomial.\n\nExamples\n\njulia> factorial(6)\n720\n\njulia> factorial(21)\nERROR: OverflowError: 21 is too large to look up in the table; consider using `factorial(big(21))` instead\nStacktrace:\n[...]\n\njulia> factorial(big(21))\n51090942171709440000\n\nExternal links\n\nFactorial on Wikipedia.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.gcd","page":"Mathematics","title":"Base.gcd","text":"gcd(x, y...)\n\nGreatest common (positive) divisor (or zero if all arguments are zero). The arguments may be integer and rational numbers.\n\ncompat: Julia 1.4\nRational arguments require Julia 1.4 or later.\n\nExamples\n\njulia> gcd(6, 9)\n3\n\njulia> gcd(6, -9)\n3\n\njulia> gcd(6, 0)\n6\n\njulia> gcd(0, 0)\n0\n\njulia> gcd(1//3, 2//3)\n1//3\n\njulia> gcd(1//3, -2//3)\n1//3\n\njulia> gcd(1//3, 2)\n1//3\n\njulia> gcd(0, 0, 10, 15)\n5\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.lcm","page":"Mathematics","title":"Base.lcm","text":"lcm(x, y...)\n\nLeast common (positive) multiple (or zero if any argument is zero). The arguments may be integer and rational numbers.\n\ncompat: Julia 1.4\nRational arguments require Julia 1.4 or later.\n\nExamples\n\njulia> lcm(2, 3)\n6\n\njulia> lcm(-2, 3)\n6\n\njulia> lcm(0, 3)\n0\n\njulia> lcm(0, 0)\n0\n\njulia> lcm(1//3, 2//3)\n2//3\n\njulia> lcm(1//3, -2//3)\n2//3\n\njulia> lcm(1//3, 2)\n2//1\n\njulia> lcm(1, 3, 5, 7)\n105\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.gcdx","page":"Mathematics","title":"Base.gcdx","text":"gcdx(a, b)\n\nComputes the greatest common (positive) divisor of a and b and their Bézout coefficients, i.e. the integer coefficients u and v that satisfy ua+vb = d = gcd(a b). gcdx(a b) returns (d u v).\n\nThe arguments may be integer and rational numbers.\n\ncompat: Julia 1.4\nRational arguments require Julia 1.4 or later.\n\nExamples\n\njulia> gcdx(12, 42)\n(6, -3, 1)\n\njulia> gcdx(240, 46)\n(2, -9, 47)\n\nnote: Note\nBézout coefficients are not uniquely defined. gcdx returns the minimal Bézout coefficients that are computed by the extended Euclidean algorithm. (Ref: D. Knuth, TAoCP, 2/e, p. 325, Algorithm X.) For signed integers, these coefficients u and v are minimal in the sense that u bd and v ad. Furthermore, the signs of u and v are chosen so that d is positive. For unsigned integers, the coefficients u and v might be near their typemax, and the identity then holds only via the unsigned integers' modulo arithmetic.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.ispow2","page":"Mathematics","title":"Base.ispow2","text":"ispow2(n::Number) -> Bool\n\nTest whether n is an integer power of two.\n\nSee also count_ones, prevpow, nextpow.\n\nExamples\n\njulia> ispow2(4)\ntrue\n\njulia> ispow2(5)\nfalse\n\njulia> ispow2(4.5)\nfalse\n\njulia> ispow2(0.25)\ntrue\n\njulia> ispow2(1//8)\ntrue\n\ncompat: Julia 1.6\nSupport for non-Integer arguments was added in Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.nextpow","page":"Mathematics","title":"Base.nextpow","text":"nextpow(a, x)\n\nThe smallest a^n not less than x, where n is a non-negative integer. a must be greater than 1, and x must be greater than 0.\n\nSee also prevpow.\n\nExamples\n\njulia> nextpow(2, 7)\n8\n\njulia> nextpow(2, 9)\n16\n\njulia> nextpow(5, 20)\n25\n\njulia> nextpow(4, 16)\n16\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.prevpow","page":"Mathematics","title":"Base.prevpow","text":"prevpow(a, x)\n\nThe largest a^n not greater than x, where n is a non-negative integer. a must be greater than 1, and x must not be less than 1.\n\nSee also nextpow, isqrt.\n\nExamples\n\njulia> prevpow(2, 7)\n4\n\njulia> prevpow(2, 9)\n8\n\njulia> prevpow(5, 20)\n5\n\njulia> prevpow(4, 16)\n16\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.nextprod","page":"Mathematics","title":"Base.nextprod","text":"nextprod(factors::Union{Tuple,AbstractVector}, n)\n\nNext integer greater than or equal to n that can be written as prod k_i^p_i for integers p_1, p_2, etcetera, for factors k_i in factors.\n\nExamples\n\njulia> nextprod((2, 3), 105)\n108\n\njulia> 2^2 * 3^3\n108\n\ncompat: Julia 1.6\nThe method that accepts a tuple requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.invmod","page":"Mathematics","title":"Base.invmod","text":"invmod(n::Integer, m::Integer)\n\nTake the inverse of n modulo m: y such that n y = 1 pmod m, and div(ym) = 0. This will throw an error if m = 0, or if gcd(nm) neq 1.\n\nExamples\n\njulia> invmod(2, 5)\n3\n\njulia> invmod(2, 3)\n2\n\njulia> invmod(5, 6)\n5\n\n\n\n\n\ninvmod(n::Integer, T) where {T <: Base.BitInteger}\ninvmod(n::T) where {T <: Base.BitInteger}\n\nCompute the modular inverse of n in the integer ring of type T, i.e. modulo 2^N where N = 8*sizeof(T) (e.g. N = 32 for Int32). In other words these methods satisfy the following identities:\n\nn * invmod(n) == 1\n(n * invmod(n, T)) % T == 1\n(n % T) * invmod(n, T) == 1\n\nNote that * here is modular multiplication in the integer ring, T.\n\nSpecifying the modulus implied by an integer type as an explicit value is often inconvenient since the modulus is by definition too big to be represented by the type.\n\nThe modular inverse is computed much more efficiently than the general case using the algorithm described in https://arxiv.org/pdf/2204.04342.pdf.\n\ncompat: Julia 1.11\nThe invmod(n) and invmod(n, T) methods require Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.powermod","page":"Mathematics","title":"Base.powermod","text":"powermod(x::Integer, p::Integer, m)\n\nCompute x^p pmod m.\n\nExamples\n\njulia> powermod(2, 6, 5)\n4\n\njulia> mod(2^6, 5)\n4\n\njulia> powermod(5, 2, 20)\n5\n\njulia> powermod(5, 2, 19)\n6\n\njulia> powermod(5, 3, 19)\n11\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.ndigits","page":"Mathematics","title":"Base.ndigits","text":"ndigits(n::Integer; base::Integer=10, pad::Integer=1)\n\nCompute the number of digits in integer n written in base base (base must not be in [-1, 0, 1]), optionally padded with zeros to a specified size (the result will never be less than pad).\n\nSee also digits, count_ones.\n\nExamples\n\njulia> ndigits(0)\n1\n\njulia> ndigits(12345)\n5\n\njulia> ndigits(1022, base=16)\n3\n\njulia> string(1022, base=16)\n\"3fe\"\n\njulia> ndigits(123, pad=5)\n5\n\njulia> ndigits(-123)\n3\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.add_sum","page":"Mathematics","title":"Base.add_sum","text":"Base.add_sum(x, y)\n\nThe reduction operator used in sum. The main difference from + is that small integers are promoted to Int/UInt.\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.widemul","page":"Mathematics","title":"Base.widemul","text":"widemul(x, y)\n\nMultiply x and y, giving the result as a larger type.\n\nSee also promote, Base.add_sum.\n\nExamples\n\njulia> widemul(Float32(3.0), 4.0) isa BigFloat\ntrue\n\njulia> typemax(Int8) * typemax(Int8)\n1\n\njulia> widemul(typemax(Int8), typemax(Int8)) # == 127^2\n16129\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.evalpoly","page":"Mathematics","title":"Base.Math.evalpoly","text":"evalpoly(x, p)\n\nEvaluate the polynomial sum_k x^k-1 pk for the coefficients p[1], p[2], ...; that is, the coefficients are given in ascending order by power of x. Loops are unrolled at compile time if the number of coefficients is statically known, i.e. when p is a Tuple. This function generates efficient code using Horner's method if x is real, or using a Goertzel-like [DK62] algorithm if x is complex.\n\n[DK62]: Donald Knuth, Art of Computer Programming, Volume 2: Seminumerical Algorithms, Sec. 4.6.4.\n\ncompat: Julia 1.4\nThis function requires Julia 1.4 or later.\n\nExamples\n\njulia> evalpoly(2, (1, 2, 3))\n17\n\n\n\n\n\n","category":"function"},{"location":"base/math/#Base.Math.@evalpoly","page":"Mathematics","title":"Base.Math.@evalpoly","text":"@evalpoly(z, c...)\n\nEvaluate the polynomial sum_k z^k-1 ck for the coefficients c[1], c[2], ...; that is, the coefficients are given in ascending order by power of z. This macro expands to efficient inline code that uses either Horner's method or, for complex z, a more efficient Goertzel-like algorithm.\n\nSee also evalpoly.\n\nExamples\n\njulia> @evalpoly(3, 1, 0, 1)\n10\n\njulia> @evalpoly(2, 1, 0, 1)\n5\n\njulia> @evalpoly(2, 1, 1, 1)\n7\n\n\n\n\n\n","category":"macro"},{"location":"base/math/#Base.FastMath.@fastmath","page":"Mathematics","title":"Base.FastMath.@fastmath","text":"@fastmath expr\n\nExecute a transformed version of the expression, which calls functions that may violate strict IEEE semantics. This allows the fastest possible operation, but results are undefined – be careful when doing this, as it may change numerical results.\n\nThis sets the LLVM Fast-Math flags, and corresponds to the -ffast-math option in clang. See the notes on performance annotations for more details.\n\nExamples\n\njulia> @fastmath 1+2\n3\n\njulia> @fastmath(sin(3))\n0.1411200080598672\n\n\n\n\n\n","category":"macro"},{"location":"base/math/#Customizable-binary-operators","page":"Mathematics","title":"Customizable binary operators","text":"","category":"section"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Some unicode characters can be used to define new binary operators that support infix notation. For example ⊗(x,y) = kron(x,y) defines the ⊗ (otimes) function to be the Kronecker product, and one can call it as binary operator using infix syntax: C = A ⊗ B as well as with the usual prefix syntax C = ⊗(A,B).","category":"page"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Other characters that support such extensions include \\odot ⊙ and \\oplus ⊕","category":"page"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"The complete list is in the parser code: https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm","category":"page"},{"location":"base/math/","page":"Mathematics","title":"Mathematics","text":"Those that are parsed like * (in terms of precedence) include * / ÷ % & ⋅ ∘ × |\\\\| ∩ ∧ ⊗ ⊘ ⊙ ⊚ ⊛ ⊠ ⊡ ⊓ ∗ ∙ ∤ ⅋ ≀ ⊼ ⋄ ⋆ ⋇ ⋉ ⋊ ⋋ ⋌ ⋏ ⋒ ⟑ ⦸ ⦼ ⦾ ⦿ ⧶ ⧷ ⨇ ⨰ ⨱ ⨲ ⨳ ⨴ ⨵ ⨶ ⨷ ⨸ ⨻ ⨼ ⨽ ⩀ ⩃ ⩄ ⩋ ⩍ ⩎ ⩑ ⩓ ⩕ ⩘ ⩚ ⩜ ⩞ ⩟ ⩠ ⫛ ⊍ ▷ ⨝ ⟕ ⟖ ⟗ and those that are parsed like + include + - |\\|| ⊕ ⊖ ⊞ ⊟ |++| ∪ ∨ ⊔ ± ∓ ∔ ∸ ≏ ⊎ ⊻ ⊽ ⋎ ⋓ ⟇ ⧺ ⧻ ⨈ ⨢ ⨣ ⨤ ⨥ ⨦ ⨧ ⨨ ⨩ ⨪ ⨫ ⨬ ⨭ ⨮ ⨹ ⨺ ⩁ ⩂ ⩅ ⩊ ⩌ ⩏ ⩐ ⩒ ⩔ ⩖ ⩗ ⩛ ⩝ ⩡ ⩢ ⩣ There are many others that are related to arrows, comparisons, and powers.","category":"page"},{"location":"stdlib/ArgTools/","page":"ArgTools","title":"ArgTools","text":"EditURL = \"https://github.com/JuliaIO/ArgTools.jl/blob/master/docs/src/index.md\"","category":"page"},{"location":"stdlib/ArgTools/#ArgTools","page":"ArgTools","title":"ArgTools","text":"","category":"section"},{"location":"stdlib/ArgTools/#Argument-Handling","page":"ArgTools","title":"Argument Handling","text":"","category":"section"},{"location":"stdlib/ArgTools/","page":"ArgTools","title":"ArgTools","text":"ArgTools.ArgRead\nArgTools.ArgWrite\nArgTools.arg_read\nArgTools.arg_write\nArgTools.arg_isdir\nArgTools.arg_mkdir","category":"page"},{"location":"stdlib/ArgTools/#ArgTools.ArgRead","page":"ArgTools","title":"ArgTools.ArgRead","text":"ArgRead = Union{AbstractString, AbstractCmd, IO}\n\nThe ArgRead types is a union of the types that the arg_read function knows how to convert into readable IO handles. See arg_read for details.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/ArgTools/#ArgTools.ArgWrite","page":"ArgTools","title":"ArgTools.ArgWrite","text":"ArgWrite = Union{AbstractString, AbstractCmd, IO}\n\nThe ArgWrite types is a union of the types that the arg_write function knows how to convert into writeable IO handles, except for Nothing which arg_write handles by generating a temporary file. See arg_write for details.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/ArgTools/#ArgTools.arg_read","page":"ArgTools","title":"ArgTools.arg_read","text":"arg_read(f::Function, arg::ArgRead) -> f(arg_io)\n\nThe arg_read function accepts an argument arg that can be any of these:\n\nAbstractString: a file path to be opened for reading\nAbstractCmd: a command to be run, reading from its standard output\nIO: an open IO handle to be read from\n\nWhether the body returns normally or throws an error, a path which is opened will be closed before returning from arg_read and an IO handle will be flushed but not closed before returning from arg_read.\n\nNote: when opening a file, ArgTools will pass lock = false to the file open(...) call. Therefore, the object returned by this function should not be used from multiple threads. This restriction may be relaxed in the future, which would not break any working code.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.arg_write","page":"ArgTools","title":"ArgTools.arg_write","text":"arg_write(f::Function, arg::ArgWrite) -> arg\narg_write(f::Function, arg::Nothing) -> tempname()\n\nThe arg_read function accepts an argument arg that can be any of these:\n\nAbstractString: a file path to be opened for writing\nAbstractCmd: a command to be run, writing to its standard input\nIO: an open IO handle to be written to\nNothing: a temporary path should be written to\n\nIf the body returns normally, a path that is opened will be closed upon completion; an IO handle argument is left open but flushed before return. If the argument is nothing then a temporary path is opened for writing and closed open completion and the path is returned from arg_write. In all other cases, arg itself is returned. This is a useful pattern since you can consistently return whatever was written, whether an argument was passed or not.\n\nIf there is an error during the evaluation of the body, a path that is opened by arg_write for writing will be deleted, whether it's passed in as a string or a temporary path generated when arg is nothing.\n\nNote: when opening a file, ArgTools will pass lock = false to the file open(...) call. Therefore, the object returned by this function should not be used from multiple threads. This restriction may be relaxed in the future, which would not break any working code.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.arg_isdir","page":"ArgTools","title":"ArgTools.arg_isdir","text":"arg_isdir(f::Function, arg::AbstractString) -> f(arg)\n\nThe arg_isdir function takes arg which must be the path to an existing directory (an error is raised otherwise) and passes that path to f finally returning the result of f(arg). This is definitely the least useful tool offered by ArgTools and mostly exists for symmetry with arg_mkdir and to give consistent error messages.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.arg_mkdir","page":"ArgTools","title":"ArgTools.arg_mkdir","text":"arg_mkdir(f::Function, arg::AbstractString) -> arg\narg_mkdir(f::Function, arg::Nothing) -> mktempdir()\n\nThe arg_mkdir function takes arg which must either be one of:\n\na path to an already existing empty directory,\na non-existent path which can be created as a directory, or\nnothing in which case a temporary directory is created.\n\nIn all cases the path to the directory is returned. If an error occurs during f(arg), the directory is returned to its original state: if it already existed but was empty, it will be emptied; if it did not exist it will be deleted.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#Function-Testing","page":"ArgTools","title":"Function Testing","text":"","category":"section"},{"location":"stdlib/ArgTools/","page":"ArgTools","title":"ArgTools","text":"ArgTools.arg_readers\nArgTools.arg_writers\nArgTools.@arg_test","category":"page"},{"location":"stdlib/ArgTools/#ArgTools.arg_readers","page":"ArgTools","title":"ArgTools.arg_readers","text":"arg_readers(arg :: AbstractString, [ type = ArgRead ]) do arg::Function\n ## pre-test setup ##\n @arg_test arg begin\n arg :: ArgRead\n ## test using `arg` ##\n end\n ## post-test cleanup ##\nend\n\nThe arg_readers function takes a path to be read and a single-argument do block, which is invoked once for each test reader type that arg_read can handle. If the optional type argument is given then the do block is only invoked for readers that produce arguments of that type.\n\nThe arg passed to the do block is not the argument value itself, because some of test argument types need to be initialized and finalized for each test case. Consider an open file handle argument: once you've used it for one test, you can't use it again; you need to close it and open the file again for the next test. This function arg can be converted into an ArgRead instance using @arg_test arg begin ... end.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.arg_writers","page":"ArgTools","title":"ArgTools.arg_writers","text":"arg_writers([ type = ArgWrite ]) do path::String, arg::Function\n ## pre-test setup ##\n @arg_test arg begin\n arg :: ArgWrite\n ## test using `arg` ##\n end\n ## post-test cleanup ##\nend\n\nThe arg_writers function takes a do block, which is invoked once for each test writer type that arg_write can handle with a temporary (non-existent) path and arg which can be converted into various writable argument types which write to path. If the optional type argument is given then the do block is only invoked for writers that produce arguments of that type.\n\nThe arg passed to the do block is not the argument value itself, because some of test argument types need to be initialized and finalized for each test case. Consider an open file handle argument: once you've used it for one test, you can't use it again; you need to close it and open the file again for the next test. This function arg can be converted into an ArgWrite instance using @arg_test arg begin ... end.\n\nThere is also an arg_writers method that takes a path name like arg_readers:\n\narg_writers(path::AbstractString, [ type = ArgWrite ]) do arg::Function\n ## pre-test setup ##\n @arg_test arg begin\n # here `arg :: ArgWrite`\n ## test using `arg` ##\n end\n ## post-test cleanup ##\nend\n\nThis method is useful if you need to specify path instead of using path name generated by tempname(). Since path is passed from outside of arg_writers, the path is not an argument to the do block in this form.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/ArgTools/#ArgTools.@arg_test","page":"ArgTools","title":"ArgTools.@arg_test","text":"@arg_test arg1 arg2 ... body\n\nThe @arg_test macro is used to convert arg functions provided by arg_readers and arg_writers into actual argument values. When you write @arg_test arg body it is equivalent to arg(arg -> body).\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/JuliaSyntaxHighlighting/#Julia-Syntax-Highlighting","page":"Julia Syntax Highlighting","title":"Julia Syntax Highlighting","text":"","category":"section"},{"location":"stdlib/JuliaSyntaxHighlighting/","page":"Julia Syntax Highlighting","title":"Julia Syntax Highlighting","text":"JuliaSyntaxHighlighting.highlight\nJuliaSyntaxHighlighting.highlight!","category":"page"},{"location":"stdlib/JuliaSyntaxHighlighting/#JuliaSyntaxHighlighting.highlight","page":"Julia Syntax Highlighting","title":"JuliaSyntaxHighlighting.highlight","text":"highlight(content::Union{AbstractString, IOBuffer, IOContext{IOBuffer}})\n\nApply syntax highlighting to content using JuliaSyntax.\n\nReturns an AnnotatedString{String}.\n\nExamples\n\njulia> JuliaSyntaxHighlighting.highlight(\"sum(1:8)\")\n\"sum(1:8)\"\n\njulia> JuliaSyntaxHighlighting.highlight(\"sum(1:8)\") |> Base.annotations\n6-element Vector{Tuple{UnitRange{Int64}, Pair{Symbol, Any}}}:\n (1:3, :face => :julia_funcall)\n (4:4, :face => :julia_rainbow_paren_1)\n (5:5, :face => :julia_number)\n (6:6, :face => :julia_operator)\n (7:7, :face => :julia_number)\n (8:8, :face => :julia_rainbow_paren_1)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/JuliaSyntaxHighlighting/#JuliaSyntaxHighlighting.highlight!","page":"Julia Syntax Highlighting","title":"JuliaSyntaxHighlighting.highlight!","text":"highlight!(content::Union{AnnotatedString, SubString{AnnotatedString}})\n\nModify content by applying syntax highlighting using JuliaSyntax.\n\nExamples\n\njulia> str = Base.AnnotatedString(\"sum(1:8)\")\n\"sum(1:8)\"\n\njulia> JuliaSyntaxHighlighting.highlight!(str)\n\"sum(1:8)\"\n\njulia> Base.annotations(str)\n6-element Vector{Tuple{UnitRange{Int64}, Pair{Symbol, Any}}}:\n (1:3, :face => :julia_funcall)\n (4:4, :face => :julia_rainbow_paren_1)\n (5:5, :face => :julia_number)\n (6:6, :face => :julia_operator)\n (7:7, :face => :julia_number)\n (8:8, :face => :julia_rainbow_paren_1)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Markdown/docs/src/index.md\"","category":"page"},{"location":"stdlib/Markdown/#markdown_stdlib","page":"Markdown","title":"Markdown","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This section describes Julia's markdown syntax, which is enabled by the Markdown standard library. The following Markdown elements are supported:","category":"page"},{"location":"stdlib/Markdown/#Inline-elements","page":"Markdown","title":"Inline elements","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Here \"inline\" refers to elements that can be found within blocks of text, i.e. paragraphs. These include the following elements.","category":"page"},{"location":"stdlib/Markdown/#Bold","page":"Markdown","title":"Bold","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Surround words with two asterisks, **, to display the enclosed text in boldface.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing a **bold** word.","category":"page"},{"location":"stdlib/Markdown/#Italics","page":"Markdown","title":"Italics","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Surround words with one asterisk, *, to display the enclosed text in italics.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing an *italicized* word.","category":"page"},{"location":"stdlib/Markdown/#Literals","page":"Markdown","title":"Literals","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Surround text that should be displayed exactly as written with single backticks, ` .","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing a `literal` word.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Literals should be used when writing text that refers to names of variables, functions, or other parts of a Julia program.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"tip: Tip\nTo include a backtick character within literal text use three backticks rather than one to enclose the text.A paragraph containing ``` `backtick` characters ```.By extension any odd number of backticks may be used to enclose a lesser number of backticks.","category":"page"},{"location":"stdlib/Markdown/#\\LaTeX","page":"Markdown","title":"LaTeX","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Surround text that should be displayed as mathematics using LaTeX syntax with double backticks, `` .","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing some ``\\LaTeX`` markup.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"tip: Tip\nAs with literals in the previous section, if literal backticks need to be written within double backticks use an even number greater than two. Note that if a single literal backtick needs to be included within LaTeX markup then two enclosing backticks is sufficient.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nThe \\ character should be escaped appropriately if the text is embedded in a Julia source code, for example, \"``\\\\LaTeX`` syntax in a docstring.\", since it is interpreted as a string literal. Alternatively, in order to avoid escaping, it is possible to use the raw string macro together with the @doc macro:@doc raw\"``\\LaTeX`` syntax in a docstring.\" functionname","category":"page"},{"location":"stdlib/Markdown/#Links","page":"Markdown","title":"Links","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Links to either external or internal targets can be written using the following syntax, where the text enclosed in square brackets, [ ], is the name of the link and the text enclosed in parentheses, ( ), is the URL.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing a link to [Julia](https://www.julialang.org).","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"It's also possible to add cross-references to other documented functions/methods/variables within the Julia documentation itself. For example:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"\"\"\"\n tryparse(type, str; base)\n\nLike [`parse`](@ref), but returns either a value of the requested type,\nor [`nothing`](@ref) if the string does not contain a valid number.\n\"\"\"","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This will create a link in the generated docs to the parse documentation (which has more information about what this function actually does), and to the nothing documentation. It's good to include cross references to mutating/non-mutating versions of a function, or to highlight a difference between two similar-seeming functions.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nThe above cross referencing is not a Markdown feature, and relies on Documenter.jl, which is used to build base Julia's documentation.","category":"page"},{"location":"stdlib/Markdown/#Footnote-references","page":"Markdown","title":"Footnote references","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Named and numbered footnote references can be written using the following syntax. A footnote name must be a single alphanumeric word containing no punctuation.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph containing a numbered footnote [^1] and a named one [^named].","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nThe text associated with a footnote can be written anywhere within the same page as the footnote reference. The syntax used to define the footnote text is discussed in the Footnotes section below.","category":"page"},{"location":"stdlib/Markdown/#Toplevel-elements","page":"Markdown","title":"Toplevel elements","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The following elements can be written either at the \"toplevel\" of a document or within another \"toplevel\" element.","category":"page"},{"location":"stdlib/Markdown/#Paragraphs","page":"Markdown","title":"Paragraphs","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A paragraph is a block of plain text, possibly containing any number of inline elements defined in the Inline elements section above, with one or more blank lines above and below it.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This is a paragraph.\n\nAnd this is *another* paragraph containing some emphasized text.\nA new line, but still part of the same paragraph.","category":"page"},{"location":"stdlib/Markdown/#Headers","page":"Markdown","title":"Headers","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A document can be split up into different sections using headers. Headers use the following syntax:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"# Level One\n## Level Two\n### Level Three\n#### Level Four\n##### Level Five\n###### Level Six","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A header line can contain any inline syntax in the same way as a paragraph can.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"tip: Tip\nTry to avoid using too many levels of header within a single document. A heavily nested document may be indicative of a need to restructure it or split it into several pages covering separate topics.","category":"page"},{"location":"stdlib/Markdown/#Code-blocks","page":"Markdown","title":"Code blocks","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Source code can be displayed as a literal block using an indent of four spaces or one tab as shown in the following example.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This is a paragraph.\n\n function func(x)\n # ...\n end\n\nAnother paragraph.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Additionally, code blocks can be enclosed using triple backticks with an optional \"language\" to specify how a block of code should be highlighted.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A code block without a \"language\":\n\n```\nfunction func(x)\n # ...\nend\n```\n\nand another one with the \"language\" specified as `julia`:\n\n```julia\nfunction func(x)\n # ...\nend\n```","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\n\"Fenced\" code blocks, as shown in the last example, should be preferred over indented code blocks since there is no way to specify what language an indented code block is written in.","category":"page"},{"location":"stdlib/Markdown/#Block-quotes","page":"Markdown","title":"Block quotes","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Text from external sources, such as quotations from books or websites, can be quoted using > characters prepended to each line of the quote as follows.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Here's a quote:\n\n> Julia is a high-level, high-performance dynamic programming language for\n> technical computing, with syntax that is familiar to users of other\n> technical computing environments.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Note that a single space must appear after the > character on each line. Quoted blocks may themselves contain other toplevel or inline elements.","category":"page"},{"location":"stdlib/Markdown/#Images","page":"Markdown","title":"Images","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The syntax for images is similar to the link syntax mentioned above. Prepending a ! character to a link will display an image from the specified URL rather than a link to it.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"![alternative text](link/to/image.png)","category":"page"},{"location":"stdlib/Markdown/#Lists","page":"Markdown","title":"Lists","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Unordered lists can be written by prepending each item in a list with either *, +, or -.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A list of items:\n\n * item one\n * item two\n * item three","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Note the two spaces before each * and the single space after each one.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Lists can contain other nested toplevel elements such as lists, code blocks, or quoteblocks. A blank line should be left between each list item when including any toplevel elements within a list.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Another list:\n\n * item one\n\n * item two\n\n ```\n f(x) = x\n ```\n\n * And a sublist:\n\n + sub-item one\n + sub-item two","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nThe contents of each item in the list must line up with the first line of the item. In the above example the fenced code block must be indented by four spaces to align with the i in item two.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Ordered lists are written by replacing the \"bullet\" character, either *, +, or -, with a positive integer followed by either . or ).","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Two ordered lists:\n\n 1. item one\n 2. item two\n 3. item three\n\n 5) item five\n 6) item six\n 7) item seven","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"An ordered list may start from a number other than one, as in the second list of the above example, where it is numbered from five. As with unordered lists, ordered lists can contain nested toplevel elements.","category":"page"},{"location":"stdlib/Markdown/#Display-equations","page":"Markdown","title":"Display equations","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Large LaTeX equations that do not fit inline within a paragraph may be written as display equations using a fenced code block with the \"language\" math as in the example below.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"```math\nf(a) = \\frac{1}{2\\pi}\\int_{0}^{2\\pi} (\\alpha+R\\cos(\\theta))d\\theta\n```","category":"page"},{"location":"stdlib/Markdown/#Footnotes","page":"Markdown","title":"Footnotes","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"This syntax is paired with the inline syntax for Footnote references. Make sure to read that section as well.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Footnote text is defined using the following syntax, which is similar to footnote reference syntax, aside from the : character that is appended to the footnote label.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"[^1]: Numbered footnote text.\n\n[^note]:\n\n Named footnote text containing several toplevel elements\n indented by 4 spaces or one tab.\n\n * item one\n * item two\n * item three\n\n ```julia\n function func(x)\n # ...\n end\n ```","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nNo checks are done during parsing to make sure that all footnote references have matching footnotes.","category":"page"},{"location":"stdlib/Markdown/#Horizontal-rules","page":"Markdown","title":"Horizontal rules","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The equivalent of an
    HTML tag can be achieved using three hyphens (---). For example:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Text above the line.\n\n---\n\nAnd text below the line.","category":"page"},{"location":"stdlib/Markdown/#Tables","page":"Markdown","title":"Tables","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Basic tables can be written using the syntax described below. Note that markdown tables have limited features and cannot contain nested toplevel elements unlike other elements discussed above – only inline elements are allowed. Tables must always contain a header row with column names. Cells cannot span multiple rows or columns of the table.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"| Column One | Column Two | Column Three |\n|:---------- | ---------- |:------------:|\n| Row `1` | Column `2` | |\n| *Row* 2 | **Row** 2 | Column ``3`` |","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"note: Note\nAs illustrated in the above example each column of | characters must be aligned vertically.A : character on either end of a column's header separator (the row containing - characters) specifies whether the row is left-aligned, right-aligned, or (when : appears on both ends) center-aligned. Providing no : characters will default to right-aligning the column.","category":"page"},{"location":"stdlib/Markdown/#Admonitions","page":"Markdown","title":"Admonitions","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Specially formatted blocks, known as admonitions, can be used to highlight particular remarks. They can be defined using the following !!! syntax:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"!!! note\n\n This is the content of the note.\n It is indented by 4 spaces. A tab would work as well.\n\n!!! warning \"Beware!\"\n\n And this is another one.\n\n This warning admonition has a custom title: `\"Beware!\"`.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The first word after !!! declares the type of the admonition. There are standard admonition types that should produce special styling. Namely (in order of decreasing severity): danger, warning, info/note, and tip.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"You can also use your own admonition types, as long as the type name only contains lowercase Latin characters (a-z). For example, you could have a terminology block like this:","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"!!! terminology \"julia vs Julia\"\n\n Strictly speaking, \"Julia\" refers to the language,\n and \"julia\" to the standard implementation.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"However, unless the code rendering the Markdown special-cases that particular admonition type, it will get the default styling.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"A custom title for the box can be provided as a string (in double quotes) after the admonition type. If no title text is specified after the admonition type, then the type name will be used as the title (e.g. \"Note\" for the note admonition).","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Admonitions, like most other toplevel elements, can contain other toplevel elements (e.g. lists, images).","category":"page"},{"location":"stdlib/Markdown/#stdlib-markdown-literals","page":"Markdown","title":"Markdown String Literals","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"The md\"\" macro allows you to embed Markdown strings directly into your Julia code. This macro is designed to simplify the inclusion of Markdown-formatted text within your Julia source files.","category":"page"},{"location":"stdlib/Markdown/#Usage","page":"Markdown","title":"Usage","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"result = md\"This is a **custom** Markdown string with [a link](http://example.com).\"","category":"page"},{"location":"stdlib/Markdown/#Markdown-Syntax-Extensions","page":"Markdown","title":"Markdown Syntax Extensions","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Julia's markdown supports interpolation in a very similar way to basic string literals, with the difference that it will store the object itself in the Markdown tree (as opposed to converting it to a string). When the Markdown content is rendered the usual show methods will be called, and these can be overridden as usual. This design allows the Markdown to be extended with arbitrarily complex features (such as references) without cluttering the basic syntax.","category":"page"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"In principle, the Markdown parser itself can also be arbitrarily extended by packages, or an entirely custom flavour of Markdown can be used, but this should generally be unnecessary.","category":"page"},{"location":"stdlib/Markdown/#stdlib-markdown-api","page":"Markdown","title":"API reference","text":"","category":"section"},{"location":"stdlib/Markdown/","page":"Markdown","title":"Markdown","text":"Markdown.MD\nMarkdown.@md_str\nMarkdown.@doc_str\nMarkdown.html\nMarkdown.latex","category":"page"},{"location":"stdlib/Markdown/#Markdown.MD","page":"Markdown","title":"Markdown.MD","text":"MD\n\nMD represents a Markdown document. Note that the MD constructor should not generally be used directly, since it constructs the internal data structures. Instead, you can construct MD objects using the exported macros @md_str and @doc_str.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Markdown/#Markdown.@md_str","page":"Markdown","title":"Markdown.@md_str","text":"@md_str -> MD\n\nParse the given string as Markdown text and return a corresponding MD object.\n\nExamples\n\njulia> s = md\"# Hello, world!\"\n Hello, world!\n ≡≡≡≡≡≡≡≡≡≡≡≡≡\n\njulia> typeof(s)\nMarkdown.MD\n\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Markdown/#Markdown.@doc_str","page":"Markdown","title":"Markdown.@doc_str","text":"@doc_str -> MD\n\nParse the given string as Markdown text, add line and module information and return a corresponding MD object.\n\n@doc_str can be used in conjunction with the Base.Docs module. Please also refer to the manual section on documentation for more information.\n\nExamples\n\njulia> s = doc\"f(x) = 2*x\"\n f(x) = 2*x\n\njulia> typeof(s)\nMarkdown.MD\n\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Markdown/#Markdown.html","page":"Markdown","title":"Markdown.html","text":"html([io::IO], md)\n\nOutput the contents of the Markdown object md in HTML format, either writing to an (optional) io stream or returning a string.\n\nOne can alternatively use show(io, \"text/html\", md) or repr(\"text/html\", md), which differ in that they wrap the output in a
    ...
    element.\n\nExamples\n\njulia> html(md\"hello _world_\")\n\"

    hello world

    \\n\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Markdown/#Markdown.latex","page":"Markdown","title":"Markdown.latex","text":"latex([io::IO], md)\n\nOutput the contents of the Markdown object md in LaTeX format, either writing to an (optional) io stream or returning a string.\n\nOne can alternatively use show(io, \"text/latex\", md) or repr(\"text/latex\", md).\n\nExamples\n\njulia> latex(md\"hello _world_\")\n\"hello \\\\emph{world}\\n\\n\"\n\n\n\n\n\n","category":"function"},{"location":"devdocs/subarrays/#SubArrays","page":"SubArrays","title":"SubArrays","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Julia's SubArray type is a container encoding a \"view\" of a parent AbstractArray. This page documents some of the design principles and implementation of SubArrays.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"One of the major design goals is to ensure high performance for views of both IndexLinear and IndexCartesian arrays. Furthermore, views of IndexLinear arrays should themselves be IndexLinear to the extent that it is possible.","category":"page"},{"location":"devdocs/subarrays/#Index-replacement","page":"SubArrays","title":"Index replacement","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Consider making 2d slices of a 3d array:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"DocTestSetup = :(import Random; Random.seed!(1234))","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> A = rand(2,3,4);\n\njulia> S1 = view(A, :, 1, 2:3)\n2×2 view(::Array{Float64, 3}, :, 1, 2:3) with eltype Float64:\n 0.839622 0.711389\n 0.967143 0.103929\n\njulia> S2 = view(A, 1, :, 2:3)\n3×2 view(::Array{Float64, 3}, 1, :, 2:3) with eltype Float64:\n 0.839622 0.711389\n 0.789764 0.806704\n 0.566704 0.962715","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"DocTestSetup = nothing","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"view drops \"singleton\" dimensions (ones that are specified by an Int), so both S1 and S2 are two-dimensional SubArrays. Consequently, the natural way to index these is with S1[i,j]. To extract the value from the parent array A, the natural approach is to replace S1[i,j] with A[i,1,(2:3)[j]] and S2[i,j] with A[1,i,(2:3)[j]].","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"The key feature of the design of SubArrays is that this index replacement can be performed without any runtime overhead.","category":"page"},{"location":"devdocs/subarrays/#SubArray-design","page":"SubArrays","title":"SubArray design","text":"","category":"section"},{"location":"devdocs/subarrays/#Type-parameters-and-fields","page":"SubArrays","title":"Type parameters and fields","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"The strategy adopted is first and foremost expressed in the definition of the type:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"struct SubArray{T,N,P,I,L} <: AbstractArray{T,N}\n parent::P\n indices::I\n offset1::Int # for linear indexing and pointer, only valid when L==true\n stride1::Int # used only for linear indexing\n ...\nend","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"SubArray has 5 type parameters. The first two are the standard element type and dimensionality. The next is the type of the parent AbstractArray. The most heavily-used is the fourth parameter, a Tuple of the types of the indices for each dimension. The final one, L, is only provided as a convenience for dispatch; it's a boolean that represents whether the index types support fast linear indexing. More on that later.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"If in our example above A is a Array{Float64, 3}, our S1 case above would be a SubArray{Float64,2,Array{Float64,3},Tuple{Base.Slice{Base.OneTo{Int64}},Int64,UnitRange{Int64}},false}. Note in particular the tuple parameter, which stores the types of the indices used to create S1. Likewise,","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> S1.indices\n(Base.Slice(Base.OneTo(2)), 1, 2:3)","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Storing these values allows index replacement, and having the types encoded as parameters allows one to dispatch to efficient algorithms.","category":"page"},{"location":"devdocs/subarrays/#Index-translation","page":"SubArrays","title":"Index translation","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Performing index translation requires that you do different things for different concrete SubArray types. For example, for S1, one needs to apply the i,j indices to the first and third dimensions of the parent array, whereas for S2 one needs to apply them to the second and third. The simplest approach to indexing would be to do the type-analysis at runtime:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"parentindices = Vector{Any}()\nfor thisindex in S.indices\n ...\n if isa(thisindex, Int)\n # Don't consume one of the input indices\n push!(parentindices, thisindex)\n elseif isa(thisindex, AbstractVector)\n # Consume an input index\n push!(parentindices, thisindex[inputindex[j]])\n j += 1\n elseif isa(thisindex, AbstractMatrix)\n # Consume two input indices\n push!(parentindices, thisindex[inputindex[j], inputindex[j+1]])\n j += 2\n elseif ...\nend\nS.parent[parentindices...]","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Unfortunately, this would be disastrous in terms of performance: each element access would allocate memory, and involves the running of a lot of poorly-typed code.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"The better approach is to dispatch to specific methods to handle each type of stored index. That's what reindex does: it dispatches on the type of the first stored index and consumes the appropriate number of input indices, and then it recurses on the remaining indices. In the case of S1, this expands to","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Base.reindex(S1, S1.indices, (i, j)) == (i, S1.indices[2], S1.indices[3][j])","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"for any pair of indices (i,j) (except CartesianIndexs and arrays thereof, see below).","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"This is the core of a SubArray; indexing methods depend upon reindex to do this index translation. Sometimes, though, we can avoid the indirection and make it even faster.","category":"page"},{"location":"devdocs/subarrays/#Linear-indexing","page":"SubArrays","title":"Linear indexing","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Linear indexing can be implemented efficiently when the entire array has a single stride that separates successive elements, starting from some offset. This means that we can pre-compute these values and represent linear indexing simply as an addition and multiplication, avoiding the indirection of reindex and (more importantly) the slow computation of the cartesian coordinates entirely.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"For SubArray types, the availability of efficient linear indexing is based purely on the types of the indices, and does not depend on values like the size of the parent array. You can ask whether a given set of indices supports fast linear indexing with the internal Base.viewindexing function:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> Base.viewindexing(S1.indices)\nIndexCartesian()\n\njulia> Base.viewindexing(S2.indices)\nIndexLinear()","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"This is computed during construction of the SubArray and stored in the L type parameter as a boolean that encodes fast linear indexing support. While not strictly necessary, it means that we can define dispatch directly on SubArray{T,N,A,I,true} without any intermediaries.","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Since this computation doesn't depend on runtime values, it can miss some cases in which the stride happens to be uniform:","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> A = reshape(1:4*2, 4, 2)\n4×2 reshape(::UnitRange{Int64}, 4, 2) with eltype Int64:\n 1 5\n 2 6\n 3 7\n 4 8\n\njulia> diff(A[2:2:4,:][:])\n3-element Vector{Int64}:\n 2\n 2\n 2","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"A view constructed as view(A, 2:2:4, :) happens to have uniform stride, and therefore linear indexing indeed could be performed efficiently. However, success in this case depends on the size of the array: if the first dimension instead were odd,","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"julia> A = reshape(1:5*2, 5, 2)\n5×2 reshape(::UnitRange{Int64}, 5, 2) with eltype Int64:\n 1 6\n 2 7\n 3 8\n 4 9\n 5 10\n\njulia> diff(A[2:2:4,:][:])\n3-element Vector{Int64}:\n 2\n 3\n 2","category":"page"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"then A[2:2:4,:] does not have uniform stride, so we cannot guarantee efficient linear indexing. Since we have to base this decision based purely on types encoded in the parameters of the SubArray, S = view(A, 2:2:4, :) cannot implement efficient linear indexing.","category":"page"},{"location":"devdocs/subarrays/#A-few-details","page":"SubArrays","title":"A few details","text":"","category":"section"},{"location":"devdocs/subarrays/","page":"SubArrays","title":"SubArrays","text":"Note that the Base.reindex function is agnostic to the types of the input indices; it simply determines how and where the stored indices should be reindexed. It not only supports integer indices, but it supports non-scalar indexing, too. This means that views of views don't need two levels of indirection; they can simply re-compute the indices into the original parent array!\nHopefully by now it's fairly clear that supporting slices means that the dimensionality, given by the parameter N, is not necessarily equal to the dimensionality of the parent array or the length of the indices tuple. Neither do user-supplied indices necessarily line up with entries in the indices tuple (e.g., the second user-supplied index might correspond to the third dimension of the parent array, and the third element in the indices tuple).\nWhat might be less obvious is that the dimensionality of the stored parent array must be equal to the number of effective indices in the indices tuple. Some examples:\nA = reshape(1:35, 5, 7) # A 2d parent Array\nS = view(A, 2:7) # A 1d view created by linear indexing\nS = view(A, :, :, 1:1) # Appending extra indices is supported\nNaively, you'd think you could just set S.parent = A and S.indices = (:,:,1:1), but supporting this dramatically complicates the reindexing process, especially for views of views. Not only do you need to dispatch on the types of the stored indices, but you need to examine whether a given index is the final one and \"merge\" any remaining stored indices together. This is not an easy task, and even worse: it's slow since it implicitly depends upon linear indexing.\nFortunately, this is precisely the computation that ReshapedArray performs, and it does so linearly if possible. Consequently, view ensures that the parent array is the appropriate dimensionality for the given indices by reshaping it if needed. The inner SubArray constructor ensures that this invariant is satisfied.\nCartesianIndex and arrays thereof throw a nasty wrench into the reindex scheme. Recall that reindex simply dispatches on the type of the stored indices in order to determine how many passed indices should be used and where they should go. But with CartesianIndex, there's no longer a one-to-one correspondence between the number of passed arguments and the number of dimensions that they index into. If we return to the above example of Base.reindex(S1, S1.indices, (i, j)), you can see that the expansion is incorrect for i, j = CartesianIndex(), CartesianIndex(2,1). It should skip the CartesianIndex() entirely and return:\n(CartesianIndex(2,1)[1], S1.indices[2], S1.indices[3][CartesianIndex(2,1)[2]])\nInstead, though, we get:\n(CartesianIndex(), S1.indices[2], S1.indices[3][CartesianIndex(2,1)])\nDoing this correctly would require combined dispatch on both the stored and passed indices across all combinations of dimensionalities in an intractable manner. As such, reindex must never be called with CartesianIndex indices. Fortunately, the scalar case is easily handled by first flattening the CartesianIndex arguments to plain integers. Arrays of CartesianIndex, however, cannot be split apart into orthogonal pieces so easily. Before attempting to use reindex, view must ensure that there are no arrays of CartesianIndex in the argument list. If there are, it can simply \"punt\" by avoiding the reindex calculation entirely, constructing a nested SubArray with two levels of indirection instead.","category":"page"},{"location":"devdocs/object/#Memory-layout-of-Julia-Objects","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"","category":"section"},{"location":"devdocs/object/#Object-layout-(jl_value_t)","page":"Memory layout of Julia Objects","title":"Object layout (jl_value_t)","text":"","category":"section"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The jl_value_t struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it is simply an opaque pointer:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"typedef struct jl_value_t* jl_pvalue_t;","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Each jl_value_t struct is contained in a jl_typetag_t struct that contains metadata information about the Julia object, such as its type and garbage collector (gc) reachability:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"typedef struct {\n opaque metadata;\n jl_value_t value;\n} jl_typetag_t;","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The type of any Julia object is an instance of a leaf jl_datatype_t object. The jl_typeof() function can be used to query for it:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_typeof(jl_value_t *v);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The layout of the object depends on its type. Reflection methods can be used to inspect that layout. A field can be accessed by calling one of the get-field methods:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i);\njl_value_t *jl_get_field(jl_value_t *o, char *fld);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"If the field types are known, a priori, to be all pointers, the values can also be extracted directly as an array access:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *v = value->fieldptr[n];","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"As an example, a \"boxed\" uint16_t is stored as follows:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"struct {\n opaque metadata;\n struct {\n uint16_t data; // -- 2 bytes\n } jl_value_t;\n};","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"This object is created by jl_box_uint16(). Note that the jl_value_t pointer references the data portion, not the metadata at the top of the struct.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"A value may be stored \"unboxed\" in many circumstances (just the data, without the metadata, and possibly not even stored but just kept in registers), so it is unsafe to assume that the address of a box is a unique identifier. The \"egal\" test (corresponding to the === function in Julia), should instead be used to compare two unknown objects for equivalence:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"int jl_egal(jl_value_t *a, jl_value_t *b);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"This optimization should be relatively transparent to the API, since the object will be \"boxed\" on-demand, whenever a jl_value_t pointer is needed.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Note that modification of a jl_value_t pointer in memory is permitted only if the object is mutable. Otherwise, modification of the value may corrupt the program and the result will be undefined. The mutability property of a value can be queried for with:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"int jl_is_mutable(jl_value_t *v);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"If the object being stored is a jl_value_t, the Julia garbage collector must be notified also:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"void jl_gc_wb(jl_value_t *parent, jl_value_t *ptr);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"However, the Embedding Julia section of the manual is also required reading at this point, for covering other details of boxing and unboxing various types, and understanding the gc interactions.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Mirror structs for some of the built-in types are defined in julia.h. The corresponding global jl_datatype_t objects are created by jl_init_types in jltypes.c.","category":"page"},{"location":"devdocs/object/#Garbage-collector-mark-bits","page":"Memory layout of Julia Objects","title":"Garbage collector mark bits","text":"","category":"section"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The garbage collector uses several bits from the metadata portion of the jl_typetag_t to track each object in the system. Further details about this algorithm can be found in the comments of the garbage collector implementation in gc.c.","category":"page"},{"location":"devdocs/object/#Object-allocation","page":"Memory layout of Julia Objects","title":"Object allocation","text":"","category":"section"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Most new objects are allocated by jl_new_structv():","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_new_struct(jl_datatype_t *type, ...);\njl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uint32_t na);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Although, isbits objects can be also constructed directly from memory:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_new_bits(jl_value_t *bt, void *data)","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"And some objects have special constructors that must be used instead of the above functions:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Types:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_datatype_t *jl_apply_type(jl_datatype_t *tc, jl_tuple_t *params);\njl_datatype_t *jl_apply_array_type(jl_datatype_t *type, size_t dim);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"While these are the most commonly used options, there are more low-level constructors too, which you can find declared in julia.h. These are used in jl_init_types() to create the initial types needed to bootstrap the creation of the Julia system image.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Tuples:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_tuple_t *jl_tuple(size_t n, ...);\njl_tuple_t *jl_tuplev(size_t n, jl_value_t **v);\njl_tuple_t *jl_alloc_tuple(size_t n);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"The representation of tuples is highly unique in the Julia object representation ecosystem. In some cases, a Base.tuple() object may be an array of pointers to the objects contained by the tuple equivalent to:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"typedef struct {\n size_t length;\n jl_value_t *data[length];\n} jl_tuple_t;","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"However, in other cases, the tuple may be converted to an anonymous isbits type and stored unboxed, or it may not stored at all (if it is not being used in a generic context as a jl_value_t*).","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Symbols:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_sym_t *jl_symbol(const char *str);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Functions and MethodInstance:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_function_t *jl_new_generic_function(jl_sym_t *name);\njl_method_instance_t *jl_new_method_instance(jl_value_t *ast, jl_tuple_t *sparams);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Arrays:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_array_t *jl_new_array(jl_value_t *atype, jl_tuple_t *dims);\njl_array_t *jl_alloc_array_1d(jl_value_t *atype, size_t nr);\njl_array_t *jl_alloc_array_nd(jl_value_t *atype, size_t *dims, size_t ndims);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Note that many of these have alternative allocation functions for various special-purposes. The list here reflects the more common usages, but a more complete list can be found by reading the julia.h header file.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Internal to Julia, storage is typically allocated by newstruct() (or newobj() for the special types):","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *newstruct(jl_value_t *type);\njl_value_t *newobj(jl_value_t *type, size_t nfields);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"And at the lowest level, memory is getting allocated by a call to the garbage collector (in gc.c), then tagged with its type:","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"jl_value_t *jl_gc_allocobj(size_t nbytes);\nvoid jl_set_typeof(jl_value_t *v, jl_datatype_t *type);","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"note: Out of date Warning\nThe documentation and usage for the function jl_gc_allocobj may be out of date","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"Note that all objects are allocated in multiples of 4 bytes and aligned to the platform pointer size. Memory is allocated from a pool for smaller objects, or directly with malloc() for large objects.","category":"page"},{"location":"devdocs/object/","page":"Memory layout of Julia Objects","title":"Memory layout of Julia Objects","text":"sidebar: Singleton Types\nSingleton types have only one instance and no data fields. Singleton instances have a size of 0 bytes, and consist only of their metadata. e.g. nothing::Nothing.See Singleton Types and Nothingness and missing values","category":"page"},{"location":"devdocs/build/windows/#Windows","page":"Windows","title":"Windows","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"This file describes how to install, or build, and use Julia on Windows.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"For more general information about Julia, please see the main README or the documentation.","category":"page"},{"location":"devdocs/build/windows/#General-Information-for-Windows","page":"Windows","title":"General Information for Windows","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"We highly recommend running Julia using a modern terminal application, in particular Windows Terminal, which can be installed from the Microsoft Store.","category":"page"},{"location":"devdocs/build/windows/#Line-endings","page":"Windows","title":"Line endings","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Julia uses binary-mode files exclusively. Unlike many other Windows programs, if you write \\n to a file, you get a \\n in the file, not some other bit pattern. This matches the behavior exhibited by other operating systems. If you have installed Git for Windows, it is suggested, but not required, that you configure your system Git to use the same convention:","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"git config --global core.eol lf\ngit config --global core.autocrlf input","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"or edit %USERPROFILE%\\.gitconfig and add/edit the lines:","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"[core]\n eol = lf\n autocrlf = input","category":"page"},{"location":"devdocs/build/windows/#Binary-distribution","page":"Windows","title":"Binary distribution","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"For the binary distribution installation notes on Windows please see the instructions at https://julialang.org/downloads/platform/#windows.","category":"page"},{"location":"devdocs/build/windows/#Source-distribution","page":"Windows","title":"Source distribution","text":"","category":"section"},{"location":"devdocs/build/windows/#Cygwin-to-MinGW-cross-compiling","page":"Windows","title":"Cygwin-to-MinGW cross-compiling","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"The recommended way of compiling Julia from source on Windows is by cross compiling from Cygwin, using versions of the MinGW-w64 compilers available through Cygwin's package manager.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Download and run Cygwin setup for 32 bit or 64 bit. Note, that you can compile either 32 or 64 bit Julia from either 32 or 64 bit Cygwin. 64 bit Cygwin has a slightly smaller but often more up-to-date selection of packages.\nAdvanced: you may skip steps 2-4 by running:\nsetup-x86_64.exe -s -q -P cmake,gcc-g++,git,make,patch,curl,m4,python3,p7zip,mingw64-i686-gcc-g++,mingw64-i686-gcc-fortran,mingw64-x86_64-gcc-g++,mingw64-x86_64-gcc-fortran\nreplacing with a site from https://cygwin.com/mirrors.html or run setup manually first and select a mirror.\nSelect installation location and a mirror to download from.\nAt the Select Packages step, select the following:\nFrom the Devel category: cmake, gcc-g++, git, make, patch\nFrom the Net category: curl\nFrom Interpreters (or Python) category: m4, python3\nFrom the Archive category: p7zip\nFor 32 bit Julia, and also from the Devel category: mingw64-i686-gcc-g++ and mingw64-i686-gcc-fortran\nFor 64 bit Julia, and also from the Devel category: mingw64-x86_64-gcc-g++ and mingw64-x86_64-gcc-fortran\nAllow Cygwin installation to finish, then start from the installed shortcut 'Cygwin Terminal', or 'Cygwin64 Terminal', respectively.\nBuild Julia and its dependencies from source:\nGet the Julia sources\ngit clone https://github.com/JuliaLang/julia.git\ncd julia\nTip: If you get an error: cannot fork() for fetch-pack: Resource temporarily unavailable from git, add alias git=\"env PATH=/usr/bin git\" to ~/.bashrc and restart Cygwin.\nSet the XC_HOST variable in Make.user to indicate MinGW-w64 cross compilation\necho 'XC_HOST = i686-w64-mingw32' > Make.user # for 32 bit Julia\n# or\necho 'XC_HOST = x86_64-w64-mingw32' > Make.user # for 64 bit Julia\nStart the build\nmake -j 4 # Adjust the number of threads (4) to match your build environment.\nmake -j 4 debug # This builds julia-debug.exe\nRun Julia using the Julia executables directly\nusr/bin/julia.exe\nusr/bin/julia-debug.exe","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"note: Pro tip: build both!\nmake O=julia-win32 configure\nmake O=julia-win64 configure\necho 'XC_HOST = i686-w64-mingw32' > julia-win32/Make.user\necho 'XC_HOST = x86_64-w64-mingw32' > julia-win64/Make.user\necho 'ifeq ($(BUILDROOT),$(JULIAHOME))\n $(error \"in-tree build disabled\")\n endif' >> Make.user\nmake -C julia-win32 # build for Windows x86 in julia-win32 folder\nmake -C julia-win64 # build for Windows x86-64 in julia-win64 folder","category":"page"},{"location":"devdocs/build/windows/#Compiling-with-MinGW/MSYS2","page":"Windows","title":"Compiling with MinGW/MSYS2","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"MSYS2 is a software distribution and build environment for Windows.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Note: MSYS2 requires 64 bit Windows 7 or newer.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Install and configure MSYS2.\nDownload and run the latest installer for the 64-bit distribution. The installer will have a name like msys2-x86_64-yyyymmdd.exe.\nOpen the MSYS2 shell. Update the package database and base packages:\npacman -Syu\nExit and restart MSYS2. Update the rest of the base packages:\npacman -Syu\nThen install tools required to build julia:\npacman -S cmake diffutils git m4 make patch tar p7zip curl python\nFor 64 bit Julia, install the x86_64 version:\npacman -S mingw-w64-x86_64-gcc\nFor 32 bit Julia, install the i686 version:\npacman -S mingw-w64-i686-gcc\nConfiguration of MSYS2 is complete. Now exit the MSYS2 shell.\nBuild Julia and its dependencies with pre-build dependencies.\nOpen a new MINGW64/MINGW32 shell. Currently we can't use both mingw32 and mingw64, so if you want to build the x86_64 and i686 versions, you'll need to build them in each environment separately.\nClone the Julia sources:\ngit clone https://github.com/JuliaLang/julia.git cd julia\nStart the build\nmake -j$(nproc)","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"note: Pro tip: build in dir\nmake O=julia-mingw-w64 configure\necho 'ifeq ($(BUILDROOT),$(JULIAHOME))\n $(error \"in-tree build disabled\")\n endif' >> Make.user\nmake -C julia-mingw-w64","category":"page"},{"location":"devdocs/build/windows/#Cross-compiling-from-Unix-(Linux/Mac/WSL)","page":"Windows","title":"Cross-compiling from Unix (Linux/Mac/WSL)","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"You can also use MinGW-w64 cross compilers to build a Windows version of Julia from Linux, Mac, or the Windows Subsystem for Linux (WSL).","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"First, you will need to ensure your system has the required dependencies. We need wine (>=1.7.5), a system compiler, and some downloaders. Note: a Cygwin install might interfere with this method if using WSL.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"On Ubuntu (on other Linux systems the dependency names are likely to be similar):","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"apt-get install wine-stable gcc wget p7zip-full winbind mingw-w64 gfortran-mingw-w64\ndpkg --add-architecture i386 && apt-get update && apt-get install wine32 # add sudo to each if needed\n# switch all of the following to their \"-posix\" variants (interactively):\nfor pkg in i686-w64-mingw32-g++ i686-w64-mingw32-gcc i686-w64-mingw32-gfortran x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gfortran; do\n sudo update-alternatives --config $pkg\ndone","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"On Mac: Install XCode, XCode command line tools, X11 (now XQuartz), and MacPorts or Homebrew. Then run port install wine wget mingw-w64, or brew install wine wget mingw-w64, as appropriate.","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Then run the build:","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"git clone https://github.com/JuliaLang/julia.git julia-win32\ncd julia-win32\necho override XC_HOST = i686-w64-mingw32 >> Make.user\nmake\nmake win-extras (Necessary before running make binary-dist)\nmake binary-dist then make exe to create the Windows installer.\nmove the julia-*.exe installer to the target machine","category":"page"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"If you are building for 64-bit Windows, the steps are essentially the same. Just replace i686 in XC_HOST with x86_64. (Note: on Mac, wine only runs in 32-bit mode).","category":"page"},{"location":"devdocs/build/windows/#Debugging-a-cross-compiled-build-under-wine","page":"Windows","title":"Debugging a cross-compiled build under wine","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"The most effective way to debug a cross-compiled version of Julia on the cross-compilation host is to install a Windows version of GDB and run it under wine as usual. The pre-built packages available as part of the MSYS2 project are known to work. Apart from the GDB package you may also need the python and termcap packages. Finally, GDB's prompt may not work when launched from the command line. This can be worked around by prepending wineconsole to the regular GDB invocation.","category":"page"},{"location":"devdocs/build/windows/#After-compiling","page":"Windows","title":"After compiling","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Compiling using one of the options above creates a basic Julia build, but not some extra components that are included if you run the full Julia binary installer. If you need these components, the easiest way to get them is to build the installer yourself using make win-extras followed by make binary-dist and make exe. Then run the resulting installer.","category":"page"},{"location":"devdocs/build/windows/#Windows-Build-Debugging","page":"Windows","title":"Windows Build Debugging","text":"","category":"section"},{"location":"devdocs/build/windows/#GDB-hangs-with-Cygwin-mintty","page":"Windows","title":"GDB hangs with Cygwin mintty","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Run GDB under the Windows console (cmd) instead. GDB may not function properly under mintty with non- Cygwin applications. You can use cmd /c start to start the Windows console from mintty if necessary.","category":"page"},{"location":"devdocs/build/windows/#GDB-not-attaching-to-the-right-process","page":"Windows","title":"GDB not attaching to the right process","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Use the PID from the Windows task manager or WINPID from the ps command instead of the PID from unix-style command line tools (e.g. pgrep). You may need to add the PID column if it is not shown by default in the Windows task manager.","category":"page"},{"location":"devdocs/build/windows/#GDB-not-showing-the-right-backtrace","page":"Windows","title":"GDB not showing the right backtrace","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"When attaching to the julia process, GDB may not be attaching to the right thread. Use info threads command to show all the threads and thread to switch threads.\nBe sure to use a 32 bit version of GDB to debug a 32 bit build of Julia, or a 64 bit version of GDB to debug a 64 bit build of Julia.","category":"page"},{"location":"devdocs/build/windows/#Build-process-is-slow/eats-memory/hangs-my-computer","page":"Windows","title":"Build process is slow/eats memory/hangs my computer","text":"","category":"section"},{"location":"devdocs/build/windows/","page":"Windows","title":"Windows","text":"Disable the Windows Superfetch and Program Compatibility Assistant services, as they are known to have spurious interactions with MinGW/Cygwin.\nAs mentioned in the link above: excessive memory use by svchost specifically may be investigated in the Task Manager by clicking on the high-memory svchost.exe process and selecting Go to Services. Disable child services one-by-one until a culprit is found.\nBeware of BLODA. The vmmap tool is indispensable for identifying such software conflicts. Use vmmap to inspect the list of loaded DLLs for bash, mintty, or another persistent process used to drive the build. Essentially any DLL outside of the Windows System directory is potential BLODA.","category":"page"},{"location":"base/io-network/#I/O-and-Network","page":"I/O and Network","title":"I/O and Network","text":"","category":"section"},{"location":"base/io-network/#General-I/O","page":"I/O and Network","title":"General I/O","text":"","category":"section"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.stdout\nBase.stderr\nBase.stdin\nBase.read(::AbstractString)\nBase.write(::AbstractString, ::Any)\nBase.open\nBase.IOStream\nBase.IOBuffer\nBase.take!(::Base.GenericIOBuffer)\nBase.Pipe\nBase.link_pipe!\nBase.fdio\nBase.flush\nBase.close\nBase.closewrite\nBase.write\nBase.read\nBase.read!\nBase.readbytes!\nBase.unsafe_read\nBase.unsafe_write\nBase.readeach\nBase.peek\nBase.position\nBase.seek\nBase.seekstart\nBase.seekend\nBase.skip\nBase.mark\nBase.unmark\nBase.reset(::IO)\nBase.ismarked\nBase.eof\nBase.isreadonly\nBase.iswritable\nBase.isreadable\nBase.isexecutable\nBase.isopen\nBase.fd\nBase.redirect_stdio\nBase.redirect_stdout\nBase.redirect_stdout(::Function, ::Any)\nBase.redirect_stderr\nBase.redirect_stderr(::Function, ::Any)\nBase.redirect_stdin\nBase.redirect_stdin(::Function, ::Any)\nBase.readchomp\nBase.truncate\nBase.skipchars\nBase.countlines\nBase.PipeBuffer\nBase.readavailable\nBase.IOContext\nBase.IOContext(::IO, ::Pair)\nBase.IOContext(::IO, ::IOContext)","category":"page"},{"location":"base/io-network/#Base.stdout","page":"I/O and Network","title":"Base.stdout","text":"stdout::IO\n\nGlobal variable referring to the standard out stream.\n\n\n\n\n\n","category":"constant"},{"location":"base/io-network/#Base.stderr","page":"I/O and Network","title":"Base.stderr","text":"stderr::IO\n\nGlobal variable referring to the standard error stream.\n\n\n\n\n\n","category":"constant"},{"location":"base/io-network/#Base.stdin","page":"I/O and Network","title":"Base.stdin","text":"stdin::IO\n\nGlobal variable referring to the standard input stream.\n\n\n\n\n\n","category":"constant"},{"location":"base/io-network/#Base.read-Tuple{AbstractString}","page":"I/O and Network","title":"Base.read","text":"read(filename::AbstractString)\n\nRead the entire contents of a file as a Vector{UInt8}.\n\nread(filename::AbstractString, String)\n\nRead the entire contents of a file as a string.\n\nread(filename::AbstractString, args...)\n\nOpen a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.write-Tuple{AbstractString, Any}","page":"I/O and Network","title":"Base.write","text":"write(filename::AbstractString, content)\n\nWrite the canonical binary representation of content to a file, which will be created if it does not exist yet or overwritten if it does exist.\n\nReturn the number of bytes written into the file.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.open","page":"I/O and Network","title":"Base.open","text":"open(f::Function, args...; kwargs...)\n\nApply the function f to the result of open(args...; kwargs...) and close the resulting file descriptor upon completion.\n\nExamples\n\njulia> write(\"myfile.txt\", \"Hello world!\");\n\njulia> open(io->read(io, String), \"myfile.txt\")\n\"Hello world!\"\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\nopen(filename::AbstractString; lock = true, keywords...) -> IOStream\n\nOpen a file in a mode specified by five boolean keyword arguments:\n\nKeyword Description Default\nread open for reading !write\nwrite open for writing truncate | append\ncreate create if non-existent !read & write | truncate | append\ntruncate truncate to zero size !read & write\nappend seek to end false\n\nThe default when no keywords are passed is to open files for reading only. Returns a stream for accessing the opened file.\n\nThe lock keyword argument controls whether operations will be locked for safe multi-threaded access.\n\ncompat: Julia 1.5\nThe lock argument is available as of Julia 1.5.\n\n\n\n\n\nopen(filename::AbstractString, [mode::AbstractString]; lock = true) -> IOStream\n\nAlternate syntax for open, where a string-based mode specifier is used instead of the five booleans. The values of mode correspond to those from fopen(3) or Perl open, and are equivalent to setting the following boolean groups:\n\nMode Description Keywords\nr read none\nw write, create, truncate write = true\na write, create, append append = true\nr+ read, write read = true, write = true\nw+ read, write, create, truncate truncate = true, read = true\na+ read, write, create, append append = true, read = true\n\nThe lock keyword argument controls whether operations will be locked for safe multi-threaded access.\n\nExamples\n\njulia> io = open(\"myfile.txt\", \"w\");\n\njulia> write(io, \"Hello world!\");\n\njulia> close(io);\n\njulia> io = open(\"myfile.txt\", \"r\");\n\njulia> read(io, String)\n\"Hello world!\"\n\njulia> write(io, \"This file is read only\")\nERROR: ArgumentError: write failed, IOStream is not writeable\n[...]\n\njulia> close(io)\n\njulia> io = open(\"myfile.txt\", \"a\");\n\njulia> write(io, \"This stream is not read only\")\n28\n\njulia> close(io)\n\njulia> rm(\"myfile.txt\")\n\ncompat: Julia 1.5\nThe lock argument is available as of Julia 1.5.\n\n\n\n\n\nopen(fd::OS_HANDLE) -> IO\n\nTake a raw file descriptor wrap it in a Julia-aware IO type, and take ownership of the fd handle. Call open(Libc.dup(fd)) to avoid the ownership capture of the original handle.\n\nwarning: Warning\nDo not call this on a handle that's already owned by some other part of the system.\n\n\n\n\n\nopen(command, mode::AbstractString, stdio=devnull)\n\nRun command asynchronously. Like open(command, stdio; read, write) except specifying the read and write flags via a mode string instead of keyword arguments. Possible mode strings are:\n\nMode Description Keywords\nr read none\nw write write = true\nr+ read, write read = true, write = true\nw+ read, write read = true, write = true\n\n\n\n\n\nopen(command, stdio=devnull; write::Bool = false, read::Bool = !write)\n\nStart running command asynchronously, and return a process::IO object. If read is true, then reads from the process come from the process's standard output and stdio optionally specifies the process's standard input stream. If write is true, then writes go to the process's standard input and stdio optionally specifies the process's standard output stream. The process's standard error stream is connected to the current global stderr.\n\n\n\n\n\nopen(f::Function, command, args...; kwargs...)\n\nSimilar to open(command, args...; kwargs...), but calls f(stream) on the resulting process stream, then closes the input stream and waits for the process to complete. Return the value returned by f on success. Throw an error if the process failed, or if the process attempts to print anything to stdout.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.IOStream","page":"I/O and Network","title":"Base.IOStream","text":"IOStream\n\nA buffered IO stream wrapping an OS file descriptor. Mostly used to represent files returned by open.\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.IOBuffer","page":"I/O and Network","title":"Base.IOBuffer","text":"IOBuffer([data::AbstractVector{UInt8}]; keywords...) -> IOBuffer\n\nCreate an in-memory I/O stream, which may optionally operate on a pre-existing array.\n\nIt may take optional keyword arguments:\n\nread, write, append: restricts operations to the buffer; see open for details.\ntruncate: truncates the buffer size to zero length.\nmaxsize: specifies a size beyond which the buffer may not be grown.\nsizehint: suggests a capacity of the buffer (data must implement sizehint!(data, size)).\n\nWhen data is not given, the buffer will be both readable and writable by default.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\", \" It has many members.\")\n56\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization. It has many members.\"\n\njulia> io = IOBuffer(b\"JuliaLang is a GitHub organization.\")\nIOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=35, maxsize=Inf, ptr=1, mark=-1)\n\njulia> read(io, String)\n\"JuliaLang is a GitHub organization.\"\n\njulia> write(io, \"This isn't writable.\")\nERROR: ArgumentError: ensureroom failed, IOBuffer is not writeable\n\njulia> io = IOBuffer(UInt8[], read=true, write=true, maxsize=34)\nIOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=34, ptr=1, mark=-1)\n\njulia> write(io, \"JuliaLang is a GitHub organization.\")\n34\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization\"\n\njulia> length(read(IOBuffer(b\"data\", read=true, truncate=false)))\n4\n\njulia> length(read(IOBuffer(b\"data\", read=true, truncate=true)))\n0\n\n\n\n\n\nIOBuffer(string::String)\n\nCreate a read-only IOBuffer on the data underlying the given string.\n\nExamples\n\njulia> io = IOBuffer(\"Haho\");\n\njulia> String(take!(io))\n\"Haho\"\n\njulia> String(take!(io))\n\"Haho\"\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.take!-Tuple{Base.GenericIOBuffer}","page":"I/O and Network","title":"Base.take!","text":"take!(b::IOBuffer)\n\nObtain the contents of an IOBuffer as an array. Afterwards, the IOBuffer is reset to its initial state.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\", \" It has many members.\")\n56\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization. It has many members.\"\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.Pipe","page":"I/O and Network","title":"Base.Pipe","text":"Pipe()\n\nConstruct an uninitialized Pipe object, especially for IO communication between multiple processes.\n\nThe appropriate end of the pipe will be automatically initialized if the object is used in process spawning. This can be useful to easily obtain references in process pipelines, e.g.:\n\njulia> err = Pipe()\n\n# After this `err` will be initialized and you may read `foo`'s\n# stderr from the `err` pipe, or pass `err` to other pipelines.\njulia> run(pipeline(pipeline(`foo`, stderr=err), `cat`), wait=false)\n\n# Now destroy the write half of the pipe, so that the read half will get EOF\njulia> closewrite(err)\n\njulia> read(err, String)\n\"stderr messages\"\n\nSee also Base.link_pipe!.\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.link_pipe!","page":"I/O and Network","title":"Base.link_pipe!","text":"link_pipe!(pipe; reader_supports_async=false, writer_supports_async=false)\n\nInitialize pipe and link the in endpoint to the out endpoint. The keyword arguments reader_supports_async/writer_supports_async correspond to OVERLAPPED on Windows and O_NONBLOCK on POSIX systems. They should be true unless they'll be used by an external program (e.g. the output of a command executed with run).\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.fdio","page":"I/O and Network","title":"Base.fdio","text":"fdio([name::AbstractString, ]fd::Integer[, own::Bool=false]) -> IOStream\n\nCreate an IOStream object from an integer file descriptor. If own is true, closing this object will close the underlying descriptor. By default, an IOStream is closed when it is garbage collected. name allows you to associate the descriptor with a named file.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.flush","page":"I/O and Network","title":"Base.flush","text":"flush(stream)\n\nCommit all currently buffered writes to the given stream.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.close","page":"I/O and Network","title":"Base.close","text":"close(stream)\n\nClose an I/O stream. Performs a flush first.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.closewrite","page":"I/O and Network","title":"Base.closewrite","text":"closewrite(stream)\n\nShutdown the write half of a full-duplex I/O stream. Performs a flush first. Notify the other end that no more data will be written to the underlying file. This is not supported by all IO types.\n\nIf implemented, closewrite causes subsequent read or eof calls that would block to instead throw EOF or return true, respectively. If the stream is already closed, this is idempotent.\n\nExamples\n\njulia> io = Base.BufferStream(); # this never blocks, so we can read and write on the same Task\n\njulia> write(io, \"request\");\n\njulia> # calling `read(io)` here would block forever\n\njulia> closewrite(io);\n\njulia> read(io, String)\n\"request\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.write","page":"I/O and Network","title":"Base.write","text":"write(io::IO, x)\n\nWrite the canonical binary representation of a value to the given I/O stream or file. Return the number of bytes written into the stream. See also print to write a text representation (with an encoding that may depend upon io).\n\nThe endianness of the written value depends on the endianness of the host system. Convert to/from a fixed endianness when writing/reading (e.g. using htol and ltoh) to get results that are consistent across platforms.\n\nYou can write multiple values with the same write call. i.e. the following are equivalent:\n\nwrite(io, x, y...)\nwrite(io, x) + write(io, y...)\n\nExamples\n\nConsistent serialization:\n\njulia> fname = tempname(); # random temporary filename\n\njulia> open(fname,\"w\") do f\n # Make sure we write 64bit integer in little-endian byte order\n write(f,htol(Int64(42)))\n end\n8\n\njulia> open(fname,\"r\") do f\n # Convert back to host byte order and host integer type\n Int(ltoh(read(f,Int64)))\n end\n42\n\nMerging write calls:\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\", \" It has many members.\")\n56\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization. It has many members.\"\n\njulia> write(io, \"Sometimes those members\") + write(io, \" write documentation.\")\n44\n\njulia> String(take!(io))\n\"Sometimes those members write documentation.\"\n\nUser-defined plain-data types without write methods can be written when wrapped in a Ref:\n\njulia> struct MyStruct; x::Float64; end\n\njulia> io = IOBuffer()\nIOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)\n\njulia> write(io, Ref(MyStruct(42.0)))\n8\n\njulia> seekstart(io); read!(io, Ref(MyStruct(NaN)))\nBase.RefValue{MyStruct}(MyStruct(42.0))\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.read","page":"I/O and Network","title":"Base.read","text":"read(io::IO, T)\n\nRead a single value of type T from io, in canonical binary representation.\n\nNote that Julia does not convert the endianness for you. Use ntoh or ltoh for this purpose.\n\nread(io::IO, String)\n\nRead the entirety of io, as a String (see also readchomp).\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization\");\n\njulia> read(io, Char)\n'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization\");\n\njulia> read(io, String)\n\"JuliaLang is a GitHub organization\"\n\n\n\n\n\nread(filename::AbstractString)\n\nRead the entire contents of a file as a Vector{UInt8}.\n\nread(filename::AbstractString, String)\n\nRead the entire contents of a file as a string.\n\nread(filename::AbstractString, args...)\n\nOpen a file and read its contents. args is passed to read: this is equivalent to open(io->read(io, args...), filename).\n\n\n\n\n\nread(s::IO, nb=typemax(Int))\n\nRead at most nb bytes from s, returning a Vector{UInt8} of the bytes read.\n\n\n\n\n\nread(s::IOStream, nb::Integer; all=true)\n\nRead at most nb bytes from s, returning a Vector{UInt8} of the bytes read.\n\nIf all is true (the default), this function will block repeatedly trying to read all requested bytes, until an error or end-of-file occurs. If all is false, at most one read call is performed, and the amount of data returned is device-dependent. Note that not all stream types support the all option.\n\n\n\n\n\nread(command::Cmd)\n\nRun command and return the resulting output as an array of bytes.\n\n\n\n\n\nread(command::Cmd, String)\n\nRun command and return the resulting output as a String.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.read!","page":"I/O and Network","title":"Base.read!","text":"read!(stream::IO, array::AbstractArray)\nread!(filename::AbstractString, array::AbstractArray)\n\nRead binary data from an I/O stream or file, filling in array.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readbytes!","page":"I/O and Network","title":"Base.readbytes!","text":"readbytes!(stream::IO, b::AbstractVector{UInt8}, nb=length(b))\n\nRead at most nb bytes from stream into b, returning the number of bytes read. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.\n\n\n\n\n\nreadbytes!(stream::IOStream, b::AbstractVector{UInt8}, nb=length(b); all::Bool=true)\n\nRead at most nb bytes from stream into b, returning the number of bytes read. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.\n\nIf all is true (the default), this function will block repeatedly trying to read all requested bytes, until an error or end-of-file occurs. If all is false, at most one read call is performed, and the amount of data returned is device-dependent. Note that not all stream types support the all option.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.unsafe_read","page":"I/O and Network","title":"Base.unsafe_read","text":"unsafe_read(io::IO, ref, nbytes::UInt)\n\nCopy nbytes from the IO stream object into ref (converted to a pointer).\n\nIt is recommended that subtypes T<:IO override the following method signature to provide more efficient implementations: unsafe_read(s::T, p::Ptr{UInt8}, n::UInt)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.unsafe_write","page":"I/O and Network","title":"Base.unsafe_write","text":"unsafe_write(io::IO, ref, nbytes::UInt)\n\nCopy nbytes from ref (converted to a pointer) into the IO object.\n\nIt is recommended that subtypes T<:IO override the following method signature to provide more efficient implementations: unsafe_write(s::T, p::Ptr{UInt8}, n::UInt)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readeach","page":"I/O and Network","title":"Base.readeach","text":"readeach(io::IO, T)\n\nReturn an iterable object yielding read(io, T).\n\nSee also skipchars, eachline, readuntil.\n\ncompat: Julia 1.6\nreadeach requires Julia 1.6 or later.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\\n It has many members.\\n\");\n\njulia> for c in readeach(io, Char)\n c == '\\n' && break\n print(c)\n end\nJuliaLang is a GitHub organization.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.peek","page":"I/O and Network","title":"Base.peek","text":"peek(stream[, T=UInt8])\n\nRead and return a value of type T from a stream without advancing the current position in the stream. See also startswith(stream, char_or_string).\n\nExamples\n\njulia> b = IOBuffer(\"julia\");\n\njulia> peek(b)\n0x6a\n\njulia> position(b)\n0\n\njulia> peek(b, Char)\n'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase)\n\ncompat: Julia 1.5\nThe method which accepts a type requires Julia 1.5 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.position","page":"I/O and Network","title":"Base.position","text":"position(l::Lexer)\n\nReturns the current position.\n\n\n\n\n\nposition(s)\n\nGet the current position of a stream.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> seek(io, 5);\n\njulia> position(io)\n5\n\njulia> skip(io, 10);\n\njulia> position(io)\n15\n\njulia> seekend(io);\n\njulia> position(io)\n35\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.seek","page":"I/O and Network","title":"Base.seek","text":"seek(s, pos)\n\nSeek a stream to the given position.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> seek(io, 5);\n\njulia> read(io, Char)\n'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.seekstart","page":"I/O and Network","title":"Base.seekstart","text":"seekstart(s)\n\nSeek a stream to its beginning.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> seek(io, 5);\n\njulia> read(io, Char)\n'L': ASCII/Unicode U+004C (category Lu: Letter, uppercase)\n\njulia> seekstart(io);\n\njulia> read(io, Char)\n'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.seekend","page":"I/O and Network","title":"Base.seekend","text":"seekend(s)\n\nSeek a stream to its end.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.skip","page":"I/O and Network","title":"Base.skip","text":"skip(s, offset)\n\nSeek a stream relative to the current position.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> seek(io, 5);\n\njulia> skip(io, 10);\n\njulia> read(io, Char)\n'G': ASCII/Unicode U+0047 (category Lu: Letter, uppercase)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.mark","page":"I/O and Network","title":"Base.mark","text":"mark(s::IO)\n\nAdd a mark at the current position of stream s. Return the marked position.\n\nSee also unmark, reset, ismarked.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.unmark","page":"I/O and Network","title":"Base.unmark","text":"unmark(s::IO)\n\nRemove a mark from stream s. Return true if the stream was marked, false otherwise.\n\nSee also mark, reset, ismarked.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.reset-Tuple{IO}","page":"I/O and Network","title":"Base.reset","text":"reset(s::IO)\n\nReset a stream s to a previously marked position, and remove the mark. Return the previously marked position. Throw an error if the stream is not marked.\n\nSee also mark, unmark, ismarked.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.ismarked","page":"I/O and Network","title":"Base.ismarked","text":"ismarked(s::IO)\n\nReturn true if stream s is marked.\n\nSee also mark, unmark, reset.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.eof","page":"I/O and Network","title":"Base.eof","text":"eof(stream) -> Bool\n\nTest whether an I/O stream is at end-of-file. If the stream is not yet exhausted, this function will block to wait for more data if necessary, and then return false. Therefore it is always safe to read one byte after seeing eof return false. eof will return false as long as buffered data is still available, even if the remote end of a connection is closed.\n\nExamples\n\njulia> b = IOBuffer(\"my buffer\");\n\njulia> eof(b)\nfalse\n\njulia> seekend(b);\n\njulia> eof(b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.isreadonly","page":"I/O and Network","title":"Base.isreadonly","text":"isreadonly(io) -> Bool\n\nDetermine whether a stream is read-only.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization\");\n\njulia> isreadonly(io)\ntrue\n\njulia> io = IOBuffer();\n\njulia> isreadonly(io)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.iswritable","page":"I/O and Network","title":"Base.iswritable","text":"iswritable(path::String)\n\nReturn true if the access permissions for the given path permitted writing by the current user.\n\nnote: Note\nThis permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling iswritable first.\n\nnote: Note\nCurrently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also ispath, isexecutable, isreadable.\n\n\n\n\n\niswritable(io) -> Bool\n\nReturn false if the specified IO object is not writable.\n\nExamples\n\njulia> open(\"myfile.txt\", \"w\") do io\n print(io, \"Hello world!\");\n iswritable(io)\n end\ntrue\n\njulia> open(\"myfile.txt\", \"r\") do io\n iswritable(io)\n end\nfalse\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.isreadable","page":"I/O and Network","title":"Base.isreadable","text":"isreadable(path::String)\n\nReturn true if the access permissions for the given path permitted reading by the current user.\n\nnote: Note\nThis permission may change before the user calls open, so it is recommended to just call open alone and handle the error if that fails, rather than calling isreadable first.\n\nnote: Note\nCurrently this function does not correctly interrogate filesystem ACLs on Windows, therefore it can return wrong results.\n\ncompat: Julia 1.11\nThis function requires at least Julia 1.11.\n\nSee also ispath, isexecutable, iswritable.\n\n\n\n\n\nisreadable(io) -> Bool\n\nReturn false if the specified IO object is not readable.\n\nExamples\n\njulia> open(\"myfile.txt\", \"w\") do io\n print(io, \"Hello world!\");\n isreadable(io)\n end\nfalse\n\njulia> open(\"myfile.txt\", \"r\") do io\n isreadable(io)\n end\ntrue\n\njulia> rm(\"myfile.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.isexecutable","page":"I/O and Network","title":"Base.isexecutable","text":"isexecutable(path::String)\n\nReturn true if the given path has executable permissions.\n\nnote: Note\nThis permission may change before the user executes path, so it is recommended to execute the file and handle the error if that fails, rather than calling isexecutable first.\n\nnote: Note\nPrior to Julia 1.6, this did not correctly interrogate filesystem ACLs on Windows, therefore it would return true for any file. From Julia 1.6 on, it correctly determines whether the file is marked as executable or not.\n\nSee also ispath, isreadable, iswritable.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.isopen","page":"I/O and Network","title":"Base.isopen","text":"isopen(object) -> Bool\n\nDetermine whether an object - such as a stream or timer – is not yet closed. Once an object is closed, it will never produce a new event. However, since a closed stream may still have data to read in its buffer, use eof to check for the ability to read data. Use the FileWatching package to be notified when a stream might be writable or readable.\n\nExamples\n\njulia> io = open(\"my_file.txt\", \"w+\");\n\njulia> isopen(io)\ntrue\n\njulia> close(io)\n\njulia> isopen(io)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.fd","page":"I/O and Network","title":"Base.fd","text":"fd(stream)\n\nReturn the file descriptor backing the stream or file. Note that this function only applies to synchronous File's and IOStream's not to any of the asynchronous streams.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stdio","page":"I/O and Network","title":"Base.redirect_stdio","text":"redirect_stdio(;stdin=stdin, stderr=stderr, stdout=stdout)\n\nRedirect a subset of the streams stdin, stderr, stdout. Each argument must be an IOStream, TTY, Pipe, socket, or devnull.\n\ncompat: Julia 1.7\nredirect_stdio requires Julia 1.7 or later.\n\n\n\n\n\nredirect_stdio(f; stdin=nothing, stderr=nothing, stdout=nothing)\n\nRedirect a subset of the streams stdin, stderr, stdout, call f() and restore each stream.\n\nPossible values for each stream are:\n\nnothing indicating the stream should not be redirected.\npath::AbstractString redirecting the stream to the file at path.\nio an IOStream, TTY, Pipe, socket, or devnull.\n\nExamples\n\njulia> redirect_stdio(stdout=\"stdout.txt\", stderr=\"stderr.txt\") do\n print(\"hello stdout\")\n print(stderr, \"hello stderr\")\n end\n\njulia> read(\"stdout.txt\", String)\n\"hello stdout\"\n\njulia> read(\"stderr.txt\", String)\n\"hello stderr\"\n\nEdge cases\n\nIt is possible to pass the same argument to stdout and stderr:\n\njulia> redirect_stdio(stdout=\"log.txt\", stderr=\"log.txt\", stdin=devnull) do\n ...\nend\n\nHowever it is not supported to pass two distinct descriptors of the same file.\n\njulia> io1 = open(\"same/path\", \"w\")\n\njulia> io2 = open(\"same/path\", \"w\")\n\njulia> redirect_stdio(f, stdout=io1, stderr=io2) # not supported\n\nAlso the stdin argument may not be the same descriptor as stdout or stderr.\n\njulia> io = open(...)\n\njulia> redirect_stdio(f, stdout=io, stdin=io) # not supported\n\ncompat: Julia 1.7\nredirect_stdio requires Julia 1.7 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stdout","page":"I/O and Network","title":"Base.redirect_stdout","text":"redirect_stdout([stream]) -> stream\n\nCreate a pipe to which all C and Julia level stdout output will be redirected. Return a stream representing the pipe ends. Data written to stdout may now be read from the rd end of the pipe.\n\nnote: Note\nstream must be a compatible objects, such as an IOStream, TTY, Pipe, socket, or devnull.\n\nSee also redirect_stdio.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stdout-Tuple{Function, Any}","page":"I/O and Network","title":"Base.redirect_stdout","text":"redirect_stdout(f::Function, stream)\n\nRun the function f while redirecting stdout to stream. Upon completion, stdout is restored to its prior setting.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.redirect_stderr","page":"I/O and Network","title":"Base.redirect_stderr","text":"redirect_stderr([stream]) -> stream\n\nLike redirect_stdout, but for stderr.\n\nnote: Note\nstream must be a compatible objects, such as an IOStream, TTY, Pipe, socket, or devnull.\n\nSee also redirect_stdio.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stderr-Tuple{Function, Any}","page":"I/O and Network","title":"Base.redirect_stderr","text":"redirect_stderr(f::Function, stream)\n\nRun the function f while redirecting stderr to stream. Upon completion, stderr is restored to its prior setting.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.redirect_stdin","page":"I/O and Network","title":"Base.redirect_stdin","text":"redirect_stdin([stream]) -> stream\n\nLike redirect_stdout, but for stdin. Note that the direction of the stream is reversed.\n\nnote: Note\nstream must be a compatible objects, such as an IOStream, TTY, Pipe, socket, or devnull.\n\nSee also redirect_stdio.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.redirect_stdin-Tuple{Function, Any}","page":"I/O and Network","title":"Base.redirect_stdin","text":"redirect_stdin(f::Function, stream)\n\nRun the function f while redirecting stdin to stream. Upon completion, stdin is restored to its prior setting.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.readchomp","page":"I/O and Network","title":"Base.readchomp","text":"readchomp(x)\n\nRead the entirety of x as a string and remove a single trailing newline if there is one. Equivalent to chomp(read(x, String)).\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> readchomp(\"my_file.txt\")\n\"JuliaLang is a GitHub organization.\\nIt has many members.\"\n\njulia> rm(\"my_file.txt\");\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.truncate","page":"I/O and Network","title":"Base.truncate","text":"truncate(file, n)\n\nResize the file or buffer given by the first argument to exactly n bytes, filling previously unallocated space with '\\0' if the file or buffer is grown.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\")\n35\n\njulia> truncate(io, 15)\nIOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=15, maxsize=Inf, ptr=16, mark=-1)\n\njulia> String(take!(io))\n\"JuliaLang is a \"\n\njulia> io = IOBuffer();\n\njulia> write(io, \"JuliaLang is a GitHub organization.\");\n\njulia> truncate(io, 40);\n\njulia> String(take!(io))\n\"JuliaLang is a GitHub organization.\\0\\0\\0\\0\\0\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.skipchars","page":"I/O and Network","title":"Base.skipchars","text":"skipchars(predicate, io::IO; linecomment=nothing)\n\nAdvance the stream io such that the next-read character will be the first remaining for which predicate returns false. If the keyword argument linecomment is specified, all characters from that character until the start of the next line are ignored.\n\nExamples\n\njulia> buf = IOBuffer(\" text\")\nIOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=1, mark=-1)\n\njulia> skipchars(isspace, buf)\nIOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=5, mark=-1)\n\njulia> String(readavailable(buf))\n\"text\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.countlines","page":"I/O and Network","title":"Base.countlines","text":"countlines(io::IO; eol::AbstractChar = '\\n')\ncountlines(filename::AbstractString; eol::AbstractChar = '\\n')\n\nRead io until the end of the stream/file and count the number of lines. To specify a file pass the filename as the first argument. EOL markers other than '\\n' are supported by passing them as the second argument. The last non-empty line of io is counted even if it does not end with the EOL, matching the length returned by eachline and readlines.\n\nTo count lines of a String, countlines(IOBuffer(str)) can be used.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\\n\");\n\njulia> countlines(io)\n1\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> countlines(io)\n1\n\njulia> eof(io) # counting lines moves the file pointer\ntrue\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization.\");\n\njulia> countlines(io, eol = '.')\n1\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\n\")\n36\n\njulia> countlines(\"my_file.txt\")\n1\n\njulia> countlines(\"my_file.txt\", eol = 'n')\n4\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.PipeBuffer","page":"I/O and Network","title":"Base.PipeBuffer","text":"PipeBuffer(data::AbstractVector{UInt8}=UInt8[]; maxsize::Integer = typemax(Int))\n\nAn IOBuffer that allows reading and performs writes by appending. Seeking and truncating are not supported. See IOBuffer for the available constructors. If data is given, creates a PipeBuffer to operate on a data vector, optionally specifying a size beyond which the underlying Array may not be grown.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readavailable","page":"I/O and Network","title":"Base.readavailable","text":"readavailable(stream)\n\nRead available buffered data from a stream. Actual I/O is performed only if no data has already been buffered. The result is a Vector{UInt8}.\n\nwarning: Warning\nThe amount of data returned is implementation-dependent; for example it can depend on the internal choice of buffer size. Other functions such as read should generally be used instead.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.IOContext","page":"I/O and Network","title":"Base.IOContext","text":"IOContext\n\nIOContext provides a mechanism for passing output configuration settings among show methods.\n\nIn short, it is an immutable dictionary that is a subclass of IO. It supports standard dictionary operations such as getindex, and can also be used as an I/O stream.\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.IOContext-Tuple{IO, Pair}","page":"I/O and Network","title":"Base.IOContext","text":"IOContext(io::IO, KV::Pair...)\n\nCreate an IOContext that wraps a given stream, adding the specified key=>value pairs to the properties of that stream (note that io can itself be an IOContext).\n\nuse (key => value) in io to see if this particular combination is in the properties set\nuse get(io, key, default) to retrieve the most recent value for a particular key\n\nThe following properties are in common use:\n\n:compact: Boolean specifying that values should be printed more compactly, e.g. that numbers should be printed with fewer digits. This is set when printing array elements. :compact output should not contain line breaks.\n:limit: Boolean specifying that containers should be truncated, e.g. showing … in place of most elements.\n:displaysize: A Tuple{Int,Int} giving the size in rows and columns to use for text output. This can be used to override the display size for called functions, but to get the size of the screen use the displaysize function.\n:typeinfo: a Type characterizing the information already printed concerning the type of the object about to be displayed. This is mainly useful when displaying a collection of objects of the same type, so that redundant type information can be avoided (e.g. [Float16(0)] can be shown as \"Float16[0.0]\" instead of \"Float16[Float16(0.0)]\" : while displaying the elements of the array, the :typeinfo property will be set to Float16).\n:color: Boolean specifying whether ANSI color/escape codes are supported/expected. By default, this is determined by whether io is a compatible terminal and by any --color command-line flag when julia was launched.\n\nExamples\n\njulia> io = IOBuffer();\n\njulia> printstyled(IOContext(io, :color => true), \"string\", color=:red)\n\njulia> String(take!(io))\n\"\\e[31mstring\\e[39m\"\n\njulia> printstyled(io, \"string\", color=:red)\n\njulia> String(take!(io))\n\"string\"\n\njulia> print(IOContext(stdout, :compact => false), 1.12341234)\n1.12341234\njulia> print(IOContext(stdout, :compact => true), 1.12341234)\n1.12341\n\njulia> function f(io::IO)\n if get(io, :short, false)\n print(io, \"short\")\n else\n print(io, \"loooooong\")\n end\n end\nf (generic function with 1 method)\n\njulia> f(stdout)\nloooooong\njulia> f(IOContext(stdout, :short => true))\nshort\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.IOContext-Tuple{IO, IOContext}","page":"I/O and Network","title":"Base.IOContext","text":"IOContext(io::IO, context::IOContext)\n\nCreate an IOContext that wraps an alternate IO but inherits the properties of context.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Text-I/O","page":"I/O and Network","title":"Text I/O","text":"","category":"section"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.show(::IO, ::Any)\nBase.summary\nBase.print\nBase.println\nBase.printstyled\nBase.sprint\nBase.showerror\nBase.dump\nMeta.@dump\nBase.readline\nBase.readuntil\nBase.readlines\nBase.eachline\nBase.copyline\nBase.copyuntil\nBase.displaysize","category":"page"},{"location":"base/io-network/#Base.show-Tuple{IO, Any}","page":"I/O and Network","title":"Base.show","text":"show([io::IO = stdout], x)\n\nWrite a text representation of a value x to the output stream io. New types T should overload show(io::IO, x::T). The representation used by show generally includes Julia-specific formatting and type information, and should be parseable Julia code when possible.\n\nrepr returns the output of show as a string.\n\nFor a more verbose human-readable text output for objects of type T, define show(io::IO, ::MIME\"text/plain\", ::T) in addition. Checking the :compact IOContext key (often checked as get(io, :compact, false)::Bool) of io in such methods is recommended, since some containers show their elements by calling this method with :compact => true.\n\nSee also print, which writes un-decorated representations.\n\nExamples\n\njulia> show(\"Hello World!\")\n\"Hello World!\"\njulia> print(\"Hello World!\")\nHello World!\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.summary","page":"I/O and Network","title":"Base.summary","text":"summary(io::IO, x)\nstr = summary(x)\n\nPrint to a stream io, or return a string str, giving a brief description of a value. By default returns string(typeof(x)), e.g. Int64.\n\nFor arrays, returns a string of size and type info, e.g. 10-element Array{Int64,1}.\n\nExamples\n\njulia> summary(1)\n\"Int64\"\n\njulia> summary(zeros(2))\n\"2-element Vector{Float64}\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.print","page":"I/O and Network","title":"Base.print","text":"print([io::IO], xs...)\n\nWrite to io (or to the default output stream stdout if io is not given) a canonical (un-decorated) text representation. The representation used by print includes minimal formatting and tries to avoid Julia-specific details.\n\nprint falls back to calling show, so most types should just define show. Define print if your type has a separate \"plain\" representation. For example, show displays strings with quotes, and print displays strings without quotes.\n\nSee also println, string, printstyled.\n\nExamples\n\njulia> print(\"Hello World!\")\nHello World!\njulia> io = IOBuffer();\n\njulia> print(io, \"Hello\", ' ', :World!)\n\njulia> String(take!(io))\n\"Hello World!\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.println","page":"I/O and Network","title":"Base.println","text":"println([io::IO], xs...)\n\nPrint (using print) xs to io followed by a newline. If io is not supplied, prints to the default output stream stdout.\n\nSee also printstyled to add colors etc.\n\nExamples\n\njulia> println(\"Hello, world\")\nHello, world\n\njulia> io = IOBuffer();\n\njulia> println(io, \"Hello\", ',', \" world.\")\n\njulia> String(take!(io))\n\"Hello, world.\\n\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.printstyled","page":"I/O and Network","title":"Base.printstyled","text":"printstyled([io], xs...; bold::Bool=false, italic::Bool=false, underline::Bool=false, blink::Bool=false, reverse::Bool=false, hidden::Bool=false, color::Union{Symbol,Int}=:normal)\n\nPrint xs in a color specified as a symbol or integer, optionally in bold.\n\nKeyword color may take any of the values :normal, :italic, :default, :bold, :black, :blink, :blue, :cyan, :green, :hidden, :light_black, :light_blue, :light_cyan, :light_green, :light_magenta, :light_red, :light_white, :light_yellow, :magenta, :nothing, :red, :reverse, :underline, :white, or :yellow or an integer between 0 and 255 inclusive. Note that not all terminals support 256 colors.\n\nKeywords bold=true, italic=true, underline=true, blink=true are self-explanatory. Keyword reverse=true prints with foreground and background colors exchanged, and hidden=true should be invisible in the terminal but can still be copied. These properties can be used in any combination.\n\nSee also print, println, show.\n\nnote: Note\nNot all terminals support italic output. Some terminals interpret italic as reverse or blink.\n\ncompat: Julia 1.7\nKeywords except color and bold were added in Julia 1.7.\n\ncompat: Julia 1.10\nSupport for italic output was added in Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.sprint","page":"I/O and Network","title":"Base.sprint","text":"sprint(f::Function, args...; context=nothing, sizehint=0)\n\nCall the given function with an I/O stream and the supplied extra arguments. Everything written to this I/O stream is returned as a string. context can be an IOContext whose properties will be used, a Pair specifying a property and its value, or a tuple of Pair specifying multiple properties and their values. sizehint suggests the capacity of the buffer (in bytes).\n\nThe optional keyword argument context can be set to a :key=>value pair, a tuple of :key=>value pairs, or an IO or IOContext object whose attributes are used for the I/O stream passed to f. The optional sizehint is a suggested size (in bytes) to allocate for the buffer used to write the string.\n\ncompat: Julia 1.7\nPassing a tuple to keyword context requires Julia 1.7 or later.\n\nExamples\n\njulia> sprint(show, 66.66666; context=:compact => true)\n\"66.6667\"\n\njulia> sprint(showerror, BoundsError([1], 100))\n\"BoundsError: attempt to access 1-element Vector{Int64} at index [100]\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.showerror","page":"I/O and Network","title":"Base.showerror","text":"showerror(io, e)\n\nShow a descriptive representation of an exception object e. This method is used to display the exception after a call to throw.\n\nExamples\n\njulia> struct MyException <: Exception\n msg::String\n end\n\njulia> function Base.showerror(io::IO, err::MyException)\n print(io, \"MyException: \")\n print(io, err.msg)\n end\n\njulia> err = MyException(\"test exception\")\nMyException(\"test exception\")\n\njulia> sprint(showerror, err)\n\"MyException: test exception\"\n\njulia> throw(MyException(\"test exception\"))\nERROR: MyException: test exception\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.dump","page":"I/O and Network","title":"Base.dump","text":"dump(x; maxdepth=8)\n\nShow every part of the representation of a value. The depth of the output is truncated at maxdepth.\n\nExamples\n\njulia> struct MyStruct\n x\n y\n end\n\njulia> x = MyStruct(1, (2,3));\n\njulia> dump(x)\nMyStruct\n x: Int64 1\n y: Tuple{Int64, Int64}\n 1: Int64 2\n 2: Int64 3\n\njulia> dump(x; maxdepth = 1)\nMyStruct\n x: Int64 1\n y: Tuple{Int64, Int64}\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Meta.@dump","page":"I/O and Network","title":"Base.Meta.@dump","text":"@dump expr\n\nShow every part of the representation of the given expression. Equivalent to dump(:(expr)).\n\n\n\n\n\n","category":"macro"},{"location":"base/io-network/#Base.readline","page":"I/O and Network","title":"Base.readline","text":"readline(io::IO=stdin; keep::Bool=false)\nreadline(filename::AbstractString; keep::Bool=false)\n\nRead a single line of text from the given I/O stream or file (defaults to stdin). When reading from a file, the text is assumed to be encoded in UTF-8. Lines in the input end with '\\n' or \"\\r\\n\" or the end of an input stream. When keep is false (as it is by default), these trailing newline characters are removed from the line before it is returned. When keep is true, they are returned as part of the line.\n\nReturn a String. See also copyline to instead write in-place to another stream (which can be a preallocated IOBuffer).\n\nSee also readuntil for reading until more general delimiters.\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> readline(\"my_file.txt\")\n\"JuliaLang is a GitHub organization.\"\n\njulia> readline(\"my_file.txt\", keep=true)\n\"JuliaLang is a GitHub organization.\\n\"\n\njulia> rm(\"my_file.txt\")\n\njulia> print(\"Enter your name: \")\nEnter your name:\n\njulia> your_name = readline()\nLogan\n\"Logan\"\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readuntil","page":"I/O and Network","title":"Base.readuntil","text":"readuntil(stream::IO, delim; keep::Bool = false)\nreaduntil(filename::AbstractString, delim; keep::Bool = false)\n\nRead a string from an I/O stream or a file, up to the given delimiter. The delimiter can be a UInt8, AbstractChar, string, or vector. Keyword argument keep controls whether the delimiter is included in the result. The text is assumed to be encoded in UTF-8.\n\nReturn a String if delim is an AbstractChar or a string or otherwise return a Vector{typeof(delim)}. See also copyuntil to instead write in-place to another stream (which can be a preallocated IOBuffer).\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> readuntil(\"my_file.txt\", 'L')\n\"Julia\"\n\njulia> readuntil(\"my_file.txt\", '.', keep = true)\n\"JuliaLang is a GitHub organization.\"\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.readlines","page":"I/O and Network","title":"Base.readlines","text":"readlines(io::IO=stdin; keep::Bool=false)\nreadlines(filename::AbstractString; keep::Bool=false)\n\nRead all lines of an I/O stream or a file as a vector of strings. Behavior is equivalent to saving the result of reading readline repeatedly with the same arguments and saving the resulting lines as a vector of strings. See also eachline to iterate over the lines without reading them all at once.\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> readlines(\"my_file.txt\")\n2-element Vector{String}:\n \"JuliaLang is a GitHub organization.\"\n \"It has many members.\"\n\njulia> readlines(\"my_file.txt\", keep=true)\n2-element Vector{String}:\n \"JuliaLang is a GitHub organization.\\n\"\n \"It has many members.\\n\"\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.eachline","page":"I/O and Network","title":"Base.eachline","text":"eachline(io::IO=stdin; keep::Bool=false)\neachline(filename::AbstractString; keep::Bool=false)\n\nCreate an iterable EachLine object that will yield each line from an I/O stream or a file. Iteration calls readline on the stream argument repeatedly with keep passed through, determining whether trailing end-of-line characters are retained. When called with a file name, the file is opened once at the beginning of iteration and closed at the end. If iteration is interrupted, the file will be closed when the EachLine object is garbage collected.\n\nTo iterate over each line of a String, eachline(IOBuffer(str)) can be used.\n\nIterators.reverse can be used on an EachLine object to read the lines in reverse order (for files, buffers, and other I/O streams supporting seek), and first or last can be used to extract the initial or final lines, respectively.\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\n It has many members.\\n\");\n\njulia> for line in eachline(\"my_file.txt\")\n print(line)\n end\nJuliaLang is a GitHub organization. It has many members.\n\njulia> rm(\"my_file.txt\");\n\ncompat: Julia 1.8\nJulia 1.8 is required to use Iterators.reverse or last with eachline iterators.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.copyline","page":"I/O and Network","title":"Base.copyline","text":"copyline(out::IO, io::IO=stdin; keep::Bool=false)\ncopyline(out::IO, filename::AbstractString; keep::Bool=false)\n\nCopy a single line of text from an I/O stream or a file to the out stream, returning out.\n\nWhen reading from a file, the text is assumed to be encoded in UTF-8. Lines in the input end with '\\n' or \"\\r\\n\" or the end of an input stream. When keep is false (as it is by default), these trailing newline characters are removed from the line before it is returned. When keep is true, they are returned as part of the line.\n\nSimilar to readline, which returns a String; in contrast, copyline writes directly to out, without allocating a string. (This can be used, for example, to read data into a pre-allocated IOBuffer.)\n\nSee also copyuntil for reading until more general delimiters.\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> String(take!(copyline(IOBuffer(), \"my_file.txt\")))\n\"JuliaLang is a GitHub organization.\"\n\njulia> String(take!(copyline(IOBuffer(), \"my_file.txt\", keep=true)))\n\"JuliaLang is a GitHub organization.\\n\"\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.copyuntil","page":"I/O and Network","title":"Base.copyuntil","text":"copyuntil(out::IO, stream::IO, delim; keep::Bool = false)\ncopyuntil(out::IO, filename::AbstractString, delim; keep::Bool = false)\n\nCopy a string from an I/O stream or a file, up to the given delimiter, to the out stream, returning out. The delimiter can be a UInt8, AbstractChar, string, or vector. Keyword argument keep controls whether the delimiter is included in the result. The text is assumed to be encoded in UTF-8.\n\nSimilar to readuntil, which returns a String; in contrast, copyuntil writes directly to out, without allocating a string. (This can be used, for example, to read data into a pre-allocated IOBuffer.)\n\nExamples\n\njulia> write(\"my_file.txt\", \"JuliaLang is a GitHub organization.\\nIt has many members.\\n\");\n\njulia> String(take!(copyuntil(IOBuffer(), \"my_file.txt\", 'L')))\n\"Julia\"\n\njulia> String(take!(copyuntil(IOBuffer(), \"my_file.txt\", '.', keep = true)))\n\"JuliaLang is a GitHub organization.\"\n\njulia> rm(\"my_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.displaysize","page":"I/O and Network","title":"Base.displaysize","text":"displaysize([io::IO]) -> (lines, columns)\n\nReturn the nominal size of the screen that may be used for rendering output to this IO object. If no input is provided, the environment variables LINES and COLUMNS are read. If those are not set, a default size of (24, 80) is returned.\n\nExamples\n\njulia> withenv(\"LINES\" => 30, \"COLUMNS\" => 100) do\n displaysize()\n end\n(30, 100)\n\nTo get your TTY size,\n\njulia> displaysize(stdout)\n(34, 147)\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Multimedia-I/O","page":"I/O and Network","title":"Multimedia I/O","text":"","category":"section"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Just as text output is performed by print and user-defined types can indicate their textual representation by overloading show, Julia provides a standardized mechanism for rich multimedia output (such as images, formatted text, or even audio and video), consisting of three parts:","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"A function display(x) to request the richest available multimedia display of a Julia object x (with a plain-text fallback).\nOverloading show allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types.\nMultimedia-capable display backends may be registered by subclassing a generic AbstractDisplay type and pushing them onto a stack of display backends via pushdisplay.","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"The base Julia runtime provides only plain-text display, but richer displays may be enabled by loading external modules or by using graphical Julia environments (such as the IPython-based IJulia notebook).","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.AbstractDisplay\nBase.Multimedia.display\nBase.Multimedia.redisplay\nBase.Multimedia.displayable\nBase.show(::IO, ::Any, ::Any)\nBase.Multimedia.showable\nBase.repr(::MIME, ::Any)\nBase.MIME\nBase.@MIME_str","category":"page"},{"location":"base/io-network/#Base.Multimedia.AbstractDisplay","page":"I/O and Network","title":"Base.Multimedia.AbstractDisplay","text":"AbstractDisplay\n\nAbstract supertype for rich display output devices. TextDisplay is a subtype of this.\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.Multimedia.display","page":"I/O and Network","title":"Base.Multimedia.display","text":"display(x)\ndisplay(d::AbstractDisplay, x)\ndisplay(mime, x)\ndisplay(d::AbstractDisplay, mime, x)\n\nDisplay x using the topmost applicable display in the display stack, typically using the richest supported multimedia output for x, with plain-text stdout output as a fallback. The display(d, x) variant attempts to display x on the given display d only, throwing a MethodError if d cannot display objects of this type.\n\nIn general, you cannot assume that display output goes to stdout (unlike print(x) or show(x)). For example, display(x) may open up a separate window with an image. display(x) means \"show x in the best way you can for the current output device(s).\" If you want REPL-like text output that is guaranteed to go to stdout, use show(stdout, \"text/plain\", x) instead.\n\nThere are also two variants with a mime argument (a MIME type string, such as \"image/png\"), which attempt to display x using the requested MIME type only, throwing a MethodError if this type is not supported by either the display(s) or by x. With these variants, one can also supply the \"raw\" data in the requested MIME type by passing x::AbstractString (for MIME types with text-based storage, such as text/html or application/postscript) or x::Vector{UInt8} (for binary MIME types).\n\nTo customize how instances of a type are displayed, overload show rather than display, as explained in the manual section on custom pretty-printing.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Multimedia.redisplay","page":"I/O and Network","title":"Base.Multimedia.redisplay","text":"redisplay(x)\nredisplay(d::AbstractDisplay, x)\nredisplay(mime, x)\nredisplay(d::AbstractDisplay, mime, x)\n\nBy default, the redisplay functions simply call display. However, some display backends may override redisplay to modify an existing display of x (if any). Using redisplay is also a hint to the backend that x may be redisplayed several times, and the backend may choose to defer the display until (for example) the next interactive prompt.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Multimedia.displayable","page":"I/O and Network","title":"Base.Multimedia.displayable","text":"displayable(mime) -> Bool\ndisplayable(d::AbstractDisplay, mime) -> Bool\n\nReturn a boolean value indicating whether the given mime type (string) is displayable by any of the displays in the current display stack, or specifically by the display d in the second variant.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.show-Tuple{IO, Any, Any}","page":"I/O and Network","title":"Base.show","text":"show(io::IO, mime, x)\n\nThe display functions ultimately call show in order to write an object x as a given mime type to a given I/O stream io (usually a memory buffer), if possible. In order to provide a rich multimedia representation of a user-defined type T, it is only necessary to define a new show method for T, via: show(io, ::MIME\"mime\", x::T) = ..., where mime is a MIME-type string and the function body calls write (or similar) to write that representation of x to io. (Note that the MIME\"\" notation only supports literal strings; to construct MIME types in a more flexible manner use MIME{Symbol(\"\")}.)\n\nFor example, if you define a MyImage type and know how to write it to a PNG file, you could define a function show(io, ::MIME\"image/png\", x::MyImage) = ... to allow your images to be displayed on any PNG-capable AbstractDisplay (such as IJulia). As usual, be sure to import Base.show in order to add new methods to the built-in Julia function show.\n\nTechnically, the MIME\"mime\" macro defines a singleton type for the given mime string, which allows us to exploit Julia's dispatch mechanisms in determining how to display objects of any given type.\n\nThe default MIME type is MIME\"text/plain\". There is a fallback definition for text/plain output that calls show with 2 arguments, so it is not always necessary to add a method for that case. If a type benefits from custom human-readable output though, show(::IO, ::MIME\"text/plain\", ::T) should be defined. For example, the Day type uses 1 day as the output for the text/plain MIME type, and Day(1) as the output of 2-argument show.\n\nExamples\n\njulia> struct Day\n n::Int\n end\n\njulia> Base.show(io::IO, ::MIME\"text/plain\", d::Day) = print(io, d.n, \" day\")\n\njulia> Day(1)\n1 day\n\nContainer types generally implement 3-argument show by calling show(io, MIME\"text/plain\"(), x) for elements x, with :compact => true set in an IOContext passed as the first argument.\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.Multimedia.showable","page":"I/O and Network","title":"Base.Multimedia.showable","text":"showable(mime, x)\n\nReturn a boolean value indicating whether or not the object x can be written as the given mime type.\n\n(By default, this is determined automatically by the existence of the corresponding show method for typeof(x). Some types provide custom showable methods; for example, if the available MIME formats depend on the value of x.)\n\nExamples\n\njulia> showable(MIME(\"text/plain\"), rand(5))\ntrue\n\njulia> showable(\"image/png\", rand(5))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.repr-Tuple{MIME, Any}","page":"I/O and Network","title":"Base.repr","text":"repr(mime, x; context=nothing)\n\nReturn an AbstractString or Vector{UInt8} containing the representation of x in the requested mime type, as written by show(io, mime, x) (throwing a MethodError if no appropriate show is available). An AbstractString is returned for MIME types with textual representations (such as \"text/html\" or \"application/postscript\"), whereas binary data is returned as Vector{UInt8}. (The function istextmime(mime) returns whether or not Julia treats a given mime type as text.)\n\nThe optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to show.\n\nAs a special case, if x is an AbstractString (for textual MIME types) or a Vector{UInt8} (for binary MIME types), the repr function assumes that x is already in the requested mime format and simply returns x. This special case does not apply to the \"text/plain\" MIME type. This is useful so that raw data can be passed to display(m::MIME, x).\n\nIn particular, repr(\"text/plain\", x) is typically a \"pretty-printed\" version of x designed for human consumption. See also repr(x) to instead return a string corresponding to show(x) that may be closer to how the value of x would be entered in Julia.\n\nExamples\n\njulia> A = [1 2; 3 4];\n\njulia> repr(\"text/plain\", A)\n\"2×2 Matrix{Int64}:\\n 1 2\\n 3 4\"\n\n\n\n\n\n","category":"method"},{"location":"base/io-network/#Base.Multimedia.MIME","page":"I/O and Network","title":"Base.Multimedia.MIME","text":"MIME\n\nA type representing a standard internet data format. \"MIME\" stands for \"Multipurpose Internet Mail Extensions\", since the standard was originally used to describe multimedia attachments to email messages.\n\nA MIME object can be passed as the second argument to show to request output in that format.\n\nExamples\n\njulia> show(stdout, MIME(\"text/plain\"), \"hi\")\n\"hi\"\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.Multimedia.@MIME_str","page":"I/O and Network","title":"Base.Multimedia.@MIME_str","text":"@MIME_str\n\nA convenience macro for writing MIME types, typically used when adding methods to show. For example the syntax show(io::IO, ::MIME\"text/html\", x::MyType) = ... could be used to define how to write an HTML representation of MyType.\n\n\n\n\n\n","category":"macro"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"As mentioned above, one can also define new display backends. For example, a module that can display PNG images in a window can register this capability with Julia, so that calling display(x) on types with PNG representations will automatically display the image using the module's window.","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"In order to define a new display backend, one should first create a subtype D of the abstract class AbstractDisplay. Then, for each MIME type (mime string) that can be displayed on D, one should define a function display(d::D, ::MIME\"mime\", x) = ... that displays x as that MIME type, usually by calling show(io, mime, x) or repr(io, mime, x). A MethodError should be thrown if x cannot be displayed as that MIME type; this is automatic if one calls show or repr. Finally, one should define a function display(d::D, x) that queries showable(mime, x) for the mime types supported by D and displays the \"best\" one; a MethodError should be thrown if no supported MIME types are found for x. Similarly, some subtypes may wish to override redisplay(d::D, ...). (Again, one should import Base.display to add new methods to display.) The return values of these functions are up to the implementation (since in some cases it may be useful to return a display \"handle\" of some type). The display functions for D can then be called directly, but they can also be invoked automatically from display(x) simply by pushing a new display onto the display-backend stack with:","category":"page"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.Multimedia.pushdisplay\nBase.Multimedia.popdisplay\nBase.Multimedia.TextDisplay\nBase.Multimedia.istextmime","category":"page"},{"location":"base/io-network/#Base.Multimedia.pushdisplay","page":"I/O and Network","title":"Base.Multimedia.pushdisplay","text":"pushdisplay(d::AbstractDisplay)\n\nPushes a new display d on top of the global display-backend stack. Calling display(x) or display(mime, x) will display x on the topmost compatible backend in the stack (i.e., the topmost backend that does not throw a MethodError).\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Multimedia.popdisplay","page":"I/O and Network","title":"Base.Multimedia.popdisplay","text":"popdisplay()\npopdisplay(d::AbstractDisplay)\n\nPop the topmost backend off of the display-backend stack, or the topmost copy of d in the second variant.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.Multimedia.TextDisplay","page":"I/O and Network","title":"Base.Multimedia.TextDisplay","text":"TextDisplay(io::IO)\n\nReturn a TextDisplay <: AbstractDisplay, which displays any object as the text/plain MIME type (by default), writing the text representation to the given I/O stream. (This is how objects are printed in the Julia REPL.)\n\n\n\n\n\n","category":"type"},{"location":"base/io-network/#Base.Multimedia.istextmime","page":"I/O and Network","title":"Base.Multimedia.istextmime","text":"istextmime(m::MIME)\n\nDetermine whether a MIME type is text data. MIME types are assumed to be binary data except for a set of types known to be text data (possibly Unicode).\n\nExamples\n\njulia> istextmime(MIME(\"text/plain\"))\ntrue\n\njulia> istextmime(MIME(\"image/png\"))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Network-I/O","page":"I/O and Network","title":"Network I/O","text":"","category":"section"},{"location":"base/io-network/","page":"I/O and Network","title":"I/O and Network","text":"Base.bytesavailable\nBase.ntoh\nBase.hton\nBase.ltoh\nBase.htol\nBase.ENDIAN_BOM","category":"page"},{"location":"base/io-network/#Base.bytesavailable","page":"I/O and Network","title":"Base.bytesavailable","text":"bytesavailable(io)\n\nReturn the number of bytes available for reading before a read from this stream or buffer will block.\n\nExamples\n\njulia> io = IOBuffer(\"JuliaLang is a GitHub organization\");\n\njulia> bytesavailable(io)\n34\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.ntoh","page":"I/O and Network","title":"Base.ntoh","text":"ntoh(x)\n\nConvert the endianness of a value from Network byte order (big-endian) to that used by the Host.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.hton","page":"I/O and Network","title":"Base.hton","text":"hton(x)\n\nConvert the endianness of a value from that used by the Host to Network byte order (big-endian).\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.ltoh","page":"I/O and Network","title":"Base.ltoh","text":"ltoh(x)\n\nConvert the endianness of a value from Little-endian to that used by the Host.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.htol","page":"I/O and Network","title":"Base.htol","text":"htol(x)\n\nConvert the endianness of a value from that used by the Host to Little-endian.\n\n\n\n\n\n","category":"function"},{"location":"base/io-network/#Base.ENDIAN_BOM","page":"I/O and Network","title":"Base.ENDIAN_BOM","text":"ENDIAN_BOM\n\nThe 32-bit byte-order-mark indicates the native byte order of the host machine. Little-endian machines will contain the value 0x04030201. Big-endian machines will contain the value 0x01020304.\n\n\n\n\n\n","category":"constant"},{"location":"base/c/#C-Interface","page":"C Interface","title":"C Interface","text":"","category":"section"},{"location":"base/c/","page":"C Interface","title":"C Interface","text":"@ccall\nccall\nCore.Intrinsics.cglobal\nBase.@cfunction\nBase.CFunction\nBase.unsafe_convert\nBase.cconvert\nBase.unsafe_load\nBase.unsafe_store!\nBase.unsafe_modify!\nBase.unsafe_replace!\nBase.unsafe_swap!\nBase.unsafe_copyto!{T}(::Ptr{T}, ::Ptr{T}, ::Any)\nBase.unsafe_copyto!(::Array, ::Any, ::Array, ::Any, ::Any)\nBase.copyto!\nBase.pointer\nBase.unsafe_wrap{T,N}(::Union{Type{Array},Type{Array{T}},Type{Array{T,N}}}, ::Ptr{T}, ::NTuple{N,Int})\nBase.pointer_from_objref\nBase.unsafe_pointer_to_objref\nBase.disable_sigint\nBase.reenable_sigint\nBase.exit_on_sigint\nBase.systemerror\nBase.windowserror\nCore.Ptr\nCore.Ref\nBase.isassigned(::Base.RefValue)\nBase.Cchar\nBase.Cuchar\nBase.Cshort\nBase.Cstring\nBase.Cushort\nBase.Cint\nBase.Cuint\nBase.Clong\nBase.Culong\nBase.Clonglong\nBase.Culonglong\nBase.Cintmax_t\nBase.Cuintmax_t\nBase.Csize_t\nBase.Cssize_t\nBase.Cptrdiff_t\nBase.Cwchar_t\nBase.Cwstring\nBase.Cfloat\nBase.Cdouble","category":"page"},{"location":"base/c/#Base.@ccall","page":"C Interface","title":"Base.@ccall","text":"@ccall library.function_name(argvalue1::argtype1, ...)::returntype\n@ccall function_name(argvalue1::argtype1, ...)::returntype\n@ccall $function_pointer(argvalue1::argtype1, ...)::returntype\n\nCall a function in a C-exported shared library, specified by library.function_name, where library is a string constant or literal. The library may be omitted, in which case the function_name is resolved in the current process. Alternatively, @ccall may also be used to call a function pointer $function_pointer, such as one returned by dlsym.\n\nEach argvalue to @ccall is converted to the corresponding argtype, by automatic insertion of calls to unsafe_convert(argtype, cconvert(argtype, argvalue)). (See also the documentation for unsafe_convert and cconvert for further details.) In most cases, this simply results in a call to convert(argtype, argvalue).\n\nExamples\n\n@ccall strlen(s::Cstring)::Csize_t\n\nThis calls the C standard library function:\n\nsize_t strlen(char *)\n\nwith a Julia variable named s. See also ccall.\n\nVarargs are supported with the following convention:\n\n@ccall printf(\"%s = %d\"::Cstring ; \"foo\"::Cstring, foo::Cint)::Cint\n\nThe semicolon is used to separate required arguments (of which there must be at least one) from variadic arguments.\n\nExample using an external library:\n\n# C signature of g_uri_escape_string:\n# char *g_uri_escape_string(const char *unescaped, const char *reserved_chars_allowed, gboolean allow_utf8);\n\nconst glib = \"libglib-2.0\"\n@ccall glib.g_uri_escape_string(my_uri::Cstring, \":/\"::Cstring, true::Cint)::Cstring\n\nThe string literal could also be used directly before the function name, if desired \"libglib-2.0\".g_uri_escape_string(...\n\n\n\n\n\n","category":"macro"},{"location":"base/c/#ccall","page":"C Interface","title":"ccall","text":"ccall((function_name, library), returntype, (argtype1, ...), argvalue1, ...)\nccall(function_name, returntype, (argtype1, ...), argvalue1, ...)\nccall(function_pointer, returntype, (argtype1, ...), argvalue1, ...)\n\nCall a function in a C-exported shared library, specified by the tuple (function_name, library), where each component is either a string or symbol. Instead of specifying a library, one can also use a function_name symbol or string, which is resolved in the current process. Alternatively, ccall may also be used to call a function pointer function_pointer, such as one returned by dlsym.\n\nNote that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression.\n\nEach argvalue to the ccall will be converted to the corresponding argtype, by automatic insertion of calls to unsafe_convert(argtype, cconvert(argtype, argvalue)). (See also the documentation for unsafe_convert and cconvert for further details.) In most cases, this simply results in a call to convert(argtype, argvalue).\n\n\n\n\n\n","category":"keyword"},{"location":"base/c/#Core.Intrinsics.cglobal","page":"C Interface","title":"Core.Intrinsics.cglobal","text":"cglobal((symbol, library) [, type=Cvoid])\n\nObtain a pointer to a global variable in a C-exported shared library, specified exactly as in ccall. Returns a Ptr{Type}, defaulting to Ptr{Cvoid} if no Type argument is supplied. The values can be read or written by unsafe_load or unsafe_store!, respectively.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.@cfunction","page":"C Interface","title":"Base.@cfunction","text":"@cfunction(callable, ReturnType, (ArgumentTypes...,)) -> Ptr{Cvoid}\n@cfunction($callable, ReturnType, (ArgumentTypes...,)) -> CFunction\n\nGenerate a C-callable function pointer from the Julia function callable for the given type signature. To pass the return value to a ccall, use the argument type Ptr{Cvoid} in the signature.\n\nNote that the argument type tuple must be a literal tuple, and not a tuple-valued variable or expression (although it can include a splat expression). And that these arguments will be evaluated in global scope during compile-time (not deferred until runtime). Adding a '$' in front of the function argument changes this to instead create a runtime closure over the local variable callable (this is not supported on all architectures).\n\nSee manual section on ccall and cfunction usage.\n\nExamples\n\njulia> function foo(x::Int, y::Int)\n return x + y\n end\n\njulia> @cfunction(foo, Int, (Int, Int))\nPtr{Cvoid} @0x000000001b82fcd0\n\n\n\n\n\n","category":"macro"},{"location":"base/c/#Base.CFunction","page":"C Interface","title":"Base.CFunction","text":"CFunction struct\n\nGarbage-collection handle for the return value from @cfunction when the first argument is annotated with '$'. Like all cfunction handles, it should be passed to ccall as a Ptr{Cvoid}, and will be converted automatically at the call site to the appropriate type.\n\nSee @cfunction.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.unsafe_convert","page":"C Interface","title":"Base.unsafe_convert","text":"unsafe_convert(T, x)\n\nConvert x to a C argument of type T where the input x must be the return value of cconvert(T, ...).\n\nIn cases where convert would need to take a Julia object and turn it into a Ptr, this function should be used to define and perform that conversion.\n\nBe careful to ensure that a Julia reference to x exists as long as the result of this function will be used. Accordingly, the argument x to this function should never be an expression, only a variable name or field reference. For example, x=a.b.c is acceptable, but x=[a,b,c] is not.\n\nThe unsafe prefix on this function indicates that using the result of this function after the x argument to this function is no longer accessible to the program may cause undefined behavior, including program corruption or segfaults, at any later time.\n\nSee also cconvert\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.cconvert","page":"C Interface","title":"Base.cconvert","text":"cconvert(T,x)\n\nConvert x to a value to be passed to C code as type T, typically by calling convert(T, x).\n\nIn cases where x cannot be safely converted to T, unlike convert, cconvert may return an object of a type different from T, which however is suitable for unsafe_convert to handle. The result of this function should be kept valid (for the GC) until the result of unsafe_convert is not needed anymore. This can be used to allocate memory that will be accessed by the ccall. If multiple objects need to be allocated, a tuple of the objects can be used as return value.\n\nNeither convert nor cconvert should take a Julia object and turn it into a Ptr.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_load","page":"C Interface","title":"Base.unsafe_load","text":"unsafe_load(p::Ptr{T}, i::Integer=1)\nunsafe_load(p::Ptr{T}, order::Symbol)\nunsafe_load(p::Ptr{T}, i::Integer, order::Symbol)\n\nLoad a value of type T from the address of the ith element (1-indexed) starting at p. This is equivalent to the C expression p[i-1]. Optionally, an atomic memory ordering can be provided.\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program or return garbage answers. Unlike C, dereferencing memory region allocated as different type may be valid provided that the types are compatible.\n\ncompat: Julia 1.10\nThe order argument is available as of Julia 1.10.\n\nSee also: atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_store!","page":"C Interface","title":"Base.unsafe_store!","text":"unsafe_store!(p::Ptr{T}, x, i::Integer=1)\nunsafe_store!(p::Ptr{T}, x, order::Symbol)\nunsafe_store!(p::Ptr{T}, x, i::Integer, order::Symbol)\n\nStore a value of type T to the address of the ith element (1-indexed) starting at p. This is equivalent to the C expression p[i-1] = x. Optionally, an atomic memory ordering can be provided.\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program. Unlike C, storing memory region allocated as different type may be valid provided that that the types are compatible.\n\ncompat: Julia 1.10\nThe order argument is available as of Julia 1.10.\n\nSee also: atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_modify!","page":"C Interface","title":"Base.unsafe_modify!","text":"unsafe_modify!(p::Ptr{T}, op, x, [order::Symbol]) -> Pair\n\nThese atomically perform the operations to get and set a memory address after applying the function op. If supported by the hardware (for example, atomic increment), this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:\n\ny = unsafe_load(p)\nz = op(y, x)\nunsafe_store!(p, z)\nreturn y => z\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\nSee also: modifyproperty!, atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_replace!","page":"C Interface","title":"Base.unsafe_replace!","text":"unsafe_replace!(p::Ptr{T}, expected, desired,\n [success_order::Symbol[, fail_order::Symbol=success_order]]) -> (; old, success::Bool)\n\nThese atomically perform the operations to get and conditionally set a memory address to a given value. If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:\n\ny = unsafe_load(p, fail_order)\nok = y === expected\nif ok\n unsafe_store!(p, desired, success_order)\nend\nreturn (; old = y, success = ok)\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\nSee also: replaceproperty!, atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_swap!","page":"C Interface","title":"Base.unsafe_swap!","text":"unsafe_swap!(p::Ptr{T}, x, [order::Symbol])\n\nThese atomically perform the operations to simultaneously get and set a memory address. If supported by the hardware, this may be optimized to the appropriate hardware instruction, otherwise its execution will be similar to:\n\ny = unsafe_load(p)\nunsafe_store!(p, x)\nreturn y\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointer p to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program.\n\ncompat: Julia 1.10\nThis function requires at least Julia 1.10.\n\nSee also: swapproperty!, atomic\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_copyto!-Union{Tuple{T}, Tuple{Ptr{T}, Ptr{T}, Any}} where T","page":"C Interface","title":"Base.unsafe_copyto!","text":"unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)\n\nCopy N elements from a source pointer to a destination, with no checking. The size of an element is determined by the type of the pointers.\n\nThe unsafe prefix on this function indicates that no validation is performed on the pointers dest and src to ensure that they are valid. Incorrect usage may corrupt or segfault your program, in the same manner as C.\n\n\n\n\n\n","category":"method"},{"location":"base/c/#Base.unsafe_copyto!-Tuple{Array, Any, Array, Any, Any}","page":"C Interface","title":"Base.unsafe_copyto!","text":"unsafe_copyto!(dest::Array, do, src::Array, so, N)\n\nCopy N elements from a source array to a destination, starting at the linear index so in the source and do in the destination (1-indexed).\n\nThe unsafe prefix on this function indicates that no validation is performed to ensure that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in the same manner as C.\n\n\n\n\n\n","category":"method"},{"location":"base/c/#Base.copyto!","page":"C Interface","title":"Base.copyto!","text":"copyto!(B::AbstractMatrix, ir_dest::AbstractUnitRange, jr_dest::AbstractUnitRange,\n tM::AbstractChar,\n M::AbstractVecOrMat, ir_src::AbstractUnitRange, jr_src::AbstractUnitRange) -> B\n\nEfficiently copy elements of matrix M to B conditioned on the character parameter tM as follows:\n\ntM Destination Source\n'N' B[ir_dest, jr_dest] M[ir_src, jr_src]\n'T' B[ir_dest, jr_dest] transpose(M)[ir_src, jr_src]\n'C' B[ir_dest, jr_dest] adjoint(M)[ir_src, jr_src]\n\nThe elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(ir_src) and length(jr_dest) == length(jr_src).\n\nSee also copy_transpose! and copy_adjoint!.\n\n\n\n\n\ncopyto!(dest::AbstractMatrix, src::UniformScaling)\n\nCopies a UniformScaling onto a matrix.\n\ncompat: Julia 1.1\nIn Julia 1.0 this method only supported a square destination matrix. Julia 1.1. added support for a rectangular matrix.\n\n\n\n\n\ncopyto!(dest, do, src, so, N)\n\nCopy N elements from collection src starting at the linear index so, to array dest starting at the index do. Return dest.\n\n\n\n\n\ncopyto!(dest::AbstractArray, src) -> dest\n\nCopy all elements from collection src to array dest, whose length must be greater than or equal to the length n of src. The first n elements of dest are overwritten, the other elements are left untouched.\n\nSee also copy!, copy.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> x = [1., 0., 3., 0., 5.];\n\njulia> y = zeros(7);\n\njulia> copyto!(y, x);\n\njulia> y\n7-element Vector{Float64}:\n 1.0\n 0.0\n 3.0\n 0.0\n 5.0\n 0.0\n 0.0\n\n\n\n\n\ncopyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest\n\nCopy the block of src in the range of Rsrc to the block of dest in the range of Rdest. The sizes of the two regions must match.\n\nExamples\n\njulia> A = zeros(5, 5);\n\njulia> B = [1 2; 3 4];\n\njulia> Ainds = CartesianIndices((2:3, 2:3));\n\njulia> Binds = CartesianIndices(B);\n\njulia> copyto!(A, Ainds, B, Binds)\n5×5 Matrix{Float64}:\n 0.0 0.0 0.0 0.0 0.0\n 0.0 1.0 2.0 0.0 0.0\n 0.0 3.0 4.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.pointer","page":"C Interface","title":"Base.pointer","text":"pointer(array [, index])\n\nGet the native address of an array or string, optionally at a given location index.\n\nThis function is \"unsafe\". Be careful to ensure that a Julia reference to array exists as long as this pointer will be used. The GC.@preserve macro should be used to protect the array argument from garbage collection within a given block of code.\n\nCalling Ref(array[, index]) is generally preferable to this function as it guarantees validity.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_wrap-Union{Tuple{N}, Tuple{T}, Tuple{Union{Type{Array}, Type{Array{T}}, Type{Array{T, N}}}, Ptr{T}, NTuple{N, Int64}}} where {T, N}","page":"C Interface","title":"Base.unsafe_wrap","text":"unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)\n\nWrap a Julia Array object around the data at the address given by pointer, without making a copy. The pointer element type T determines the array element type. dims is either an integer (for a 1d array) or a tuple of the array dimensions. own optionally specifies whether Julia should take ownership of the memory, calling free on the pointer when the array is no longer referenced.\n\nThis function is labeled \"unsafe\" because it will crash if pointer is not a valid memory address to data of the requested length. Unlike unsafe_load and unsafe_store!, the programmer is responsible also for ensuring that the underlying data is not accessed through two arrays of different element type, similar to the strict aliasing rule in C.\n\n\n\n\n\n","category":"method"},{"location":"base/c/#Base.pointer_from_objref","page":"C Interface","title":"Base.pointer_from_objref","text":"pointer_from_objref(x)\n\nGet the memory address of a Julia object as a Ptr. The existence of the resulting Ptr will not protect the object from garbage collection, so you must ensure that the object remains referenced for the whole time that the Ptr will be used.\n\nThis function may not be called on immutable objects, since they do not have stable memory addresses.\n\nSee also unsafe_pointer_to_objref.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.unsafe_pointer_to_objref","page":"C Interface","title":"Base.unsafe_pointer_to_objref","text":"unsafe_pointer_to_objref(p::Ptr)\n\nConvert a Ptr to an object reference. Assumes the pointer refers to a valid heap-allocated Julia object. If this is not the case, undefined behavior results, hence this function is considered \"unsafe\" and should be used with care.\n\nSee also pointer_from_objref.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.disable_sigint","page":"C Interface","title":"Base.disable_sigint","text":"disable_sigint(f::Function)\n\nDisable Ctrl-C handler during execution of a function on the current task, for calling external code that may call julia code that is not interrupt safe. Intended to be called using do block syntax as follows:\n\ndisable_sigint() do\n # interrupt-unsafe code\n ...\nend\n\nThis is not needed on worker threads (Threads.threadid() != 1) since the InterruptException will only be delivered to the master thread. External functions that do not call julia code or julia runtime automatically disable sigint during their execution.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.reenable_sigint","page":"C Interface","title":"Base.reenable_sigint","text":"reenable_sigint(f::Function)\n\nRe-enable Ctrl-C handler during execution of a function. Temporarily reverses the effect of disable_sigint.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.exit_on_sigint","page":"C Interface","title":"Base.exit_on_sigint","text":"exit_on_sigint(on::Bool)\n\nSet exit_on_sigint flag of the julia runtime. If false, Ctrl-C (SIGINT) is capturable as InterruptException in try block. This is the default behavior in REPL, any code run via -e and -E and in Julia script run with -i option.\n\nIf true, InterruptException is not thrown by Ctrl-C. Running code upon such event requires atexit. This is the default behavior in Julia script run without -i option.\n\ncompat: Julia 1.5\nFunction exit_on_sigint requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.systemerror","page":"C Interface","title":"Base.systemerror","text":"systemerror(sysfunc[, errno::Cint=Libc.errno()])\nsystemerror(sysfunc, iftrue::Bool)\n\nRaises a SystemError for errno with the descriptive string sysfunc if iftrue is true\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Base.windowserror","page":"C Interface","title":"Base.windowserror","text":"windowserror(sysfunc[, code::UInt32=Libc.GetLastError()])\nwindowserror(sysfunc, iftrue::Bool)\n\nLike systemerror, but for Windows API functions that use GetLastError to return an error code instead of setting errno.\n\n\n\n\n\n","category":"function"},{"location":"base/c/#Core.Ptr","page":"C Interface","title":"Core.Ptr","text":"Ptr{T}\n\nA memory address referring to data of type T. However, there is no guarantee that the memory is actually valid, or that it actually represents data of the specified type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Core.Ref","page":"C Interface","title":"Core.Ref","text":"Ref{T}\n\nAn object that safely references data of type T. This type is guaranteed to point to valid, Julia-allocated memory of the correct type. The underlying data is protected from freeing by the garbage collector as long as the Ref itself is referenced.\n\nIn Julia, Ref objects are dereferenced (loaded or stored) with [].\n\nCreation of a Ref to a value x of type T is usually written Ref(x). Additionally, for creating interior pointers to containers (such as Array or Ptr), it can be written Ref(a, i) for creating a reference to the i-th element of a.\n\nRef{T}() creates a reference to a value of type T without initialization. For a bitstype T, the value will be whatever currently resides in the memory allocated. For a non-bitstype T, the reference will be undefined and attempting to dereference it will result in an error, \"UndefRefError: access to undefined reference\".\n\nTo check if a Ref is an undefined reference, use isassigned(ref::RefValue). For example, isassigned(Ref{T}()) is false if T is not a bitstype. If T is a bitstype, isassigned(Ref{T}()) will always be true.\n\nWhen passed as a ccall argument (either as a Ptr or Ref type), a Ref object will be converted to a native pointer to the data it references. For most T, or when converted to a Ptr{Cvoid}, this is a pointer to the object data. When T is an isbits type, this value may be safely mutated, otherwise mutation is strictly undefined behavior.\n\nAs a special case, setting T = Any will instead cause the creation of a pointer to the reference itself when converted to a Ptr{Any} (a jl_value_t const* const* if T is immutable, else a jl_value_t *const *). When converted to a Ptr{Cvoid}, it will still return a pointer to the data region as for any other T.\n\nA C_NULL instance of Ptr can be passed to a ccall Ref argument to initialize it.\n\nUse in broadcasting\n\nRef is sometimes used in broadcasting in order to treat the referenced values as a scalar.\n\nExamples\n\njulia> r = Ref(5) # Create a Ref with an initial value\nBase.RefValue{Int64}(5)\n\njulia> r[] # Getting a value from a Ref\n5\n\njulia> r[] = 7 # Storing a new value in a Ref\n7\n\njulia> r # The Ref now contains 7\nBase.RefValue{Int64}(7)\n\njulia> isa.(Ref([1,2,3]), [Array, Dict, Int]) # Treat reference values as scalar during broadcasting\n3-element BitVector:\n 1\n 0\n 0\n\njulia> Ref{Function}() # Undefined reference to a non-bitstype, Function\nBase.RefValue{Function}(#undef)\n\njulia> try\n Ref{Function}()[] # Dereferencing an undefined reference will result in an error\n catch e\n println(e)\n end\nUndefRefError()\n\njulia> Ref{Int64}()[]; # A reference to a bitstype refers to an undetermined value if not given\n\njulia> isassigned(Ref{Int64}()) # A reference to a bitstype is always assigned\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.isassigned-Tuple{Base.RefValue}","page":"C Interface","title":"Base.isassigned","text":"isassigned(ref::RefValue) -> Bool\n\nTest whether the given Ref is associated with a value. This is always true for a Ref of a bitstype object. Return false if the reference is undefined.\n\nExamples\n\njulia> ref = Ref{Function}()\nBase.RefValue{Function}(#undef)\n\njulia> isassigned(ref)\nfalse\n\njulia> ref[] = (foobar(x) = x)\nfoobar (generic function with 1 method)\n\njulia> isassigned(ref)\ntrue\n\njulia> isassigned(Ref{Int}())\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/c/#Base.Cchar","page":"C Interface","title":"Base.Cchar","text":"Cchar\n\nEquivalent to the native char c-type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cuchar","page":"C Interface","title":"Base.Cuchar","text":"Cuchar\n\nEquivalent to the native unsigned char c-type (UInt8).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cshort","page":"C Interface","title":"Base.Cshort","text":"Cshort\n\nEquivalent to the native signed short c-type (Int16).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cstring","page":"C Interface","title":"Base.Cstring","text":"Cstring\n\nA C-style string composed of the native character type Cchars. Cstrings are NUL-terminated. For C-style strings composed of the native wide character type, see Cwstring. For more information about string interoperability with C, see the manual.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cushort","page":"C Interface","title":"Base.Cushort","text":"Cushort\n\nEquivalent to the native unsigned short c-type (UInt16).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cint","page":"C Interface","title":"Base.Cint","text":"Cint\n\nEquivalent to the native signed int c-type (Int32).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cuint","page":"C Interface","title":"Base.Cuint","text":"Cuint\n\nEquivalent to the native unsigned int c-type (UInt32).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Clong","page":"C Interface","title":"Base.Clong","text":"Clong\n\nEquivalent to the native signed long c-type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Culong","page":"C Interface","title":"Base.Culong","text":"Culong\n\nEquivalent to the native unsigned long c-type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Clonglong","page":"C Interface","title":"Base.Clonglong","text":"Clonglong\n\nEquivalent to the native signed long long c-type (Int64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Culonglong","page":"C Interface","title":"Base.Culonglong","text":"Culonglong\n\nEquivalent to the native unsigned long long c-type (UInt64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cintmax_t","page":"C Interface","title":"Base.Cintmax_t","text":"Cintmax_t\n\nEquivalent to the native intmax_t c-type (Int64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cuintmax_t","page":"C Interface","title":"Base.Cuintmax_t","text":"Cuintmax_t\n\nEquivalent to the native uintmax_t c-type (UInt64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Csize_t","page":"C Interface","title":"Base.Csize_t","text":"Csize_t\n\nEquivalent to the native size_t c-type (UInt).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cssize_t","page":"C Interface","title":"Base.Cssize_t","text":"Cssize_t\n\nEquivalent to the native ssize_t c-type.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cptrdiff_t","page":"C Interface","title":"Base.Cptrdiff_t","text":"Cptrdiff_t\n\nEquivalent to the native ptrdiff_t c-type (Int).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cwchar_t","page":"C Interface","title":"Base.Cwchar_t","text":"Cwchar_t\n\nEquivalent to the native wchar_t c-type (Int32).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cwstring","page":"C Interface","title":"Base.Cwstring","text":"Cwstring\n\nA C-style string composed of the native wide character type Cwchar_ts. Cwstrings are NUL-terminated. For C-style strings composed of the native character type, see Cstring. For more information about string interoperability with C, see the manual.\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cfloat","page":"C Interface","title":"Base.Cfloat","text":"Cfloat\n\nEquivalent to the native float c-type (Float32).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#Base.Cdouble","page":"C Interface","title":"Base.Cdouble","text":"Cdouble\n\nEquivalent to the native double c-type (Float64).\n\n\n\n\n\n","category":"type"},{"location":"base/c/#LLVM-Interface","page":"C Interface","title":"LLVM Interface","text":"","category":"section"},{"location":"base/c/","page":"C Interface","title":"C Interface","text":"Core.Intrinsics.llvmcall","category":"page"},{"location":"base/c/#Core.Intrinsics.llvmcall","page":"C Interface","title":"Core.Intrinsics.llvmcall","text":"llvmcall(fun_ir::String, returntype, Tuple{argtype1, ...}, argvalue1, ...)\nllvmcall((mod_ir::String, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)\nllvmcall((mod_bc::Vector{UInt8}, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)\n\nCall the LLVM code provided in the first argument. There are several ways to specify this first argument:\n\nas a literal string, representing function-level IR (similar to an LLVM define block), with arguments are available as consecutive unnamed SSA variables (%0, %1, etc.);\nas a 2-element tuple, containing a string of module IR and a string representing the name of the entry-point function to call;\nas a 2-element tuple, but with the module provided as an Vector{UInt8} with bitcode.\n\nNote that contrary to ccall, the argument types must be specified as a tuple type, and not a tuple of types. All types, as well as the LLVM code, should be specified as literals, and not as variables or expressions (it may be necessary to use @eval to generate these literals).\n\nOpaque pointers (written as ptr) are not allowed in the LLVM code.\n\nSee test/llvmcall.jl for usage examples.\n\n\n\n\n\n","category":"function"},{"location":"manual/code-loading/#code-loading","page":"Code Loading","title":"Code Loading","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"note: Note\nThis chapter covers the technical details of package loading. To install packages, use Pkg, Julia's built-in package manager, to add packages to your active environment. To use packages already in your active environment, write import X or using X, as described in the Modules documentation.","category":"page"},{"location":"manual/code-loading/#Definitions","page":"Code Loading","title":"Definitions","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Julia has two mechanisms for loading code:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Code inclusion: e.g. include(\"source.jl\"). Inclusion allows you to split a single program across multiple source files. The expression include(\"source.jl\") causes the contents of the file source.jl to be evaluated in the global scope of the module where the include call occurs. If include(\"source.jl\") is called multiple times, source.jl is evaluated multiple times. The included path, source.jl, is interpreted relative to the file where the include call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, pwd().\nPackage loading: e.g. import X or using X. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name X inside of the importing module. If the same X package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that import X can load different packages in different contexts: X can refer to one package named X in the main project but potentially to different packages also named X in each dependency. More on this below.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Code inclusion is quite straightforward and simple: it evaluates the given source file in the context of the caller. Package loading is built on top of code inclusion and serves a different purpose. The rest of this chapter focuses on the behavior and mechanics of package loading.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A package is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by import X or using X statements. These statements also make the module named X—which results from loading the package code—available within the module where the import statement occurs. The meaning of X in import X is context-dependent: which X package is loaded depends on what code the statement occurs in. Thus, handling of import X happens in two stages: first, it determines what package is defined to be X in this context; second, it determines where that particular X package is found.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"These questions are answered by searching through the project environments listed in LOAD_PATH for project files (Project.toml or JuliaProject.toml), manifest files (Manifest.toml or JuliaManifest.toml, or the same names suffixed by -v{major}.{minor}.toml for specific versions), or folders of source files.","category":"page"},{"location":"manual/code-loading/#Federation-of-packages","page":"Code Loading","title":"Federation of packages","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Most of the time, a package is uniquely identifiable simply from its name. However, sometimes a project might encounter a situation where it needs to use two different packages that share the same name. While you might be able fix this by renaming one of the packages, being forced to do so can be highly disruptive in a large, shared code base. Instead, Julia's code loading mechanism allows the same package name to refer to different packages in different components of an application.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Julia supports federated package management, which means that multiple independent parties can maintain both public and private packages and registries of packages, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The Pkg package manager that ships with Julia lets you install and manage your projects' dependencies. It assists in creating and manipulating project files (which describe what other projects that your project depends on), and manifest files (which snapshot exact versions of your project's complete dependency graph).","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project may end up depending on different packages that have the same name. Julia's package loading mechanism does not require package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by universally unique identifiers (UUIDs), which get assigned when each package is created. Usually you won't have to work directly with these somewhat cumbersome 128-bit identifiers since Pkg will take care of generating and tracking them for you. However, these UUIDs provide the definitive answer to the question of \"what package does X refer to?\"","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called App, which uses two packages: Pub and Priv. Priv is a private package that you created, whereas Pub is a public package that you use but don't control. When you created Priv, there was no public package by the name Priv. Subsequently, however, an unrelated package also named Priv has been published and become popular. In fact, the Pub package has started to use it. Therefore, when you next upgrade Pub to get the latest bug fixes and features, App will end up depending on two different packages named Priv—through no action of yours other than upgrading. App has a direct dependency on your private Priv package, and an indirect dependency, through Pub, on the new public Priv package. Since these two Priv packages are different but are both required for App to continue working correctly, the expression import Priv must refer to different Priv packages depending on whether it occurs in App's code or in Pub's code. To handle this, Julia's package loading mechanism distinguishes the two Priv packages by their UUID and picks the correct one based on its context (the module that called import). How this distinction works is determined by environments, as explained in the following sections.","category":"page"},{"location":"manual/code-loading/#Environments","page":"Code Loading","title":"Environments","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"An environment determines what import X and using X mean in various code contexts and what files these statements cause to be loaded. Julia understands two kinds of environments:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A project environment is a directory with a project file and an optional manifest file, and forms an explicit environment. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version.\nA package directory is a directory containing the source trees of a set of packages as subdirectories, and forms an implicit environment. If X is a subdirectory of a package directory and X/src/X.jl exists, then the package X is available in the package directory environment and X/src/X.jl is the source file by which it is loaded.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"These can be intermixed to create a stacked environment: an ordered set of project environments and package directories, overlaid to make a single composite environment. The precedence and visibility rules then combine to determine which packages are available and where they get loaded from. Julia's load path forms a stacked environment, for example.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"These environment each serve a different purpose:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Project environments provide reproducibility. By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project and all of its dependencies. The manifest file, in particular, captures the exact version of every dependency, identified by a cryptographic hash of its source tree, which makes it possible for Pkg to retrieve the correct versions and be sure that you are running the exact code that was recorded for all dependencies.\nPackage directories provide convenience when a full carefully-tracked project environment is unnecessary. They are useful when you want to put a set of packages somewhere and be able to directly use them, without needing to create a project environment for them.\nStacked environments allow for adding tools to the primary environment. You can push an environment of development tools onto the end of the stack to make them available from the REPL and scripts, but not from inside packages.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"At a high-level, each environment conceptually defines three maps: roots, graph and paths. When resolving the meaning of import X, the roots and graph maps are used to determine the identity of X, while the paths map is used to locate the source code of X. The specific roles of the three maps are:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"roots: name::Symbol ⟶ uuid::UUID\nAn environment's roots map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in Main). When Julia encounters import X in the main project, it looks up the identity of X as roots[:X].\ngraph: context::UUID ⟶ name::Symbol ⟶ uuid::UUID\nAn environment's graph is a multilevel map which assigns, for each context UUID, a map from names to UUIDs, similar to the roots map but specific to that context. When Julia sees import X in the code of the package whose UUID is context, it looks up the identity of X as graph[context][:X]. In particular, this means that import X can refer to different packages depending on context.\npaths: uuid::UUID × name::Symbol ⟶ path::String\nThe paths map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of X in import X has been resolved to a UUID via roots or graph (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire X by looking up paths[uuid,:X] in the environment. Including this file should define a module named X. Once this package is loaded, any subsequent import resolving to the same uuid will create a new binding to the already-loaded package module.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Each kind of environment defines these three maps differently, as detailed in the following sections.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"note: Note\nFor ease of understanding, the examples throughout this chapter show full data structures for roots, graph and paths. However, Julia's package loading code does not explicitly create these. Instead, it lazily computes only as much of each structure as it needs to load a given package.","category":"page"},{"location":"manual/code-loading/#Project-environments","page":"Code Loading","title":"Project environments","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A project environment is determined by a directory containing a project file called Project.toml, and optionally a manifest file called Manifest.toml. These files may also be called JuliaProject.toml and JuliaManifest.toml, in which case Project.toml and Manifest.toml are ignored. This allows for coexistence with other tools that might consider files called Project.toml and Manifest.toml significant. For pure Julia projects, however, the names Project.toml and Manifest.toml are preferred. However, from Julia v1.11 onwards, (Julia)Manifest-v{major}.{minor}.toml is recognized as a format to make a given julia version use a specific manifest file i.e. in the same folder, a Manifest-v1.11.toml would be used by v1.11 and Manifest.toml by any other julia version.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The roots, graph and paths maps of a project environment are defined as follows:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The roots map of the environment is determined by the contents of the project file, specifically, its top-level name and uuid entries and its [deps] section (all optional). Consider the following example project file for the hypothetical application, App, as described earlier:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"name = \"App\"\nuuid = \"8f986787-14fe-4607-ba5d-fbff2944afa9\"\n\n[deps]\nPriv = \"ba13f791-ae1d-465a-978b-69c3ad90f72b\"\nPub = \"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"This project file implies the following roots map, if it was represented by a Julia dictionary:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"roots = Dict(\n :App => UUID(\"8f986787-14fe-4607-ba5d-fbff2944afa9\"),\n :Priv => UUID(\"ba13f791-ae1d-465a-978b-69c3ad90f72b\"),\n :Pub => UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"),\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Given this roots map, in App's code the statement import Priv will cause Julia to look up roots[:Priv], which yields ba13f791-ae1d-465a-978b-69c3ad90f72b, the UUID of the Priv package that is to be loaded in that context. This UUID identifies which Priv package to load and use when the main application evaluates import Priv.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The dependency graph of a project environment is determined by the contents of the manifest file, if present. If there is no manifest file, graph is empty. A manifest file contains a stanza for each of a project's direct or indirect dependencies. For each dependency, the file lists the package's UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for App:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"[[Priv]] # the private one\ndeps = [\"Pub\", \"Zebra\"]\nuuid = \"ba13f791-ae1d-465a-978b-69c3ad90f72b\"\npath = \"deps/Priv\"\n\n[[Priv]] # the public one\nuuid = \"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\"\ngit-tree-sha1 = \"1bf63d3be994fe83456a03b874b409cfd59a6373\"\nversion = \"0.1.5\"\n\n[[Pub]]\nuuid = \"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"\ngit-tree-sha1 = \"9ebd50e2b0dd1e110e842df3b433cb5869b0dd38\"\nversion = \"2.1.4\"\n\n [Pub.deps]\n Priv = \"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\"\n Zebra = \"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"\n\n[[Zebra]]\nuuid = \"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"\ngit-tree-sha1 = \"e808e36a5d7173974b90a15a353b564f3494092f\"\nversion = \"3.4.2\"","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"This manifest file describes a possible complete dependency graph for the App project:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"There are two different packages named Priv that the application uses. It uses a private package, which is a root dependency, and a public one, which is an indirect dependency through Pub. These are differentiated by their distinct UUIDs, and they have different deps:\nThe private Priv depends on the Pub and Zebra packages.\nThe public Priv has no dependencies.\nThe application also depends on the Pub package, which in turn depends on the public Priv and the same Zebra package that the private Priv package depends on.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"This dependency graph represented as a dictionary, looks like this:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"graph = Dict(\n # Priv – the private one:\n UUID(\"ba13f791-ae1d-465a-978b-69c3ad90f72b\") => Dict(\n :Pub => UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"),\n :Zebra => UUID(\"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"),\n ),\n # Priv – the public one:\n UUID(\"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\") => Dict(),\n # Pub:\n UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\") => Dict(\n :Priv => UUID(\"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\"),\n :Zebra => UUID(\"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"),\n ),\n # Zebra:\n UUID(\"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\") => Dict(),\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Given this dependency graph, when Julia sees import Priv in the Pub package—which has UUID c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1—it looks up:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"graph[UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\")][:Priv]","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"and gets 2d15fe94-a1f7-436c-a4d8-07a9a496e01c, which indicates that in the context of the Pub package, import Priv refers to the public Priv package, rather than the private one which the app depends on directly. This is how the name Priv can refer to different packages in the main project than it does in one of its package's dependencies, which allows for duplicate names in the package ecosystem.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"What happens if import Zebra is evaluated in the main App code base? Since Zebra does not appear in the project file, the import will fail even though Zebra does appear in the manifest file. Moreover, if import Zebra occurs in the public Priv package—the one with UUID 2d15fe94-a1f7-436c-a4d8-07a9a496e01c—then that would also fail since that Priv package has no declared dependencies in the manifest file and therefore cannot load any packages. The Zebra package can only be loaded by packages for which it appear as an explicit dependency in the manifest file: the Pub package and one of the Priv packages.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The paths map of a project environment is extracted from the manifest file. The path of a package uuid named X is determined by these rules (in order):","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If the project file in the directory matches uuid and name X, then either:\nIt has a toplevel path entry, then uuid will be mapped to that path, interpreted relative to the directory containing the project file.\nOtherwise, uuid is mapped to src/X.jl relative to the directory containing the project file.\nIf the above is not the case and the project file has a corresponding manifest file and the manifest contains a stanza matching uuid then:\nIf it has a path entry, use that path (relative to the directory containing the manifest file).\nIf it has a git-tree-sha1 entry, compute a deterministic hash function of uuid and git-tree-sha1—call it slug—and look for a directory named packages/X/$slug in each directory in the Julia DEPOT_PATH global array. Use the first such directory that exists.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If any of these result in success, the path to the source code entry point will be either that result, the relative path from that result plus src/X.jl; otherwise, there is no path mapping for uuid. When loading X, if no source code path is found, the lookup will fail, and the user may be prompted to install the appropriate package version or to take other corrective action (e.g. declaring X as a dependency).","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"In the example manifest file above, to find the path of the first Priv package—the one with UUID ba13f791-ae1d-465a-978b-69c3ad90f72b—Julia looks for its stanza in the manifest file, sees that it has a path entry, looks at deps/Priv relative to the App project directory—let's suppose the App code lives in /home/me/projects/App—sees that /home/me/projects/App/deps/Priv exists and therefore loads Priv from there.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If, on the other hand, Julia was loading the other Priv package—the one with UUID 2d15fe94-a1f7-436c-a4d8-07a9a496e01c—it finds its stanza in the manifest, see that it does not have a path entry, but that it does have a git-tree-sha1 entry. It then computes the slug for this UUID/SHA-1 pair, which is HDkrT (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this Priv package will be packages/Priv/HDkrT/src/Priv.jl in one of the package depots. Suppose the contents of DEPOT_PATH is [\"/home/me/.julia\", \"/usr/local/julia\"], then Julia will look at the following paths to see if they exist:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"/home/me/.julia/packages/Priv/HDkrT\n/usr/local/julia/packages/Priv/HDkrT","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Julia uses the first of these that exists to try to load the public Priv package from the file packages/Priv/HDKrT/src/Priv.jl in the depot where it was found.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Here is a representation of a possible paths map for our example App project environment, as provided in the Manifest given above for the dependency graph, after searching the local file system:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"paths = Dict(\n # Priv – the private one:\n (UUID(\"ba13f791-ae1d-465a-978b-69c3ad90f72b\"), :Priv) =>\n # relative entry-point inside `App` repo:\n \"/home/me/projects/App/deps/Priv/src/Priv.jl\",\n # Priv – the public one:\n (UUID(\"2d15fe94-a1f7-436c-a4d8-07a9a496e01c\"), :Priv) =>\n # package installed in the system depot:\n \"/usr/local/julia/packages/Priv/HDkr/src/Priv.jl\",\n # Pub:\n (UUID(\"c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1\"), :Pub) =>\n # package installed in the user depot:\n \"/home/me/.julia/packages/Pub/oKpw/src/Pub.jl\",\n # Zebra:\n (UUID(\"f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62\"), :Zebra) =>\n # package installed in the system depot:\n \"/usr/local/julia/packages/Zebra/me9k/src/Zebra.jl\",\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"This example map includes three different kinds of package locations (the first and third are part of the default load path):","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The private Priv package is \"vendored\" inside the App repository.\nThe public Priv and Zebra packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system.\nThe Pub package is in the user depot, where packages installed by the user live. These are only available to the user who installed them.","category":"page"},{"location":"manual/code-loading/#Package-directories","page":"Code Loading","title":"Package directories","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Package directories provide a simpler kind of environment without the ability to handle name collisions. In a package directory, the set of top-level packages is the set of subdirectories that \"look like\" packages. A package X exists in a package directory if the directory contains one of the following \"entry point\" files:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"X.jl\nX/src/X.jl\nX.jl/src/X.jl","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Which dependencies a package in a package directory can import depends on whether the package contains a project file:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If it has a project file, it can only import those packages which are identified in the [deps] section of the project file.\nIf it does not have a project file, it can import any top-level package—i.e. the same packages that can be loaded in Main or the REPL.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The roots map is determined by examining the contents of the package directory to generate a list of all packages that exist. Additionally, a UUID will be assigned to each entry as follows: For a given package found inside the folder X...","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If X/Project.toml exists and has a uuid entry, then uuid is that value.\nIf X/Project.toml exists and but does not have a top-level UUID entry, uuid is a dummy UUID generated by hashing the canonical (real) path to X/Project.toml.\nOtherwise (if Project.toml does not exist), then uuid is the all-zero nil UUID.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The dependency graph of a project directory is determined by the presence and contents of project files in the subdirectory of each package. The rules are:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"If a package subdirectory has no project file, then it is omitted from graph and import statements in its code are treated as top-level, the same as the main project and REPL.\nIf a package subdirectory has a project file, then the graph entry for its UUID is the [deps] map of the project file, which is considered to be empty if the section is absent.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"As an example, suppose a package directory has the following structure and content:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Aardvark/\n src/Aardvark.jl:\n import Bobcat\n import Cobra\n\nBobcat/\n Project.toml:\n [deps]\n Cobra = \"4725e24d-f727-424b-bca0-c4307a3456fa\"\n Dingo = \"7a7925be-828c-4418-bbeb-bac8dfc843bc\"\n\n src/Bobcat.jl:\n import Cobra\n import Dingo\n\nCobra/\n Project.toml:\n uuid = \"4725e24d-f727-424b-bca0-c4307a3456fa\"\n [deps]\n Dingo = \"7a7925be-828c-4418-bbeb-bac8dfc843bc\"\n\n src/Cobra.jl:\n import Dingo\n\nDingo/\n Project.toml:\n uuid = \"7a7925be-828c-4418-bbeb-bac8dfc843bc\"\n\n src/Dingo.jl:\n # no imports","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Here is a corresponding roots structure, represented as a dictionary:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"roots = Dict(\n :Aardvark => UUID(\"00000000-0000-0000-0000-000000000000\"), # no project file, nil UUID\n :Bobcat => UUID(\"85ad11c7-31f6-5d08-84db-0a4914d4cadf\"), # dummy UUID based on path\n :Cobra => UUID(\"4725e24d-f727-424b-bca0-c4307a3456fa\"), # UUID from project file\n :Dingo => UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\"), # UUID from project file\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Here is the corresponding graph structure, represented as a dictionary:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"graph = Dict(\n # Bobcat:\n UUID(\"85ad11c7-31f6-5d08-84db-0a4914d4cadf\") => Dict(\n :Cobra => UUID(\"4725e24d-f727-424b-bca0-c4307a3456fa\"),\n :Dingo => UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\"),\n ),\n # Cobra:\n UUID(\"4725e24d-f727-424b-bca0-c4307a3456fa\") => Dict(\n :Dingo => UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\"),\n ),\n # Dingo:\n UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\") => Dict(),\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A few general rules to note:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A package without a project file can depend on any top-level dependency, and since every package in a package directory is available at the top-level, it can import all packages in the environment.\nA package with a project file cannot depend on one without a project file since packages with project files can only load packages in graph and packages without project files do not appear in graph.\nA package with a project file but no explicit UUID can only be depended on by packages without project files since dummy UUIDs assigned to these packages are strictly internal.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Observe the following specific instances of these rules in our example:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Aardvark can import on any of Bobcat, Cobra or Dingo; it does import Bobcat and Cobra.\nBobcat can and does import both Cobra and Dingo, which both have project files with UUIDs and are declared as dependencies in Bobcat's [deps] section.\nBobcat cannot depend on Aardvark since Aardvark does not have a project file.\nCobra can and does import Dingo, which has a project file and UUID, and is declared as a dependency in Cobra's [deps] section.\nCobra cannot depend on Aardvark or Bobcat since neither have real UUIDs.\nDingo cannot import anything because it has a project file without a [deps] section.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The paths map in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is /home/me/animals then the paths map could be represented by this dictionary:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"paths = Dict(\n (UUID(\"00000000-0000-0000-0000-000000000000\"), :Aardvark) =>\n \"/home/me/AnimalPackages/Aardvark/src/Aardvark.jl\",\n (UUID(\"85ad11c7-31f6-5d08-84db-0a4914d4cadf\"), :Bobcat) =>\n \"/home/me/AnimalPackages/Bobcat/src/Bobcat.jl\",\n (UUID(\"4725e24d-f727-424b-bca0-c4307a3456fa\"), :Cobra) =>\n \"/home/me/AnimalPackages/Cobra/src/Cobra.jl\",\n (UUID(\"7a7925be-828c-4418-bbeb-bac8dfc843bc\"), :Dingo) =>\n \"/home/me/AnimalPackages/Dingo/src/Dingo.jl\",\n)","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Since all packages in a package directory environment are, by definition, subdirectories with the expected entry-point files, their paths map entries always have this form.","category":"page"},{"location":"manual/code-loading/#Environment-stacks","page":"Code Loading","title":"Environment stacks","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The third and final kind of environment is one that combines other environments by overlaying several of them, making the packages in each available in a single composite environment. These composite environments are called environment stacks. The Julia LOAD_PATH global defines an environment stack—the environment in which the Julia process operates. If you want your Julia process to have access only to the packages in one project or package directory, make it the only entry in LOAD_PATH. It is often quite useful, however, to have access to some of your favorite tools—standard libraries, profilers, debuggers, personal utilities, etc.—even if they are not dependencies of the project you're working on. By adding an environment containing these tools to the load path, you immediately have access to them in top-level code without needing to add them to your project.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The mechanism for combining the roots, graph and paths data structures of the components of an environment stack is simple: they are merged as dictionaries, favoring earlier entries over later ones in the case of key collisions. In other words, if we have stack = [env₁, env₂, …] then we have:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"roots = reduce(merge, reverse([roots₁, roots₂, …]))\ngraph = reduce(merge, reverse([graph₁, graph₂, …]))\npaths = reduce(merge, reverse([paths₁, paths₂, …]))","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The subscripted rootsᵢ, graphᵢ and pathsᵢ variables correspond to the subscripted environments, envᵢ, contained in stack. The reverse is present because merge favors the last argument rather than first when there are collisions between keys in its argument dictionaries. There are a couple of noteworthy features of this design:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The primary environment—i.e. the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies.\nPackages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack (either by graph or path, or both).","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right trade-off: it's better to break your development tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project.","category":"page"},{"location":"manual/code-loading/#man-extensions","page":"Code Loading","title":"Package Extensions","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A package \"extension\" is a module that is automatically loaded when a specified set of other packages (its \"extension dependencies\") are loaded in the current Julia session. Extensions are defined under the [extensions] section in the project file. The extension dependencies of an extension are a subset of those packages listed under the [weakdeps] section of the project file. Those packages can have compat entries like other packages.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"name = \"MyPackage\"\n\n[compat]\nExtDep = \"1.0\"\nOtherExtDep = \"1.0\"\n\n[weakdeps]\nExtDep = \"c9a23...\" # uuid\nOtherExtDep = \"862e...\" # uuid\n\n[extensions]\nBarExt = [\"ExtDep\", \"OtherExtDep\"]\nFooExt = \"ExtDep\"\n...","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"The keys under extensions are the names of the extensions. They are loaded when all the packages on the right hand side (the extension dependencies) of that extension are loaded. If an extension only has one extension dependency the list of extension dependencies can be written as just a string for brevity. The location for the entry point of the extension is either in ext/FooExt.jl or ext/FooExt/FooExt.jl for extension FooExt. The content of an extension is often structured as:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"module FooExt\n\n# Load main package and extension dependencies\nusing MyPackage, ExtDep\n\n# Extend functionality in main package with types from the extension dependencies\nMyPackage.func(x::ExtDep.SomeStruct) = ...\n\nend","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"When a package with extensions is added to an environment, the weakdeps and extensions sections are stored in the manifest file in the section for that package. The dependency lookup rules for a package are the same as for its \"parent\" except that the listed extension dependencies are also considered as dependencies.","category":"page"},{"location":"manual/code-loading/#workspaces","page":"Code Loading","title":"Workspaces","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"A project file can define a workspace by giving a set of projects that is part of that workspace:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"[workspace]\nprojects = [\"test\", \"benchmarks\", \"docs\", \"SomePackage\"]","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Each subfolder contains its own Project.toml file, which may include additional dependencies and compatibility constraints. In such cases, the package manager gathers all dependency information from all the projects in the workspace generating a single manifest file that combines the versions of all dependencies.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Furthermore, workspaces can be \"nested\", meaning a project defining a workspace can also be part of another workspace. In this scenario, a single manifest file is still utilized, stored alongside the \"root project\" (the project that doesn't have another workspace including it). An example file structure could look like this:","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Project.toml # projects = [\"MyPackage\"]\nManifest.toml\nMyPackage/\n Project.toml # projects = [\"test\"]\n test/\n Project.toml","category":"page"},{"location":"manual/code-loading/#preferences","page":"Code Loading","title":"Package/Environment Preferences","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Preferences are dictionaries of metadata that influence package behavior within an environment. The preferences system supports reading preferences at compile-time, which means that at code-loading time, we must ensure that the precompilation files selected by Julia were built with the same preferences as the current environment before loading them. The public API for modifying Preferences is contained within the Preferences.jl package. Preferences are stored as TOML dictionaries within a (Julia)LocalPreferences.toml file next to the currently-active project. If a preference is \"exported\", it is instead stored within the (Julia)Project.toml instead. The intention is to allow shared projects to contain shared preferences, while allowing for users themselves to override those preferences with their own settings in the LocalPreferences.toml file, which should be .gitignored as the name implies.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Preferences that are accessed during compilation are automatically marked as compile-time preferences, and any change recorded to these preferences will cause the Julia compiler to recompile any cached precompilation file(s) (.ji and corresponding .so, .dll, or .dylib files) for that module. This is done by serializing the hash of all compile-time preferences during compilation, then checking that hash against the current environment when searching for the proper file(s) to load.","category":"page"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Preferences can be set with depot-wide defaults; if package Foo is installed within your global environment and it has preferences set, these preferences will apply as long as your global environment is part of your LOAD_PATH. Preferences in environments higher up in the environment stack get overridden by the more proximal entries in the load path, ending with the currently active project. This allows depot-wide preference defaults to exist, with active projects able to merge or even completely overwrite these inherited preferences. See the docstring for Preferences.set_preferences!() for the full details of how to set preferences to allow or disallow merging.","category":"page"},{"location":"manual/code-loading/#Conclusion","page":"Code Loading","title":"Conclusion","text":"","category":"section"},{"location":"manual/code-loading/","page":"Code Loading","title":"Code Loading","text":"Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Typically, Julia users should be able to use the built-in package manager to manage their projects without needing a precise understanding of these interactions. A call to Pkg.add(\"X\") will add to the appropriate project and manifest files, selected via Pkg.activate(\"Y\"), so that a future call to import X will load X without further thought.","category":"page"},{"location":"manual/mathematical-operations/#Mathematical-Operations-and-Elementary-Functions","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia provides a complete collection of basic arithmetic and bitwise operators across all of its numeric primitive types, as well as providing portable, efficient implementations of a comprehensive collection of standard mathematical functions.","category":"page"},{"location":"manual/mathematical-operations/#Arithmetic-Operators","page":"Mathematical Operations and Elementary Functions","title":"Arithmetic Operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The following arithmetic operators are supported on all primitive numeric types:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Expression Name Description\n+x unary plus the identity operation\n-x unary minus maps values to their additive inverses\nx + y binary plus performs addition\nx - y binary minus performs subtraction\nx * y times performs multiplication\nx / y divide performs division\nx ÷ y integer divide x / y, truncated to an integer\nx \\ y inverse divide equivalent to y / x\nx ^ y power raises x to the yth power\nx % y remainder equivalent to rem(x, y)","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"A numeric literal placed directly before an identifier or parentheses, e.g. 2x or 2(x + y), is treated as a multiplication, except with higher precedence than other binary operations. See Numeric Literal Coefficients for details.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia's promotion system makes arithmetic operations on mixtures of argument types \"just work\" naturally and automatically. See Conversion and Promotion for details of the promotion system.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The ÷ sign can be conveniently typed by writing \\div to the REPL or Julia IDE. See the manual section on Unicode input for more information.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Here are some simple examples using arithmetic operators:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> 1 + 2 + 3\n6\n\njulia> 1 - 2\n-1\n\njulia> 3*2/12\n0.5","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"(By convention, we tend to space operators more tightly if they get applied before other nearby operators. For instance, we would generally write -x + 2 to reflect that first x gets negated, and then 2 is added to that result.)","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"When used in multiplication, false acts as a strong zero:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> NaN * false\n0.0\n\njulia> false * Inf\n0.0","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"This is useful for preventing the propagation of NaN values in quantities that are known to be zero. See Knuth (1992) for motivation.","category":"page"},{"location":"manual/mathematical-operations/#Boolean-Operators","page":"Mathematical Operations and Elementary Functions","title":"Boolean Operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The following Boolean operators are supported on Bool types:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Expression Name\n!x negation\nx && y short-circuiting and\nx || y short-circuiting or","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Negation changes true to false and vice versa. The short-circuiting operations are explained on the linked page.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Note that Bool is an integer type and all the usual promotion rules and numeric operators are also defined on it.","category":"page"},{"location":"manual/mathematical-operations/#Bitwise-Operators","page":"Mathematical Operations and Elementary Functions","title":"Bitwise Operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The following bitwise operators are supported on all primitive integer types:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Expression Name\n~x bitwise not\nx & y bitwise and\nx | y bitwise or\nx ⊻ y bitwise xor (exclusive or)\nx ⊼ y bitwise nand (not and)\nx ⊽ y bitwise nor (not or)\nx >>> y logical shift right\nx >> y arithmetic shift right\nx << y logical/arithmetic shift left","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Here are some examples with bitwise operators:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> ~123\n-124\n\njulia> 123 & 234\n106\n\njulia> 123 | 234\n251\n\njulia> 123 ⊻ 234\n145\n\njulia> xor(123, 234)\n145\n\njulia> nand(123, 123)\n-124\n\njulia> 123 ⊼ 123\n-124\n\njulia> nor(123, 124)\n-128\n\njulia> 123 ⊽ 124\n-128\n\njulia> ~UInt32(123)\n0xffffff84\n\njulia> ~UInt8(123)\n0x84","category":"page"},{"location":"manual/mathematical-operations/#Updating-operators","page":"Mathematical Operations and Elementary Functions","title":"Updating operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Every binary arithmetic and bitwise operator also has an updating version that assigns the result of the operation back into its left operand. The updating version of the binary operator is formed by placing a = immediately after the operator. For example, writing x += 3 is equivalent to writing x = x + 3:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> x = 1\n1\n\njulia> x += 3\n4\n\njulia> x\n4","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The updating versions of all the binary arithmetic and bitwise operators are:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"+= -= *= /= \\= ÷= %= ^= &= |= ⊻= >>>= >>= <<=","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"note: Note\nAn updating operator rebinds the variable on the left-hand side. As a result, the type of the variable may change.julia> x = 0x01; typeof(x)\nUInt8\n\njulia> x *= 2 # Same as x = x * 2\n2\n\njulia> typeof(x)\nInt64","category":"page"},{"location":"manual/mathematical-operations/#man-dot-operators","page":"Mathematical Operations and Elementary Functions","title":"Vectorized \"dot\" operators","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"For every binary operation like ^, there is a corresponding \"dot\" operation .^ that is automatically defined to perform ^ element-by-element on arrays. For example, [1, 2, 3] ^ 3 is not defined, since there is no standard mathematical meaning to \"cubing\" a (non-square) array, but [1, 2, 3] .^ 3 is defined as computing the elementwise (or \"vectorized\") result [1^3, 2^3, 3^3]. Similarly for unary operators like ! or √, there is a corresponding .√ that applies the operator elementwise.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> [1, 2, 3] .^ 3\n3-element Vector{Int64}:\n 1\n 8\n 27","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"More specifically, a .^ b is parsed as the \"dot\" call (^).(a,b), which performs a broadcast operation: it can combine arrays and scalars, arrays of the same size (performing the operation elementwise), and even arrays of different shapes (e.g. combining row and column vectors to produce a matrix). Moreover, like all vectorized \"dot calls,\" these \"dot operators\" are fusing. For example, if you compute 2 .* A.^2 .+ sin.(A) (or equivalently @. 2A^2 + sin(A), using the @. macro) for an array A, it performs a single loop over A, computing 2a^2 + sin(a) for each element a of A. In particular, nested dot calls like f.(g.(x)) are fused, and \"adjacent\" binary operators like x .+ 3 .* x.^2 are equivalent to nested dot calls (+).(x, (*).(3, (^).(x, 2))).","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Furthermore, \"dotted\" updating operators like a .+= b (or @. a += b) are parsed as a .= a .+ b, where .= is a fused in-place assignment operation (see the dot syntax documentation).","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Note the dot syntax is also applicable to user-defined operators. For example, if you define ⊗(A, B) = kron(A, B) to give a convenient infix syntax A ⊗ B for Kronecker products (kron), then [A, B] .⊗ [C, D] will compute [A⊗C, B⊗D] with no additional coding.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Combining dot operators with numeric literals can be ambiguous. For example, it is not clear whether 1.+x means 1. + x or 1 .+ x. Therefore this syntax is disallowed, and spaces must be used around the operator in such cases.","category":"page"},{"location":"manual/mathematical-operations/#Numeric-Comparisons","page":"Mathematical Operations and Elementary Functions","title":"Numeric Comparisons","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Standard comparison operations are defined for all the primitive numeric types:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Operator Name\n== equality\n!=, ≠ inequality\n< less than\n<=, ≤ less than or equal to\n> greater than\n>=, ≥ greater than or equal to","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Here are some simple examples:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> 1 == 1\ntrue\n\njulia> 1 == 2\nfalse\n\njulia> 1 != 2\ntrue\n\njulia> 1 == 1.0\ntrue\n\njulia> 1 < 2\ntrue\n\njulia> 1.0 > 3\nfalse\n\njulia> 1 >= 1.0\ntrue\n\njulia> -1 <= 1\ntrue\n\njulia> -1 <= -1\ntrue\n\njulia> -1 <= -2\nfalse\n\njulia> 3 < -0.5\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Integers are compared in the standard manner – by comparison of bits. Floating-point numbers are compared according to the IEEE 754 standard:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Finite numbers are ordered in the usual manner.\nPositive zero is equal but not greater than negative zero.\nInf is equal to itself and greater than everything else except NaN.\n-Inf is equal to itself and less than everything else except NaN.\nNaN is not equal to, not less than, and not greater than anything, including itself.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The last point is potentially surprising and thus worth noting:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> NaN == NaN\nfalse\n\njulia> NaN != NaN\ntrue\n\njulia> NaN < NaN\nfalse\n\njulia> NaN > NaN\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"and can cause headaches when working with arrays:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> [1 NaN] == [1 NaN]\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia provides additional functions to test numbers for special values, which can be useful in situations like hash key comparisons:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Tests if\nisequal(x, y) x and y are identical\nisfinite(x) x is a finite number\nisinf(x) x is infinite\nisnan(x) x is not a number","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"isequal considers NaNs equal to each other:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> isequal(NaN, NaN)\ntrue\n\njulia> isequal([1 NaN], [1 NaN])\ntrue\n\njulia> isequal(NaN, NaN32)\ntrue","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"isequal can also be used to distinguish signed zeros:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> -0.0 == 0.0\ntrue\n\njulia> isequal(-0.0, 0.0)\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Mixed-type comparisons between signed integers, unsigned integers, and floats can be tricky. A great deal of care has been taken to ensure that Julia does them correctly.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"For other types, isequal defaults to calling ==, so if you want to define equality for your own types then you only need to add a == method. If you define your own equality function, you should probably define a corresponding hash method to ensure that isequal(x,y) implies hash(x) == hash(y).","category":"page"},{"location":"manual/mathematical-operations/#Chaining-comparisons","page":"Mathematical Operations and Elementary Functions","title":"Chaining comparisons","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Unlike most languages, with the notable exception of Python, comparisons can be arbitrarily chained:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5\ntrue","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Chaining comparisons is often quite convenient in numerical code. Chained comparisons use the && operator for scalar comparisons, and the & operator for elementwise comparisons, which allows them to work on arrays. For example, 0 .< A .< 1 gives a boolean array whose entries are true where the corresponding elements of A are between 0 and 1.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Note the evaluation behavior of chained comparisons:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> v(x) = (println(x); x)\nv (generic function with 1 method)\n\njulia> v(1) < v(2) <= v(3)\n2\n1\n3\ntrue\n\njulia> v(1) > v(2) <= v(3)\n2\n1\nfalse","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The middle expression is only evaluated once, rather than twice as it would be if the expression were written as v(1) < v(2) && v(2) <= v(3). However, the order of evaluations in a chained comparison is undefined. It is strongly recommended not to use expressions with side effects (such as printing) in chained comparisons. If side effects are required, the short-circuit && operator should be used explicitly (see Short-Circuit Evaluation).","category":"page"},{"location":"manual/mathematical-operations/#Elementary-Functions","page":"Mathematical Operations and Elementary Functions","title":"Elementary Functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia provides a comprehensive collection of mathematical functions and operators. These mathematical operations are defined over as broad a class of numerical values as permit sensible definitions, including integers, floating-point numbers, rationals, and complex numbers, wherever such definitions make sense.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Moreover, these functions (like any Julia function) can be applied in \"vectorized\" fashion to arrays and other collections with the dot syntax f.(A), e.g. sin.(A) will compute the sine of each element of an array A.","category":"page"},{"location":"manual/mathematical-operations/#Operator-Precedence-and-Associativity","page":"Mathematical Operations and Elementary Functions","title":"Operator Precedence and Associativity","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia applies the following order and associativity of operations, from highest precedence to lowest:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Category Operators Associativity\nSyntax . followed by :: Left\nExponentiation ^ Right\nUnary + - ! ~ ¬ √ ∛ ∜ ⋆ ± ∓ <: >: Right[1]\nBitshifts << >> >>> Left\nFractions // Left\nMultiplication * / % & \\ ÷ Left[2]\nAddition + - | ⊻ Left[2]\nSyntax : .. Left\nSyntax |> Left\nSyntax <| Right\nComparisons > < >= <= == === != !== <: Non-associative\nControl flow && followed by || followed by ? Right\nPair => Right\nAssignments = += -= *= /= //= \\= ^= ÷= %= |= &= ⊻= <<= >>= >>>= Right","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"[1]: The unary operators + and - require explicit parentheses around their argument to disambiguate them from the operator ++, etc. Other compositions of unary operators are parsed with right-associativity, e. g., √√-a as √(√(-a)).","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"[2]: The operators +, ++ and * are non-associative. a + b + c is parsed as +(a, b, c) not +(+(a, b), c). However, the fallback methods for +(a, b, c, d...) and *(a, b, c, d...) both default to left-associative evaluation.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"For a complete list of every Julia operator's precedence, see the top of this file: src/julia-parser.scm. Note that some of the operators there are not defined in the Base module but may be given definitions by standard libraries, packages or user code.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"You can also find the numerical precedence for any given operator via the built-in function Base.operator_precedence, where higher numbers take precedence:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.)\n(11, 12, 17)\n\njulia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.operator_precedence(:(=)) # (Note the necessary parens on `:(=)`)\n(0, 1, 1)","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"A symbol representing the operator associativity can also be found by calling the built-in function Base.operator_associativity:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> Base.operator_associativity(:-), Base.operator_associativity(:+), Base.operator_associativity(:^)\n(:left, :none, :right)\n\njulia> Base.operator_associativity(:⊗), Base.operator_associativity(:sin), Base.operator_associativity(:→)\n(:left, :none, :right)","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Note that symbols such as :sin return precedence 0. This value represents invalid operators and not operators of lowest precedence. Similarly, such operators are assigned associativity :none.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Numeric literal coefficients, e.g. 2x, are treated as multiplications with higher precedence than any other binary operation, with the exception of ^ where they have higher precedence only as the exponent.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> x = 3; 2x^2\n18\n\njulia> x = 3; 2^2x\n64","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Juxtaposition parses like a unary operator, which has the same natural asymmetry around exponents: -x^y and 2x^y parse as -(x^y) and 2(x^y) whereas x^-y and x^2y parse as x^(-y) and x^(2y).","category":"page"},{"location":"manual/mathematical-operations/#Numerical-Conversions","page":"Mathematical Operations and Elementary Functions","title":"Numerical Conversions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Julia supports three forms of numerical conversion, which differ in their handling of inexact conversions.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The notation T(x) or convert(T, x) converts x to a value of type T.\nIf T is a floating-point type, the result is the nearest representable value, which could be positive or negative infinity.\nIf T is an integer type, an InexactError is raised if x is not representable by T.\nx % T converts an integer x to a value of integer type T congruent to x modulo 2^n, where n is the number of bits in T. In other words, the binary representation is truncated to fit.\nThe Rounding functions take a type T as an optional argument. For example, round(Int,x) is a shorthand for Int(round(x)).","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"The following examples show the different forms.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"julia> Int8(127)\n127\n\njulia> Int8(128)\nERROR: InexactError: trunc(Int8, 128)\nStacktrace:\n[...]\n\njulia> Int8(127.0)\n127\n\njulia> Int8(3.14)\nERROR: InexactError: Int8(3.14)\nStacktrace:\n[...]\n\njulia> Int8(128.0)\nERROR: InexactError: Int8(128.0)\nStacktrace:\n[...]\n\njulia> 127 % Int8\n127\n\njulia> 128 % Int8\n-128\n\njulia> round(Int8,127.4)\n127\n\njulia> round(Int8,127.6)\nERROR: InexactError: Int8(128.0)\nStacktrace:\n[...]","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"See Conversion and Promotion for how to define your own conversions and promotions.","category":"page"},{"location":"manual/mathematical-operations/#Rounding-functions","page":"Mathematical Operations and Elementary Functions","title":"Rounding functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Description Return type\nround(x) round x to the nearest integer typeof(x)\nround(T, x) round x to the nearest integer T\nfloor(x) round x towards -Inf typeof(x)\nfloor(T, x) round x towards -Inf T\nceil(x) round x towards +Inf typeof(x)\nceil(T, x) round x towards +Inf T\ntrunc(x) round x towards zero typeof(x)\ntrunc(T, x) round x towards zero T","category":"page"},{"location":"manual/mathematical-operations/#Division-functions","page":"Mathematical Operations and Elementary Functions","title":"Division functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Description\ndiv(x, y), x÷y truncated division; quotient rounded towards zero\nfld(x, y) floored division; quotient rounded towards -Inf\ncld(x, y) ceiling division; quotient rounded towards +Inf\nrem(x, y), x%y remainder; satisfies x == div(x, y)*y + rem(x, y); sign matches x\nmod(x, y) modulus; satisfies x == fld(x, y)*y + mod(x, y); sign matches y\nmod1(x, y) mod with offset 1; returns r∈(0, y] for y>0 or r∈[y, 0) for y<0, where mod(r, y) == mod(x, y)\nmod2pi(x) modulus with respect to 2pi; 0 <= mod2pi(x) < 2pi\ndivrem(x, y) returns (div(x, y),rem(x, y))\nfldmod(x, y) returns (fld(x, y), mod(x, y))\ngcd(x, y...) greatest positive common divisor of x, y,...\nlcm(x, y...) least positive common multiple of x, y,...","category":"page"},{"location":"manual/mathematical-operations/#Sign-and-absolute-value-functions","page":"Mathematical Operations and Elementary Functions","title":"Sign and absolute value functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Description\nabs(x) a positive value with the magnitude of x\nabs2(x) the squared magnitude of x\nsign(x) indicates the sign of x, returning -1, 0, or +1\nsignbit(x) indicates whether the sign bit is on (true) or off (false)\ncopysign(x, y) a value with the magnitude of x and the sign of y\nflipsign(x, y) a value with the magnitude of x and the sign of x*y","category":"page"},{"location":"manual/mathematical-operations/#Powers,-logs-and-roots","page":"Mathematical Operations and Elementary Functions","title":"Powers, logs and roots","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Function Description\nsqrt(x), √x square root of x\ncbrt(x), ∛x cube root of x\nhypot(x, y) hypotenuse of right-angled triangle with other sides of length x and y\nexp(x) natural exponential function at x\nexpm1(x) accurate exp(x) - 1 for x near zero\nldexp(x, n) x * 2^n computed efficiently for integer values of n\nlog(x) natural logarithm of x\nlog(b, x) base b logarithm of x\nlog2(x) base 2 logarithm of x\nlog10(x) base 10 logarithm of x\nlog1p(x) accurate log(1 + x) for x near zero\nexponent(x) binary exponent of x\nsignificand(x) binary significand (a.k.a. mantissa) of a floating-point number x","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"For an overview of why functions like hypot, expm1, and log1p are necessary and useful, see John D. Cook's excellent pair of blog posts on the subject: expm1, log1p, erfc, and hypot.","category":"page"},{"location":"manual/mathematical-operations/#Trigonometric-and-hyperbolic-functions","page":"Mathematical Operations and Elementary Functions","title":"Trigonometric and hyperbolic functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"All the standard trigonometric and hyperbolic functions are also defined:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"sin cos tan cot sec csc\nsinh cosh tanh coth sech csch\nasin acos atan acot asec acsc\nasinh acosh atanh acoth asech acsch\nsinc cosc","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"These are all single-argument functions, with atan also accepting two arguments corresponding to a traditional atan2 function.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Additionally, sinpi(x) and cospi(x) are provided for more accurate computations of sin(pi * x) and cos(pi * x) respectively.","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"In order to compute trigonometric functions with degrees instead of radians, suffix the function with d. For example, sind(x) computes the sine of x where x is specified in degrees. The complete list of trigonometric functions with degree variants is:","category":"page"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"sind cosd tand cotd secd cscd\nasind acosd atand acotd asecd acscd","category":"page"},{"location":"manual/mathematical-operations/#Special-functions","page":"Mathematical Operations and Elementary Functions","title":"Special functions","text":"","category":"section"},{"location":"manual/mathematical-operations/","page":"Mathematical Operations and Elementary Functions","title":"Mathematical Operations and Elementary Functions","text":"Many other special mathematical functions are provided by the package SpecialFunctions.jl.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Calling-C-and-Fortran-Code","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Though most code can be written in Julia, there are many high-quality, mature libraries for numerical computing already written in C and Fortran. To allow easy use of this existing code, Julia makes it simple and efficient to call C and Fortran functions. Julia has a \"no boilerplate\" philosophy: functions can be called directly from Julia without any \"glue\" code, code generation, or compilation – even from the interactive prompt. This is accomplished just by making an appropriate call with the @ccall macro (or the less convenient ccall syntax, see the ccall syntax section).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The code to be called must be available as a shared library. Most C and Fortran libraries ship compiled as shared libraries already, but if you are compiling the code yourself using GCC (or Clang), you will need to use the -shared and -fPIC options. The machine instructions generated by Julia's JIT are the same as a native C call would be, so the resulting overhead is the same as calling a library function from C code. [1]","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"By default, Fortran compilers generate mangled names (for example, converting function names to lowercase or uppercase, often appending an underscore), and so to call a Fortran function you must pass the mangled identifier corresponding to the rule followed by your Fortran compiler. Also, when calling a Fortran function, all inputs must be passed as pointers to allocated values on the heap or stack. This applies not only to arrays and other mutable objects which are normally heap-allocated, but also to scalar values such as integers and floats which are normally stack-allocated and commonly passed in registers when using C or Julia calling conventions.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The syntax for @ccall to generate a call to the library function is:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":" @ccall library.function_name(argvalue1::argtype1, ...)::returntype\n @ccall function_name(argvalue1::argtype1, ...)::returntype\n @ccall $function_pointer(argvalue1::argtype1, ...)::returntype","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"where library is a string constant or literal (but see Non-constant Function Specifications below). The library may be omitted, in which case the function name is resolved in the current process. This form can be used to call C library functions, functions in the Julia runtime, or functions in an application linked to Julia. The full path to the library may also be specified. Alternatively, @ccall may also be used to call a function pointer $function_pointer, such as one returned by Libdl.dlsym. The argtypes corresponds to the C-function signature and the argvalues are the actual argument values to be passed to the function.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nSee below for how to map C types to Julia types.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"As a complete but simple example, the following calls the clock function from the standard C library on most Unix-derived systems:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> t = @ccall clock()::Int32\n2292761\n\njulia> typeof(t)\nInt32","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"clock takes no arguments and returns an Int32. To call the getenv function to get a pointer to the value of an environment variable, one makes a call like this:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> path = @ccall getenv(\"SHELL\"::Cstring)::Cstring\nCstring(@0x00007fff5fbffc45)\n\njulia> unsafe_string(path)\n\"/bin/bash\"","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In practice, especially when providing reusable functionality, one generally wraps @ccall uses in Julia functions that set up arguments and then check for errors in whatever manner the C or Fortran function specifies. And if an error occurs it is thrown as a normal Julia exception. This is especially important since C and Fortran APIs are notoriously inconsistent about how they indicate error conditions. For example, the getenv C library function is wrapped in the following Julia function, which is a simplified version of the actual definition from env.jl:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"function getenv(var::AbstractString)\n val = @ccall getenv(var::Cstring)::Cstring\n if val == C_NULL\n error(\"getenv: undefined variable: \", var)\n end\n return unsafe_string(val)\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The C getenv function indicates an error by returning C_NULL, but other standard C functions indicate errors in different ways, including by returning -1, 0, 1, and other special values. This wrapper throws an exception indicating the problem if the caller tries to get a non-existent environment variable:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> getenv(\"SHELL\")\n\"/bin/bash\"\n\njulia> getenv(\"FOOBAR\")\nERROR: getenv: undefined variable: FOOBAR","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Here is a slightly more complex example that discovers the local machine's hostname.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"function gethostname()\n hostname = Vector{UInt8}(undef, 256) # MAXHOSTNAMELEN\n err = @ccall gethostname(hostname::Ptr{UInt8}, sizeof(hostname)::Csize_t)::Int32\n Base.systemerror(\"gethostname\", err != 0)\n hostname[end] = 0 # ensure null-termination\n return GC.@preserve hostname unsafe_string(pointer(hostname))\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"This example first allocates an array of bytes. It then calls the C library function gethostname to populate the array with the hostname. Finally, it takes a pointer to the hostname buffer, and converts the pointer to a Julia string, assuming that it is a null-terminated C string.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"It is common for C libraries to use this pattern of requiring the caller to allocate memory to be passed to the callee and populated. Allocation of memory from Julia like this is generally accomplished by creating an uninitialized array and passing a pointer to its data to the C function. This is why we don't use the Cstring type here: as the array is uninitialized, it could contain null bytes. Converting to a Cstring as part of the @ccall checks for contained null bytes and could therefore throw a conversion error.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Dereferencing pointer(hostname) with unsafe_string is an unsafe operation as it requires access to the memory allocated for hostname that may have been in the meanwhile garbage collected. The macro GC.@preserve prevents this from happening and therefore accessing an invalid memory location.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Finally, here is an example of specifying a library via a path. We create a shared library with the following content","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"#include \n\nvoid say_y(int y)\n{\n printf(\"Hello from C: got y = %d.\\n\", y);\n}","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"and compile it with gcc -fPIC -shared -o mylib.so mylib.c. It can then be called by specifying the (absolute) path as the library name:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> @ccall \"./mylib.so\".say_y(5::Cint)::Cvoid\nHello from C: got y = 5.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Creating-C-Compatible-Julia-Function-Pointers","page":"Calling C and Fortran Code","title":"Creating C-Compatible Julia Function Pointers","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"It is possible to pass Julia functions to native C functions that accept function pointer arguments. For example, to match C prototypes of the form:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"typedef returntype (*functiontype)(argumenttype, ...)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The macro @cfunction generates the C-compatible function pointer for a call to a Julia function. The arguments to @cfunction are:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"A Julia function\nThe function's return type\nA tuple of input types, corresponding to the function signature","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nAs with @ccall, the return type and the input types must be literal constants.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nCurrently, only the platform-default C calling convention is supported. This means that @cfunction-generated pointers cannot be used in calls where WINAPI expects a stdcall function on 32-bit Windows, but can be used on WIN64 (where stdcall is unified with the C calling convention).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nCallback functions exposed via @cfunction should not throw errors, as that will return control to the Julia runtime unexpectedly and may leave the program in an undefined state.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"A classic example is the standard C library qsort function, declared as:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"void qsort(void *base, size_t nitems, size_t size,\n int (*compare)(const void*, const void*));","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The base argument is a pointer to an array of length nitems, with elements of size bytes each. compare is a callback function which takes pointers to two elements a and b and returns an integer less/greater than zero if a should appear before/after b (or zero if any order is permitted).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Now, suppose that we have a 1-d array A of values in Julia that we want to sort using the qsort function (rather than Julia's built-in sort function). Before we consider calling qsort and passing arguments, we need to write a comparison function:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> function mycompare(a, b)::Cint\n return (a < b) ? -1 : ((a > b) ? +1 : 0)\n end;","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"qsort expects a comparison function that return a C int, so we annotate the return type to be Cint.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In order to pass this function to C, we obtain its address using the macro @cfunction:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> mycompare_c = @cfunction(mycompare, Cint, (Ref{Cdouble}, Ref{Cdouble}));","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"@cfunction requires three arguments: the Julia function (mycompare), the return type (Cint), and a literal tuple of the input argument types, in this case to sort an array of Cdouble (Float64) elements.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The final call to qsort looks like this:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> A = [1.3, -2.7, 4.4, 3.1];\n\njulia> @ccall qsort(A::Ptr{Cdouble}, length(A)::Csize_t, sizeof(eltype(A))::Csize_t, mycompare_c::Ptr{Cvoid})::Cvoid\n\njulia> A\n4-element Vector{Float64}:\n -2.7\n 1.3\n 3.1\n 4.4","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"As the example shows, the original Julia array A has now been sorted: [-2.7, 1.3, 3.1, 4.4]. Note that Julia takes care of converting the array to a Ptr{Cdouble}), computing the size of the element type in bytes, and so on.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For fun, try inserting a println(\"mycompare($a, $b)\") line into mycompare, which will allow you to see the comparisons that qsort is performing (and to verify that it is really calling the Julia function that you passed to it).","category":"page"},{"location":"manual/calling-c-and-fortran-code/#mapping-c-types-to-julia","page":"Calling C and Fortran Code","title":"Mapping C Types to Julia","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"It is critical to exactly match the declared C type with its declaration in Julia. Inconsistencies can cause code that works correctly on one system to fail or produce indeterminate results on a different system.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Note that no C header files are used anywhere in the process of calling C functions: you are responsible for making sure that your Julia types and call signatures accurately reflect those in the C header file.[2]","category":"page"},{"location":"manual/calling-c-and-fortran-code/#automatic-type-conversion","page":"Calling C and Fortran Code","title":"Automatic Type Conversion","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Julia automatically inserts calls to the Base.cconvert function to convert each argument to the specified type. For example, the following call:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"@ccall \"libfoo\".foo(x::Int32, y::Float64)::Cvoid","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"will behave as if it were written like this:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"c_x = Base.cconvert(Int32, x)\nc_y = Base.cconvert(Float64, y)\nGC.@preserve c_x c_y begin\n @ccall \"libfoo\".foo(\n Base.unsafe_convert(Int32, c_x)::Int32,\n Base.unsafe_convert(Float64, c_y)::Float64\n )::Cvoid\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Base.cconvert normally just calls convert, but can be defined to return an arbitrary new object more appropriate for passing to C. This should be used to perform all allocations of memory that will be accessed by the C code. For example, this is used to convert an Array of objects (e.g. strings) to an array of pointers.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Base.unsafe_convert handles conversion to Ptr types. It is considered unsafe because converting an object to a native pointer can hide the object from the garbage collector, causing it to be freed prematurely.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Type-Correspondences","page":"Calling C and Fortran Code","title":"Type Correspondences","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"First, let's review some relevant Julia type terminology:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Syntax / Keyword Example Description\nmutable struct BitSet \"Leaf Type\" :: A group of related data that includes a type-tag, is managed by the Julia GC, and is defined by object-identity. The type parameters of a leaf type must be fully defined (no TypeVars are allowed) in order for the instance to be constructed.\nabstract type Any, AbstractArray{T, N}, Complex{T} \"Super Type\" :: A super-type (not a leaf-type) that cannot be instantiated, but can be used to describe a group of types.\nT{A} Vector{Int} \"Type Parameter\" :: A specialization of a type (typically used for dispatch or storage optimization).\n \"TypeVar\" :: The T in the type parameter declaration is referred to as a TypeVar (short for type variable).\nprimitive type Int, Float64 \"Primitive Type\" :: A type with no fields, but a size. It is stored and defined by-value.\nstruct Pair{Int, Int} \"Struct\" :: A type with all fields defined to be constant. It is defined by-value, and may be stored with a type-tag.\n ComplexF64 (isbits) \"Is-Bits\" :: A primitive type, or a struct type where all fields are other isbits types. It is defined by-value, and is stored without a type-tag.\nstruct ...; end nothing \"Singleton\" :: a Leaf Type or Struct with no fields.\n(...) or tuple(...) (1, 2, 3) \"Tuple\" :: an immutable data-structure similar to an anonymous struct type, or a constant array. Represented as either an array or a struct.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#man-bits-types","page":"Calling C and Fortran Code","title":"Bits Types","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"There are several special types to be aware of, as no other type can be defined to behave the same:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Float32\nExactly corresponds to the float type in C (or REAL*4 in Fortran).\nFloat64\nExactly corresponds to the double type in C (or REAL*8 in Fortran).\nComplexF32\nExactly corresponds to the complex float type in C (or COMPLEX*8 in Fortran).\nComplexF64\nExactly corresponds to the complex double type in C (or COMPLEX*16 in Fortran).\nSigned\nExactly corresponds to the signed type annotation in C (or any INTEGER type in Fortran). Any Julia type that is not a subtype of Signed is assumed to be unsigned.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Ref{T}\nBehaves like a Ptr{T} that can manage its memory via the Julia GC.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Array{T,N}\nWhen an array is passed to C as a Ptr{T} argument, it is not reinterpret-cast: Julia requires that the element type of the array matches T, and the address of the first element is passed.\nTherefore, if an Array contains data in the wrong format, it will have to be explicitly converted using a call such as trunc.(Int32, A).\nTo pass an array A as a pointer of a different type without converting the data beforehand (for example, to pass a Float64 array to a function that operates on uninterpreted bytes), you can declare the argument as Ptr{Cvoid}.\nIf an array of eltype Ptr{T} is passed as a Ptr{Ptr{T}} argument, Base.cconvert will attempt to first make a null-terminated copy of the array with each element replaced by its Base.cconvert version. This allows, for example, passing an argv pointer array of type Vector{String} to an argument of type Ptr{Ptr{Cchar}}.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"On all systems we currently support, basic C/C++ value types may be translated to Julia types as follows. Every C type also has a corresponding Julia type with the same name, prefixed by C. This can help when writing portable code (and remembering that an int in C is not the same as an Int in Julia).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"System Independent Types","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"C name Fortran name Standard Julia Alias Julia Base Type\nunsigned char CHARACTER Cuchar UInt8\nbool (_Bool in C99+) Cuchar UInt8\nshort INTEGER*2, LOGICAL*2 Cshort Int16\nunsigned short Cushort UInt16\nint, BOOL (C, typical) INTEGER*4, LOGICAL*4 Cint Int32\nunsigned int Cuint UInt32\nlong long INTEGER*8, LOGICAL*8 Clonglong Int64\nunsigned long long Culonglong UInt64\nintmax_t Cintmax_t Int64\nuintmax_t Cuintmax_t UInt64\nfloat REAL*4i Cfloat Float32\ndouble REAL*8 Cdouble Float64\ncomplex float COMPLEX*8 ComplexF32 Complex{Float32}\ncomplex double COMPLEX*16 ComplexF64 Complex{Float64}\nptrdiff_t Cptrdiff_t Int\nssize_t Cssize_t Int\nsize_t Csize_t UInt\nvoid Cvoid\nvoid and [[noreturn]] or _Noreturn Union{}\nvoid* Ptr{Cvoid} (or similarly Ref{Cvoid})\nT* (where T represents an appropriately defined type) Ref{T} (T may be safely mutated only if T is an isbits type)\nchar* (or char[], e.g. a string) CHARACTER*N Cstring if null-terminated, or Ptr{UInt8} if not\nchar** (or *char[]) Ptr{Ptr{UInt8}}\njl_value_t* (any Julia Type) Any\njl_value_t* const* (a reference to a Julia value) Ref{Any} (const, since mutation would require a write barrier, which is not possible to insert correctly)\nva_arg Not supported\n... (variadic function specification) T... (where T is one of the above types, when using the ccall function)\n... (variadic function specification) ; va_arg1::T, va_arg2::S, etc. (only supported with @ccall macro)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The Cstring type is essentially a synonym for Ptr{UInt8}, except the conversion to Cstring throws an error if the Julia string contains any embedded null characters (which would cause the string to be silently truncated if the C routine treats null as the terminator). If you are passing a char* to a C routine that does not assume null termination (e.g. because you pass an explicit string length), or if you know for certain that your Julia string does not contain null and want to skip the check, you can use Ptr{UInt8} as the argument type. Cstring can also be used as the ccall return type, but in that case it obviously does not introduce any extra checks and is only meant to improve the readability of the call.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"System Dependent Types","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"C name Standard Julia Alias Julia Base Type\nchar Cchar Int8 (x86, x86_64), UInt8 (powerpc, arm)\nlong Clong Int (UNIX), Int32 (Windows)\nunsigned long Culong UInt (UNIX), UInt32 (Windows)\nwchar_t Cwchar_t Int32 (UNIX), UInt16 (Windows)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nWhen calling Fortran, all inputs must be passed by pointers to heap- or stack-allocated values, so all type correspondences above should contain an additional Ptr{..} or Ref{..} wrapper around their type specification.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"warning: Warning\nFor string arguments (char*) the Julia type should be Cstring (if null-terminated data is expected), or either Ptr{Cchar} or Ptr{UInt8} otherwise (these two pointer types have the same effect), as described above, not String. Similarly, for array arguments (T[] or T*), the Julia type should again be Ptr{T}, not Vector{T}.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"warning: Warning\nJulia's Char type is 32 bits, which is not the same as the wide-character type (wchar_t or wint_t) on all platforms.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"warning: Warning\nA return type of Union{} means the function will not return, i.e., C++11 [[noreturn]] or C11 _Noreturn (e.g. jl_throw or longjmp). Do not use this for functions that return no value (void) but do return, for those, use Cvoid instead.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nFor wchar_t* arguments, the Julia type should be Cwstring (if the C routine expects a null-terminated string), or Ptr{Cwchar_t} otherwise. Note also that UTF-8 string data in Julia is internally null-terminated, so it can be passed to C functions expecting null-terminated data without making a copy (but using the Cwstring type will cause an error to be thrown if the string itself contains null characters).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nC functions that take an argument of type char** can be called by using a Ptr{Ptr{UInt8}} type within Julia. For example, C functions of the form:int main(int argc, char **argv);can be called via the following Julia code:argv = [ \"a.out\", \"arg1\", \"arg2\" ]\n@ccall main(length(argv)::Int32, argv::Ptr{Ptr{UInt8}})::Int32","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nFor Fortran functions taking variable length strings of type character(len=*) the string lengths are provided as hidden arguments. Type and position of these arguments in the list are compiler specific, where compiler vendors usually default to using Csize_t as type and append the hidden arguments at the end of the argument list. While this behaviour is fixed for some compilers (GNU), others optionally permit placing hidden arguments directly after the character argument (Intel, PGI). For example, Fortran subroutines of the formsubroutine test(str1, str2)\ncharacter(len=*) :: str1,str2can be called via the following Julia code, where the lengths are appendedstr1 = \"foo\"\nstr2 = \"bar\"\nccall(:test, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Csize_t, Csize_t),\n str1, str2, sizeof(str1), sizeof(str2))","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"warning: Warning\nFortran compilers may also add other hidden arguments for pointers, assumed-shape (:) and assumed-size (*) arrays. Such behaviour can be avoided by using ISO_C_BINDING and including bind(c) in the definition of the subroutine, which is strongly recommended for interoperable code. In this case, there will be no hidden arguments, at the cost of some language features (e.g. only character(len=1) will be permitted to pass strings).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nA C function declared to return Cvoid will return the value nothing in Julia.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Struct-Type-Correspondences","page":"Calling C and Fortran Code","title":"Struct Type Correspondences","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Composite types such as struct in C or TYPE in Fortran90 (or STRUCTURE / RECORD in some variants of F77), can be mirrored in Julia by creating a struct definition with the same field layout.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"When used recursively, isbits types are stored inline. All other types are stored as a pointer to the data. When mirroring a struct used by-value inside another struct in C, it is imperative that you do not attempt to manually copy the fields over, as this will not preserve the correct field alignment. Instead, declare an isbits struct type and use that instead. Unnamed structs are not possible in the translation to Julia.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Packed structs and union declarations are not supported by Julia.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"You can get an approximation of a union if you know, a priori, the field that will have the greatest size (potentially including padding). When translating your fields to Julia, declare the Julia field to be only of that type.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Arrays of parameters can be expressed with NTuple. For example, the struct in C notation is written as","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"struct B {\n int A[3];\n};\n\nb_a_2 = B.A[2];","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"can be written in Julia as","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"struct B\n A::NTuple{3, Cint}\nend\n\nb_a_2 = B.A[3] # note the difference in indexing (1-based in Julia, 0-based in C)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Arrays of unknown size (C99-compliant variable length structs specified by [] or [0]) are not directly supported. Often the best way to deal with these is to deal with the byte offsets directly. For example, if a C library declared a proper string type and returned a pointer to it:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"struct String {\n int strlen;\n char data[];\n};","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In Julia, we can access the parts independently to make a copy of that string:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"str = from_c::Ptr{Cvoid}\nlen = unsafe_load(Ptr{Cint}(str))\nunsafe_string(str + Core.sizeof(Cint), len)","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Type-Parameters","page":"Calling C and Fortran Code","title":"Type Parameters","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The type arguments to @ccall and @cfunction are evaluated statically, when the method containing the usage is defined. They therefore must take the form of a literal tuple, not a variable, and cannot reference local variables.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"This may sound like a strange restriction, but remember that since C is not a dynamic language like Julia, its functions can only accept argument types with a statically-known, fixed signature.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"However, while the type layout must be known statically to compute the intended C ABI, the static parameters of the function are considered to be part of this static environment. The static parameters of the function may be used as type parameters in the call signature, as long as they don't affect the layout of the type. For example, f(x::T) where {T} = @ccall valid(x::Ptr{T})::Ptr{T} is valid, since Ptr is always a word-size primitive type. But, g(x::T) where {T} = @ccall notvalid(x::T)::T is not valid, since the type layout of T is not known statically.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#SIMD-Values","page":"Calling C and Fortran Code","title":"SIMD Values","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Note: This feature is currently implemented on 64-bit x86 and AArch64 platforms only.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"If a C/C++ routine has an argument or return value that is a native SIMD type, the corresponding Julia type is a homogeneous tuple of VecElement that naturally maps to the SIMD type. Specifically:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The tuple must be the same size as the SIMD type. For example, a tuple representing an __m128 on x86 must have a size of 16 bytes.\nThe element type of the tuple must be an instance of VecElement{T} where T is a primitive type that is 1, 2, 4 or 8 bytes.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For instance, consider this C routine that uses AVX intrinsics:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"#include \n\n__m256 dist( __m256 a, __m256 b ) {\n return _mm256_sqrt_ps(_mm256_add_ps(_mm256_mul_ps(a, a),\n _mm256_mul_ps(b, b)));\n}","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The following Julia code calls dist using ccall:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"const m256 = NTuple{8, VecElement{Float32}}\n\na = m256(ntuple(i -> VecElement(sin(Float32(i))), 8))\nb = m256(ntuple(i -> VecElement(cos(Float32(i))), 8))\n\nfunction call_dist(a::m256, b::m256)\n @ccall \"libdist\".dist(a::m256, b::m256)::m256\nend\n\nprintln(call_dist(a,b))","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The host machine must have the requisite SIMD registers. For example, the code above will not work on hosts without AVX support.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Memory-Ownership","page":"Calling C and Fortran Code","title":"Memory Ownership","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"malloc/free","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Memory allocation and deallocation of such objects must be handled by calls to the appropriate cleanup routines in the libraries being used, just like in any C program. Do not try to free an object received from a C library with Libc.free in Julia, as this may result in the free function being called via the wrong library and cause the process to abort. The reverse (passing an object allocated in Julia to be freed by an external library) is equally invalid.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#When-to-use-T,-Ptr{T}-and-Ref{T}","page":"Calling C and Fortran Code","title":"When to use T, Ptr{T} and Ref{T}","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In Julia code wrapping calls to external C routines, ordinary (non-pointer) data should be declared to be of type T inside the @ccall, as they are passed by value. For C code accepting pointers, Ref{T} should generally be used for the types of input arguments, allowing the use of pointers to memory managed by either Julia or C through the implicit call to Base.cconvert. In contrast, pointers returned by the C function called should be declared to be of the output type Ptr{T}, reflecting that the memory pointed to is managed by C only. Pointers contained in C structs should be represented as fields of type Ptr{T} within the corresponding Julia struct types designed to mimic the internal structure of corresponding C structs.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In Julia code wrapping calls to external Fortran routines, all input arguments should be declared as of type Ref{T}, as Fortran passes all variables by pointers to memory locations. The return type should either be Cvoid for Fortran subroutines, or a T for Fortran functions returning the type T.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Mapping-C-Functions-to-Julia","page":"Calling C and Fortran Code","title":"Mapping C Functions to Julia","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/#@ccall-/-@cfunction-argument-translation-guide","page":"Calling C and Fortran Code","title":"@ccall / @cfunction argument translation guide","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For translating a C argument list to Julia:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"T, where T is one of the primitive types: char, int, long, short, float, double, complex, enum or any of their typedef equivalents\nT, where T is an equivalent Julia Bits Type (per the table above)\nif T is an enum, the argument type should be equivalent to Cint or Cuint\nargument value will be copied (passed by value)\nstruct T (including typedef to a struct)\nT, where T is a Julia leaf type\nargument value will be copied (passed by value)\nvoid*\ndepends on how this parameter is used, first translate this to the intended pointer type, then determine the Julia equivalent using the remaining rules in this list\nthis argument may be declared as Ptr{Cvoid} if it really is just an unknown pointer\njl_value_t*\nAny\nargument value must be a valid Julia object\njl_value_t* const*\nRef{Any}\nargument list must be a valid Julia object (or C_NULL)\ncannot be used for an output parameter, unless the user is able to separately arrange for the object to be GC-preserved\nT*\nRef{T}, where T is the Julia type corresponding to T\nargument value will be copied if it is an inlinealloc type (which includes isbits otherwise, the value must be a valid Julia object\nT (*)(...) (e.g. a pointer to a function)\nPtr{Cvoid} (you may need to use @cfunction explicitly to create this pointer)\n... (e.g. a vararg)\n[for ccall]: T..., where T is the single Julia type of all remaining arguments\n[for @ccall]: ; va_arg1::T, va_arg2::S, etc, where T and S are the Julia type (i.e. separate the regular arguments from varargs with a ;)\ncurrently unsupported by @cfunction\nva_arg\nnot supported by ccall or @cfunction","category":"page"},{"location":"manual/calling-c-and-fortran-code/#@ccall-/-@cfunction-return-type-translation-guide","page":"Calling C and Fortran Code","title":"@ccall / @cfunction return type translation guide","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For translating a C return type to Julia:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"void\nCvoid (this will return the singleton instance nothing::Cvoid)\nT, where T is one of the primitive types: char, int, long, short, float, double, complex, enum or any of their typedef equivalents\nT, where T is an equivalent Julia Bits Type (per the table above)\nif T is an enum, the argument type should be equivalent to Cint or Cuint\nargument value will be copied (returned by-value)\nstruct T (including typedef to a struct)\nT, where T is a Julia Leaf Type\nargument value will be copied (returned by-value)\nvoid*\ndepends on how this parameter is used, first translate this to the intended pointer type, then determine the Julia equivalent using the remaining rules in this list\nthis argument may be declared as Ptr{Cvoid} if it really is just an unknown pointer\njl_value_t*\nAny\nargument value must be a valid Julia object\njl_value_t**\nPtr{Any} (Ref{Any} is invalid as a return type)\nT*\nIf the memory is already owned by Julia, or is an isbits type, and is known to be non-null:\nRef{T}, where T is the Julia type corresponding to T\na return type of Ref{Any} is invalid, it should either be Any (corresponding to jl_value_t*) or Ptr{Any} (corresponding to jl_value_t**)\nC MUST NOT modify the memory returned via Ref{T} if T is an isbits type\nIf the memory is owned by C:\nPtr{T}, where T is the Julia type corresponding to T\nT (*)(...) (e.g. a pointer to a function)\nPtr{Cvoid} to call this directly from Julia you will need to pass this as the first argument to @ccall. See Indirect Calls.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Passing-Pointers-for-Modifying-Inputs","page":"Calling C and Fortran Code","title":"Passing Pointers for Modifying Inputs","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Because C doesn't support multiple return values, often C functions will take pointers to data that the function will modify. To accomplish this within a @ccall, you need to first encapsulate the value inside a Ref{T} of the appropriate type. When you pass this Ref object as an argument, Julia will automatically pass a C pointer to the encapsulated data:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"width = Ref{Cint}(0)\nrange = Ref{Cfloat}(0)\n@ccall foo(width::Ref{Cint}, range::Ref{Cfloat})::Cvoid","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Upon return, the contents of width and range can be retrieved (if they were changed by foo) by width[] and range[]; that is, they act like zero-dimensional arrays.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#C-Wrapper-Examples","page":"Calling C and Fortran Code","title":"C Wrapper Examples","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Let's start with a simple example of a C wrapper that returns a Ptr type:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"mutable struct gsl_permutation\nend\n\n# The corresponding C signature is\n# gsl_permutation * gsl_permutation_alloc (size_t n);\nfunction permutation_alloc(n::Integer)\n output_ptr = @ccall \"libgsl\".gsl_permutation_alloc(n::Csize_t)::Ptr{gsl_permutation}\n if output_ptr == C_NULL # Could not allocate memory\n throw(OutOfMemoryError())\n end\n return output_ptr\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The GNU Scientific Library (here assumed to be accessible through :libgsl) defines an opaque pointer, gsl_permutation *, as the return type of the C function gsl_permutation_alloc. As user code never has to look inside the gsl_permutation struct, the corresponding Julia wrapper simply needs a new type declaration, gsl_permutation, that has no internal fields and whose sole purpose is to be placed in the type parameter of a Ptr type. The return type of the ccall is declared as Ptr{gsl_permutation}, since the memory allocated and pointed to by output_ptr is controlled by C.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The input n is passed by value, and so the function's input signature is simply declared as ::Csize_t without any Ref or Ptr necessary. (If the wrapper was calling a Fortran function instead, the corresponding function input signature would instead be ::Ref{Csize_t}, since Fortran variables are passed by pointers.) Furthermore, n can be any type that is convertible to a Csize_t integer; the ccall implicitly calls Base.cconvert(Csize_t, n).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Here is a second example wrapping the corresponding destructor:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"# The corresponding C signature is\n# void gsl_permutation_free (gsl_permutation * p);\nfunction permutation_free(p::Ptr{gsl_permutation})\n @ccall \"libgsl\".gsl_permutation_free(p::Ptr{gsl_permutation})::Cvoid\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Here is a third example passing Julia arrays:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"# The corresponding C signature is\n# int gsl_sf_bessel_Jn_array (int nmin, int nmax, double x,\n# double result_array[])\nfunction sf_bessel_Jn_array(nmin::Integer, nmax::Integer, x::Real)\n if nmax < nmin\n throw(DomainError())\n end\n result_array = Vector{Cdouble}(undef, nmax - nmin + 1)\n errorcode = @ccall \"libgsl\".gsl_sf_bessel_Jn_array(\n nmin::Cint, nmax::Cint, x::Cdouble, result_array::Ref{Cdouble})::Cint\n if errorcode != 0\n error(\"GSL error code $errorcode\")\n end\n return result_array\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The C function wrapped returns an integer error code; the results of the actual evaluation of the Bessel J function populate the Julia array result_array. This variable is declared as a Ref{Cdouble}, since its memory is allocated and managed by Julia. The implicit call to Base.cconvert(Ref{Cdouble}, result_array) unpacks the Julia pointer to a Julia array data structure into a form understandable by C.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Fortran-Wrapper-Example","page":"Calling C and Fortran Code","title":"Fortran Wrapper Example","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The following example utilizes ccall to call a function in a common Fortran library (libBLAS) to compute a dot product. Notice that the argument mapping is a bit different here than above, as we need to map from Julia to Fortran. On every argument type, we specify Ref or Ptr. This mangling convention may be specific to your Fortran compiler and operating system and is likely undocumented. However, wrapping each in a Ref (or Ptr, where equivalent) is a frequent requirement of Fortran compiler implementations:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"function compute_dot(DX::Vector{Float64}, DY::Vector{Float64})\n @assert length(DX) == length(DY)\n n = length(DX)\n incx = incy = 1\n product = @ccall \"libLAPACK\".ddot(\n n::Ref{Int32}, DX::Ptr{Float64}, incx::Ref{Int32}, DY::Ptr{Float64}, incy::Ref{Int32})::Float64\n return product\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Garbage-Collection-Safety","page":"Calling C and Fortran Code","title":"Garbage Collection Safety","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"When passing data to a @ccall, it is best to avoid using the pointer function. Instead define a Base.cconvert method and pass the variables directly to the @ccall. @ccall automatically arranges that all of its arguments will be preserved from garbage collection until the call returns. If a C API will store a reference to memory allocated by Julia, after the @ccall returns, you must ensure that the object remains visible to the garbage collector. The suggested way to do this is to make a global variable of type Array{Ref,1} to hold these values until the C library notifies you that it is finished with them.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Whenever you have created a pointer to Julia data, you must ensure the original data exists until you have finished using the pointer. Many methods in Julia such as unsafe_load and String make copies of data instead of taking ownership of the buffer, so that it is safe to free (or alter) the original data without affecting Julia. A notable exception is unsafe_wrap which, for performance reasons, shares (or can be told to take ownership of) the underlying buffer.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The garbage collector does not guarantee any order of finalization. That is, if a contained a reference to b and both a and b are due for garbage collection, there is no guarantee that b would be finalized after a. If proper finalization of a depends on b being valid, it must be handled in other ways.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Non-constant-Function-Specifications","page":"Calling C and Fortran Code","title":"Non-constant Function Specifications","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"In some cases, the exact name or path of the needed library is not known in advance and must be computed at run time. To handle such cases, the library component specification can be a function call, e.g. find_blas().dgemm. The call expression will be executed when the ccall itself is executed. However, it is assumed that the library location does not change once it is determined, so the result of the call can be cached and reused. Therefore, the number of times the expression executes is unspecified, and returning different values for multiple calls results in unspecified behavior.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"If even more flexibility is needed, it is possible to use computed values as function names by staging through eval as follows:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"@eval @ccall \"lib\".$(string(\"a\", \"b\"))()::Cint","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"This expression constructs a name using string, then substitutes this name into a new @ccall expression, which is then evaluated. Keep in mind that eval only operates at the top level, so within this expression local variables will not be available (unless their values are substituted with $). For this reason, eval is typically only used to form top-level definitions, for example when wrapping libraries that contain many similar functions. A similar example can be constructed for @cfunction.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep reading. The next section discusses how to use indirect calls to efficiently achieve a similar effect.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Indirect-Calls","page":"Calling C and Fortran Code","title":"Indirect Calls","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The first argument to @ccall can also be an expression evaluated at run time. In this case, the expression must evaluate to a Ptr, which will be used as the address of the native function to call. This behavior occurs when the first @ccall argument contains references to non-constants, such as local variables, function arguments, or non-constant globals.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For example, you might look up the function via dlsym, then cache it in a shared reference for that session. For example:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"macro dlsym(lib, func)\n z = Ref{Ptr{Cvoid}}(C_NULL)\n quote\n let zlocal = $z[]\n if zlocal == C_NULL\n zlocal = dlsym($(esc(lib))::Ptr{Cvoid}, $(esc(func)))::Ptr{Cvoid}\n $z[] = zlocal\n end\n zlocal\n end\n end\nend\n\nmylibvar = Libdl.dlopen(\"mylib\")\n@ccall $(@dlsym(mylibvar, \"myfunc\"))()::Cvoid","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Closure-cfunctions","page":"Calling C and Fortran Code","title":"Closure cfunctions","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The first argument to @cfunction can be marked with a $, in which case the return value will instead be a struct CFunction which closes over the argument. You must ensure that this return object is kept alive until all uses of it are done. The contents and code at the cfunction pointer will be erased via a finalizer when this reference is dropped and atexit. This is not usually needed, since this functionality is not present in C, but can be useful for dealing with ill-designed APIs which don't provide a separate closure environment parameter.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"function qsort(a::Vector{T}, cmp) where T\n isbits(T) || throw(ArgumentError(\"this method can only qsort isbits arrays\"))\n callback = @cfunction $cmp Cint (Ref{T}, Ref{T})\n # Here, `callback` isa Base.CFunction, which will be converted to Ptr{Cvoid}\n # (and protected against finalization) by the ccall\n @ccall qsort(a::Ptr{T}, length(a)::Csize_t, Base.elsize(a)::Csize_t, callback::Ptr{Cvoid})\n # We could instead use:\n # GC.@preserve callback begin\n # use(Base.unsafe_convert(Ptr{Cvoid}, callback))\n # end\n # if we needed to use it outside of a `ccall`\n return a\nend","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nClosure @cfunction relies on LLVM trampolines, which are not available on all platforms (for example ARM and PowerPC).","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Closing-a-Library","page":"Calling C and Fortran Code","title":"Closing a Library","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"It is sometimes useful to close (unload) a library so that it can be reloaded. For instance, when developing C code for use with Julia, one may need to compile, call the C code from Julia, then close the library, make an edit, recompile, and load in the new changes. One can either restart Julia or use the Libdl functions to manage the library explicitly, such as:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"lib = Libdl.dlopen(\"./my_lib.so\") # Open the library explicitly.\nsym = Libdl.dlsym(lib, :my_fcn) # Get a symbol for the function to call.\n@ccall $sym(...) # Use the pointer `sym` instead of the library.symbol tuple.\nLibdl.dlclose(lib) # Close the library explicitly.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Note that when using @ccall with the input (e.g., @ccall \"./my_lib.so\".my_fcn(...)::Cvoid), the library is opened implicitly and it may not be explicitly closed.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Variadic-function-calls","page":"Calling C and Fortran Code","title":"Variadic function calls","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"To call variadic C functions a semicolon can be used in the argument list to separate required arguments from variadic arguments. An example with the printf function is given below:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> @ccall printf(\"%s = %d\\n\"::Cstring ; \"foo\"::Cstring, foo::Cint)::Cint\nfoo = 3\n8","category":"page"},{"location":"manual/calling-c-and-fortran-code/#ccall-interface","page":"Calling C and Fortran Code","title":"ccall interface","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"There is another alternative interface to @ccall. This interface is slightly less convenient but it does allow one to specify a calling convention.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The arguments to ccall are:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"A (:function, \"library\") pair (most common),\nOR\na :function name symbol or \"function\" name string (for symbols in the current process or libc),\nOR\na function pointer (for example, from dlsym).\nThe function's return type\nA tuple of input types, corresponding to the function signature. One common mistake is forgetting that a 1-tuple of argument types must be written with a trailing comma.\nThe actual argument values to be passed to the function, if any; each is a separate parameter.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nThe (:function, \"library\") pair, return type, and input types must be literal constants (i.e., they can't be variables, but see Non-constant Function Specifications).The remaining parameters are evaluated at compile-time, when the containing method is defined.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"A table of translations between the macro and function interfaces is given below.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"@ccall ccall\n@ccall clock()::Int32 ccall(:clock, Int32, ())\n@ccall f(a::Cint)::Cint ccall(:a, Cint, (Cint,), a)\n@ccall \"mylib\".f(a::Cint, b::Cdouble)::Cvoid ccall((:f, \"mylib\"), Cvoid, (Cint, Cdouble), (a, b))\n@ccall $fptr.f()::Cvoid ccall(fptr, f, Cvoid, ())\n@ccall printf(\"%s = %d\\n\"::Cstring ; \"foo\"::Cstring, foo::Cint)::Cint \n@ccall printf(\"%s = %s\\n\"::Cstring ; \"2 + 2\"::Cstring, \"5\"::Cstring)::Cint ccall(:printf, Cint, (Cstring, Cstring...), \"%s = %s\\n\", \"2 + 2\", \"5\")\n ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn))","category":"page"},{"location":"manual/calling-c-and-fortran-code/#calling-convention","page":"Calling C and Fortran Code","title":"Calling Convention","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The second argument to ccall (immediately preceding return type) can optionally be a calling convention specifier (the @ccall macro currently does not support giving a calling convention). Without any specifier, the platform-default C calling convention is used. Other supported conventions are: stdcall, cdecl, fastcall, and thiscall (no-op on 64-bit Windows). For example (from base/libc.jl) we see the same gethostnameccall as above, but with the correct signature for Windows:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"hn = Vector{UInt8}(undef, 256)\nerr = ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn))","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For more information, please see the LLVM Language Reference.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"There is one additional special calling convention llvmcall, which allows inserting calls to LLVM intrinsics directly. This can be especially useful when targeting unusual platforms such as GPGPUs. For example, for CUDA, we need to be able to read the thread index:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"ccall(\"llvm.nvvm.read.ptx.sreg.tid.x\", llvmcall, Int32, ())","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"As with any ccall, it is essential to get the argument signature exactly correct. Also, note that there is no compatibility layer that ensures the intrinsic makes sense and works on the current target, unlike the equivalent Julia functions exposed by Core.Intrinsics.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Accessing-Global-Variables","page":"Calling C and Fortran Code","title":"Accessing Global Variables","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Global variables exported by native libraries can be accessed by name using the cglobal function. The arguments to cglobal are a symbol specification identical to that used by ccall, and a type describing the value stored in the variable:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"julia> cglobal((:errno, :libc), Int32)\nPtr{Int32} @0x00007f418d0816b8","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The result is a pointer giving the address of the value. The value can be manipulated through this pointer using unsafe_load and unsafe_store!.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"note: Note\nThis errno symbol may not be found in a library named \"libc\", as this is an implementation detail of your system compiler. Typically standard library symbols should be accessed just by name, allowing the compiler to fill in the correct one. Also, however, the errno symbol shown in this example is special in most compilers, and so the value seen here is probably not what you expect or want. Compiling the equivalent code in C on any multi-threaded-capable system would typically actually call a different function (via macro preprocessor overloading), and may give a different result than the legacy value printed here.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Accessing-Data-through-a-Pointer","page":"Calling C and Fortran Code","title":"Accessing Data through a Pointer","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The following methods are described as \"unsafe\" because a bad pointer or type declaration can cause Julia to terminate abruptly.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Given a Ptr{T}, the contents of type T can generally be copied from the referenced memory into a Julia object using unsafe_load(ptr, [index]). The index argument is optional (default is 1), and follows the Julia-convention of 1-based indexing. This function is intentionally similar to the behavior of getindex and setindex! (e.g. [] access syntax).","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The return value will be a new object initialized to contain a copy of the contents of the referenced memory. The referenced memory can safely be freed or released.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"If T is Any, then the memory is assumed to contain a reference to a Julia object (a jl_value_t*), the result will be a reference to this object, and the object will not be copied. You must be careful in this case to ensure that the object was always visible to the garbage collector (pointers do not count, but the new reference does) to ensure the memory is not prematurely freed. Note that if the object was not originally allocated by Julia, the new object will never be finalized by Julia's garbage collector. If the Ptr itself is actually a jl_value_t*, it can be converted back to a Julia object reference by unsafe_pointer_to_objref(ptr). (Julia values v can be converted to jl_value_t* pointers, as Ptr{Cvoid}, by calling pointer_from_objref(v).)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The reverse operation (writing data to a Ptr{T}), can be performed using unsafe_store!(ptr, value, [index]). Currently, this is only supported for primitive types or other pointer-free (isbits) immutable struct types.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Any operation that throws an error is probably currently unimplemented and should be posted as a bug so that it can be resolved.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"If the pointer of interest is a plain-data array (primitive type or immutable struct), the function unsafe_wrap(Array, ptr,dims, own = false) may be more useful. The final parameter should be true if Julia should \"take ownership\" of the underlying buffer and call free(ptr) when the returned Array object is finalized. If the own parameter is omitted or false, the caller must ensure the buffer remains in existence until all access is complete.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Arithmetic on the Ptr type in Julia (e.g. using +) does not behave the same as C's pointer arithmetic. Adding an integer to a Ptr in Julia always moves the pointer by some number of bytes, not elements. This way, the address values obtained from pointer arithmetic do not depend on the element types of pointers.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#Thread-safety","page":"Calling C and Fortran Code","title":"Thread-safety","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Some C libraries execute their callbacks from a different thread, and since Julia isn't thread-safe you'll need to take some extra precautions. In particular, you'll need to set up a two-layered system: the C callback should only schedule (via Julia's event loop) the execution of your \"real\" callback. To do this, create an AsyncCondition object and wait on it:","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"cond = Base.AsyncCondition()\nwait(cond)","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"The callback you pass to C should only execute a ccall to :uv_async_send, passing cond.handle as the argument, taking care to avoid any allocations or other interactions with the Julia runtime.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"Note that events may be coalesced, so multiple calls to uv_async_send may result in a single wakeup notification to the condition.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#More-About-Callbacks","page":"Calling C and Fortran Code","title":"More About Callbacks","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For more details on how to pass callbacks to C libraries, see this blog post.","category":"page"},{"location":"manual/calling-c-and-fortran-code/#C","page":"Calling C and Fortran Code","title":"C++","text":"","category":"section"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"For tools to create C++ bindings, see the CxxWrap package.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"[1]: Non-library function calls in both C and Julia can be inlined and thus may have even less overhead than calls to shared library functions. The point above is that the cost of actually doing foreign function call is about the same as doing a call in either native language.","category":"page"},{"location":"manual/calling-c-and-fortran-code/","page":"Calling C and Fortran Code","title":"Calling C and Fortran Code","text":"[2]: The Clang package can be used to auto-generate Julia code from a C header file.","category":"page"},{"location":"base/libc/#C-Standard-Library","page":"C Standard Library","title":"C Standard Library","text":"","category":"section"},{"location":"base/libc/","page":"C Standard Library","title":"C Standard Library","text":"Base.Libc.malloc\nBase.Libc.calloc\nBase.Libc.realloc\nBase.Libc.memcpy\nBase.Libc.memmove\nBase.Libc.memset\nBase.Libc.memcmp\nBase.Libc.free\nBase.Libc.errno\nBase.Libc.strerror\nBase.Libc.GetLastError\nBase.Libc.FormatMessage\nBase.Libc.time(::Base.Libc.TmStruct)\nBase.Libc.strftime\nBase.Libc.strptime\nBase.Libc.TmStruct\nBase.Libc.FILE\nBase.Libc.flush_cstdio\nBase.Libc.systemsleep\nBase.Libc.mkfifo","category":"page"},{"location":"base/libc/#Base.Libc.malloc","page":"C Standard Library","title":"Base.Libc.malloc","text":"malloc(size::Integer) -> Ptr{Cvoid}\n\nCall malloc from the C standard library.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.calloc","page":"C Standard Library","title":"Base.Libc.calloc","text":"calloc(num::Integer, size::Integer) -> Ptr{Cvoid}\n\nCall calloc from the C standard library.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.realloc","page":"C Standard Library","title":"Base.Libc.realloc","text":"realloc(addr::Ptr, size::Integer) -> Ptr{Cvoid}\n\nCall realloc from the C standard library.\n\nSee warning in the documentation for free regarding only using this on memory originally obtained from malloc.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.memcpy","page":"C Standard Library","title":"Base.memcpy","text":"memcpy(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid}\n\nCall memcpy from the C standard library.\n\ncompat: Julia 1.10\nSupport for memcpy requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.memmove","page":"C Standard Library","title":"Base.memmove","text":"memmove(dst::Ptr, src::Ptr, n::Integer) -> Ptr{Cvoid}\n\nCall memmove from the C standard library.\n\ncompat: Julia 1.10\nSupport for memmove requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.memset","page":"C Standard Library","title":"Base.memset","text":"memset(dst::Ptr, val, n::Integer) -> Ptr{Cvoid}\n\nCall memset from the C standard library.\n\ncompat: Julia 1.10\nSupport for memset requires at least Julia 1.10.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.memcmp","page":"C Standard Library","title":"Base.memcmp","text":"memcmp(a::Ptr, b::Ptr, n::Integer) -> Int\n\nCall memcmp from the C standard library.\n\ncompat: Julia 1.10\nSupport for memcmp requires at least Julia 1.9.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.free","page":"C Standard Library","title":"Base.Libc.free","text":"free(addr::Ptr)\n\nCall free from the C standard library. Only use this on memory obtained from malloc, not on pointers retrieved from other C libraries. Ptr objects obtained from C libraries should be freed by the free functions defined in that library, to avoid assertion failures if multiple libc libraries exist on the system.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.errno","page":"C Standard Library","title":"Base.Libc.errno","text":"errno([code])\n\nGet the value of the C library's errno. If an argument is specified, it is used to set the value of errno.\n\nThe value of errno is only valid immediately after a ccall to a C library routine that sets it. Specifically, you cannot call errno at the next prompt in a REPL, because lots of code is executed between prompts.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.strerror","page":"C Standard Library","title":"Base.Libc.strerror","text":"strerror(n=errno())\n\nConvert a system call error code to a descriptive string\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.GetLastError","page":"C Standard Library","title":"Base.Libc.GetLastError","text":"GetLastError()\n\nCall the Win32 GetLastError function [only available on Windows].\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.FormatMessage","page":"C Standard Library","title":"Base.Libc.FormatMessage","text":"FormatMessage(n=GetLastError())\n\nConvert a Win32 system call error code to a descriptive string [only available on Windows].\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.time-Tuple{Base.Libc.TmStruct}","page":"C Standard Library","title":"Base.Libc.time","text":"time(t::TmStruct) -> Float64\n\nConverts a TmStruct struct to a number of seconds since the epoch.\n\n\n\n\n\n","category":"method"},{"location":"base/libc/#Base.Libc.strftime","page":"C Standard Library","title":"Base.Libc.strftime","text":"strftime([format], time)\n\nConvert time, given as a number of seconds since the epoch or a TmStruct, to a formatted string using the given format. Supported formats are the same as those in the standard C library.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.strptime","page":"C Standard Library","title":"Base.Libc.strptime","text":"strptime([format], timestr)\n\nParse a formatted time string into a TmStruct giving the seconds, minute, hour, date, etc. Supported formats are the same as those in the standard C library. On some platforms, timezones will not be parsed correctly. If the result of this function will be passed to time to convert it to seconds since the epoch, the isdst field should be filled in manually. Setting it to -1 will tell the C library to use the current system settings to determine the timezone.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.TmStruct","page":"C Standard Library","title":"Base.Libc.TmStruct","text":"TmStruct([seconds])\n\nConvert a number of seconds since the epoch to broken-down format, with fields sec, min, hour, mday, month, year, wday, yday, and isdst.\n\n\n\n\n\n","category":"type"},{"location":"base/libc/#Base.Libc.FILE","page":"C Standard Library","title":"Base.Libc.FILE","text":"FILE(::Ptr)\nFILE(::IO)\n\nA libc FILE*, representing an opened file.\n\nIt can be passed as a Ptr{FILE} argument to ccall and also supports seek, position and close.\n\nA FILE can be constructed from an ordinary IO object, provided it is an open file. It must be closed afterward.\n\nExamples\n\njulia> using Base.Libc\n\njulia> mktemp() do _, io\n # write to the temporary file using `puts(char*, FILE*)` from libc\n file = FILE(io)\n ccall(:fputs, Cint, (Cstring, Ptr{FILE}), \"hello world\", file)\n close(file)\n # read the file again\n seek(io, 0)\n read(io, String)\n end\n\"hello world\"\n\n\n\n\n\n","category":"type"},{"location":"base/libc/#Base.Libc.flush_cstdio","page":"C Standard Library","title":"Base.Libc.flush_cstdio","text":"flush_cstdio()\n\nFlushes the C stdout and stderr streams (which may have been written to by external C code).\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.systemsleep","page":"C Standard Library","title":"Base.Libc.systemsleep","text":"systemsleep(s::Real)\n\nSuspends execution for s seconds. This function does not yield to Julia's scheduler and therefore blocks the Julia thread that it is running on for the duration of the sleep time.\n\nSee also sleep.\n\n\n\n\n\n","category":"function"},{"location":"base/libc/#Base.Libc.mkfifo","page":"C Standard Library","title":"Base.Libc.mkfifo","text":"mkfifo(path::AbstractString, [mode::Integer]) -> path\n\nMake a FIFO special file (a named pipe) at path. Return path as-is on success.\n\nmkfifo is supported only in Unix platforms.\n\ncompat: Julia 1.11\nmkfifo requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/DelimitedFiles/#Delimited-Files","page":"Delimited Files","title":"Delimited Files","text":"","category":"section"},{"location":"stdlib/DelimitedFiles/","page":"Delimited Files","title":"Delimited Files","text":"DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type, ::AbstractChar)\nDelimitedFiles.readdlm(::Any, ::AbstractChar, ::AbstractChar)\nDelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type)\nDelimitedFiles.readdlm(::Any, ::AbstractChar)\nDelimitedFiles.readdlm(::Any, ::Type)\nDelimitedFiles.readdlm(::Any)\nDelimitedFiles.writedlm","category":"page"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, AbstractChar, Type, AbstractChar}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, delim::AbstractChar, T::Type, eol::AbstractChar; header=false, skipstart=0, skipblanks=true, use_mmap, quotes=true, dims, comments=false, comment_char='#')\n\nRead a matrix from the source where each line (separated by eol) gives one row, with elements separated by the given delimiter. The source can be a text file, stream or byte array. Memory mapped files can be used by passing the byte array representation of the mapped segment as source.\n\nIf T is a numeric type, the result is an array of that type, with any non-numeric elements as NaN for floating-point types, or zero. Other useful values of T include String, AbstractString, and Any.\n\nIf header is true, the first row of data will be read as header and the tuple (data_cells, header_cells) is returned instead of only data_cells.\n\nSpecifying skipstart will ignore the corresponding number of initial lines from the input.\n\nIf skipblanks is true, blank lines in the input will be ignored.\n\nIf use_mmap is true, the file specified by source is memory mapped for potential speedups if the file is large. Default is false. On a Windows filesystem, use_mmap should not be set to true unless the file is only read once and is also not written to. Some edge cases exist where an OS is Unix-like but the filesystem is Windows-like.\n\nIf quotes is true, columns enclosed within double-quote (\") characters are allowed to contain new lines and column delimiters. Double-quote characters within a quoted field must be escaped with another double-quote. Specifying dims as a tuple of the expected rows and columns (including header, if any) may speed up reading of large files. If comments is true, lines beginning with comment_char and text following comment_char in any line are ignored.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [5; 6; 7; 8];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y])\n end\n\njulia> readdlm(\"delim_file.txt\", '\\t', Int, '\\n')\n4×2 Matrix{Int64}:\n 1 5\n 2 6\n 3 7\n 4 8\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, AbstractChar, AbstractChar}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, delim::AbstractChar, eol::AbstractChar; options...)\n\nIf all data is numeric, the result will be a numeric array. If some elements cannot be parsed as numbers, a heterogeneous array of numbers and strings is returned.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, AbstractChar, Type}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, delim::AbstractChar, T::Type; options...)\n\nThe end of line delimiter is taken as \\n.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [1.1; 2.2; 3.3; 4.4];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y], ',')\n end;\n\njulia> readdlm(\"delim_file.txt\", ',', Float64)\n4×2 Matrix{Float64}:\n 1.0 1.1\n 2.0 2.2\n 3.0 3.3\n 4.0 4.4\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, AbstractChar}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, delim::AbstractChar; options...)\n\nThe end of line delimiter is taken as \\n. If all data is numeric, the result will be a numeric array. If some elements cannot be parsed as numbers, a heterogeneous array of numbers and strings is returned.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [1.1; 2.2; 3.3; 4.4];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y], ',')\n end;\n\njulia> readdlm(\"delim_file.txt\", ',')\n4×2 Matrix{Float64}:\n 1.0 1.1\n 2.0 2.2\n 3.0 3.3\n 4.0 4.4\n\njulia> z = [\"a\"; \"b\"; \"c\"; \"d\"];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x z], ',')\n end;\n\njulia> readdlm(\"delim_file.txt\", ',')\n4×2 Matrix{Any}:\n 1 \"a\"\n 2 \"b\"\n 3 \"c\"\n 4 \"d\"\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any, Type}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source, T::Type; options...)\n\nThe columns are assumed to be separated by one or more whitespaces. The end of line delimiter is taken as \\n.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [5; 6; 7; 8];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y])\n end;\n\njulia> readdlm(\"delim_file.txt\", Int64)\n4×2 Matrix{Int64}:\n 1 5\n 2 6\n 3 7\n 4 8\n\njulia> readdlm(\"delim_file.txt\", Float64)\n4×2 Matrix{Float64}:\n 1.0 5.0\n 2.0 6.0\n 3.0 7.0\n 4.0 8.0\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.readdlm-Tuple{Any}","page":"Delimited Files","title":"DelimitedFiles.readdlm","text":"readdlm(source; options...)\n\nThe columns are assumed to be separated by one or more whitespaces. The end of line delimiter is taken as \\n. If all data is numeric, the result will be a numeric array. If some elements cannot be parsed as numbers, a heterogeneous array of numbers and strings is returned.\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [\"a\"; \"b\"; \"c\"; \"d\"];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y])\n end;\n\njulia> readdlm(\"delim_file.txt\")\n4×2 Matrix{Any}:\n 1 \"a\"\n 2 \"b\"\n 3 \"c\"\n 4 \"d\"\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"method"},{"location":"stdlib/DelimitedFiles/#DelimitedFiles.writedlm","page":"Delimited Files","title":"DelimitedFiles.writedlm","text":"writedlm(f, A, delim='\\t'; opts)\n\nWrite A (a vector, matrix, or an iterable collection of iterable rows) as text to f (either a filename string or an IO stream) using the given delimiter delim (which defaults to tab, but can be any printable Julia object, typically a Char or AbstractString).\n\nFor example, two vectors x and y of the same length can be written as two columns of tab-delimited text to f by either writedlm(f, [x y]) or by writedlm(f, zip(x, y)).\n\nExamples\n\njulia> using DelimitedFiles\n\njulia> x = [1; 2; 3; 4];\n\njulia> y = [5; 6; 7; 8];\n\njulia> open(\"delim_file.txt\", \"w\") do io\n writedlm(io, [x y])\n end\n\njulia> readdlm(\"delim_file.txt\", '\\t', Int, '\\n')\n4×2 Matrix{Int64}:\n 1 5\n 2 6\n 3 7\n 4 8\n\njulia> rm(\"delim_file.txt\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/docs/src/index.md\"","category":"page"},{"location":"stdlib/LinearAlgebra/#man-linalg","page":"Linear Algebra","title":"Linear Algebra","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"DocTestSetup = :(using LinearAlgebra)","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations of many common and useful linear algebra operations which can be loaded with using LinearAlgebra. Basic operations, such as tr, det, and inv are all supported:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> A = [1 2 3; 4 1 6; 7 8 1]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 1 6\n 7 8 1\n\njulia> tr(A)\n3\n\njulia> det(A)\n104.0\n\njulia> inv(A)\n3×3 Matrix{Float64}:\n -0.451923 0.211538 0.0865385\n 0.365385 -0.192308 0.0576923\n 0.240385 0.0576923 -0.0673077","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"As well as other useful operations, such as finding eigenvalues or eigenvectors:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> A = [-4. -17.; 2. 2.]\n2×2 Matrix{Float64}:\n -4.0 -17.0\n 2.0 2.0\n\njulia> eigvals(A)\n2-element Vector{ComplexF64}:\n -1.0 - 5.0im\n -1.0 + 5.0im\n\njulia> eigvecs(A)\n2×2 Matrix{ComplexF64}:\n 0.945905-0.0im 0.945905+0.0im\n -0.166924+0.278207im -0.166924-0.278207im","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In addition, Julia provides many factorizations which can be used to speed up problems such as linear solve or matrix exponentiation by pre-factorizing a matrix into a form more amenable (for performance or memory reasons) to the problem. See the documentation on factorize for more information. As an example:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> A = [1.5 2 -4; 3 -1 -6; -10 2.3 4]\n3×3 Matrix{Float64}:\n 1.5 2.0 -4.0\n 3.0 -1.0 -6.0\n -10.0 2.3 4.0\n\njulia> factorize(A)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n -0.15 1.0 0.0\n -0.3 -0.132196 1.0\nU factor:\n3×3 Matrix{Float64}:\n -10.0 2.3 4.0\n 0.0 2.345 -3.4\n 0.0 0.0 -5.24947","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Since A is not Hermitian, symmetric, triangular, tridiagonal, or bidiagonal, an LU factorization may be the best we can do. Compare with:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5]\n3×3 Matrix{Float64}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0\n\njulia> factorize(B)\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n3×3 Tridiagonal{Float64, Vector{Float64}}:\n -1.64286 0.0 ⋅\n 0.0 -2.8 0.0\n ⋅ 0.0 5.0\nU factor:\n3×3 UnitUpperTriangular{Float64, Matrix{Float64}}:\n 1.0 0.142857 -0.8\n ⋅ 1.0 -0.6\n ⋅ ⋅ 1.0\npermutation:\n3-element Vector{Int64}:\n 1\n 2\n 3","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Here, Julia was able to detect that B is in fact symmetric, and used a more appropriate factorization. Often it's possible to write more efficient code for a matrix that is known to have certain properties e.g. it is symmetric, or tridiagonal. Julia provides some special types so that you can \"tag\" matrices as having these properties. For instance:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5]\n3×3 Matrix{Float64}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0\n\njulia> sB = Symmetric(B)\n3×3 Symmetric{Float64, Matrix{Float64}}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"sB has been tagged as a matrix that's (real) symmetric, so for later operations we might perform on it, such as eigenfactorization or computing matrix-vector products, efficiencies can be found by only referencing half of it. For example:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5]\n3×3 Matrix{Float64}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0\n\njulia> sB = Symmetric(B)\n3×3 Symmetric{Float64, Matrix{Float64}}:\n 1.5 2.0 -4.0\n 2.0 -1.0 -3.0\n -4.0 -3.0 5.0\n\njulia> x = [1; 2; 3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> sB\\x\n3-element Vector{Float64}:\n -1.7391304347826084\n -1.1086956521739126\n -1.4565217391304346","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The \\ operation here performs the linear solution. The left-division operator is pretty powerful and it's easy to write compact, readable code that is flexible enough to solve all sorts of systems of linear equations.","category":"page"},{"location":"stdlib/LinearAlgebra/#Special-matrices","page":"Linear Algebra","title":"Special matrices","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Matrices with special symmetries and structures arise often in linear algebra and are frequently associated with various matrix factorizations. Julia features a rich collection of special matrix types, which allow for fast computation with specialized routines that are specially developed for particular matrix types.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The following tables summarize the types of special matrices that have been implemented in Julia, as well as whether hooks to various optimized methods for them in LAPACK are available.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Type Description\nSymmetric Symmetric matrix\nHermitian Hermitian matrix\nUpperTriangular Upper triangular matrix\nUnitUpperTriangular Upper triangular matrix with unit diagonal\nLowerTriangular Lower triangular matrix\nUnitLowerTriangular Lower triangular matrix with unit diagonal\nUpperHessenberg Upper Hessenberg matrix\nTridiagonal Tridiagonal matrix\nSymTridiagonal Symmetric tridiagonal matrix\nBidiagonal Upper/lower bidiagonal matrix\nDiagonal Diagonal matrix\nUniformScaling Uniform scaling operator","category":"page"},{"location":"stdlib/LinearAlgebra/#Elementary-operations","page":"Linear Algebra","title":"Elementary operations","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Matrix type + - * \\ Other functions with optimized methods\nSymmetric MV inv, sqrt, cbrt, exp\nHermitian MV inv, sqrt, cbrt, exp\nUpperTriangular MV MV inv, det, logdet\nUnitUpperTriangular MV MV inv, det, logdet\nLowerTriangular MV MV inv, det, logdet\nUnitLowerTriangular MV MV inv, det, logdet\nUpperHessenberg MM inv, det\nSymTridiagonal M M MS MV eigmax, eigmin\nTridiagonal M M MS MV \nBidiagonal M M MS MV \nDiagonal M M MV MV inv, det, logdet, /\nUniformScaling M M MVS MVS /","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Legend:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Key Description\nM (matrix) An optimized method for matrix-matrix operations is available\nV (vector) An optimized method for matrix-vector operations is available\nS (scalar) An optimized method for matrix-scalar operations is available","category":"page"},{"location":"stdlib/LinearAlgebra/#Matrix-factorizations","page":"Linear Algebra","title":"Matrix factorizations","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Matrix type LAPACK eigen eigvals eigvecs svd svdvals\nSymmetric SY ARI \nHermitian HE ARI \nUpperTriangular TR A A A \nUnitUpperTriangular TR A A A \nLowerTriangular TR A A A \nUnitLowerTriangular TR A A A \nSymTridiagonal ST A ARI AV \nTridiagonal GT \nBidiagonal BD A A\nDiagonal DI A ","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Legend:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Key Description Example\nA (all) An optimized method to find all the characteristic values and/or vectors is available e.g. eigvals(M)\nR (range) An optimized method to find the ilth through the ihth characteristic values are available eigvals(M, il, ih)\nI (interval) An optimized method to find the characteristic values in the interval [vl, vh] is available eigvals(M, vl, vh)\nV (vectors) An optimized method to find the characteristic vectors corresponding to the characteristic values x=[x1, x2,...] is available eigvecs(M, x)","category":"page"},{"location":"stdlib/LinearAlgebra/#The-uniform-scaling-operator","page":"Linear Algebra","title":"The uniform scaling operator","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"A UniformScaling operator represents a scalar times the identity operator, λ*I. The identity operator I is defined as a constant and is an instance of UniformScaling. The size of these operators are generic and match the other matrix in the binary operations +, -, * and \\. For A+I and A-I this means that A must be square. Multiplication with the identity operator I is a noop (except for checking that the scaling factor is one) and therefore almost without overhead.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"To see the UniformScaling operator in action:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> U = UniformScaling(2);\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> a + U\n2×2 Matrix{Int64}:\n 3 2\n 3 6\n\njulia> a * U\n2×2 Matrix{Int64}:\n 2 4\n 6 8\n\njulia> [a U]\n2×4 Matrix{Int64}:\n 1 2 2 0\n 3 4 0 2\n\njulia> b = [1 2 3; 4 5 6]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> b - U\nERROR: DimensionMismatch: matrix is not square: dimensions are (2, 3)\nStacktrace:\n[...]","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"If you need to solve many systems of the form (A+μI)x = b for the same A and different μ, it might be beneficial to first compute the Hessenberg factorization F of A via the hessenberg function. Given F, Julia employs an efficient algorithm for (F+μ*I) \\ b (equivalent to (A+μ*I)x \\ b) and related operations like determinants.","category":"page"},{"location":"stdlib/LinearAlgebra/#man-linalg-factorizations","page":"Linear Algebra","title":"Matrix factorizations","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Matrix factorizations (a.k.a. matrix decompositions) compute the factorization of a matrix into a product of matrices, and are one of the central concepts in (numerical) linear algebra.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The following table summarizes the types of matrix factorizations that have been implemented in Julia. Details of their associated methods can be found in the Standard functions section of the Linear Algebra documentation.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Type Description\nBunchKaufman Bunch-Kaufman factorization\nCholesky Cholesky factorization\nCholeskyPivoted Pivoted Cholesky factorization\nLDLt LDL(T) factorization\nLU LU factorization\nQR QR factorization\nQRCompactWY Compact WY form of the QR factorization\nQRPivoted Pivoted QR factorization\nLQ QR factorization of transpose(A)\nHessenberg Hessenberg decomposition\nEigen Spectral decomposition\nGeneralizedEigen Generalized spectral decomposition\nSVD Singular value decomposition\nGeneralizedSVD Generalized SVD\nSchur Schur decomposition\nGeneralizedSchur Generalized Schur decomposition","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Adjoints and transposes of Factorization objects are lazily wrapped in AdjointFactorization and TransposeFactorization objects, respectively. Generically, transpose of real Factorizations are wrapped as AdjointFactorization.","category":"page"},{"location":"stdlib/LinearAlgebra/#man-linalg-abstractq","page":"Linear Algebra","title":"Orthogonal matrices (AbstractQ)","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Some matrix factorizations generate orthogonal/unitary \"matrix\" factors. These factorizations include QR-related factorizations obtained from calls to qr, i.e., QR, QRCompactWY and QRPivoted, the Hessenberg factorization obtained from calls to hessenberg, and the LQ factorization obtained from lq. While these orthogonal/unitary factors admit a matrix representation, their internal representation is, for performance and memory reasons, different. Hence, they should be rather viewed as matrix-backed, function-based linear operators. In particular, reading, for instance, a column of its matrix representation requires running \"matrix\"-vector multiplication code, rather than simply reading out data from memory (possibly filling parts of the vector with structural zeros). Another clear distinction from other, non-triangular matrix types is that the underlying multiplication code allows for in-place modification during multiplication. Furthermore, objects of specific AbstractQ subtypes as those created via qr, hessenberg and lq can behave like a square or a rectangular matrix depending on context:","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"julia> using LinearAlgebra\n\njulia> Q = qr(rand(3,2)).Q\n3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}\n\njulia> Matrix(Q)\n3×2 Matrix{Float64}:\n -0.320597 0.865734\n -0.765834 -0.475694\n -0.557419 0.155628\n\njulia> Q*I\n3×3 Matrix{Float64}:\n -0.320597 0.865734 -0.384346\n -0.765834 -0.475694 -0.432683\n -0.557419 0.155628 0.815514\n\njulia> Q*ones(2)\n3-element Vector{Float64}:\n 0.5451367118802273\n -1.241527373086654\n -0.40179067589600226\n\njulia> Q*ones(3)\n3-element Vector{Float64}:\n 0.16079054743832022\n -1.674209978965636\n 0.41372375588835797\n\njulia> ones(1,2) * Q'\n1×3 Matrix{Float64}:\n 0.545137 -1.24153 -0.401791\n\njulia> ones(1,3) * Q'\n1×3 Matrix{Float64}:\n 0.160791 -1.67421 0.413724","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Due to this distinction from dense or structured matrices, the abstract AbstractQ type does not subtype AbstractMatrix, but instead has its own type hierarchy. Custom types that subtype AbstractQ can rely on generic fallbacks if the following interface is satisfied. For example, for","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"struct MyQ{T} <: LinearAlgebra.AbstractQ{T}\n # required fields\nend","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"provide overloads for","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Base.size(Q::MyQ) # size of corresponding square matrix representation\nBase.convert(::Type{AbstractQ{T}}, Q::MyQ) # eltype promotion [optional]\nLinearAlgebra.lmul!(Q::MyQ, x::AbstractVecOrMat) # left-multiplication\nLinearAlgebra.rmul!(A::AbstractMatrix, Q::MyQ) # right-multiplication","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"If eltype promotion is not of interest, the convert method is unnecessary, since by default convert(::Type{AbstractQ{T}}, Q::AbstractQ{T}) returns Q itself. Adjoints of AbstractQ-typed objects are lazily wrapped in an AdjointQ wrapper type, which requires its own LinearAlgebra.lmul! and LinearAlgebra.rmul! methods. Given this set of methods, any Q::MyQ can be used like a matrix, preferably in a multiplicative context: multiplication via * with scalars, vectors and matrices from left and right, obtaining a matrix representation of Q via Matrix(Q) (or Q*I) and indexing into the matrix representation all work. In contrast, addition and subtraction as well as more generally broadcasting over elements in the matrix representation fail because that would be highly inefficient. For such use cases, consider computing the matrix representation up front and cache it for future reuse.","category":"page"},{"location":"stdlib/LinearAlgebra/#man-linalg-pivoting-strategies","page":"Linear Algebra","title":"Pivoting Strategies","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Several of Julia's matrix factorizations support pivoting, which can be used to improve their numerical stability. In fact, some matrix factorizations, such as the LU factorization, may fail without pivoting.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In pivoting, first, a pivot element with good numerical properties is chosen based on a pivoting strategy. Next, the rows and columns of the original matrix are permuted to bring the chosen element in place for subsequent computation. Furthermore, the process is repeated for each stage of the factorization.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Consequently, besides the conventional matrix factors, the outputs of pivoted factorization schemes also include permutation matrices.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In the following, the pivoting strategies implemented in Julia are briefly described. Note that not all matrix factorizations may support them. Consult the documentation of the respective matrix factorization for details on the supported pivoting strategies.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"See also LinearAlgebra.ZeroPivotException.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.NoPivot\nLinearAlgebra.RowNonZero\nLinearAlgebra.RowMaximum\nLinearAlgebra.ColumnNorm","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.NoPivot","page":"Linear Algebra","title":"LinearAlgebra.NoPivot","text":"NoPivot\n\nPivoting is not performed. Matrix factorizations such as the LU factorization may fail without pivoting, and may also be numerically unstable for floating-point matrices in the face of roundoff error. This pivot strategy is mainly useful for pedagogical purposes.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.RowNonZero","page":"Linear Algebra","title":"LinearAlgebra.RowNonZero","text":"RowNonZero\n\nFirst non-zero element in the remaining rows is chosen as the pivot element.\n\nBeware that for floating-point matrices, the resulting LU algorithm is numerically unstable — this strategy is mainly useful for comparison to hand calculations (which typically use this strategy) or for other algebraic types (e.g. rational numbers) not susceptible to roundoff errors. Otherwise, the default RowMaximum pivoting strategy should be generally preferred in Gaussian elimination.\n\nNote that the element type of the matrix must admit an iszero method.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.RowMaximum","page":"Linear Algebra","title":"LinearAlgebra.RowMaximum","text":"RowMaximum\n\nThe maximum-magnitude element in the remaining rows is chosen as the pivot element. This is the default strategy for LU factorization of floating-point matrices, and is sometimes referred to as the \"partial pivoting\" algorithm.\n\nNote that the element type of the matrix must admit an abs method, whose result type must admit a < method.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ColumnNorm","page":"Linear Algebra","title":"LinearAlgebra.ColumnNorm","text":"ColumnNorm\n\nThe column with the maximum norm is used for subsequent computation. This is used for pivoted QR factorization.\n\nNote that the element type of the matrix must admit norm and abs methods, whose respective result types must admit a < method.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#Standard-functions","page":"Linear Algebra","title":"Standard functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Linear algebra functions in Julia are largely implemented by calling functions from LAPACK. Sparse matrix factorizations call functions from SuiteSparse. Other sparse solvers are available as Julia packages.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Base.:*(::AbstractMatrix, ::AbstractMatrix)\nBase.:*(::AbstractMatrix, ::AbstractMatrix, ::AbstractVector)\nBase.:\\(::AbstractMatrix, ::AbstractVecOrMat)\nBase.:/(::AbstractVecOrMat, ::AbstractVecOrMat)\nLinearAlgebra.SingularException\nLinearAlgebra.PosDefException\nLinearAlgebra.ZeroPivotException\nLinearAlgebra.RankDeficientException\nLinearAlgebra.LAPACKException\nLinearAlgebra.dot\nLinearAlgebra.dot(::Any, ::Any, ::Any)\nLinearAlgebra.cross\nLinearAlgebra.axpy!\nLinearAlgebra.axpby!\nLinearAlgebra.rotate!\nLinearAlgebra.reflect!\nLinearAlgebra.factorize\nLinearAlgebra.Diagonal\nLinearAlgebra.Bidiagonal\nLinearAlgebra.SymTridiagonal\nLinearAlgebra.Tridiagonal\nLinearAlgebra.Symmetric\nLinearAlgebra.Hermitian\nLinearAlgebra.LowerTriangular\nLinearAlgebra.UpperTriangular\nLinearAlgebra.UnitLowerTriangular\nLinearAlgebra.UnitUpperTriangular\nLinearAlgebra.UpperHessenberg\nLinearAlgebra.UniformScaling\nLinearAlgebra.I\nLinearAlgebra.UniformScaling(::Integer)\nLinearAlgebra.Factorization\nLinearAlgebra.LU\nLinearAlgebra.lu\nLinearAlgebra.lu!\nLinearAlgebra.Cholesky\nLinearAlgebra.CholeskyPivoted\nLinearAlgebra.cholesky\nLinearAlgebra.cholesky!\nLinearAlgebra.lowrankupdate\nLinearAlgebra.lowrankdowndate\nLinearAlgebra.lowrankupdate!\nLinearAlgebra.lowrankdowndate!\nLinearAlgebra.LDLt\nLinearAlgebra.ldlt\nLinearAlgebra.ldlt!\nLinearAlgebra.QR\nLinearAlgebra.QRCompactWY\nLinearAlgebra.QRPivoted\nLinearAlgebra.qr\nLinearAlgebra.qr!\nLinearAlgebra.LQ\nLinearAlgebra.lq\nLinearAlgebra.lq!\nLinearAlgebra.BunchKaufman\nLinearAlgebra.bunchkaufman\nLinearAlgebra.bunchkaufman!\nLinearAlgebra.Eigen\nLinearAlgebra.GeneralizedEigen\nLinearAlgebra.eigvals\nLinearAlgebra.eigvals!\nLinearAlgebra.eigmax\nLinearAlgebra.eigmin\nLinearAlgebra.eigvecs\nLinearAlgebra.eigen\nLinearAlgebra.eigen!\nLinearAlgebra.Hessenberg\nLinearAlgebra.hessenberg\nLinearAlgebra.hessenberg!\nLinearAlgebra.Schur\nLinearAlgebra.GeneralizedSchur\nLinearAlgebra.schur\nLinearAlgebra.schur!\nLinearAlgebra.ordschur\nLinearAlgebra.ordschur!\nLinearAlgebra.SVD\nLinearAlgebra.GeneralizedSVD\nLinearAlgebra.svd\nLinearAlgebra.svd!\nLinearAlgebra.svdvals\nLinearAlgebra.svdvals!\nLinearAlgebra.Givens\nLinearAlgebra.givens\nLinearAlgebra.triu\nLinearAlgebra.triu!\nLinearAlgebra.tril\nLinearAlgebra.tril!\nLinearAlgebra.diagind\nLinearAlgebra.diag\nLinearAlgebra.diagm\nLinearAlgebra.rank\nLinearAlgebra.norm\nLinearAlgebra.opnorm\nLinearAlgebra.normalize!\nLinearAlgebra.normalize\nLinearAlgebra.cond\nLinearAlgebra.condskeel\nLinearAlgebra.tr\nLinearAlgebra.det\nLinearAlgebra.logdet\nLinearAlgebra.logabsdet\nBase.inv(::AbstractMatrix)\nLinearAlgebra.pinv\nLinearAlgebra.nullspace\nBase.kron\nBase.kron!\nLinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat})\nBase.cis(::AbstractMatrix)\nBase.:^(::AbstractMatrix, ::Number)\nBase.:^(::Number, ::AbstractMatrix)\nLinearAlgebra.log(::StridedMatrix)\nLinearAlgebra.sqrt(::StridedMatrix)\nLinearAlgebra.cbrt(::AbstractMatrix{<:Real})\nLinearAlgebra.cos(::StridedMatrix{<:Real})\nLinearAlgebra.sin(::StridedMatrix{<:Real})\nLinearAlgebra.sincos(::StridedMatrix{<:Real})\nLinearAlgebra.tan(::StridedMatrix{<:Real})\nLinearAlgebra.sec(::StridedMatrix)\nLinearAlgebra.csc(::StridedMatrix)\nLinearAlgebra.cot(::StridedMatrix)\nLinearAlgebra.cosh(::StridedMatrix)\nLinearAlgebra.sinh(::StridedMatrix)\nLinearAlgebra.tanh(::StridedMatrix)\nLinearAlgebra.sech(::StridedMatrix)\nLinearAlgebra.csch(::StridedMatrix)\nLinearAlgebra.coth(::StridedMatrix)\nLinearAlgebra.acos(::StridedMatrix)\nLinearAlgebra.asin(::StridedMatrix)\nLinearAlgebra.atan(::StridedMatrix)\nLinearAlgebra.asec(::StridedMatrix)\nLinearAlgebra.acsc(::StridedMatrix)\nLinearAlgebra.acot(::StridedMatrix)\nLinearAlgebra.acosh(::StridedMatrix)\nLinearAlgebra.asinh(::StridedMatrix)\nLinearAlgebra.atanh(::StridedMatrix)\nLinearAlgebra.asech(::StridedMatrix)\nLinearAlgebra.acsch(::StridedMatrix)\nLinearAlgebra.acoth(::StridedMatrix)\nLinearAlgebra.lyap\nLinearAlgebra.sylvester\nLinearAlgebra.issuccess\nLinearAlgebra.issymmetric\nLinearAlgebra.isposdef\nLinearAlgebra.isposdef!\nLinearAlgebra.istril\nLinearAlgebra.istriu\nLinearAlgebra.isdiag\nLinearAlgebra.ishermitian\nBase.transpose\nLinearAlgebra.transpose!\nLinearAlgebra.Transpose\nLinearAlgebra.TransposeFactorization\nBase.adjoint\nLinearAlgebra.adjoint!\nLinearAlgebra.Adjoint\nLinearAlgebra.AdjointFactorization\nBase.copy(::Union{Transpose,Adjoint})\nLinearAlgebra.stride1\nLinearAlgebra.checksquare\nLinearAlgebra.peakflops\nLinearAlgebra.hermitianpart\nLinearAlgebra.hermitianpart!\nLinearAlgebra.copy_adjoint!\nLinearAlgebra.copy_transpose!","category":"page"},{"location":"stdlib/LinearAlgebra/#Base.:*-Tuple{AbstractMatrix, AbstractMatrix}","page":"Linear Algebra","title":"Base.:*","text":"*(A::AbstractMatrix, B::AbstractMatrix)\n\nMatrix multiplication.\n\nExamples\n\njulia> [1 1; 0 1] * [1 0; 1 1]\n2×2 Matrix{Int64}:\n 2 1\n 1 1\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:*-Tuple{AbstractMatrix, AbstractMatrix, AbstractVector}","page":"Linear Algebra","title":"Base.:*","text":"*(A, B::AbstractMatrix, C)\nA * B * C * D\n\nChained multiplication of 3 or 4 matrices is done in the most efficient sequence, based on the sizes of the arrays. That is, the number of scalar multiplications needed for (A * B) * C (with 3 dense matrices) is compared to that for A * (B * C) to choose which of these to execute.\n\nIf the last factor is a vector, or the first a transposed vector, then it is efficient to deal with these first. In particular x' * B * y means (x' * B) * y for an ordinary column-major B::Matrix. Unlike dot(x, B, y), this allocates an intermediate array.\n\nIf the first or last factor is a number, this will be fused with the matrix multiplication, using 5-arg mul!.\n\nSee also muladd, dot.\n\ncompat: Julia 1.7\nThese optimisations require at least Julia 1.7.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:\\-Tuple{AbstractMatrix, AbstractVecOrMat}","page":"Linear Algebra","title":"Base.:\\","text":"\\(A, B)\n\nMatrix division using a polyalgorithm. For input matrices A and B, the result X is such that A*X == B when A is square. The solver that is used depends upon the structure of A. If A is upper or lower triangular (or diagonal), no factorization of A is required and the system is solved with either forward or backward substitution. For non-triangular square matrices, an LU factorization is used.\n\nFor rectangular A the result is the minimum-norm least squares solution computed by a pivoted QR factorization of A and a rank estimate of A based on the R factor.\n\nWhen A is sparse, a similar polyalgorithm is used. For indefinite matrices, the LDLt factorization does not use pivoting during the numerical factorization and therefore the procedure can fail even for invertible matrices.\n\nSee also: factorize, pinv.\n\nExamples\n\njulia> A = [1 0; 1 -2]; B = [32; -4];\n\njulia> X = A \\ B\n2-element Vector{Float64}:\n 32.0\n 18.0\n\njulia> A * X == B\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:/-Tuple{AbstractVecOrMat, AbstractVecOrMat}","page":"Linear Algebra","title":"Base.:/","text":"A / B\n\nMatrix right-division: A / B is equivalent to (B' \\ A')' where \\ is the left-division operator. For square matrices, the result X is such that A == X*B.\n\nSee also: rdiv!.\n\nExamples\n\njulia> A = Float64[1 4 5; 3 9 2]; B = Float64[1 4 2; 3 4 2; 8 7 1];\n\njulia> X = A / B\n2×3 Matrix{Float64}:\n -0.65 3.75 -1.2\n 3.25 -2.75 1.0\n\njulia> isapprox(A, X*B)\ntrue\n\njulia> isapprox(X, A*pinv(B))\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.SingularException","page":"Linear Algebra","title":"LinearAlgebra.SingularException","text":"SingularException\n\nException thrown when the input matrix has one or more zero-valued eigenvalues, and is not invertible. A linear solve involving such a matrix cannot be computed. The info field indicates the location of (one of) the singular value(s).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.PosDefException","page":"Linear Algebra","title":"LinearAlgebra.PosDefException","text":"PosDefException\n\nException thrown when the input matrix was not positive definite. Some linear algebra functions and factorizations are only applicable to positive definite matrices. The info field indicates the location of (one of) the eigenvalue(s) which is (are) less than/equal to 0.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ZeroPivotException","page":"Linear Algebra","title":"LinearAlgebra.ZeroPivotException","text":"ZeroPivotException <: Exception\n\nException thrown when a matrix factorization/solve encounters a zero in a pivot (diagonal) position and cannot proceed. This may not mean that the matrix is singular: it may be fruitful to switch to a different factorization such as pivoted LU that can re-order variables to eliminate spurious zero pivots. The info field indicates the location of (one of) the zero pivot(s).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.RankDeficientException","page":"Linear Algebra","title":"LinearAlgebra.RankDeficientException","text":"RankDeficientException\n\nException thrown when the input matrix is rank deficient. Some linear algebra functions, such as the Cholesky decomposition, are only applicable to matrices that are not rank deficient. The info field indicates the computed rank of the matrix.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACKException","page":"Linear Algebra","title":"LinearAlgebra.LAPACKException","text":"LAPACKException\n\nGeneric LAPACK exception thrown either during direct calls to the LAPACK functions or during calls to other functions that use the LAPACK functions internally but lack specialized error handling. The info field contains additional information on the underlying error and depends on the LAPACK function that was invoked.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.dot","page":"Linear Algebra","title":"LinearAlgebra.dot","text":"dot(x, y)\nx ⋅ y\n\nCompute the dot product between two vectors. For complex vectors, the first vector is conjugated.\n\ndot also works on arbitrary iterable objects, including arrays of any dimension, as long as dot is defined on the elements.\n\ndot is semantically equivalent to sum(dot(vx,vy) for (vx,vy) in zip(x, y)), with the added restriction that the arguments must have equal lengths.\n\nx ⋅ y (where ⋅ can be typed by tab-completing \\cdot in the REPL) is a synonym for dot(x, y).\n\nExamples\n\njulia> dot([1; 1], [2; 3])\n5\n\njulia> dot([im; im], [1; 1])\n0 - 2im\n\njulia> dot(1:5, 2:6)\n70\n\njulia> x = fill(2., (5,5));\n\njulia> y = fill(3., (5,5));\n\njulia> dot(x, y)\n150.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.dot-Tuple{Any, Any, Any}","page":"Linear Algebra","title":"LinearAlgebra.dot","text":"dot(x, A, y)\n\nCompute the generalized dot product dot(x, A*y) between two vectors x and y, without storing the intermediate result of A*y. As for the two-argument dot(_,_), this acts recursively. Moreover, for complex vectors, the first vector is conjugated.\n\ncompat: Julia 1.4\nThree-argument dot requires at least Julia 1.4.\n\nExamples\n\njulia> dot([1; 1], [1 2; 3 4], [2; 3])\n26\n\njulia> dot(1:5, reshape(1:25, 5, 5), 2:6)\n4850\n\njulia> ⋅(1:5, reshape(1:25, 5, 5), 2:6) == dot(1:5, reshape(1:25, 5, 5), 2:6)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.cross","page":"Linear Algebra","title":"LinearAlgebra.cross","text":"cross(x, y)\n×(x,y)\n\nCompute the cross product of two 3-vectors.\n\nExamples\n\njulia> a = [0;1;0]\n3-element Vector{Int64}:\n 0\n 1\n 0\n\njulia> b = [0;0;1]\n3-element Vector{Int64}:\n 0\n 0\n 1\n\njulia> cross(a,b)\n3-element Vector{Int64}:\n 1\n 0\n 0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.axpy!","page":"Linear Algebra","title":"LinearAlgebra.axpy!","text":"axpy!(α, x::AbstractArray, y::AbstractArray)\n\nOverwrite y with x * α + y and return y. If x and y have the same axes, it's equivalent with y .+= x .* a.\n\nExamples\n\njulia> x = [1; 2; 3];\n\njulia> y = [4; 5; 6];\n\njulia> axpy!(2, x, y)\n3-element Vector{Int64}:\n 6\n 9\n 12\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.axpby!","page":"Linear Algebra","title":"LinearAlgebra.axpby!","text":"axpby!(α, x::AbstractArray, β, y::AbstractArray)\n\nOverwrite y with x * α + y * β and return y. If x and y have the same axes, it's equivalent with y .= x .* a .+ y .* β.\n\nExamples\n\njulia> x = [1; 2; 3];\n\njulia> y = [4; 5; 6];\n\njulia> axpby!(2, x, 2, y)\n3-element Vector{Int64}:\n 10\n 14\n 18\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.rotate!","page":"Linear Algebra","title":"LinearAlgebra.rotate!","text":"rotate!(x, y, c, s)\n\nOverwrite x with c*x + s*y and y with -conj(s)*x + c*y. Returns x and y.\n\ncompat: Julia 1.5\nrotate! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.reflect!","page":"Linear Algebra","title":"LinearAlgebra.reflect!","text":"reflect!(x, y, c, s)\n\nOverwrite x with c*x + s*y and y with conj(s)*x - c*y. Returns x and y.\n\ncompat: Julia 1.5\nreflect! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.factorize","page":"Linear Algebra","title":"LinearAlgebra.factorize","text":"factorize(A)\n\nCompute a convenient factorization of A, based upon the type of the input matrix. factorize checks A to see if it is symmetric/triangular/etc. if A is passed as a generic matrix. factorize checks every element of A to verify/rule out each property. It will short-circuit as soon as it can rule out symmetry/triangular structure. The return value can be reused for efficient solving of multiple systems. For example: A=factorize(A); x=A\\b; y=A\\C.\n\nProperties of A type of factorization\nPositive-definite Cholesky (see cholesky)\nDense Symmetric/Hermitian Bunch-Kaufman (see bunchkaufman)\nSparse Symmetric/Hermitian LDLt (see ldlt)\nTriangular Triangular\nDiagonal Diagonal\nBidiagonal Bidiagonal\nTridiagonal LU (see lu)\nSymmetric real tridiagonal LDLt (see ldlt)\nGeneral square LU (see lu)\nGeneral non-square QR (see qr)\n\nIf factorize is called on a Hermitian positive-definite matrix, for instance, then factorize will return a Cholesky factorization.\n\nExamples\n\njulia> A = Array(Bidiagonal(fill(1.0, (5, 5)), :U))\n5×5 Matrix{Float64}:\n 1.0 1.0 0.0 0.0 0.0\n 0.0 1.0 1.0 0.0 0.0\n 0.0 0.0 1.0 1.0 0.0\n 0.0 0.0 0.0 1.0 1.0\n 0.0 0.0 0.0 0.0 1.0\n\njulia> factorize(A) # factorize will check to see that A is already factorized\n5×5 Bidiagonal{Float64, Vector{Float64}}:\n 1.0 1.0 ⋅ ⋅ ⋅\n ⋅ 1.0 1.0 ⋅ ⋅\n ⋅ ⋅ 1.0 1.0 ⋅\n ⋅ ⋅ ⋅ 1.0 1.0\n ⋅ ⋅ ⋅ ⋅ 1.0\n\nThis returns a 5×5 Bidiagonal{Float64}, which can now be passed to other linear algebra functions (e.g. eigensolvers) which will use specialized methods for Bidiagonal types.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Diagonal","page":"Linear Algebra","title":"LinearAlgebra.Diagonal","text":"Diagonal(V::AbstractVector)\n\nConstruct a lazy matrix with V as its diagonal.\n\nSee also UniformScaling for the lazy identity matrix I, diagm to make a dense matrix, and diag to extract diagonal elements.\n\nExamples\n\njulia> d = Diagonal([1, 10, 100])\n3×3 Diagonal{Int64, Vector{Int64}}:\n 1 ⋅ ⋅\n ⋅ 10 ⋅\n ⋅ ⋅ 100\n\njulia> diagm([7, 13])\n2×2 Matrix{Int64}:\n 7 0\n 0 13\n\njulia> ans + I\n2×2 Matrix{Int64}:\n 8 0\n 0 14\n\njulia> I(2)\n2×2 Diagonal{Bool, Vector{Bool}}:\n 1 ⋅\n ⋅ 1\n\nnote: Note\nA one-column matrix is not treated like a vector, but instead calls the method Diagonal(A::AbstractMatrix) which extracts 1-element diag(A):\n\njulia> A = transpose([7.0 13.0])\n2×1 transpose(::Matrix{Float64}) with eltype Float64:\n 7.0\n 13.0\n\njulia> Diagonal(A)\n1×1 Diagonal{Float64, Vector{Float64}}:\n 7.0\n\n\n\n\n\nDiagonal(A::AbstractMatrix)\n\nConstruct a matrix from the principal diagonal of A. The input matrix A may be rectangular, but the output will be square.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> D = Diagonal(A)\n2×2 Diagonal{Int64, Vector{Int64}}:\n 1 ⋅\n ⋅ 4\n\njulia> A = [1 2 3; 4 5 6]\n2×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n\njulia> Diagonal(A)\n2×2 Diagonal{Int64, Vector{Int64}}:\n 1 ⋅\n ⋅ 5\n\n\n\n\n\nDiagonal{T}(undef, n)\n\nConstruct an uninitialized Diagonal{T} of length n. See undef.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Bidiagonal","page":"Linear Algebra","title":"LinearAlgebra.Bidiagonal","text":"Bidiagonal(dv::V, ev::V, uplo::Symbol) where V <: AbstractVector\n\nConstructs an upper (uplo=:U) or lower (uplo=:L) bidiagonal matrix using the given diagonal (dv) and off-diagonal (ev) vectors. The result is of type Bidiagonal and provides efficient specialized linear solvers, but may be converted into a regular matrix with convert(Array, _) (or Array(_) for short). The length of ev must be one less than the length of dv.\n\nExamples\n\njulia> dv = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> ev = [7, 8, 9]\n3-element Vector{Int64}:\n 7\n 8\n 9\n\njulia> Bu = Bidiagonal(dv, ev, :U) # ev is on the first superdiagonal\n4×4 Bidiagonal{Int64, Vector{Int64}}:\n 1 7 ⋅ ⋅\n ⋅ 2 8 ⋅\n ⋅ ⋅ 3 9\n ⋅ ⋅ ⋅ 4\n\njulia> Bl = Bidiagonal(dv, ev, :L) # ev is on the first subdiagonal\n4×4 Bidiagonal{Int64, Vector{Int64}}:\n 1 ⋅ ⋅ ⋅\n 7 2 ⋅ ⋅\n ⋅ 8 3 ⋅\n ⋅ ⋅ 9 4\n\n\n\n\n\nBidiagonal(A, uplo::Symbol)\n\nConstruct a Bidiagonal matrix from the main diagonal of A and its first super- (if uplo=:U) or sub-diagonal (if uplo=:L).\n\nExamples\n\njulia> A = [1 1 1 1; 2 2 2 2; 3 3 3 3; 4 4 4 4]\n4×4 Matrix{Int64}:\n 1 1 1 1\n 2 2 2 2\n 3 3 3 3\n 4 4 4 4\n\njulia> Bidiagonal(A, :U) # contains the main diagonal and first superdiagonal of A\n4×4 Bidiagonal{Int64, Vector{Int64}}:\n 1 1 ⋅ ⋅\n ⋅ 2 2 ⋅\n ⋅ ⋅ 3 3\n ⋅ ⋅ ⋅ 4\n\njulia> Bidiagonal(A, :L) # contains the main diagonal and first subdiagonal of A\n4×4 Bidiagonal{Int64, Vector{Int64}}:\n 1 ⋅ ⋅ ⋅\n 2 2 ⋅ ⋅\n ⋅ 3 3 ⋅\n ⋅ ⋅ 4 4\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.SymTridiagonal","page":"Linear Algebra","title":"LinearAlgebra.SymTridiagonal","text":"SymTridiagonal(dv::V, ev::V) where V <: AbstractVector\n\nConstruct a symmetric tridiagonal matrix from the diagonal (dv) and first sub/super-diagonal (ev), respectively. The result is of type SymTridiagonal and provides efficient specialized eigensolvers, but may be converted into a regular matrix with convert(Array, _) (or Array(_) for short).\n\nFor SymTridiagonal block matrices, the elements of dv are symmetrized. The argument ev is interpreted as the superdiagonal. Blocks from the subdiagonal are (materialized) transpose of the corresponding superdiagonal blocks.\n\nExamples\n\njulia> dv = [1, 2, 3, 4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> ev = [7, 8, 9]\n3-element Vector{Int64}:\n 7\n 8\n 9\n\njulia> SymTridiagonal(dv, ev)\n4×4 SymTridiagonal{Int64, Vector{Int64}}:\n 1 7 ⋅ ⋅\n 7 2 8 ⋅\n ⋅ 8 3 9\n ⋅ ⋅ 9 4\n\njulia> A = SymTridiagonal(fill([1 2; 3 4], 3), fill([1 2; 3 4], 2));\n\njulia> A[1,1]\n2×2 Symmetric{Int64, Matrix{Int64}}:\n 1 2\n 2 4\n\njulia> A[1,2]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> A[2,1]\n2×2 Matrix{Int64}:\n 1 3\n 2 4\n\n\n\n\n\nSymTridiagonal(A::AbstractMatrix)\n\nConstruct a symmetric tridiagonal matrix from the diagonal and first superdiagonal of the symmetric matrix A.\n\nExamples\n\njulia> A = [1 2 3; 2 4 5; 3 5 6]\n3×3 Matrix{Int64}:\n 1 2 3\n 2 4 5\n 3 5 6\n\njulia> SymTridiagonal(A)\n3×3 SymTridiagonal{Int64, Vector{Int64}}:\n 1 2 ⋅\n 2 4 5\n ⋅ 5 6\n\njulia> B = reshape([[1 2; 2 3], [1 2; 3 4], [1 3; 2 4], [1 2; 2 3]], 2, 2);\n\njulia> SymTridiagonal(B)\n2×2 SymTridiagonal{Matrix{Int64}, Vector{Matrix{Int64}}}:\n [1 2; 2 3] [1 3; 2 4]\n [1 2; 3 4] [1 2; 2 3]\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Tridiagonal","page":"Linear Algebra","title":"LinearAlgebra.Tridiagonal","text":"Tridiagonal(dl::V, d::V, du::V) where V <: AbstractVector\n\nConstruct a tridiagonal matrix from the first subdiagonal, diagonal, and first superdiagonal, respectively. The result is of type Tridiagonal and provides efficient specialized linear solvers, but may be converted into a regular matrix with convert(Array, _) (or Array(_) for short). The lengths of dl and du must be one less than the length of d.\n\nnote: Note\nThe subdiagonal dl and the superdiagonal du must not be aliased to each other. If aliasing is detected, the constructor will use a copy of du as its argument.\n\nExamples\n\njulia> dl = [1, 2, 3];\n\njulia> du = [4, 5, 6];\n\njulia> d = [7, 8, 9, 0];\n\njulia> Tridiagonal(dl, d, du)\n4×4 Tridiagonal{Int64, Vector{Int64}}:\n 7 4 ⋅ ⋅\n 1 8 5 ⋅\n ⋅ 2 9 6\n ⋅ ⋅ 3 0\n\n\n\n\n\nTridiagonal(A)\n\nConstruct a tridiagonal matrix from the first sub-diagonal, diagonal and first super-diagonal of the matrix A.\n\nExamples\n\njulia> A = [1 2 3 4; 1 2 3 4; 1 2 3 4; 1 2 3 4]\n4×4 Matrix{Int64}:\n 1 2 3 4\n 1 2 3 4\n 1 2 3 4\n 1 2 3 4\n\njulia> Tridiagonal(A)\n4×4 Tridiagonal{Int64, Vector{Int64}}:\n 1 2 ⋅ ⋅\n 1 2 3 ⋅\n ⋅ 2 3 4\n ⋅ ⋅ 3 4\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Symmetric","page":"Linear Algebra","title":"LinearAlgebra.Symmetric","text":"Symmetric(A, uplo=:U)\n\nConstruct a Symmetric view of the upper (if uplo = :U) or lower (if uplo = :L) triangle of the matrix A.\n\nSymmetric views are mainly useful for real-symmetric matrices, for which specialized algorithms (e.g. for eigenproblems) are enabled for Symmetric types. More generally, see also Hermitian(A) for Hermitian matrices A == A', which is effectively equivalent to Symmetric for real matrices but is also useful for complex matrices. (Whereas complex Symmetric matrices are supported but have few if any specialized algorithms.)\n\nTo compute the symmetric part of a real matrix, or more generally the Hermitian part (A + A') / 2 of a real or complex matrix A, use hermitianpart.\n\nExamples\n\njulia> A = [1 2 3; 4 5 6; 7 8 9]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n 7 8 9\n\njulia> Supper = Symmetric(A)\n3×3 Symmetric{Int64, Matrix{Int64}}:\n 1 2 3\n 2 5 6\n 3 6 9\n\njulia> Slower = Symmetric(A, :L)\n3×3 Symmetric{Int64, Matrix{Int64}}:\n 1 4 7\n 4 5 8\n 7 8 9\n\njulia> hermitianpart(A)\n3×3 Hermitian{Float64, Matrix{Float64}}:\n 1.0 3.0 5.0\n 3.0 5.0 7.0\n 5.0 7.0 9.0\n\nNote that Supper will not be equal to Slower unless A is itself symmetric (e.g. if A == transpose(A)).\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Hermitian","page":"Linear Algebra","title":"LinearAlgebra.Hermitian","text":"Hermitian(A, uplo=:U)\n\nConstruct a Hermitian view of the upper (if uplo = :U) or lower (if uplo = :L) triangle of the matrix A.\n\nTo compute the Hermitian part of A, use hermitianpart.\n\nExamples\n\njulia> A = [1 2+2im 3-3im; 4 5 6-6im; 7 8+8im 9]\n3×3 Matrix{Complex{Int64}}:\n 1+0im 2+2im 3-3im\n 4+0im 5+0im 6-6im\n 7+0im 8+8im 9+0im\n\njulia> Hupper = Hermitian(A)\n3×3 Hermitian{Complex{Int64}, Matrix{Complex{Int64}}}:\n 1+0im 2+2im 3-3im\n 2-2im 5+0im 6-6im\n 3+3im 6+6im 9+0im\n\njulia> Hlower = Hermitian(A, :L)\n3×3 Hermitian{Complex{Int64}, Matrix{Complex{Int64}}}:\n 1+0im 4+0im 7+0im\n 4+0im 5+0im 8-8im\n 7+0im 8+8im 9+0im\n\njulia> hermitianpart(A)\n3×3 Hermitian{ComplexF64, Matrix{ComplexF64}}:\n 1.0+0.0im 3.0+1.0im 5.0-1.5im\n 3.0-1.0im 5.0+0.0im 7.0-7.0im\n 5.0+1.5im 7.0+7.0im 9.0+0.0im\n\nNote that Hupper will not be equal to Hlower unless A is itself Hermitian (e.g. if A == adjoint(A)).\n\nAll non-real parts of the diagonal will be ignored.\n\nHermitian(fill(complex(1,1), 1, 1)) == fill(1, 1, 1)\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LowerTriangular","page":"Linear Algebra","title":"LinearAlgebra.LowerTriangular","text":"LowerTriangular(A::AbstractMatrix)\n\nConstruct a LowerTriangular view of the matrix A.\n\nExamples\n\njulia> A = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]\n3×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> LowerTriangular(A)\n3×3 LowerTriangular{Float64, Matrix{Float64}}:\n 1.0 ⋅ ⋅\n 4.0 5.0 ⋅\n 7.0 8.0 9.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UpperTriangular","page":"Linear Algebra","title":"LinearAlgebra.UpperTriangular","text":"UpperTriangular(A::AbstractMatrix)\n\nConstruct an UpperTriangular view of the matrix A.\n\nExamples\n\njulia> A = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]\n3×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> UpperTriangular(A)\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 1.0 2.0 3.0\n ⋅ 5.0 6.0\n ⋅ ⋅ 9.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UnitLowerTriangular","page":"Linear Algebra","title":"LinearAlgebra.UnitLowerTriangular","text":"UnitLowerTriangular(A::AbstractMatrix)\n\nConstruct a UnitLowerTriangular view of the matrix A. Such a view has the oneunit of the eltype of A on its diagonal.\n\nExamples\n\njulia> A = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]\n3×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> UnitLowerTriangular(A)\n3×3 UnitLowerTriangular{Float64, Matrix{Float64}}:\n 1.0 ⋅ ⋅\n 4.0 1.0 ⋅\n 7.0 8.0 1.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UnitUpperTriangular","page":"Linear Algebra","title":"LinearAlgebra.UnitUpperTriangular","text":"UnitUpperTriangular(A::AbstractMatrix)\n\nConstruct an UnitUpperTriangular view of the matrix A. Such a view has the oneunit of the eltype of A on its diagonal.\n\nExamples\n\njulia> A = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]\n3×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0\n 7.0 8.0 9.0\n\njulia> UnitUpperTriangular(A)\n3×3 UnitUpperTriangular{Float64, Matrix{Float64}}:\n 1.0 2.0 3.0\n ⋅ 1.0 6.0\n ⋅ ⋅ 1.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UpperHessenberg","page":"Linear Algebra","title":"LinearAlgebra.UpperHessenberg","text":"UpperHessenberg(A::AbstractMatrix)\n\nConstruct an UpperHessenberg view of the matrix A. Entries of A below the first subdiagonal are ignored.\n\ncompat: Julia 1.3\nThis type was added in Julia 1.3.\n\nEfficient algorithms are implemented for H \\ b, det(H), and similar.\n\nSee also the hessenberg function to factor any matrix into a similar upper-Hessenberg matrix.\n\nIf F::Hessenberg is the factorization object, the unitary matrix can be accessed with F.Q and the Hessenberg matrix with F.H. When Q is extracted, the resulting type is the HessenbergQ object, and may be converted to a regular matrix with convert(Array, _) (or Array(_) for short).\n\nIterating the decomposition produces the factors F.Q and F.H.\n\nExamples\n\njulia> A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]\n4×4 Matrix{Int64}:\n 1 2 3 4\n 5 6 7 8\n 9 10 11 12\n 13 14 15 16\n\njulia> UpperHessenberg(A)\n4×4 UpperHessenberg{Int64, Matrix{Int64}}:\n 1 2 3 4\n 5 6 7 8\n ⋅ 10 11 12\n ⋅ ⋅ 15 16\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UniformScaling","page":"Linear Algebra","title":"LinearAlgebra.UniformScaling","text":"UniformScaling{T<:Number}\n\nGenerically sized uniform scaling operator defined as a scalar times the identity operator, λ*I. Although without an explicit size, it acts similarly to a matrix in many cases and includes support for some indexing. See also I.\n\ncompat: Julia 1.6\nIndexing using ranges is available as of Julia 1.6.\n\nExamples\n\njulia> J = UniformScaling(2.)\nUniformScaling{Float64}\n2.0*I\n\njulia> A = [1. 2.; 3. 4.]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> J*A\n2×2 Matrix{Float64}:\n 2.0 4.0\n 6.0 8.0\n\njulia> J[1:2, 1:2]\n2×2 Matrix{Float64}:\n 2.0 0.0\n 0.0 2.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.I","page":"Linear Algebra","title":"LinearAlgebra.I","text":"I\n\nAn object of type UniformScaling, representing an identity matrix of any size.\n\nExamples\n\njulia> fill(1, (5,6)) * I == fill(1, (5,6))\ntrue\n\njulia> [1 2im 3; 1im 2 3] * I\n2×3 Matrix{Complex{Int64}}:\n 1+0im 0+2im 3+0im\n 0+1im 2+0im 3+0im\n\n\n\n\n\n","category":"constant"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.UniformScaling-Tuple{Integer}","page":"Linear Algebra","title":"LinearAlgebra.UniformScaling","text":"(I::UniformScaling)(n::Integer)\n\nConstruct a Diagonal matrix from a UniformScaling.\n\ncompat: Julia 1.2\nThis method is available as of Julia 1.2.\n\nExamples\n\njulia> I(3)\n3×3 Diagonal{Bool, Vector{Bool}}:\n 1 ⋅ ⋅\n ⋅ 1 ⋅\n ⋅ ⋅ 1\n\njulia> (0.7*I)(3)\n3×3 Diagonal{Float64, Vector{Float64}}:\n 0.7 ⋅ ⋅\n ⋅ 0.7 ⋅\n ⋅ ⋅ 0.7\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Factorization","page":"Linear Algebra","title":"LinearAlgebra.Factorization","text":"LinearAlgebra.Factorization\n\nAbstract type for matrix factorizations a.k.a. matrix decompositions. See online documentation for a list of available matrix factorizations.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LU","page":"Linear Algebra","title":"LinearAlgebra.LU","text":"LU <: Factorization\n\nMatrix factorization type of the LU factorization of a square matrix A. This is the return type of lu, the corresponding matrix factorization function.\n\nThe individual components of the factorization F::LU can be accessed via getproperty:\n\nComponent Description\nF.L L (unit lower triangular) part of LU\nF.U U (upper triangular) part of LU\nF.p (right) permutation Vector\nF.P (right) permutation Matrix\n\nIterating the factorization produces the components F.L, F.U, and F.p.\n\nExamples\n\njulia> A = [4 3; 6 3]\n2×2 Matrix{Int64}:\n 4 3\n 6 3\n\njulia> F = lu(A)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.666667 1.0\nU factor:\n2×2 Matrix{Float64}:\n 6.0 3.0\n 0.0 1.0\n\njulia> F.L * F.U == A[F.p, :]\ntrue\n\njulia> l, u, p = lu(A); # destructuring via iteration\n\njulia> l == F.L && u == F.U && p == F.p\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lu","page":"Linear Algebra","title":"LinearAlgebra.lu","text":"lu(A::AbstractSparseMatrixCSC; check = true, q = nothing, control = get_umfpack_control()) -> F::UmfpackLU\n\nCompute the LU factorization of a sparse matrix A.\n\nFor sparse A with real or complex element type, the return type of F is UmfpackLU{Tv, Ti}, with Tv = Float64 or ComplexF64 respectively and Ti is an integer type (Int32 or Int64).\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nThe permutation q can either be a permutation vector or nothing. If no permutation vector is provided or q is nothing, UMFPACK's default is used. If the permutation is not zero-based, a zero-based copy is made.\n\nThe control vector defaults to the Julia SparseArrays package's default configuration for UMFPACK (NB: this is modified from the UMFPACK defaults to disable iterative refinement), but can be changed by passing a vector of length UMFPACK_CONTROL, see the UMFPACK manual for possible configurations. For example to reenable iterative refinement:\n\numfpack_control = SparseArrays.UMFPACK.get_umfpack_control(Float64, Int64) # read Julia default configuration for a Float64 sparse matrix\nSparseArrays.UMFPACK.show_umf_ctrl(umfpack_control) # optional - display values\numfpack_control[SparseArrays.UMFPACK.JL_UMFPACK_IRSTEP] = 2.0 # reenable iterative refinement (2 is UMFPACK default max iterative refinement steps)\n\nAlu = lu(A; control = umfpack_control)\nx = Alu \\ b # solve Ax = b, including UMFPACK iterative refinement\n\nThe individual components of the factorization F can be accessed by indexing:\n\nComponent Description\nL L (lower triangular) part of LU\nU U (upper triangular) part of LU\np right permutation Vector\nq left permutation Vector\nRs Vector of scaling factors\n: (L,U,p,q,Rs) components\n\nThe relation between F and A is\n\nF.L*F.U == (F.Rs .* A)[F.p, F.q]\n\nF further supports the following functions:\n\n\\\ndet\n\nSee also lu!\n\nnote: Note\nlu(A::AbstractSparseMatrixCSC) uses the UMFPACK[ACM832] library that is part of SuiteSparse. As this library only supports sparse matrices with Float64 or ComplexF64 elements, lu converts A into a copy that is of type SparseMatrixCSC{Float64} or SparseMatrixCSC{ComplexF64} as appropriate.\n\n[ACM832]: Davis, Timothy A. (2004b). Algorithm 832: UMFPACK V4.3–-an Unsymmetric-Pattern Multifrontal Method. ACM Trans. Math. Softw., 30(2), 196–199. doi:10.1145/992200.992206\n\n\n\n\n\nlu(A, pivot = RowMaximum(); check = true, allowsingular = false) -> F::LU\n\nCompute the LU factorization of A.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nBy default, with check = true, an error is also thrown when the decomposition produces valid factors, but the upper-triangular factor U is rank-deficient. This may be changed by passing allowsingular = true.\n\nIn most cases, if A is a subtype S of AbstractMatrix{T} with an element type T supporting +, -, * and /, the return type is LU{T,S{T}}.\n\nIn general, LU factorization involves a permutation of the rows of the matrix (corresponding to the F.p output described below), known as \"pivoting\" (because it corresponds to choosing which row contains the \"pivot\", the diagonal entry of F.U). One of the following pivoting strategies can be selected via the optional pivot argument:\n\nRowMaximum() (default): the standard pivoting strategy; the pivot corresponds to the element of maximum absolute value among the remaining, to be factorized rows. This pivoting strategy requires the element type to also support abs and <. (This is generally the only numerically stable option for floating-point matrices.)\nRowNonZero(): the pivot corresponds to the first non-zero element among the remaining, to be factorized rows. (This corresponds to the typical choice in hand calculations, and is also useful for more general algebraic number types that support iszero but not abs or <.)\nNoPivot(): pivoting turned off (will fail if a zero entry is encountered in a pivot position, even when allowsingular = true).\n\nThe individual components of the factorization F can be accessed via getproperty:\n\nComponent Description\nF.L L (lower triangular) part of LU\nF.U U (upper triangular) part of LU\nF.p (right) permutation Vector\nF.P (right) permutation Matrix\n\nIterating the factorization produces the components F.L, F.U, and F.p.\n\nThe relationship between F and A is\n\nF.L*F.U == A[F.p, :]\n\nF further supports the following functions:\n\nSupported function LU LU{T,Tridiagonal{T}}\n/ ✓ \n\\ ✓ ✓\ninv ✓ ✓\ndet ✓ ✓\nlogdet ✓ ✓\nlogabsdet ✓ ✓\nsize ✓ ✓\n\ncompat: Julia 1.11\nThe allowsingular keyword argument was added in Julia 1.11.\n\nExamples\n\njulia> A = [4 3; 6 3]\n2×2 Matrix{Int64}:\n 4 3\n 6 3\n\njulia> F = lu(A)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.666667 1.0\nU factor:\n2×2 Matrix{Float64}:\n 6.0 3.0\n 0.0 1.0\n\njulia> F.L * F.U == A[F.p, :]\ntrue\n\njulia> l, u, p = lu(A); # destructuring via iteration\n\njulia> l == F.L && u == F.U && p == F.p\ntrue\n\njulia> lu([1 2; 1 2], allowsingular = true)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 1.0 1.0\nU factor (rank-deficient):\n2×2 Matrix{Float64}:\n 1.0 2.0\n 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lu!","page":"Linear Algebra","title":"LinearAlgebra.lu!","text":"lu!(F::UmfpackLU, A::AbstractSparseMatrixCSC; check=true, reuse_symbolic=true, q=nothing) -> F::UmfpackLU\n\nCompute the LU factorization of a sparse matrix A, reusing the symbolic factorization of an already existing LU factorization stored in F. Unless reuse_symbolic is set to false, the sparse matrix A must have an identical nonzero pattern as the matrix used to create the LU factorization F, otherwise an error is thrown. If the size of A and F differ, all vectors will be resized accordingly.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nThe permutation q can either be a permutation vector or nothing. If no permutation vector is provided or q is nothing, UMFPACK's default is used. If the permutation is not zero based, a zero based copy is made.\n\nSee also lu\n\nnote: Note\nlu!(F::UmfpackLU, A::AbstractSparseMatrixCSC) uses the UMFPACK library that is part of SuiteSparse. As this library only supports sparse matrices with Float64 or ComplexF64 elements, lu! will automatically convert the types to those set by the LU factorization or SparseMatrixCSC{ComplexF64} as appropriate.\n\ncompat: Julia 1.5\nlu! for UmfpackLU requires at least Julia 1.5.\n\nExamples\n\njulia> A = sparse(Float64[1.0 2.0; 0.0 3.0]);\n\njulia> F = lu(A);\n\njulia> B = sparse(Float64[1.0 1.0; 0.0 1.0]);\n\njulia> lu!(F, B);\n\njulia> F \\ ones(2)\n2-element Vector{Float64}:\n 0.0\n 1.0\n\n\n\n\n\nlu!(A, pivot = RowMaximum(); check = true, allowsingular = false) -> LU\n\nlu! is the same as lu, but saves space by overwriting the input A, instead of creating a copy. An InexactError exception is thrown if the factorization produces a number not representable by the element type of A, e.g. for integer types.\n\ncompat: Julia 1.11\nThe allowsingular keyword argument was added in Julia 1.11.\n\nExamples\n\njulia> A = [4. 3.; 6. 3.]\n2×2 Matrix{Float64}:\n 4.0 3.0\n 6.0 3.0\n\njulia> F = lu!(A)\nLU{Float64, Matrix{Float64}, Vector{Int64}}\nL factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.666667 1.0\nU factor:\n2×2 Matrix{Float64}:\n 6.0 3.0\n 0.0 1.0\n\njulia> iA = [4 3; 6 3]\n2×2 Matrix{Int64}:\n 4 3\n 6 3\n\njulia> lu!(iA)\nERROR: InexactError: Int64(0.6666666666666666)\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Cholesky","page":"Linear Algebra","title":"LinearAlgebra.Cholesky","text":"Cholesky <: Factorization\n\nMatrix factorization type of the Cholesky factorization of a dense symmetric/Hermitian positive definite matrix A. This is the return type of cholesky, the corresponding matrix factorization function.\n\nThe triangular Cholesky factor can be obtained from the factorization F::Cholesky via F.L and F.U, where A ≈ F.U' * F.U ≈ F.L * F.L'.\n\nThe following functions are available for Cholesky objects: size, \\, inv, det, logdet and isposdef.\n\nIterating the decomposition produces the components L and U.\n\nExamples\n\njulia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.]\n3×3 Matrix{Float64}:\n 4.0 12.0 -16.0\n 12.0 37.0 -43.0\n -16.0 -43.0 98.0\n\njulia> C = cholesky(A)\nCholesky{Float64, Matrix{Float64}}\nU factor:\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 2.0 6.0 -8.0\n ⋅ 1.0 5.0\n ⋅ ⋅ 3.0\n\njulia> C.U\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 2.0 6.0 -8.0\n ⋅ 1.0 5.0\n ⋅ ⋅ 3.0\n\njulia> C.L\n3×3 LowerTriangular{Float64, Matrix{Float64}}:\n 2.0 ⋅ ⋅\n 6.0 1.0 ⋅\n -8.0 5.0 3.0\n\njulia> C.L * C.U == A\ntrue\n\njulia> l, u = C; # destructuring via iteration\n\njulia> l == C.L && u == C.U\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.CholeskyPivoted","page":"Linear Algebra","title":"LinearAlgebra.CholeskyPivoted","text":"CholeskyPivoted\n\nMatrix factorization type of the pivoted Cholesky factorization of a dense symmetric/Hermitian positive semi-definite matrix A. This is the return type of cholesky(_, ::RowMaximum), the corresponding matrix factorization function.\n\nThe triangular Cholesky factor can be obtained from the factorization F::CholeskyPivoted via F.L and F.U, and the permutation via F.p, where A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr' with Ur = F.U[1:F.rank, :] and Lr = F.L[:, 1:F.rank], or alternatively A ≈ Up' * Up ≈ Lp * Lp' with Up = F.U[1:F.rank, invperm(F.p)] and Lp = F.L[invperm(F.p), 1:F.rank].\n\nThe following functions are available for CholeskyPivoted objects: size, \\, inv, det, and rank.\n\nIterating the decomposition produces the components L and U.\n\nExamples\n\njulia> X = [1.0, 2.0, 3.0, 4.0];\n\njulia> A = X * X';\n\njulia> C = cholesky(A, RowMaximum(), check = false)\nCholeskyPivoted{Float64, Matrix{Float64}, Vector{Int64}}\nU factor with rank 1:\n4×4 UpperTriangular{Float64, Matrix{Float64}}:\n 4.0 2.0 3.0 1.0\n ⋅ 0.0 6.0 2.0\n ⋅ ⋅ 9.0 3.0\n ⋅ ⋅ ⋅ 1.0\npermutation:\n4-element Vector{Int64}:\n 4\n 2\n 3\n 1\n\njulia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p]\ntrue\n\njulia> l, u = C; # destructuring via iteration\n\njulia> l == C.L && u == C.U\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.cholesky","page":"Linear Algebra","title":"LinearAlgebra.cholesky","text":"cholesky(A, NoPivot(); check = true) -> Cholesky\n\nCompute the Cholesky factorization of a dense symmetric positive definite matrix A and return a Cholesky factorization. The matrix A can either be a Symmetric or Hermitian AbstractMatrix or a perfectly symmetric or Hermitian AbstractMatrix.\n\nThe triangular Cholesky factor can be obtained from the factorization F via F.L and F.U, where A ≈ F.U' * F.U ≈ F.L * F.L'.\n\nThe following functions are available for Cholesky objects: size, \\, inv, det, logdet and isposdef.\n\nIf you have a matrix A that is slightly non-Hermitian due to roundoff errors in its construction, wrap it in Hermitian(A) before passing it to cholesky in order to treat it as perfectly Hermitian.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nExamples\n\njulia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.]\n3×3 Matrix{Float64}:\n 4.0 12.0 -16.0\n 12.0 37.0 -43.0\n -16.0 -43.0 98.0\n\njulia> C = cholesky(A)\nCholesky{Float64, Matrix{Float64}}\nU factor:\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 2.0 6.0 -8.0\n ⋅ 1.0 5.0\n ⋅ ⋅ 3.0\n\njulia> C.U\n3×3 UpperTriangular{Float64, Matrix{Float64}}:\n 2.0 6.0 -8.0\n ⋅ 1.0 5.0\n ⋅ ⋅ 3.0\n\njulia> C.L\n3×3 LowerTriangular{Float64, Matrix{Float64}}:\n 2.0 ⋅ ⋅\n 6.0 1.0 ⋅\n -8.0 5.0 3.0\n\njulia> C.L * C.U == A\ntrue\n\n\n\n\n\ncholesky(A, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted\n\nCompute the pivoted Cholesky factorization of a dense symmetric positive semi-definite matrix A and return a CholeskyPivoted factorization. The matrix A can either be a Symmetric or Hermitian AbstractMatrix or a perfectly symmetric or Hermitian AbstractMatrix.\n\nThe triangular Cholesky factor can be obtained from the factorization F via F.L and F.U, and the permutation via F.p, where A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr' with Ur = F.U[1:F.rank, :] and Lr = F.L[:, 1:F.rank], or alternatively A ≈ Up' * Up ≈ Lp * Lp' with Up = F.U[1:F.rank, invperm(F.p)] and Lp = F.L[invperm(F.p), 1:F.rank].\n\nThe following functions are available for CholeskyPivoted objects: size, \\, inv, det, and rank.\n\nThe argument tol determines the tolerance for determining the rank. For negative values, the tolerance is the machine precision.\n\nIf you have a matrix A that is slightly non-Hermitian due to roundoff errors in its construction, wrap it in Hermitian(A) before passing it to cholesky in order to treat it as perfectly Hermitian.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nExamples\n\njulia> X = [1.0, 2.0, 3.0, 4.0];\n\njulia> A = X * X';\n\njulia> C = cholesky(A, RowMaximum(), check = false)\nCholeskyPivoted{Float64, Matrix{Float64}, Vector{Int64}}\nU factor with rank 1:\n4×4 UpperTriangular{Float64, Matrix{Float64}}:\n 4.0 2.0 3.0 1.0\n ⋅ 0.0 6.0 2.0\n ⋅ ⋅ 9.0 3.0\n ⋅ ⋅ ⋅ 1.0\npermutation:\n4-element Vector{Int64}:\n 4\n 2\n 3\n 1\n\njulia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p]\ntrue\n\njulia> l, u = C; # destructuring via iteration\n\njulia> l == C.L && u == C.U\ntrue\n\n\n\n\n\ncholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.Factor\n\nCompute the Cholesky factorization of a sparse positive definite matrix A. A must be a SparseMatrixCSC or a Symmetric/Hermitian view of a SparseMatrixCSC. Note that even if A doesn't have the type tag, it must still be symmetric or Hermitian. If perm is not given, a fill-reducing permutation is used. F = cholesky(A) is most frequently used to solve systems of equations with F\\b, but also the methods diag, det, and logdet are defined for F. You can also extract individual factors from F, using F.L. However, since pivoting is on by default, the factorization is internally represented as A == P'*L*L'*P with a permutation matrix P; using just L without accounting for P will give incorrect answers. To include the effects of permutation, it's typically preferable to extract \"combined\" factors like PtL = F.PtL (the equivalent of P'*L) and LtP = F.UP (the equivalent of L'*P).\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nSetting the optional shift keyword argument computes the factorization of A+shift*I instead of A. If the perm argument is provided, it should be a permutation of 1:size(A,1) giving the ordering to use (instead of CHOLMOD's default AMD ordering).\n\nExamples\n\nIn the following example, the fill-reducing permutation used is [3, 2, 1]. If perm is set to 1:3 to enforce no permutation, the number of nonzero elements in the factor is 6.\n\njulia> A = [2 1 1; 1 2 0; 1 0 2]\n3×3 Matrix{Int64}:\n 2 1 1\n 1 2 0\n 1 0 2\n\njulia> C = cholesky(sparse(A))\nSparseArrays.CHOLMOD.Factor{Float64, Int64}\ntype: LLt\nmethod: simplicial\nmaxnnz: 5\nnnz: 5\nsuccess: true\n\njulia> C.p\n3-element Vector{Int64}:\n 3\n 2\n 1\n\njulia> L = sparse(C.L);\n\njulia> Matrix(L)\n3×3 Matrix{Float64}:\n 1.41421 0.0 0.0\n 0.0 1.41421 0.0\n 0.707107 0.707107 1.0\n\njulia> L * L' ≈ A[C.p, C.p]\ntrue\n\njulia> P = sparse(1:3, C.p, ones(3))\n3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:\n ⋅ ⋅ 1.0\n ⋅ 1.0 ⋅\n 1.0 ⋅ ⋅\n\njulia> P' * L * L' * P ≈ A\ntrue\n\njulia> C = cholesky(sparse(A), perm=1:3)\nSparseArrays.CHOLMOD.Factor{Float64, Int64}\ntype: LLt\nmethod: simplicial\nmaxnnz: 6\nnnz: 6\nsuccess: true\n\njulia> L = sparse(C.L);\n\njulia> Matrix(L)\n3×3 Matrix{Float64}:\n 1.41421 0.0 0.0\n 0.707107 1.22474 0.0\n 0.707107 -0.408248 1.1547\n\njulia> L * L' ≈ A\ntrue\n\nnote: Note\nThis method uses the CHOLMOD[ACM887][DavisHager2009] library from SuiteSparse. CHOLMOD only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.Many other functions from CHOLMOD are wrapped but not exported from the Base.SparseArrays.CHOLMOD module.\n\n[ACM887]: Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008). Algorithm 887: CHOLMOD, Supernodal Sparse Cholesky Factorization and Update/Downdate. ACM Trans. Math. Softw., 35(3). doi:10.1145/1391989.1391995\n\n[DavisHager2009]: Davis, Timothy A., & Hager, W. W. (2009). Dynamic Supernodes in Sparse Cholesky Update/Downdate and Triangular Solves. ACM Trans. Math. Softw., 35(4). doi:10.1145/1462173.1462176\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.cholesky!","page":"Linear Algebra","title":"LinearAlgebra.cholesky!","text":"cholesky!(A::AbstractMatrix, NoPivot(); check = true) -> Cholesky\n\nThe same as cholesky, but saves space by overwriting the input A, instead of creating a copy. An InexactError exception is thrown if the factorization produces a number not representable by the element type of A, e.g. for integer types.\n\nExamples\n\njulia> A = [1 2; 2 50]\n2×2 Matrix{Int64}:\n 1 2\n 2 50\n\njulia> cholesky!(A)\nERROR: InexactError: Int64(6.782329983125268)\nStacktrace:\n[...]\n\n\n\n\n\ncholesky!(A::AbstractMatrix, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted\n\nThe same as cholesky, but saves space by overwriting the input A, instead of creating a copy. An InexactError exception is thrown if the factorization produces a number not representable by the element type of A, e.g. for integer types.\n\n\n\n\n\ncholesky!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.Factor\n\nCompute the Cholesky (LL) factorization of A, reusing the symbolic factorization F. A must be a SparseMatrixCSC or a Symmetric/ Hermitian view of a SparseMatrixCSC. Note that even if A doesn't have the type tag, it must still be symmetric or Hermitian.\n\nSee also cholesky.\n\nnote: Note\nThis method uses the CHOLMOD library from SuiteSparse, which only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lowrankupdate","page":"Linear Algebra","title":"LinearAlgebra.lowrankupdate","text":"lowrankupdate(C::Cholesky, v::AbstractVector) -> CC::Cholesky\n\nUpdate a Cholesky factorization C with the vector v. If A = C.U'C.U then CC = cholesky(C.U'C.U + v*v') but the computation of CC only uses O(n^2) operations.\n\n\n\n\n\nlowrankupdate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor\n\nGet an LDLt Factorization of A + C*C' given an LDLt or LLt factorization F of A.\n\nThe returned factor is always an LDLt factorization.\n\nSee also lowrankupdate!, lowrankdowndate, lowrankdowndate!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lowrankdowndate","page":"Linear Algebra","title":"LinearAlgebra.lowrankdowndate","text":"lowrankdowndate(C::Cholesky, v::AbstractVector) -> CC::Cholesky\n\nDowndate a Cholesky factorization C with the vector v. If A = C.U'C.U then CC = cholesky(C.U'C.U - v*v') but the computation of CC only uses O(n^2) operations.\n\n\n\n\n\nlowrankdowndate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor\n\nGet an LDLt Factorization of A + C*C' given an LDLt or LLt factorization F of A.\n\nThe returned factor is always an LDLt factorization.\n\nSee also lowrankdowndate!, lowrankupdate, lowrankupdate!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lowrankupdate!","page":"Linear Algebra","title":"LinearAlgebra.lowrankupdate!","text":"lowrankupdate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky\n\nUpdate a Cholesky factorization C with the vector v. If A = C.U'C.U then CC = cholesky(C.U'C.U + v*v') but the computation of CC only uses O(n^2) operations. The input factorization C is updated in place such that on exit C == CC. The vector v is destroyed during the computation.\n\n\n\n\n\nlowrankupdate!(F::CHOLMOD.Factor, C::AbstractArray)\n\nUpdate an LDLt or LLt Factorization F of A to a factorization of A + C*C'.\n\nLLt factorizations are converted to LDLt.\n\nSee also lowrankupdate, lowrankdowndate, lowrankdowndate!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lowrankdowndate!","page":"Linear Algebra","title":"LinearAlgebra.lowrankdowndate!","text":"lowrankdowndate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky\n\nDowndate a Cholesky factorization C with the vector v. If A = C.U'C.U then CC = cholesky(C.U'C.U - v*v') but the computation of CC only uses O(n^2) operations. The input factorization C is updated in place such that on exit C == CC. The vector v is destroyed during the computation.\n\n\n\n\n\nlowrankdowndate!(F::CHOLMOD.Factor, C::AbstractArray)\n\nUpdate an LDLt or LLt Factorization F of A to a factorization of A - C*C'.\n\nLLt factorizations are converted to LDLt.\n\nSee also lowrankdowndate, lowrankupdate, lowrankupdate!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LDLt","page":"Linear Algebra","title":"LinearAlgebra.LDLt","text":"LDLt <: Factorization\n\nMatrix factorization type of the LDLt factorization of a real SymTridiagonal matrix S such that S = L*Diagonal(d)*L', where L is a UnitLowerTriangular matrix and d is a vector. The main use of an LDLt factorization F = ldlt(S) is to solve the linear system of equations Sx = b with F\\b. This is the return type of ldlt, the corresponding matrix factorization function.\n\nThe individual components of the factorization F::LDLt can be accessed via getproperty:\n\nComponent Description\nF.L L (unit lower triangular) part of LDLt\nF.D D (diagonal) part of LDLt\nF.Lt Lt (unit upper triangular) part of LDLt\nF.d diagonal values of D as a Vector\n\nExamples\n\njulia> S = SymTridiagonal([3., 4., 5.], [1., 2.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 3.0 1.0 ⋅\n 1.0 4.0 2.0\n ⋅ 2.0 5.0\n\njulia> F = ldlt(S)\nLDLt{Float64, SymTridiagonal{Float64, Vector{Float64}}}\nL factor:\n3×3 UnitLowerTriangular{Float64, SymTridiagonal{Float64, Vector{Float64}}}:\n 1.0 ⋅ ⋅\n 0.333333 1.0 ⋅\n 0.0 0.545455 1.0\nD factor:\n3×3 Diagonal{Float64, Vector{Float64}}:\n 3.0 ⋅ ⋅\n ⋅ 3.66667 ⋅\n ⋅ ⋅ 3.90909\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ldlt","page":"Linear Algebra","title":"LinearAlgebra.ldlt","text":"ldlt(S::SymTridiagonal) -> LDLt\n\nCompute an LDLt (i.e., LDL^T) factorization of the real symmetric tridiagonal matrix S such that S = L*Diagonal(d)*L' where L is a unit lower triangular matrix and d is a vector. The main use of an LDLt factorization F = ldlt(S) is to solve the linear system of equations Sx = b with F\\b.\n\nSee also bunchkaufman for a similar, but pivoted, factorization of arbitrary symmetric or Hermitian matrices.\n\nExamples\n\njulia> S = SymTridiagonal([3., 4., 5.], [1., 2.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 3.0 1.0 ⋅\n 1.0 4.0 2.0\n ⋅ 2.0 5.0\n\njulia> ldltS = ldlt(S);\n\njulia> b = [6., 7., 8.];\n\njulia> ldltS \\ b\n3-element Vector{Float64}:\n 1.7906976744186047\n 0.627906976744186\n 1.3488372093023255\n\njulia> S \\ b\n3-element Vector{Float64}:\n 1.7906976744186047\n 0.627906976744186\n 1.3488372093023255\n\n\n\n\n\nldlt(A::SparseMatrixCSC; shift = 0.0, check = true, perm=nothing) -> CHOLMOD.Factor\n\nCompute the LDL factorization of a sparse matrix A. A must be a SparseMatrixCSC or a Symmetric/Hermitian view of a SparseMatrixCSC. Note that even if A doesn't have the type tag, it must still be symmetric or Hermitian. A fill-reducing permutation is used. F = ldlt(A) is most frequently used to solve systems of equations A*x = b with F\\b. The returned factorization object F also supports the methods diag, det, logdet, and inv. You can extract individual factors from F using F.L. However, since pivoting is on by default, the factorization is internally represented as A == P'*L*D*L'*P with a permutation matrix P; using just L without accounting for P will give incorrect answers. To include the effects of permutation, it is typically preferable to extract \"combined\" factors like PtL = F.PtL (the equivalent of P'*L) and LtP = F.UP (the equivalent of L'*P). The complete list of supported factors is :L, :PtL, :D, :UP, :U, :LD, :DU, :PtLD, :DUP.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nSetting the optional shift keyword argument computes the factorization of A+shift*I instead of A. If the perm argument is provided, it should be a permutation of 1:size(A,1) giving the ordering to use (instead of CHOLMOD's default AMD ordering).\n\nnote: Note\nThis method uses the CHOLMOD[ACM887][DavisHager2009] library from SuiteSparse. CHOLMOD only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.Many other functions from CHOLMOD are wrapped but not exported from the Base.SparseArrays.CHOLMOD module.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ldlt!","page":"Linear Algebra","title":"LinearAlgebra.ldlt!","text":"ldlt!(S::SymTridiagonal) -> LDLt\n\nSame as ldlt, but saves space by overwriting the input S, instead of creating a copy.\n\nExamples\n\njulia> S = SymTridiagonal([3., 4., 5.], [1., 2.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 3.0 1.0 ⋅\n 1.0 4.0 2.0\n ⋅ 2.0 5.0\n\njulia> ldltS = ldlt!(S);\n\njulia> ldltS === S\nfalse\n\njulia> S\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 3.0 0.333333 ⋅\n 0.333333 3.66667 0.545455\n ⋅ 0.545455 3.90909\n\n\n\n\n\nldlt!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.Factor\n\nCompute the LDL factorization of A, reusing the symbolic factorization F. A must be a SparseMatrixCSC or a Symmetric/Hermitian view of a SparseMatrixCSC. Note that even if A doesn't have the type tag, it must still be symmetric or Hermitian.\n\nSee also ldlt.\n\nnote: Note\nThis method uses the CHOLMOD library from SuiteSparse, which only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.QR","page":"Linear Algebra","title":"LinearAlgebra.QR","text":"QR <: Factorization\n\nA QR matrix factorization stored in a packed format, typically obtained from qr. If A is an m×n matrix, then\n\nA = Q R\n\nwhere Q is an orthogonal/unitary matrix and R is upper triangular. The matrix Q is stored as a sequence of Householder reflectors v_i and coefficients tau_i where:\n\nQ = prod_i=1^min(mn) (I - tau_i v_i v_i^T)\n\nIterating the decomposition produces the components Q and R.\n\nThe object has two fields:\n\nfactors is an m×n matrix.\nThe upper triangular part contains the elements of R, that is R = triu(F.factors) for a QR object F.\nThe subdiagonal part contains the reflectors v_i stored in a packed format where v_i is the ith column of the matrix V = I + tril(F.factors, -1).\nτ is a vector of length min(m,n) containing the coefficients au_i.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.QRCompactWY","page":"Linear Algebra","title":"LinearAlgebra.QRCompactWY","text":"QRCompactWY <: Factorization\n\nA QR matrix factorization stored in a compact blocked format, typically obtained from qr. If A is an m×n matrix, then\n\nA = Q R\n\nwhere Q is an orthogonal/unitary matrix and R is upper triangular. It is similar to the QR format except that the orthogonal/unitary matrix Q is stored in Compact WY format [Schreiber1989]. For the block size n_b, it is stored as a m×n lower trapezoidal matrix V and a matrix T = (T_1 T_2 T_b-1 T_b) composed of b = lceil min(mn) n_b rceil upper triangular matrices T_j of size n_b×n_b (j = 1 b-1) and an upper trapezoidal n_b×min(mn) - (b-1) n_b matrix T_b (j=b) whose upper square part denoted with T_b satisfying\n\nQ = prod_i=1^min(mn) (I - tau_i v_i v_i^T)\n= prod_j=1^b (I - V_j T_j V_j^T)\n\nsuch that v_i is the ith column of V, tau_i is the ith element of [diag(T_1); diag(T_2); …; diag(T_b)], and (V_1 V_2 V_b) is the left m×min(m, n) block of V. When constructed using qr, the block size is given by n_b = min(m n 36).\n\nIterating the decomposition produces the components Q and R.\n\nThe object has two fields:\n\nfactors, as in the QR type, is an m×n matrix.\nThe upper triangular part contains the elements of R, that is R = triu(F.factors) for a QR object F.\nThe subdiagonal part contains the reflectors v_i stored in a packed format such that V = I + tril(F.factors, -1).\nT is a n_b-by-min(mn) matrix as described above. The subdiagonal elements for each triangular matrix T_j are ignored.\n\nnote: Note\nThis format should not to be confused with the older WY representation [Bischof1987].\n\n[Bischof1987]: C Bischof and C Van Loan, \"The WY representation for products of Householder matrices\", SIAM J Sci Stat Comput 8 (1987), s2-s13. doi:10.1137/0908009\n\n[Schreiber1989]: R Schreiber and C Van Loan, \"A storage-efficient WY representation for products of Householder transformations\", SIAM J Sci Stat Comput 10 (1989), 53-57. doi:10.1137/0910005\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.QRPivoted","page":"Linear Algebra","title":"LinearAlgebra.QRPivoted","text":"QRPivoted <: Factorization\n\nA QR matrix factorization with column pivoting in a packed format, typically obtained from qr. If A is an m×n matrix, then\n\nA P = Q R\n\nwhere P is a permutation matrix, Q is an orthogonal/unitary matrix and R is upper triangular. The matrix Q is stored as a sequence of Householder reflectors:\n\nQ = prod_i=1^min(mn) (I - tau_i v_i v_i^T)\n\nIterating the decomposition produces the components Q, R, and p.\n\nThe object has three fields:\n\nfactors is an m×n matrix.\nThe upper triangular part contains the elements of R, that is R = triu(F.factors) for a QR object F.\nThe subdiagonal part contains the reflectors v_i stored in a packed format where v_i is the ith column of the matrix V = I + tril(F.factors, -1).\nτ is a vector of length min(m,n) containing the coefficients au_i.\njpvt is an integer vector of length n corresponding to the permutation P.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.qr","page":"Linear Algebra","title":"LinearAlgebra.qr","text":"qr(A::SparseMatrixCSC; tol=_default_tol(A), ordering=ORDERING_DEFAULT) -> QRSparse\n\nCompute the QR factorization of a sparse matrix A. Fill-reducing row and column permutations are used such that F.R = F.Q'*A[F.prow,F.pcol]. The main application of this type is to solve least squares or underdetermined problems with \\. The function calls the C library SPQR[ACM933].\n\nnote: Note\nqr(A::SparseMatrixCSC) uses the SPQR library that is part of SuiteSparse. As this library only supports sparse matrices with Float64 or ComplexF64 elements, as of Julia v1.4 qr converts A into a copy that is of type SparseMatrixCSC{Float64} or SparseMatrixCSC{ComplexF64} as appropriate.\n\nExamples\n\njulia> A = sparse([1,2,3,4], [1,1,2,2], [1.0,1.0,1.0,1.0])\n4×2 SparseMatrixCSC{Float64, Int64} with 4 stored entries:\n 1.0 ⋅\n 1.0 ⋅\n ⋅ 1.0\n ⋅ 1.0\n\njulia> qr(A)\nSparseArrays.SPQR.QRSparse{Float64, Int64}\nQ factor:\n4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64}\nR factor:\n2×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries:\n -1.41421 ⋅\n ⋅ -1.41421\nRow permutation:\n4-element Vector{Int64}:\n 1\n 3\n 4\n 2\nColumn permutation:\n2-element Vector{Int64}:\n 1\n 2\n\n[ACM933]: Foster, L. V., & Davis, T. A. (2013). Algorithm 933: Reliable Calculation of Numerical Rank, Null Space Bases, Pseudoinverse Solutions, and Basic Solutions Using SuitesparseQR. ACM Trans. Math. Softw., 40(1). doi:10.1145/2513109.2513116\n\n\n\n\n\nqr(A, pivot = NoPivot(); blocksize) -> F\n\nCompute the QR factorization of the matrix A: an orthogonal (or unitary if A is complex-valued) matrix Q, and an upper triangular matrix R such that\n\nA = Q R\n\nThe returned object F stores the factorization in a packed format:\n\nif pivot == ColumnNorm() then F is a QRPivoted object,\notherwise if the element type of A is a BLAS type (Float32, Float64, ComplexF32 or ComplexF64), then F is a QRCompactWY object,\notherwise F is a QR object.\n\nThe individual components of the decomposition F can be retrieved via property accessors:\n\nF.Q: the orthogonal/unitary matrix Q\nF.R: the upper triangular matrix R\nF.p: the permutation vector of the pivot (QRPivoted only)\nF.P: the permutation matrix of the pivot (QRPivoted only)\n\nnote: Note\nEach reference to the upper triangular factor via F.R allocates a new array. It is therefore advisable to cache that array, say, by R = F.R and continue working with R.\n\nIterating the decomposition produces the components Q, R, and if extant p.\n\nThe following functions are available for the QR objects: inv, size, and \\. When A is rectangular, \\ will return a least squares solution and if the solution is not unique, the one with smallest norm is returned. When A is not full rank, factorization with (column) pivoting is required to obtain a minimum norm solution.\n\nMultiplication with respect to either full/square or non-full/square Q is allowed, i.e. both F.Q*F.R and F.Q*A are supported. A Q matrix can be converted into a regular matrix with Matrix. This operation returns the \"thin\" Q factor, i.e., if A is m×n with m>=n, then Matrix(F.Q) yields an m×n matrix with orthonormal columns. To retrieve the \"full\" Q factor, an m×m orthogonal matrix, use F.Q*I or collect(F.Q). If m<=n, then Matrix(F.Q) yields an m×m orthogonal matrix.\n\nThe block size for QR decomposition can be specified by keyword argument blocksize :: Integer when pivot == NoPivot() and A isa StridedMatrix{<:BlasFloat}. It is ignored when blocksize > minimum(size(A)). See QRCompactWY.\n\ncompat: Julia 1.4\nThe blocksize keyword argument requires Julia 1.4 or later.\n\nExamples\n\njulia> A = [3.0 -6.0; 4.0 -8.0; 0.0 1.0]\n3×2 Matrix{Float64}:\n 3.0 -6.0\n 4.0 -8.0\n 0.0 1.0\n\njulia> F = qr(A)\nLinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}\nQ factor: 3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}\nR factor:\n2×2 Matrix{Float64}:\n -5.0 10.0\n 0.0 -1.0\n\njulia> F.Q * F.R == A\ntrue\n\nnote: Note\nqr returns multiple types because LAPACK uses several representations that minimize the memory storage requirements of products of Householder elementary reflectors, so that the Q and R matrices can be stored compactly rather as two separate dense matrices.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.qr!","page":"Linear Algebra","title":"LinearAlgebra.qr!","text":"qr!(A, pivot = NoPivot(); blocksize)\n\nqr! is the same as qr when A is a subtype of AbstractMatrix, but saves space by overwriting the input A, instead of creating a copy. An InexactError exception is thrown if the factorization produces a number not representable by the element type of A, e.g. for integer types.\n\ncompat: Julia 1.4\nThe blocksize keyword argument requires Julia 1.4 or later.\n\nExamples\n\njulia> a = [1. 2.; 3. 4.]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> qr!(a)\nLinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}\nQ factor: 2×2 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}\nR factor:\n2×2 Matrix{Float64}:\n -3.16228 -4.42719\n 0.0 -0.632456\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> qr!(a)\nERROR: InexactError: Int64(3.1622776601683795)\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LQ","page":"Linear Algebra","title":"LinearAlgebra.LQ","text":"LQ <: Factorization\n\nMatrix factorization type of the LQ factorization of a matrix A. The LQ decomposition is the QR decomposition of transpose(A). This is the return type of lq, the corresponding matrix factorization function.\n\nIf S::LQ is the factorization object, the lower triangular component can be obtained via S.L, and the orthogonal/unitary component via S.Q, such that A ≈ S.L*S.Q.\n\nIterating the decomposition produces the components S.L and S.Q.\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> S = lq(A)\nLQ{Float64, Matrix{Float64}, Vector{Float64}}\nL factor:\n2×2 Matrix{Float64}:\n -8.60233 0.0\n 4.41741 -0.697486\nQ factor: 2×2 LinearAlgebra.LQPackedQ{Float64, Matrix{Float64}, Vector{Float64}}\n\njulia> S.L * S.Q\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> l, q = S; # destructuring via iteration\n\njulia> l == S.L && q == S.Q\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lq","page":"Linear Algebra","title":"LinearAlgebra.lq","text":"lq(A) -> S::LQ\n\nCompute the LQ decomposition of A. The decomposition's lower triangular component can be obtained from the LQ object S via S.L, and the orthogonal/unitary component via S.Q, such that A ≈ S.L*S.Q.\n\nIterating the decomposition produces the components S.L and S.Q.\n\nThe LQ decomposition is the QR decomposition of transpose(A), and it is useful in order to compute the minimum-norm solution lq(A) \\ b to an underdetermined system of equations (A has more columns than rows, but has full row rank).\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> S = lq(A)\nLQ{Float64, Matrix{Float64}, Vector{Float64}}\nL factor:\n2×2 Matrix{Float64}:\n -8.60233 0.0\n 4.41741 -0.697486\nQ factor: 2×2 LinearAlgebra.LQPackedQ{Float64, Matrix{Float64}, Vector{Float64}}\n\njulia> S.L * S.Q\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> l, q = S; # destructuring via iteration\n\njulia> l == S.L && q == S.Q\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lq!","page":"Linear Algebra","title":"LinearAlgebra.lq!","text":"lq!(A) -> LQ\n\nCompute the LQ factorization of A, using the input matrix as a workspace. See also lq.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BunchKaufman","page":"Linear Algebra","title":"LinearAlgebra.BunchKaufman","text":"BunchKaufman <: Factorization\n\nMatrix factorization type of the Bunch-Kaufman factorization of a symmetric or Hermitian matrix A as P'UDU'P or P'LDL'P, depending on whether the upper (the default) or the lower triangle is stored in A. If A is complex symmetric then U' and L' denote the unconjugated transposes, i.e. transpose(U) and transpose(L), respectively. This is the return type of bunchkaufman, the corresponding matrix factorization function.\n\nIf S::BunchKaufman is the factorization object, the components can be obtained via S.D, S.U or S.L as appropriate given S.uplo, and S.p.\n\nIterating the decomposition produces the components S.D, S.U or S.L as appropriate given S.uplo, and S.p.\n\nExamples\n\njulia> A = Float64.([1 2; 2 3])\n2×2 Matrix{Float64}:\n 1.0 2.0\n 2.0 3.0\n\njulia> S = bunchkaufman(A) # A gets wrapped internally by Symmetric(A)\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n2×2 Tridiagonal{Float64, Vector{Float64}}:\n -0.333333 0.0\n 0.0 3.0\nU factor:\n2×2 UnitUpperTriangular{Float64, Matrix{Float64}}:\n 1.0 0.666667\n ⋅ 1.0\npermutation:\n2-element Vector{Int64}:\n 1\n 2\n\njulia> d, u, p = S; # destructuring via iteration\n\njulia> d == S.D && u == S.U && p == S.p\ntrue\n\njulia> S = bunchkaufman(Symmetric(A, :L))\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n2×2 Tridiagonal{Float64, Vector{Float64}}:\n 3.0 0.0\n 0.0 -0.333333\nL factor:\n2×2 UnitLowerTriangular{Float64, Matrix{Float64}}:\n 1.0 ⋅\n 0.666667 1.0\npermutation:\n2-element Vector{Int64}:\n 2\n 1\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.bunchkaufman","page":"Linear Algebra","title":"LinearAlgebra.bunchkaufman","text":"bunchkaufman(A, rook::Bool=false; check = true) -> S::BunchKaufman\n\nCompute the Bunch-Kaufman [Bunch1977] factorization of a symmetric or Hermitian matrix A as P'*U*D*U'*P or P'*L*D*L'*P, depending on which triangle is stored in A, and return a BunchKaufman object. Note that if A is complex symmetric then U' and L' denote the unconjugated transposes, i.e. transpose(U) and transpose(L).\n\nIterating the decomposition produces the components S.D, S.U or S.L as appropriate given S.uplo, and S.p.\n\nIf rook is true, rook pivoting is used. If rook is false, rook pivoting is not used.\n\nWhen check = true, an error is thrown if the decomposition fails. When check = false, responsibility for checking the decomposition's validity (via issuccess) lies with the user.\n\nThe following functions are available for BunchKaufman objects: size, \\, inv, issymmetric, ishermitian, getindex.\n\n[Bunch1977]: J R Bunch and L Kaufman, Some stable methods for calculating inertia and solving symmetric linear systems, Mathematics of Computation 31:137 (1977), 163-179. url.\n\nExamples\n\njulia> A = Float64.([1 2; 2 3])\n2×2 Matrix{Float64}:\n 1.0 2.0\n 2.0 3.0\n\njulia> S = bunchkaufman(A) # A gets wrapped internally by Symmetric(A)\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n2×2 Tridiagonal{Float64, Vector{Float64}}:\n -0.333333 0.0\n 0.0 3.0\nU factor:\n2×2 UnitUpperTriangular{Float64, Matrix{Float64}}:\n 1.0 0.666667\n ⋅ 1.0\npermutation:\n2-element Vector{Int64}:\n 1\n 2\n\njulia> d, u, p = S; # destructuring via iteration\n\njulia> d == S.D && u == S.U && p == S.p\ntrue\n\njulia> S.U*S.D*S.U' - S.P*A*S.P'\n2×2 Matrix{Float64}:\n 0.0 0.0\n 0.0 0.0\n\njulia> S = bunchkaufman(Symmetric(A, :L))\nBunchKaufman{Float64, Matrix{Float64}, Vector{Int64}}\nD factor:\n2×2 Tridiagonal{Float64, Vector{Float64}}:\n 3.0 0.0\n 0.0 -0.333333\nL factor:\n2×2 UnitLowerTriangular{Float64, Matrix{Float64}}:\n 1.0 ⋅\n 0.666667 1.0\npermutation:\n2-element Vector{Int64}:\n 2\n 1\n\njulia> S.L*S.D*S.L' - A[S.p, S.p]\n2×2 Matrix{Float64}:\n 0.0 0.0\n 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.bunchkaufman!","page":"Linear Algebra","title":"LinearAlgebra.bunchkaufman!","text":"bunchkaufman!(A, rook::Bool=false; check = true) -> BunchKaufman\n\nbunchkaufman! is the same as bunchkaufman, but saves space by overwriting the input A, instead of creating a copy.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Eigen","page":"Linear Algebra","title":"LinearAlgebra.Eigen","text":"Eigen <: Factorization\n\nMatrix factorization type of the eigenvalue/spectral decomposition of a square matrix A. This is the return type of eigen, the corresponding matrix factorization function.\n\nIf F::Eigen is the factorization object, the eigenvalues can be obtained via F.values and the eigenvectors as the columns of the matrix F.vectors. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nExamples\n\njulia> F = eigen([1.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 18.0])\nEigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}\nvalues:\n3-element Vector{Float64}:\n 1.0\n 3.0\n 18.0\nvectors:\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> F.values\n3-element Vector{Float64}:\n 1.0\n 3.0\n 18.0\n\njulia> F.vectors\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> vals, vecs = F; # destructuring via iteration\n\njulia> vals == F.values && vecs == F.vectors\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.GeneralizedEigen","page":"Linear Algebra","title":"LinearAlgebra.GeneralizedEigen","text":"GeneralizedEigen <: Factorization\n\nMatrix factorization type of the generalized eigenvalue/spectral decomposition of A and B. This is the return type of eigen, the corresponding matrix factorization function, when called with two matrix arguments.\n\nIf F::GeneralizedEigen is the factorization object, the eigenvalues can be obtained via F.values and the eigenvectors as the columns of the matrix F.vectors. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nExamples\n\njulia> A = [1 0; 0 -1]\n2×2 Matrix{Int64}:\n 1 0\n 0 -1\n\njulia> B = [0 1; 1 0]\n2×2 Matrix{Int64}:\n 0 1\n 1 0\n\njulia> F = eigen(A, B)\nGeneralizedEigen{ComplexF64, ComplexF64, Matrix{ComplexF64}, Vector{ComplexF64}}\nvalues:\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\nvectors:\n2×2 Matrix{ComplexF64}:\n 0.0+1.0im 0.0-1.0im\n -1.0+0.0im -1.0-0.0im\n\njulia> F.values\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\n\njulia> F.vectors\n2×2 Matrix{ComplexF64}:\n 0.0+1.0im 0.0-1.0im\n -1.0+0.0im -1.0-0.0im\n\njulia> vals, vecs = F; # destructuring via iteration\n\njulia> vals == F.values && vecs == F.vectors\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigvals","page":"Linear Algebra","title":"LinearAlgebra.eigvals","text":"eigvals(A; permute::Bool=true, scale::Bool=true, sortby) -> values\n\nReturn the eigenvalues of A.\n\nFor general non-symmetric matrices it is possible to specify how the matrix is balanced before the eigenvalue calculation. The permute, scale, and sortby keywords are the same as for eigen.\n\nExamples\n\njulia> diag_matrix = [1 0; 0 4]\n2×2 Matrix{Int64}:\n 1 0\n 0 4\n\njulia> eigvals(diag_matrix)\n2-element Vector{Float64}:\n 1.0\n 4.0\n\n\n\n\n\nFor a scalar input, eigvals will return a scalar.\n\nExamples\n\njulia> eigvals(-2)\n-2\n\n\n\n\n\neigvals(A, B) -> values\n\nCompute the generalized eigenvalues of A and B.\n\nExamples\n\njulia> A = [1 0; 0 -1]\n2×2 Matrix{Int64}:\n 1 0\n 0 -1\n\njulia> B = [0 1; 1 0]\n2×2 Matrix{Int64}:\n 0 1\n 1 0\n\njulia> eigvals(A,B)\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\n\n\n\n\n\neigvals(A::Union{SymTridiagonal, Hermitian, Symmetric}, irange::UnitRange) -> values\n\nReturn the eigenvalues of A. It is possible to calculate only a subset of the eigenvalues by specifying a UnitRange irange covering indices of the sorted eigenvalues, e.g. the 2nd to 8th eigenvalues.\n\nExamples\n\njulia> A = SymTridiagonal([1.; 2.; 1.], [2.; 3.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 1.0 2.0 ⋅\n 2.0 2.0 3.0\n ⋅ 3.0 1.0\n\njulia> eigvals(A, 2:2)\n1-element Vector{Float64}:\n 0.9999999999999996\n\njulia> eigvals(A)\n3-element Vector{Float64}:\n -2.1400549446402604\n 1.0000000000000002\n 5.140054944640259\n\n\n\n\n\neigvals(A::Union{SymTridiagonal, Hermitian, Symmetric}, vl::Real, vu::Real) -> values\n\nReturn the eigenvalues of A. It is possible to calculate only a subset of the eigenvalues by specifying a pair vl and vu for the lower and upper boundaries of the eigenvalues.\n\nExamples\n\njulia> A = SymTridiagonal([1.; 2.; 1.], [2.; 3.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 1.0 2.0 ⋅\n 2.0 2.0 3.0\n ⋅ 3.0 1.0\n\njulia> eigvals(A, -1, 2)\n1-element Vector{Float64}:\n 1.0000000000000009\n\njulia> eigvals(A)\n3-element Vector{Float64}:\n -2.1400549446402604\n 1.0000000000000002\n 5.140054944640259\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigvals!","page":"Linear Algebra","title":"LinearAlgebra.eigvals!","text":"eigvals!(A; permute::Bool=true, scale::Bool=true, sortby) -> values\n\nSame as eigvals, but saves space by overwriting the input A, instead of creating a copy. The permute, scale, and sortby keywords are the same as for eigen.\n\nnote: Note\nThe input matrix A will not contain its eigenvalues after eigvals! is called on it - A is used as a workspace.\n\nExamples\n\njulia> A = [1. 2.; 3. 4.]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> eigvals!(A)\n2-element Vector{Float64}:\n -0.3722813232690143\n 5.372281323269014\n\njulia> A\n2×2 Matrix{Float64}:\n -0.372281 -1.0\n 0.0 5.37228\n\n\n\n\n\neigvals!(A, B; sortby) -> values\n\nSame as eigvals, but saves space by overwriting the input A (and B), instead of creating copies.\n\nnote: Note\nThe input matrices A and B will not contain their eigenvalues after eigvals! is called. They are used as workspaces.\n\nExamples\n\njulia> A = [1. 0.; 0. -1.]\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 -1.0\n\njulia> B = [0. 1.; 1. 0.]\n2×2 Matrix{Float64}:\n 0.0 1.0\n 1.0 0.0\n\njulia> eigvals!(A, B)\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\n\njulia> A\n2×2 Matrix{Float64}:\n -0.0 -1.0\n 1.0 -0.0\n\njulia> B\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\n\n\n\n\n\neigvals!(A::Union{SymTridiagonal, Hermitian, Symmetric}, irange::UnitRange) -> values\n\nSame as eigvals, but saves space by overwriting the input A, instead of creating a copy. irange is a range of eigenvalue indices to search for - for instance, the 2nd to 8th eigenvalues.\n\n\n\n\n\neigvals!(A::Union{SymTridiagonal, Hermitian, Symmetric}, vl::Real, vu::Real) -> values\n\nSame as eigvals, but saves space by overwriting the input A, instead of creating a copy. vl is the lower bound of the interval to search for eigenvalues, and vu is the upper bound.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigmax","page":"Linear Algebra","title":"LinearAlgebra.eigmax","text":"eigmax(A; permute::Bool=true, scale::Bool=true)\n\nReturn the largest eigenvalue of A. The option permute=true permutes the matrix to become closer to upper triangular, and scale=true scales the matrix by its diagonal elements to make rows and columns more equal in norm. Note that if the eigenvalues of A are complex, this method will fail, since complex numbers cannot be sorted.\n\nExamples\n\njulia> A = [0 im; -im 0]\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+1im\n 0-1im 0+0im\n\njulia> eigmax(A)\n1.0\n\njulia> A = [0 im; -1 0]\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+1im\n -1+0im 0+0im\n\njulia> eigmax(A)\nERROR: DomainError with Complex{Int64}[0+0im 0+1im; -1+0im 0+0im]:\n`A` cannot have complex eigenvalues.\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigmin","page":"Linear Algebra","title":"LinearAlgebra.eigmin","text":"eigmin(A; permute::Bool=true, scale::Bool=true)\n\nReturn the smallest eigenvalue of A. The option permute=true permutes the matrix to become closer to upper triangular, and scale=true scales the matrix by its diagonal elements to make rows and columns more equal in norm. Note that if the eigenvalues of A are complex, this method will fail, since complex numbers cannot be sorted.\n\nExamples\n\njulia> A = [0 im; -im 0]\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+1im\n 0-1im 0+0im\n\njulia> eigmin(A)\n-1.0\n\njulia> A = [0 im; -1 0]\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+1im\n -1+0im 0+0im\n\njulia> eigmin(A)\nERROR: DomainError with Complex{Int64}[0+0im 0+1im; -1+0im 0+0im]:\n`A` cannot have complex eigenvalues.\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigvecs","page":"Linear Algebra","title":"LinearAlgebra.eigvecs","text":"eigvecs(A::SymTridiagonal[, eigvals]) -> Matrix\n\nReturn a matrix M whose columns are the eigenvectors of A. (The kth eigenvector can be obtained from the slice M[:, k].)\n\nIf the optional vector of eigenvalues eigvals is specified, eigvecs returns the specific corresponding eigenvectors.\n\nExamples\n\njulia> A = SymTridiagonal([1.; 2.; 1.], [2.; 3.])\n3×3 SymTridiagonal{Float64, Vector{Float64}}:\n 1.0 2.0 ⋅\n 2.0 2.0 3.0\n ⋅ 3.0 1.0\n\njulia> eigvals(A)\n3-element Vector{Float64}:\n -2.1400549446402604\n 1.0000000000000002\n 5.140054944640259\n\njulia> eigvecs(A)\n3×3 Matrix{Float64}:\n 0.418304 -0.83205 0.364299\n -0.656749 -7.39009e-16 0.754109\n 0.627457 0.5547 0.546448\n\njulia> eigvecs(A, [1.])\n3×1 Matrix{Float64}:\n 0.8320502943378438\n 4.263514128092366e-17\n -0.5547001962252291\n\n\n\n\n\neigvecs(A; permute::Bool=true, scale::Bool=true, `sortby`) -> Matrix\n\nReturn a matrix M whose columns are the eigenvectors of A. (The kth eigenvector can be obtained from the slice M[:, k].) The permute, scale, and sortby keywords are the same as for eigen.\n\nExamples\n\njulia> eigvecs([1.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 18.0])\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\n\n\n\n\neigvecs(A, B) -> Matrix\n\nReturn a matrix M whose columns are the generalized eigenvectors of A and B. (The kth eigenvector can be obtained from the slice M[:, k].)\n\nExamples\n\njulia> A = [1 0; 0 -1]\n2×2 Matrix{Int64}:\n 1 0\n 0 -1\n\njulia> B = [0 1; 1 0]\n2×2 Matrix{Int64}:\n 0 1\n 1 0\n\njulia> eigvecs(A, B)\n2×2 Matrix{ComplexF64}:\n 0.0+1.0im 0.0-1.0im\n -1.0+0.0im -1.0-0.0im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigen","page":"Linear Algebra","title":"LinearAlgebra.eigen","text":"eigen(A; permute::Bool=true, scale::Bool=true, sortby) -> Eigen\n\nCompute the eigenvalue decomposition of A, returning an Eigen factorization object F which contains the eigenvalues in F.values and the eigenvectors in the columns of the matrix F.vectors. This corresponds to solving an eigenvalue problem of the form Ax = λx, where A is a matrix, x is an eigenvector, and λ is an eigenvalue. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nThe following functions are available for Eigen objects: inv, det, and isposdef.\n\nFor general nonsymmetric matrices it is possible to specify how the matrix is balanced before the eigenvector calculation. The option permute=true permutes the matrix to become closer to upper triangular, and scale=true scales the matrix by its diagonal elements to make rows and columns more equal in norm. The default is true for both options.\n\nBy default, the eigenvalues and vectors are sorted lexicographically by (real(λ),imag(λ)). A different comparison function by(λ) can be passed to sortby, or you can pass sortby=nothing to leave the eigenvalues in an arbitrary order. Some special matrix types (e.g. Diagonal or SymTridiagonal) may implement their own sorting convention and not accept a sortby keyword.\n\nExamples\n\njulia> F = eigen([1.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 18.0])\nEigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}\nvalues:\n3-element Vector{Float64}:\n 1.0\n 3.0\n 18.0\nvectors:\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> F.values\n3-element Vector{Float64}:\n 1.0\n 3.0\n 18.0\n\njulia> F.vectors\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> vals, vecs = F; # destructuring via iteration\n\njulia> vals == F.values && vecs == F.vectors\ntrue\n\n\n\n\n\neigen(A, B; sortby) -> GeneralizedEigen\n\nCompute the generalized eigenvalue decomposition of A and B, returning a GeneralizedEigen factorization object F which contains the generalized eigenvalues in F.values and the generalized eigenvectors in the columns of the matrix F.vectors. This corresponds to solving a generalized eigenvalue problem of the form Ax = λBx, where A, B are matrices, x is an eigenvector, and λ is an eigenvalue. (The kth generalized eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nBy default, the eigenvalues and vectors are sorted lexicographically by (real(λ),imag(λ)). A different comparison function by(λ) can be passed to sortby, or you can pass sortby=nothing to leave the eigenvalues in an arbitrary order.\n\nExamples\n\njulia> A = [1 0; 0 -1]\n2×2 Matrix{Int64}:\n 1 0\n 0 -1\n\njulia> B = [0 1; 1 0]\n2×2 Matrix{Int64}:\n 0 1\n 1 0\n\njulia> F = eigen(A, B);\n\njulia> F.values\n2-element Vector{ComplexF64}:\n 0.0 - 1.0im\n 0.0 + 1.0im\n\njulia> F.vectors\n2×2 Matrix{ComplexF64}:\n 0.0+1.0im 0.0-1.0im\n -1.0+0.0im -1.0-0.0im\n\njulia> vals, vecs = F; # destructuring via iteration\n\njulia> vals == F.values && vecs == F.vectors\ntrue\n\n\n\n\n\neigen(A::Union{SymTridiagonal, Hermitian, Symmetric}, irange::UnitRange) -> Eigen\n\nCompute the eigenvalue decomposition of A, returning an Eigen factorization object F which contains the eigenvalues in F.values and the eigenvectors in the columns of the matrix F.vectors. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nThe following functions are available for Eigen objects: inv, det, and isposdef.\n\nThe UnitRange irange specifies indices of the sorted eigenvalues to search for.\n\nnote: Note\nIf irange is not 1:n, where n is the dimension of A, then the returned factorization will be a truncated factorization.\n\n\n\n\n\neigen(A::Union{SymTridiagonal, Hermitian, Symmetric}, vl::Real, vu::Real) -> Eigen\n\nCompute the eigenvalue decomposition of A, returning an Eigen factorization object F which contains the eigenvalues in F.values and the eigenvectors in the columns of the matrix F.vectors. (The kth eigenvector can be obtained from the slice F.vectors[:, k].)\n\nIterating the decomposition produces the components F.values and F.vectors.\n\nThe following functions are available for Eigen objects: inv, det, and isposdef.\n\nvl is the lower bound of the window of eigenvalues to search for, and vu is the upper bound.\n\nnote: Note\nIf [vl, vu] does not contain all eigenvalues of A, then the returned factorization will be a truncated factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.eigen!","page":"Linear Algebra","title":"LinearAlgebra.eigen!","text":"eigen!(A; permute, scale, sortby)\neigen!(A, B; sortby)\n\nSame as eigen, but saves space by overwriting the input A (and B), instead of creating a copy.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Hessenberg","page":"Linear Algebra","title":"LinearAlgebra.Hessenberg","text":"Hessenberg <: Factorization\n\nA Hessenberg object represents the Hessenberg factorization QHQ' of a square matrix, or a shift Q(H+μI)Q' thereof, which is produced by the hessenberg function.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.hessenberg","page":"Linear Algebra","title":"LinearAlgebra.hessenberg","text":"hessenberg(A) -> Hessenberg\n\nCompute the Hessenberg decomposition of A and return a Hessenberg object. If F is the factorization object, the unitary matrix can be accessed with F.Q (of type LinearAlgebra.HessenbergQ) and the Hessenberg matrix with F.H (of type UpperHessenberg), either of which may be converted to a regular matrix with Matrix(F.H) or Matrix(F.Q).\n\nIf A is Hermitian or real-Symmetric, then the Hessenberg decomposition produces a real-symmetric tridiagonal matrix and F.H is of type SymTridiagonal.\n\nNote that the shifted factorization A+μI = Q (H+μI) Q' can be constructed efficiently by F + μ*I using the UniformScaling object I, which creates a new Hessenberg object with shared storage and a modified shift. The shift of a given F is obtained by F.μ. This is useful because multiple shifted solves (F + μ*I) \\ b (for different μ and/or b) can be performed efficiently once F is created.\n\nIterating the decomposition produces the factors F.Q, F.H, F.μ.\n\nExamples\n\njulia> A = [4. 9. 7.; 4. 4. 1.; 4. 3. 2.]\n3×3 Matrix{Float64}:\n 4.0 9.0 7.0\n 4.0 4.0 1.0\n 4.0 3.0 2.0\n\njulia> F = hessenberg(A)\nHessenberg{Float64, UpperHessenberg{Float64, Matrix{Float64}}, Matrix{Float64}, Vector{Float64}, Bool}\nQ factor: 3×3 LinearAlgebra.HessenbergQ{Float64, Matrix{Float64}, Vector{Float64}, false}\nH factor:\n3×3 UpperHessenberg{Float64, Matrix{Float64}}:\n 4.0 -11.3137 -1.41421\n -5.65685 5.0 2.0\n ⋅ -8.88178e-16 1.0\n\njulia> F.Q * F.H * F.Q'\n3×3 Matrix{Float64}:\n 4.0 9.0 7.0\n 4.0 4.0 1.0\n 4.0 3.0 2.0\n\njulia> q, h = F; # destructuring via iteration\n\njulia> q == F.Q && h == F.H\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.hessenberg!","page":"Linear Algebra","title":"LinearAlgebra.hessenberg!","text":"hessenberg!(A) -> Hessenberg\n\nhessenberg! is the same as hessenberg, but saves space by overwriting the input A, instead of creating a copy.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Schur","page":"Linear Algebra","title":"LinearAlgebra.Schur","text":"Schur <: Factorization\n\nMatrix factorization type of the Schur factorization of a matrix A. This is the return type of schur(_), the corresponding matrix factorization function.\n\nIf F::Schur is the factorization object, the (quasi) triangular Schur factor can be obtained via either F.Schur or F.T and the orthogonal/unitary Schur vectors via F.vectors or F.Z such that A = F.vectors * F.Schur * F.vectors'. The eigenvalues of A can be obtained with F.values.\n\nIterating the decomposition produces the components F.T, F.Z, and F.values.\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> F = schur(A)\nSchur{Float64, Matrix{Float64}, Vector{Float64}}\nT factor:\n2×2 Matrix{Float64}:\n 3.0 9.0\n 0.0 -2.0\nZ factor:\n2×2 Matrix{Float64}:\n 0.961524 0.274721\n -0.274721 0.961524\neigenvalues:\n2-element Vector{Float64}:\n 3.0\n -2.0\n\njulia> F.vectors * F.Schur * F.vectors'\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> t, z, vals = F; # destructuring via iteration\n\njulia> t == F.T && z == F.Z && vals == F.values\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.GeneralizedSchur","page":"Linear Algebra","title":"LinearAlgebra.GeneralizedSchur","text":"GeneralizedSchur <: Factorization\n\nMatrix factorization type of the generalized Schur factorization of two matrices A and B. This is the return type of schur(_, _), the corresponding matrix factorization function.\n\nIf F::GeneralizedSchur is the factorization object, the (quasi) triangular Schur factors can be obtained via F.S and F.T, the left unitary/orthogonal Schur vectors via F.left or F.Q, and the right unitary/orthogonal Schur vectors can be obtained with F.right or F.Z such that A=F.left*F.S*F.right' and B=F.left*F.T*F.right'. The generalized eigenvalues of A and B can be obtained with F.α./F.β.\n\nIterating the decomposition produces the components F.S, F.T, F.Q, F.Z, F.α, and F.β.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.schur","page":"Linear Algebra","title":"LinearAlgebra.schur","text":"schur(A) -> F::Schur\n\nComputes the Schur factorization of the matrix A. The (quasi) triangular Schur factor can be obtained from the Schur object F with either F.Schur or F.T and the orthogonal/unitary Schur vectors can be obtained with F.vectors or F.Z such that A = F.vectors * F.Schur * F.vectors'. The eigenvalues of A can be obtained with F.values.\n\nFor real A, the Schur factorization is \"quasitriangular\", which means that it is upper-triangular except with 2×2 diagonal blocks for any conjugate pair of complex eigenvalues; this allows the factorization to be purely real even when there are complex eigenvalues. To obtain the (complex) purely upper-triangular Schur factorization from a real quasitriangular factorization, you can use Schur{Complex}(schur(A)).\n\nIterating the decomposition produces the components F.T, F.Z, and F.values.\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> F = schur(A)\nSchur{Float64, Matrix{Float64}, Vector{Float64}}\nT factor:\n2×2 Matrix{Float64}:\n 3.0 9.0\n 0.0 -2.0\nZ factor:\n2×2 Matrix{Float64}:\n 0.961524 0.274721\n -0.274721 0.961524\neigenvalues:\n2-element Vector{Float64}:\n 3.0\n -2.0\n\njulia> F.vectors * F.Schur * F.vectors'\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> t, z, vals = F; # destructuring via iteration\n\njulia> t == F.T && z == F.Z && vals == F.values\ntrue\n\n\n\n\n\nschur(A, B) -> F::GeneralizedSchur\n\nComputes the Generalized Schur (or QZ) factorization of the matrices A and B. The (quasi) triangular Schur factors can be obtained from the Schur object F with F.S and F.T, the left unitary/orthogonal Schur vectors can be obtained with F.left or F.Q and the right unitary/orthogonal Schur vectors can be obtained with F.right or F.Z such that A=F.left*F.S*F.right' and B=F.left*F.T*F.right'. The generalized eigenvalues of A and B can be obtained with F.α./F.β.\n\nIterating the decomposition produces the components F.S, F.T, F.Q, F.Z, F.α, and F.β.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.schur!","page":"Linear Algebra","title":"LinearAlgebra.schur!","text":"schur!(A) -> F::Schur\n\nSame as schur but uses the input argument A as workspace.\n\nExamples\n\njulia> A = [5. 7.; -2. -4.]\n2×2 Matrix{Float64}:\n 5.0 7.0\n -2.0 -4.0\n\njulia> F = schur!(A)\nSchur{Float64, Matrix{Float64}, Vector{Float64}}\nT factor:\n2×2 Matrix{Float64}:\n 3.0 9.0\n 0.0 -2.0\nZ factor:\n2×2 Matrix{Float64}:\n 0.961524 0.274721\n -0.274721 0.961524\neigenvalues:\n2-element Vector{Float64}:\n 3.0\n -2.0\n\njulia> A\n2×2 Matrix{Float64}:\n 3.0 9.0\n 0.0 -2.0\n\n\n\n\n\nschur!(A::StridedMatrix, B::StridedMatrix) -> F::GeneralizedSchur\n\nSame as schur but uses the input matrices A and B as workspace.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ordschur","page":"Linear Algebra","title":"LinearAlgebra.ordschur","text":"ordschur(F::Schur, select::Union{Vector{Bool},BitVector}) -> F::Schur\n\nReorders the Schur factorization F of a matrix A = Z*T*Z' according to the logical array select returning the reordered factorization F object. The selected eigenvalues appear in the leading diagonal of F.Schur and the corresponding leading columns of F.vectors form an orthogonal/unitary basis of the corresponding right invariant subspace. In the real case, a complex conjugate pair of eigenvalues must be either both included or both excluded via select.\n\n\n\n\n\nordschur(F::GeneralizedSchur, select::Union{Vector{Bool},BitVector}) -> F::GeneralizedSchur\n\nReorders the Generalized Schur factorization F of a matrix pair (A, B) = (Q*S*Z', Q*T*Z') according to the logical array select and returns a GeneralizedSchur object F. The selected eigenvalues appear in the leading diagonal of both F.S and F.T, and the left and right orthogonal/unitary Schur vectors are also reordered such that (A, B) = F.Q*(F.S, F.T)*F.Z' still holds and the generalized eigenvalues of A and B can still be obtained with F.α./F.β.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ordschur!","page":"Linear Algebra","title":"LinearAlgebra.ordschur!","text":"ordschur!(F::Schur, select::Union{Vector{Bool},BitVector}) -> F::Schur\n\nSame as ordschur but overwrites the factorization F.\n\n\n\n\n\nordschur!(F::GeneralizedSchur, select::Union{Vector{Bool},BitVector}) -> F::GeneralizedSchur\n\nSame as ordschur but overwrites the factorization F.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.SVD","page":"Linear Algebra","title":"LinearAlgebra.SVD","text":"SVD <: Factorization\n\nMatrix factorization type of the singular value decomposition (SVD) of a matrix A. This is the return type of svd(_), the corresponding matrix factorization function.\n\nIf F::SVD is the factorization object, U, S, V and Vt can be obtained via F.U, F.S, F.V and F.Vt, such that A = U * Diagonal(S) * Vt. The singular values in S are sorted in descending order.\n\nIterating the decomposition produces the components U, S, and V.\n\nExamples\n\njulia> A = [1. 0. 0. 0. 2.; 0. 0. 3. 0. 0.; 0. 0. 0. 0. 0.; 0. 2. 0. 0. 0.]\n4×5 Matrix{Float64}:\n 1.0 0.0 0.0 0.0 2.0\n 0.0 0.0 3.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 2.0 0.0 0.0 0.0\n\njulia> F = svd(A)\nSVD{Float64, Float64, Matrix{Float64}, Vector{Float64}}\nU factor:\n4×4 Matrix{Float64}:\n 0.0 1.0 0.0 0.0\n 1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0\n 0.0 0.0 -1.0 0.0\nsingular values:\n4-element Vector{Float64}:\n 3.0\n 2.23606797749979\n 2.0\n 0.0\nVt factor:\n4×5 Matrix{Float64}:\n -0.0 0.0 1.0 -0.0 0.0\n 0.447214 0.0 0.0 0.0 0.894427\n 0.0 -1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0 0.0\n\njulia> F.U * Diagonal(F.S) * F.Vt\n4×5 Matrix{Float64}:\n 1.0 0.0 0.0 0.0 2.0\n 0.0 0.0 3.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 2.0 0.0 0.0 0.0\n\njulia> u, s, v = F; # destructuring via iteration\n\njulia> u == F.U && s == F.S && v == F.V\ntrue\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.GeneralizedSVD","page":"Linear Algebra","title":"LinearAlgebra.GeneralizedSVD","text":"GeneralizedSVD <: Factorization\n\nMatrix factorization type of the generalized singular value decomposition (SVD) of two matrices A and B, such that A = F.U*F.D1*F.R0*F.Q' and B = F.V*F.D2*F.R0*F.Q'. This is the return type of svd(_, _), the corresponding matrix factorization function.\n\nFor an M-by-N matrix A and P-by-N matrix B,\n\nU is a M-by-M orthogonal matrix,\nV is a P-by-P orthogonal matrix,\nQ is a N-by-N orthogonal matrix,\nD1 is a M-by-(K+L) diagonal matrix with 1s in the first K entries,\nD2 is a P-by-(K+L) matrix whose top right L-by-L block is diagonal,\nR0 is a (K+L)-by-N matrix whose rightmost (K+L)-by-(K+L) block is nonsingular upper block triangular,\n\nK+L is the effective numerical rank of the matrix [A; B].\n\nIterating the decomposition produces the components U, V, Q, D1, D2, and R0.\n\nThe entries of F.D1 and F.D2 are related, as explained in the LAPACK documentation for the generalized SVD and the xGGSVD3 routine which is called underneath (in LAPACK 3.6.0 and newer).\n\nExamples\n\njulia> A = [1. 0.; 0. -1.]\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 -1.0\n\njulia> B = [0. 1.; 1. 0.]\n2×2 Matrix{Float64}:\n 0.0 1.0\n 1.0 0.0\n\njulia> F = svd(A, B)\nGeneralizedSVD{Float64, Matrix{Float64}, Float64, Vector{Float64}}\nU factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\nV factor:\n2×2 Matrix{Float64}:\n -0.0 -1.0\n 1.0 0.0\nQ factor:\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\nD1 factor:\n2×2 Matrix{Float64}:\n 0.707107 0.0\n 0.0 0.707107\nD2 factor:\n2×2 Matrix{Float64}:\n 0.707107 0.0\n 0.0 0.707107\nR0 factor:\n2×2 Matrix{Float64}:\n 1.41421 0.0\n 0.0 -1.41421\n\njulia> F.U*F.D1*F.R0*F.Q'\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 -1.0\n\njulia> F.V*F.D2*F.R0*F.Q'\n2×2 Matrix{Float64}:\n -0.0 1.0\n 1.0 0.0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.svd","page":"Linear Algebra","title":"LinearAlgebra.svd","text":"svd(A; full::Bool = false, alg::Algorithm = default_svd_alg(A)) -> SVD\n\nCompute the singular value decomposition (SVD) of A and return an SVD object.\n\nU, S, V and Vt can be obtained from the factorization F with F.U, F.S, F.V and F.Vt, such that A = U * Diagonal(S) * Vt. The algorithm produces Vt and hence Vt is more efficient to extract than V. The singular values in S are sorted in descending order.\n\nIterating the decomposition produces the components U, S, and V.\n\nIf full = false (default), a \"thin\" SVD is returned. For an M times N matrix A, in the full factorization U is M times M and V is N times N, while in the thin factorization U is M times K and V is N times K, where K = min(MN) is the number of singular values.\n\nIf alg = DivideAndConquer() a divide-and-conquer algorithm is used to calculate the SVD. Another (typically slower but more accurate) option is alg = QRIteration().\n\ncompat: Julia 1.3\nThe alg keyword argument requires Julia 1.3 or later.\n\nExamples\n\njulia> A = rand(4,3);\n\njulia> F = svd(A); # Store the Factorization Object\n\njulia> A ≈ F.U * Diagonal(F.S) * F.Vt\ntrue\n\njulia> U, S, V = F; # destructuring via iteration\n\njulia> A ≈ U * Diagonal(S) * V'\ntrue\n\njulia> Uonly, = svd(A); # Store U only\n\njulia> Uonly == U\ntrue\n\n\n\n\n\nsvd(A, B) -> GeneralizedSVD\n\nCompute the generalized SVD of A and B, returning a GeneralizedSVD factorization object F such that [A;B] = [F.U * F.D1; F.V * F.D2] * F.R0 * F.Q'\n\nU is a M-by-M orthogonal matrix,\nV is a P-by-P orthogonal matrix,\nQ is a N-by-N orthogonal matrix,\nD1 is a M-by-(K+L) diagonal matrix with 1s in the first K entries,\nD2 is a P-by-(K+L) matrix whose top right L-by-L block is diagonal,\nR0 is a (K+L)-by-N matrix whose rightmost (K+L)-by-(K+L) block is nonsingular upper block triangular,\n\nK+L is the effective numerical rank of the matrix [A; B].\n\nIterating the decomposition produces the components U, V, Q, D1, D2, and R0.\n\nThe generalized SVD is used in applications such as when one wants to compare how much belongs to A vs. how much belongs to B, as in human vs yeast genome, or signal vs noise, or between clusters vs within clusters. (See Edelman and Wang for discussion: https://arxiv.org/abs/1901.00485)\n\nIt decomposes [A; B] into [UC; VS]H, where [UC; VS] is a natural orthogonal basis for the column space of [A; B], and H = RQ' is a natural non-orthogonal basis for the rowspace of [A;B], where the top rows are most closely attributed to the A matrix, and the bottom to the B matrix. The multi-cosine/sine matrices C and S provide a multi-measure of how much A vs how much B, and U and V provide directions in which these are measured.\n\nExamples\n\njulia> A = randn(3,2); B=randn(4,2);\n\njulia> F = svd(A, B);\n\njulia> U,V,Q,C,S,R = F;\n\njulia> H = R*Q';\n\njulia> [A; B] ≈ [U*C; V*S]*H\ntrue\n\njulia> [A; B] ≈ [F.U*F.D1; F.V*F.D2]*F.R0*F.Q'\ntrue\n\njulia> Uonly, = svd(A,B);\n\njulia> U == Uonly\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.svd!","page":"Linear Algebra","title":"LinearAlgebra.svd!","text":"svd!(A; full::Bool = false, alg::Algorithm = default_svd_alg(A)) -> SVD\n\nsvd! is the same as svd, but saves space by overwriting the input A, instead of creating a copy. See documentation of svd for details.\n\n\n\n\n\nsvd!(A, B) -> GeneralizedSVD\n\nsvd! is the same as svd, but modifies the arguments A and B in-place, instead of making copies. See documentation of svd for details.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.svdvals","page":"Linear Algebra","title":"LinearAlgebra.svdvals","text":"svdvals(A)\n\nReturn the singular values of A in descending order.\n\nExamples\n\njulia> A = [1. 0. 0. 0. 2.; 0. 0. 3. 0. 0.; 0. 0. 0. 0. 0.; 0. 2. 0. 0. 0.]\n4×5 Matrix{Float64}:\n 1.0 0.0 0.0 0.0 2.0\n 0.0 0.0 3.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0\n 0.0 2.0 0.0 0.0 0.0\n\njulia> svdvals(A)\n4-element Vector{Float64}:\n 3.0\n 2.23606797749979\n 2.0\n 0.0\n\n\n\n\n\nsvdvals(A, B)\n\nReturn the generalized singular values from the generalized singular value decomposition of A and B. See also svd.\n\nExamples\n\njulia> A = [1. 0.; 0. -1.]\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 -1.0\n\njulia> B = [0. 1.; 1. 0.]\n2×2 Matrix{Float64}:\n 0.0 1.0\n 1.0 0.0\n\njulia> svdvals(A, B)\n2-element Vector{Float64}:\n 1.0\n 1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.svdvals!","page":"Linear Algebra","title":"LinearAlgebra.svdvals!","text":"svdvals!(A)\n\nReturn the singular values of A, saving space by overwriting the input. See also svdvals and svd.\n\n\n\n\n\nsvdvals!(A, B)\n\nReturn the generalized singular values from the generalized singular value decomposition of A and B, saving space by overwriting A and B. See also svd and svdvals.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Givens","page":"Linear Algebra","title":"LinearAlgebra.Givens","text":"LinearAlgebra.Givens(i1,i2,c,s) -> G\n\nA Givens rotation linear operator. The fields c and s represent the cosine and sine of the rotation angle, respectively. The Givens type supports left multiplication G*A and conjugated transpose right multiplication A*G'. The type doesn't have a size and can therefore be multiplied with matrices of arbitrary size as long as i2<=size(A,2) for G*A or i2<=size(A,1) for A*G'.\n\nSee also givens.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.givens","page":"Linear Algebra","title":"LinearAlgebra.givens","text":"givens(f::T, g::T, i1::Integer, i2::Integer) where {T} -> (G::Givens, r::T)\n\nComputes the Givens rotation G and scalar r such that for any vector x where\n\nx[i1] = f\nx[i2] = g\n\nthe result of the multiplication\n\ny = G*x\n\nhas the property that\n\ny[i1] = r\ny[i2] = 0\n\nSee also LinearAlgebra.Givens.\n\n\n\n\n\ngivens(A::AbstractArray, i1::Integer, i2::Integer, j::Integer) -> (G::Givens, r)\n\nComputes the Givens rotation G and scalar r such that the result of the multiplication\n\nB = G*A\n\nhas the property that\n\nB[i1,j] = r\nB[i2,j] = 0\n\nSee also LinearAlgebra.Givens.\n\n\n\n\n\ngivens(x::AbstractVector, i1::Integer, i2::Integer) -> (G::Givens, r)\n\nComputes the Givens rotation G and scalar r such that the result of the multiplication\n\nB = G*x\n\nhas the property that\n\nB[i1] = r\nB[i2] = 0\n\nSee also LinearAlgebra.Givens.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.triu","page":"Linear Algebra","title":"LinearAlgebra.triu","text":"triu(M)\n\nUpper triangle of a matrix.\n\nExamples\n\njulia> a = fill(1.0, (4,4))\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> triu(a)\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 0.0 1.0 1.0 1.0\n 0.0 0.0 1.0 1.0\n 0.0 0.0 0.0 1.0\n\n\n\n\n\ntriu(M, k::Integer)\n\nReturn the upper triangle of M starting from the kth superdiagonal.\n\nExamples\n\njulia> a = fill(1.0, (4,4))\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> triu(a,3)\n4×4 Matrix{Float64}:\n 0.0 0.0 0.0 1.0\n 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0\n\njulia> triu(a,-3)\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.triu!","page":"Linear Algebra","title":"LinearAlgebra.triu!","text":"triu!(M)\n\nUpper triangle of a matrix, overwriting M in the process. See also triu.\n\n\n\n\n\ntriu!(M, k::Integer)\n\nReturn the upper triangle of M starting from the kth superdiagonal, overwriting M in the process.\n\nExamples\n\njulia> M = [1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5]\n5×5 Matrix{Int64}:\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n\njulia> triu!(M, 1)\n5×5 Matrix{Int64}:\n 0 2 3 4 5\n 0 0 3 4 5\n 0 0 0 4 5\n 0 0 0 0 5\n 0 0 0 0 0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.tril","page":"Linear Algebra","title":"LinearAlgebra.tril","text":"tril(M)\n\nLower triangle of a matrix.\n\nExamples\n\njulia> a = fill(1.0, (4,4))\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> tril(a)\n4×4 Matrix{Float64}:\n 1.0 0.0 0.0 0.0\n 1.0 1.0 0.0 0.0\n 1.0 1.0 1.0 0.0\n 1.0 1.0 1.0 1.0\n\n\n\n\n\ntril(M, k::Integer)\n\nReturn the lower triangle of M starting from the kth superdiagonal.\n\nExamples\n\njulia> a = fill(1.0, (4,4))\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> tril(a,3)\n4×4 Matrix{Float64}:\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n 1.0 1.0 1.0 1.0\n\njulia> tril(a,-3)\n4×4 Matrix{Float64}:\n 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0\n 1.0 0.0 0.0 0.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.tril!","page":"Linear Algebra","title":"LinearAlgebra.tril!","text":"tril!(M)\n\nLower triangle of a matrix, overwriting M in the process. See also tril.\n\n\n\n\n\ntril!(M, k::Integer)\n\nReturn the lower triangle of M starting from the kth superdiagonal, overwriting M in the process.\n\nExamples\n\njulia> M = [1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5]\n5×5 Matrix{Int64}:\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n\njulia> tril!(M, 2)\n5×5 Matrix{Int64}:\n 1 2 3 0 0\n 1 2 3 4 0\n 1 2 3 4 5\n 1 2 3 4 5\n 1 2 3 4 5\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.diagind","page":"Linear Algebra","title":"LinearAlgebra.diagind","text":"diagind(M::AbstractMatrix, k::Integer = 0, indstyle::IndexStyle = IndexLinear())\ndiagind(M::AbstractMatrix, indstyle::IndexStyle = IndexLinear())\n\nAn AbstractRange giving the indices of the kth diagonal of the matrix M. Optionally, an index style may be specified which determines the type of the range returned. If indstyle isa IndexLinear (default), this returns an AbstractRange{Integer}. On the other hand, if indstyle isa IndexCartesian, this returns an AbstractRange{CartesianIndex{2}}.\n\nIf k is not provided, it is assumed to be 0 (corresponding to the main diagonal).\n\nSee also: diag, diagm, Diagonal.\n\nExamples\n\njulia> A = [1 2 3; 4 5 6; 7 8 9]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n 7 8 9\n\njulia> diagind(A, -1)\n2:4:6\n\njulia> diagind(A, IndexCartesian())\nStepRangeLen(CartesianIndex(1, 1), CartesianIndex(1, 1), 3)\n\ncompat: Julia 1.11\nSpecifying an IndexStyle requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.diag","page":"Linear Algebra","title":"LinearAlgebra.diag","text":"diag(M, k::Integer=0)\n\nThe kth diagonal of a matrix, as a vector.\n\nSee also diagm, diagind, Diagonal, isdiag.\n\nExamples\n\njulia> A = [1 2 3; 4 5 6; 7 8 9]\n3×3 Matrix{Int64}:\n 1 2 3\n 4 5 6\n 7 8 9\n\njulia> diag(A,1)\n2-element Vector{Int64}:\n 2\n 6\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.diagm","page":"Linear Algebra","title":"LinearAlgebra.diagm","text":"diagm(kv::Pair{<:Integer,<:AbstractVector}...)\ndiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)\n\nConstruct a matrix from Pairs of diagonals and vectors. Vector kv.second will be placed on the kv.first diagonal. By default the matrix is square and its size is inferred from kv, but a non-square size m×n (padded with zeros as needed) can be specified by passing m,n as the first arguments. For repeated diagonal indices kv.first the values in the corresponding vectors kv.second will be added.\n\ndiagm constructs a full matrix; if you want storage-efficient versions with fast arithmetic, see Diagonal, Bidiagonal Tridiagonal and SymTridiagonal.\n\nExamples\n\njulia> diagm(1 => [1,2,3])\n4×4 Matrix{Int64}:\n 0 1 0 0\n 0 0 2 0\n 0 0 0 3\n 0 0 0 0\n\njulia> diagm(1 => [1,2,3], -1 => [4,5])\n4×4 Matrix{Int64}:\n 0 1 0 0\n 4 0 2 0\n 0 5 0 3\n 0 0 0 0\n\njulia> diagm(1 => [1,2,3], 1 => [1,2,3])\n4×4 Matrix{Int64}:\n 0 2 0 0\n 0 0 4 0\n 0 0 0 6\n 0 0 0 0\n\n\n\n\n\ndiagm(v::AbstractVector)\ndiagm(m::Integer, n::Integer, v::AbstractVector)\n\nConstruct a matrix with elements of the vector as diagonal elements. By default, the matrix is square and its size is given by length(v), but a non-square size m×n can be specified by passing m,n as the first arguments.\n\nExamples\n\njulia> diagm([1,2,3])\n3×3 Matrix{Int64}:\n 1 0 0\n 0 2 0\n 0 0 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.rank","page":"Linear Algebra","title":"LinearAlgebra.rank","text":"rank(::QRSparse{Tv,Ti}) -> Ti\n\nReturn the rank of the QR factorization\n\n\n\n\n\nrank(S::SparseMatrixCSC{Tv,Ti}; [tol::Real]) -> Ti\n\nCalculate rank of S by calculating its QR factorization. Values smaller than tol are considered as zero. See SPQR's manual.\n\n\n\n\n\nrank(A::AbstractMatrix; atol::Real=0, rtol::Real=atol>0 ? 0 : n*ϵ)\nrank(A::AbstractMatrix, rtol::Real)\n\nCompute the numerical rank of a matrix by counting how many outputs of svdvals(A) are greater than max(atol, rtol*σ₁) where σ₁ is A's largest calculated singular value. atol and rtol are the absolute and relative tolerances, respectively. The default relative tolerance is n*ϵ, where n is the size of the smallest dimension of A, and ϵ is the eps of the element type of A.\n\nnote: Note\nNumerical rank can be a sensitive and imprecise characterization of ill-conditioned matrices with singular values that are close to the threshold tolerance max(atol, rtol*σ₁). In such cases, slight perturbations to the singular-value computation or to the matrix can change the result of rank by pushing one or more singular values across the threshold. These variations can even occur due to changes in floating-point errors between different Julia versions, architectures, compilers, or operating systems.\n\ncompat: Julia 1.1\nThe atol and rtol keyword arguments requires at least Julia 1.1. In Julia 1.0 rtol is available as a positional argument, but this will be deprecated in Julia 2.0.\n\nExamples\n\njulia> rank(Matrix(I, 3, 3))\n3\n\njulia> rank(diagm(0 => [1, 0, 2]))\n2\n\njulia> rank(diagm(0 => [1, 0.001, 2]), rtol=0.1)\n2\n\njulia> rank(diagm(0 => [1, 0.001, 2]), rtol=0.00001)\n3\n\njulia> rank(diagm(0 => [1, 0.001, 2]), atol=1.5)\n1\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.norm","page":"Linear Algebra","title":"LinearAlgebra.norm","text":"norm(A, p::Real=2)\n\nFor any iterable container A (including arrays of any dimension) of numbers (or any element type for which norm is defined), compute the p-norm (defaulting to p=2) as if A were a vector of the corresponding length.\n\nThe p-norm is defined as\n\nA_p = left( sum_i=1^n a_i ^p right)^1p\n\nwith a_i the entries of A, a_i the norm of a_i, and n the length of A. Since the p-norm is computed using the norms of the entries of A, the p-norm of a vector of vectors is not compatible with the interpretation of it as a block vector in general if p != 2.\n\np can assume any numeric value (even though not all values produce a mathematically valid vector norm). In particular, norm(A, Inf) returns the largest value in abs.(A), whereas norm(A, -Inf) returns the smallest. If A is a matrix and p=2, then this is equivalent to the Frobenius norm.\n\nThe second argument p is not necessarily a part of the interface for norm, i.e. a custom type may only implement norm(A) without second argument.\n\nUse opnorm to compute the operator norm of a matrix.\n\nExamples\n\njulia> v = [3, -2, 6]\n3-element Vector{Int64}:\n 3\n -2\n 6\n\njulia> norm(v)\n7.0\n\njulia> norm(v, 1)\n11.0\n\njulia> norm(v, Inf)\n6.0\n\njulia> norm([1 2 3; 4 5 6; 7 8 9])\n16.881943016134134\n\njulia> norm([1 2 3 4 5 6 7 8 9])\n16.881943016134134\n\njulia> norm(1:9)\n16.881943016134134\n\njulia> norm(hcat(v,v), 1) == norm(vcat(v,v), 1) != norm([v,v], 1)\ntrue\n\njulia> norm(hcat(v,v), 2) == norm(vcat(v,v), 2) == norm([v,v], 2)\ntrue\n\njulia> norm(hcat(v,v), Inf) == norm(vcat(v,v), Inf) != norm([v,v], Inf)\ntrue\n\n\n\n\n\nnorm(x::Number, p::Real=2)\n\nFor numbers, return left( x^p right)^1p.\n\nExamples\n\njulia> norm(2, 1)\n2.0\n\njulia> norm(-2, 1)\n2.0\n\njulia> norm(2, 2)\n2.0\n\njulia> norm(-2, 2)\n2.0\n\njulia> norm(2, Inf)\n2.0\n\njulia> norm(-2, Inf)\n2.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.opnorm","page":"Linear Algebra","title":"LinearAlgebra.opnorm","text":"opnorm(A::AbstractMatrix, p::Real=2)\n\nCompute the operator norm (or matrix norm) induced by the vector p-norm, where valid values of p are 1, 2, or Inf. (Note that for sparse matrices, p=2 is currently not implemented.) Use norm to compute the Frobenius norm.\n\nWhen p=1, the operator norm is the maximum absolute column sum of A:\n\nA_1 = max_1 j n sum_i=1^m a_ij \n\nwith a_ij the entries of A, and m and n its dimensions.\n\nWhen p=2, the operator norm is the spectral norm, equal to the largest singular value of A.\n\nWhen p=Inf, the operator norm is the maximum absolute row sum of A:\n\nA_infty = max_1 i m sum _j=1^n a_ij \n\nExamples\n\njulia> A = [1 -2 -3; 2 3 -1]\n2×3 Matrix{Int64}:\n 1 -2 -3\n 2 3 -1\n\njulia> opnorm(A, Inf)\n6.0\n\njulia> opnorm(A, 1)\n5.0\n\n\n\n\n\nopnorm(x::Number, p::Real=2)\n\nFor numbers, return left( x^p right)^1p. This is equivalent to norm.\n\n\n\n\n\nopnorm(A::Adjoint{<:Any,<:AbstractVector}, q::Real=2)\nopnorm(A::Transpose{<:Any,<:AbstractVector}, q::Real=2)\n\nFor Adjoint/Transpose-wrapped vectors, return the operator q-norm of A, which is equivalent to the p-norm with value p = q/(q-1). They coincide at p = q = 2. Use norm to compute the p norm of A as a vector.\n\nThe difference in norm between a vector space and its dual arises to preserve the relationship between duality and the dot product, and the result is consistent with the operator p-norm of a 1 × n matrix.\n\nExamples\n\njulia> v = [1; im];\n\njulia> vc = v';\n\njulia> opnorm(vc, 1)\n1.0\n\njulia> norm(vc, 1)\n2.0\n\njulia> norm(v, 1)\n2.0\n\njulia> opnorm(vc, 2)\n1.4142135623730951\n\njulia> norm(vc, 2)\n1.4142135623730951\n\njulia> norm(v, 2)\n1.4142135623730951\n\njulia> opnorm(vc, Inf)\n2.0\n\njulia> norm(vc, Inf)\n1.0\n\njulia> norm(v, Inf)\n1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.normalize!","page":"Linear Algebra","title":"LinearAlgebra.normalize!","text":"normalize!(a::AbstractArray, p::Real=2)\n\nNormalize the array a in-place so that its p-norm equals unity, i.e. norm(a, p) == 1. See also normalize and norm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.normalize","page":"Linear Algebra","title":"LinearAlgebra.normalize","text":"normalize(a, p::Real=2)\n\nNormalize a so that its p-norm equals unity, i.e. norm(a, p) == 1. For scalars, this is similar to sign(a), except normalize(0) = NaN. See also normalize!, norm, and sign.\n\nExamples\n\njulia> a = [1,2,4];\n\njulia> b = normalize(a)\n3-element Vector{Float64}:\n 0.2182178902359924\n 0.4364357804719848\n 0.8728715609439696\n\njulia> norm(b)\n1.0\n\njulia> c = normalize(a, 1)\n3-element Vector{Float64}:\n 0.14285714285714285\n 0.2857142857142857\n 0.5714285714285714\n\njulia> norm(c, 1)\n1.0\n\njulia> a = [1 2 4 ; 1 2 4]\n2×3 Matrix{Int64}:\n 1 2 4\n 1 2 4\n\njulia> norm(a)\n6.48074069840786\n\njulia> normalize(a)\n2×3 Matrix{Float64}:\n 0.154303 0.308607 0.617213\n 0.154303 0.308607 0.617213\n\njulia> normalize(3, 1)\n1.0\n\njulia> normalize(-8, 1)\n-1.0\n\njulia> normalize(0, 1)\nNaN\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.cond","page":"Linear Algebra","title":"LinearAlgebra.cond","text":"cond(M, p::Real=2)\n\nCondition number of the matrix M, computed using the operator p-norm. Valid values for p are 1, 2 (default), or Inf.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.condskeel","page":"Linear Algebra","title":"LinearAlgebra.condskeel","text":"condskeel(M, [x, p::Real=Inf])\n\nkappa_S(M p) = leftVert leftvert M rightvert leftvert M^-1 rightvert rightVert_p \nkappa_S(M x p) = fracleftVert leftvert M rightvert leftvert M^-1 rightvert leftvert x rightvert rightVert_pleft Vert x right Vert_p\n\nSkeel condition number kappa_S of the matrix M, optionally with respect to the vector x, as computed using the operator p-norm. leftvert M rightvert denotes the matrix of (entry wise) absolute values of M; leftvert M rightvert_ij = leftvert M_ij rightvert. Valid values for p are 1, 2 and Inf (default).\n\nThis quantity is also known in the literature as the Bauer condition number, relative condition number, or componentwise relative condition number.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.tr","page":"Linear Algebra","title":"LinearAlgebra.tr","text":"tr(M)\n\nMatrix trace. Sums the diagonal elements of M.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> tr(A)\n5\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.det","page":"Linear Algebra","title":"LinearAlgebra.det","text":"det(M)\n\nMatrix determinant.\n\nSee also: logdet and logabsdet.\n\nExamples\n\njulia> M = [1 0; 2 2]\n2×2 Matrix{Int64}:\n 1 0\n 2 2\n\njulia> det(M)\n2.0\n\nNote that, in general, det computes a floating-point approximation of the determinant, even for integer matrices, typically via Gaussian elimination. Julia includes an exact algorithm for integer determinants (the Bareiss algorithm), but only uses it by default for BigInt matrices (since determinants quickly overflow any fixed integer precision):\n\njulia> det(BigInt[1 0; 2 2]) # exact integer determinant\n2\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.logdet","page":"Linear Algebra","title":"LinearAlgebra.logdet","text":"logdet(M)\n\nLogarithm of matrix determinant. Equivalent to log(det(M)), but may provide increased accuracy and avoids overflow/underflow.\n\nExamples\n\njulia> M = [1 0; 2 2]\n2×2 Matrix{Int64}:\n 1 0\n 2 2\n\njulia> logdet(M)\n0.6931471805599453\n\njulia> logdet(Matrix(I, 3, 3))\n0.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.logabsdet","page":"Linear Algebra","title":"LinearAlgebra.logabsdet","text":"logabsdet(M)\n\nLog of absolute value of matrix determinant. Equivalent to (log(abs(det(M))), sign(det(M))), but may provide increased accuracy and/or speed.\n\nExamples\n\njulia> A = [-1. 0.; 0. 1.]\n2×2 Matrix{Float64}:\n -1.0 0.0\n 0.0 1.0\n\njulia> det(A)\n-1.0\n\njulia> logabsdet(A)\n(0.0, -1.0)\n\njulia> B = [2. 0.; 0. 1.]\n2×2 Matrix{Float64}:\n 2.0 0.0\n 0.0 1.0\n\njulia> det(B)\n2.0\n\njulia> logabsdet(B)\n(0.6931471805599453, 1.0)\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.inv-Tuple{AbstractMatrix}","page":"Linear Algebra","title":"Base.inv","text":"inv(M)\n\nMatrix inverse. Computes matrix N such that M * N = I, where I is the identity matrix. Computed by solving the left-division N = M \\ I.\n\nExamples\n\njulia> M = [2 5; 1 3]\n2×2 Matrix{Int64}:\n 2 5\n 1 3\n\njulia> N = inv(M)\n2×2 Matrix{Float64}:\n 3.0 -5.0\n -1.0 2.0\n\njulia> M*N == N*M == Matrix(I, 2, 2)\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.pinv","page":"Linear Algebra","title":"LinearAlgebra.pinv","text":"pinv(M; atol::Real=0, rtol::Real=atol>0 ? 0 : n*ϵ)\npinv(M, rtol::Real) = pinv(M; rtol=rtol) # to be deprecated in Julia 2.0\n\nComputes the Moore-Penrose pseudoinverse.\n\nFor matrices M with floating point elements, it is convenient to compute the pseudoinverse by inverting only singular values greater than max(atol, rtol*σ₁) where σ₁ is the largest singular value of M.\n\nThe optimal choice of absolute (atol) and relative tolerance (rtol) varies both with the value of M and the intended application of the pseudoinverse. The default relative tolerance is n*ϵ, where n is the size of the smallest dimension of M, and ϵ is the eps of the element type of M.\n\nFor inverting dense ill-conditioned matrices in a least-squares sense, rtol = sqrt(eps(real(float(oneunit(eltype(M)))))) is recommended.\n\nFor more information, see [issue8859], [B96], [S84], [KY88].\n\nExamples\n\njulia> M = [1.5 1.3; 1.2 1.9]\n2×2 Matrix{Float64}:\n 1.5 1.3\n 1.2 1.9\n\njulia> N = pinv(M)\n2×2 Matrix{Float64}:\n 1.47287 -1.00775\n -0.930233 1.16279\n\njulia> M * N\n2×2 Matrix{Float64}:\n 1.0 -2.22045e-16\n 4.44089e-16 1.0\n\n[issue8859]: Issue 8859, \"Fix least squares\", https://github.com/JuliaLang/julia/pull/8859\n\n[B96]: Åke Björck, \"Numerical Methods for Least Squares Problems\", SIAM Press, Philadelphia, 1996, \"Other Titles in Applied Mathematics\", Vol. 51. doi:10.1137/1.9781611971484\n\n[S84]: G. W. Stewart, \"Rank Degeneracy\", SIAM Journal on Scientific and Statistical Computing, 5(2), 1984, 403-413. doi:10.1137/0905030\n\n[KY88]: Konstantinos Konstantinides and Kung Yao, \"Statistical analysis of effective singular values in matrix rank determination\", IEEE Transactions on Acoustics, Speech and Signal Processing, 36(5), 1988, 757-763. doi:10.1109/29.1585\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.nullspace","page":"Linear Algebra","title":"LinearAlgebra.nullspace","text":"nullspace(M; atol::Real=0, rtol::Real=atol>0 ? 0 : n*ϵ)\nnullspace(M, rtol::Real) = nullspace(M; rtol=rtol) # to be deprecated in Julia 2.0\n\nComputes a basis for the nullspace of M by including the singular vectors of M whose singular values have magnitudes smaller than max(atol, rtol*σ₁), where σ₁ is M's largest singular value.\n\nBy default, the relative tolerance rtol is n*ϵ, where n is the size of the smallest dimension of M, and ϵ is the eps of the element type of M.\n\nExamples\n\njulia> M = [1 0 0; 0 1 0; 0 0 0]\n3×3 Matrix{Int64}:\n 1 0 0\n 0 1 0\n 0 0 0\n\njulia> nullspace(M)\n3×1 Matrix{Float64}:\n 0.0\n 0.0\n 1.0\n\njulia> nullspace(M, rtol=3)\n3×3 Matrix{Float64}:\n 0.0 1.0 0.0\n 1.0 0.0 0.0\n 0.0 0.0 1.0\n\njulia> nullspace(M, atol=0.95)\n3×1 Matrix{Float64}:\n 0.0\n 0.0\n 1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.kron","page":"Linear Algebra","title":"Base.kron","text":"kron(A, B)\n\nComputes the Kronecker product of two vectors, matrices or numbers.\n\nFor real vectors v and w, the Kronecker product is related to the outer product by kron(v,w) == vec(w * transpose(v)) or w * transpose(v) == reshape(kron(v,w), (length(w), length(v))). Note how the ordering of v and w differs on the left and right of these expressions (due to column-major storage). For complex vectors, the outer product w * v' also differs by conjugation of v.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> B = [im 1; 1 -im]\n2×2 Matrix{Complex{Int64}}:\n 0+1im 1+0im\n 1+0im 0-1im\n\njulia> kron(A, B)\n4×4 Matrix{Complex{Int64}}:\n 0+1im 1+0im 0+2im 2+0im\n 1+0im 0-1im 2+0im 0-2im\n 0+3im 3+0im 0+4im 4+0im\n 3+0im 0-3im 4+0im 0-4im\n\njulia> v = [1, 2]; w = [3, 4, 5];\n\njulia> w*transpose(v)\n3×2 Matrix{Int64}:\n 3 6\n 4 8\n 5 10\n\njulia> reshape(kron(v,w), (length(w), length(v)))\n3×2 Matrix{Int64}:\n 3 6\n 4 8\n 5 10\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.kron!","page":"Linear Algebra","title":"Base.kron!","text":"kron!(C, A, B)\n\nComputes the Kronecker product of A and B and stores the result in C, overwriting the existing content of C. This is the in-place version of kron.\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.exp-Tuple{StridedMatrix{var\"#s9708\"} where var\"#s9708\"<:Union{Float32, Float64, ComplexF64, ComplexF32}}","page":"Linear Algebra","title":"Base.exp","text":"exp(A::AbstractMatrix)\n\nCompute the matrix exponential of A, defined by\n\ne^A = sum_n=0^infty fracA^nn\n\nFor symmetric or Hermitian A, an eigendecomposition (eigen) is used, otherwise the scaling and squaring algorithm (see [H05]) is chosen.\n\n[H05]: Nicholas J. Higham, \"The squaring and scaling method for the matrix exponential revisited\", SIAM Journal on Matrix Analysis and Applications, 26(4), 2005, 1179-1193. doi:10.1137/090768539\n\nExamples\n\njulia> A = Matrix(1.0I, 2, 2)\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\n\njulia> exp(A)\n2×2 Matrix{Float64}:\n 2.71828 0.0\n 0.0 2.71828\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.cis-Tuple{AbstractMatrix}","page":"Linear Algebra","title":"Base.cis","text":"cis(A::AbstractMatrix)\n\nMore efficient method for exp(im*A) of square matrix A (especially if A is Hermitian or real-Symmetric).\n\nSee also cispi, sincos, exp.\n\ncompat: Julia 1.7\nSupport for using cis with matrices was added in Julia 1.7.\n\nExamples\n\njulia> cis([π 0; 0 π]) ≈ -I\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:^-Tuple{AbstractMatrix, Number}","page":"Linear Algebra","title":"Base.:^","text":"^(A::AbstractMatrix, p::Number)\n\nMatrix power, equivalent to exp(plog(A))\n\nExamples\n\njulia> [1 2; 0 3]^3\n2×2 Matrix{Int64}:\n 1 26\n 0 27\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.:^-Tuple{Number, AbstractMatrix}","page":"Linear Algebra","title":"Base.:^","text":"^(b::Number, A::AbstractMatrix)\n\nMatrix exponential, equivalent to exp(log(b)A).\n\ncompat: Julia 1.1\nSupport for raising Irrational numbers (like ℯ) to a matrix was added in Julia 1.1.\n\nExamples\n\njulia> 2^[1 2; 0 3]\n2×2 Matrix{Float64}:\n 2.0 6.0\n 0.0 8.0\n\njulia> ℯ^[1 2; 0 3]\n2×2 Matrix{Float64}:\n 2.71828 17.3673\n 0.0 20.0855\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.log-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.log","text":"log(A::AbstractMatrix)\n\nIf A has no negative real eigenvalue, compute the principal matrix logarithm of A, i.e. the unique matrix X such that e^X = A and -pi Im(lambda) pi for all the eigenvalues lambda of X. If A has nonpositive eigenvalues, a nonprincipal matrix function is returned whenever possible.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used, if A is triangular an improved version of the inverse scaling and squaring method is employed (see [AH12] and [AHR13]). If A is real with no negative eigenvalues, then the real Schur form is computed. Otherwise, the complex Schur form is computed. Then the upper (quasi-)triangular algorithm in [AHR13] is used on the upper (quasi-)triangular factor.\n\n[AH12]: Awad H. Al-Mohy and Nicholas J. Higham, \"Improved inverse scaling and squaring algorithms for the matrix logarithm\", SIAM Journal on Scientific Computing, 34(4), 2012, C153-C169. doi:10.1137/110852553\n\n[AHR13]: Awad H. Al-Mohy, Nicholas J. Higham and Samuel D. Relton, \"Computing the Fréchet derivative of the matrix logarithm and estimating the condition number\", SIAM Journal on Scientific Computing, 35(4), 2013, C394-C410. doi:10.1137/120885991\n\nExamples\n\njulia> A = Matrix(2.7182818*I, 2, 2)\n2×2 Matrix{Float64}:\n 2.71828 0.0\n 0.0 2.71828\n\njulia> log(A)\n2×2 Matrix{Float64}:\n 1.0 0.0\n 0.0 1.0\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.sqrt-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.sqrt","text":"sqrt(x)\n\nReturn sqrtx.\n\nThrow a DomainError for negative Real arguments. Use Complex negative arguments instead to obtain a Complex result.\n\nThe prefix operator √ is equivalent to sqrt.\n\nnote: Branch cut\nsqrt has a branch cut along the negative real axis; -0.0im is taken to be below the axis.\n\nSee also: hypot.\n\nExamples\n\njulia> sqrt(big(81))\n9.0\n\njulia> sqrt(big(-81))\nERROR: DomainError with -81.0:\nNaN result for non-NaN input.\nStacktrace:\n [1] sqrt(::BigFloat) at ./mpfr.jl:501\n[...]\n\njulia> sqrt(big(complex(-81)))\n0.0 + 9.0im\n\njulia> sqrt(-81 - 0.0im) # -0.0im is below the branch cut\n0.0 - 9.0im\n\njulia> .√(1:4)\n4-element Vector{Float64}:\n 1.0\n 1.4142135623730951\n 1.7320508075688772\n 2.0\n\n\n\n\n\nsqrt(A::AbstractMatrix)\n\nIf A has no negative real eigenvalues, compute the principal matrix square root of A, that is the unique matrix X with eigenvalues having positive real part such that X^2 = A. Otherwise, a nonprincipal square root is returned.\n\nIf A is real-symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the square root. For such matrices, eigenvalues λ that appear to be slightly negative due to roundoff errors are treated as if they were zero. More precisely, matrices with all eigenvalues ≥ -rtol*(max |λ|) are treated as semidefinite (yielding a Hermitian square root), with negative eigenvalues taken to be zero. rtol is a keyword argument to sqrt (in the Hermitian/real-symmetric case only) that defaults to machine precision scaled by size(A,1).\n\nOtherwise, the square root is determined by means of the Björck-Hammarling method [BH83], which computes the complex Schur form (schur) and then the complex square root of the triangular factor. If a real square root exists, then an extension of this method [H87] that computes the real Schur form and then the real square root of the quasi-triangular factor is instead used.\n\n[BH83]: Åke Björck and Sven Hammarling, \"A Schur method for the square root of a matrix\", Linear Algebra and its Applications, 52-53, 1983, 127-140. doi:10.1016/0024-3795(83)80010-X\n\n[H87]: Nicholas J. Higham, \"Computing real square roots of a real matrix\", Linear Algebra and its Applications, 88-89, 1987, 405-430. doi:10.1016/0024-3795(87)90118-2\n\nExamples\n\njulia> A = [4 0; 0 4]\n2×2 Matrix{Int64}:\n 4 0\n 0 4\n\njulia> sqrt(A)\n2×2 Matrix{Float64}:\n 2.0 0.0\n 0.0 2.0\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.cbrt-Tuple{AbstractMatrix{<:Real}}","page":"Linear Algebra","title":"Base.Math.cbrt","text":"cbrt(A::AbstractMatrix{<:Real})\n\nComputes the real-valued cube root of a real-valued matrix A. If T = cbrt(A), then we have T*T*T ≈ A, see example given below.\n\nIf A is symmetric, i.e., of type HermOrSym{<:Real}, then (eigen) is used to find the cube root. Otherwise, a specialized version of the p-th root algorithm [S03] is utilized, which exploits the real-valued Schur decomposition (schur) to compute the cube root.\n\n[S03]: Matthew I. Smith, \"A Schur Algorithm for Computing Matrix pth Roots\", SIAM Journal on Matrix Analysis and Applications, vol. 24, 2003, pp. 971–989. doi:10.1137/S0895479801392697\n\nExamples\n\njulia> A = [0.927524 -0.15857; -1.3677 -1.01172]\n2×2 Matrix{Float64}:\n 0.927524 -0.15857\n -1.3677 -1.01172\n\njulia> T = cbrt(A)\n2×2 Matrix{Float64}:\n 0.910077 -0.151019\n -1.30257 -0.936818\n\njulia> T*T*T ≈ A\ntrue\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.cos-Tuple{StridedMatrix{var\"#s9710\"} where var\"#s9710\"<:Real}","page":"Linear Algebra","title":"Base.cos","text":"cos(A::AbstractMatrix)\n\nCompute the matrix cosine of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the cosine. Otherwise, the cosine is determined by calling exp.\n\nExamples\n\njulia> cos(fill(1.0, (2,2)))\n2×2 Matrix{Float64}:\n 0.291927 -0.708073\n -0.708073 0.291927\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.sin-Tuple{StridedMatrix{var\"#s9711\"} where var\"#s9711\"<:Real}","page":"Linear Algebra","title":"Base.sin","text":"sin(A::AbstractMatrix)\n\nCompute the matrix sine of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the sine. Otherwise, the sine is determined by calling exp.\n\nExamples\n\njulia> sin(fill(1.0, (2,2)))\n2×2 Matrix{Float64}:\n 0.454649 0.454649\n 0.454649 0.454649\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.sincos-Tuple{StridedMatrix{var\"#s9712\"} where var\"#s9712\"<:Real}","page":"Linear Algebra","title":"Base.Math.sincos","text":"sincos(A::AbstractMatrix)\n\nCompute the matrix sine and cosine of a square matrix A.\n\nExamples\n\njulia> S, C = sincos(fill(1.0, (2,2)));\n\njulia> S\n2×2 Matrix{Float64}:\n 0.454649 0.454649\n 0.454649 0.454649\n\njulia> C\n2×2 Matrix{Float64}:\n 0.291927 -0.708073\n -0.708073 0.291927\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.tan-Tuple{StridedMatrix{var\"#s9713\"} where var\"#s9713\"<:Real}","page":"Linear Algebra","title":"Base.tan","text":"tan(A::AbstractMatrix)\n\nCompute the matrix tangent of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\nExamples\n\njulia> tan(fill(1.0, (2,2)))\n2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.sec-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.sec","text":"sec(A::AbstractMatrix)\n\nCompute the matrix secant of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.csc-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.csc","text":"csc(A::AbstractMatrix)\n\nCompute the matrix cosecant of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.cot-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.cot","text":"cot(A::AbstractMatrix)\n\nCompute the matrix cotangent of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.cosh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.cosh","text":"cosh(A::AbstractMatrix)\n\nCompute the matrix hyperbolic cosine of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.sinh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.sinh","text":"sinh(A::AbstractMatrix)\n\nCompute the matrix hyperbolic sine of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.tanh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.tanh","text":"tanh(A::AbstractMatrix)\n\nCompute the matrix hyperbolic tangent of a square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.sech-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.sech","text":"sech(A::AbstractMatrix)\n\nCompute the matrix hyperbolic secant of square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.csch-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.csch","text":"csch(A::AbstractMatrix)\n\nCompute the matrix hyperbolic cosecant of square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.coth-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.coth","text":"coth(A::AbstractMatrix)\n\nCompute the matrix hyperbolic cotangent of square matrix A.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.acos-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.acos","text":"acos(A::AbstractMatrix)\n\nCompute the inverse matrix cosine of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the inverse cosine. Otherwise, the inverse cosine is determined by using log and sqrt. For the theory and logarithmic formulas used to compute this function, see [AH16_1].\n\n[AH16_1]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\nExamples\n\njulia> acos(cos([0.5 0.1; -0.2 0.3]))\n2×2 Matrix{ComplexF64}:\n 0.5-8.32667e-17im 0.1+0.0im\n -0.2+2.63678e-16im 0.3-3.46945e-16im\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.asin-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.asin","text":"asin(A::AbstractMatrix)\n\nCompute the inverse matrix sine of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the inverse sine. Otherwise, the inverse sine is determined by using log and sqrt. For the theory and logarithmic formulas used to compute this function, see [AH16_2].\n\n[AH16_2]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\nExamples\n\njulia> asin(sin([0.5 0.1; -0.2 0.3]))\n2×2 Matrix{ComplexF64}:\n 0.5-4.16334e-17im 0.1-5.55112e-17im\n -0.2+9.71445e-17im 0.3-1.249e-16im\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.atan-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.atan","text":"atan(A::AbstractMatrix)\n\nCompute the inverse matrix tangent of a square matrix A.\n\nIf A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the inverse tangent. Otherwise, the inverse tangent is determined by using log. For the theory and logarithmic formulas used to compute this function, see [AH16_3].\n\n[AH16_3]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\nExamples\n\njulia> atan(tan([0.5 0.1; -0.2 0.3]))\n2×2 Matrix{ComplexF64}:\n 0.5+1.38778e-17im 0.1-2.77556e-17im\n -0.2+6.93889e-17im 0.3-4.16334e-17im\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.asec-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.asec","text":"asec(A::AbstractMatrix)\n\nCompute the inverse matrix secant of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.acsc-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.acsc","text":"acsc(A::AbstractMatrix)\n\nCompute the inverse matrix cosecant of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.acot-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.acot","text":"acot(A::AbstractMatrix)\n\nCompute the inverse matrix cotangent of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.acosh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.acosh","text":"acosh(A::AbstractMatrix)\n\nCompute the inverse hyperbolic matrix cosine of a square matrix A. For the theory and logarithmic formulas used to compute this function, see [AH16_4].\n\n[AH16_4]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.asinh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.asinh","text":"asinh(A::AbstractMatrix)\n\nCompute the inverse hyperbolic matrix sine of a square matrix A. For the theory and logarithmic formulas used to compute this function, see [AH16_5].\n\n[AH16_5]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.atanh-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.atanh","text":"atanh(A::AbstractMatrix)\n\nCompute the inverse hyperbolic matrix tangent of a square matrix A. For the theory and logarithmic formulas used to compute this function, see [AH16_6].\n\n[AH16_6]: Mary Aprahamian and Nicholas J. Higham, \"Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms\", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.asech-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.asech","text":"asech(A::AbstractMatrix)\n\nCompute the inverse matrix hyperbolic secant of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.acsch-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.acsch","text":"acsch(A::AbstractMatrix)\n\nCompute the inverse matrix hyperbolic cosecant of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#Base.Math.acoth-Tuple{StridedMatrix{T} where T}","page":"Linear Algebra","title":"Base.Math.acoth","text":"acoth(A::AbstractMatrix)\n\nCompute the inverse matrix hyperbolic cotangent of A. \n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lyap","page":"Linear Algebra","title":"LinearAlgebra.lyap","text":"lyap(A, C)\n\nComputes the solution X to the continuous Lyapunov equation AX + XA' + C = 0, where no eigenvalue of A has a zero real part and no two eigenvalues are negative complex conjugates of each other.\n\nExamples\n\njulia> A = [3. 4.; 5. 6]\n2×2 Matrix{Float64}:\n 3.0 4.0\n 5.0 6.0\n\njulia> B = [1. 1.; 1. 2.]\n2×2 Matrix{Float64}:\n 1.0 1.0\n 1.0 2.0\n\njulia> X = lyap(A, B)\n2×2 Matrix{Float64}:\n 0.5 -0.5\n -0.5 0.25\n\njulia> A*X + X*A' ≈ -B\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.sylvester","page":"Linear Algebra","title":"LinearAlgebra.sylvester","text":"sylvester(A, B, C)\n\nComputes the solution X to the Sylvester equation AX + XB + C = 0, where A, B and C have compatible dimensions and A and -B have no eigenvalues with equal real part.\n\nExamples\n\njulia> A = [3. 4.; 5. 6]\n2×2 Matrix{Float64}:\n 3.0 4.0\n 5.0 6.0\n\njulia> B = [1. 1.; 1. 2.]\n2×2 Matrix{Float64}:\n 1.0 1.0\n 1.0 2.0\n\njulia> C = [1. 2.; -2. 1]\n2×2 Matrix{Float64}:\n 1.0 2.0\n -2.0 1.0\n\njulia> X = sylvester(A, B, C)\n2×2 Matrix{Float64}:\n -4.46667 1.93333\n 3.73333 -1.8\n\njulia> A*X + X*B ≈ -C\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.issuccess","page":"Linear Algebra","title":"LinearAlgebra.issuccess","text":"issuccess(F::Factorization)\n\nTest that a factorization of a matrix succeeded.\n\ncompat: Julia 1.6\nissuccess(::CholeskyPivoted) requires Julia 1.6 or later.\n\nExamples\n\njulia> F = cholesky([1 0; 0 1]);\n\njulia> issuccess(F)\ntrue\n\n\n\n\n\nissuccess(F::LU; allowsingular = false)\n\nTest that the LU factorization of a matrix succeeded. By default a factorization that produces a valid but rank-deficient U factor is considered a failure. This can be changed by passing allowsingular = true.\n\ncompat: Julia 1.11\nThe allowsingular keyword argument was added in Julia 1.11.\n\nExamples\n\njulia> F = lu([1 2; 1 2], check = false);\n\njulia> issuccess(F)\nfalse\n\njulia> issuccess(F, allowsingular = true)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.issymmetric","page":"Linear Algebra","title":"LinearAlgebra.issymmetric","text":"issymmetric(A) -> Bool\n\nTest whether a matrix is symmetric.\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> issymmetric(a)\ntrue\n\njulia> b = [1 im; -im 1]\n2×2 Matrix{Complex{Int64}}:\n 1+0im 0+1im\n 0-1im 1+0im\n\njulia> issymmetric(b)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.isposdef","page":"Linear Algebra","title":"LinearAlgebra.isposdef","text":"isposdef(A) -> Bool\n\nTest whether a matrix is positive definite (and Hermitian) by trying to perform a Cholesky factorization of A.\n\nSee also isposdef!, cholesky.\n\nExamples\n\njulia> A = [1 2; 2 50]\n2×2 Matrix{Int64}:\n 1 2\n 2 50\n\njulia> isposdef(A)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.isposdef!","page":"Linear Algebra","title":"LinearAlgebra.isposdef!","text":"isposdef!(A) -> Bool\n\nTest whether a matrix is positive definite (and Hermitian) by trying to perform a Cholesky factorization of A, overwriting A in the process. See also isposdef.\n\nExamples\n\njulia> A = [1. 2.; 2. 50.];\n\njulia> isposdef!(A)\ntrue\n\njulia> A\n2×2 Matrix{Float64}:\n 1.0 2.0\n 2.0 6.78233\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.istril","page":"Linear Algebra","title":"LinearAlgebra.istril","text":"istril(A::AbstractMatrix, k::Integer = 0) -> Bool\n\nTest whether A is lower triangular starting from the kth superdiagonal.\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> istril(a)\nfalse\n\njulia> istril(a, 1)\ntrue\n\njulia> c = [1 1 0; 1 1 1; 1 1 1]\n3×3 Matrix{Int64}:\n 1 1 0\n 1 1 1\n 1 1 1\n\njulia> istril(c)\nfalse\n\njulia> istril(c, 1)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.istriu","page":"Linear Algebra","title":"LinearAlgebra.istriu","text":"istriu(A::AbstractMatrix, k::Integer = 0) -> Bool\n\nTest whether A is upper triangular starting from the kth superdiagonal.\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> istriu(a)\nfalse\n\njulia> istriu(a, -1)\ntrue\n\njulia> c = [1 1 1; 1 1 1; 0 1 1]\n3×3 Matrix{Int64}:\n 1 1 1\n 1 1 1\n 0 1 1\n\njulia> istriu(c)\nfalse\n\njulia> istriu(c, -1)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.isdiag","page":"Linear Algebra","title":"LinearAlgebra.isdiag","text":"isdiag(A) -> Bool\n\nTest whether a matrix is diagonal in the sense that iszero(A[i,j]) is true unless i == j. Note that it is not necessary for A to be square; if you would also like to check that, you need to check that size(A, 1) == size(A, 2).\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> isdiag(a)\nfalse\n\njulia> b = [im 0; 0 -im]\n2×2 Matrix{Complex{Int64}}:\n 0+1im 0+0im\n 0+0im 0-1im\n\njulia> isdiag(b)\ntrue\n\njulia> c = [1 0 0; 0 2 0]\n2×3 Matrix{Int64}:\n 1 0 0\n 0 2 0\n\njulia> isdiag(c)\ntrue\n\njulia> d = [1 0 0; 0 2 3]\n2×3 Matrix{Int64}:\n 1 0 0\n 0 2 3\n\njulia> isdiag(d)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ishermitian","page":"Linear Algebra","title":"LinearAlgebra.ishermitian","text":"ishermitian(A) -> Bool\n\nTest whether a matrix is Hermitian.\n\nExamples\n\njulia> a = [1 2; 2 -1]\n2×2 Matrix{Int64}:\n 1 2\n 2 -1\n\njulia> ishermitian(a)\ntrue\n\njulia> b = [1 im; -im 1]\n2×2 Matrix{Complex{Int64}}:\n 1+0im 0+1im\n 0-1im 1+0im\n\njulia> ishermitian(b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Base.transpose","page":"Linear Algebra","title":"Base.transpose","text":"transpose(A)\n\nLazy transpose. Mutating the returned object should appropriately mutate A. Often, but not always, yields Transpose(A), where Transpose is a lazy transpose wrapper. Note that this operation is recursive.\n\nThis operation is intended for linear algebra usage - for general data manipulation see permutedims, which is non-recursive.\n\nExamples\n\njulia> A = [3 2; 0 0]\n2×2 Matrix{Int64}:\n 3 2\n 0 0\n\njulia> B = transpose(A)\n2×2 transpose(::Matrix{Int64}) with eltype Int64:\n 3 0\n 2 0\n\njulia> B isa Transpose\ntrue\n\njulia> transpose(B) === A # the transpose of a transpose unwraps the parent\ntrue\n\njulia> Transpose(B) # however, the constructor always wraps its argument\n2×2 transpose(transpose(::Matrix{Int64})) with eltype Int64:\n 3 2\n 0 0\n\njulia> B[1,2] = 4; # modifying B will modify A automatically\n\njulia> A\n2×2 Matrix{Int64}:\n 3 2\n 4 0\n\nFor complex matrices, the adjoint operation is equivalent to a conjugate-transpose.\n\njulia> A = reshape([Complex(x, x) for x in 1:4], 2, 2)\n2×2 Matrix{Complex{Int64}}:\n 1+1im 3+3im\n 2+2im 4+4im\n\njulia> adjoint(A) == conj(transpose(A))\ntrue\n\nThe transpose of an AbstractVector is a row-vector:\n\njulia> v = [1,2,3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> transpose(v) # returns a row-vector\n1×3 transpose(::Vector{Int64}) with eltype Int64:\n 1 2 3\n\njulia> transpose(v) * v # compute the dot product\n14\n\nFor a matrix of matrices, the individual blocks are recursively operated on:\n\njulia> C = [1 3; 2 4]\n2×2 Matrix{Int64}:\n 1 3\n 2 4\n\njulia> D = reshape([C, 2C, 3C, 4C], 2, 2) # construct a block matrix\n2×2 Matrix{Matrix{Int64}}:\n [1 3; 2 4] [3 9; 6 12]\n [2 6; 4 8] [4 12; 8 16]\n\njulia> transpose(D) # blocks are recursively transposed\n2×2 transpose(::Matrix{Matrix{Int64}}) with eltype Transpose{Int64, Matrix{Int64}}:\n [1 2; 3 4] [2 4; 6 8]\n [3 6; 9 12] [4 8; 12 16]\n\n\n\n\n\ntranspose(F::Factorization)\n\nLazy transpose of the factorization F. By default, returns a TransposeFactorization, except for Factorizations with real eltype, in which case returns an AdjointFactorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.transpose!","page":"Linear Algebra","title":"LinearAlgebra.transpose!","text":"transpose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}) where {Tv,Ti}\n\nTranspose the matrix A and stores it in the matrix X. size(X) must be equal to size(transpose(A)). No additional memory is allocated other than resizing the rowval and nzval of X, if needed.\n\nSee halfperm!\n\n\n\n\n\ntranspose!(dest,src)\n\nTranspose array src and store the result in the preallocated array dest, which should have a size corresponding to (size(src,2),size(src,1)). No in-place transposition is supported and unexpected results will happen if src and dest have overlapping memory regions.\n\nExamples\n\njulia> A = [3+2im 9+2im; 8+7im 4+6im]\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 8+7im 4+6im\n\njulia> B = zeros(Complex{Int64}, 2, 2)\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+0im\n 0+0im 0+0im\n\njulia> transpose!(B, A);\n\njulia> B\n2×2 Matrix{Complex{Int64}}:\n 3+2im 8+7im\n 9+2im 4+6im\n\njulia> A\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 8+7im 4+6im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Transpose","page":"Linear Algebra","title":"LinearAlgebra.Transpose","text":"Transpose\n\nLazy wrapper type for a transpose view of the underlying linear algebra object, usually an AbstractVector/AbstractMatrix. Usually, the Transpose constructor should not be called directly, use transpose instead. To materialize the view use copy.\n\nThis type is intended for linear algebra usage - for general data manipulation see permutedims.\n\nExamples\n\njulia> A = [2 3; 0 0]\n2×2 Matrix{Int64}:\n 2 3\n 0 0\n\njulia> Transpose(A)\n2×2 transpose(::Matrix{Int64}) with eltype Int64:\n 2 0\n 3 0\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.TransposeFactorization","page":"Linear Algebra","title":"LinearAlgebra.TransposeFactorization","text":"TransposeFactorization\n\nLazy wrapper type for the transpose of the underlying Factorization object. Usually, the TransposeFactorization constructor should not be called directly, use transpose(:: Factorization) instead.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#Base.adjoint","page":"Linear Algebra","title":"Base.adjoint","text":"A'\nadjoint(A)\n\nLazy adjoint (conjugate transposition). Note that adjoint is applied recursively to elements.\n\nFor number types, adjoint returns the complex conjugate, and therefore it is equivalent to the identity function for real numbers.\n\nThis operation is intended for linear algebra usage - for general data manipulation see permutedims.\n\nExamples\n\njulia> A = [3+2im 9+2im; 0 0]\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 0+0im 0+0im\n\njulia> B = A' # equivalently adjoint(A)\n2×2 adjoint(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:\n 3-2im 0+0im\n 9-2im 0+0im\n\njulia> B isa Adjoint\ntrue\n\njulia> adjoint(B) === A # the adjoint of an adjoint unwraps the parent\ntrue\n\njulia> Adjoint(B) # however, the constructor always wraps its argument\n2×2 adjoint(adjoint(::Matrix{Complex{Int64}})) with eltype Complex{Int64}:\n 3+2im 9+2im\n 0+0im 0+0im\n\njulia> B[1,2] = 4 + 5im; # modifying B will modify A automatically\n\njulia> A\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 4-5im 0+0im\n\nFor real matrices, the adjoint operation is equivalent to a transpose.\n\njulia> A = reshape([x for x in 1:4], 2, 2)\n2×2 Matrix{Int64}:\n 1 3\n 2 4\n\njulia> A'\n2×2 adjoint(::Matrix{Int64}) with eltype Int64:\n 1 2\n 3 4\n\njulia> adjoint(A) == transpose(A)\ntrue\n\nThe adjoint of an AbstractVector is a row-vector:\n\njulia> x = [3, 4im]\n2-element Vector{Complex{Int64}}:\n 3 + 0im\n 0 + 4im\n\njulia> x'\n1×2 adjoint(::Vector{Complex{Int64}}) with eltype Complex{Int64}:\n 3+0im 0-4im\n\njulia> x'x # compute the dot product, equivalently x' * x\n25 + 0im\n\nFor a matrix of matrices, the individual blocks are recursively operated on:\n\njulia> A = reshape([x + im*x for x in 1:4], 2, 2)\n2×2 Matrix{Complex{Int64}}:\n 1+1im 3+3im\n 2+2im 4+4im\n\njulia> C = reshape([A, 2A, 3A, 4A], 2, 2)\n2×2 Matrix{Matrix{Complex{Int64}}}:\n [1+1im 3+3im; 2+2im 4+4im] [3+3im 9+9im; 6+6im 12+12im]\n [2+2im 6+6im; 4+4im 8+8im] [4+4im 12+12im; 8+8im 16+16im]\n\njulia> C'\n2×2 adjoint(::Matrix{Matrix{Complex{Int64}}}) with eltype Adjoint{Complex{Int64}, Matrix{Complex{Int64}}}:\n [1-1im 2-2im; 3-3im 4-4im] [2-2im 4-4im; 6-6im 8-8im]\n [3-3im 6-6im; 9-9im 12-12im] [4-4im 8-8im; 12-12im 16-16im]\n\n\n\n\n\nadjoint(F::Factorization)\n\nLazy adjoint of the factorization F. By default, returns an AdjointFactorization wrapper.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.adjoint!","page":"Linear Algebra","title":"LinearAlgebra.adjoint!","text":"adjoint!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}) where {Tv,Ti}\n\nTranspose the matrix A and stores the adjoint of the elements in the matrix X. size(X) must be equal to size(transpose(A)). No additional memory is allocated other than resizing the rowval and nzval of X, if needed.\n\nSee halfperm!\n\n\n\n\n\nadjoint!(dest,src)\n\nConjugate transpose array src and store the result in the preallocated array dest, which should have a size corresponding to (size(src,2),size(src,1)). No in-place transposition is supported and unexpected results will happen if src and dest have overlapping memory regions.\n\nExamples\n\njulia> A = [3+2im 9+2im; 8+7im 4+6im]\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 8+7im 4+6im\n\njulia> B = zeros(Complex{Int64}, 2, 2)\n2×2 Matrix{Complex{Int64}}:\n 0+0im 0+0im\n 0+0im 0+0im\n\njulia> adjoint!(B, A);\n\njulia> B\n2×2 Matrix{Complex{Int64}}:\n 3-2im 8-7im\n 9-2im 4-6im\n\njulia> A\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 8+7im 4+6im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.Adjoint","page":"Linear Algebra","title":"LinearAlgebra.Adjoint","text":"Adjoint\n\nLazy wrapper type for an adjoint view of the underlying linear algebra object, usually an AbstractVector/AbstractMatrix. Usually, the Adjoint constructor should not be called directly, use adjoint instead. To materialize the view use copy.\n\nThis type is intended for linear algebra usage - for general data manipulation see permutedims.\n\nExamples\n\njulia> A = [3+2im 9+2im; 0 0]\n2×2 Matrix{Complex{Int64}}:\n 3+2im 9+2im\n 0+0im 0+0im\n\njulia> Adjoint(A)\n2×2 adjoint(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:\n 3-2im 0+0im\n 9-2im 0+0im\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.AdjointFactorization","page":"Linear Algebra","title":"LinearAlgebra.AdjointFactorization","text":"AdjointFactorization\n\nLazy wrapper type for the adjoint of the underlying Factorization object. Usually, the AdjointFactorization constructor should not be called directly, use adjoint(:: Factorization) instead.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/LinearAlgebra/#Base.copy-Tuple{Union{Adjoint, Transpose}}","page":"Linear Algebra","title":"Base.copy","text":"copy(A::Transpose)\ncopy(A::Adjoint)\n\nEagerly evaluate the lazy matrix transpose/adjoint. Note that the transposition is applied recursively to elements.\n\nThis operation is intended for linear algebra usage - for general data manipulation see permutedims, which is non-recursive.\n\nExamples\n\njulia> A = [1 2im; -3im 4]\n2×2 Matrix{Complex{Int64}}:\n 1+0im 0+2im\n 0-3im 4+0im\n\njulia> T = transpose(A)\n2×2 transpose(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:\n 1+0im 0-3im\n 0+2im 4+0im\n\njulia> copy(T)\n2×2 Matrix{Complex{Int64}}:\n 1+0im 0-3im\n 0+2im 4+0im\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.stride1","page":"Linear Algebra","title":"LinearAlgebra.stride1","text":"stride1(A) -> Int\n\nReturn the distance between successive array elements in dimension 1 in units of element size.\n\nExamples\n\njulia> A = [1,2,3,4]\n4-element Vector{Int64}:\n 1\n 2\n 3\n 4\n\njulia> LinearAlgebra.stride1(A)\n1\n\njulia> B = view(A, 2:2:4)\n2-element view(::Vector{Int64}, 2:2:4) with eltype Int64:\n 2\n 4\n\njulia> LinearAlgebra.stride1(B)\n2\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.checksquare","page":"Linear Algebra","title":"LinearAlgebra.checksquare","text":"LinearAlgebra.checksquare(A)\n\nCheck that a matrix is square, then return its common dimension. For multiple arguments, return a vector.\n\nExamples\n\njulia> A = fill(1, (4,4)); B = fill(1, (5,5));\n\njulia> LinearAlgebra.checksquare(A, B)\n2-element Vector{Int64}:\n 4\n 5\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.peakflops","page":"Linear Algebra","title":"LinearAlgebra.peakflops","text":"LinearAlgebra.peakflops(n::Integer=4096; eltype::DataType=Float64, ntrials::Integer=3, parallel::Bool=false)\n\npeakflops computes the peak flop rate of the computer by using double precision gemm!. By default, if no arguments are specified, it multiplies two Float64 matrices of size n x n, where n = 4096. If the underlying BLAS is using multiple threads, higher flop rates are realized. The number of BLAS threads can be set with BLAS.set_num_threads(n).\n\nIf the keyword argument eltype is provided, peakflops will construct matrices with elements of type eltype for calculating the peak flop rate.\n\nBy default, peakflops will use the best timing from 3 trials. If the ntrials keyword argument is provided, peakflops will use those many trials for picking the best timing.\n\nIf the keyword argument parallel is set to true, peakflops is run in parallel on all the worker processors. The flop rate of the entire parallel computer is returned. When running in parallel, only 1 BLAS thread is used. The argument n still refers to the size of the problem that is solved on each processor.\n\ncompat: Julia 1.1\nThis function requires at least Julia 1.1. In Julia 1.0 it is available from the standard library InteractiveUtils.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.hermitianpart","page":"Linear Algebra","title":"LinearAlgebra.hermitianpart","text":"hermitianpart(A, uplo=:U) -> Hermitian\n\nReturn the Hermitian part of the square matrix A, defined as (A + A') / 2, as a Hermitian matrix. For real matrices A, this is also known as the symmetric part of A; it is also sometimes called the \"operator real part\". The optional argument uplo controls the corresponding argument of the Hermitian view. For real matrices, the latter is equivalent to a Symmetric view.\n\nSee also hermitianpart! for the corresponding in-place operation.\n\ncompat: Julia 1.10\nThis function requires Julia 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.hermitianpart!","page":"Linear Algebra","title":"LinearAlgebra.hermitianpart!","text":"hermitianpart!(A, uplo=:U) -> Hermitian\n\nOverwrite the square matrix A in-place with its Hermitian part (A + A') / 2, and return Hermitian(A, uplo). For real matrices A, this is also known as the symmetric part of A.\n\nSee also hermitianpart for the corresponding out-of-place operation.\n\ncompat: Julia 1.10\nThis function requires Julia 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.copy_adjoint!","page":"Linear Algebra","title":"LinearAlgebra.copy_adjoint!","text":"copy_adjoint!(B::AbstractVecOrMat, ir_dest::AbstractRange{Int}, jr_dest::AbstractRange{Int},\n A::AbstractVecOrMat, ir_src::AbstractRange{Int}, jr_src::AbstractRange{Int}) -> B\n\nEfficiently copy elements of matrix A to B with adjunction as follows:\n\nB[ir_dest, jr_dest] = adjoint(A)[jr_src, ir_src]\n\nThe elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(jr_src) and length(jr_dest) == length(ir_src).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.copy_transpose!","page":"Linear Algebra","title":"LinearAlgebra.copy_transpose!","text":"copy_transpose!(B::AbstractVecOrMat, ir_dest::AbstractRange{Int}, jr_dest::AbstractRange{Int},\n A::AbstractVecOrMat, ir_src::AbstractRange{Int}, jr_src::AbstractRange{Int}) -> B\n\nEfficiently copy elements of matrix A to B with transposition as follows:\n\nB[ir_dest, jr_dest] = transpose(A)[jr_src, ir_src]\n\nThe elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(jr_src) and length(jr_dest) == length(ir_src).\n\n\n\n\n\ncopy_transpose!(B::AbstractMatrix, ir_dest::AbstractUnitRange, jr_dest::AbstractUnitRange,\n tM::AbstractChar,\n M::AbstractVecOrMat, ir_src::AbstractUnitRange, jr_src::AbstractUnitRange) -> B\n\nEfficiently copy elements of matrix M to B conditioned on the character parameter tM as follows:\n\ntM Destination Source\n'N' B[ir_dest, jr_dest] transpose(M)[jr_src, ir_src]\n'T' B[ir_dest, jr_dest] M[jr_src, ir_src]\n'C' B[ir_dest, jr_dest] conj(M)[jr_src, ir_src]\n\nThe elements B[ir_dest, jr_dest] are overwritten. Furthermore, the index range parameters must satisfy length(ir_dest) == length(jr_src) and length(jr_dest) == length(ir_src).\n\nSee also copyto! and copy_adjoint!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Low-level-matrix-operations","page":"Linear Algebra","title":"Low-level matrix operations","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In many cases there are in-place versions of matrix operations that allow you to supply a pre-allocated output vector or matrix. This is useful when optimizing critical code in order to avoid the overhead of repeated allocations. These in-place operations are suffixed with ! below (e.g. mul!) according to the usual Julia convention.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.mul!\nLinearAlgebra.lmul!\nLinearAlgebra.rmul!\nLinearAlgebra.ldiv!\nLinearAlgebra.rdiv!","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.mul!","page":"Linear Algebra","title":"LinearAlgebra.mul!","text":"mul!(Y, A, B) -> Y\n\nCalculates the matrix-matrix or matrix-vector product A B and stores the result in Y, overwriting the existing value of Y. Note that Y must not be aliased with either A or B.\n\nExamples\n\njulia> A = [1.0 2.0; 3.0 4.0]; B = [1.0 1.0; 1.0 1.0]; Y = similar(B);\n\njulia> mul!(Y, A, B) === Y\ntrue\n\njulia> Y\n2×2 Matrix{Float64}:\n 3.0 3.0\n 7.0 7.0\n\njulia> Y == A * B\ntrue\n\nImplementation\n\nFor custom matrix and vector types, it is recommended to implement 5-argument mul! rather than implementing 3-argument mul! directly if possible.\n\n\n\n\n\nmul!(C, A, B, α, β) -> C\n\nCombined inplace matrix-matrix or matrix-vector multiply-add A B α + C β. The result is stored in C by overwriting it. Note that C must not be aliased with either A or B.\n\ncompat: Julia 1.3\nFive-argument mul! requires at least Julia 1.3.\n\nExamples\n\njulia> A = [1.0 2.0; 3.0 4.0]; B = [1.0 1.0; 1.0 1.0]; C = [1.0 2.0; 3.0 4.0];\n\njulia> α, β = 100.0, 10.0;\n\njulia> mul!(C, A, B, α, β) === C\ntrue\n\njulia> C\n2×2 Matrix{Float64}:\n 310.0 320.0\n 730.0 740.0\n\njulia> C_original = [1.0 2.0; 3.0 4.0]; # A copy of the original value of C\n\njulia> C == A * B * α + C_original * β\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.lmul!","page":"Linear Algebra","title":"LinearAlgebra.lmul!","text":"lmul!(a::Number, B::AbstractArray)\n\nScale an array B by a scalar a overwriting B in-place. Use rmul! to multiply scalar from right. The scaling operation respects the semantics of the multiplication * between a and an element of B. In particular, this also applies to multiplication involving non-finite numbers such as NaN and ±Inf.\n\ncompat: Julia 1.1\nPrior to Julia 1.1, NaN and ±Inf entries in B were treated inconsistently.\n\nExamples\n\njulia> B = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> lmul!(2, B)\n2×2 Matrix{Int64}:\n 2 4\n 6 8\n\njulia> lmul!(0.0, [Inf])\n1-element Vector{Float64}:\n NaN\n\n\n\n\n\nlmul!(A, B)\n\nCalculate the matrix-matrix product AB, overwriting B, and return the result. Here, A must be of special matrix type, like, e.g., Diagonal, UpperTriangular or LowerTriangular, or of some orthogonal type, see QR.\n\nExamples\n\njulia> B = [0 1; 1 0];\n\njulia> A = UpperTriangular([1 2; 0 3]);\n\njulia> lmul!(A, B);\n\njulia> B\n2×2 Matrix{Int64}:\n 2 1\n 3 0\n\njulia> B = [1.0 2.0; 3.0 4.0];\n\njulia> F = qr([0 1; -1 0]);\n\njulia> lmul!(F.Q, B)\n2×2 Matrix{Float64}:\n 3.0 4.0\n 1.0 2.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.rmul!","page":"Linear Algebra","title":"LinearAlgebra.rmul!","text":"rmul!(A::AbstractArray, b::Number)\n\nScale an array A by a scalar b overwriting A in-place. Use lmul! to multiply scalar from left. The scaling operation respects the semantics of the multiplication * between an element of A and b. In particular, this also applies to multiplication involving non-finite numbers such as NaN and ±Inf.\n\ncompat: Julia 1.1\nPrior to Julia 1.1, NaN and ±Inf entries in A were treated inconsistently.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> rmul!(A, 2)\n2×2 Matrix{Int64}:\n 2 4\n 6 8\n\njulia> rmul!([NaN], 0.0)\n1-element Vector{Float64}:\n NaN\n\n\n\n\n\nrmul!(A, B)\n\nCalculate the matrix-matrix product AB, overwriting A, and return the result. Here, B must be of special matrix type, like, e.g., Diagonal, UpperTriangular or LowerTriangular, or of some orthogonal type, see QR.\n\nExamples\n\njulia> A = [0 1; 1 0];\n\njulia> B = UpperTriangular([1 2; 0 3]);\n\njulia> rmul!(A, B);\n\njulia> A\n2×2 Matrix{Int64}:\n 0 3\n 1 2\n\njulia> A = [1.0 2.0; 3.0 4.0];\n\njulia> F = qr([0 1; -1 0]);\n\njulia> rmul!(A, F.Q)\n2×2 Matrix{Float64}:\n 2.0 1.0\n 4.0 3.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.ldiv!","page":"Linear Algebra","title":"LinearAlgebra.ldiv!","text":"ldiv!(Y, A, B) -> Y\n\nCompute A \\ B in-place and store the result in Y, returning the result.\n\nThe argument A should not be a matrix. Rather, instead of matrices it should be a factorization object (e.g. produced by factorize or cholesky). The reason for this is that factorization itself is both expensive and typically allocates memory (although it can also be done in-place via, e.g., lu!), and performance-critical situations requiring ldiv! usually also require fine-grained control over the factorization of A.\n\nnote: Note\nCertain structured matrix types, such as Diagonal and UpperTriangular, are permitted, as these are already in a factorized form\n\nExamples\n\njulia> A = [1 2.2 4; 3.1 0.2 3; 4 1 2];\n\njulia> X = [1; 2.5; 3];\n\njulia> Y = zero(X);\n\njulia> ldiv!(Y, qr(A), X);\n\njulia> Y\n3-element Vector{Float64}:\n 0.7128099173553719\n -0.051652892561983674\n 0.10020661157024757\n\njulia> A\\X\n3-element Vector{Float64}:\n 0.7128099173553719\n -0.05165289256198333\n 0.10020661157024785\n\n\n\n\n\nldiv!(A, B)\n\nCompute A \\ B in-place and overwriting B to store the result.\n\nThe argument A should not be a matrix. Rather, instead of matrices it should be a factorization object (e.g. produced by factorize or cholesky). The reason for this is that factorization itself is both expensive and typically allocates memory (although it can also be done in-place via, e.g., lu!), and performance-critical situations requiring ldiv! usually also require fine-grained control over the factorization of A.\n\nnote: Note\nCertain structured matrix types, such as Diagonal and UpperTriangular, are permitted, as these are already in a factorized form\n\nExamples\n\njulia> A = [1 2.2 4; 3.1 0.2 3; 4 1 2];\n\njulia> X = [1; 2.5; 3];\n\njulia> Y = copy(X);\n\njulia> ldiv!(qr(A), X);\n\njulia> X\n3-element Vector{Float64}:\n 0.7128099173553719\n -0.051652892561983674\n 0.10020661157024757\n\njulia> A\\Y\n3-element Vector{Float64}:\n 0.7128099173553719\n -0.05165289256198333\n 0.10020661157024785\n\n\n\n\n\nldiv!(a::Number, B::AbstractArray)\n\nDivide each entry in an array B by a scalar a overwriting B in-place. Use rdiv! to divide scalar from right.\n\nExamples\n\njulia> B = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> ldiv!(2.0, B)\n2×2 Matrix{Float64}:\n 0.5 1.0\n 1.5 2.0\n\n\n\n\n\nldiv!(A::Tridiagonal, B::AbstractVecOrMat) -> B\n\nCompute A \\ B in-place by Gaussian elimination with partial pivoting and store the result in B, returning the result. In the process, the diagonals of A are overwritten as well.\n\ncompat: Julia 1.11\nldiv! for Tridiagonal left-hand sides requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.rdiv!","page":"Linear Algebra","title":"LinearAlgebra.rdiv!","text":"rdiv!(A, B)\n\nCompute A / B in-place and overwriting A to store the result.\n\nThe argument B should not be a matrix. Rather, instead of matrices it should be a factorization object (e.g. produced by factorize or cholesky). The reason for this is that factorization itself is both expensive and typically allocates memory (although it can also be done in-place via, e.g., lu!), and performance-critical situations requiring rdiv! usually also require fine-grained control over the factorization of B.\n\nnote: Note\nCertain structured matrix types, such as Diagonal and UpperTriangular, are permitted, as these are already in a factorized form\n\n\n\n\n\nrdiv!(A::AbstractArray, b::Number)\n\nDivide each entry in an array A by a scalar b overwriting A in-place. Use ldiv! to divide scalar from left.\n\nExamples\n\njulia> A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> rdiv!(A, 2.0)\n2×2 Matrix{Float64}:\n 0.5 1.0\n 1.5 2.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#BLAS-functions","page":"Linear Algebra","title":"BLAS functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"In Julia (as in much of scientific computation), dense linear-algebra operations are based on the LAPACK library, which in turn is built on top of basic linear-algebra building-blocks known as the BLAS. There are highly optimized implementations of BLAS available for every computer architecture, and sometimes in high-performance linear algebra routines it is useful to call the BLAS functions directly.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS provides wrappers for some of the BLAS functions. Those BLAS functions that overwrite one of the input arrays have names ending in '!'. Usually, a BLAS function has four methods defined, for Float32, Float64, ComplexF32, and ComplexF64 arrays.","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-chars","page":"Linear Algebra","title":"BLAS character arguments","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Many BLAS functions accept arguments that determine whether to transpose an argument (trans), which triangle of a matrix to reference (uplo or ul), whether the diagonal of a triangular matrix can be assumed to be all ones (dA) or which side of a matrix multiplication the input argument belongs on (side). The possibilities are:","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-side","page":"Linear Algebra","title":"Multiplication order","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"side Meaning\n'L' The argument goes on the left side of a matrix-matrix operation.\n'R' The argument goes on the right side of a matrix-matrix operation.","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-uplo","page":"Linear Algebra","title":"Triangle referencing","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"uplo/ul Meaning\n'U' Only the upper triangle of the matrix will be used.\n'L' Only the lower triangle of the matrix will be used.","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-trans","page":"Linear Algebra","title":"Transposition operation","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"trans/tX Meaning\n'N' The input matrix X is not transposed or conjugated.\n'T' The input matrix X will be transposed.\n'C' The input matrix X will be conjugated and transposed.","category":"page"},{"location":"stdlib/LinearAlgebra/#stdlib-blas-diag","page":"Linear Algebra","title":"Unit diagonal","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"diag/dX Meaning\n'N' The diagonal values of the matrix X will be read.\n'U' The diagonal of the matrix X is assumed to be all ones.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS\nLinearAlgebra.BLAS.set_num_threads\nLinearAlgebra.BLAS.get_num_threads","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS","page":"Linear Algebra","title":"LinearAlgebra.BLAS","text":"Interface to BLAS subroutines.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.set_num_threads","page":"Linear Algebra","title":"LinearAlgebra.BLAS.set_num_threads","text":"set_num_threads(n::Integer)\nset_num_threads(::Nothing)\n\nSet the number of threads the BLAS library should use equal to n::Integer.\n\nAlso accepts nothing, in which case julia tries to guess the default number of threads. Passing nothing is discouraged and mainly exists for historical reasons.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.get_num_threads","page":"Linear Algebra","title":"LinearAlgebra.BLAS.get_num_threads","text":"get_num_threads()\n\nGet the number of threads the BLAS library is using.\n\ncompat: Julia 1.6\nget_num_threads requires at least Julia 1.6.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"BLAS functions can be divided into three groups, also called three levels, depending on when they were first proposed, the type of input parameters, and the complexity of the operation.","category":"page"},{"location":"stdlib/LinearAlgebra/#Level-1-BLAS-functions","page":"Linear Algebra","title":"Level 1 BLAS functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The level 1 BLAS functions were first proposed in [(Lawson, 1979)][Lawson-1979] and define operations between scalars and vectors.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"[Lawson-1979]: https://dl.acm.org/doi/10.1145/355841.355847","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"# xROTG\n# xROTMG\nLinearAlgebra.BLAS.rot!\n# xROTM\n# xSWAP\nLinearAlgebra.BLAS.scal!\nLinearAlgebra.BLAS.scal\nLinearAlgebra.BLAS.blascopy!\n# xAXPY!\n# xAXPBY!\nLinearAlgebra.BLAS.dot\nLinearAlgebra.BLAS.dotu\nLinearAlgebra.BLAS.dotc\n# xxDOT\nLinearAlgebra.BLAS.nrm2\nLinearAlgebra.BLAS.asum\nLinearAlgebra.BLAS.iamax","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.rot!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.rot!","text":"rot!(n, X, incx, Y, incy, c, s)\n\nOverwrite X with c*X + s*Y and Y with -conj(s)*X + c*Y for the first n elements of array X with stride incx and first n elements of array Y with stride incy. Returns X and Y.\n\ncompat: Julia 1.5\nrot! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.scal!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.scal!","text":"scal!(n, a, X, incx)\nscal!(a, X)\n\nOverwrite X with a*X for the first n elements of array X with stride incx. Returns X.\n\nIf n and incx are not provided, length(X) and stride(X,1) are used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.scal","page":"Linear Algebra","title":"LinearAlgebra.BLAS.scal","text":"scal(n, a, X, incx)\nscal(a, X)\n\nReturn X scaled by a for the first n elements of array X with stride incx.\n\nIf n and incx are not provided, length(X) and stride(X,1) are used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.blascopy!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.blascopy!","text":"blascopy!(n, X, incx, Y, incy)\n\nCopy n elements of array X with stride incx to array Y with stride incy. Returns Y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.dot","page":"Linear Algebra","title":"LinearAlgebra.BLAS.dot","text":"dot(n, X, incx, Y, incy)\n\nDot product of two vectors consisting of n elements of array X with stride incx and n elements of array Y with stride incy.\n\nExamples\n\njulia> BLAS.dot(10, fill(1.0, 10), 1, fill(1.0, 20), 2)\n10.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.dotu","page":"Linear Algebra","title":"LinearAlgebra.BLAS.dotu","text":"dotu(n, X, incx, Y, incy)\n\nDot function for two complex vectors consisting of n elements of array X with stride incx and n elements of array Y with stride incy.\n\nExamples\n\njulia> BLAS.dotu(10, fill(1.0im, 10), 1, fill(1.0+im, 20), 2)\n-10.0 + 10.0im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.dotc","page":"Linear Algebra","title":"LinearAlgebra.BLAS.dotc","text":"dotc(n, X, incx, U, incy)\n\nDot function for two complex vectors, consisting of n elements of array X with stride incx and n elements of array U with stride incy, conjugating the first vector.\n\nExamples\n\njulia> BLAS.dotc(10, fill(1.0im, 10), 1, fill(1.0+im, 20), 2)\n10.0 - 10.0im\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.nrm2","page":"Linear Algebra","title":"LinearAlgebra.BLAS.nrm2","text":"nrm2(n, X, incx)\n\n2-norm of a vector consisting of n elements of array X with stride incx.\n\nExamples\n\njulia> BLAS.nrm2(4, fill(1.0, 8), 2)\n2.0\n\njulia> BLAS.nrm2(1, fill(1.0, 8), 2)\n1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.asum","page":"Linear Algebra","title":"LinearAlgebra.BLAS.asum","text":"asum(n, X, incx)\n\nSum of the magnitudes of the first n elements of array X with stride incx.\n\nFor a real array, the magnitude is the absolute value. For a complex array, the magnitude is the sum of the absolute value of the real part and the absolute value of the imaginary part.\n\nExamples\n\njulia> BLAS.asum(5, fill(1.0im, 10), 2)\n5.0\n\njulia> BLAS.asum(2, fill(1.0im, 10), 5)\n2.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.iamax","page":"Linear Algebra","title":"LinearAlgebra.BLAS.iamax","text":"iamax(n, dx, incx)\niamax(dx)\n\nFind the index of the element of dx with the maximum absolute value. n is the length of dx, and incx is the stride. If n and incx are not provided, they assume default values of n=length(dx) and incx=stride1(dx).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Level-2-BLAS-functions","page":"Linear Algebra","title":"Level 2 BLAS functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The level 2 BLAS functions were published in [(Dongarra, 1988)][Dongarra-1988], and define matrix-vector operations.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"[Dongarra-1988]: https://dl.acm.org/doi/10.1145/42288.42291","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"return a vector","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS.gemv!\nLinearAlgebra.BLAS.gemv(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gemv(::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gbmv!\nLinearAlgebra.BLAS.gbmv\nLinearAlgebra.BLAS.hemv!\nLinearAlgebra.BLAS.hemv(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.hemv(::Any, ::Any, ::Any)\n# hbmv!, hbmv\nLinearAlgebra.BLAS.hpmv!\nLinearAlgebra.BLAS.symv!\nLinearAlgebra.BLAS.symv(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.symv(::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.sbmv!\nLinearAlgebra.BLAS.sbmv(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.sbmv(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.spmv!\nLinearAlgebra.BLAS.trmv!\nLinearAlgebra.BLAS.trmv\n# xTBMV\n# xTPMV\nLinearAlgebra.BLAS.trsv!\nLinearAlgebra.BLAS.trsv\n# xTBSV\n# xTPSV","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemv!","text":"gemv!(tA, alpha, A, x, beta, y)\n\nUpdate the vector y as alpha*A*x + beta*y or alpha*A'x + beta*y according to tA. alpha and beta are scalars. Return the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemv-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemv","text":"gemv(tA, alpha, A, x)\n\nReturn alpha*A*x or alpha*A'x according to tA. alpha is a scalar.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemv-Tuple{Any, Any, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemv","text":"gemv(tA, A, x)\n\nReturn A*x or A'x according to tA.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gbmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gbmv!","text":"gbmv!(trans, m, kl, ku, alpha, A, x, beta, y)\n\nUpdate vector y as alpha*A*x + beta*y or alpha*A'*x + beta*y according to trans. The matrix A is a general band matrix of dimension m by size(A,2) with kl sub-diagonals and ku super-diagonals. alpha and beta are scalars. Return the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gbmv","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gbmv","text":"gbmv(trans, m, kl, ku, alpha, A, x)\n\nReturn alpha*A*x or alpha*A'*x according to trans. The matrix A is a general band matrix of dimension m by size(A,2) with kl sub-diagonals and ku super-diagonals, and alpha is a scalar.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemv!","text":"hemv!(ul, alpha, A, x, beta, y)\n\nUpdate the vector y as alpha*A*x + beta*y. A is assumed to be Hermitian. Only the ul triangle of A is used. alpha and beta are scalars. Return the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemv-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemv","text":"hemv(ul, alpha, A, x)\n\nReturn alpha*A*x. A is assumed to be Hermitian. Only the ul triangle of A is used. alpha is a scalar.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemv-Tuple{Any, Any, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemv","text":"hemv(ul, A, x)\n\nReturn A*x. A is assumed to be Hermitian. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hpmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hpmv!","text":"hpmv!(uplo, α, AP, x, β, y)\n\nUpdate vector y as α*A*x + β*y, where A is a Hermitian matrix provided in packed format AP.\n\nWith uplo = 'U', the array AP must contain the upper triangular part of the Hermitian matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.\n\nWith uplo = 'L', the array AP must contain the lower triangular part of the Hermitian matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.\n\nThe scalar inputs α and β must be complex or real numbers.\n\nThe array inputs x, y and AP must all be of ComplexF32 or ComplexF64 type.\n\nReturn the updated y.\n\ncompat: Julia 1.5\nhpmv! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symv!","text":"symv!(ul, alpha, A, x, beta, y)\n\nUpdate the vector y as alpha*A*x + beta*y. A is assumed to be symmetric. Only the ul triangle of A is used. alpha and beta are scalars. Return the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symv-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symv","text":"symv(ul, alpha, A, x)\n\nReturn alpha*A*x. A is assumed to be symmetric. Only the ul triangle of A is used. alpha is a scalar.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symv-Tuple{Any, Any, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symv","text":"symv(ul, A, x)\n\nReturn A*x. A is assumed to be symmetric. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.sbmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.sbmv!","text":"sbmv!(uplo, k, alpha, A, x, beta, y)\n\nUpdate vector y as alpha*A*x + beta*y where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. The storage layout for A is described the reference BLAS module, level-2 BLAS at https://www.netlib.org/lapack/explore-html/. Only the uplo triangle of A is used.\n\nReturn the updated y.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.sbmv-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.sbmv","text":"sbmv(uplo, k, alpha, A, x)\n\nReturn alpha*A*x where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. Only the uplo triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.sbmv-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.sbmv","text":"sbmv(uplo, k, A, x)\n\nReturn A*x where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. Only the uplo triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.spmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.spmv!","text":"spmv!(uplo, α, AP, x, β, y)\n\nUpdate vector y as α*A*x + β*y, where A is a symmetric matrix provided in packed format AP.\n\nWith uplo = 'U', the array AP must contain the upper triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.\n\nWith uplo = 'L', the array AP must contain the lower triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.\n\nThe scalar inputs α and β must be real.\n\nThe array inputs x, y and AP must all be of Float32 or Float64 type.\n\nReturn the updated y.\n\ncompat: Julia 1.5\nspmv! requires at least Julia 1.5.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trmv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trmv!","text":"trmv!(ul, tA, dA, A, b)\n\nReturn op(A)*b, where op is determined by tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. The multiplication occurs in-place on b.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trmv","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trmv","text":"trmv(ul, tA, dA, A, b)\n\nReturn op(A)*b, where op is determined by tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trsv!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trsv!","text":"trsv!(ul, tA, dA, A, b)\n\nOverwrite b with the solution to A*x = b or one of the other two variants determined by tA and ul. dA determines if the diagonal values are read or are assumed to be all ones. Return the updated b.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trsv","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trsv","text":"trsv(ul, tA, dA, A, b)\n\nReturn the solution to A*x = b or one of the other two variants determined by tA and ul. dA determines if the diagonal values are read or are assumed to be all ones.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"return a matrix","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS.ger!\n# xGERU\n# xGERC\nLinearAlgebra.BLAS.her!\n# xHPR\n# xHER2\n# xHPR2\nLinearAlgebra.BLAS.syr!\nLinearAlgebra.BLAS.spr!\n# xSYR2\n# xSPR2","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.ger!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.ger!","text":"ger!(alpha, x, y, A)\n\nRank-1 update of the matrix A with vectors x and y as alpha*x*y' + A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.her!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.her!","text":"her!(uplo, alpha, x, A)\n\nMethods for complex arrays only. Rank-1 update of the Hermitian matrix A with vector x as alpha*x*x' + A. uplo controls which triangle of A is updated. Returns A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syr!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syr!","text":"syr!(uplo, alpha, x, A)\n\nRank-1 update of the symmetric matrix A with vector x as alpha*x*transpose(x) + A. uplo controls which triangle of A is updated. Returns A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.spr!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.spr!","text":"spr!(uplo, α, x, AP)\n\nUpdate matrix A as A+α*x*x', where A is a symmetric matrix provided in packed format AP and x is a vector.\n\nWith uplo = 'U', the array AP must contain the upper triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.\n\nWith uplo = 'L', the array AP must contain the lower triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.\n\nThe scalar input α must be real.\n\nThe array inputs x and AP must all be of Float32 or Float64 type. Return the updated AP.\n\ncompat: Julia 1.8\nspr! requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#Level-3-BLAS-functions","page":"Linear Algebra","title":"Level 3 BLAS functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"The level 3 BLAS functions were published in [(Dongarra, 1990)][Dongarra-1990], and define matrix-matrix operations.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"[Dongarra-1990]: https://dl.acm.org/doi/10.1145/77626.79170","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.BLAS.gemmt!\nLinearAlgebra.BLAS.gemmt(::Any, ::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gemmt(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gemm!\nLinearAlgebra.BLAS.gemm(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.gemm(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.symm!\nLinearAlgebra.BLAS.symm(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.symm(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.hemm!\nLinearAlgebra.BLAS.hemm(::Any, ::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.hemm(::Any, ::Any, ::Any, ::Any)\nLinearAlgebra.BLAS.syrk!\nLinearAlgebra.BLAS.syrk\nLinearAlgebra.BLAS.herk!\nLinearAlgebra.BLAS.herk\nLinearAlgebra.BLAS.syr2k!\nLinearAlgebra.BLAS.syr2k\nLinearAlgebra.BLAS.her2k!\nLinearAlgebra.BLAS.her2k\nLinearAlgebra.BLAS.trmm!\nLinearAlgebra.BLAS.trmm\nLinearAlgebra.BLAS.trsm!\nLinearAlgebra.BLAS.trsm","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemmt!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemmt!","text":"gemmt!(uplo, tA, tB, alpha, A, B, beta, C)\n\nUpdate the lower or upper triangular part specified by uplo of C as alpha*A*B + beta*C or the other variants according to tA and tB. Return the updated C.\n\ncompat: Julia 1.11\ngemmt! requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemmt-NTuple{6, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemmt","text":"gemmt(uplo, tA, tB, alpha, A, B)\n\nReturn the lower or upper triangular part specified by uplo of A*B or the other three variants according to tA and tB.\n\ncompat: Julia 1.11\ngemmt requires at least Julia 1.11.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemmt-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemmt","text":"gemmt(uplo, tA, tB, A, B)\n\nReturn the lower or upper triangular part specified by uplo of A*B or the other three variants according to tA and tB.\n\ncompat: Julia 1.11\ngemmt requires at least Julia 1.11.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemm!","text":"gemm!(tA, tB, alpha, A, B, beta, C)\n\nUpdate C as alpha*A*B + beta*C or the other three variants according to tA and tB. Return the updated C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemm-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemm","text":"gemm(tA, tB, alpha, A, B)\n\nReturn alpha*A*B or the other three variants according to tA and tB.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.gemm-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.gemm","text":"gemm(tA, tB, A, B)\n\nReturn A*B or the other three variants according to tA and tB.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symm!","text":"symm!(side, ul, alpha, A, B, beta, C)\n\nUpdate C as alpha*A*B + beta*C or alpha*B*A + beta*C according to side. A is assumed to be symmetric. Only the ul triangle of A is used. Return the updated C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symm-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symm","text":"symm(side, ul, alpha, A, B)\n\nReturn alpha*A*B or alpha*B*A according to side. A is assumed to be symmetric. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.symm-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.symm","text":"symm(side, ul, A, B)\n\nReturn A*B or B*A according to side. A is assumed to be symmetric. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemm!","text":"hemm!(side, ul, alpha, A, B, beta, C)\n\nUpdate C as alpha*A*B + beta*C or alpha*B*A + beta*C according to side. A is assumed to be Hermitian. Only the ul triangle of A is used. Return the updated C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemm-NTuple{5, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemm","text":"hemm(side, ul, alpha, A, B)\n\nReturn alpha*A*B or alpha*B*A according to side. A is assumed to be Hermitian. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.hemm-NTuple{4, Any}","page":"Linear Algebra","title":"LinearAlgebra.BLAS.hemm","text":"hemm(side, ul, A, B)\n\nReturn A*B or B*A according to side. A is assumed to be Hermitian. Only the ul triangle of A is used.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syrk!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syrk!","text":"syrk!(uplo, trans, alpha, A, beta, C)\n\nRank-k update of the symmetric matrix C as alpha*A*transpose(A) + beta*C or alpha*transpose(A)*A + beta*C according to trans. Only the uplo triangle of C is used. Return C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syrk","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syrk","text":"syrk(uplo, trans, alpha, A)\n\nReturn either the upper triangle or the lower triangle of A, according to uplo, of alpha*A*transpose(A) or alpha*transpose(A)*A, according to trans.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.herk!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.herk!","text":"herk!(uplo, trans, alpha, A, beta, C)\n\nMethods for complex arrays only. Rank-k update of the Hermitian matrix C as alpha*A*A' + beta*C or alpha*A'*A + beta*C according to trans. Only the uplo triangle of C is updated. Returns C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.herk","page":"Linear Algebra","title":"LinearAlgebra.BLAS.herk","text":"herk(uplo, trans, alpha, A)\n\nMethods for complex arrays only. Returns the uplo triangle of alpha*A*A' or alpha*A'*A, according to trans.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syr2k!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syr2k!","text":"syr2k!(uplo, trans, alpha, A, B, beta, C)\n\nRank-2k update of the symmetric matrix C as alpha*A*transpose(B) + alpha*B*transpose(A) + beta*C or alpha*transpose(A)*B + alpha*transpose(B)*A + beta*C according to trans. Only the uplo triangle of C is used. Returns C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.syr2k","page":"Linear Algebra","title":"LinearAlgebra.BLAS.syr2k","text":"syr2k(uplo, trans, alpha, A, B)\n\nReturns the uplo triangle of alpha*A*transpose(B) + alpha*B*transpose(A) or alpha*transpose(A)*B + alpha*transpose(B)*A, according to trans.\n\n\n\n\n\nsyr2k(uplo, trans, A, B)\n\nReturn the uplo triangle of A*transpose(B) + B*transpose(A) or transpose(A)*B + transpose(B)*A, according to trans.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.her2k!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.her2k!","text":"her2k!(uplo, trans, alpha, A, B, beta, C)\n\nRank-2k update of the Hermitian matrix C as alpha*A*B' + alpha*B*A' + beta*C or alpha*A'*B + alpha*B'*A + beta*C according to trans. The scalar beta has to be real. Only the uplo triangle of C is used. Return C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.her2k","page":"Linear Algebra","title":"LinearAlgebra.BLAS.her2k","text":"her2k(uplo, trans, alpha, A, B)\n\nReturn the uplo triangle of alpha*A*B' + alpha*B*A' or alpha*A'*B + alpha*B'*A, according to trans.\n\n\n\n\n\nher2k(uplo, trans, A, B)\n\nReturn the uplo triangle of A*B' + B*A' or A'*B + B'*A, according to trans.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trmm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trmm!","text":"trmm!(side, ul, tA, dA, alpha, A, B)\n\nUpdate B as alpha*A*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. Return the updated B.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trmm","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trmm","text":"trmm(side, ul, tA, dA, alpha, A, B)\n\nReturn alpha*A*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trsm!","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trsm!","text":"trsm!(side, ul, tA, dA, alpha, A, B)\n\nOverwrite B with the solution to A*X = alpha*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. Returns the updated B.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.BLAS.trsm","page":"Linear Algebra","title":"LinearAlgebra.BLAS.trsm","text":"trsm(side, ul, tA, dA, alpha, A, B)\n\nReturn the solution to A*X = alpha*B or one of the other three variants determined by determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#man-linalg-lapack-functions","page":"Linear Algebra","title":"LAPACK functions","text":"","category":"section"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.LAPACK provides wrappers for some of the LAPACK functions for linear algebra. Those functions that overwrite one of the input arrays have names ending in '!'.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Usually a function has 4 methods defined, one each for Float64, Float32, ComplexF64 and ComplexF32 arrays.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"Note that the LAPACK API provided by Julia can and will change in the future. Since this API is not user-facing, there is no commitment to support/deprecate this specific set of functions in future releases.","category":"page"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"LinearAlgebra.LAPACK\nLinearAlgebra.LAPACK.gbtrf!\nLinearAlgebra.LAPACK.gbtrs!\nLinearAlgebra.LAPACK.gebal!\nLinearAlgebra.LAPACK.gebak!\nLinearAlgebra.LAPACK.gebrd!\nLinearAlgebra.LAPACK.gelqf!\nLinearAlgebra.LAPACK.geqlf!\nLinearAlgebra.LAPACK.geqrf!\nLinearAlgebra.LAPACK.geqp3!\nLinearAlgebra.LAPACK.gerqf!\nLinearAlgebra.LAPACK.geqrt!\nLinearAlgebra.LAPACK.geqrt3!\nLinearAlgebra.LAPACK.getrf!\nLinearAlgebra.LAPACK.tzrzf!\nLinearAlgebra.LAPACK.ormrz!\nLinearAlgebra.LAPACK.gels!\nLinearAlgebra.LAPACK.gesv!\nLinearAlgebra.LAPACK.getrs!\nLinearAlgebra.LAPACK.getri!\nLinearAlgebra.LAPACK.gesvx!\nLinearAlgebra.LAPACK.gelsd!\nLinearAlgebra.LAPACK.gelsy!\nLinearAlgebra.LAPACK.gglse!\nLinearAlgebra.LAPACK.geev!\nLinearAlgebra.LAPACK.gesdd!\nLinearAlgebra.LAPACK.gesvd!\nLinearAlgebra.LAPACK.ggsvd!\nLinearAlgebra.LAPACK.ggsvd3!\nLinearAlgebra.LAPACK.geevx!\nLinearAlgebra.LAPACK.ggev!\nLinearAlgebra.LAPACK.ggev3!\nLinearAlgebra.LAPACK.gtsv!\nLinearAlgebra.LAPACK.gttrf!\nLinearAlgebra.LAPACK.gttrs!\nLinearAlgebra.LAPACK.orglq!\nLinearAlgebra.LAPACK.orgqr!\nLinearAlgebra.LAPACK.orgql!\nLinearAlgebra.LAPACK.orgrq!\nLinearAlgebra.LAPACK.ormlq!\nLinearAlgebra.LAPACK.ormqr!\nLinearAlgebra.LAPACK.ormql!\nLinearAlgebra.LAPACK.ormrq!\nLinearAlgebra.LAPACK.gemqrt!\nLinearAlgebra.LAPACK.posv!\nLinearAlgebra.LAPACK.potrf!\nLinearAlgebra.LAPACK.potri!\nLinearAlgebra.LAPACK.potrs!\nLinearAlgebra.LAPACK.pstrf!\nLinearAlgebra.LAPACK.ptsv!\nLinearAlgebra.LAPACK.pttrf!\nLinearAlgebra.LAPACK.pttrs!\nLinearAlgebra.LAPACK.trtri!\nLinearAlgebra.LAPACK.trtrs!\nLinearAlgebra.LAPACK.trcon!\nLinearAlgebra.LAPACK.trevc!\nLinearAlgebra.LAPACK.trrfs!\nLinearAlgebra.LAPACK.stev!\nLinearAlgebra.LAPACK.stebz!\nLinearAlgebra.LAPACK.stegr!\nLinearAlgebra.LAPACK.stein!\nLinearAlgebra.LAPACK.syconv!\nLinearAlgebra.LAPACK.sysv!\nLinearAlgebra.LAPACK.sytrf!\nLinearAlgebra.LAPACK.sytri!\nLinearAlgebra.LAPACK.sytrs!\nLinearAlgebra.LAPACK.hesv!\nLinearAlgebra.LAPACK.hetrf!\nLinearAlgebra.LAPACK.hetri!\nLinearAlgebra.LAPACK.hetrs!\nLinearAlgebra.LAPACK.syev!\nLinearAlgebra.LAPACK.syevr!\nLinearAlgebra.LAPACK.syevd!\nLinearAlgebra.LAPACK.sygvd!\nLinearAlgebra.LAPACK.bdsqr!\nLinearAlgebra.LAPACK.bdsdc!\nLinearAlgebra.LAPACK.gecon!\nLinearAlgebra.LAPACK.gehrd!\nLinearAlgebra.LAPACK.orghr!\nLinearAlgebra.LAPACK.gees!\nLinearAlgebra.LAPACK.gges!\nLinearAlgebra.LAPACK.gges3!\nLinearAlgebra.LAPACK.trexc!\nLinearAlgebra.LAPACK.trsen!\nLinearAlgebra.LAPACK.tgsen!\nLinearAlgebra.LAPACK.trsyl!\nLinearAlgebra.LAPACK.hseqr!","category":"page"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK","page":"Linear Algebra","title":"LinearAlgebra.LAPACK","text":"Interfaces to LAPACK subroutines.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gbtrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gbtrf!","text":"gbtrf!(kl, ku, m, AB) -> (AB, ipiv)\n\nCompute the LU factorization of a banded matrix AB. kl is the first subdiagonal containing a nonzero band, ku is the last superdiagonal containing one, and m is the first dimension of the matrix AB. Returns the LU factorization in-place and ipiv, the vector of pivots used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gbtrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gbtrs!","text":"gbtrs!(trans, kl, ku, m, AB, ipiv, B)\n\nSolve the equation AB * X = B. trans determines the orientation of AB. It may be N (no transpose), T (transpose), or C (conjugate transpose). kl is the first subdiagonal containing a nonzero band, ku is the last superdiagonal containing one, and m is the first dimension of the matrix AB. ipiv is the vector of pivots returned from gbtrf!. Returns the vector or matrix X, overwriting B in-place.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gebal!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gebal!","text":"gebal!(job, A) -> (ilo, ihi, scale)\n\nBalance the matrix A before computing its eigensystem or Schur factorization. job can be one of N (A will not be permuted or scaled), P (A will only be permuted), S (A will only be scaled), or B (A will be both permuted and scaled). Modifies A in-place and returns ilo, ihi, and scale. If permuting was turned on, A[i,j] = 0 if j > i and 1 < j < ilo or j > ihi. scale contains information about the scaling/permutations performed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gebak!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gebak!","text":"gebak!(job, side, ilo, ihi, scale, V)\n\nTransform the eigenvectors V of a matrix balanced using gebal! to the unscaled/unpermuted eigenvectors of the original matrix. Modifies V in-place. side can be L (left eigenvectors are transformed) or R (right eigenvectors are transformed).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gebrd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gebrd!","text":"gebrd!(A) -> (A, d, e, tauq, taup)\n\nReduce A in-place to bidiagonal form A = QBP'. Returns A, containing the bidiagonal matrix B; d, containing the diagonal elements of B; e, containing the off-diagonal elements of B; tauq, containing the elementary reflectors representing Q; and taup, containing the elementary reflectors representing P.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gelqf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gelqf!","text":"gelqf!(A, tau)\n\nCompute the LQ factorization of A, A = LQ. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.\n\nReturns A and tau modified in-place.\n\n\n\n\n\ngelqf!(A) -> (A, tau)\n\nCompute the LQ factorization of A, A = LQ.\n\nReturns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqlf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqlf!","text":"geqlf!(A, tau)\n\nCompute the QL factorization of A, A = QL. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.\n\nReturns A and tau modified in-place.\n\n\n\n\n\ngeqlf!(A) -> (A, tau)\n\nCompute the QL factorization of A, A = QL.\n\nReturns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqrf!","text":"geqrf!(A, tau)\n\nCompute the QR factorization of A, A = QR. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.\n\nReturns A and tau modified in-place.\n\n\n\n\n\ngeqrf!(A) -> (A, tau)\n\nCompute the QR factorization of A, A = QR.\n\nReturns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqp3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqp3!","text":"geqp3!(A, [jpvt, tau]) -> (A, tau, jpvt)\n\nCompute the pivoted QR factorization of A, AP = QR using BLAS level 3. P is a pivoting matrix, represented by jpvt. tau stores the elementary reflectors. The arguments jpvt and tau are optional and allow for passing preallocated arrays. When passed, jpvt must have length greater than or equal to n if A is an (m x n) matrix and tau must have length greater than or equal to the smallest dimension of A. On entry, if jpvt[j] does not equal zero then the jth column of A is permuted to the front of AP.\n\nA, jpvt, and tau are modified in-place.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gerqf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gerqf!","text":"gerqf!(A, tau)\n\nCompute the RQ factorization of A, A = RQ. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.\n\nReturns A and tau modified in-place.\n\n\n\n\n\ngerqf!(A) -> (A, tau)\n\nCompute the RQ factorization of A, A = RQ.\n\nReturns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqrt!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqrt!","text":"geqrt!(A, T)\n\nCompute the blocked QR factorization of A, A = QR. T contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization. The first dimension of T sets the block size and it must be between 1 and n. The second dimension of T must equal the smallest dimension of A.\n\nReturns A and T modified in-place.\n\n\n\n\n\ngeqrt!(A, nb) -> (A, T)\n\nCompute the blocked QR factorization of A, A = QR. nb sets the block size and it must be between 1 and n, the second dimension of A.\n\nReturns A, modified in-place, and T, which contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geqrt3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geqrt3!","text":"geqrt3!(A, T)\n\nRecursively computes the blocked QR factorization of A, A = QR. T contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization. The first dimension of T sets the block size and it must be between 1 and n. The second dimension of T must equal the smallest dimension of A.\n\nReturns A and T modified in-place.\n\n\n\n\n\ngeqrt3!(A) -> (A, T)\n\nRecursively computes the blocked QR factorization of A, A = QR.\n\nReturns A, modified in-place, and T, which contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.getrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.getrf!","text":"getrf!(A, ipiv) -> (A, ipiv, info)\n\nCompute the pivoted LU factorization of A, A = LU. ipiv contains the pivoting information and info a code which indicates success (info = 0), a singular value in U (info = i, in which case U[i,i] is singular), or an error code (info < 0).\n\n\n\n\n\ngetrf!(A) -> (A, ipiv, info)\n\nCompute the pivoted LU factorization of A, A = LU.\n\nReturns A, modified in-place, ipiv, the pivoting information, and an info code which indicates success (info = 0), a singular value in U (info = i, in which case U[i,i] is singular), or an error code (info < 0).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.tzrzf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.tzrzf!","text":"tzrzf!(A) -> (A, tau)\n\nTransforms the upper trapezoidal matrix A to upper triangular form in-place. Returns A and tau, the scalar parameters for the elementary reflectors of the transformation.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormrz!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormrz!","text":"ormrz!(side, trans, A, tau, C)\n\nMultiplies the matrix C by Q from the transformation supplied by tzrzf!. Depending on side or trans the multiplication can be left-sided (side = L, Q*C) or right-sided (side = R, C*Q) and Q can be unmodified (trans = N), transposed (trans = T), or conjugate transposed (trans = C). Returns matrix C which is modified in-place with the result of the multiplication.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gels!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gels!","text":"gels!(trans, A, B) -> (F, B, ssr)\n\nSolves the linear equation A * X = B, transpose(A) * X = B, or adjoint(A) * X = B using a QR or LQ factorization. Modifies the matrix/vector B in place with the solution. A is overwritten with its QR or LQ factorization. trans may be one of N (no modification), T (transpose), or C (conjugate transpose). gels! searches for the minimum norm/least squares solution. A may be under or over determined. The solution is returned in B.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gesv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gesv!","text":"gesv!(A, B) -> (B, A, ipiv)\n\nSolves the linear equation A * X = B where A is a square matrix using the LU factorization of A. A is overwritten with its LU factorization and B is overwritten with the solution X. ipiv contains the pivoting information for the LU factorization of A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.getrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.getrs!","text":"getrs!(trans, A, ipiv, B)\n\nSolves the linear equation A * X = B, transpose(A) * X = B, or adjoint(A) * X = B for square A. Modifies the matrix/vector B in place with the solution. A is the LU factorization from getrf!, with ipiv the pivoting information. trans may be one of N (no modification), T (transpose), or C (conjugate transpose).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.getri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.getri!","text":"getri!(A, ipiv)\n\nComputes the inverse of A, using its LU factorization found by getrf!. ipiv is the pivot information output and A contains the LU factorization of getrf!. A is overwritten with its inverse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gesvx!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gesvx!","text":"gesvx!(fact, trans, A, AF, ipiv, equed, R, C, B) -> (X, equed, R, C, B, rcond, ferr, berr, work)\n\nSolves the linear equation A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) using the LU factorization of A. fact may be E, in which case A will be equilibrated and copied to AF; F, in which case AF and ipiv from a previous LU factorization are inputs; or N, in which case A will be copied to AF and then factored. If fact = F, equed may be N, meaning A has not been equilibrated; R, meaning A was multiplied by Diagonal(R) from the left; C, meaning A was multiplied by Diagonal(C) from the right; or B, meaning A was multiplied by Diagonal(R) from the left and Diagonal(C) from the right. If fact = F and equed = R or B the elements of R must all be positive. If fact = F and equed = C or B the elements of C must all be positive.\n\nReturns the solution X; equed, which is an output if fact is not N, and describes the equilibration that was performed; R, the row equilibration diagonal; C, the column equilibration diagonal; B, which may be overwritten with its equilibrated form Diagonal(R)*B (if trans = N and equed = R,B) or Diagonal(C)*B (if trans = T,C and equed = C,B); rcond, the reciprocal condition number of A after equilbrating; ferr, the forward error bound for each solution vector in X; berr, the forward error bound for each solution vector in X; and work, the reciprocal pivot growth factor.\n\n\n\n\n\ngesvx!(A, B)\n\nThe no-equilibration, no-transpose simplification of gesvx!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gelsd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gelsd!","text":"gelsd!(A, B, rcond) -> (B, rnk)\n\nComputes the least norm solution of A * X = B by finding the SVD factorization of A, then dividing-and-conquering the problem. B is overwritten with the solution X. Singular values below rcond will be treated as zero. Returns the solution in B and the effective rank of A in rnk.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gelsy!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gelsy!","text":"gelsy!(A, B, rcond) -> (B, rnk)\n\nComputes the least norm solution of A * X = B by finding the full QR factorization of A, then dividing-and-conquering the problem. B is overwritten with the solution X. Singular values below rcond will be treated as zero. Returns the solution in B and the effective rank of A in rnk.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gglse!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gglse!","text":"gglse!(A, c, B, d) -> (X,res)\n\nSolves the equation A * x = c where x is subject to the equality constraint B * x = d. Uses the formula ||c - A*x||^2 = 0 to solve. Returns X and the residual sum-of-squares.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geev!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geev!","text":"geev!(jobvl, jobvr, A) -> (W, VL, VR)\n\nFinds the eigensystem of A. If jobvl = N, the left eigenvectors of A aren't computed. If jobvr = N, the right eigenvectors of A aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. Returns the eigenvalues in W, the right eigenvectors in VR, and the left eigenvectors in VL.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gesdd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gesdd!","text":"gesdd!(job, A) -> (U, S, VT)\n\nFinds the singular value decomposition of A, A = U * S * V', using a divide and conquer approach. If job = A, all the columns of U and the rows of V' are computed. If job = N, no columns of U or rows of V' are computed. If job = O, A is overwritten with the columns of (thin) U and the rows of (thin) V'. If job = S, the columns of (thin) U and the rows of (thin) V' are computed and returned separately.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gesvd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gesvd!","text":"gesvd!(jobu, jobvt, A) -> (U, S, VT)\n\nFinds the singular value decomposition of A, A = U * S * V'. If jobu = A, all the columns of U are computed. If jobvt = A all the rows of V' are computed. If jobu = N, no columns of U are computed. If jobvt = N no rows of V' are computed. If jobu = O, A is overwritten with the columns of (thin) U. If jobvt = O, A is overwritten with the rows of (thin) V'. If jobu = S, the columns of (thin) U are computed and returned separately. If jobvt = S the rows of (thin) V' are computed and returned separately. jobu and jobvt can't both be O.\n\nReturns U, S, and Vt, where S are the singular values of A.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ggsvd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ggsvd!","text":"ggsvd!(jobu, jobv, jobq, A, B) -> (U, V, Q, alpha, beta, k, l, R)\n\nFinds the generalized singular value decomposition of A and B, U'*A*Q = D1*R and V'*B*Q = D2*R. D1 has alpha on its diagonal and D2 has beta on its diagonal. If jobu = U, the orthogonal/unitary matrix U is computed. If jobv = V the orthogonal/unitary matrix V is computed. If jobq = Q, the orthogonal/unitary matrix Q is computed. If jobu, jobv or jobq is N, that matrix is not computed. This function is only available in LAPACK versions prior to 3.6.0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ggsvd3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ggsvd3!","text":"ggsvd3!(jobu, jobv, jobq, A, B) -> (U, V, Q, alpha, beta, k, l, R)\n\nFinds the generalized singular value decomposition of A and B, U'*A*Q = D1*R and V'*B*Q = D2*R. D1 has alpha on its diagonal and D2 has beta on its diagonal. If jobu = U, the orthogonal/unitary matrix U is computed. If jobv = V the orthogonal/unitary matrix V is computed. If jobq = Q, the orthogonal/unitary matrix Q is computed. If jobu, jobv, or jobq is N, that matrix is not computed. This function requires LAPACK 3.6.0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.geevx!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.geevx!","text":"geevx!(balanc, jobvl, jobvr, sense, A) -> (A, w, VL, VR, ilo, ihi, scale, abnrm, rconde, rcondv)\n\nFinds the eigensystem of A with matrix balancing. If jobvl = N, the left eigenvectors of A aren't computed. If jobvr = N, the right eigenvectors of A aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. If balanc = N, no balancing is performed. If balanc = P, A is permuted but not scaled. If balanc = S, A is scaled but not permuted. If balanc = B, A is permuted and scaled. If sense = N, no reciprocal condition numbers are computed. If sense = E, reciprocal condition numbers are computed for the eigenvalues only. If sense = V, reciprocal condition numbers are computed for the right eigenvectors only. If sense = B, reciprocal condition numbers are computed for the right eigenvectors and the eigenvectors. If sense = E,B, the right and left eigenvectors must be computed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ggev!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ggev!","text":"ggev!(jobvl, jobvr, A, B) -> (alpha, beta, vl, vr)\n\nFinds the generalized eigendecomposition of A and B. If jobvl = N, the left eigenvectors aren't computed. If jobvr = N, the right eigenvectors aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ggev3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ggev3!","text":"ggev3!(jobvl, jobvr, A, B) -> (alpha, beta, vl, vr)\n\nFinds the generalized eigendecomposition of A and B using a blocked algorithm. If jobvl = N, the left eigenvectors aren't computed. If jobvr = N, the right eigenvectors aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. This function requires LAPACK 3.6.0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gtsv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gtsv!","text":"gtsv!(dl, d, du, B)\n\nSolves the equation A * X = B where A is a tridiagonal matrix with dl on the subdiagonal, d on the diagonal, and du on the superdiagonal.\n\nOverwrites B with the solution X and returns it.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gttrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gttrf!","text":"gttrf!(dl, d, du) -> (dl, d, du, du2, ipiv)\n\nFinds the LU factorization of a tridiagonal matrix with dl on the subdiagonal, d on the diagonal, and du on the superdiagonal.\n\nModifies dl, d, and du in-place and returns them and the second superdiagonal du2 and the pivoting vector ipiv.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gttrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gttrs!","text":"gttrs!(trans, dl, d, du, du2, ipiv, B)\n\nSolves the equation A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) using the LU factorization computed by gttrf!. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orglq!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orglq!","text":"orglq!(A, tau, k = length(tau))\n\nExplicitly finds the matrix Q of a LQ factorization after calling gelqf! on A. Uses the output of gelqf!. A is overwritten by Q.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orgqr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orgqr!","text":"orgqr!(A, tau, k = length(tau))\n\nExplicitly finds the matrix Q of a QR factorization after calling geqrf! on A. Uses the output of geqrf!. A is overwritten by Q.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orgql!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orgql!","text":"orgql!(A, tau, k = length(tau))\n\nExplicitly finds the matrix Q of a QL factorization after calling geqlf! on A. Uses the output of geqlf!. A is overwritten by Q.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orgrq!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orgrq!","text":"orgrq!(A, tau, k = length(tau))\n\nExplicitly finds the matrix Q of a RQ factorization after calling gerqf! on A. Uses the output of gerqf!. A is overwritten by Q.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormlq!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormlq!","text":"ormlq!(side, trans, A, tau, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a LQ factorization of A computed using gelqf!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormqr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormqr!","text":"ormqr!(side, trans, A, tau, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QR factorization of A computed using geqrf!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormql!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormql!","text":"ormql!(side, trans, A, tau, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QL factorization of A computed using geqlf!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ormrq!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ormrq!","text":"ormrq!(side, trans, A, tau, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a RQ factorization of A computed using gerqf!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gemqrt!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gemqrt!","text":"gemqrt!(side, trans, V, T, C)\n\nComputes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QR factorization of A computed using geqrt!. C is overwritten.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.posv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.posv!","text":"posv!(uplo, A, B) -> (A, B)\n\nFinds the solution to A * X = B where A is a symmetric or Hermitian positive definite matrix. If uplo = U the upper Cholesky decomposition of A is computed. If uplo = L the lower Cholesky decomposition of A is computed. A is overwritten by its Cholesky decomposition. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.potrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.potrf!","text":"potrf!(uplo, A)\n\nComputes the Cholesky (upper if uplo = U, lower if uplo = L) decomposition of positive-definite matrix A. A is overwritten and returned with an info code.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.potri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.potri!","text":"potri!(uplo, A)\n\nComputes the inverse of positive-definite matrix A after calling potrf! to find its (upper if uplo = U, lower if uplo = L) Cholesky decomposition.\n\nA is overwritten by its inverse and returned.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.potrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.potrs!","text":"potrs!(uplo, A, B)\n\nFinds the solution to A * X = B where A is a symmetric or Hermitian positive definite matrix whose Cholesky decomposition was computed by potrf!. If uplo = U the upper Cholesky decomposition of A was computed. If uplo = L the lower Cholesky decomposition of A was computed. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.pstrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.pstrf!","text":"pstrf!(uplo, A, tol) -> (A, piv, rank, info)\n\nComputes the (upper if uplo = U, lower if uplo = L) pivoted Cholesky decomposition of positive-definite matrix A with a user-set tolerance tol. A is overwritten by its Cholesky decomposition.\n\nReturns A, the pivots piv, the rank of A, and an info code. If info = 0, the factorization succeeded. If info = i > 0, then A is indefinite or rank-deficient.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.ptsv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.ptsv!","text":"ptsv!(D, E, B)\n\nSolves A * X = B for positive-definite tridiagonal A. D is the diagonal of A and E is the off-diagonal. B is overwritten with the solution X and returned.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.pttrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.pttrf!","text":"pttrf!(D, E)\n\nComputes the LDLt factorization of a positive-definite tridiagonal matrix with D as diagonal and E as off-diagonal. D and E are overwritten and returned.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.pttrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.pttrs!","text":"pttrs!(D, E, B)\n\nSolves A * X = B for positive-definite tridiagonal A with diagonal D and off-diagonal E after computing A's LDLt factorization using pttrf!. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trtri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trtri!","text":"trtri!(uplo, diag, A)\n\nFinds the inverse of (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. A is overwritten with its inverse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trtrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trtrs!","text":"trtrs!(uplo, trans, diag, A, B)\n\nSolves A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) for (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. B is overwritten with the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trcon!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trcon!","text":"trcon!(norm, uplo, diag, A)\n\nFinds the reciprocal condition number of (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. If norm = I, the condition number is found in the infinity norm. If norm = O or 1, the condition number is found in the one norm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trevc!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trevc!","text":"trevc!(side, howmny, select, T, VL = similar(T), VR = similar(T))\n\nFinds the eigensystem of an upper triangular matrix T. If side = R, the right eigenvectors are computed. If side = L, the left eigenvectors are computed. If side = B, both sets are computed. If howmny = A, all eigenvectors are found. If howmny = B, all eigenvectors are found and backtransformed using VL and VR. If howmny = S, only the eigenvectors corresponding to the values in select are computed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trrfs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trrfs!","text":"trrfs!(uplo, trans, diag, A, B, X, Ferr, Berr) -> (Ferr, Berr)\n\nEstimates the error in the solution to A * X = B (trans = N), transpose(A) * X = B (trans = T), adjoint(A) * X = B (trans = C) for side = L, or the equivalent equations a right-handed side = R X * A after computing X using trtrs!. If uplo = U, A is upper triangular. If uplo = L, A is lower triangular. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. Ferr and Berr are optional inputs. Ferr is the forward error and Berr is the backward error, each component-wise.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.stev!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.stev!","text":"stev!(job, dv, ev) -> (dv, Zmat)\n\nComputes the eigensystem for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If job = N only the eigenvalues are found and returned in dv. If job = V then the eigenvectors are also found and returned in Zmat.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.stebz!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.stebz!","text":"stebz!(range, order, vl, vu, il, iu, abstol, dv, ev) -> (dv, iblock, isplit)\n\nComputes the eigenvalues for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. If order = B, eigvalues are ordered within a block. If order = E, they are ordered across all the blocks. abstol can be set as a tolerance for convergence.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.stegr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.stegr!","text":"stegr!(jobz, range, dv, ev, vl, vu, il, iu) -> (w, Z)\n\nComputes the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. The eigenvalues are returned in w and the eigenvectors in Z.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.stein!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.stein!","text":"stein!(dv, ev_in, w_in, iblock_in, isplit_in)\n\nComputes the eigenvectors for a symmetric tridiagonal matrix with dv as diagonal and ev_in as off-diagonal. w_in specifies the input eigenvalues for which to find corresponding eigenvectors. iblock_in specifies the submatrices corresponding to the eigenvalues in w_in. isplit_in specifies the splitting points between the submatrix blocks.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.syconv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.syconv!","text":"syconv!(uplo, A, ipiv) -> (A, work)\n\nConverts a symmetric matrix A (which has been factorized into a triangular matrix) into two matrices L and D. If uplo = U, A is upper triangular. If uplo = L, it is lower triangular. ipiv is the pivot vector from the triangular factorization. A is overwritten by L and D.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sysv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sysv!","text":"sysv!(uplo, A, B) -> (B, A, ipiv)\n\nFinds the solution to A * X = B for symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X. A is overwritten by its Bunch-Kaufman factorization. ipiv contains pivoting information about the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sytrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sytrf!","text":"sytrf!(uplo, A) -> (A, ipiv, info)\n\nComputes the Bunch-Kaufman factorization of a symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.\n\nReturns A, overwritten by the factorization, a pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.\n\n\n\n\n\nsytrf!(uplo, A, ipiv) -> (A, ipiv, info)\n\nComputes the Bunch-Kaufman factorization of a symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.\n\nReturns A, overwritten by the factorization, the pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sytri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sytri!","text":"sytri!(uplo, A, ipiv)\n\nComputes the inverse of a symmetric matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. A is overwritten by its inverse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sytrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sytrs!","text":"sytrs!(uplo, A, ipiv, B)\n\nSolves the equation A * X = B for a symmetric matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hesv!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hesv!","text":"hesv!(uplo, A, B) -> (B, A, ipiv)\n\nFinds the solution to A * X = B for Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X. A is overwritten by its Bunch-Kaufman factorization. ipiv contains pivoting information about the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hetrf!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hetrf!","text":"hetrf!(uplo, A) -> (A, ipiv, info)\n\nComputes the Bunch-Kaufman factorization of a Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.\n\nReturns A, overwritten by the factorization, a pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.\n\n\n\n\n\nhetrf!(uplo, A, ipiv) -> (A, ipiv, info)\n\nComputes the Bunch-Kaufman factorization of a Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.\n\nReturns A, overwritten by the factorization, the pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hetri!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hetri!","text":"hetri!(uplo, A, ipiv)\n\nComputes the inverse of a Hermitian matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. A is overwritten by its inverse.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hetrs!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hetrs!","text":"hetrs!(uplo, A, ipiv, B)\n\nSolves the equation A * X = B for a Hermitian matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.syev!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.syev!","text":"syev!(jobz, uplo, A)\n\nFinds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.syevr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.syevr!","text":"syevr!(jobz, range, uplo, A, vl, vu, il, iu, abstol) -> (W, Z)\n\nFinds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. abstol can be set as a tolerance for convergence.\n\nThe eigenvalues are returned in W and the eigenvectors in Z.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.syevd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.syevd!","text":"syevd!(jobz, uplo, A)\n\nFinds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used.\n\nUse the divide-and-conquer method, instead of the QR iteration used by syev! or multiple relatively robust representations used by syevr!. See James W. Demmel et al, SIAM J. Sci. Comput. 30, 3, 1508 (2008) for a comparison of the accuracy and performatce of different methods.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.sygvd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.sygvd!","text":"sygvd!(itype, jobz, uplo, A, B) -> (w, A, B)\n\nFinds the generalized eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A and symmetric positive-definite matrix B. If uplo = U, the upper triangles of A and B are used. If uplo = L, the lower triangles of A and B are used. If itype = 1, the problem to solve is A * x = lambda * B * x. If itype = 2, the problem to solve is A * B * x = lambda * x. If itype = 3, the problem to solve is B * A * x = lambda * x.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.bdsqr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.bdsqr!","text":"bdsqr!(uplo, d, e_, Vt, U, C) -> (d, Vt, U, C)\n\nComputes the singular value decomposition of a bidiagonal matrix with d on the diagonal and e_ on the off-diagonal. If uplo = U, e_ is the superdiagonal. If uplo = L, e_ is the subdiagonal. Can optionally also compute the product Q' * C.\n\nReturns the singular values in d, and the matrix C overwritten with Q' * C.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.bdsdc!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.bdsdc!","text":"bdsdc!(uplo, compq, d, e_) -> (d, e, u, vt, q, iq)\n\nComputes the singular value decomposition of a bidiagonal matrix with d on the diagonal and e_ on the off-diagonal using a divide and conqueq method. If uplo = U, e_ is the superdiagonal. If uplo = L, e_ is the subdiagonal. If compq = N, only the singular values are found. If compq = I, the singular values and vectors are found. If compq = P, the singular values and vectors are found in compact form. Only works for real types.\n\nReturns the singular values in d, and if compq = P, the compact singular vectors in iq.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gecon!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gecon!","text":"gecon!(normtype, A, anorm)\n\nFinds the reciprocal condition number of matrix A. If normtype = I, the condition number is found in the infinity norm. If normtype = O or 1, the condition number is found in the one norm. A must be the result of getrf! and anorm is the norm of A in the relevant norm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gehrd!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gehrd!","text":"gehrd!(ilo, ihi, A) -> (A, tau)\n\nConverts a matrix A to Hessenberg form. If A is balanced with gebal! then ilo and ihi are the outputs of gebal!. Otherwise they should be ilo = 1 and ihi = size(A,2). tau contains the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.orghr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.orghr!","text":"orghr!(ilo, ihi, A, tau)\n\nExplicitly finds Q, the orthogonal/unitary matrix from gehrd!. ilo, ihi, A, and tau must correspond to the input/output to gehrd!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gees!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gees!","text":"gees!(jobvs, A) -> (A, vs, w)\n\nComputes the eigenvalues (jobvs = N) or the eigenvalues and Schur vectors (jobvs = V) of matrix A. A is overwritten by its Schur form.\n\nReturns A, vs containing the Schur vectors, and w, containing the eigenvalues.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gges!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gges!","text":"gges!(jobvsl, jobvsr, A, B) -> (A, B, alpha, beta, vsl, vsr)\n\nComputes the generalized eigenvalues, generalized Schur form, left Schur vectors (jobsvl = V), or right Schur vectors (jobvsr = V) of A and B.\n\nThe generalized eigenvalues are returned in alpha and beta. The left Schur vectors are returned in vsl and the right Schur vectors are returned in vsr.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.gges3!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.gges3!","text":"gges3!(jobvsl, jobvsr, A, B) -> (A, B, alpha, beta, vsl, vsr)\n\nComputes the generalized eigenvalues, generalized Schur form, left Schur vectors (jobsvl = V), or right Schur vectors (jobvsr = V) of A and B using a blocked algorithm. This function requires LAPACK 3.6.0.\n\nThe generalized eigenvalues are returned in alpha and beta. The left Schur vectors are returned in vsl and the right Schur vectors are returned in vsr.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trexc!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trexc!","text":"trexc!(compq, ifst, ilst, T, Q) -> (T, Q)\ntrexc!(ifst, ilst, T, Q) -> (T, Q)\n\nReorder the Schur factorization T of a matrix, such that the diagonal block of T with row index ifst is moved to row index ilst. If compq = V, the Schur vectors Q are reordered. If compq = N they are not modified. The 4-arg method calls the 5-arg method with compq = V.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trsen!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trsen!","text":"trsen!(job, compq, select, T, Q) -> (T, Q, w, s, sep)\ntrsen!(select, T, Q) -> (T, Q, w, s, sep)\n\nReorder the Schur factorization of a matrix and optionally finds reciprocal condition numbers. If job = N, no condition numbers are found. If job = E, only the condition number for this cluster of eigenvalues is found. If job = V, only the condition number for the invariant subspace is found. If job = B then the condition numbers for the cluster and subspace are found. If compq = V the Schur vectors Q are updated. If compq = N the Schur vectors are not modified. select determines which eigenvalues are in the cluster. The 3-arg method calls the 5-arg method with job = N and compq = V.\n\nReturns T, Q, reordered eigenvalues in w, the condition number of the cluster of eigenvalues s, and the condition number of the invariant subspace sep.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.tgsen!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.tgsen!","text":"tgsen!(select, S, T, Q, Z) -> (S, T, alpha, beta, Q, Z)\n\nReorders the vectors of a generalized Schur decomposition. select specifies the eigenvalues in each cluster.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.trsyl!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.trsyl!","text":"trsyl!(transa, transb, A, B, C, isgn=1) -> (C, scale)\n\nSolves the Sylvester matrix equation A * X +/- X * B = scale*C where A and B are both quasi-upper triangular. If transa = N, A is not modified. If transa = T, A is transposed. If transa = C, A is conjugate transposed. Similarly for transb and B. If isgn = 1, the equation A * X + X * B = scale * C is solved. If isgn = -1, the equation A * X - X * B = scale * C is solved.\n\nReturns X (overwriting C) and scale.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/#LinearAlgebra.LAPACK.hseqr!","page":"Linear Algebra","title":"LinearAlgebra.LAPACK.hseqr!","text":"hseqr!(job, compz, ilo, ihi, H, Z) -> (H, Z, w)\n\nComputes all eigenvalues and (optionally) the Schur factorization of a matrix reduced to Hessenberg form. If H is balanced with gebal! then ilo and ihi are the outputs of gebal!. Otherwise they should be ilo = 1 and ihi = size(H,2). tau contains the elementary reflectors of the factorization.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/LinearAlgebra/","page":"Linear Algebra","title":"Linear Algebra","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/Sockets/","page":"Sockets","title":"Sockets","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Sockets/docs/src/index.md\"","category":"page"},{"location":"stdlib/Sockets/#Sockets","page":"Sockets","title":"Sockets","text":"","category":"section"},{"location":"stdlib/Sockets/","page":"Sockets","title":"Sockets","text":"Sockets.Sockets\nSockets.connect(::TCPSocket, ::Integer)\nSockets.connect(::AbstractString)\nSockets.listen(::Any)\nSockets.listen(::AbstractString)\nSockets.getaddrinfo\nSockets.getipaddr\nSockets.getipaddrs\nSockets.islinklocaladdr\nSockets.getalladdrinfo\nSockets.DNSError\nSockets.getnameinfo\nSockets.getsockname\nSockets.getpeername\nSockets.IPAddr\nSockets.IPv4\nSockets.IPv6\nSockets.@ip_str\nSockets.TCPSocket\nSockets.UDPSocket\nSockets.accept\nSockets.listenany\nSockets.bind\nSockets.send\nSockets.recv\nSockets.recvfrom\nSockets.setopt\nSockets.nagle\nSockets.quickack","category":"page"},{"location":"stdlib/Sockets/#Sockets.Sockets","page":"Sockets","title":"Sockets.Sockets","text":"Support for sockets. Provides IPAddr and subtypes, TCPSocket, and UDPSocket.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Sockets/#Sockets.connect-Tuple{TCPSocket, Integer}","page":"Sockets","title":"Sockets.connect","text":"connect([host], port::Integer) -> TCPSocket\n\nConnect to the host host on port port.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Sockets/#Sockets.connect-Tuple{AbstractString}","page":"Sockets","title":"Sockets.connect","text":"connect(path::AbstractString) -> PipeEndpoint\n\nConnect to the named pipe / UNIX domain socket at path.\n\nnote: Note\nPath length on Unix is limited to somewhere between 92 and 108 bytes (cf. man unix).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Sockets/#Sockets.listen-Tuple{Any}","page":"Sockets","title":"Sockets.listen","text":"listen([addr, ]port::Integer; backlog::Integer=BACKLOG_DEFAULT) -> TCPServer\n\nListen on port on the address specified by addr. By default this listens on localhost only. To listen on all interfaces pass IPv4(0) or IPv6(0) as appropriate. backlog determines how many connections can be pending (not having called accept) before the server will begin to reject them. The default value of backlog is 511.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Sockets/#Sockets.listen-Tuple{AbstractString}","page":"Sockets","title":"Sockets.listen","text":"listen(path::AbstractString) -> PipeServer\n\nCreate and listen on a named pipe / UNIX domain socket.\n\nnote: Note\nPath length on Unix is limited to somewhere between 92 and 108 bytes (cf. man unix).\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Sockets/#Sockets.getaddrinfo","page":"Sockets","title":"Sockets.getaddrinfo","text":"getaddrinfo(host::AbstractString, IPAddr) -> IPAddr\n\nGets the first IP address of the host of the specified IPAddr type. Uses the operating system's underlying getaddrinfo implementation, which may do a DNS lookup.\n\nExamples\n\njulia> getaddrinfo(\"localhost\", IPv6)\nip\"::1\"\n\njulia> getaddrinfo(\"localhost\", IPv4)\nip\"127.0.0.1\"\n\n\n\n\n\ngetaddrinfo(host::AbstractString) -> IPAddr\n\nGets the first available IP address of host, which may be either an IPv4 or IPv6 address. Uses the operating system's underlying getaddrinfo implementation, which may do a DNS lookup.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getipaddr","page":"Sockets","title":"Sockets.getipaddr","text":"getipaddr() -> IPAddr\n\nGet an IP address of the local machine, preferring IPv4 over IPv6. Throws if no addresses are available.\n\ngetipaddr(addr_type::Type{T}) where T<:IPAddr -> T\n\nGet an IP address of the local machine of the specified type. Throws if no addresses of the specified type are available.\n\nThis function is a backwards-compatibility wrapper around getipaddrs. New applications should use getipaddrs instead.\n\nExamples\n\njulia> getipaddr()\nip\"192.168.1.28\"\n\njulia> getipaddr(IPv6)\nip\"fe80::9731:35af:e1c5:6e49\"\n\nSee also getipaddrs.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getipaddrs","page":"Sockets","title":"Sockets.getipaddrs","text":"getipaddrs(addr_type::Type{T}=IPAddr; loopback::Bool=false) where T<:IPAddr -> Vector{T}\n\nGet the IP addresses of the local machine.\n\nSetting the optional addr_type parameter to IPv4 or IPv6 causes only addresses of that type to be returned.\n\nThe loopback keyword argument dictates whether loopback addresses (e.g. ip\"127.0.0.1\", ip\"::1\") are included.\n\ncompat: Julia 1.2\nThis function is available as of Julia 1.2.\n\nExamples\n\njulia> getipaddrs()\n5-element Array{IPAddr,1}:\n ip\"198.51.100.17\"\n ip\"203.0.113.2\"\n ip\"2001:db8:8:4:445e:5fff:fe5d:5500\"\n ip\"2001:db8:8:4:c164:402e:7e3c:3668\"\n ip\"fe80::445e:5fff:fe5d:5500\"\n\njulia> getipaddrs(IPv6)\n3-element Array{IPv6,1}:\n ip\"2001:db8:8:4:445e:5fff:fe5d:5500\"\n ip\"2001:db8:8:4:c164:402e:7e3c:3668\"\n ip\"fe80::445e:5fff:fe5d:5500\"\n\nSee also islinklocaladdr.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.islinklocaladdr","page":"Sockets","title":"Sockets.islinklocaladdr","text":"islinklocaladdr(addr::IPAddr)\n\nTests if an IP address is a link-local address. Link-local addresses are not guaranteed to be unique beyond their network segment, therefore routers do not forward them. Link-local addresses are from the address blocks 169.254.0.0/16 or fe80::/10.\n\nExamples\n\nfilter(!islinklocaladdr, getipaddrs())\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getalladdrinfo","page":"Sockets","title":"Sockets.getalladdrinfo","text":"getalladdrinfo(host::AbstractString) -> Vector{IPAddr}\n\nGets all of the IP addresses of the host. Uses the operating system's underlying getaddrinfo implementation, which may do a DNS lookup.\n\nExamples\n\njulia> getalladdrinfo(\"google.com\")\n2-element Array{IPAddr,1}:\n ip\"172.217.6.174\"\n ip\"2607:f8b0:4000:804::200e\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.DNSError","page":"Sockets","title":"Sockets.DNSError","text":"DNSError\n\nThe type of exception thrown when an error occurs in DNS lookup. The host field indicates the host URL string. The code field indicates the error code based on libuv.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.getnameinfo","page":"Sockets","title":"Sockets.getnameinfo","text":"getnameinfo(host::IPAddr) -> String\n\nPerforms a reverse-lookup for IP address to return a hostname and service using the operating system's underlying getnameinfo implementation.\n\nExamples\n\njulia> getnameinfo(IPv4(\"8.8.8.8\"))\n\"google-public-dns-a.google.com\"\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getsockname","page":"Sockets","title":"Sockets.getsockname","text":"getsockname(sock::Union{TCPServer, TCPSocket}) -> (IPAddr, UInt16)\n\nGet the IP address and port that the given socket is bound to.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.getpeername","page":"Sockets","title":"Sockets.getpeername","text":"getpeername(sock::TCPSocket) -> (IPAddr, UInt16)\n\nGet the IP address and port of the remote endpoint that the given socket is connected to. Valid only for connected TCP sockets.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.IPAddr","page":"Sockets","title":"Sockets.IPAddr","text":"IPAddr\n\nAbstract supertype for IP addresses. IPv4 and IPv6 are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.IPv4","page":"Sockets","title":"Sockets.IPv4","text":"IPv4(host::Integer) -> IPv4\n\nReturn an IPv4 object from IP address host formatted as an Integer.\n\nExamples\n\njulia> IPv4(3223256218)\nip\"192.30.252.154\"\n\n\n\n\n\nIPv4(str::AbstractString) -> IPv4\n\nParse an IPv4 address string into an IPv4 object.\n\nExamples\n\njulia> IPv4(\"127.0.0.1\")\nip\"127.0.0.1\"\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.IPv6","page":"Sockets","title":"Sockets.IPv6","text":"IPv6(host::Integer) -> IPv6\n\nReturn an IPv6 object from IP address host formatted as an Integer.\n\nExamples\n\njulia> IPv6(3223256218)\nip\"::c01e:fc9a\"\n\n\n\n\n\nIPv6(str::AbstractString) -> IPv6\n\nParse an IPv6 address string into an IPv6 object.\n\nExamples\n\njulia> IPv6(\"::1\")\nip\"::1\"\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.@ip_str","page":"Sockets","title":"Sockets.@ip_str","text":"@ip_str str -> IPAddr\n\nParse str as an IP address.\n\nExamples\n\njulia> ip\"127.0.0.1\"\nip\"127.0.0.1\"\n\njulia> @ip_str \"2001:db8:0:0:0:0:2:1\"\nip\"2001:db8::2:1\"\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Sockets/#Sockets.TCPSocket","page":"Sockets","title":"Sockets.TCPSocket","text":"TCPSocket(; delay=true)\n\nOpen a TCP socket using libuv. If delay is true, libuv delays creation of the socket's file descriptor till the first bind call. TCPSocket has various fields to denote the state of the socket as well as its send/receive buffers.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.UDPSocket","page":"Sockets","title":"Sockets.UDPSocket","text":"UDPSocket()\n\nOpen a UDP socket using libuv. UDPSocket has various fields to denote the state of the socket.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Sockets/#Sockets.accept","page":"Sockets","title":"Sockets.accept","text":"accept(server[, client])\n\nAccepts a connection on the given server and returns a connection to the client. An uninitialized client stream may be provided, in which case it will be used instead of creating a new stream.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.listenany","page":"Sockets","title":"Sockets.listenany","text":"listenany([host::IPAddr,] port_hint; backlog::Integer=BACKLOG_DEFAULT) -> (UInt16, TCPServer)\n\nCreate a TCPServer on any port, using hint as a starting point. Returns a tuple of the actual port that the server was created on and the server itself. The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Base.bind","page":"Sockets","title":"Base.bind","text":"bind(socket::Union{TCPServer, UDPSocket, TCPSocket}, host::IPAddr, port::Integer; ipv6only=false, reuseaddr=false, kws...)\n\nBind socket to the given host:port. Note that 0.0.0.0 will listen on all devices.\n\nThe ipv6only parameter disables dual stack mode. If ipv6only=true, only an IPv6 stack is created.\nIf reuseaddr=true, multiple threads or processes can bind to the same address without error if they all set reuseaddr=true, but only the last to bind will receive any traffic.\n\n\n\n\n\nbind(chnl::Channel, task::Task)\n\nAssociate the lifetime of chnl with a task. Channel chnl is automatically closed when the task terminates. Any uncaught exception in the task is propagated to all waiters on chnl.\n\nThe chnl object can be explicitly closed independent of task termination. Terminating tasks have no effect on already closed Channel objects.\n\nWhen a channel is bound to multiple tasks, the first task to terminate will close the channel. When multiple channels are bound to the same task, termination of the task will close all of the bound channels.\n\nExamples\n\njulia> c = Channel(0);\n\njulia> task = @async foreach(i->put!(c, i), 1:4);\n\njulia> bind(c,task);\n\njulia> for i in c\n @show i\n end;\ni = 1\ni = 2\ni = 3\ni = 4\n\njulia> isopen(c)\nfalse\n\njulia> c = Channel(0);\n\njulia> task = @async (put!(c, 1); error(\"foo\"));\n\njulia> bind(c, task);\n\njulia> take!(c)\n1\n\njulia> put!(c, 1);\nERROR: TaskFailedException\nStacktrace:\n[...]\n nested task error: foo\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.send","page":"Sockets","title":"Sockets.send","text":"send(socket::UDPSocket, host::IPAddr, port::Integer, msg)\n\nSend msg over socket to host:port.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.recv","page":"Sockets","title":"Sockets.recv","text":"recv(socket::UDPSocket)\n\nRead a UDP packet from the specified socket, and return the bytes received. This call blocks.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.recvfrom","page":"Sockets","title":"Sockets.recvfrom","text":"recvfrom(socket::UDPSocket) -> (host_port, data)\n\nRead a UDP packet from the specified socket, returning a tuple of (host_port, data), where host_port will be an InetAddr{IPv4} or InetAddr{IPv6}, as appropriate.\n\ncompat: Julia 1.3\nPrior to Julia version 1.3, the first returned value was an address (IPAddr). In version 1.3 it was changed to an InetAddr.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.setopt","page":"Sockets","title":"Sockets.setopt","text":"setopt(sock::UDPSocket; multicast_loop=nothing, multicast_ttl=nothing, enable_broadcast=nothing, ttl=nothing)\n\nSet UDP socket options.\n\nmulticast_loop: loopback for multicast packets (default: true).\nmulticast_ttl: TTL for multicast packets (default: nothing).\nenable_broadcast: flag must be set to true if socket will be used for broadcast messages, or else the UDP system will return an access error (default: false).\nttl: Time-to-live of packets sent on the socket (default: nothing).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.nagle","page":"Sockets","title":"Sockets.nagle","text":"nagle(socket::Union{TCPServer, TCPSocket}, enable::Bool)\n\nNagle's algorithm batches multiple small TCP packets into larger ones. This can improve throughput but worsen latency. Nagle's algorithm is enabled by default. This function sets whether Nagle's algorithm is active on a given TCP server or socket. The opposite option is called TCP_NODELAY in other languages.\n\ncompat: Julia 1.3\nThis function requires Julia 1.3 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Sockets/#Sockets.quickack","page":"Sockets","title":"Sockets.quickack","text":"quickack(socket::Union{TCPServer, TCPSocket}, enable::Bool)\n\nOn Linux systems, the TCP_QUICKACK is disabled or enabled on socket.\n\n\n\n\n\n","category":"function"},{"location":"manual/distributed-computing/#Multi-processing-and-Distributed-Computing","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"An implementation of distributed memory parallel computing is provided by module Distributed as part of the standard library shipped with Julia.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Most modern computers possess more than one CPU, and several computers can be combined together in a cluster. Harnessing the power of these multiple CPUs allows many computations to be completed more quickly. There are two major factors that influence performance: the speed of the CPUs themselves, and the speed of their access to memory. In a cluster, it's fairly obvious that a given CPU will have fastest access to the RAM within the same computer (node). Perhaps more surprisingly, similar issues are relevant on a typical multicore laptop, due to differences in the speed of main memory and the cache. Consequently, a good multiprocessing environment should allow control over the \"ownership\" of a chunk of memory by a particular CPU. Julia provides a multiprocessing environment based on message passing to allow programs to run on multiple processes in separate memory domains at once.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia's implementation of message passing is different from other environments such as MPI[1]. Communication in Julia is generally \"one-sided\", meaning that the programmer needs to explicitly manage only one process in a two-process operation. Furthermore, these operations typically do not look like \"message send\" and \"message receive\" but rather resemble higher-level operations like calls to user functions.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Distributed programming in Julia is built on two primitives: remote references and remote calls. A remote reference is an object that can be used from any process to refer to an object stored on a particular process. A remote call is a request by one process to call a certain function on certain arguments on another (possibly the same) process.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Remote references come in two flavors: Future and RemoteChannel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A remote call returns a Future to its result. Remote calls return immediately; the process that made the call proceeds to its next operation while the remote call happens somewhere else. You can wait for a remote call to finish by calling wait on the returned Future, and you can obtain the full value of the result using fetch.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"On the other hand, RemoteChannel s are rewritable. For example, multiple processes can coordinate their processing by referencing the same remote Channel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Each process has an associated identifier. The process providing the interactive Julia prompt always has an id equal to 1. The processes used by default for parallel operations are referred to as \"workers\". When there is only one process, process 1 is considered a worker. Otherwise, workers are considered to be all processes other than process 1. As a result, adding 2 or more processes is required to gain benefits from parallel processing methods like pmap. Adding a single process is beneficial if you just wish to do other things in the main process while a long computation is running on the worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Let's try this out. Starting with julia -p n provides n worker processes on the local machine. Generally it makes sense for n to equal the number of CPU threads (logical cores) on the machine. Note that the -p argument implicitly loads module Distributed.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"$ julia -p 2\n\njulia> r = remotecall(rand, 2, 2, 2)\nFuture(2, 1, 4, nothing)\n\njulia> s = @spawnat 2 1 .+ fetch(r)\nFuture(2, 1, 5, nothing)\n\njulia> fetch(s)\n2×2 Array{Float64,2}:\n 1.18526 1.50912\n 1.16296 1.60607","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The first argument to remotecall is the function to call. Most parallel programming in Julia does not reference specific processes or the number of processes available, but remotecall is considered a low-level interface providing finer control. The second argument to remotecall is the id of the process that will do the work, and the remaining arguments will be passed to the function being called.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As you can see, in the first line we asked process 2 to construct a 2-by-2 random matrix, and in the second line we asked it to add 1 to it. The result of both calculations is available in the two futures, r and s. The @spawnat macro evaluates the expression in the second argument on the process specified by the first argument.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Occasionally you might want a remotely-computed value immediately. This typically happens when you read from a remote object to obtain data needed by the next local operation. The function remotecall_fetch exists for this purpose. It is equivalent to fetch(remotecall(...)) but is more efficient.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> remotecall_fetch(r-> fetch(r)[1, 1], 2, r)\n0.18526337335308085","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This fetches the array on worker 2 and returns the first value. Note, that fetch doesn't move any data in this case, since it's executed on the worker that owns the array. One can also write:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> remotecall_fetch(getindex, 2, r, 1, 1)\n0.10824216411304866","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Remember that getindex(r,1,1) is equivalent to r[1,1], so this call fetches the first element of the future r.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"To make things easier, the symbol :any can be passed to @spawnat, which picks where to do the operation for you:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> r = @spawnat :any rand(2,2)\nFuture(2, 1, 4, nothing)\n\njulia> s = @spawnat :any 1 .+ fetch(r)\nFuture(3, 1, 5, nothing)\n\njulia> fetch(s)\n2×2 Array{Float64,2}:\n 1.38854 1.9098\n 1.20939 1.57158","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Note that we used 1 .+ fetch(r) instead of 1 .+ r. This is because we do not know where the code will run, so in general a fetch might be required to move r to the process doing the addition. In this case, @spawnat is smart enough to perform the computation on the process that owns r, so the fetch will be a no-op (no work is done).","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"(It is worth noting that @spawnat is not built-in but defined in Julia as a macro. It is possible to define your own such constructs.)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"An important thing to remember is that, once fetched, a Future will cache its value locally. Further fetch calls do not entail a network hop. Once all referencing Futures have fetched, the remote stored value is deleted.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"@async is similar to @spawnat, but only runs tasks on the local process. We use it to create a \"feeder\" task for each process. Each task picks the next index that needs to be computed, then waits for its process to finish, then repeats until we run out of indices. Note that the feeder tasks do not begin to execute until the main task reaches the end of the @sync block, at which point it surrenders control and waits for all the local tasks to complete before returning from the function. As for v0.7 and beyond, the feeder tasks are able to share state via nextidx because they all run on the same process. Even if Tasks are scheduled cooperatively, locking may still be required in some contexts, as in asynchronous I/O. This means context switches only occur at well-defined points: in this case, when remotecall_fetch is called. This is the current state of implementation and it may change for future Julia versions, as it is intended to make it possible to run up to N Tasks on M Process, aka M:N Threading. Then a lock acquiring\\releasing model for nextidx will be needed, as it is not safe to let multiple processes read-write a resource at the same time.","category":"page"},{"location":"manual/distributed-computing/#code-availability","page":"Multi-processing and Distributed Computing","title":"Code Availability and Loading Packages","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Your code must be available on any process that runs it. For example, type the following into the Julia prompt:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> function rand2(dims...)\n return 2*rand(dims...)\n end\n\njulia> rand2(2,2)\n2×2 Array{Float64,2}:\n 0.153756 0.368514\n 1.15119 0.918912\n\njulia> fetch(@spawnat :any rand2(2,2))\nERROR: RemoteException(2, CapturedException(UndefVarError(Symbol(\"#rand2\"))))\nStacktrace:\n[...]","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Process 1 knew about the function rand2, but process 2 did not.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Most commonly you'll be loading code from files or packages, and you have a considerable amount of flexibility in controlling which processes load code. Consider a file, DummyModule.jl, containing the following code:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"module DummyModule\n\nexport MyType, f\n\nmutable struct MyType\n a::Int\nend\n\nf(x) = x^2+1\n\nprintln(\"loaded\")\n\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In order to refer to MyType across all processes, DummyModule.jl needs to be loaded on every process. Calling include(\"DummyModule.jl\") loads it only on a single process. To load it on every process, use the @everywhere macro (starting Julia with julia -p 2):","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere include(\"DummyModule.jl\")\nloaded\n From worker 3: loaded\n From worker 2: loaded","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As usual, this does not bring DummyModule into scope on any of the process, which requires using or import. Moreover, when DummyModule is brought into scope on one process, it is not on any other:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using .DummyModule\n\njulia> MyType(7)\nMyType(7)\n\njulia> fetch(@spawnat 2 MyType(7))\nERROR: On worker 2:\nUndefVarError: `MyType` not defined in `Main`\n⋮\n\njulia> fetch(@spawnat 2 DummyModule.MyType(7))\nMyType(7)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"However, it's still possible, for instance, to send a MyType to a process which has loaded DummyModule even if it's not in scope:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> put!(RemoteChannel(2), MyType(7))\nRemoteChannel{Channel{Any}}(2, 1, 13)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A file can also be preloaded on multiple processes at startup with the -L flag, and a driver script can be used to drive the computation:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia -p -L file1.jl -L file2.jl driver.jl","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The Julia process running the driver script in the example above has an id equal to 1, just like a process providing an interactive prompt.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Finally, if DummyModule.jl is not a standalone file but a package, then using DummyModule will load DummyModule.jl on all processes, but only bring it into scope on the process where using was called.","category":"page"},{"location":"manual/distributed-computing/#Starting-and-managing-worker-processes","page":"Multi-processing and Distributed Computing","title":"Starting and managing worker processes","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The base Julia installation has in-built support for two types of clusters:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A local cluster specified with the -p option as shown above.\nA cluster spanning machines using the --machine-file option. This uses a passwordless ssh login to start Julia worker processes (from the same path as the current host) on the specified machines. Each machine definition takes the form [count*][user@]host[:port] [bind_addr[:port]]. user defaults to current user, port to the standard ssh port. count is the number of workers to spawn on the node, and defaults to 1. The optional bind-to bind_addr[:port] specifies the IP address and port that other workers should use to connect to this worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"note: Note\nWhile Julia generally strives for backward compatibility, distribution of code to worker processes relies on Serialization.serialize. As pointed out in the corresponding documentation, this can not be guaranteed to work across different Julia versions, so it is advised that all workers on all machines use the same version.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Functions addprocs, rmprocs, workers, and others are available as a programmatic means of adding, removing and querying the processes in a cluster.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using Distributed\n\njulia> addprocs(2)\n2-element Array{Int64,1}:\n 2\n 3","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Module Distributed must be explicitly loaded on the master process before invoking addprocs. It is automatically made available on the worker processes.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"note: Note\nNote that workers do not run a ~/.julia/config/startup.jl startup script, nor do they synchronize their global state (such as command-line switches, global variables, new method definitions, and loaded modules) with any of the other running processes. You may use addprocs(exeflags=\"--project\") to initialize a worker with a particular environment, and then @everywhere using or @everywhere include(\"file.jl\").","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Other types of clusters can be supported by writing your own custom ClusterManager, as described below in the ClusterManagers section.","category":"page"},{"location":"manual/distributed-computing/#Data-Movement","page":"Multi-processing and Distributed Computing","title":"Data Movement","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Sending messages and moving data constitute most of the overhead in a distributed program. Reducing the number of messages and the amount of data sent is critical to achieving performance and scalability. To this end, it is important to understand the data movement performed by Julia's various distributed programming constructs.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"fetch can be considered an explicit data movement operation, since it directly asks that an object be moved to the local machine. @spawnat (and a few related constructs) also moves data, but this is not as obvious, hence it can be called an implicit data movement operation. Consider these two approaches to constructing and squaring a random matrix:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Method 1:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> A = rand(1000,1000);\n\njulia> Bref = @spawnat :any A^2;\n\n[...]\n\njulia> fetch(Bref);","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Method 2:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> Bref = @spawnat :any rand(1000,1000)^2;\n\n[...]\n\njulia> fetch(Bref);","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The difference seems trivial, but in fact is quite significant due to the behavior of @spawnat. In the first method, a random matrix is constructed locally, then sent to another process where it is squared. In the second method, a random matrix is both constructed and squared on another process. Therefore the second method sends much less data than the first.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In this toy example, the two methods are easy to distinguish and choose from. However, in a real program designing data movement might require more thought and likely some measurement. For example, if the first process needs matrix A then the first method might be better. Or, if computing A is expensive and only the current process has it, then moving it to another process might be unavoidable. Or, if the current process has very little to do between the @spawnat and fetch(Bref), it might be better to eliminate the parallelism altogether. Or imagine rand(1000,1000) is replaced with a more expensive operation. Then it might make sense to add another @spawnat statement just for this step.","category":"page"},{"location":"manual/distributed-computing/#Global-variables","page":"Multi-processing and Distributed Computing","title":"Global variables","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Expressions executed remotely via @spawnat, or closures specified for remote execution using remotecall may refer to global variables. Global bindings under module Main are treated a little differently compared to global bindings in other modules. Consider the following code snippet:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A = rand(10,10)\nremotecall_fetch(()->sum(A), 2)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In this case sum MUST be defined in the remote process. Note that A is a global variable defined in the local workspace. Worker 2 does not have a variable called A under Main. The act of shipping the closure ()->sum(A) to worker 2 results in Main.A being defined on 2. Main.A continues to exist on worker 2 even after the call remotecall_fetch returns. Remote calls with embedded global references (under Main module only) manage globals as follows:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"New global bindings are created on destination workers if they are referenced as part of a remote call.\nGlobal constants are declared as constants on remote nodes too.\nGlobals are re-sent to a destination worker only in the context of a remote call, and then only if its value has changed. Also, the cluster does not synchronize global bindings across nodes. For example:\nA = rand(10,10)\nremotecall_fetch(()->sum(A), 2) # worker 2\nA = rand(10,10)\nremotecall_fetch(()->sum(A), 3) # worker 3\nA = nothing\nExecuting the above snippet results in Main.A on worker 2 having a different value from Main.A on worker 3, while the value of Main.A on node 1 is set to nothing.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As you may have realized, while memory associated with globals may be collected when they are reassigned on the master, no such action is taken on the workers as the bindings continue to be valid. clear! can be used to manually reassign specific globals on remote nodes to nothing once they are no longer required. This will release any memory associated with them as part of a regular garbage collection cycle.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Thus programs should be careful referencing globals in remote calls. In fact, it is preferable to avoid them altogether if possible. If you must reference globals, consider using let blocks to localize global variables.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"For example:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> A = rand(10,10);\n\njulia> remotecall_fetch(()->A, 2);\n\njulia> B = rand(10,10);\n\njulia> let B = B\n remotecall_fetch(()->B, 2)\n end;\n\njulia> @fetchfrom 2 InteractiveUtils.varinfo()\nname size summary\n––––––––– ––––––––– ––––––––––––––––––––––\nA 800 bytes 10×10 Array{Float64,2}\nBase Module\nCore Module\nMain Module","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As can be seen, global variable A is defined on worker 2, but B is captured as a local variable and hence a binding for B does not exist on worker 2.","category":"page"},{"location":"manual/distributed-computing/#Parallel-Map-and-Loops","page":"Multi-processing and Distributed Computing","title":"Parallel Map and Loops","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Fortunately, many useful parallel computations do not require data movement. A common example is a Monte Carlo simulation, where multiple processes can handle independent simulation trials simultaneously. We can use @spawnat to flip coins on two processes. First, write the following function in count_heads.jl:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"function count_heads(n)\n c::Int = 0\n for i = 1:n\n c += rand(Bool)\n end\n c\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The function count_heads simply adds together n random bits. Here is how we can perform some trials on two machines, and add together the results:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere include_string(Main, $(read(\"count_heads.jl\", String)), \"count_heads.jl\")\n\njulia> a = @spawnat :any count_heads(100000000)\nFuture(2, 1, 6, nothing)\n\njulia> b = @spawnat :any count_heads(100000000)\nFuture(3, 1, 7, nothing)\n\njulia> fetch(a)+fetch(b)\n100001564","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This example demonstrates a powerful and often-used parallel programming pattern. Many iterations run independently over several processes, and then their results are combined using some function. The combination process is called a reduction, since it is generally tensor-rank-reducing: a vector of numbers is reduced to a single number, or a matrix is reduced to a single row or column, etc. In code, this typically looks like the pattern x = f(x,v[i]), where x is the accumulator, f is the reduction function, and the v[i] are the elements being reduced. It is desirable for f to be associative, so that it does not matter what order the operations are performed in.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Notice that our use of this pattern with count_heads can be generalized. We used two explicit @spawnat statements, which limits the parallelism to two processes. To run on any number of processes, we can use a parallel for loop, running in distributed memory, which can be written in Julia using @distributed like this:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"nheads = @distributed (+) for i = 1:200000000\n Int(rand(Bool))\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This construct implements the pattern of assigning iterations to multiple processes, and combining them with a specified reduction (in this case (+)). The result of each iteration is taken as the value of the last expression inside the loop. The whole parallel loop expression itself evaluates to the final answer.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Note that although parallel for loops look like serial for loops, their behavior is dramatically different. In particular, the iterations do not happen in a specified order, and writes to variables or arrays will not be globally visible since iterations run on different processes. Any variables used inside the parallel loop will be copied and broadcast to each process.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"For example, the following code will not work as intended:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"a = zeros(100000)\n@distributed for i = 1:100000\n a[i] = i\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This code will not initialize all of a, since each process will have a separate copy of it. Parallel for loops like these must be avoided. Fortunately, Shared Arrays can be used to get around this limitation:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"using SharedArrays\n\na = SharedArray{Float64}(10)\n@distributed for i = 1:10\n a[i] = i\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Using \"outside\" variables in parallel loops is perfectly reasonable if the variables are read-only:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"a = randn(1000)\n@distributed (+) for i = 1:100000\n f(a[rand(1:end)])\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Here each iteration applies f to a randomly-chosen sample from a vector a shared by all processes.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As you could see, the reduction operator can be omitted if it is not needed. In that case, the loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns an array of Future immediately without waiting for completion. The caller can wait for the Future completions at a later point by calling fetch on them, or wait for completion at the end of the loop by prefixing it with @sync, like @sync @distributed for.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In some cases no reduction operator is needed, and we merely wish to apply a function to all integers in some range (or, more generally, to all elements in some collection). This is another useful operation called parallel map, implemented in Julia as the pmap function. For example, we could compute the singular values of several large random matrices in parallel as follows:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10];\n\njulia> pmap(svdvals, M);","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia's pmap is designed for the case where each function call does a large amount of work. In contrast, @distributed for can handle situations where each iteration is tiny, perhaps merely summing two numbers. Only worker processes are used by both pmap and @distributed for for the parallel computation. In case of @distributed for, the final reduction is done on the calling process.","category":"page"},{"location":"manual/distributed-computing/#Remote-References-and-AbstractChannels","page":"Multi-processing and Distributed Computing","title":"Remote References and AbstractChannels","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Remote references always refer to an implementation of an AbstractChannel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A concrete implementation of an AbstractChannel (like Channel), is required to implement put!, take!, fetch, isready and wait. The remote object referred to by a Future is stored in a Channel{Any}(1), i.e., a Channel of size 1 capable of holding objects of Any type.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"RemoteChannel, which is rewritable, can point to any type and size of channels, or any other implementation of an AbstractChannel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The constructor RemoteChannel(f::Function, pid)() allows us to construct references to channels holding more than one value of a specific type. f is a function executed on pid and it must return an AbstractChannel.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"For example, RemoteChannel(()->Channel{Int}(10), pid), will return a reference to a channel of type Int and size 10. The channel exists on worker pid.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Methods put!, take!, fetch, isready and wait on a RemoteChannel are proxied onto the backing store on the remote process.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"RemoteChannel can thus be used to refer to user implemented AbstractChannel objects. A simple example of this is the following DictChannel which uses a dictionary as its remote store:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> struct DictChannel{T} <: AbstractChannel{T}\n d::Dict\n cond_take::Threads.Condition # waiting for data to become available\n DictChannel{T}() where {T} = new(Dict(), Threads.Condition())\n DictChannel() = DictChannel{Any}()\n end\n\njulia> begin\n function Base.put!(D::DictChannel, k, v)\n @lock D.cond_take begin\n D.d[k] = v\n notify(D.cond_take)\n end\n return D\n end\n function Base.take!(D::DictChannel, k)\n @lock D.cond_take begin\n v = fetch(D, k)\n delete!(D.d, k)\n return v\n end\n end\n Base.isready(D::DictChannel) = @lock D.cond_take !isempty(D.d)\n Base.isready(D::DictChannel, k) = @lock D.cond_take haskey(D.d, k)\n function Base.fetch(D::DictChannel, k)\n @lock D.cond_take begin\n wait(D, k)\n return D.d[k]\n end\n end\n function Base.wait(D::DictChannel, k)\n @lock D.cond_take begin\n while !isready(D, k)\n wait(D.cond_take)\n end\n end\n end\n end;\n\njulia> d = DictChannel();\n\njulia> isready(d)\nfalse\n\njulia> put!(d, :k, :v);\n\njulia> isready(d, :k)\ntrue\n\njulia> fetch(d, :k)\n:v\n\njulia> wait(d, :k)\n\njulia> take!(d, :k)\n:v\n\njulia> isready(d, :k)\nfalse","category":"page"},{"location":"manual/distributed-computing/#Channels-and-RemoteChannels","page":"Multi-processing and Distributed Computing","title":"Channels and RemoteChannels","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A Channel is local to a process. Worker 2 cannot directly refer to a Channel on worker 3 and vice-versa. A RemoteChannel, however, can put and take values across workers.\nA RemoteChannel can be thought of as a handle to a Channel.\nThe process id, pid, associated with a RemoteChannel identifies the process where the backing store, i.e., the backing Channel exists.\nAny process with a reference to a RemoteChannel can put and take items from the channel. Data is automatically sent to (or retrieved from) the process a RemoteChannel is associated with.\nSerializing a Channel also serializes any data present in the channel. Deserializing it therefore effectively makes a copy of the original object.\nOn the other hand, serializing a RemoteChannel only involves the serialization of an identifier that identifies the location and instance of Channel referred to by the handle. A deserialized RemoteChannel object (on any worker), therefore also points to the same backing store as the original.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The channels example from above can be modified for interprocess communication, as shown below.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"We start 4 workers to process a single jobs remote channel. Jobs, identified by an id (job_id), are written to the channel. Each remotely executing task in this simulation reads a job_id, waits for a random amount of time and writes back a tuple of job_id, time taken and its own pid to the results channel. Finally all the results are printed out on the master process.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> addprocs(4); # add worker processes\n\njulia> const jobs = RemoteChannel(()->Channel{Int}(32));\n\njulia> const results = RemoteChannel(()->Channel{Tuple}(32));\n\njulia> @everywhere function do_work(jobs, results) # define work function everywhere\n while true\n job_id = take!(jobs)\n exec_time = rand()\n sleep(exec_time) # simulates elapsed time doing actual work\n put!(results, (job_id, exec_time, myid()))\n end\n end\n\njulia> function make_jobs(n)\n for i in 1:n\n put!(jobs, i)\n end\n end;\n\njulia> n = 12;\n\njulia> errormonitor(@async make_jobs(n)); # feed the jobs channel with \"n\" jobs\n\njulia> for p in workers() # start tasks on the workers to process requests in parallel\n remote_do(do_work, p, jobs, results)\n end\n\njulia> @elapsed while n > 0 # print out results\n job_id, exec_time, where = take!(results)\n println(\"$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where\")\n global n = n - 1\n end\n1 finished in 0.18 seconds on worker 4\n2 finished in 0.26 seconds on worker 5\n6 finished in 0.12 seconds on worker 4\n7 finished in 0.18 seconds on worker 4\n5 finished in 0.35 seconds on worker 5\n4 finished in 0.68 seconds on worker 2\n3 finished in 0.73 seconds on worker 3\n11 finished in 0.01 seconds on worker 3\n12 finished in 0.02 seconds on worker 3\n9 finished in 0.26 seconds on worker 5\n8 finished in 0.57 seconds on worker 4\n10 finished in 0.58 seconds on worker 2\n0.055971741","category":"page"},{"location":"manual/distributed-computing/#Remote-References-and-Distributed-Garbage-Collection","page":"Multi-processing and Distributed Computing","title":"Remote References and Distributed Garbage Collection","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Objects referred to by remote references can be freed only when all held references in the cluster are deleted.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The node where the value is stored keeps track of which of the workers have a reference to it. Every time a RemoteChannel or a (unfetched) Future is serialized to a worker, the node pointed to by the reference is notified. And every time a RemoteChannel or a (unfetched) Future is garbage collected locally, the node owning the value is again notified. This is implemented in an internal cluster aware serializer. Remote references are only valid in the context of a running cluster. Serializing and deserializing references to and from regular IO objects is not supported.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The notifications are done via sending of \"tracking\" messages–an \"add reference\" message when a reference is serialized to a different process and a \"delete reference\" message when a reference is locally garbage collected.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Since Futures are write-once and cached locally, the act of fetching a Future also updates reference tracking information on the node owning the value.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The node which owns the value frees it once all references to it are cleared.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"With Futures, serializing an already fetched Future to a different node also sends the value since the original remote store may have collected the value by this time.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"It is important to note that when an object is locally garbage collected depends on the size of the object and the current memory pressure in the system.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In case of remote references, the size of the local reference object is quite small, while the value stored on the remote node may be quite large. Since the local object may not be collected immediately, it is a good practice to explicitly call finalize on local instances of a RemoteChannel, or on unfetched Futures. Since calling fetch on a Future also removes its reference from the remote store, this is not required on fetched Futures. Explicitly calling finalize results in an immediate message sent to the remote node to go ahead and remove its reference to the value.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Once finalized, a reference becomes invalid and cannot be used in any further calls.","category":"page"},{"location":"manual/distributed-computing/#Local-invocations","page":"Multi-processing and Distributed Computing","title":"Local invocations","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Data is necessarily copied over to the remote node for execution. This is the case for both remotecalls and when data is stored to a RemoteChannel / Future on a different node. As expected, this results in a copy of the serialized objects on the remote node. However, when the destination node is the local node, i.e. the calling process id is the same as the remote node id, it is executed as a local call. It is usually (not always) executed in a different task - but there is no serialization/deserialization of data. Consequently, the call refers to the same object instances as passed - no copies are created. This behavior is highlighted below:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using Distributed;\n\njulia> rc = RemoteChannel(()->Channel(3)); # RemoteChannel created on local node\n\njulia> v = [0];\n\njulia> for i in 1:3\n v[1] = i # Reusing `v`\n put!(rc, v)\n end;\n\njulia> result = [take!(rc) for _ in 1:3];\n\njulia> println(result);\nArray{Int64,1}[[3], [3], [3]]\n\njulia> println(\"Num Unique objects : \", length(unique(map(objectid, result))));\nNum Unique objects : 1\n\njulia> addprocs(1);\n\njulia> rc = RemoteChannel(()->Channel(3), workers()[1]); # RemoteChannel created on remote node\n\njulia> v = [0];\n\njulia> for i in 1:3\n v[1] = i\n put!(rc, v)\n end;\n\njulia> result = [take!(rc) for _ in 1:3];\n\njulia> println(result);\nArray{Int64,1}[[1], [2], [3]]\n\njulia> println(\"Num Unique objects : \", length(unique(map(objectid, result))));\nNum Unique objects : 3","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As can be seen, put! on a locally owned RemoteChannel with the same object v modified between calls results in the same single object instance stored. As opposed to copies of v being created when the node owning rc is a different node.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"It is to be noted that this is generally not an issue. It is something to be factored in only if the object is both being stored locally and modified post the call. In such cases it may be appropriate to store a deepcopy of the object.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"This is also true for remotecalls on the local node as seen in the following example:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using Distributed; addprocs(1);\n\njulia> v = [0];\n\njulia> v2 = remotecall_fetch(x->(x[1] = 1; x), myid(), v); # Executed on local node\n\njulia> println(\"v=$v, v2=$v2, \", v === v2);\nv=[1], v2=[1], true\n\njulia> v = [0];\n\njulia> v2 = remotecall_fetch(x->(x[1] = 1; x), workers()[1], v); # Executed on remote node\n\njulia> println(\"v=$v, v2=$v2, \", v === v2);\nv=[0], v2=[1], false","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As can be seen once again, a remote call onto the local node behaves just like a direct invocation. The call modifies local objects passed as arguments. In the remote invocation, it operates on a copy of the arguments.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"To repeat, in general this is not an issue. If the local node is also being used as a compute node, and the arguments used post the call, this behavior needs to be factored in and if required deep copies of arguments must be passed to the call invoked on the local node. Calls on remote nodes will always operate on copies of arguments.","category":"page"},{"location":"manual/distributed-computing/#man-shared-arrays","page":"Multi-processing and Distributed Computing","title":"Shared Arrays","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Shared Arrays use system shared memory to map the same array across many processes. A SharedArray is a good choice when you want to have a large amount of data jointly accessible to two or more processes on the same machine. Shared Array support is available via the module SharedArrays, which must be explicitly loaded on all participating workers.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A complementary data structure is provided by the external package DistributedArrays.jl in the form of a DArray. While there are some similarities to a SharedArray, the behavior of a DArray is quite different. In a SharedArray, each \"participating\" process has access to the entire array; in contrast, in a DArray, each process has local access to just a chunk of the data, and no two processes share the same chunk.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"SharedArray indexing (assignment and accessing values) works just as with regular arrays, and is efficient because the underlying memory is available to the local process. Therefore, most algorithms work naturally on SharedArrays, albeit in single-process mode. In cases where an algorithm insists on an Array input, the underlying array can be retrieved from a SharedArray by calling sdata. For other AbstractArray types, sdata just returns the object itself, so it's safe to use sdata on any Array-type object.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The constructor for a shared array is of the form:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"SharedArray{T,N}(dims::NTuple; init=false, pids=Int[])","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"which creates an N-dimensional shared array of a bits type T and size dims across the processes specified by pids. Unlike distributed arrays, a shared array is accessible only from those participating workers specified by the pids named argument (and the creating process too, if it is on the same host). Note that only elements that are isbits are supported in a SharedArray.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"If an init function, of signature initfn(S::SharedArray), is specified, it is called on all the participating workers. You can specify that each worker runs the init function on a distinct portion of the array, thereby parallelizing initialization.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Here's a brief example:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> using Distributed\n\njulia> addprocs(3)\n3-element Array{Int64,1}:\n 2\n 3\n 4\n\njulia> @everywhere using SharedArrays\n\njulia> S = SharedArray{Int,2}((3,4), init = S -> S[localindices(S)] = repeat([myid()], length(localindices(S))))\n3×4 SharedArray{Int64,2}:\n 2 2 3 4\n 2 3 3 4\n 2 3 4 4\n\njulia> S[3,2] = 7\n7\n\njulia> S\n3×4 SharedArray{Int64,2}:\n 2 2 3 4\n 2 3 3 4\n 2 7 4 4","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"SharedArrays.localindices provides disjoint one-dimensional ranges of indices, and is sometimes convenient for splitting up tasks among processes. You can, of course, divide the work any way you wish:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> S = SharedArray{Int,2}((3,4), init = S -> S[indexpids(S):length(procs(S)):length(S)] = repeat([myid()], length( indexpids(S):length(procs(S)):length(S))))\n3×4 SharedArray{Int64,2}:\n 2 2 2 2\n 3 3 3 3\n 4 4 4 4","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Since all processes have access to the underlying data, you do have to be careful not to set up conflicts. For example:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"@sync begin\n for p in procs(S)\n @async begin\n remotecall_wait(fill!, p, S, p)\n end\n end\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"would result in undefined behavior. Because each process fills the entire array with its own pid, whichever process is the last to execute (for any particular element of S) will have its pid retained.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As a more extended and complex example, consider running the following \"kernel\" in parallel:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"q[i,j,t+1] = q[i,j,t] + u[i,j,t]","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In this case, if we try to split up the work using a one-dimensional index, we are likely to run into trouble: if q[i,j,t] is near the end of the block assigned to one worker and q[i,j,t+1] is near the beginning of the block assigned to another, it's very likely that q[i,j,t] will not be ready at the time it's needed for computing q[i,j,t+1]. In such cases, one is better off chunking the array manually. Let's split along the second dimension. Define a function that returns the (irange, jrange) indices assigned to this worker:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere function myrange(q::SharedArray)\n idx = indexpids(q)\n if idx == 0 # This worker is not assigned a piece\n return 1:0, 1:0\n end\n nchunks = length(procs(q))\n splits = [round(Int, s) for s in range(0, stop=size(q,2), length=nchunks+1)]\n 1:size(q,1), splits[idx]+1:splits[idx+1]\n end","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Next, define the kernel:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere function advection_chunk!(q, u, irange, jrange, trange)\n @show (irange, jrange, trange) # display so we can see what's happening\n for t in trange, j in jrange, i in irange\n q[i,j,t+1] = q[i,j,t] + u[i,j,t]\n end\n q\n end","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"We also define a convenience wrapper for a SharedArray implementation","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @everywhere advection_shared_chunk!(q, u) =\n advection_chunk!(q, u, myrange(q)..., 1:size(q,3)-1)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Now let's compare three different versions, one that runs in a single process:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> advection_serial!(q, u) = advection_chunk!(q, u, 1:size(q,1), 1:size(q,2), 1:size(q,3)-1);","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"one that uses @distributed:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> function advection_parallel!(q, u)\n for t = 1:size(q,3)-1\n @sync @distributed for j = 1:size(q,2)\n for i = 1:size(q,1)\n q[i,j,t+1]= q[i,j,t] + u[i,j,t]\n end\n end\n end\n q\n end;","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"and one that delegates in chunks:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> function advection_shared!(q, u)\n @sync begin\n for p in procs(q)\n @async remotecall_wait(advection_shared_chunk!, p, q, u)\n end\n end\n q\n end;","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"If we create SharedArrays and time these functions, we get the following results (with julia -p 4):","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> q = SharedArray{Float64,3}((500,500,500));\n\njulia> u = SharedArray{Float64,3}((500,500,500));","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Run the functions once to JIT-compile and @time them on the second run:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> @time advection_serial!(q, u);\n(irange,jrange,trange) = (1:500,1:500,1:499)\n 830.220 milliseconds (216 allocations: 13820 bytes)\n\njulia> @time advection_parallel!(q, u);\n 2.495 seconds (3999 k allocations: 289 MB, 2.09% gc time)\n\njulia> @time advection_shared!(q,u);\n From worker 2: (irange,jrange,trange) = (1:500,1:125,1:499)\n From worker 4: (irange,jrange,trange) = (1:500,251:375,1:499)\n From worker 3: (irange,jrange,trange) = (1:500,126:250,1:499)\n From worker 5: (irange,jrange,trange) = (1:500,376:500,1:499)\n 238.119 milliseconds (2264 allocations: 169 KB)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The biggest advantage of advection_shared! is that it minimizes traffic among the workers, allowing each to compute for an extended time on the assigned piece.","category":"page"},{"location":"manual/distributed-computing/#Shared-Arrays-and-Distributed-Garbage-Collection","page":"Multi-processing and Distributed Computing","title":"Shared Arrays and Distributed Garbage Collection","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Like remote references, shared arrays are also dependent on garbage collection on the creating node to release references from all participating workers. Code which creates many short lived shared array objects would benefit from explicitly finalizing these objects as soon as possible. This results in both memory and file handles mapping the shared segment being released sooner.","category":"page"},{"location":"manual/distributed-computing/#ClusterManagers","page":"Multi-processing and Distributed Computing","title":"ClusterManagers","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The launching, management and networking of Julia processes into a logical cluster is done via cluster managers. A ClusterManager is responsible for","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"launching worker processes in a cluster environment\nmanaging events during the lifetime of each worker\noptionally, providing data transport","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A Julia cluster has the following characteristics:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The initial Julia process, also called the master, is special and has an id of 1.\nOnly the master process can add or remove worker processes.\nAll processes can directly communicate with each other.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Connections between workers (using the in-built TCP/IP transport) is established in the following manner:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"addprocs is called on the master process with a ClusterManager object.\naddprocs calls the appropriate launch method which spawns required number of worker processes on appropriate machines.\nEach worker starts listening on a free port and writes out its host and port information to stdout.\nThe cluster manager captures the stdout of each worker and makes it available to the master process.\nThe master process parses this information and sets up TCP/IP connections to each worker.\nEvery worker is also notified of other workers in the cluster.\nEach worker connects to all workers whose id is less than the worker's own id.\nIn this way a mesh network is established, wherein every worker is directly connected with every other worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"While the default transport layer uses plain TCPSocket, it is possible for a Julia cluster to provide its own transport.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia provides two in-built cluster managers:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"LocalManager, used when addprocs() or addprocs(np::Integer) are called\nSSHManager, used when addprocs(hostnames::Array) is called with a list of hostnames","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"LocalManager is used to launch additional workers on the same host, thereby leveraging multi-core and multi-processor hardware.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Thus, a minimal cluster manager would need to:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"be a subtype of the abstract ClusterManager\nimplement launch, a method responsible for launching new workers\nimplement manage, which is called at various events during a worker's lifetime (for example, sending an interrupt signal)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"addprocs(manager::FooManager) requires FooManager to implement:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"function launch(manager::FooManager, params::Dict, launched::Array, c::Condition)\n [...]\nend\n\nfunction manage(manager::FooManager, id::Integer, config::WorkerConfig, op::Symbol)\n [...]\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As an example let us see how the LocalManager, the manager responsible for starting workers on the same host, is implemented:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"struct LocalManager <: ClusterManager\n np::Integer\nend\n\nfunction launch(manager::LocalManager, params::Dict, launched::Array, c::Condition)\n [...]\nend\n\nfunction manage(manager::LocalManager, id::Integer, config::WorkerConfig, op::Symbol)\n [...]\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The launch method takes the following arguments:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"manager::ClusterManager: the cluster manager that addprocs is called with\nparams::Dict: all the keyword arguments passed to addprocs\nlaunched::Array: the array to append one or more WorkerConfig objects to\nc::Condition: the condition variable to be notified as and when workers are launched","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The launch method is called asynchronously in a separate task. The termination of this task signals that all requested workers have been launched. Hence the launch function MUST exit as soon as all the requested workers have been launched.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Newly launched workers are connected to each other and the master process in an all-to-all manner. Specifying the command line argument --worker[=] results in the launched processes initializing themselves as workers and connections being set up via TCP/IP sockets.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"All workers in a cluster share the same cookie as the master. When the cookie is unspecified, i.e, with the --worker option, the worker tries to read it from its standard input. LocalManager and SSHManager both pass the cookie to newly launched workers via their standard inputs.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"By default a worker will listen on a free port at the address returned by a call to getipaddr(). A specific address to listen on may be specified by optional argument --bind-to bind_addr[:port]. This is useful for multi-homed hosts.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"As an example of a non-TCP/IP transport, an implementation may choose to use MPI, in which case --worker must NOT be specified. Instead, newly launched workers should call init_worker(cookie) before using any of the parallel constructs.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"For every worker launched, the launch method must add a WorkerConfig object (with appropriate fields initialized) to launched","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"mutable struct WorkerConfig\n # Common fields relevant to all cluster managers\n io::Union{IO, Nothing}\n host::Union{AbstractString, Nothing}\n port::Union{Integer, Nothing}\n\n # Used when launching additional workers at a host\n count::Union{Int, Symbol, Nothing}\n exename::Union{AbstractString, Cmd, Nothing}\n exeflags::Union{Cmd, Nothing}\n\n # External cluster managers can use this to store information at a per-worker level\n # Can be a dict if multiple fields need to be stored.\n userdata::Any\n\n # SSHManager / SSH tunnel connections to workers\n tunnel::Union{Bool, Nothing}\n bind_addr::Union{AbstractString, Nothing}\n sshflags::Union{Cmd, Nothing}\n max_parallel::Union{Integer, Nothing}\n\n # Used by Local/SSH managers\n connect_at::Any\n\n [...]\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Most of the fields in WorkerConfig are used by the inbuilt managers. Custom cluster managers would typically specify only io or host / port:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"If io is specified, it is used to read host/port information. A Julia worker prints out its bind address and port at startup. This allows Julia workers to listen on any free port available instead of requiring worker ports to be configured manually.\nIf io is not specified, host and port are used to connect.\ncount, exename and exeflags are relevant for launching additional workers from a worker. For example, a cluster manager may launch a single worker per node, and use that to launch additional workers.\ncount with an integer value n will launch a total of n workers.\ncount with a value of :auto will launch as many workers as the number of CPU threads (logical cores) on that machine.\nexename is the name of the julia executable including the full path.\nexeflags should be set to the required command line arguments for new workers.\ntunnel, bind_addr, sshflags and max_parallel are used when a ssh tunnel is required to connect to the workers from the master process.\nuserdata is provided for custom cluster managers to store their own worker-specific information.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"manage(manager::FooManager, id::Integer, config::WorkerConfig, op::Symbol) is called at different times during the worker's lifetime with appropriate op values:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"with :register/:deregister when a worker is added / removed from the Julia worker pool.\nwith :interrupt when interrupt(workers) is called. The ClusterManager should signal the appropriate worker with an interrupt signal.\nwith :finalize for cleanup purposes.","category":"page"},{"location":"manual/distributed-computing/#Cluster-Managers-with-Custom-Transports","page":"Multi-processing and Distributed Computing","title":"Cluster Managers with Custom Transports","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Replacing the default TCP/IP all-to-all socket connections with a custom transport layer is a little more involved. Each Julia process has as many communication tasks as the workers it is connected to. For example, consider a Julia cluster of 32 processes in an all-to-all mesh network:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Each Julia process thus has 31 communication tasks.\nEach task handles all incoming messages from a single remote worker in a message-processing loop.\nThe message-processing loop waits on an IO object (for example, a TCPSocket in the default implementation), reads an entire message, processes it and waits for the next one.\nSending messages to a process is done directly from any Julia task–not just communication tasks–again, via the appropriate IO object.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Replacing the default transport requires the new implementation to set up connections to remote workers and to provide appropriate IO objects that the message-processing loops can wait on. The manager-specific callbacks to be implemented are:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"connect(manager::FooManager, pid::Integer, config::WorkerConfig)\nkill(manager::FooManager, pid::Int, config::WorkerConfig)","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The default implementation (which uses TCP/IP sockets) is implemented as connect(manager::ClusterManager, pid::Integer, config::WorkerConfig).","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"connect should return a pair of IO objects, one for reading data sent from worker pid, and the other to write data that needs to be sent to worker pid. Custom cluster managers can use an in-memory BufferStream as the plumbing to proxy data between the custom, possibly non-IO transport and Julia's in-built parallel infrastructure.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A BufferStream is an in-memory IOBuffer which behaves like an IO–it is a stream which can be handled asynchronously.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The folder clustermanager/0mq in the Examples repository contains an example of using ZeroMQ to connect Julia workers in a star topology with a 0MQ broker in the middle. Note: The Julia processes are still all logically connected to each other–any worker can message any other worker directly without any awareness of 0MQ being used as the transport layer.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"When using custom transports:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia workers must NOT be started with --worker. Starting with --worker will result in the newly launched workers defaulting to the TCP/IP socket transport implementation.\nFor every incoming logical connection with a worker, Base.process_messages(rd::IO, wr::IO)() must be called. This launches a new task that handles reading and writing of messages from/to the worker represented by the IO objects.\ninit_worker(cookie, manager::FooManager) must be called as part of worker process initialization.\nField connect_at::Any in WorkerConfig can be set by the cluster manager when launch is called. The value of this field is passed in all connect callbacks. Typically, it carries information on how to connect to a worker. For example, the TCP/IP socket transport uses this field to specify the (host, port) tuple at which to connect to a worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"kill(manager, pid, config) is called to remove a worker from the cluster. On the master process, the corresponding IO objects must be closed by the implementation to ensure proper cleanup. The default implementation simply executes an exit() call on the specified remote worker.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The Examples folder clustermanager/simple is an example that shows a simple implementation using UNIX domain sockets for cluster setup.","category":"page"},{"location":"manual/distributed-computing/#Network-Requirements-for-LocalManager-and-SSHManager","page":"Multi-processing and Distributed Computing","title":"Network Requirements for LocalManager and SSHManager","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Julia clusters are designed to be executed on already secured environments on infrastructure such as local laptops, departmental clusters, or even the cloud. This section covers network security requirements for the inbuilt LocalManager and SSHManager:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The master process does not listen on any port. It only connects out to the workers.\nEach worker binds to only one of the local interfaces and listens on an ephemeral port number assigned by the OS.\nLocalManager, used by addprocs(N), by default binds only to the loopback interface. This means that workers started later on remote hosts (or by anyone with malicious intentions) are unable to connect to the cluster. An addprocs(4) followed by an addprocs([\"remote_host\"]) will fail. Some users may need to create a cluster comprising their local system and a few remote systems. This can be done by explicitly requesting LocalManager to bind to an external network interface via the restrict keyword argument: addprocs(4; restrict=false).\nSSHManager, used by addprocs(list_of_remote_hosts), launches workers on remote hosts via SSH. By default SSH is only used to launch Julia workers. Subsequent master-worker and worker-worker connections use plain, unencrypted TCP/IP sockets. The remote hosts must have passwordless login enabled. Additional SSH flags or credentials may be specified via keyword argument sshflags.\naddprocs(list_of_remote_hosts; tunnel=true, sshflags=) is useful when we wish to use SSH connections for master-worker too. A typical scenario for this is a local laptop running the Julia REPL (i.e., the master) with the rest of the cluster on the cloud, say on Amazon EC2. In this case only port 22 needs to be opened at the remote cluster coupled with SSH client authenticated via public key infrastructure (PKI). Authentication credentials can be supplied via sshflags, for example sshflags=`-i `.\nIn an all-to-all topology (the default), all workers connect to each other via plain TCP sockets. The security policy on the cluster nodes must thus ensure free connectivity between workers for the ephemeral port range (varies by OS).\nSecuring and encrypting all worker-worker traffic (via SSH) or encrypting individual messages can be done via a custom ClusterManager.\nIf you specify multiplex=true as an option to addprocs, SSH multiplexing is used to create a tunnel between the master and workers. If you have configured SSH multiplexing on your own and the connection has already been established, SSH multiplexing is used regardless of multiplex option. If multiplexing is enabled, forwarding is set by using the existing connection (-O forward option in ssh). This is beneficial if your servers require password authentication; you can avoid authentication in Julia by logging in to the server ahead of addprocs. The control socket will be located at ~/.ssh/julia-%r@%h:%p during the session unless the existing multiplexing connection is used. Note that bandwidth may be limited if you create multiple processes on a node and enable multiplexing, because in that case processes share a single multiplexing TCP connection.","category":"page"},{"location":"manual/distributed-computing/#man-cluster-cookie","page":"Multi-processing and Distributed Computing","title":"Cluster Cookie","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"All processes in a cluster share the same cookie which, by default, is a randomly generated string on the master process:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"cluster_cookie() returns the cookie, while cluster_cookie(cookie)() sets it and returns the new cookie.\nAll connections are authenticated on both sides to ensure that only workers started by the master are allowed to connect to each other.\nThe cookie may be passed to the workers at startup via argument --worker=. If argument --worker is specified without the cookie, the worker tries to read the cookie from its standard input (stdin). The stdin is closed immediately after the cookie is retrieved.\nClusterManagers can retrieve the cookie on the master by calling cluster_cookie(). Cluster managers not using the default TCP/IP transport (and hence not specifying --worker) must call init_worker(cookie, manager) with the same cookie as on the master.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Note that environments requiring higher levels of security can implement this via a custom ClusterManager. For example, cookies can be pre-shared and hence not specified as a startup argument.","category":"page"},{"location":"manual/distributed-computing/#Specifying-Network-Topology-(Experimental)","page":"Multi-processing and Distributed Computing","title":"Specifying Network Topology (Experimental)","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"The keyword argument topology passed to addprocs is used to specify how the workers must be connected to each other:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":":all_to_all, the default: all workers are connected to each other.\n:master_worker: only the driver process, i.e. pid 1, has connections to the workers.\n:custom: the launch method of the cluster manager specifies the connection topology via the fields ident and connect_idents in WorkerConfig. A worker with a cluster-manager-provided identity ident will connect to all workers specified in connect_idents.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Keyword argument lazy=true|false only affects topology option :all_to_all. If true, the cluster starts off with the master connected to all workers. Specific worker-worker connections are established at the first remote invocation between two workers. This helps in reducing initial resources allocated for intra-cluster communication. Connections are setup depending on the runtime requirements of a parallel program. Default value for lazy is true.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Currently, sending a message between unconnected workers results in an error. This behaviour, as with the functionality and interface, should be considered experimental in nature and may change in future releases.","category":"page"},{"location":"manual/distributed-computing/#Noteworthy-external-packages","page":"Multi-processing and Distributed Computing","title":"Noteworthy external packages","text":"","category":"section"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Outside of Julia parallelism there are plenty of external packages that should be mentioned. For example, MPI.jl is a Julia wrapper for the MPI protocol, Dagger.jl provides functionality similar to Python's Dask, and DistributedArrays.jl provides array operations distributed across workers, as outlined above.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"A mention must be made of Julia's GPU programming ecosystem, which includes:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"CUDA.jl wraps the various CUDA libraries and supports compiling Julia kernels for Nvidia GPUs.\noneAPI.jl wraps the oneAPI unified programming model, and supports executing Julia kernels on supported accelerators. Currently only Linux is supported.\nAMDGPU.jl wraps the AMD ROCm libraries and supports compiling Julia kernels for AMD GPUs. Currently only Linux is supported.\nHigh-level libraries like KernelAbstractions.jl, Tullio.jl and ArrayFire.jl.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In the following example we will use both DistributedArrays.jl and CUDA.jl to distribute an array across multiple processes by first casting it through distribute() and CuArray().","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Remember when importing DistributedArrays.jl to import it across all processes using @everywhere","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"$ ./julia -p 4\n\njulia> addprocs()\n\njulia> @everywhere using DistributedArrays\n\njulia> using CUDA\n\njulia> B = ones(10_000) ./ 2;\n\njulia> A = ones(10_000) .* π;\n\njulia> C = 2 .* A ./ B;\n\njulia> all(C .≈ 4*π)\ntrue\n\njulia> typeof(C)\nArray{Float64,1}\n\njulia> dB = distribute(B);\n\njulia> dA = distribute(A);\n\njulia> dC = 2 .* dA ./ dB;\n\njulia> all(dC .≈ 4*π)\ntrue\n\njulia> typeof(dC)\nDistributedArrays.DArray{Float64,1,Array{Float64,1}}\n\njulia> cuB = CuArray(B);\n\njulia> cuA = CuArray(A);\n\njulia> cuC = 2 .* cuA ./ cuB;\n\njulia> all(cuC .≈ 4*π);\ntrue\n\njulia> typeof(cuC)\nCuArray{Float64,1}","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"In the following example we will use both DistributedArrays.jl and CUDA.jl to distribute an array across multiple processes and call a generic function on it.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"function power_method(M, v)\n for i in 1:100\n v = M*v\n v /= norm(v)\n end\n\n return v, norm(M*v) / norm(v) # or (M*v) ./ v\nend","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"power_method repeatedly creates a new vector and normalizes it. We have not specified any type signature in function declaration, let's see if it works with the aforementioned datatypes:","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"julia> M = [2. 1; 1 1];\n\njulia> v = rand(2)\n2-element Array{Float64,1}:\n0.40395\n0.445877\n\njulia> power_method(M,v)\n([0.850651, 0.525731], 2.618033988749895)\n\njulia> cuM = CuArray(M);\n\njulia> cuv = CuArray(v);\n\njulia> curesult = power_method(cuM, cuv);\n\njulia> typeof(curesult)\nCuArray{Float64,1}\n\njulia> dM = distribute(M);\n\njulia> dv = distribute(v);\n\njulia> dC = power_method(dM, dv);\n\njulia> typeof(dC)\nTuple{DistributedArrays.DArray{Float64,1,Array{Float64,1}},Float64}","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"To end this short exposure to external packages, we can consider MPI.jl, a Julia wrapper of the MPI protocol. As it would take too long to consider every inner function, it would be better to simply appreciate the approach used to implement the protocol.","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"Consider this toy script which simply calls each subprocess, instantiate its rank and when the master process is reached, performs the ranks' sum","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"import MPI\n\nMPI.Init()\n\ncomm = MPI.COMM_WORLD\nMPI.Barrier(comm)\n\nroot = 0\nr = MPI.Comm_rank(comm)\n\nsr = MPI.Reduce(r, MPI.SUM, root, comm)\n\nif(MPI.Comm_rank(comm) == root)\n @printf(\"sum of ranks: %s\\n\", sr)\nend\n\nMPI.Finalize()","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"mpirun -np 4 ./julia example.jl","category":"page"},{"location":"manual/distributed-computing/","page":"Multi-processing and Distributed Computing","title":"Multi-processing and Distributed Computing","text":"[1]: In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication patterns. For additional information on the latest MPI standard, see https://mpi-forum.org/docs.","category":"page"},{"location":"manual/running-external-programs/#Running-External-Programs","page":"Running External Programs","title":"Running External Programs","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Julia borrows backtick notation for commands from the shell, Perl, and Ruby. However, in Julia, writing","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> `echo hello`\n`echo hello`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"differs in several aspects from the behavior in various shells, Perl, or Ruby:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Instead of immediately running the command, backticks create a Cmd object to represent the command. You can use this object to connect the command to others via pipes, run it, and read or write to it.\nWhen the command is run, Julia does not capture its output unless you specifically arrange for it to. Instead, the output of the command by default goes to stdout as it would using libc's system call.\nThe command is never run with a shell. Instead, Julia parses the command syntax directly, appropriately interpolating variables and splitting on words as the shell would, respecting shell quoting syntax. The command is run as julia's immediate child process, using fork and exec calls.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"note: Note\nThe following assumes a Posix environment as on Linux or MacOS. On Windows, many similar commands, such as echo and dir, are not external programs and instead are built into the shell cmd.exe itself. One option to run these commands is to invoke cmd.exe, for example cmd /C echo hello. Alternatively Julia can be run inside a Posix environment such as Cygwin.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Here's a simple example of running an external program:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> mycommand = `echo hello`\n`echo hello`\n\njulia> typeof(mycommand)\nCmd\n\njulia> run(mycommand);\nhello","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The hello is the output of the echo command, sent to stdout. If the external command fails to run successfully, the run method throws an ProcessFailedException.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"If you want to read the output of the external command, read or readchomp can be used instead:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> read(`echo hello`, String)\n\"hello\\n\"\n\njulia> readchomp(`echo hello`)\n\"hello\"","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"More generally, you can use open to read from or write to an external command.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> open(`less`, \"w\", stdout) do io\n for i = 1:3\n println(io, i)\n end\n end\n1\n2\n3","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The program name and the individual arguments in a command can be accessed and iterated over as if the command were an array of strings:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> collect(`echo \"foo bar\"`)\n2-element Vector{String}:\n \"echo\"\n \"foo bar\"\n\njulia> `echo \"foo bar\"`[2]\n\"foo bar\"","category":"page"},{"location":"manual/running-external-programs/#command-interpolation","page":"Running External Programs","title":"Interpolation","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Suppose you want to do something a bit more complicated and use the name of a file in the variable file as an argument to a command. You can use $ for interpolation much as you would in a string literal (see Strings):","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> file = \"/etc/passwd\"\n\"/etc/passwd\"\n\njulia> `sort $file`\n`sort /etc/passwd`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"A common pitfall when running external programs via a shell is that if a file name contains characters that are special to the shell, they may cause undesirable behavior. Suppose, for example, rather than /etc/passwd, we wanted to sort the contents of the file /Volumes/External HD/data.csv. Let's try it:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> file = \"/Volumes/External HD/data.csv\"\n\"/Volumes/External HD/data.csv\"\n\njulia> `sort $file`\n`sort '/Volumes/External HD/data.csv'`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"How did the file name get quoted? Julia knows that file is meant to be interpolated as a single argument, so it quotes the word for you. Actually, that is not quite accurate: the value of file is never interpreted by a shell, so there's no need for actual quoting; the quotes are inserted only for presentation to the user. This will even work if you interpolate a value as part of a shell word:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> path = \"/Volumes/External HD\"\n\"/Volumes/External HD\"\n\njulia> name = \"data\"\n\"data\"\n\njulia> ext = \"csv\"\n\"csv\"\n\njulia> `sort $path/$name.$ext`\n`sort '/Volumes/External HD/data.csv'`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"As you can see, the space in the path variable is appropriately escaped. But what if you want to interpolate multiple words? In that case, just use an array (or any other iterable container):","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> files = [\"/etc/passwd\",\"/Volumes/External HD/data.csv\"]\n2-element Vector{String}:\n \"/etc/passwd\"\n \"/Volumes/External HD/data.csv\"\n\njulia> `grep foo $files`\n`grep foo /etc/passwd '/Volumes/External HD/data.csv'`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"If you interpolate an array as part of a shell word, Julia emulates the shell's {a,b,c} argument generation:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> names = [\"foo\",\"bar\",\"baz\"]\n3-element Vector{String}:\n \"foo\"\n \"bar\"\n \"baz\"\n\njulia> `grep xylophone $names.txt`\n`grep xylophone foo.txt bar.txt baz.txt`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Moreover, if you interpolate multiple arrays into the same word, the shell's Cartesian product generation behavior is emulated:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> names = [\"foo\",\"bar\",\"baz\"]\n3-element Vector{String}:\n \"foo\"\n \"bar\"\n \"baz\"\n\njulia> exts = [\"aux\",\"log\"]\n2-element Vector{String}:\n \"aux\"\n \"log\"\n\njulia> `rm -f $names.$exts`\n`rm -f foo.aux foo.log bar.aux bar.log baz.aux baz.log`","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Since you can interpolate literal arrays, you can use this generative functionality without needing to create temporary array objects first:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> `rm -rf $[\"foo\",\"bar\",\"baz\",\"qux\"].$[\"aux\",\"log\",\"pdf\"]`\n`rm -rf foo.aux foo.log foo.pdf bar.aux bar.log bar.pdf baz.aux baz.log baz.pdf qux.aux qux.log qux.pdf`","category":"page"},{"location":"manual/running-external-programs/#Quoting","page":"Running External Programs","title":"Quoting","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Inevitably, one wants to write commands that aren't quite so simple, and it becomes necessary to use quotes. Here's a simple example of a Perl one-liner at a shell prompt:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"sh$ perl -le '$|=1; for (0..3) { print }'\n0\n1\n2\n3","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The Perl expression needs to be in single quotes for two reasons: so that spaces don't break the expression into multiple shell words, and so that uses of Perl variables like $| (yes, that's the name of a variable in Perl), don't cause interpolation. In other instances, you may want to use double quotes so that interpolation does occur:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"sh$ first=\"A\"\nsh$ second=\"B\"\nsh$ perl -le '$|=1; print for @ARGV' \"1: $first\" \"2: $second\"\n1: A\n2: B","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"In general, the Julia backtick syntax is carefully designed so that you can just cut-and-paste shell commands as is into backticks and they will work: the escaping, quoting, and interpolation behaviors are the same as the shell's. The only difference is that the interpolation is integrated and aware of Julia's notion of what is a single string value, and what is a container for multiple values. Let's try the above two examples in Julia:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> A = `perl -le '$|=1; for (0..3) { print }'`\n`perl -le '$|=1; for (0..3) { print }'`\n\njulia> run(A);\n0\n1\n2\n3\n\njulia> first = \"A\"; second = \"B\";\n\njulia> B = `perl -le 'print for @ARGV' \"1: $first\" \"2: $second\"`\n`perl -le 'print for @ARGV' '1: A' '2: B'`\n\njulia> run(B);\n1: A\n2: B","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The results are identical, and Julia's interpolation behavior mimics the shell's with some improvements due to the fact that Julia supports first-class iterable objects while most shells use strings split on spaces for this, which introduces ambiguities. When trying to port shell commands to Julia, try cut and pasting first. Since Julia shows commands to you before running them, you can easily and safely just examine its interpretation without doing any damage.","category":"page"},{"location":"manual/running-external-programs/#Pipelines","page":"Running External Programs","title":"Pipelines","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Shell metacharacters, such as |, &, and >, need to be quoted (or escaped) inside of Julia's backticks:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(`echo hello '|' sort`);\nhello | sort\n\njulia> run(`echo hello \\| sort`);\nhello | sort","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This expression invokes the echo command with three words as arguments: hello, |, and sort. The result is that a single line is printed: hello | sort. How, then, does one construct a pipeline? Instead of using '|' inside of backticks, one uses pipeline:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(pipeline(`echo hello`, `sort`));\nhello","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This pipes the output of the echo command to the sort command. Of course, this isn't terribly interesting since there's only one line to sort, but we can certainly do much more interesting things:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(pipeline(`cut -d: -f3 /etc/passwd`, `sort -n`, `tail -n5`))\n210\n211\n212\n213\n214","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This prints the highest five user IDs on a UNIX system. The cut, sort and tail commands are all spawned as immediate children of the current julia process, with no intervening shell process. Julia itself does the work to setup pipes and connect file descriptors that is normally done by the shell. Since Julia does this itself, it retains better control and can do some things that shells cannot.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Julia can run multiple commands in parallel:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(`echo hello` & `echo world`);\nworld\nhello","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The order of the output here is non-deterministic because the two echo processes are started nearly simultaneously, and race to make the first write to the stdout descriptor they share with each other and the julia parent process. Julia lets you pipe the output from both of these processes to another program:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(pipeline(`echo world` & `echo hello`, `sort`));\nhello\nworld","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"In terms of UNIX plumbing, what's happening here is that a single UNIX pipe object is created and written to by both echo processes, and the other end of the pipe is read from by the sort command.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"IO redirection can be accomplished by passing keyword arguments stdin, stdout, and stderr to the pipeline function:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"pipeline(`do_work`, stdout=pipeline(`sort`, \"out.txt\"), stderr=\"errs.txt\")","category":"page"},{"location":"manual/running-external-programs/#Avoiding-Deadlock-in-Pipelines","page":"Running External Programs","title":"Avoiding Deadlock in Pipelines","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"When reading and writing to both ends of a pipeline from a single process, it is important to avoid forcing the kernel to buffer all of the data.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"For example, when reading all of the output from a command, call read(out, String), not wait(process), since the former will actively consume all of the data written by the process, whereas the latter will attempt to store the data in the kernel's buffers while waiting for a reader to be connected.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Another common solution is to separate the reader and writer of the pipeline into separate Tasks:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"writer = @async write(process, \"data\")\nreader = @async do_compute(read(process, String))\nwait(writer)\nfetch(reader)","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"(commonly also, reader is not a separate task, since we immediately fetch it anyways).","category":"page"},{"location":"manual/running-external-programs/#Complex-Example","page":"Running External Programs","title":"Complex Example","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The combination of a high-level programming language, a first-class command abstraction, and automatic setup of pipes between processes is a powerful one. To give some sense of the complex pipelines that can be created easily, here are some more sophisticated examples, with apologies for the excessive use of Perl one-liners:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> prefixer(prefix, sleep) = `perl -nle '$|=1; print \"'$prefix' \", $_; sleep '$sleep';'`;\n\njulia> run(pipeline(`perl -le '$|=1; for(0..5){ print; sleep 1 }'`, prefixer(\"A\",2) & prefixer(\"B\",2)));\nB 0\nA 1\nB 2\nA 3\nB 4\nA 5","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This is a classic example of a single producer feeding two concurrent consumers: one perl process generates lines with the numbers 0 through 5 on them, while two parallel processes consume that output, one prefixing lines with the letter \"A\", the other with the letter \"B\". Which consumer gets the first line is non-deterministic, but once that race has been won, the lines are consumed alternately by one process and then the other. (Setting $|=1 in Perl causes each print statement to flush the stdout handle, which is necessary for this example to work. Otherwise all the output is buffered and printed to the pipe at once, to be read by just one consumer process.)","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"Here is an even more complex multi-stage producer-consumer example:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(pipeline(`perl -le '$|=1; for(0..5){ print; sleep 1 }'`,\n prefixer(\"X\",3) & prefixer(\"Y\",3) & prefixer(\"Z\",3),\n prefixer(\"A\",2) & prefixer(\"B\",2)));\nA X 0\nB Y 1\nA Z 2\nB X 3\nA Y 4\nB Z 5","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This example is similar to the previous one, except there are two stages of consumers, and the stages have different latency so they use a different number of parallel workers, to maintain saturated throughput.","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"We strongly encourage you to try all these examples to see how they work.","category":"page"},{"location":"manual/running-external-programs/#Cmd-Objects","page":"Running External Programs","title":"Cmd Objects","text":"","category":"section"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"The backtick syntax create an object of type Cmd. Such object may also be constructed directly from an existing Cmd or list of arguments:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"run(Cmd(`pwd`, dir=\"..\"))\nrun(Cmd([\"pwd\"], detach=true, ignorestatus=true))","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"This allows you to specify several aspects of the Cmd's execution environment via keyword arguments. For example, the dir keyword provides control over the Cmd's working directory:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(Cmd(`pwd`, dir=\"/\"));\n/","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"And the env keyword allows you to set execution environment variables:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(Cmd(`sh -c \"echo foo \\$HOWLONG\"`, env=(\"HOWLONG\" => \"ever!\",)));\nfoo ever!","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"See Cmd for additional keyword arguments. The setenv and addenv commands provide another means for replacing or adding to the Cmd execution environment variables, respectively:","category":"page"},{"location":"manual/running-external-programs/","page":"Running External Programs","title":"Running External Programs","text":"julia> run(setenv(`sh -c \"echo foo \\$HOWLONG\"`, (\"HOWLONG\" => \"ever!\",)));\nfoo ever!\n\njulia> run(addenv(`sh -c \"echo foo \\$HOWLONG\"`, \"HOWLONG\" => \"ever!\"));\nfoo ever!","category":"page"},{"location":"manual/networking-and-streams/#Networking-and-Streams","page":"Networking and Streams","title":"Networking and Streams","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Julia provides a rich interface to deal with streaming I/O objects such as terminals, pipes and TCP sockets. These objects allow data to be sent and received in a stream-like fashion, which means that data is processed sequentially as it becomes available. This interface, though asynchronous at the system level, is presented in a synchronous manner to the programmer. This is achieved by making heavy use of Julia cooperative threading (coroutine) functionality.","category":"page"},{"location":"manual/networking-and-streams/#Basic-Stream-I/O","page":"Networking and Streams","title":"Basic Stream I/O","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"All Julia streams expose at least a read and a write method, taking the stream as their first argument, e.g.:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> write(stdout, \"Hello World\"); # suppress return value 11 with ;\nHello World\njulia> read(stdin, Char)\n\n'\\n': ASCII/Unicode U+000a (category Cc: Other, control)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that write returns 11, the number of bytes (in \"Hello World\") written to stdout, but this return value is suppressed with the ;.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Here Enter was pressed again so that Julia would read the newline. Now, as you can see from this example, write takes the data to write as its second argument, while read takes the type of the data to be read as the second argument.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"For example, to read a simple byte array, we could do:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> x = zeros(UInt8, 4)\n4-element Array{UInt8,1}:\n 0x00\n 0x00\n 0x00\n 0x00\n\njulia> read!(stdin, x)\nabcd\n4-element Array{UInt8,1}:\n 0x61\n 0x62\n 0x63\n 0x64","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"However, since this is slightly cumbersome, there are several convenience methods provided. For example, we could have written the above as:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> read(stdin, 4)\nabcd\n4-element Array{UInt8,1}:\n 0x61\n 0x62\n 0x63\n 0x64","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"or if we had wanted to read the entire line instead:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> readline(stdin)\nabcd\n\"abcd\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that depending on your terminal settings, your TTY (\"teletype terminal\") may be line buffered and might thus require an additional enter before stdin data is sent to Julia. When running Julia from the command line in a TTY, output is sent to the console by default, and standard input is read from the keyboard.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To read every line from stdin you can use eachline:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"for line in eachline(stdin)\n print(\"Found $line\")\nend","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"or read if you wanted to read by character instead:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"while !eof(stdin)\n x = read(stdin, Char)\n println(\"Found: $x\")\nend","category":"page"},{"location":"manual/networking-and-streams/#Text-I/O","page":"Networking and Streams","title":"Text I/O","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that the write method mentioned above operates on binary streams. In particular, values do not get converted to any canonical text representation but are written out as is:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> write(stdout, 0x61); # suppress return value 1 with ;\na","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that a is written to stdout by the write function and that the returned value is 1 (since 0x61 is one byte).","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"For text I/O, use the print or show methods, depending on your needs (see the documentation for these two methods for a detailed discussion of the difference between them):","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> print(stdout, 0x61)\n97","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"See Custom pretty-printing for more information on how to implement display methods for custom types.","category":"page"},{"location":"manual/networking-and-streams/#IO-Output-Contextual-Properties","page":"Networking and Streams","title":"IO Output Contextual Properties","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Sometimes IO output can benefit from the ability to pass contextual information into show methods. The IOContext object provides this framework for associating arbitrary metadata with an IO object. For example, :compact => true adds a hinting parameter to the IO object that the invoked show method should print a shorter output (if applicable). See the IOContext documentation for a list of common properties.","category":"page"},{"location":"manual/networking-and-streams/#Working-with-Files","page":"Networking and Streams","title":"Working with Files","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"You can write content to a file with the write(filename::String, content) method:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> write(\"hello.txt\", \"Hello, World!\")\n13","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"(13 is the number of bytes written.)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"You can read the contents of a file with the read(filename::String) method, or read(filename::String, String) to the contents as a string:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> read(\"hello.txt\", String)\n\"Hello, World!\"","category":"page"},{"location":"manual/networking-and-streams/#Advanced:-streaming-files","page":"Networking and Streams","title":"Advanced: streaming files","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"The read and write methods above allow you to read and write file contents. Like many other environments, Julia also has an open function, which takes a filename and returns an IOStream object that you can use to read and write things from the file. For example, if we have a file, hello.txt, whose contents are Hello, World!:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> f = open(\"hello.txt\")\nIOStream()\n\njulia> readlines(f)\n1-element Array{String,1}:\n \"Hello, World!\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"If you want to write to a file, you can open it with the write (\"w\") flag:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> f = open(\"hello.txt\",\"w\")\nIOStream()\n\njulia> write(f,\"Hello again.\")\n12","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"If you examine the contents of hello.txt at this point, you will notice that it is empty; nothing has actually been written to disk yet. This is because the IOStream must be closed before the write is actually flushed to disk:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> close(f)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Examining hello.txt again will show its contents have been changed.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Opening a file, doing something to its contents, and closing it again is a very common pattern. To make this easier, there exists another invocation of open which takes a function as its first argument and filename as its second, opens the file, calls the function with the file as an argument, and then closes it again. For example, given a function:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"function read_and_capitalize(f::IOStream)\n return uppercase(read(f, String))\nend","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"You can call:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> open(read_and_capitalize, \"hello.txt\")\n\"HELLO AGAIN.\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"to open hello.txt, call read_and_capitalize on it, close hello.txt and return the capitalized contents.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To avoid even having to define a named function, you can use the do syntax, which creates an anonymous function on the fly:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> open(\"hello.txt\") do f\n uppercase(read(f, String))\n end\n\"HELLO AGAIN.\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"If you want to redirect stdout to a file","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"out_file = open(\"output.txt\", \"w\")\n\n# Redirect stdout to file\nredirect_stdout(out_file) do\n # Your code here\n println(\"This output goes to `out_file` via the `stdout` variable.\")\nend\n\n# Close file\nclose(out_file)\n","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Redirecting stdout to a file can help you save and analyze program output, automate processes, and meet compliance requirements.","category":"page"},{"location":"manual/networking-and-streams/#A-simple-TCP-example","page":"Networking and Streams","title":"A simple TCP example","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Let's jump right in with a simple example involving TCP sockets. This functionality is in a standard library package called Sockets. Let's first create a simple server:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> using Sockets\n\njulia> errormonitor(@async begin\n server = listen(2000)\n while true\n sock = accept(server)\n println(\"Hello World\\n\")\n end\n end)\nTask (runnable) @0x00007fd31dc11ae0","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To those familiar with the Unix socket API, the method names will feel familiar, though their usage is somewhat simpler than the raw Unix socket API. The first call to listen will create a server waiting for incoming connections on the specified port (2000) in this case. The same function may also be used to create various other kinds of servers:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> listen(2000) # Listens on localhost:2000 (IPv4)\nSockets.TCPServer(active)\n\njulia> listen(ip\"127.0.0.1\",2000) # Equivalent to the first\nSockets.TCPServer(active)\n\njulia> listen(ip\"::1\",2000) # Listens on localhost:2000 (IPv6)\nSockets.TCPServer(active)\n\njulia> listen(IPv4(0),2001) # Listens on port 2001 on all IPv4 interfaces\nSockets.TCPServer(active)\n\njulia> listen(IPv6(0),2001) # Listens on port 2001 on all IPv6 interfaces\nSockets.TCPServer(active)\n\njulia> listen(\"testsocket\") # Listens on a UNIX domain socket\nSockets.PipeServer(active)\n\njulia> listen(\"\\\\\\\\.\\\\pipe\\\\testsocket\") # Listens on a Windows named pipe\nSockets.PipeServer(active)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Note that the return type of the last invocation is different. This is because this server does not listen on TCP, but rather on a named pipe (Windows) or UNIX domain socket. Also note that Windows named pipe format has to be a specific pattern such that the name prefix (\\\\.\\pipe\\) uniquely identifies the file type. The difference between TCP and named pipes or UNIX domain sockets is subtle and has to do with the accept and connect methods. The accept method retrieves a connection to the client that is connecting on the server we just created, while the connect function connects to a server using the specified method. The connect function takes the same arguments as listen, so, assuming the environment (i.e. host, cwd, etc.) is the same you should be able to pass the same arguments to connect as you did to listen to establish the connection. So let's try that out (after having created the server above):","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> connect(2000)\nTCPSocket(open, 0 bytes waiting)\n\njulia> Hello World","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"As expected we saw \"Hello World\" printed. So, let's actually analyze what happened behind the scenes. When we called connect, we connect to the server we had just created. Meanwhile, the accept function returns a server-side connection to the newly created socket and prints \"Hello World\" to indicate that the connection was successful.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"A great strength of Julia is that since the API is exposed synchronously even though the I/O is actually happening asynchronously, we didn't have to worry about callbacks or even making sure that the server gets to run. When we called connect the current task waited for the connection to be established and only continued executing after that was done. In this pause, the server task resumed execution (because a connection request was now available), accepted the connection, printed the message and waited for the next client. Reading and writing works in the same way. To see this, consider the following simple echo server:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> errormonitor(@async begin\n server = listen(2001)\n while true\n sock = accept(server)\n @async while isopen(sock)\n write(sock, readline(sock, keep=true))\n end\n end\n end)\nTask (runnable) @0x00007fd31dc12e60\n\njulia> clientside = connect(2001)\nTCPSocket(RawFD(28) open, 0 bytes waiting)\n\njulia> errormonitor(@async while isopen(clientside)\n write(stdout, readline(clientside, keep=true))\n end)\nTask (runnable) @0x00007fd31dc11870\n\njulia> println(clientside,\"Hello World from the Echo Server\")\nHello World from the Echo Server","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"As with other streams, use close to disconnect the socket:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> close(clientside)","category":"page"},{"location":"manual/networking-and-streams/#Resolving-IP-Addresses","page":"Networking and Streams","title":"Resolving IP Addresses","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"One of the connect methods that does not follow the listen methods is connect(host::String,port), which will attempt to connect to the host given by the host parameter on the port given by the port parameter. It allows you to do things like:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> connect(\"google.com\", 80)\nTCPSocket(RawFD(30) open, 0 bytes waiting)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"At the base of this functionality is getaddrinfo, which will do the appropriate address resolution:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> getaddrinfo(\"google.com\")\nip\"74.125.226.225\"","category":"page"},{"location":"manual/networking-and-streams/#Asynchronous-I/O","page":"Networking and Streams","title":"Asynchronous I/O","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"All I/O operations exposed by Base.read and Base.write can be performed asynchronously through the use of coroutines. You can create a new coroutine to read from or write to a stream using the @async macro:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> task = @async open(\"foo.txt\", \"w\") do io\n write(io, \"Hello, World!\")\n end;\n\njulia> wait(task)\n\njulia> readlines(\"foo.txt\")\n1-element Array{String,1}:\n \"Hello, World!\"","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"It's common to run into situations where you want to perform multiple asynchronous operations concurrently and wait until they've all completed. You can use the @sync macro to cause your program to block until all of the coroutines it wraps around have exited:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"julia> using Sockets\n\njulia> @sync for hostname in (\"google.com\", \"github.com\", \"julialang.org\")\n @async begin\n conn = connect(hostname, 80)\n write(conn, \"GET / HTTP/1.1\\r\\nHost:$(hostname)\\r\\n\\r\\n\")\n readline(conn, keep=true)\n println(\"Finished connection to $(hostname)\")\n end\n end\nFinished connection to google.com\nFinished connection to julialang.org\nFinished connection to github.com","category":"page"},{"location":"manual/networking-and-streams/#Multicast","page":"Networking and Streams","title":"Multicast","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Julia supports multicast over IPv4 and IPv6 using the User Datagram Protocol (UDP) as transport.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Unlike the Transmission Control Protocol (TCP), UDP makes almost no assumptions about the needs of the application. TCP provides flow control (it accelerates and decelerates to maximize throughput), reliability (lost or corrupt packets are automatically retransmitted), sequencing (packets are ordered by the operating system before they are given to the application), segment size, and session setup and teardown. UDP provides no such features.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"A common use for UDP is in multicast applications. TCP is a stateful protocol for communication between exactly two devices. UDP can use special multicast addresses to allow simultaneous communication between many devices.","category":"page"},{"location":"manual/networking-and-streams/#Receiving-IP-Multicast-Packets","page":"Networking and Streams","title":"Receiving IP Multicast Packets","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To transmit data over UDP multicast, simply recv on the socket, and the first packet received will be returned. Note that it may not be the first packet that you sent however!","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"using Sockets\ngroup = ip\"228.5.6.7\"\nsocket = Sockets.UDPSocket()\nbind(socket, ip\"0.0.0.0\", 6789)\njoin_multicast_group(socket, group)\nprintln(String(recv(socket)))\nleave_multicast_group(socket, group)\nclose(socket)","category":"page"},{"location":"manual/networking-and-streams/#Sending-IP-Multicast-Packets","page":"Networking and Streams","title":"Sending IP Multicast Packets","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"To transmit data over UDP multicast, simply send to the socket. Notice that it is not necessary for a sender to join the multicast group.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"using Sockets\ngroup = ip\"228.5.6.7\"\nsocket = Sockets.UDPSocket()\nsend(socket, group, 6789, \"Hello over IPv4\")\nclose(socket)","category":"page"},{"location":"manual/networking-and-streams/#IPv6-Example","page":"Networking and Streams","title":"IPv6 Example","text":"","category":"section"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"This example gives the same functionality as the previous program, but uses IPv6 as the network-layer protocol.","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Listener:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"using Sockets\ngroup = Sockets.IPv6(\"ff05::5:6:7\")\nsocket = Sockets.UDPSocket()\nbind(socket, Sockets.IPv6(\"::\"), 6789)\njoin_multicast_group(socket, group)\nprintln(String(recv(socket)))\nleave_multicast_group(socket, group)\nclose(socket)","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"Sender:","category":"page"},{"location":"manual/networking-and-streams/","page":"Networking and Streams","title":"Networking and Streams","text":"using Sockets\ngroup = Sockets.IPv6(\"ff05::5:6:7\")\nsocket = Sockets.UDPSocket()\nsend(socket, group, 6789, \"Hello over IPv6\")\nclose(socket)","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/REPL/docs/src/index.md\"","category":"page"},{"location":"stdlib/REPL/#The-Julia-REPL","page":"The Julia REPL","title":"The Julia REPL","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Julia comes with a full-featured interactive command-line REPL (read-eval-print loop) built into the julia executable. In addition to allowing quick and easy evaluation of Julia statements, it has a searchable history, tab-completion, many helpful keybindings, and dedicated help and shell modes. The REPL can be started by simply calling julia with no arguments or double-clicking on the executable:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"using REPL\nio = IOBuffer()\nREPL.banner(io)\nbanner = String(take!(io))\nimport Markdown\nMarkdown.parse(\"```\\n\\$ julia\\n\\n$(banner)\\njulia>\\n```\")","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"To exit the interactive session, type ^D – the control key together with the d key on a blank line – or type exit() followed by the return or enter key. The REPL greets you with a banner and a julia> prompt.","category":"page"},{"location":"stdlib/REPL/#The-different-prompt-modes","page":"The Julia REPL","title":"The different prompt modes","text":"","category":"section"},{"location":"stdlib/REPL/#The-Julian-mode","page":"The Julia REPL","title":"The Julian mode","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The REPL has five main modes of operation. The first and most common is the Julian prompt. It is the default mode of operation; each new line initially starts with julia>. It is here that you can enter Julia expressions. Hitting return or enter after a complete expression has been entered will evaluate the entry and show the result of the last expression.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> string(1 + 2)\n\"3\"","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"There are a number of useful features unique to interactive work. In addition to showing the result, the REPL also binds the result to the variable ans. A trailing semicolon on the line can be used as a flag to suppress showing the result.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> string(3 * 4);\n\njulia> ans\n\"12\"","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In Julia mode, the REPL supports something called prompt pasting. This activates when pasting text that starts with julia> into the REPL. In that case, only expressions starting with julia> (as well as the other REPL mode prompts: shell>, help?>, pkg> ) are parsed, but others are removed. This makes it possible to paste a chunk of text that has been copied from a REPL session without having to scrub away prompts and outputs. This feature is enabled by default but can be disabled or enabled at will with REPL.enable_promptpaste(::Bool). If it is enabled, you can try it out by pasting the code block above this paragraph straight into the REPL. This feature does not work on the standard Windows command prompt due to its limitation at detecting when a paste occurs.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Objects are printed at the REPL using the show function with a specific IOContext. In particular, the :limit attribute is set to true. Other attributes can receive in certain show methods a default value if it's not already set, like :compact. It's possible, as an experimental feature, to specify the attributes used by the REPL via the Base.active_repl.options.iocontext dictionary (associating values to attributes). For example:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> rand(2, 2)\n2×2 Array{Float64,2}:\n 0.8833 0.329197\n 0.719708 0.59114\n\njulia> show(IOContext(stdout, :compact => false), \"text/plain\", rand(2, 2))\n 0.43540323669187075 0.15759787870609387\n 0.2540832269192739 0.4597637838786053\njulia> Base.active_repl.options.iocontext[:compact] = false;\n\njulia> rand(2, 2)\n2×2 Array{Float64,2}:\n 0.2083967319174056 0.13330606013126012\n 0.6244375177790158 0.9777957560761545","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In order to define automatically the values of this dictionary at startup time, one can use the atreplinit function in the ~/.julia/config/startup.jl file, for example:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"atreplinit() do repl\n repl.options.iocontext[:compact] = false\nend","category":"page"},{"location":"stdlib/REPL/#Help-mode","page":"The Julia REPL","title":"Help mode","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"When the cursor is at the beginning of the line, the prompt can be changed to a help mode by typing ?. Julia will attempt to print help or documentation for anything entered in help mode:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ? # upon typing ?, the prompt changes (in place) to: help?>\n\nhelp?> string\nsearch: string String Cstring Cwstring RevString randstring bytestring SubString\n\n string(xs...)\n\n Create a string from any values using the print function.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Macros, types and variables can also be queried:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"help?> @time\n @time\n\n A macro to execute an expression, printing the time it took to execute, the number of allocations,\n and the total number of bytes its execution caused to be allocated, before returning the value of the\n expression.\n\n See also @timev, @timed, @elapsed, and @allocated.\n\nhelp?> Int32\nsearch: Int32 UInt32\n\n Int32 <: Signed\n\n 32-bit signed integer type.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"A string or regex literal searches all docstrings using apropos:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"help?> \"aprop\"\nREPL.stripmd\nBase.Docs.apropos\n\nhelp?> r\"ap..p\"\nBase.:∘\nBase.shell_escape_posixly\nDistributed.CachingPool\nREPL.stripmd\nBase.Docs.apropos","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Another feature of help mode is the ability to access extended docstrings. You can do this by typing something like ??Print rather than ?Print which will display the # Extended help section from the source codes documentation.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Help mode can be exited by pressing backspace at the beginning of the line.","category":"page"},{"location":"stdlib/REPL/#man-shell-mode","page":"The Julia REPL","title":"Shell mode","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Just as help mode is useful for quick access to documentation, another common task is to use the system shell to execute system commands. Just as ? entered help mode when at the beginning of the line, a semicolon (;) will enter the shell mode. And it can be exited by pressing backspace at the beginning of the line.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ; # upon typing ;, the prompt changes (in place) to: shell>\n\nshell> echo hello\nhello","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"note: Note\nFor Windows users, Julia's shell mode does not expose windows shell commands. Hence, this will fail:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ; # upon typing ;, the prompt changes (in place) to: shell>\n\nshell> dir\nERROR: IOError: could not spawn `dir`: no such file or directory (ENOENT)\nStacktrace!\n.......","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"However, you can get access to PowerShell like this:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ; # upon typing ;, the prompt changes (in place) to: shell>\n\nshell> powershell\nWindows PowerShell\nCopyright (C) Microsoft Corporation. All rights reserved.\nPS C:\\Users\\elm>","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"... and to cmd.exe like that (see the dir command):","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> ; # upon typing ;, the prompt changes (in place) to: shell>\n\nshell> cmd\nMicrosoft Windows [version 10.0.17763.973]\n(c) 2018 Microsoft Corporation. All rights reserved.\nC:\\Users\\elm>dir\n Volume in drive C has no label\n Volume Serial Number is 1643-0CD7\n Directory of C:\\Users\\elm\n\n29/01/2020 22:15 .\n29/01/2020 22:15 ..\n02/02/2020 08:06 .atom","category":"page"},{"location":"stdlib/REPL/#Pkg-mode","page":"The Julia REPL","title":"Pkg mode","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The Package manager mode accepts specialized commands for loading and updating packages. It is entered by pressing the ] key at the Julian REPL prompt and exited by pressing CTRL-C or pressing the backspace key at the beginning of the line. The prompt for this mode is pkg>. It supports its own help-mode, which is entered by pressing ? at the beginning of the line of the pkg> prompt. The Package manager mode is documented in the Pkg manual, available at https://julialang.github.io/Pkg.jl/v1/.","category":"page"},{"location":"stdlib/REPL/#Search-modes","page":"The Julia REPL","title":"Search modes","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In all of the above modes, the executed lines get saved to a history file, which can be searched. To initiate an incremental search through the previous history, type ^R – the control key together with the r key. The prompt will change to (reverse-i-search)`':, and as you type the search query will appear in the quotes. The most recent result that matches the query will dynamically update to the right of the colon as more is typed. To find an older result using the same query, simply type ^R again.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Just as ^R is a reverse search, ^S is a forward search, with the prompt (i-search)`':. The two may be used in conjunction with each other to move through the previous or next matching results, respectively.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"All executed commands in the Julia REPL are logged into ~/.julia/logs/repl_history.jl along with a timestamp of when it was executed and the current REPL mode you were in. Search mode queries this log file in order to find the commands which you previously ran. This can be disabled at startup by passing the --history-file=no flag to Julia.","category":"page"},{"location":"stdlib/REPL/#Key-bindings","page":"The Julia REPL","title":"Key bindings","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The Julia REPL makes great use of key bindings. Several control-key bindings were already introduced above (^D to exit, ^R and ^S for searching), but there are many more. In addition to the control-key, there are also meta-key bindings. These vary more by platform, but most terminals default to using alt- or option- held down with a key to send the meta-key (or can be configured to do so), or pressing Esc and then the key.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Keybinding Description\nProgram control \n^D Exit (when buffer is empty)\n^C Interrupt or cancel\n^L Clear console screen\nReturn/Enter, ^J New line, executing if it is complete\nmeta-Return/Enter Insert new line without executing it\n? or ; Enter help or shell mode (when at start of a line)\n^R, ^S Incremental history search, described above\nCursor movement \nRight arrow, ^F Move right one character\nLeft arrow, ^B Move left one character\nctrl-Right, meta-F Move right one word\nctrl-Left, meta-B Move left one word\nHome, ^A Move to beginning of line\nEnd, ^E Move to end of line\nUp arrow, ^P Move up one line (or change to the previous history entry that matches the text before the cursor)\nDown arrow, ^N Move down one line (or change to the next history entry that matches the text before the cursor)\nShift-Arrow Key Move cursor according to the direction of the Arrow key, while activating the region (\"shift selection\")\nPage-up, meta-P Change to the previous history entry\nPage-down, meta-N Change to the next history entry\nmeta-< Change to the first history entry (of the current session if it is before the current position in history)\nmeta-> Change to the last history entry\n^-Space Set the \"mark\" in the editing region (and de-activate the region if it's active)\n^-Space ^-Space Set the \"mark\" in the editing region and make the region \"active\", i.e. highlighted\n^G De-activate the region (i.e. make it not highlighted)\n^X^X Exchange the current position with the mark\nEditing \nBackspace, ^H Delete the previous character, or the whole region when it's active\nDelete, ^D Forward delete one character (when buffer has text)\nmeta-Backspace Delete the previous word\nmeta-d Forward delete the next word\n^W Delete previous text up to the nearest whitespace\nmeta-w Copy the current region in the kill ring\nmeta-W \"Kill\" the current region, placing the text in the kill ring\n^U \"Kill\" to beginning of line, placing the text in the kill ring\n^K \"Kill\" to end of line, placing the text in the kill ring\n^Y \"Yank\" insert the text from the kill ring\nmeta-y Replace a previously yanked text with an older entry from the kill ring\n^T Transpose the characters about the cursor\nmeta-Up arrow Transpose current line with line above\nmeta-Down arrow Transpose current line with line below\nmeta-u Change the next word to uppercase\nmeta-c Change the next word to titlecase\nmeta-l Change the next word to lowercase\n^/, ^_ Undo previous editing action\n^Q Write a number in REPL and press ^Q to open editor at corresponding stackframe or method\nmeta-Left Arrow Indent the current line on the left\nmeta-Right Arrow Indent the current line on the right\nmeta-. Insert last word from previous history entry\nmeta-e Edit the current input in an editor","category":"page"},{"location":"stdlib/REPL/#Customizing-keybindings","page":"The Julia REPL","title":"Customizing keybindings","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Julia's REPL keybindings may be fully customized to a user's preferences by passing a dictionary to REPL.setup_interface. The keys of this dictionary may be characters or strings. The key '*' refers to the default action. Control plus character x bindings are indicated with \"^x\". Meta plus x can be written \"\\\\M-x\" or \"\\ex\", and Control plus x can be written \"\\\\C-x\" or \"^x\". The values of the custom keymap must be nothing (indicating that the input should be ignored) or functions that accept the signature (PromptState, AbstractREPL, Char). The REPL.setup_interface function must be called before the REPL is initialized, by registering the operation with atreplinit . For example, to bind the up and down arrow keys to move through history without prefix search, one could put the following code in ~/.julia/config/startup.jl:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"import REPL\nimport REPL.LineEdit\n\nconst mykeys = Dict{Any,Any}(\n # Up Arrow\n \"\\e[A\" => (s,o...)->(LineEdit.edit_move_up(s) || LineEdit.history_prev(s, LineEdit.mode(s).hist)),\n # Down Arrow\n \"\\e[B\" => (s,o...)->(LineEdit.edit_move_down(s) || LineEdit.history_next(s, LineEdit.mode(s).hist))\n)\n\nfunction customize_keys(repl)\n repl.interface = REPL.setup_interface(repl; extra_repl_keymap = mykeys)\nend\n\natreplinit(customize_keys)","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Users should refer to LineEdit.jl to discover the available actions on key input.","category":"page"},{"location":"stdlib/REPL/#Tab-completion","page":"The Julia REPL","title":"Tab completion","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In the Julian, pkg and help modes of the REPL, one can enter the first few characters of a function or type and then press the tab key to get a list all matches:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> x[TAB]\njulia> xor","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In some cases it only completes part of the name, up to the next ambiguity:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> mapf[TAB]\njulia> mapfold","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"If you hit tab again, then you get the list of things that might complete this:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> mapfold[TAB]\nmapfoldl mapfoldr","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"When a single complete tab-complete result is available at the end of an input line and 2 or more characters have been typed, a hint of the completion will show in a lighter color. This can be disabled via Base.active_repl.options.hint_tab_completes = false.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"compat: Julia 1.11\nTab-complete hinting was added in Julia 1.11","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Like other components of the REPL, the search is case-sensitive:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> stri[TAB]\nstride strides string strip\n\njulia> Stri[TAB]\nStridedArray StridedMatrix StridedVecOrMat StridedVector String","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The tab key can also be used to substitute LaTeX math symbols with their Unicode equivalents, and get a list of LaTeX matches as well:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> \\pi[TAB]\njulia> π\nπ = 3.1415926535897...\n\njulia> e\\_1[TAB] = [1,0]\njulia> e₁ = [1,0]\n2-element Array{Int64,1}:\n 1\n 0\n\njulia> e\\^1[TAB] = [1 0]\njulia> e¹ = [1 0]\n1×2 Array{Int64,2}:\n 1 0\n\njulia> \\sqrt[TAB]2 # √ is equivalent to the sqrt function\njulia> √2\n1.4142135623730951\n\njulia> \\hbar[TAB](h) = h / 2\\pi[TAB]\njulia> ħ(h) = h / 2π\nħ (generic function with 1 method)\n\njulia> \\h[TAB]\n\\hat \\hermitconjmatrix \\hkswarow \\hrectangle\n\\hatapprox \\hexagon \\hookleftarrow \\hrectangleblack\n\\hbar \\hexagonblack \\hookrightarrow \\hslash\n\\heartsuit \\hksearow \\house \\hspace\n\njulia> α=\"\\alpha[TAB]\" # LaTeX completion also works in strings\njulia> α=\"α\"","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"A full list of tab-completions can be found in the Unicode Input section of the manual.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Completion of paths works for strings and julia's shell mode:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> path=\"/[TAB]\"\n.dockerenv .juliabox/ boot/ etc/ lib/ media/ opt/ root/ sbin/ sys/ usr/\n.dockerinit bin/ dev/ home/ lib64/ mnt/ proc/ run/ srv/ tmp/ var/\nshell> /[TAB]\n.dockerenv .juliabox/ boot/ etc/ lib/ media/ opt/ root/ sbin/ sys/ usr/\n.dockerinit bin/ dev/ home/ lib64/ mnt/ proc/ run/ srv/ tmp/ var/","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Dictionary keys can also be tab completed:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> foo = Dict(\"qwer1\"=>1, \"qwer2\"=>2, \"asdf\"=>3)\nDict{String,Int64} with 3 entries:\n \"qwer2\" => 2\n \"asdf\" => 3\n \"qwer1\" => 1\n\njulia> foo[\"q[TAB]\n\n\"qwer1\" \"qwer2\"\njulia> foo[\"qwer","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Tab completion can also help completing fields:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> x = 3 + 4im;\n\njulia> x.[TAB][TAB]\nim re\n\njulia> import UUIDs\n\njulia> UUIDs.uuid[TAB][TAB]\nuuid1 uuid4 uuid5 uuid_version","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Fields for output from functions can also be completed:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> split(\"\",\"\")[1].[TAB]\nlastindex offset string","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The completion of fields for output from functions uses type inference, and it can only suggest fields if the function is type stable.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Tab completion can help with investigation of the available methods matching the input arguments:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> max([TAB] # All methods are displayed, not shown here due to size of the list\n\njulia> max([1, 2], [TAB] # All methods where `Vector{Int}` matches as first argument\nmax(x, y) in Base at operators.jl:215\nmax(a, b, c, xs...) in Base at operators.jl:281\n\njulia> max([1, 2], max(1, 2), [TAB] # All methods matching the arguments.\nmax(x, y) in Base at operators.jl:215\nmax(a, b, c, xs...) in Base at operators.jl:281","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Keywords are also displayed in the suggested methods after ;, see below line where limit and keepempty are keyword arguments:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> split(\"1 1 1\", [TAB]\nsplit(str::AbstractString; limit, keepempty) in Base at strings/util.jl:302\nsplit(str::T, splitter; limit, keepempty) where T<:AbstractString in Base at strings/util.jl:277","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The completion of the methods uses type inference and can therefore see if the arguments match even if the arguments are output from functions. The function needs to be type stable for the completion to be able to remove non-matching methods.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"If you wonder which methods can be used with particular argument types, use ? as the function name. This shows an example of looking for functions in InteractiveUtils that accept a single string:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> InteractiveUtils.?(\"somefile\")[TAB]\nedit(path::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:197\nless(file::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:266","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"This listed methods in the InteractiveUtils module that can be called on a string. By default, this excludes methods where all arguments are typed as Any, but you can see those too by holding down SHIFT-TAB instead of TAB:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> InteractiveUtils.?(\"somefile\")[SHIFT-TAB]\napropos(string) in REPL at REPL/src/docview.jl:796\nclipboard(x) in InteractiveUtils at InteractiveUtils/src/clipboard.jl:64\ncode_llvm(f) in InteractiveUtils at InteractiveUtils/src/codeview.jl:221\ncode_native(f) in InteractiveUtils at InteractiveUtils/src/codeview.jl:243\nedit(path::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:197\nedit(f) in InteractiveUtils at InteractiveUtils/src/editless.jl:225\neval(x) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:3\ninclude(x) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:3\nless(file::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:266\nless(f) in InteractiveUtils at InteractiveUtils/src/editless.jl:274\nreport_bug(kind) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:391\nseparate_kwargs(args...; kwargs...) in InteractiveUtils at InteractiveUtils/src/macros.jl:7","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"You can also use ?(\"somefile\")[TAB] and look across all modules, but the method lists can be long.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"By omitting the closing parenthesis, you can include functions that might require additional arguments:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> using Mmap\n\nhelp?> Mmap.?(\"file\",[TAB]\nMmap.Anonymous(name::String, readonly::Bool, create::Bool) in Mmap at Mmap/src/Mmap.jl:16\nmmap(file::AbstractString) in Mmap at Mmap/src/Mmap.jl:245\nmmap(file::AbstractString, ::Type{T}) where T<:Array in Mmap at Mmap/src/Mmap.jl:245\nmmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}) where {T<:Array, N} in Mmap at Mmap/src/Mmap.jl:245\nmmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}, offset::Integer; grow, shared) where {T<:Array, N} in Mmap at Mmap/src/Mmap.jl:245\nmmap(file::AbstractString, ::Type{T}, len::Integer) where T<:Array in Mmap at Mmap/src/Mmap.jl:251\nmmap(file::AbstractString, ::Type{T}, len::Integer, offset::Integer; grow, shared) where T<:Array in Mmap at Mmap/src/Mmap.jl:251\nmmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}) where {T<:BitArray, N} in Mmap at Mmap/src/Mmap.jl:316\nmmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}, offset::Integer; grow, shared) where {T<:BitArray, N} in Mmap at Mmap/src/Mmap.jl:316\nmmap(file::AbstractString, ::Type{T}, len::Integer) where T<:BitArray in Mmap at Mmap/src/Mmap.jl:322\nmmap(file::AbstractString, ::Type{T}, len::Integer, offset::Integer; grow, shared) where T<:BitArray in Mmap at Mmap/src/Mmap.jl:322","category":"page"},{"location":"stdlib/REPL/#Customizing-Colors","page":"The Julia REPL","title":"Customizing Colors","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The colors used by Julia and the REPL can be customized, as well. To change the color of the Julia prompt you can add something like the following to your ~/.julia/config/startup.jl file, which is to be placed inside your home directory:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"function customize_colors(repl)\n repl.prompt_color = Base.text_colors[:cyan]\nend\n\natreplinit(customize_colors)","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The available color keys can be seen by typing Base.text_colors in the help mode of the REPL. In addition, the integers 0 to 255 can be used as color keys for terminals with 256 color support.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"You can also change the colors for the help and shell prompts and input and answer text by setting the appropriate field of repl in the customize_colors function above (respectively, help_color, shell_color, input_color, and answer_color). For the latter two, be sure that the envcolors field is also set to false.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"It is also possible to apply boldface formatting by using Base.text_colors[:bold] as a color. For instance, to print answers in boldface font, one can use the following as a ~/.julia/config/startup.jl:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"function customize_colors(repl)\n repl.envcolors = false\n repl.answer_color = Base.text_colors[:bold]\nend\n\natreplinit(customize_colors)","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"You can also customize the color used to render warning and informational messages by setting the appropriate environment variables. For instance, to render error, warning, and informational messages respectively in magenta, yellow, and cyan you can add the following to your ~/.julia/config/startup.jl file:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"ENV[\"JULIA_ERROR_COLOR\"] = :magenta\nENV[\"JULIA_WARN_COLOR\"] = :yellow\nENV[\"JULIA_INFO_COLOR\"] = :cyan","category":"page"},{"location":"stdlib/REPL/#Changing-the-contextual-module-which-is-active-at-the-REPL","page":"The Julia REPL","title":"Changing the contextual module which is active at the REPL","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"When entering expressions at the REPL, they are by default evaluated in the Main module;","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> @__MODULE__\nMain","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"It is possible to change this contextual module via the function REPL.activate(m) where m is a Module or by typing the module in the REPL and pressing the keybinding Alt-m with the cursor on the module name (Esc-m on MacOS). Pressing the keybinding on an empty prompt toggles the context between the previously active non-Main module and Main. The active module is shown in the prompt (unless it is Main):","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> using REPL\n\njulia> REPL.activate(Base)\n\n(Base) julia> @__MODULE__\nBase\n\n(Base) julia> using REPL # Need to load REPL into Base module to use it\n\n(Base) julia> REPL.activate(Main)\n\njulia>\n\njulia> Core # using the keybinding to change module\n\n(Core) julia>\n\n(Core) julia> # going back to Main via keybinding\n\njulia>\n\njulia> # going back to previously-active Core via keybinding\n\n(Core) julia>","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Functions that take an optional module argument often defaults to the REPL context module. As an example, calling varinfo() will show the variables of the current active module:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> module CustomMod\n export var, f\n var = 1\n f(x) = x^2\n end;\n\njulia> REPL.activate(CustomMod)\n\n(Main.CustomMod) julia> varinfo()\n name size summary\n ––––––––– ––––––– ––––––––––––––––––––––––––––––––––\n CustomMod Module\n f 0 bytes f (generic function with 1 method)\n var 8 bytes Int64","category":"page"},{"location":"stdlib/REPL/#Numbered-prompt","page":"The Julia REPL","title":"Numbered prompt","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"It is possible to get an interface which is similar to the IPython REPL and the Mathematica notebook with numbered input prompts and output prefixes. This is done by calling REPL.numbered_prompt!(). If you want to have this enabled on startup, add","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"atreplinit() do repl\n @eval import REPL\n if !isdefined(repl, :interface)\n repl.interface = REPL.setup_interface(repl)\n end\n REPL.numbered_prompt!(repl)\nend","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"to your startup.jl file. In numbered prompt the variable Out[n] (where n is an integer) can be used to refer to earlier results:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"In [1]: 5 + 3\nOut[1]: 8\n\nIn [2]: Out[1] + 5\nOut[2]: 13\n\nIn [3]: Out\nOut[3]: Dict{Int64, Any} with 2 entries:\n 2 => 13\n 1 => 8","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"note: Note\nSince all outputs from previous REPL evaluations are saved in the Out variable, one should be careful if they are returning many large in-memory objects like arrays, since they will be protected from garbage collection so long as a reference to them remains in Out. If you need to remove references to objects in Out, you can clear the entire history it stores with empty!(Out), or clear an individual entry with Out[n] = nothing.","category":"page"},{"location":"stdlib/REPL/#TerminalMenus","page":"The Julia REPL","title":"TerminalMenus","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"TerminalMenus is a submodule of the Julia REPL and enables small, low-profile interactive menus in the terminal.","category":"page"},{"location":"stdlib/REPL/#Examples","page":"The Julia REPL","title":"Examples","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"import REPL\nusing REPL.TerminalMenus\n\noptions = [\"apple\", \"orange\", \"grape\", \"strawberry\",\n \"blueberry\", \"peach\", \"lemon\", \"lime\"]\n","category":"page"},{"location":"stdlib/REPL/#RadioMenu","page":"The Julia REPL","title":"RadioMenu","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The RadioMenu allows the user to select one option from the list. The request function displays the interactive menu and returns the index of the selected choice. If a user presses 'q' or ctrl-c, request will return a -1.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"# `pagesize` is the number of items to be displayed at a time.\n# The UI will scroll if the number of options is greater\n# than the `pagesize`\nmenu = RadioMenu(options, pagesize=4)\n\n# `request` displays the menu and returns the index after the\n# user has selected a choice\nchoice = request(\"Choose your favorite fruit:\", menu)\n\nif choice != -1\n println(\"Your favorite fruit is \", options[choice], \"!\")\nelse\n println(\"Menu canceled.\")\nend\n","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Output:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Choose your favorite fruit:\n^ grape\n strawberry\n > blueberry\nv peach\nYour favorite fruit is blueberry!","category":"page"},{"location":"stdlib/REPL/#MultiSelectMenu","page":"The Julia REPL","title":"MultiSelectMenu","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The MultiSelectMenu allows users to select many choices from a list.","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"# here we use the default `pagesize` 10\nmenu = MultiSelectMenu(options)\n\n# `request` returns a `Set` of selected indices\n# if the menu us canceled (ctrl-c or q), return an empty set\nchoices = request(\"Select the fruits you like:\", menu)\n\nif length(choices) > 0\n println(\"You like the following fruits:\")\n for i in choices\n println(\" - \", options[i])\n end\nelse\n println(\"Menu canceled.\")\nend","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Output:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Select the fruits you like:\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n [ ] apple\n > [X] orange\n [X] grape\n [ ] strawberry\n [ ] blueberry\n [X] peach\n [ ] lemon\n [ ] lime\nYou like the following fruits:\n - orange\n - grape\n - peach","category":"page"},{"location":"stdlib/REPL/#Customization-/-Configuration","page":"The Julia REPL","title":"Customization / Configuration","text":"","category":"section"},{"location":"stdlib/REPL/#ConfiguredMenu-subtypes","page":"The Julia REPL","title":"ConfiguredMenu subtypes","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Starting with Julia 1.6, the recommended way to configure menus is via the constructor. For instance, the default multiple-selection menu","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> menu = MultiSelectMenu(options, pagesize=5);\n\njulia> request(menu) # ASCII is used by default\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n [ ] apple\n [X] orange\n [ ] grape\n > [X] strawberry\nv [ ] blueberry","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"can instead be rendered with Unicode selection and navigation characters with","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> menu = MultiSelectMenu(options, pagesize=5, charset=:unicode);\n\njulia> request(menu)\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n ⬚ apple\n ✓ orange\n ⬚ grape\n → ✓ strawberry\n↓ ⬚ blueberry","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"More fine-grained configuration is also possible:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"julia> menu = MultiSelectMenu(options, pagesize=5, charset=:unicode, checked=\"YEP!\", unchecked=\"NOPE\", cursor='⧐');\n\njulia> request(menu)\njulia> request(menu)\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n NOPE apple\n YEP! orange\n NOPE grape\n ⧐ YEP! strawberry\n↓ NOPE blueberry","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Aside from the overall charset option, for RadioMenu the configurable options are:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"cursor::Char='>'|'→': character to use for cursor\nup_arrow::Char='^'|'↑': character to use for up arrow\ndown_arrow::Char='v'|'↓': character to use for down arrow\nupdown_arrow::Char='I'|'↕': character to use for up/down arrow in one-line page\nscroll_wrap::Bool=false: optionally wrap-around at the beginning/end of a menu\nctrl_c_interrupt::Bool=true: If false, return empty on ^C, if true throw InterruptException() on ^C","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"MultiSelectMenu adds:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"checked::String=\"[X]\"|\"✓\": string to use for checked\nunchecked::String=\"[ ]\"|\"⬚\"): string to use for unchecked","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"You can create new menu types of your own. Types that are derived from TerminalMenus.ConfiguredMenu configure the menu options at construction time.","category":"page"},{"location":"stdlib/REPL/#Legacy-interface","page":"The Julia REPL","title":"Legacy interface","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Prior to Julia 1.6, and still supported throughout Julia 1.x, one can also configure menus by calling TerminalMenus.config().","category":"page"},{"location":"stdlib/REPL/#References","page":"The Julia REPL","title":"References","text":"","category":"section"},{"location":"stdlib/REPL/#REPL","page":"The Julia REPL","title":"REPL","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Base.atreplinit","category":"page"},{"location":"stdlib/REPL/#Base.atreplinit","page":"The Julia REPL","title":"Base.atreplinit","text":"atreplinit(f)\n\nRegister a one-argument function to be called before the REPL interface is initialized in interactive sessions; this is useful to customize the interface. The argument of f is the REPL object. This function should be called from within the .julia/config/startup.jl initialization file.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#TerminalMenus-2","page":"The Julia REPL","title":"TerminalMenus","text":"","category":"section"},{"location":"stdlib/REPL/#Menus","page":"The Julia REPL","title":"Menus","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.RadioMenu\nREPL.TerminalMenus.MultiSelectMenu","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.RadioMenu","page":"The Julia REPL","title":"REPL.TerminalMenus.RadioMenu","text":"RadioMenu\n\nA menu that allows a user to select a single option from a list.\n\nSample Output\n\njulia> request(RadioMenu(options, pagesize=4))\nChoose your favorite fruit:\n^ grape\n strawberry\n > blueberry\nv peach\nYour favorite fruit is blueberry!\n\n\n\n\n\n","category":"type"},{"location":"stdlib/REPL/#REPL.TerminalMenus.MultiSelectMenu","page":"The Julia REPL","title":"REPL.TerminalMenus.MultiSelectMenu","text":"MultiSelectMenu\n\nA menu that allows a user to select a multiple options from a list.\n\nSample Output\n\njulia> request(MultiSelectMenu(options))\nSelect the fruits you like:\n[press: Enter=toggle, a=all, n=none, d=done, q=abort]\n [ ] apple\n > [X] orange\n [X] grape\n [ ] strawberry\n [ ] blueberry\n [X] peach\n [ ] lemon\n [ ] lime\nYou like the following fruits:\n - orange\n - grape\n - peach\n\n\n\n\n\n","category":"type"},{"location":"stdlib/REPL/#Configuration","page":"The Julia REPL","title":"Configuration","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.Config\nREPL.TerminalMenus.MultiSelectConfig\nREPL.TerminalMenus.config","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.Config","page":"The Julia REPL","title":"REPL.TerminalMenus.Config","text":"Config(; scroll_wrap=false, ctrl_c_interrupt=true, charset=:ascii, cursor::Char, up_arrow::Char, down_arrow::Char)\n\nConfigure behavior for selection menus via keyword arguments:\n\nscroll_wrap, if true, causes the menu to wrap around when scrolling above the first or below the last entry\nctrl_c_interrupt, if true, throws an InterruptException if the user hits Ctrl-C during menu selection. If false, TerminalMenus.request will return the default result from TerminalMenus.selected.\ncharset affects the default values for cursor, up_arrow, and down_arrow, and can be :ascii or :unicode\ncursor is the character printed to indicate the option that will be chosen by hitting \"Enter.\" Defaults are '>' or '→', depending on charset.\nup_arrow is the character printed when the display does not include the first entry. Defaults are '^' or '↑', depending on charset.\ndown_arrow is the character printed when the display does not include the last entry. Defaults are 'v' or '↓', depending on charset.\n\nSubtypes of ConfiguredMenu will print cursor, up_arrow, and down_arrow automatically as needed, your writeline method should not print them.\n\ncompat: Julia 1.6\nConfig is available as of Julia 1.6. On older releases use the global CONFIG.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/REPL/#REPL.TerminalMenus.MultiSelectConfig","page":"The Julia REPL","title":"REPL.TerminalMenus.MultiSelectConfig","text":"MultiSelectConfig(; charset=:ascii, checked::String, unchecked::String, kwargs...)\n\nConfigure behavior for a multiple-selection menu via keyword arguments:\n\nchecked is the string to print when an option has been selected. Defaults are \"[X]\" or \"✓\", depending on charset.\nunchecked is the string to print when an option has not been selected. Defaults are \"[ ]\" or \"⬚\", depending on charset.\n\nAll other keyword arguments are as described for TerminalMenus.Config. checked and unchecked are not printed automatically, and should be printed by your writeline method.\n\ncompat: Julia 1.6\nMultiSelectConfig is available as of Julia 1.6. On older releases use the global CONFIG.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/REPL/#REPL.TerminalMenus.config","page":"The Julia REPL","title":"REPL.TerminalMenus.config","text":"config( )\n\nKeyword-only function to configure global menu parameters\n\nArguments\n\ncharset::Symbol=:na: ui characters to use (:ascii or :unicode); overridden by other arguments\ncursor::Char='>'|'→': character to use for cursor\nup_arrow::Char='^'|'↑': character to use for up arrow\ndown_arrow::Char='v'|'↓': character to use for down arrow\nchecked::String=\"[X]\"|\"✓\": string to use for checked\nunchecked::String=\"[ ]\"|\"⬚\"): string to use for unchecked\nscroll::Symbol=:nowrap: If :wrap wrap cursor around top and bottom, if :nowrap do not wrap cursor\nsupress_output::Bool=false: Ignored legacy argument, pass suppress_output as a keyword argument to request instead.\nctrl_c_interrupt::Bool=true: If false, return empty on ^C, if true throw InterruptException() on ^C\n\ncompat: Julia 1.6\nAs of Julia 1.6, config is deprecated. Use Config or MultiSelectConfig instead.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#User-interaction","page":"The Julia REPL","title":"User interaction","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.request","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.request","page":"The Julia REPL","title":"REPL.TerminalMenus.request","text":"request(m::AbstractMenu; cursor=1)\n\nDisplay the menu and enter interactive mode. cursor indicates the item number used for the initial cursor position. cursor can be either an Int or a RefValue{Int}. The latter is useful for observation and control of the cursor position from the outside.\n\nReturns selected(m).\n\ncompat: Julia 1.6\nThe cursor argument requires Julia 1.6 or later.\n\n\n\n\n\nrequest([term,] msg::AbstractString, m::AbstractMenu)\n\nShorthand for println(msg); request(m).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#AbstractMenu-extension-interface","page":"The Julia REPL","title":"AbstractMenu extension interface","text":"","category":"section"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"Any subtype of AbstractMenu must be mutable, and must contain the fields pagesize::Int and pageoffset::Int. Any subtype must also implement the following functions:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.pick\nREPL.TerminalMenus.cancel\nREPL.TerminalMenus.writeline","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.pick","page":"The Julia REPL","title":"REPL.TerminalMenus.pick","text":"pick(m::AbstractMenu, cursor::Int)\n\nDefines what happens when a user presses the Enter key while the menu is open. If true is returned, request() will exit. cursor indexes the position of the selection.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#REPL.TerminalMenus.cancel","page":"The Julia REPL","title":"REPL.TerminalMenus.cancel","text":"cancel(m::AbstractMenu)\n\nDefine what happens when a user cancels ('q' or ctrl-c) a menu. request() will always exit after calling this function.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#REPL.TerminalMenus.writeline","page":"The Julia REPL","title":"REPL.TerminalMenus.writeline","text":"writeline(buf::IO, m::AbstractMenu, idx::Int, iscursor::Bool)\n\nWrite the option at index idx to buf. iscursor, if true, indicates that this item is at the current cursor position (the one that will be selected by hitting \"Enter\").\n\nIf m is a ConfiguredMenu, TerminalMenus will print the cursor indicator. Otherwise the callee is expected to handle such printing.\n\ncompat: Julia 1.6\nwriteline requires Julia 1.6 or higher.On older versions of Julia, this was writeLine(buf::IO, m::AbstractMenu, idx, iscursor::Bool) and m is assumed to be unconfigured. The selection and cursor indicators can be obtained from TerminalMenus.CONFIG.This older function is supported on all Julia 1.x versions but will be dropped in Julia 2.0.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"It must also implement either options or numoptions:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.options\nREPL.TerminalMenus.numoptions","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.options","page":"The Julia REPL","title":"REPL.TerminalMenus.options","text":"options(m::AbstractMenu)\n\nReturn a list of strings to be displayed as options in the current page.\n\nAlternatively, implement numoptions, in which case options is not needed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#REPL.TerminalMenus.numoptions","page":"The Julia REPL","title":"REPL.TerminalMenus.numoptions","text":"numoptions(m::AbstractMenu) -> Int\n\nReturn the number of options in menu m. Defaults to length(options(m)).\n\ncompat: Julia 1.6\nThis function requires Julia 1.6 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"If the subtype does not have a field named selected, it must also implement","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.selected","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.selected","page":"The Julia REPL","title":"REPL.TerminalMenus.selected","text":"selected(m::AbstractMenu)\n\nReturn information about the user-selected option. By default it returns m.selected.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"The following are optional but can allow additional customization:","category":"page"},{"location":"stdlib/REPL/","page":"The Julia REPL","title":"The Julia REPL","text":"REPL.TerminalMenus.header\nREPL.TerminalMenus.keypress","category":"page"},{"location":"stdlib/REPL/#REPL.TerminalMenus.header","page":"The Julia REPL","title":"REPL.TerminalMenus.header","text":"header(m::AbstractMenu) -> String\n\nReturn a header string to be printed above the menu. Defaults to \"\".\n\n\n\n\n\n","category":"function"},{"location":"stdlib/REPL/#REPL.TerminalMenus.keypress","page":"The Julia REPL","title":"REPL.TerminalMenus.keypress","text":"keypress(m::AbstractMenu, i::UInt32) -> Bool\n\nHandle any non-standard keypress event. If true is returned, TerminalMenus.request will exit. Defaults to false.\n\n\n\n\n\n","category":"function"},{"location":"base/stacktraces/#StackTraces","page":"StackTraces","title":"StackTraces","text":"","category":"section"},{"location":"base/stacktraces/","page":"StackTraces","title":"StackTraces","text":"Base.StackTraces.StackFrame\nBase.StackTraces.StackTrace\nBase.StackTraces.stacktrace","category":"page"},{"location":"base/stacktraces/#Base.StackTraces.StackFrame","page":"StackTraces","title":"Base.StackTraces.StackFrame","text":"StackFrame\n\nStack information representing execution context, with the following fields:\n\nfunc::Symbol\nThe name of the function containing the execution context.\nlinfo::Union{Method, Core.MethodInstance, Core.CodeInfo, Nothing}\nThe Method, MethodInstance, or CodeInfo containing the execution context (if it could be found), or nothing (for example, if the inlining was a result of macro expansion).\nfile::Symbol\nThe path to the file containing the execution context.\nline::Int\nThe line number in the file containing the execution context.\nfrom_c::Bool\nTrue if the code is from C.\ninlined::Bool\nTrue if the code is from an inlined frame.\npointer::UInt64\nRepresentation of the pointer to the execution context as returned by backtrace.\n\n\n\n\n\n","category":"type"},{"location":"base/stacktraces/#Base.StackTraces.StackTrace","page":"StackTraces","title":"Base.StackTraces.StackTrace","text":"StackTrace\n\nAn alias for Vector{StackFrame} provided for convenience; returned by calls to stacktrace.\n\n\n\n\n\n","category":"type"},{"location":"base/stacktraces/#Base.StackTraces.stacktrace","page":"StackTraces","title":"Base.StackTraces.stacktrace","text":"stacktrace([trace::Vector{Ptr{Cvoid}},] [c_funcs::Bool=false]) -> StackTrace\n\nReturn a stack trace in the form of a vector of StackFrames. (By default stacktrace doesn't return C functions, but this can be enabled.) When called without specifying a trace, stacktrace first calls backtrace.\n\n\n\n\n\n","category":"function"},{"location":"base/stacktraces/","page":"StackTraces","title":"StackTraces","text":"The following methods and types in Base.StackTraces are not exported and need to be called e.g. as StackTraces.lookup(ptr).","category":"page"},{"location":"base/stacktraces/","page":"StackTraces","title":"StackTraces","text":"Base.StackTraces.lookup\nBase.StackTraces.remove_frames!","category":"page"},{"location":"base/stacktraces/#Base.StackTraces.lookup","page":"StackTraces","title":"Base.StackTraces.lookup","text":"lookup(pointer::Ptr{Cvoid}) -> Vector{StackFrame}\n\nGiven a pointer to an execution context (usually generated by a call to backtrace), looks up stack frame context information. Returns an array of frame information for all functions inlined at that point, innermost function first.\n\n\n\n\n\n","category":"function"},{"location":"base/stacktraces/#Base.StackTraces.remove_frames!","page":"StackTraces","title":"Base.StackTraces.remove_frames!","text":"remove_frames!(stack::StackTrace, name::Symbol)\n\nTakes a StackTrace (a vector of StackFrames) and a function name (a Symbol) and removes the StackFrame specified by the function name from the StackTrace (also removing all frames above the specified function). Primarily used to remove StackTraces functions from the StackTrace prior to returning it.\n\n\n\n\n\nremove_frames!(stack::StackTrace, m::Module)\n\nReturn the StackTrace with all StackFrames from the provided Module removed.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Pkg/","page":"Pkg","title":"Pkg","text":"EditURL = \"https://github.com/JuliaLang/Pkg.jl/blob/master/docs/src/basedocs.md\"","category":"page"},{"location":"stdlib/Pkg/#Pkg","page":"Pkg","title":"Pkg","text":"","category":"section"},{"location":"stdlib/Pkg/","page":"Pkg","title":"Pkg","text":"Pkg is Julia's builtin package manager, and handles operations such as installing, updating and removing packages.","category":"page"},{"location":"stdlib/Pkg/","page":"Pkg","title":"Pkg","text":"note: Note\nWhat follows is a very brief introduction to Pkg. For more information on Project.toml files, Manifest.toml files, package version compatibility ([compat]), environments, registries, etc., it is highly recommended to read the full manual, which is available here: https://pkgdocs.julialang.org. For a tutorial on creating packages, see Creating Packages.","category":"page"},{"location":"stdlib/Pkg/","page":"Pkg","title":"Pkg","text":"import Markdown\nfile = joinpath(Sys.STDLIB, \"Pkg\", \"docs\", \"src\", \"getting-started.md\")\nstr = read(file, String)\nstr = replace(str, r\"^#.*$\"m => \"\")\nstr = replace(str, \"[API Reference](@ref)\" => \"[API Reference](https://pkgdocs.julialang.org/v1/api/)\")\nstr = replace(str, \"(@ref Working-with-Environments)\" => \"(https://pkgdocs.julialang.org/v1/environments/)\")\nstr = replace(str, \"(@ref Managing-Packages)\" => \"(https://pkgdocs.julialang.org/v1/managing-packages/)\")\nMarkdown.parse(str)","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"EditURL = \"https://github.com/JuliaSparse/SparseArrays.jl/blob/master/docs/src/index.md\"","category":"page"},{"location":"stdlib/SparseArrays/#Sparse-Arrays","page":"Sparse Arrays","title":"Sparse Arrays","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"DocTestSetup = :(using SparseArrays, LinearAlgebra)","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Julia has support for sparse vectors and sparse matrices in the SparseArrays stdlib module. Sparse arrays are arrays that contain enough zeros that storing them in a special data structure leads to savings in space and execution time, compared to dense arrays.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"External packages which implement different sparse storage types, multidimensional sparse arrays, and more can be found in Noteworthy External Sparse Packages","category":"page"},{"location":"stdlib/SparseArrays/#man-csc","page":"Sparse Arrays","title":"Compressed Sparse Column (CSC) Sparse Matrix Storage","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"In Julia, sparse matrices are stored in the Compressed Sparse Column (CSC) format. Julia sparse matrices have the type SparseMatrixCSC{Tv,Ti}, where Tv is the type of the stored values, and Ti is the integer type for storing column pointers and row indices. The internal representation of SparseMatrixCSC is as follows:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}\n m::Int # Number of rows\n n::Int # Number of columns\n colptr::Vector{Ti} # Column j is in colptr[j]:(colptr[j+1]-1)\n rowval::Vector{Ti} # Row indices of stored values\n nzval::Vector{Tv} # Stored values, typically nonzeros\nend","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The compressed sparse column storage makes it easy and quick to access the elements in the column of a sparse matrix, whereas accessing the sparse matrix by rows is considerably slower. Operations such as insertion of previously unstored entries one at a time in the CSC structure tend to be slow. This is because all elements of the sparse matrix that are beyond the point of insertion have to be moved one place over.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"All operations on sparse matrices are carefully implemented to exploit the CSC data structure for performance, and to avoid expensive operations.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"If you have data in CSC format from a different application or library, and wish to import it in Julia, make sure that you use 1-based indexing. The row indices in every column need to be sorted, and if they are not, the matrix will display incorrectly. If your SparseMatrixCSC object contains unsorted row indices, one quick way to sort them is by doing a double transpose. Since the transpose operation is lazy, make a copy to materialize each transpose.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"In some applications, it is convenient to store explicit zero values in a SparseMatrixCSC. These are accepted by functions in Base (but there is no guarantee that they will be preserved in mutating operations). Such explicitly stored zeros are treated as structural nonzeros by many routines. The nnz function returns the number of elements explicitly stored in the sparse data structure, including non-structural zeros. In order to count the exact number of numerical nonzeros, use count(!iszero, x), which inspects every stored element of a sparse matrix. dropzeros, and the in-place dropzeros!, can be used to remove stored zeros from the sparse matrix.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> A = sparse([1, 1, 2, 3], [1, 3, 2, 3], [0, 1, 2, 0])\n3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:\n 0 ⋅ 1\n ⋅ 2 ⋅\n ⋅ ⋅ 0\n\njulia> dropzeros(A)\n3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:\n ⋅ ⋅ 1\n ⋅ 2 ⋅\n ⋅ ⋅ ⋅","category":"page"},{"location":"stdlib/SparseArrays/#Sparse-Vector-Storage","page":"Sparse Arrays","title":"Sparse Vector Storage","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Sparse vectors are stored in a close analog to compressed sparse column format for sparse matrices. In Julia, sparse vectors have the type SparseVector{Tv,Ti} where Tv is the type of the stored values and Ti the integer type for the indices. The internal representation is as follows:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}\n n::Int # Length of the sparse vector\n nzind::Vector{Ti} # Indices of stored values\n nzval::Vector{Tv} # Stored values, typically nonzeros\nend","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"As for SparseMatrixCSC, the SparseVector type can also contain explicitly stored zeros. (See Sparse Matrix Storage.).","category":"page"},{"location":"stdlib/SparseArrays/#Sparse-Vector-and-Matrix-Constructors","page":"Sparse Arrays","title":"Sparse Vector and Matrix Constructors","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The simplest way to create a sparse array is to use a function equivalent to the zeros function that Julia provides for working with dense arrays. To produce a sparse array instead, you can use the same name with an sp prefix:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> spzeros(3)\n3-element SparseVector{Float64, Int64} with 0 stored entries","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The sparse function is often a handy way to construct sparse arrays. For example, to construct a sparse matrix we can input a vector I of row indices, a vector J of column indices, and a vector V of stored values (this is also known as the COO (coordinate) format). sparse(I,J,V) then constructs a sparse matrix such that S[I[k], J[k]] = V[k]. The equivalent sparse vector constructor is sparsevec, which takes the (row) index vector I and the vector V with the stored values and constructs a sparse vector R such that R[I[k]] = V[k].","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3];\n\njulia> S = sparse(I,J,V)\n5×18 SparseMatrixCSC{Int64, Int64} with 4 stored entries:\n⎡⠀⠈⠀⠀⠀⠀⠀⠀⢀⎤\n⎣⠀⠀⠀⠂⡀⠀⠀⠀⠀⎦\n\njulia> R = sparsevec(I,V)\n5-element SparseVector{Int64, Int64} with 4 stored entries:\n [1] = 1\n [3] = -5\n [4] = 2\n [5] = 3","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The inverse of the sparse and sparsevec functions is findnz, which retrieves the inputs used to create the sparse array (including stored entries equal to zero). findall(!iszero, x) returns the Cartesian indices of non-zero entries in x (not including stored entries equal to zero).","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> findnz(S)\n([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5])\n\njulia> findall(!iszero, S)\n4-element Vector{CartesianIndex{2}}:\n CartesianIndex(1, 4)\n CartesianIndex(4, 7)\n CartesianIndex(5, 9)\n CartesianIndex(3, 18)\n\njulia> findnz(R)\n([1, 3, 4, 5], [1, -5, 2, 3])\n\njulia> findall(!iszero, R)\n4-element Vector{Int64}:\n 1\n 3\n 4\n 5","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Another way to create a sparse array is to convert a dense array into a sparse array using the sparse function:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> sparse(Matrix(1.0I, 5, 5))\n5×5 SparseMatrixCSC{Float64, Int64} with 5 stored entries:\n 1.0 ⋅ ⋅ ⋅ ⋅\n ⋅ 1.0 ⋅ ⋅ ⋅\n ⋅ ⋅ 1.0 ⋅ ⋅\n ⋅ ⋅ ⋅ 1.0 ⋅\n ⋅ ⋅ ⋅ ⋅ 1.0\n\njulia> sparse([1.0, 0.0, 1.0])\n3-element SparseVector{Float64, Int64} with 2 stored entries:\n [1] = 1.0\n [3] = 1.0","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"You can go in the other direction using the Array constructor. The issparse function can be used to query if a matrix is sparse.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"julia> issparse(spzeros(5))\ntrue","category":"page"},{"location":"stdlib/SparseArrays/#Sparse-matrix-operations","page":"Sparse Arrays","title":"Sparse matrix operations","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Arithmetic operations on sparse matrices also work as they do on dense matrices. Indexing of, assignment into, and concatenation of sparse matrices work in the same way as dense matrices. Indexing operations, especially assignment, are expensive, when carried out one element at a time. In many cases it may be better to convert the sparse matrix into (I,J,V) format using findnz, manipulate the values or the structure in the dense vectors (I,J,V), and then reconstruct the sparse matrix.","category":"page"},{"location":"stdlib/SparseArrays/#Correspondence-of-dense-and-sparse-methods","page":"Sparse Arrays","title":"Correspondence of dense and sparse methods","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"The following table gives a correspondence between built-in methods on sparse matrices and their corresponding methods on dense matrix types. In general, methods that generate sparse matrices differ from their dense counterparts in that the resulting matrix follows the same sparsity pattern as a given sparse matrix S, or that the resulting sparse matrix has density d, i.e. each matrix element has a probability d of being non-zero.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Details can be found in the Sparse Vectors and Matrices section of the standard library reference.","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Sparse Dense Description\nspzeros(m,n) zeros(m,n) Creates a m-by-n matrix of zeros. (spzeros(m,n) is empty.)\nsparse(I,n,n) Matrix(I,n,n) Creates a n-by-n identity matrix.\nsparse(A) Array(S) Interconverts between dense and sparse formats.\nsprand(m,n,d) rand(m,n) Creates a m-by-n random matrix (of density d) with iid non-zero elements distributed uniformly on the half-open interval 0 1).\nsprandn(m,n,d) randn(m,n) Creates a m-by-n random matrix (of density d) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution.\nsprandn(rng,m,n,d) randn(rng,m,n) Creates a m-by-n random matrix (of density d) with iid non-zero elements generated with the rng random number generator","category":"page"},{"location":"stdlib/SparseArrays/#stdlib-sparse-arrays","page":"Sparse Arrays","title":"SparseArrays API","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"SparseArrays.AbstractSparseArray\nSparseArrays.AbstractSparseVector\nSparseArrays.AbstractSparseMatrix\nSparseArrays.SparseVector\nSparseArrays.SparseMatrixCSC\nSparseArrays.sparse\nSparseArrays.sparse!\nSparseArrays.sparsevec\nBase.similar(::SparseArrays.AbstractSparseMatrixCSC, ::Type)\nSparseArrays.issparse\nSparseArrays.nnz\nSparseArrays.findnz\nSparseArrays.spzeros\nSparseArrays.spzeros!\nSparseArrays.spdiagm\nSparseArrays.sparse_hcat\nSparseArrays.sparse_vcat\nSparseArrays.sparse_hvcat\nSparseArrays.blockdiag\nSparseArrays.sprand\nSparseArrays.sprandn\nSparseArrays.nonzeros\nSparseArrays.rowvals\nSparseArrays.nzrange\nSparseArrays.droptol!\nSparseArrays.dropzeros!\nSparseArrays.dropzeros\nSparseArrays.permute\npermute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1})\nSparseArrays.halfperm!\nSparseArrays.ftranspose!","category":"page"},{"location":"stdlib/SparseArrays/#SparseArrays.AbstractSparseArray","page":"Sparse Arrays","title":"SparseArrays.AbstractSparseArray","text":"AbstractSparseArray{Tv,Ti,N}\n\nSupertype for N-dimensional sparse arrays (or array-like types) with elements of type Tv and index type Ti. SparseMatrixCSC, SparseVector and SuiteSparse.CHOLMOD.Sparse are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.AbstractSparseVector","page":"Sparse Arrays","title":"SparseArrays.AbstractSparseVector","text":"AbstractSparseVector{Tv,Ti}\n\nSupertype for one-dimensional sparse arrays (or array-like types) with elements of type Tv and index type Ti. Alias for AbstractSparseArray{Tv,Ti,1}.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.AbstractSparseMatrix","page":"Sparse Arrays","title":"SparseArrays.AbstractSparseMatrix","text":"AbstractSparseMatrix{Tv,Ti}\n\nSupertype for two-dimensional sparse arrays (or array-like types) with elements of type Tv and index type Ti. Alias for AbstractSparseArray{Tv,Ti,2}.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.SparseVector","page":"Sparse Arrays","title":"SparseArrays.SparseVector","text":"SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}\n\nVector type for storing sparse vectors. Can be created by passing the length of the vector, a sorted vector of non-zero indices, and a vector of non-zero values.\n\nFor instance, the vector [5, 6, 0, 7] can be represented as\n\nSparseVector(4, [1, 2, 4], [5, 6, 7])\n\nThis indicates that the element at index 1 is 5, at index 2 is 6, at index 3 is zero(Int), and at index 4 is 7.\n\nIt may be more convenient to create sparse vectors directly from dense vectors using sparse as\n\nsparse([5, 6, 0, 7])\n\nyields the same sparse vector.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.SparseMatrixCSC","page":"Sparse Arrays","title":"SparseArrays.SparseMatrixCSC","text":"SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}\n\nMatrix type for storing sparse matrices in the Compressed Sparse Column format. The standard way of constructing SparseMatrixCSC is through the sparse function. See also spzeros, spdiagm and sprand.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse","page":"Sparse Arrays","title":"SparseArrays.sparse","text":"sparse(A)\n\nConvert an AbstractMatrix A into a sparse matrix.\n\nExamples\n\njulia> A = Matrix(1.0I, 3, 3)\n3×3 Matrix{Float64}:\n 1.0 0.0 0.0\n 0.0 1.0 0.0\n 0.0 0.0 1.0\n\njulia> sparse(A)\n3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:\n 1.0 ⋅ ⋅\n ⋅ 1.0 ⋅\n ⋅ ⋅ 1.0\n\n\n\n\n\nsparse(I, J, V,[ m, n, combine])\n\nCreate a sparse matrix S of dimensions m x n such that S[I[k], J[k]] = V[k]. The combine function is used to combine duplicates. If m and n are not specified, they are set to maximum(I) and maximum(J) respectively. If the combine function is not supplied, combine defaults to + unless the elements of V are Booleans in which case combine defaults to |. All elements of I must satisfy 1 <= I[k] <= m, and all elements of J must satisfy 1 <= J[k] <= n. Numerical zeros in (I, J, V) are retained as structural nonzeros; to drop numerical zeros, use dropzeros!.\n\nFor additional documentation and an expert driver, see SparseArrays.sparse!.\n\nExamples\n\njulia> Is = [1; 2; 3];\n\njulia> Js = [1; 2; 3];\n\njulia> Vs = [1; 2; 3];\n\njulia> sparse(Is, Js, Vs)\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 1 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse!","page":"Sparse Arrays","title":"SparseArrays.sparse!","text":"sparse!(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{Tv},\n m::Integer, n::Integer, combine, klasttouch::Vector{Ti},\n csrrowptr::Vector{Ti}, csrcolval::Vector{Ti}, csrnzval::Vector{Tv},\n [csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}] ) where {Tv,Ti<:Integer}\n\nParent of and expert driver for sparse; see sparse for basic usage. This method allows the user to provide preallocated storage for sparse's intermediate objects and result as described below. This capability enables more efficient successive construction of SparseMatrixCSCs from coordinate representations, and also enables extraction of an unsorted-column representation of the result's transpose at no additional cost.\n\nThis method consists of three major steps: (1) Counting-sort the provided coordinate representation into an unsorted-row CSR form including repeated entries. (2) Sweep through the CSR form, simultaneously calculating the desired CSC form's column-pointer array, detecting repeated entries, and repacking the CSR form with repeated entries combined; this stage yields an unsorted-row CSR form with no repeated entries. (3) Counting-sort the preceding CSR form into a fully-sorted CSC form with no repeated entries.\n\nInput arrays csrrowptr, csrcolval, and csrnzval constitute storage for the intermediate CSR forms and require length(csrrowptr) >= m + 1, length(csrcolval) >= length(I), and length(csrnzval >= length(I)). Input array klasttouch, workspace for the second stage, requires length(klasttouch) >= n. Optional input arrays csccolptr, cscrowval, and cscnzval constitute storage for the returned CSC form S. If necessary, these are resized automatically to satisfy length(csccolptr) = n + 1, length(cscrowval) = nnz(S) and length(cscnzval) = nnz(S); hence, if nnz(S) is unknown at the outset, passing in empty vectors of the appropriate type (Vector{Ti}() and Vector{Tv}() respectively) suffices, or calling the sparse! method neglecting cscrowval and cscnzval.\n\nOn return, csrrowptr, csrcolval, and csrnzval contain an unsorted-column representation of the result's transpose.\n\nYou may reuse the input arrays' storage (I, J, V) for the output arrays (csccolptr, cscrowval, cscnzval). For example, you may call sparse!(I, J, V, csrrowptr, csrcolval, csrnzval, I, J, V). Note that they will be resized to satisfy the conditions above.\n\nFor the sake of efficiency, this method performs no argument checking beyond 1 <= I[k] <= m and 1 <= J[k] <= n. Use with care. Testing with --check-bounds=yes is wise.\n\nThis method runs in O(m, n, length(I)) time. The HALFPERM algorithm described in F. Gustavson, \"Two fast algorithms for sparse matrices: multiplication and permuted transposition,\" ACM TOMS 4(3), 250-269 (1978) inspired this method's use of a pair of counting sorts.\n\n\n\n\n\nSparseArrays.sparse!(I, J, V, [m, n, combine]) -> SparseMatrixCSC\n\nVariant of sparse! that re-uses the input vectors (I, J, V) for the final matrix storage. After construction the input vectors will alias the matrix buffers; S.colptr === I, S.rowval === J, and S.nzval === V holds, and they will be resize!d as necessary.\n\nNote that some work buffers will still be allocated. Specifically, this method is a convenience wrapper around sparse!(I, J, V, m, n, combine, klasttouch, csrrowptr, csrcolval, csrnzval, csccolptr, cscrowval, cscnzval) where this method allocates klasttouch, csrrowptr, csrcolval, and csrnzval of appropriate size, but reuses I, J, and V for csccolptr, cscrowval, and cscnzval.\n\nArguments m, n, and combine defaults to maximum(I), maximum(J), and +, respectively.\n\ncompat: Julia 1.10\nThis method requires Julia version 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparsevec","page":"Sparse Arrays","title":"SparseArrays.sparsevec","text":"sparsevec(I, V, [m, combine])\n\nCreate a sparse vector S of length m such that S[I[k]] = V[k]. Duplicates are combined using the combine function, which defaults to + if no combine argument is provided, unless the elements of V are Booleans in which case combine defaults to |.\n\nExamples\n\njulia> II = [1, 3, 3, 5]; V = [0.1, 0.2, 0.3, 0.2];\n\njulia> sparsevec(II, V)\n5-element SparseVector{Float64, Int64} with 3 stored entries:\n [1] = 0.1\n [3] = 0.5\n [5] = 0.2\n\njulia> sparsevec(II, V, 8, -)\n8-element SparseVector{Float64, Int64} with 3 stored entries:\n [1] = 0.1\n [3] = -0.1\n [5] = 0.2\n\njulia> sparsevec([1, 3, 1, 2, 2], [true, true, false, false, false])\n3-element SparseVector{Bool, Int64} with 3 stored entries:\n [1] = 1\n [2] = 0\n [3] = 1\n\n\n\n\n\nsparsevec(d::Dict, [m])\n\nCreate a sparse vector of length m where the nonzero indices are keys from the dictionary, and the nonzero values are the values from the dictionary.\n\nExamples\n\njulia> sparsevec(Dict(1 => 3, 2 => 2))\n2-element SparseVector{Int64, Int64} with 2 stored entries:\n [1] = 3\n [2] = 2\n\n\n\n\n\nsparsevec(A)\n\nConvert a vector A into a sparse vector of length m.\n\nExamples\n\njulia> sparsevec([1.0, 2.0, 0.0, 0.0, 3.0, 0.0])\n6-element SparseVector{Float64, Int64} with 3 stored entries:\n [1] = 1.0\n [2] = 2.0\n [5] = 3.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#Base.similar-Tuple{SparseArrays.AbstractSparseMatrixCSC, Type}","page":"Sparse Arrays","title":"Base.similar","text":"similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}\n\nCreate an uninitialized mutable array with the given element type, index type, and size, based upon the given source SparseMatrixCSC. The new sparse matrix maintains the structure of the original sparse matrix, except in the case where dimensions of the output matrix are different from the output.\n\nThe output matrix has zeros in the same locations as the input, but uninitialized values for the nonzero locations.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/SparseArrays/#SparseArrays.issparse","page":"Sparse Arrays","title":"SparseArrays.issparse","text":"issparse(S)\n\nReturns true if S is sparse, and false otherwise.\n\nExamples\n\njulia> sv = sparsevec([1, 4], [2.3, 2.2], 10)\n10-element SparseVector{Float64, Int64} with 2 stored entries:\n [1] = 2.3\n [4] = 2.2\n\njulia> issparse(sv)\ntrue\n\njulia> issparse(Array(sv))\nfalse\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.nnz","page":"Sparse Arrays","title":"SparseArrays.nnz","text":"nnz(A)\n\nReturns the number of stored (filled) elements in a sparse array.\n\nExamples\n\njulia> A = sparse(2I, 3, 3)\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 2 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 2\n\njulia> nnz(A)\n3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.findnz","page":"Sparse Arrays","title":"SparseArrays.findnz","text":"findnz(A::SparseMatrixCSC)\n\nReturn a tuple (I, J, V) where I and J are the row and column indices of the stored (\"structurally non-zero\") values in sparse matrix A, and V is a vector of the values.\n\nExamples\n\njulia> A = sparse([1 2 0; 0 0 3; 0 4 0])\n3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:\n 1 2 ⋅\n ⋅ ⋅ 3\n ⋅ 4 ⋅\n\njulia> findnz(A)\n([1, 1, 3, 2], [1, 2, 2, 3], [1, 2, 4, 3])\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.spzeros","page":"Sparse Arrays","title":"SparseArrays.spzeros","text":"spzeros([type,]m[,n])\n\nCreate a sparse vector of length m or sparse matrix of size m x n. This sparse array will not contain any nonzero values. No storage will be allocated for nonzero values during construction. The type defaults to Float64 if not specified.\n\nExamples\n\njulia> spzeros(3, 3)\n3×3 SparseMatrixCSC{Float64, Int64} with 0 stored entries:\n ⋅ ⋅ ⋅\n ⋅ ⋅ ⋅\n ⋅ ⋅ ⋅\n\njulia> spzeros(Float32, 4)\n4-element SparseVector{Float32, Int64} with 0 stored entries\n\n\n\n\n\nspzeros([type], I::AbstractVector, J::AbstractVector, [m, n])\n\nCreate a sparse matrix S of dimensions m x n with structural zeros at S[I[k], J[k]].\n\nThis method can be used to construct the sparsity pattern of the matrix, and is more efficient than using e.g. sparse(I, J, zeros(length(I))).\n\nFor additional documentation and an expert driver, see SparseArrays.spzeros!.\n\ncompat: Julia 1.10\nThis methods requires Julia version 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.spzeros!","page":"Sparse Arrays","title":"SparseArrays.spzeros!","text":"spzeros!(::Type{Tv}, I::AbstractVector{Ti}, J::AbstractVector{Ti}, m::Integer, n::Integer,\n klasttouch::Vector{Ti}, csrrowptr::Vector{Ti}, csrcolval::Vector{Ti},\n [csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}]) where {Tv,Ti<:Integer}\n\nParent of and expert driver for spzeros(I, J) allowing user to provide preallocated storage for intermediate objects. This method is to spzeros what SparseArrays.sparse! is to sparse. See documentation for SparseArrays.sparse! for details and required buffer lengths.\n\ncompat: Julia 1.10\nThis methods requires Julia version 1.10 or later.\n\n\n\n\n\nSparseArrays.spzeros!(::Type{Tv}, I, J, [m, n]) -> SparseMatrixCSC{Tv}\n\nVariant of spzeros! that re-uses the input vectors I and J for the final matrix storage. After construction the input vectors will alias the matrix buffers; S.colptr === I and S.rowval === J holds, and they will be resize!d as necessary.\n\nNote that some work buffers will still be allocated. Specifically, this method is a convenience wrapper around spzeros!(Tv, I, J, m, n, klasttouch, csrrowptr, csrcolval, csccolptr, cscrowval) where this method allocates klasttouch, csrrowptr, and csrcolval of appropriate size, but reuses I and J for csccolptr and cscrowval.\n\nArguments m and n defaults to maximum(I) and maximum(J).\n\ncompat: Julia 1.10\nThis method requires Julia version 1.10 or later.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.spdiagm","page":"Sparse Arrays","title":"SparseArrays.spdiagm","text":"spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)\nspdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)\n\nConstruct a sparse diagonal matrix from Pairs of vectors and diagonals. Each vector kv.second will be placed on the kv.first diagonal. By default, the matrix is square and its size is inferred from kv, but a non-square size m×n (padded with zeros as needed) can be specified by passing m,n as the first arguments.\n\nExamples\n\njulia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1])\n5×5 SparseMatrixCSC{Int64, Int64} with 8 stored entries:\n ⋅ 4 ⋅ ⋅ ⋅\n 1 ⋅ 3 ⋅ ⋅\n ⋅ 2 ⋅ 2 ⋅\n ⋅ ⋅ 3 ⋅ 1\n ⋅ ⋅ ⋅ 4 ⋅\n\n\n\n\n\nspdiagm(v::AbstractVector)\nspdiagm(m::Integer, n::Integer, v::AbstractVector)\n\nConstruct a sparse matrix with elements of the vector as diagonal elements. By default (no given m and n), the matrix is square and its size is given by length(v), but a non-square size m×n can be specified by passing m and n as the first arguments.\n\ncompat: Julia 1.6\nThese functions require at least Julia 1.6.\n\nExamples\n\njulia> spdiagm([1,2,3])\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 1 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 3\n\njulia> spdiagm(sparse([1,0,3]))\n3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:\n 1 ⋅ ⋅\n ⋅ ⋅ ⋅\n ⋅ ⋅ 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse_hcat","page":"Sparse Arrays","title":"SparseArrays.sparse_hcat","text":"sparse_hcat(A...)\n\nConcatenate along dimension 2. Return a SparseMatrixCSC object.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized \"sparse\" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse_vcat","page":"Sparse Arrays","title":"SparseArrays.sparse_vcat","text":"sparse_vcat(A...)\n\nConcatenate along dimension 1. Return a SparseMatrixCSC object.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized \"sparse\" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sparse_hvcat","page":"Sparse Arrays","title":"SparseArrays.sparse_hvcat","text":"sparse_hvcat(rows::Tuple{Vararg{Int}}, values...)\n\nSparse horizontal and vertical concatenation in one call. This function is called for block matrix syntax. The first argument specifies the number of arguments to concatenate in each block row.\n\ncompat: Julia 1.8\nThis method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized \"sparse\" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.blockdiag","page":"Sparse Arrays","title":"SparseArrays.blockdiag","text":"blockdiag(A...)\n\nConcatenate matrices block-diagonally. Currently only implemented for sparse matrices.\n\nExamples\n\njulia> blockdiag(sparse(2I, 3, 3), sparse(4I, 2, 2))\n5×5 SparseMatrixCSC{Int64, Int64} with 5 stored entries:\n 2 ⋅ ⋅ ⋅ ⋅\n ⋅ 2 ⋅ ⋅ ⋅\n ⋅ ⋅ 2 ⋅ ⋅\n ⋅ ⋅ ⋅ 4 ⋅\n ⋅ ⋅ ⋅ ⋅ 4\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sprand","page":"Sparse Arrays","title":"SparseArrays.sprand","text":"sprand([rng],[T::Type],m,[n],p::AbstractFloat)\nsprand([rng],m,[n],p::AbstractFloat,[rfn=rand])\n\nCreate a random length m sparse vector or m by n sparse matrix, in which the probability of any element being nonzero is independently given by p (and hence the mean density of nonzeros is also exactly p). The optional rng argument specifies a random number generator, see Random Numbers. The optional T argument specifies the element type, which defaults to Float64.\n\nBy default, nonzero values are sampled from a uniform distribution using the rand function, i.e. by rand(T), or rand(rng, T) if rng is supplied; for the default T=Float64, this corresponds to nonzero values sampled uniformly in [0,1).\n\nYou can sample nonzero values from a different distribution by passing a custom rfn function instead of rand. This should be a function rfn(k) that returns an array of k random numbers sampled from the desired distribution; alternatively, if rng is supplied, it should instead be a function rfn(rng, k).\n\nExamples\n\njulia> sprand(Bool, 2, 2, 0.5)\n2×2 SparseMatrixCSC{Bool, Int64} with 2 stored entries:\n 1 1\n ⋅ ⋅\n\njulia> sprand(Float64, 3, 0.75)\n3-element SparseVector{Float64, Int64} with 2 stored entries:\n [1] = 0.795547\n [2] = 0.49425\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.sprandn","page":"Sparse Arrays","title":"SparseArrays.sprandn","text":"sprandn([rng][,Type],m[,n],p::AbstractFloat)\n\nCreate a random sparse vector of length m or sparse matrix of size m by n with the specified (independent) probability p of any entry being nonzero, where nonzero values are sampled from the normal distribution. The optional rng argument specifies a random number generator, see Random Numbers.\n\ncompat: Julia 1.1\nSpecifying the output element type Type requires at least Julia 1.1.\n\nExamples\n\njulia> sprandn(2, 2, 0.75)\n2×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries:\n -1.20577 ⋅\n 0.311817 -0.234641\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.nonzeros","page":"Sparse Arrays","title":"SparseArrays.nonzeros","text":"nonzeros(A)\n\nReturn a vector of the structural nonzero values in sparse array A. This includes zeros that are explicitly stored in the sparse array. The returned vector points directly to the internal nonzero storage of A, and any modifications to the returned vector will mutate A as well. See rowvals and nzrange.\n\nExamples\n\njulia> A = sparse(2I, 3, 3)\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 2 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 2\n\njulia> nonzeros(A)\n3-element Vector{Int64}:\n 2\n 2\n 2\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.rowvals","page":"Sparse Arrays","title":"SparseArrays.rowvals","text":"rowvals(A::AbstractSparseMatrixCSC)\n\nReturn a vector of the row indices of A. Any modifications to the returned vector will mutate A as well. Providing access to how the row indices are stored internally can be useful in conjunction with iterating over structural nonzero values. See also nonzeros and nzrange.\n\nExamples\n\njulia> A = sparse(2I, 3, 3)\n3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:\n 2 ⋅ ⋅\n ⋅ 2 ⋅\n ⋅ ⋅ 2\n\njulia> rowvals(A)\n3-element Vector{Int64}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.nzrange","page":"Sparse Arrays","title":"SparseArrays.nzrange","text":"nzrange(A::AbstractSparseMatrixCSC, col::Integer)\n\nReturn the range of indices to the structural nonzero values of a sparse matrix column. In conjunction with nonzeros and rowvals, this allows for convenient iterating over a sparse matrix :\n\nA = sparse(I,J,V)\nrows = rowvals(A)\nvals = nonzeros(A)\nm, n = size(A)\nfor j = 1:n\n for i in nzrange(A, j)\n row = rows[i]\n val = vals[i]\n # perform sparse wizardry...\n end\nend\n\nwarning: Warning\nAdding or removing nonzero elements to the matrix may invalidate the nzrange, one should not mutate the matrix while iterating.\n\n\n\n\n\nnzrange(x::SparseVectorUnion, col)\n\nGive the range of indices to the structural nonzero values of a sparse vector. The column index col is ignored (assumed to be 1).\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.droptol!","page":"Sparse Arrays","title":"SparseArrays.droptol!","text":"droptol!(A::AbstractSparseMatrixCSC, tol)\n\nRemoves stored values from A whose absolute value is less than or equal to tol.\n\n\n\n\n\ndroptol!(x::AbstractCompressedVector, tol)\n\nRemoves stored values from x whose absolute value is less than or equal to tol.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.dropzeros!","page":"Sparse Arrays","title":"SparseArrays.dropzeros!","text":"dropzeros!(x::AbstractCompressedVector)\n\nRemoves stored numerical zeros from x.\n\nFor an out-of-place version, see dropzeros. For algorithmic information, see fkeep!.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.dropzeros","page":"Sparse Arrays","title":"SparseArrays.dropzeros","text":"dropzeros(A::AbstractSparseMatrixCSC;)\n\nGenerates a copy of A and removes stored numerical zeros from that copy.\n\nFor an in-place version and algorithmic information, see dropzeros!.\n\nExamples\n\njulia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0])\n3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:\n 1.0 ⋅ ⋅\n ⋅ 0.0 ⋅\n ⋅ ⋅ 1.0\n\njulia> dropzeros(A)\n3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries:\n 1.0 ⋅ ⋅\n ⋅ ⋅ ⋅\n ⋅ ⋅ 1.0\n\n\n\n\n\ndropzeros(x::AbstractCompressedVector)\n\nGenerates a copy of x and removes numerical zeros from that copy.\n\nFor an in-place version and algorithmic information, see dropzeros!.\n\nExamples\n\njulia> A = sparsevec([1, 2, 3], [1.0, 0.0, 1.0])\n3-element SparseVector{Float64, Int64} with 3 stored entries:\n [1] = 1.0\n [2] = 0.0\n [3] = 1.0\n\njulia> dropzeros(A)\n3-element SparseVector{Float64, Int64} with 2 stored entries:\n [1] = 1.0\n [3] = 1.0\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.permute","page":"Sparse Arrays","title":"SparseArrays.permute","text":"permute(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},\n q::AbstractVector{<:Integer}) where {Tv,Ti}\n\nBilaterally permute A, returning PAQ (A[p,q]). Column-permutation q's length must match A's column count (length(q) == size(A, 2)). Row-permutation p's length must match A's row count (length(p) == size(A, 1)).\n\nFor expert drivers and additional information, see permute!.\n\nExamples\n\njulia> A = spdiagm(0 => [1, 2, 3, 4], 1 => [5, 6, 7])\n4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:\n 1 5 ⋅ ⋅\n ⋅ 2 6 ⋅\n ⋅ ⋅ 3 7\n ⋅ ⋅ ⋅ 4\n\njulia> permute(A, [4, 3, 2, 1], [1, 2, 3, 4])\n4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:\n ⋅ ⋅ ⋅ 4\n ⋅ ⋅ 3 7\n ⋅ 2 6 ⋅\n 1 5 ⋅ ⋅\n\njulia> permute(A, [1, 2, 3, 4], [4, 3, 2, 1])\n4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:\n ⋅ ⋅ 5 1\n ⋅ 6 2 ⋅\n 7 3 ⋅ ⋅\n 4 ⋅ ⋅ ⋅\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#Base.permute!-Union{Tuple{Tq}, Tuple{Tp}, Tuple{Ti}, Tuple{Tv}, Tuple{SparseMatrixCSC{Tv, Ti}, SparseMatrixCSC{Tv, Ti}, AbstractVector{Tp}, AbstractVector{Tq}}} where {Tv, Ti, Tp<:Integer, Tq<:Integer}","page":"Sparse Arrays","title":"Base.permute!","text":"permute!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti},\n p::AbstractVector{<:Integer}, q::AbstractVector{<:Integer},\n [C::AbstractSparseMatrixCSC{Tv,Ti}]) where {Tv,Ti}\n\nBilaterally permute A, storing result PAQ (A[p,q]) in X. Stores intermediate result (AQ)^T (transpose(A[:,q])) in optional argument C if present. Requires that none of X, A, and, if present, C alias each other; to store result PAQ back into A, use the following method lacking X:\n\npermute!(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},\n q::AbstractVector{<:Integer}[, C::AbstractSparseMatrixCSC{Tv,Ti},\n [workcolptr::Vector{Ti}]]) where {Tv,Ti}\n\nX's dimensions must match those of A (size(X, 1) == size(A, 1) and size(X, 2) == size(A, 2)), and X must have enough storage to accommodate all allocated entries in A (length(rowvals(X)) >= nnz(A) and length(nonzeros(X)) >= nnz(A)). Column-permutation q's length must match A's column count (length(q) == size(A, 2)). Row-permutation p's length must match A's row count (length(p) == size(A, 1)).\n\nC's dimensions must match those of transpose(A) (size(C, 1) == size(A, 2) and size(C, 2) == size(A, 1)), and C must have enough storage to accommodate all allocated entries in A (length(rowvals(C)) >= nnz(A) and length(nonzeros(C)) >= nnz(A)).\n\nFor additional (algorithmic) information, and for versions of these methods that forgo argument checking, see (unexported) parent methods unchecked_noalias_permute! and unchecked_aliasing_permute!.\n\nSee also permute.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/SparseArrays/#SparseArrays.halfperm!","page":"Sparse Arrays","title":"SparseArrays.halfperm!","text":"halfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},\n q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}\n\nColumn-permute and transpose A, simultaneously applying f to each entry of A, storing the result (f(A)Q)^T (map(f, transpose(A[:,q]))) in X.\n\nElement type Tv of X must match f(::TvA), where TvA is the element type of A. X's dimensions must match those of transpose(A) (size(X, 1) == size(A, 2) and size(X, 2) == size(A, 1)), and X must have enough storage to accommodate all allocated entries in A (length(rowvals(X)) >= nnz(A) and length(nonzeros(X)) >= nnz(A)). Column-permutation q's length must match A's column count (length(q) == size(A, 2)).\n\nThis method is the parent of several methods performing transposition and permutation operations on SparseMatrixCSCs. As this method performs no argument checking, prefer the safer child methods ([c]transpose[!], permute[!]) to direct use.\n\nThis method implements the HALFPERM algorithm described in F. Gustavson, \"Two fast algorithms for sparse matrices: multiplication and permuted transposition,\" ACM TOMS 4(3), 250-269 (1978). The algorithm runs in O(size(A, 1), size(A, 2), nnz(A)) time and requires no space beyond that passed in.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/#SparseArrays.ftranspose!","page":"Sparse Arrays","title":"SparseArrays.ftranspose!","text":"ftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}\n\nTranspose A and store it in X while applying the function f to the non-zero elements. Does not remove the zeros created by f. size(X) must be equal to size(transpose(A)). No additional memory is allocated other than resizing the rowval and nzval of X, if needed.\n\nSee halfperm!\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/SparseArrays/#Noteworthy-External-Sparse-Packages","page":"Sparse Arrays","title":"Noteworthy External Sparse Packages","text":"","category":"section"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"Several other Julia packages provide sparse matrix implementations that should be mentioned:","category":"page"},{"location":"stdlib/SparseArrays/","page":"Sparse Arrays","title":"Sparse Arrays","text":"SuiteSparseGraphBLAS.jl is a wrapper over the fast, multithreaded SuiteSparse:GraphBLAS C library. On CPU this is typically the fastest option, often significantly outperforming MKLSparse.\nCUDA.jl exposes the CUSPARSE library for GPU sparse matrix operations.\nSparseMatricesCSR.jl provides a Julia native implementation of the Compressed Sparse Rows (CSR) format.\nMKLSparse.jl accelerates SparseArrays sparse-dense matrix operations using Intel's MKL library.\nSparseArrayKit.jl available for multidimensional sparse arrays.\nLuxurySparse.jl provides static sparse array formats, as well as a coordinate format.\nExtendableSparse.jl enables fast insertion into sparse matrices using a lazy approach to new stored indices.\nFinch.jl supports extensive multidimensional sparse array formats and operations through a mini tensor language and compiler, all in native Julia. Support for COO, CSF, CSR, CSC and more, as well as operations like broadcast, reduce, etc. and custom operations.","category":"page"},{"location":"devdocs/jit/#JIT-Design-and-Implementation","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"This document explains the design and implementation of Julia's JIT, after codegen has finished and unoptimized LLVM IR has been produced. The JIT is responsible for optimizing and compiling this IR to machine code, and for linking it into the current process and making the code available for execution.","category":"page"},{"location":"devdocs/jit/#Introduction","page":"JIT Design and Implementation","title":"Introduction","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"The JIT is responsible for managing compilation resources, looking up previously compiled code, and compiling new code. It is primarily built on LLVM's On-Request-Compilation (ORCv2) technology, which provides support for a number of useful features such as concurrent compilation, lazy compilation, and the ability to compile code in a separate process. Though LLVM provides a basic JIT compiler in the form of LLJIT, Julia uses many ORCv2 APIs directly to create its own custom JIT compiler.","category":"page"},{"location":"devdocs/jit/#Overview","page":"JIT Design and Implementation","title":"Overview","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"(Image: Diagram of the compiler flow)","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Codegen produces an LLVM module containing IR for one or more Julia functions from the original Julia SSA IR produced by type inference (labeled as translate on the compiler diagram above). It also produces a mapping of code-instance to LLVM function name. However, though some optimizations have been applied by the Julia-based compiler on Julia IR, the LLVM IR produced by codegen still contains many opportunities for optimization. Thus, the first step the JIT takes is to run a target-independent optimization pipeline[tdp] on the LLVM module. Then, the JIT runs a target-dependent optimization pipeline, which includes target-specific optimizations and code generation, and outputs an object file. Finally, the JIT links the resulting object file into the current process and makes the code available for execution. All of this is controlled by code in src/jitlayers.cpp.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"[tdp]: This is not a totally-target independent pipeline, as transformations such as vectorization rely upon target information such as vector register width and cost modeling. Additionally, codegen itself makes a few target-dependent assumptions, and the optimization pipeline will take advantage of that knowledge.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Currently, only one thread at a time is permitted to enter the optimize-compile-link pipeline at a time, due to restrictions imposed by one of our linkers (RuntimeDyld). However, the JIT is designed to support concurrent optimization and compilation, and the linker restriction is expected to be lifted in the future when RuntimeDyld has been fully superseded on all platforms.","category":"page"},{"location":"devdocs/jit/#Optimization-Pipeline","page":"JIT Design and Implementation","title":"Optimization Pipeline","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"The optimization pipeline is based off LLVM's new pass manager, but the pipeline is customized for Julia's needs. The pipeline is defined in src/pipeline.cpp, and broadly proceeds through a number of stages as detailed below.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Early Simplification\nThese passes are mainly used to simplify the IR and canonicalize patterns so that later passes can identify those patterns more easily. Additionally, various intrinsic calls such as branch prediction hints and annotations are lowered into other metadata or other IR features. SimplifyCFG (simplify control flow graph), DCE (dead code elimination), and SROA (scalar replacement of aggregates) are some of the key players here.\nEarly Optimization\nThese passes are typically cheap and are primarily focused around reducing the number of instructions in the IR and propagating knowledge to other instructions. For example, EarlyCSE is used to perform common subexpression elimination, and InstCombine and InstSimplify perform a number of small peephole optimizations to make operations less expensive.\nLoop Optimization\nThese passes canonicalize and simplify loops. Loops are often hot code, which makes loop optimization extremely important for performance. Key players here include LoopRotate, LICM, and LoopFullUnroll. Some bounds check elimination also happens here, as a result of the IRCE pass which can prove certain bounds are never exceeded.\nScalar Optimization\nThe scalar optimization pipeline contains a number of more expensive, but more powerful passes such as GVN (global value numbering), SCCP (sparse conditional constant propagation), and another round of bounds check elimination. These passes are expensive, but they can often remove large amounts of code and make vectorization much more successful and effective. Several other simplification and optimization passes intersperse the more expensive ones to reduce the amount of work they have to do.\nVectorization\nAutomatic vectorization is an extremely powerful transformation for CPU-intensive code. Briefly, vectorization allows execution of a single instruction on multiple data (SIMD), e.g. performing 8 addition operations at the same time. However, proving code to be both capable of vectorization and profitable to vectorize is difficult, and this relies heavily on the prior optimization passes to massage the IR into a state where vectorization is worth it.\nIntrinsic Lowering\nJulia inserts a number of custom intrinsics, for reasons such as object allocation, garbage collection, and exception handling. These intrinsics were originally placed to make optimization opportunities more obvious, but they are now lowered into LLVM IR to enable the IR to be emitted as machine code.\nCleanup\nThese passes are last-chance optimizations, and perform small optimizations such as fused multiply-add propagation and division-remainder simplification. Additionally, targets that do not support half-precision floating point numbers will have their half-precision instructions lowered into single-precision instructions here, and passes are added to provide sanitizer support.","category":"page"},{"location":"devdocs/jit/#Target-Dependent-Optimization-and-Code-Generation","page":"JIT Design and Implementation","title":"Target-Dependent Optimization and Code Generation","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"LLVM provides target-dependent optimization and machine code generation in the same pipeline, located in the TargetMachine for a given platform. These passes include instruction selection, instruction scheduling, register allocation, and machine code emission. The LLVM documentation provides a good overview of the process, and the LLVM source code is the best place to look for details on the pipeline and passes.","category":"page"},{"location":"devdocs/jit/#Linking","page":"JIT Design and Implementation","title":"Linking","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Currently, Julia is transitioning between two linkers: the older RuntimeDyld linker, and the newer JITLink linker. JITLink contains a number of features that RuntimeDyld does not have, such as concurrent and reentrant linking, but currently lacks good support for profiling integrations and does not yet support all of the platforms that RuntimeDyld supports. Over time, JITLink is expected to replace RuntimeDyld entirely. Further details on JITLink can be found in the LLVM documentation.","category":"page"},{"location":"devdocs/jit/#Execution","page":"JIT Design and Implementation","title":"Execution","text":"","category":"section"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Once the code has been linked into the current process, it is available for execution. This fact is made known to the generating codeinst by updating the invoke, specsigflags, and specptr fields appropriately. Codeinsts support upgrading invoke, specsigflags, and specptr fields, so long as every combination of these fields that exists at any given point in time is valid to be called. This allows the JIT to update these fields without invalidating existing codeinsts, supporting a potential future concurrent JIT. Specifically, the following states may be valid:","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"invoke is NULL, specsigflags is 0b00, specptr is NULL\nThis is the initial state of a codeinst, and indicates that the codeinst has not yet been compiled.\ninvoke is non-null, specsigflags is 0b00, specptr is NULL\nThis indicates that the codeinst was not compiled with any specialization, and that the codeinst should be invoked directly. Note that in this instance, invoke does not read either the specsigflags or specptr fields, and therefore they may be modified without invalidating the invoke pointer.\ninvoke is non-null, specsigflags is 0b10, specptr is non-null\nThis indicates that the codeinst was compiled, but a specialized function signature was deemed unnecessary by codegen.\ninvoke is non-null, specsigflags is 0b11, specptr is non-null\nThis indicates that the codeinst was compiled, and a specialized function signature was deemed necessary by codegen. The specptr field contains a pointer to the specialized function signature. The invoke pointer is permitted to read both specsigflags and specptr fields.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"In addition, there are a number of different transitional states that occur during the update process. To account for these potential situations, the following write and read patterns should be used when dealing with these codeinst fields.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"When writing invoke, specsigflags, and specptr:\nPerform an atomic compare-exchange operation of specptr assuming the old value was NULL. This compare-exchange operation should have at least acquire-release ordering, to provide ordering guarantees of the remaining memory operations in the write.\nIf specptr was non-null, cease the write operation and wait for bit 0b10 of specsigflags to be written.\nWrite the new low bit of specsigflags to its final value. This may be a relaxed write.\nWrite the new invoke pointer to its final value. This must have at least a release memory ordering to synchronize with reads of invoke.\nSet the second bit of specsigflags to 1. This must be at least a release memory ordering to synchronize with reads of specsigflags. This step completes the write operation and announces to all other threads that all fields have been set.\nWhen reading all of invoke, specsigflags, and specptr:\nRead the invoke field with at least an acquire memory ordering. This load will be referred to as initial_invoke.\nIf initial_invoke is NULL, the codeinst is not yet executable. invoke is NULL, specsigflags may be treated as 0b00, specptr may be treated as NULL.\nRead the specptr field with at least an acquire memory ordering.\nIf specptr is NULL, then the initial_invoke pointer must not be relying on specptr to guarantee correct execution. Therefore, invoke is non-null, specsigflags may be treated as 0b00, specptr may be treated as NULL.\nIf specptr is non-null, then initial_invoke might not be the final invoke field that uses specptr. This can occur if specptr has been written, but invoke has not yet been written. Therefore, spin on the second bit of specsigflags until it is set to 1 with at least acquire memory ordering.\nRe-read the invoke field with at least an acquire memory ordering. This load will be referred to as final_invoke.\nRead the specsigflags field with any memory ordering.\ninvoke is final_invoke, specsigflags is the value read in step 7, specptr is the value read in step 3.\nWhen updating a specptr to a different but equivalent function pointer:\nPerform a release store of the new function pointer to specptr. Races here must be benign, as the old function pointer is required to still be valid, and any new ones are also required to be valid as well. Once a pointer has been written to specptr, it must always be callable whether or not it is later overwritten.","category":"page"},{"location":"devdocs/jit/","page":"JIT Design and Implementation","title":"JIT Design and Implementation","text":"Although these write, read, and update steps are complicated, they ensure that the JIT can update codeinsts without invalidating existing codeinsts, and that the JIT can update codeinsts without invalidating existing invoke pointers. This allows the JIT to potentially reoptimize functions at higher optimization levels in the future, and also will allow the JIT to support concurrent compilation of functions in the future.","category":"page"},{"location":"devdocs/gc/#Garbage-Collection-in-Julia","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"","category":"section"},{"location":"devdocs/gc/#Introduction","page":"Garbage Collection in Julia","title":"Introduction","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia has a non-moving, partially concurrent, parallel, generational and mostly precise mark-sweep collector (an interface for conservative stack scanning is provided as an option for users who wish to call Julia from C).","category":"page"},{"location":"devdocs/gc/#Allocation","page":"Garbage Collection in Julia","title":"Allocation","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia uses two types of allocators, the size of the allocation request determining which one is used. Objects up to 2k bytes are allocated on a per-thread free-list pool allocator, while objects larger than 2k bytes are allocated through libc malloc.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia’s pool allocator partitions objects on different size classes, so that a memory page managed by the pool allocator (which spans 4 operating system pages on 64bit platforms) only contains objects of the same size class. Each memory page from the pool allocator is paired with some page metadata stored on per-thread lock-free lists. The page metadata contains information such as whether the page has live objects at all, number of free slots, and offsets to the first and last objects in the free-list contained in that page. These metadata are used to optimize the collection phase: a page which has no live objects at all may be returned to the operating system without any need of scanning it, for example.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"While a page that has no objects may be returned to the operating system, its associated metadata is permanently allocated and may outlive the given page. As mentioned above, metadata for allocated pages are stored on per-thread lock-free lists. Metadata for free pages, however, may be stored into three separate lock-free lists depending on whether the page has been mapped but never accessed (page_pool_clean), or whether the page has been lazily sweeped and it's waiting to be madvised by a background GC thread (page_pool_lazily_freed), or whether the page has been madvised (page_pool_freed).","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia's pool allocator follows a \"tiered\" allocation discipline. When requesting a memory page for the pool allocator, Julia will:","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Try to claim a page from page_pool_lazily_freed, which contains pages which were empty on the last stop-the-world phase, but not yet madivsed by a concurrent sweeper GC thread.\nIf it failed claiming a page from page_pool_lazily_freed, it will try to claim a page from the page_pool_clean, which contains pages which were mmaped on a previous page allocation request but never accessed.\nIf it failed claiming a page from pool_page_clean and from page_pool_lazily_freed, it will try to claim a page from page_pool_freed, which contains pages which have already been madvised by a concurrent sweeper GC thread and whose underlying virtual address can be recycled.\nIf it failed in all of the attempts mentioned above, it will mmap a batch of pages, claim one page for itself, and insert the remaining pages into page_pool_clean.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"(Image: Diagram of tiered pool allocation)","category":"page"},{"location":"devdocs/gc/#Marking-and-Generational-Collection","page":"Garbage Collection in Julia","title":"Marking and Generational Collection","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Julia’s mark phase is implemented through a parallel iterative depth-first-search over the object graph. Julia’s collector is non-moving, so object age information can’t be determined through the memory region in which the object resides alone, but has to be somehow encoded in the object header or on a side table. The lowest two bits of an object’s header are used to store, respectively, a mark bit that is set when an object is scanned during the mark phase and an age bit for the generational collection.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Generational collection is implemented through sticky bits: objects are only pushed to the mark-stack, and therefore traced, if their mark-bits are not set. When objects reach the oldest generation, their mark-bits are not reset during the so-called \"quick-sweep\", which leads to these objects not being traced in a subsequent mark phase. A \"full-sweep\", however, causes the mark-bits of all objects to be reset, leading to all objects being traced in a subsequent mark phase. Objects are promoted to the next generation during every sweep phase they survive. On the mutator side, field writes are intercepted through a write barrier that pushes an object’s address into a per-thread remembered set if the object is in the last generation, and if the object at the field being written is not. Objects in this remembered set are then traced during the mark phase.","category":"page"},{"location":"devdocs/gc/#Sweeping","page":"Garbage Collection in Julia","title":"Sweeping","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"Sweeping of object pools for Julia may fall into two categories: if a given page managed by the pool allocator contains at least one live object, then a free-list must be threaded through its dead objects; if a given page contains no live objects at all, then its underlying physical memory may be returned to the operating system through, for instance, the use of madvise system calls on Linux.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"The first category of sweeping is parallelized through work-stealing. For the second category of sweeping, if concurrent page sweeping is enabled through the flag --gcthreads=X,1 we perform the madvise system calls in a background sweeper thread, concurrently with the mutator threads. During the stop-the-world phase of the collector, pool allocated pages which contain no live objects are initially pushed into the pool_page_lazily_freed. The background sweeping thread is then woken up and is responsible for removing pages from pool_page_lazily_freed, calling madvise on them, and inserting them into pool_page_freed. As described above, pool_page_lazily_freed is also shared with mutator threads. This implies that on allocation-heavy multithreaded workloads, mutator threads would often avoid a page fault on allocation (coming from accessing a fresh mmaped page or accessing a madvised page) by directly allocating from a page in pool_page_lazily_freed, while the background sweeper thread needs to madvise a reduce number of pages given some of them were already claimed by the mutators.","category":"page"},{"location":"devdocs/gc/#Heuristics","page":"Garbage Collection in Julia","title":"Heuristics","text":"","category":"section"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"GC heuristics tune the GC by changing the size of the allocation interval between garbage collections.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"The GC heuristics measure how big the heap size is after a collection and set the next collection according to the algorithm described by https://dl.acm.org/doi/10.1145/3563323, in summary, it argues that the heap target should have a square root relationship with the live heap, and that it should also be scaled by how fast the GC is freeing objects and how fast the mutators are allocating. The heuristics measure the heap size by counting the number of pages that are in use and the objects that use malloc. Previously we measured the heap size by counting the alive objects, but that doesn't take into account fragmentation which could lead to bad decisions, that also meant that we used thread local information (allocations) to make decisions about a process wide (when to GC), measuring pages means the decision is global.","category":"page"},{"location":"devdocs/gc/","page":"Garbage Collection in Julia","title":"Garbage Collection in Julia","text":"The GC will do full collections when the heap size reaches 80% of the maximum allowed size.","category":"page"},{"location":"manual/constructors/#man-constructors","page":"Constructors","title":"Constructors","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Constructors [1] are functions that create new objects – specifically, instances of Composite Types. In Julia, type objects also serve as constructor functions: they create new instances of themselves when applied to an argument tuple as a function. This much was already mentioned briefly when composite types were introduced. For example:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct Foo\n bar\n baz\n end\n\njulia> foo = Foo(1, 2)\nFoo(1, 2)\n\njulia> foo.bar\n1\n\njulia> foo.baz\n2","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"For many types, forming new objects by binding their field values together is all that is ever needed to create instances. However, in some cases more functionality is required when creating composite objects. Sometimes invariants must be enforced, either by checking arguments or by transforming them. Recursive data structures, especially those that may be self-referential, often cannot be constructed cleanly without first being created in an incomplete state and then altered programmatically to be made whole, as a separate step from object creation. Sometimes, it's just convenient to be able to construct objects with fewer or different types of parameters than they have fields. Julia's system for object construction addresses all of these cases and more.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"[1]: Nomenclature: while the term \"constructor\" generally refers to the entire function which constructs objects of a type, it is common to abuse terminology slightly and refer to specific constructor methods as \"constructors\". In such situations, it is generally clear from the context that the term is used to mean \"constructor method\" rather than \"constructor function\", especially as it is often used in the sense of singling out a particular method of the constructor from all of the others.","category":"page"},{"location":"manual/constructors/#man-outer-constructor-methods","page":"Constructors","title":"Outer Constructor Methods","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"A constructor is just like any other function in Julia in that its overall behavior is defined by the combined behavior of its methods. Accordingly, you can add functionality to a constructor by simply defining new methods. For example, let's say you want to add a constructor method for Foo objects that takes only one argument and uses the given value for both the bar and baz fields. This is simple:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Foo(x) = Foo(x,x)\nFoo\n\njulia> Foo(1)\nFoo(1, 1)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"You could also add a zero-argument Foo constructor method that supplies default values for both of the bar and baz fields:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Foo() = Foo(0)\nFoo\n\njulia> Foo()\nFoo(0, 0)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Here the zero-argument constructor method calls the single-argument constructor method, which in turn calls the automatically provided two-argument constructor method. For reasons that will become clear very shortly, additional constructor methods declared as normal methods like this are called outer constructor methods. Outer constructor methods can only ever create a new instance by calling another constructor method, such as the automatically provided default ones.","category":"page"},{"location":"manual/constructors/#man-inner-constructor-methods","page":"Constructors","title":"Inner Constructor Methods","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"While outer constructor methods succeed in addressing the problem of providing additional convenience methods for constructing objects, they fail to address the other two use cases mentioned in the introduction of this chapter: enforcing invariants, and allowing construction of self-referential objects. For these problems, one needs inner constructor methods. An inner constructor method is like an outer constructor method, except for two differences:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"It is declared inside the block of a type declaration, rather than outside of it like normal methods.\nIt has access to a special locally existent function called new that creates objects of the block's type.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"For example, suppose one wants to declare a type that holds a pair of real numbers, subject to the constraint that the first number is not greater than the second one. One could declare it like this:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct OrderedPair\n x::Real\n y::Real\n OrderedPair(x,y) = x > y ? error(\"out of order\") : new(x,y)\n end","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Now OrderedPair objects can only be constructed such that x <= y:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> OrderedPair(1, 2)\nOrderedPair(1, 2)\n\njulia> OrderedPair(2,1)\nERROR: out of order\nStacktrace:\n [1] error at ./error.jl:33 [inlined]\n [2] OrderedPair(::Int64, ::Int64) at ./none:4\n [3] top-level scope","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"If the type were declared mutable, you could reach in and directly change the field values to violate this invariant. Of course, messing around with an object's internals uninvited is bad practice. You (or someone else) can also provide additional outer constructor methods at any later point, but once a type is declared, there is no way to add more inner constructor methods. Since outer constructor methods can only create objects by calling other constructor methods, ultimately, some inner constructor must be called to create an object. This guarantees that all objects of the declared type must come into existence by a call to one of the inner constructor methods provided with the type, thereby giving some degree of enforcement of a type's invariants.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"If any inner constructor method is defined, no default constructor method is provided: it is presumed that you have supplied yourself with all the inner constructors you need. The default constructor is equivalent to writing your own inner constructor method that takes all of the object's fields as parameters (constrained to be of the correct type, if the corresponding field has a type), and passes them to new, returning the resulting object:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct Foo\n bar\n baz\n Foo(bar,baz) = new(bar,baz)\n end\n","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This declaration has the same effect as the earlier definition of the Foo type without an explicit inner constructor method. The following two types are equivalent – one with a default constructor, the other with an explicit constructor:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct T1\n x::Int64\n end\n\njulia> struct T2\n x::Int64\n T2(x) = new(x)\n end\n\njulia> T1(1)\nT1(1)\n\njulia> T2(1)\nT2(1)\n\njulia> T1(1.0)\nT1(1)\n\njulia> T2(1.0)\nT2(1)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"It is good practice to provide as few inner constructor methods as possible: only those taking all arguments explicitly and enforcing essential error checking and transformation. Additional convenience constructor methods, supplying default values or auxiliary transformations, should be provided as outer constructors that call the inner constructors to do the heavy lifting. This separation is typically quite natural.","category":"page"},{"location":"manual/constructors/#Incomplete-Initialization","page":"Constructors","title":"Incomplete Initialization","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The final problem which has still not been addressed is construction of self-referential objects, or more generally, recursive data structures. Since the fundamental difficulty may not be immediately obvious, let us briefly explain it. Consider the following recursive type declaration:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> mutable struct SelfReferential\n obj::SelfReferential\n end\n","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This type may appear innocuous enough, until one considers how to construct an instance of it. If a is an instance of SelfReferential, then a second instance can be created by the call:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> b = SelfReferential(a)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"But how does one construct the first instance when no instance exists to provide as a valid value for its obj field? The only solution is to allow creating an incompletely initialized instance of SelfReferential with an unassigned obj field, and using that incomplete instance as a valid value for the obj field of another instance, such as, for example, itself.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"To allow for the creation of incompletely initialized objects, Julia allows the new function to be called with fewer than the number of fields that the type has, returning an object with the unspecified fields uninitialized. The inner constructor method can then use the incomplete object, finishing its initialization before returning it. Here, for example, is another attempt at defining the SelfReferential type, this time using a zero-argument inner constructor returning instances having obj fields pointing to themselves:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> mutable struct SelfReferential\n obj::SelfReferential\n SelfReferential() = (x = new(); x.obj = x)\n end\n","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"We can verify that this constructor works and constructs objects that are, in fact, self-referential:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> x = SelfReferential();\n\njulia> x === x\ntrue\n\njulia> x === x.obj\ntrue\n\njulia> x === x.obj.obj\ntrue","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Although it is generally a good idea to return a fully initialized object from an inner constructor, it is possible to return incompletely initialized objects:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> mutable struct Incomplete\n data\n Incomplete() = new()\n end\n\njulia> z = Incomplete();","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"While you are allowed to create objects with uninitialized fields, any access to an uninitialized reference is an immediate error:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> z.data\nERROR: UndefRefError: access to undefined reference","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This avoids the need to continually check for null values. However, not all object fields are references. Julia considers some types to be \"plain data\", meaning all of their data is self-contained and does not reference other objects. The plain data types consist of primitive types (e.g. Int) and immutable structs of other plain data types (see also: isbits, isbitstype). The initial contents of a plain data type is undefined:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct HasPlain\n n::Int\n HasPlain() = new()\n end\n\njulia> HasPlain()\nHasPlain(438103441441)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Arrays of plain data types exhibit the same behavior.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"You can pass incomplete objects to other functions from inner constructors to delegate their completion:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> mutable struct Lazy\n data\n Lazy(v) = complete_me(new(), v)\n end","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"As with incomplete objects returned from constructors, if complete_me or any of its callees try to access the data field of the Lazy object before it has been initialized, an error will be thrown immediately.","category":"page"},{"location":"manual/constructors/#Parametric-Constructors","page":"Constructors","title":"Parametric Constructors","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Parametric types add a few wrinkles to the constructor story. Recall from Parametric Types that, by default, instances of parametric composite types can be constructed either with explicitly given type parameters or with type parameters implied by the types of the arguments given to the constructor. Here are some examples:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct Point{T<:Real}\n x::T\n y::T\n end\n\njulia> Point(1,2) ## implicit T ##\nPoint{Int64}(1, 2)\n\njulia> Point(1.0,2.5) ## implicit T ##\nPoint{Float64}(1.0, 2.5)\n\njulia> Point(1,2.5) ## implicit T ##\nERROR: MethodError: no method matching Point(::Int64, ::Float64)\nThe type `Point` exists, but no method is defined for this combination of argument types when trying to construct it.\n\nClosest candidates are:\n Point(::T, ::T) where T<:Real at none:2\n\njulia> Point{Int64}(1, 2) ## explicit T ##\nPoint{Int64}(1, 2)\n\njulia> Point{Int64}(1.0,2.5) ## explicit T ##\nERROR: InexactError: Int64(2.5)\nStacktrace:\n[...]\n\njulia> Point{Float64}(1.0, 2.5) ## explicit T ##\nPoint{Float64}(1.0, 2.5)\n\njulia> Point{Float64}(1,2) ## explicit T ##\nPoint{Float64}(1.0, 2.0)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"As you can see, for constructor calls with explicit type parameters, the arguments are converted to the implied field types: Point{Int64}(1,2) works, but Point{Int64}(1.0,2.5) raises an InexactError when converting 2.5 to Int64. When the type is implied by the arguments to the constructor call, as in Point(1,2), then the types of the arguments must agree – otherwise the T cannot be determined – but any pair of real arguments with matching type may be given to the generic Point constructor.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"What's really going on here is that Point, Point{Float64} and Point{Int64} are all different constructor functions. In fact, Point{T} is a distinct constructor function for each type T. Without any explicitly provided inner constructors, the declaration of the composite type Point{T<:Real} automatically provides an inner constructor, Point{T}, for each possible type T<:Real, that behaves just like non-parametric default inner constructors do. It also provides a single general outer Point constructor that takes pairs of real arguments, which must be of the same type. This automatic provision of constructors is equivalent to the following explicit declaration:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct Point{T<:Real}\n x::T\n y::T\n Point{T}(x,y) where {T<:Real} = new(x,y)\n end\n\njulia> Point(x::T, y::T) where {T<:Real} = Point{T}(x,y);","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Notice that each definition looks like the form of constructor call that it handles. The call Point{Int64}(1,2) will invoke the definition Point{T}(x,y) inside the struct block. The outer constructor declaration, on the other hand, defines a method for the general Point constructor which only applies to pairs of values of the same real type. This declaration makes constructor calls without explicit type parameters, like Point(1,2) and Point(1.0,2.5), work. Since the method declaration restricts the arguments to being of the same type, calls like Point(1,2.5), with arguments of different types, result in \"no method\" errors.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Suppose we wanted to make the constructor call Point(1,2.5) work by \"promoting\" the integer value 1 to the floating-point value 1.0. The simplest way to achieve this is to define the following additional outer constructor method:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Point(x::Int64, y::Float64) = Point(convert(Float64,x),y);","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This method uses the convert function to explicitly convert x to Float64 and then delegates construction to the general constructor for the case where both arguments are Float64. With this method definition what was previously a MethodError now successfully creates a point of type Point{Float64}:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> p = Point(1,2.5)\nPoint{Float64}(1.0, 2.5)\n\njulia> typeof(p)\nPoint{Float64}","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"However, other similar calls still don't work:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Point(1.5,2)\nERROR: MethodError: no method matching Point(::Float64, ::Int64)\nThe type `Point` exists, but no method is defined for this combination of argument types when trying to construct it.\n\nClosest candidates are:\n Point(::T, !Matched::T) where T<:Real\n @ Main none:1\n Point(!Matched::Int64, !Matched::Float64)\n @ Main none:1\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"For a more general way to make all such calls work sensibly, see Conversion and Promotion. At the risk of spoiling the suspense, we can reveal here that all it takes is the following outer method definition to make all calls to the general Point constructor work as one would expect:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Point(x::Real, y::Real) = Point(promote(x,y)...);","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The promote function converts all its arguments to a common type – in this case Float64. With this method definition, the Point constructor promotes its arguments the same way that numeric operators like + do, and works for all kinds of real numbers:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> Point(1.5,2)\nPoint{Float64}(1.5, 2.0)\n\njulia> Point(1,1//2)\nPoint{Rational{Int64}}(1//1, 1//2)\n\njulia> Point(1.0,1//2)\nPoint{Float64}(1.0, 0.5)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Thus, while the implicit type parameter constructors provided by default in Julia are fairly strict, it is possible to make them behave in a more relaxed but sensible manner quite easily. Moreover, since constructors can leverage all of the power of the type system, methods, and multiple dispatch, defining sophisticated behavior is typically quite simple.","category":"page"},{"location":"manual/constructors/#Case-Study:-Rational","page":"Constructors","title":"Case Study: Rational","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Perhaps the best way to tie all these pieces together is to present a real world example of a parametric composite type and its constructor methods. To that end, we implement our own rational number type OurRational, similar to Julia's built-in Rational type, defined in rational.jl:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct OurRational{T<:Integer} <: Real\n num::T\n den::T\n function OurRational{T}(num::T, den::T) where T<:Integer\n if num == 0 && den == 0\n error(\"invalid rational: 0//0\")\n end\n num = flipsign(num, den)\n den = flipsign(den, den)\n g = gcd(num, den)\n num = div(num, g)\n den = div(den, g)\n new(num, den)\n end\n end\n\njulia> OurRational(n::T, d::T) where {T<:Integer} = OurRational{T}(n,d)\nOurRational\n\njulia> OurRational(n::Integer, d::Integer) = OurRational(promote(n,d)...)\nOurRational\n\njulia> OurRational(n::Integer) = OurRational(n,one(n))\nOurRational\n\njulia> ⊘(n::Integer, d::Integer) = OurRational(n,d)\n⊘ (generic function with 1 method)\n\njulia> ⊘(x::OurRational, y::Integer) = x.num ⊘ (x.den*y)\n⊘ (generic function with 2 methods)\n\njulia> ⊘(x::Integer, y::OurRational) = (x*y.den) ⊘ y.num\n⊘ (generic function with 3 methods)\n\njulia> ⊘(x::Complex, y::Real) = complex(real(x) ⊘ y, imag(x) ⊘ y)\n⊘ (generic function with 4 methods)\n\njulia> ⊘(x::Real, y::Complex) = (x*y') ⊘ real(y*y')\n⊘ (generic function with 5 methods)\n\njulia> function ⊘(x::Complex, y::Complex)\n xy = x*y'\n yy = real(y*y')\n complex(real(xy) ⊘ yy, imag(xy) ⊘ yy)\n end\n⊘ (generic function with 6 methods)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The first line – struct OurRational{T<:Integer} <: Real – declares that OurRational takes one type parameter of an integer type, and is itself a real type. The field declarations num::T and den::T indicate that the data held in a OurRational{T} object are a pair of integers of type T, one representing the rational value's numerator and the other representing its denominator.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Now things get interesting. OurRational has a single inner constructor method which checks that num and den aren't both zero and ensures that every rational is constructed in \"lowest terms\" with a non-negative denominator. This is accomplished by first flipping the signs of numerator and denominator if the denominator is negative. Then, both are divided by their greatest common divisor (gcd always returns a non-negative number, regardless of the sign of its arguments). Because this is the only inner constructor for OurRational, we can be certain that OurRational objects are always constructed in this normalized form.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"OurRational also provides several outer constructor methods for convenience. The first is the \"standard\" general constructor that infers the type parameter T from the type of the numerator and denominator when they have the same type. The second applies when the given numerator and denominator values have different types: it promotes them to a common type and then delegates construction to the outer constructor for arguments of matching type. The third outer constructor turns integer values into rationals by supplying a value of 1 as the denominator.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Following the outer constructor definitions, we defined a number of methods for the ⊘ operator, which provides a syntax for writing rationals (e.g. 1 ⊘ 2). Julia's Rational type uses the // operator for this purpose. Before these definitions, ⊘ is a completely undefined operator with only syntax and no meaning. Afterwards, it behaves just as described in Rational Numbers – its entire behavior is defined in these few lines. Note that the infix use of ⊘ works because Julia has a set of symbols that are recognized to be infix operators. The first and most basic definition just makes a ⊘ b construct a OurRational by applying the OurRational constructor to a and b when they are integers. When one of the operands of ⊘ is already a rational number, we construct a new rational for the resulting ratio slightly differently; this behavior is actually identical to division of a rational with an integer. Finally, applying ⊘ to complex integral values creates an instance of Complex{<:OurRational} – a complex number whose real and imaginary parts are rationals:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> z = (1 + 2im) ⊘ (1 - 2im);\n\njulia> typeof(z)\nComplex{OurRational{Int64}}\n\njulia> typeof(z) <: Complex{<:OurRational}\ntrue","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"Thus, although the ⊘ operator usually returns an instance of OurRational, if either of its arguments are complex integers, it will return an instance of Complex{<:OurRational} instead. The interested reader should consider perusing the rest of rational.jl: it is short, self-contained, and implements an entire basic Julia type.","category":"page"},{"location":"manual/constructors/#Outer-only-constructors","page":"Constructors","title":"Outer-only constructors","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"As we have seen, a typical parametric type has inner constructors that are called when type parameters are known; e.g. they apply to Point{Int} but not to Point. Optionally, outer constructors that determine type parameters automatically can be added, for example constructing a Point{Int} from the call Point(1,2). Outer constructors call inner constructors to actually make instances. However, in some cases one would rather not provide inner constructors, so that specific type parameters cannot be requested manually.","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"For example, say we define a type that stores a vector along with an accurate representation of its sum:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct SummedArray{T<:Number,S<:Number}\n data::Vector{T}\n sum::S\n end\n\njulia> SummedArray(Int32[1; 2; 3], Int32(6))\nSummedArray{Int32, Int32}(Int32[1, 2, 3], 6)","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The problem is that we want S to be a larger type than T, so that we can sum many elements with less information loss. For example, when T is Int32, we would like S to be Int64. Therefore we want to avoid an interface that allows the user to construct instances of the type SummedArray{Int32,Int32}. One way to do this is to provide a constructor only for SummedArray, but inside the struct definition block to suppress generation of default constructors:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct SummedArray{T<:Number,S<:Number}\n data::Vector{T}\n sum::S\n function SummedArray(a::Vector{T}) where T\n S = widen(T)\n new{T,S}(a, sum(S, a))\n end\n end\n\njulia> SummedArray(Int32[1; 2; 3], Int32(6))\nERROR: MethodError: no method matching SummedArray(::Vector{Int32}, ::Int32)\nThe type `SummedArray` exists, but no method is defined for this combination of argument types when trying to construct it.\n\nClosest candidates are:\n SummedArray(::Vector{T}) where T\n @ Main none:4\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"This constructor will be invoked by the syntax SummedArray(a). The syntax new{T,S} allows specifying parameters for the type to be constructed, i.e. this call will return a SummedArray{T,S}. new{T,S} can be used in any constructor definition, but for convenience the parameters to new{} are automatically derived from the type being constructed when possible.","category":"page"},{"location":"manual/constructors/#Constructors-are-just-callable-objects","page":"Constructors","title":"Constructors are just callable objects","text":"","category":"section"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"An object of any type may be made callable by defining a method. This includes types, i.e., objects of type Type; and constructors may, in fact, be viewed as just callable type objects. For example, there are many methods defined on Bool and various supertypes of it:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> methods(Bool)\n# 10 methods for type constructor:\n [1] Bool(x::BigFloat)\n @ Base.MPFR mpfr.jl:393\n [2] Bool(x::Float16)\n @ Base float.jl:338\n [3] Bool(x::Rational)\n @ Base rational.jl:138\n [4] Bool(x::Real)\n @ Base float.jl:233\n [5] (dt::Type{<:Integer})(ip::Sockets.IPAddr)\n @ Sockets ~/tmp/jl/jl/julia-nightly-assert/share/julia/stdlib/v1.11/Sockets/src/IPAddr.jl:11\n [6] (::Type{T})(x::Enum{T2}) where {T<:Integer, T2<:Integer}\n @ Base.Enums Enums.jl:19\n [7] (::Type{T})(z::Complex) where T<:Real\n @ Base complex.jl:44\n [8] (::Type{T})(x::Base.TwicePrecision) where T<:Number\n @ Base twiceprecision.jl:265\n [9] (::Type{T})(x::T) where T<:Number\n @ boot.jl:894\n [10] (::Type{T})(x::AbstractChar) where T<:Union{AbstractChar, Number}\n @ char.jl:50","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"The usual constructor syntax is exactly equivalent to the function-like object syntax, so trying to define a method with each syntax will cause the first method to be overwritten by the next one:","category":"page"},{"location":"manual/constructors/","page":"Constructors","title":"Constructors","text":"julia> struct S\n f::Int\n end\n\njulia> S() = S(7)\nS\n\njulia> (::Type{S})() = S(8) # overwrites the previous constructor method\n\njulia> S()\nS(8)","category":"page"},{"location":"devdocs/builtins/#lib-builtins","page":"Core.Builtins","title":"Core.Builtins","text":"","category":"section"},{"location":"devdocs/builtins/#Builtin-Function-APIs","page":"Core.Builtins","title":"Builtin Function APIs","text":"","category":"section"},{"location":"devdocs/builtins/","page":"Core.Builtins","title":"Core.Builtins","text":"The following Builtin function APIs are considered unstable, but provide the basic definitions for what defines the abilities and behaviors of a Julia program. They are typically accessed through a higher level generic API.","category":"page"},{"location":"devdocs/builtins/","page":"Core.Builtins","title":"Core.Builtins","text":"Core.memoryref\nCore.memoryrefoffset\nCore.memoryrefget\nCore.memoryrefset!\nCore.memoryref_isassigned\nCore.memoryrefswap!\nCore.memoryrefmodify!\nCore.memoryrefreplace!\nCore.memoryrefsetonce!\nCore.Intrinsics.atomic_pointerref\nCore.Intrinsics.atomic_pointerset\nCore.Intrinsics.atomic_pointerswap\nCore.Intrinsics.atomic_pointermodify\nCore.Intrinsics.atomic_pointerreplace\nCore.get_binding_type\nCore.set_binding_type!\nCore.IntrinsicFunction\nCore.Intrinsics\nCore.IR","category":"page"},{"location":"devdocs/builtins/#Core.memoryref","page":"Core.Builtins","title":"Core.memoryref","text":"Core.memoryref(::GenericMemory)\nCore.memoryref(::GenericMemoryRef, index::Int, [boundscheck::Bool])\n\nReturn a GenericMemoryRef for a GenericMemory. See MemoryRef.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefoffset","page":"Core.Builtins","title":"Core.memoryrefoffset","text":"Core..memoryrefoffset(::GenericMemoryRef)\n\nReturn the offset index that was used to construct the MemoryRef. See Core.memoryref.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefget","page":"Core.Builtins","title":"Core.memoryrefget","text":"Core.memoryrefget(::GenericMemoryRef, ordering::Symbol, boundscheck::Bool)\n\nReturn the value stored at the MemoryRef, throwing a BoundsError if the Memory is empty. See ref[]. The memory ordering specified must be compatible with the isatomic parameter.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefset!","page":"Core.Builtins","title":"Core.memoryrefset!","text":"Core.memoryrefset!(::GenericMemoryRef, value, ordering::Symbol, boundscheck::Bool)\n\nStore the value to the MemoryRef, throwing a BoundsError if the Memory is empty. See ref[] = value. The memory ordering specified must be compatible with the isatomic parameter.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryref_isassigned","page":"Core.Builtins","title":"Core.memoryref_isassigned","text":"Core.memoryref_isassigned(::GenericMemoryRef, ordering::Symbol, boundscheck::Bool)\n\nReturn whether there is a value stored at the MemoryRef, returning false if the Memory is empty. See isassigned(::Base.RefValue), Core.memoryrefget. The memory ordering specified must be compatible with the isatomic parameter.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefswap!","page":"Core.Builtins","title":"Core.memoryrefswap!","text":"Core.memoryrefswap!(::GenericMemoryRef, value, ordering::Symbol, boundscheck::Bool)\n\nAtomically perform the operations to simultaneously get and set a MemoryRef value.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also swapproperty! and Core.memoryrefset!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefmodify!","page":"Core.Builtins","title":"Core.memoryrefmodify!","text":"Core.memoryrefmodify!(::GenericMemoryRef, op, value, ordering::Symbol, boundscheck::Bool) -> Pair\n\nAtomically perform the operations to get and set a MemoryRef value after applying the function op.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also modifyproperty! and Core.memoryrefset!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefreplace!","page":"Core.Builtins","title":"Core.memoryrefreplace!","text":"Core.memoryrefreplace!(::GenericMemoryRef, expected, desired,\n success_order::Symbol, fail_order::Symbol=success_order, boundscheck::Bool) -> (; old, success::Bool)\n\nAtomically perform the operations to get and conditionally set a MemoryRef value.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also replaceproperty! and Core.memoryrefset!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.memoryrefsetonce!","page":"Core.Builtins","title":"Core.memoryrefsetonce!","text":"Core.memoryrefsetonce!(::GenericMemoryRef, value,\n success_order::Symbol, fail_order::Symbol=success_order, boundscheck::Bool) -> success::Bool\n\nAtomically perform the operations to set a MemoryRef to a given value, only if it was previously not set.\n\ncompat: Julia 1.11\nThis function requires Julia 1.11 or later.\n\nSee also setpropertyonce! and Core.memoryrefset!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointerref","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointerref","text":"Core.Intrinsics.atomic_pointerref(pointer::Ptr{T}, order::Symbol) --> T\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_load.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointerset","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointerset","text":"Core.Intrinsics.atomic_pointerset(pointer::Ptr{T}, new::T, order::Symbol) --> pointer\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_store!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointerswap","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointerswap","text":"Core.Intrinsics.atomic_pointerswap(pointer::Ptr{T}, new::T, order::Symbol) --> old\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_swap!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointermodify","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointermodify","text":"Core.Intrinsics.atomic_pointermodify(pointer::Ptr{T}, function::(old::T,arg::S)->T, arg::S, order::Symbol) --> old\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_modify!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.Intrinsics.atomic_pointerreplace","page":"Core.Builtins","title":"Core.Intrinsics.atomic_pointerreplace","text":"Core.Intrinsics.atomic_pointerreplace(pointer::Ptr{T}, expected::Any, new::T, success_order::Symbol, failure_order::Symbol) --> (old, cmp)\n\ncompat: Julia 1.7\nThis function requires Julia 1.7 or later.\n\nSee unsafe_replace!.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.get_binding_type","page":"Core.Builtins","title":"Core.get_binding_type","text":"Core.get_binding_type(module::Module, name::Symbol)\n\nRetrieve the declared type of the binding name from the module module.\n\ncompat: Julia 1.9\nThis function requires Julia 1.9 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.set_binding_type!","page":"Core.Builtins","title":"Core.set_binding_type!","text":"Core.set_binding_type!(module::Module, name::Symbol, [type::Type])\n\nSet the declared type of the binding name in the module module to type. Error if the binding already has a type that is not equivalent to type. If the type argument is absent, set the binding type to Any if unset, but do not error.\n\ncompat: Julia 1.9\nThis function requires Julia 1.9 or later.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/builtins/#Core.IntrinsicFunction","page":"Core.Builtins","title":"Core.IntrinsicFunction","text":"Core.IntrinsicFunction <: Core.Builtin <: Function\n\nThe Core.IntrinsicFunction function define some basic primitives for what defines the abilities and behaviors of a Julia program\n\n\n\n\n\n","category":"type"},{"location":"devdocs/builtins/#Core.Intrinsics","page":"Core.Builtins","title":"Core.Intrinsics","text":"Core.Intrinsics\n\nThe Core.Intrinsics module holds the Core.IntrinsicFunction objects.\n\n\n\n\n\n","category":"module"},{"location":"devdocs/builtins/#Core.IR","page":"Core.Builtins","title":"Core.IR","text":"Core.IR\n\nThe Core.IR module exports the IR object model.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/SHA/#SHA","page":"SHA","title":"SHA","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"DocTestSetup = quote\n using SHA\n using InteractiveUtils\nend","category":"page"},{"location":"stdlib/SHA/#SHA-functions","page":"SHA","title":"SHA functions","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Usage is very straightforward:","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"julia> using SHA\n\njulia> bytes2hex(sha256(\"test\"))\n\"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08\"","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Each exported function (at the time of this writing, SHA-1, SHA-2 224, 256, 384 and 512, and SHA-3 224, 256, 384 and 512 functions are implemented) takes in either an AbstractVector{UInt8}, an AbstractString or an IO object. This makes it trivial to checksum a file:","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"shell> cat /tmp/test.txt\ntest\njulia> using SHA\n\njulia> open(\"/tmp/test.txt\") do f\n sha2_256(f)\n end\n32-element Array{UInt8,1}:\n 0x9f\n 0x86\n 0xd0\n 0x81\n 0x88\n 0x4c\n 0x7d\n 0x65\n ⋮\n 0x5d\n 0x6c\n 0x15\n 0xb0\n 0xf0\n 0x0a\n 0x08","category":"page"},{"location":"stdlib/SHA/#All-SHA-functions","page":"SHA","title":"All SHA functions","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Due to the colloquial usage of sha256 to refer to sha2_256, convenience functions are provided, mapping shaxxx() function calls to sha2_xxx(). For SHA-3, no such colloquialisms exist and the user must use the full sha3_xxx() names.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"shaxxx() takes AbstractString and array-like objects (NTuple and Array) with elements of type UInt8.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-1","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"sha1","category":"page"},{"location":"stdlib/SHA/#SHA.sha1","page":"SHA","title":"SHA.sha1","text":"sha1(data)\n\nHash data using the sha1 algorithm and return the resulting digest. See also SHA1_CTX.\n\n\n\n\n\nsha1(io::IO)\n\nHash data from io using sha1 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-2","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"sha224\nsha256\nsha384\nsha512\nsha2_224\nsha2_256\nsha2_384\nsha2_512","category":"page"},{"location":"stdlib/SHA/#SHA.sha224","page":"SHA","title":"SHA.sha224","text":"sha224(data)\n\nHash data using the sha224 algorithm and return the resulting digest. See also SHA2_224_CTX.\n\n\n\n\n\nsha224(io::IO)\n\nHash data from io using sha224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha256","page":"SHA","title":"SHA.sha256","text":"sha256(data)\n\nHash data using the sha256 algorithm and return the resulting digest. See also SHA2_256_CTX.\n\n\n\n\n\nsha256(io::IO)\n\nHash data from io using sha256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha384","page":"SHA","title":"SHA.sha384","text":"sha384(data)\n\nHash data using the sha384 algorithm and return the resulting digest. See also SHA2_384_CTX.\n\n\n\n\n\nsha384(io::IO)\n\nHash data from io using sha384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha512","page":"SHA","title":"SHA.sha512","text":"sha512(data)\n\nHash data using the sha512 algorithm and return the resulting digest. See also SHA2_512_CTX.\n\n\n\n\n\nsha512(io::IO)\n\nHash data from io using sha512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha2_224","page":"SHA","title":"SHA.sha2_224","text":"sha2_224(data)\n\nHash data using the sha2_224 algorithm and return the resulting digest. See also SHA2_224_CTX.\n\n\n\n\n\nsha2_224(io::IO)\n\nHash data from io using sha2_224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha2_256","page":"SHA","title":"SHA.sha2_256","text":"sha2_256(data)\n\nHash data using the sha2_256 algorithm and return the resulting digest. See also SHA2_256_CTX.\n\n\n\n\n\nsha2_256(io::IO)\n\nHash data from io using sha2_256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha2_384","page":"SHA","title":"SHA.sha2_384","text":"sha2_384(data)\n\nHash data using the sha2_384 algorithm and return the resulting digest. See also SHA2_384_CTX.\n\n\n\n\n\nsha2_384(io::IO)\n\nHash data from io using sha2_384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha2_512","page":"SHA","title":"SHA.sha2_512","text":"sha2_512(data)\n\nHash data using the sha2_512 algorithm and return the resulting digest. See also SHA2_512_CTX.\n\n\n\n\n\nsha2_512(io::IO)\n\nHash data from io using sha2_512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-3","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"sha3_224\nsha3_256\nsha3_384\nsha3_512","category":"page"},{"location":"stdlib/SHA/#SHA.sha3_224","page":"SHA","title":"SHA.sha3_224","text":"sha3_224(data)\n\nHash data using the sha3_224 algorithm and return the resulting digest. See also SHA3_224_CTX.\n\n\n\n\n\nsha3_224(io::IO)\n\nHash data from io using sha3_224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha3_256","page":"SHA","title":"SHA.sha3_256","text":"sha3_256(data)\n\nHash data using the sha3_256 algorithm and return the resulting digest. See also SHA3_256_CTX.\n\n\n\n\n\nsha3_256(io::IO)\n\nHash data from io using sha3_256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha3_384","page":"SHA","title":"SHA.sha3_384","text":"sha3_384(data)\n\nHash data using the sha3_384 algorithm and return the resulting digest. See also SHA3_384_CTX.\n\n\n\n\n\nsha3_384(io::IO)\n\nHash data from io using sha3_384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.sha3_512","page":"SHA","title":"SHA.sha3_512","text":"sha3_512(data)\n\nHash data using the sha3_512 algorithm and return the resulting digest. See also SHA3_512_CTX.\n\n\n\n\n\nsha3_512(io::IO)\n\nHash data from io using sha3_512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#Working-with-context","page":"SHA","title":"Working with context","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"To create a hash from multiple items the SHAX_XXX_CTX() types can be used to create a stateful hash object that is updated with update! and finalized with digest!","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"julia> using SHA\n\njulia> ctx = SHA2_256_CTX()\nSHA2 256-bit hash state\n\njulia> update!(ctx, b\"some data\")\n0x0000000000000009\n\njulia> update!(ctx, b\"some more data\")\n0x0000000000000017\n\njulia> digest!(ctx)\n32-element Vector{UInt8}:\n 0xbe\n 0xcf\n 0x23\n 0xda\n 0xaf\n 0x02\n 0xf7\n 0xa3\n 0x57\n 0x92\n ⋮\n 0x89\n 0x4f\n 0x59\n 0xd8\n 0xb3\n 0xb4\n 0x81\n 0x8b\n 0xc5","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Note that, at the time of this writing, the SHA3 code is not optimized, and as such is roughly an order of magnitude slower than SHA2.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"update!\ndigest!","category":"page"},{"location":"stdlib/SHA/#SHA.update!","page":"SHA","title":"SHA.update!","text":"update!(context, data[, datalen])\n\nUpdate the SHA context with the bytes in data. See also digest! for finalizing the hash.\n\nExamples\n\njulia> ctx = SHA1_CTX()\nSHA1 hash state\n\njulia> update!(ctx, b\"data to to be hashed\")\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.digest!","page":"SHA","title":"SHA.digest!","text":"digest!(context)\n\nFinalize the SHA context and return the hash as array of bytes (Array{Uint8, 1}). Updating the context after calling digest! on it will error.\n\nExamples\n\njulia> ctx = SHA1_CTX()\nSHA1 hash state\n\njulia> update!(ctx, b\"data to to be hashed\")\n\njulia> digest!(ctx)\n20-element Array{UInt8,1}:\n 0x83\n 0xe4\n ⋮\n 0x89\n 0xf5\n\njulia> update!(ctx, b\"more data\")\nERROR: Cannot update CTX after `digest!` has been called on it\n[...]\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#All-SHA-context-types","page":"SHA","title":"All SHA context types","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-1","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA1_CTX","category":"page"},{"location":"stdlib/SHA/#SHA.SHA1_CTX","page":"SHA","title":"SHA.SHA1_CTX","text":"SHA1_CTX()\n\nConstruct an empty SHA1 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-2","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"Convenience types are also provided, where SHAXXX_CTX is a type alias for SHA2_XXX_CTX.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA224_CTX\nSHA256_CTX\nSHA384_CTX\nSHA512_CTX\nSHA2_224_CTX\nSHA2_256_CTX\nSHA2_384_CTX\nSHA2_512_CTX","category":"page"},{"location":"stdlib/SHA/#SHA.SHA224_CTX","page":"SHA","title":"SHA.SHA224_CTX","text":"SHA2_224_CTX()\n\nConstruct an empty SHA2_224 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA256_CTX","page":"SHA","title":"SHA.SHA256_CTX","text":"SHA2_256_CTX()\n\nConstruct an empty SHA2_256 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA384_CTX","page":"SHA","title":"SHA.SHA384_CTX","text":"SHA2_384()\n\nConstruct an empty SHA2_384 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA512_CTX","page":"SHA","title":"SHA.SHA512_CTX","text":"SHA2_512_CTX()\n\nConstruct an empty SHA2_512 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA2_224_CTX","page":"SHA","title":"SHA.SHA2_224_CTX","text":"SHA2_224_CTX()\n\nConstruct an empty SHA2_224 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA2_256_CTX","page":"SHA","title":"SHA.SHA2_256_CTX","text":"SHA2_256_CTX()\n\nConstruct an empty SHA2_256 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA2_384_CTX","page":"SHA","title":"SHA.SHA2_384_CTX","text":"SHA2_384()\n\nConstruct an empty SHA2_384 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA2_512_CTX","page":"SHA","title":"SHA.SHA2_512_CTX","text":"SHA2_512_CTX()\n\nConstruct an empty SHA2_512 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-3","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA3_224_CTX\nSHA3_256_CTX\nSHA3_384_CTX\nSHA3_512_CTX","category":"page"},{"location":"stdlib/SHA/#SHA.SHA3_224_CTX","page":"SHA","title":"SHA.SHA3_224_CTX","text":"SHA3_224_CTX()\n\nConstruct an empty SHA3_224 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA3_256_CTX","page":"SHA","title":"SHA.SHA3_256_CTX","text":"SHA3_256_CTX()\n\nConstruct an empty SHA3_256 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA3_384_CTX","page":"SHA","title":"SHA.SHA3_384_CTX","text":"SHA3_384_CTX()\n\nConstruct an empty SHA3_384 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#SHA.SHA3_512_CTX","page":"SHA","title":"SHA.SHA3_512_CTX","text":"SHA3_512_CTX()\n\nConstruct an empty SHA3_512 context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/#HMAC-functions","page":"SHA","title":"HMAC functions","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"julia> using SHA\n\njulia> key = collect(codeunits(\"key_string\"))\n10-element Vector{UInt8}:\n 0x6b\n 0x65\n 0x79\n 0x5f\n 0x73\n 0x74\n 0x72\n 0x69\n 0x6e\n 0x67\n\njulia> bytes2hex(hmac_sha3_256(key, \"test-message\"))\n\"bc49a6f2aa29b27ee5ed1e944edd7f3d153e8a01535d98b5e24dac9a589a6248\"","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"To create a hash from multiple items, the HMAC_CTX() types can be used to create a stateful hash object that is updated with update! and finalized with digest!.","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"julia> using SHA\n\njulia> key = collect(codeunits(\"key_string\"))\n10-element Vector{UInt8}:\n 0x6b\n 0x65\n 0x79\n 0x5f\n 0x73\n 0x74\n 0x72\n 0x69\n 0x6e\n 0x67\n\njulia> ctx = HMAC_CTX(SHA3_256_CTX(), key);\n\njulia> update!(ctx, b\"test-\")\n0x0000000000000000000000000000008d\n\njulia> update!(ctx, b\"message\")\n0x00000000000000000000000000000094\n\njulia> bytes2hex(digest!(ctx))\n\"bc49a6f2aa29b27ee5ed1e944edd7f3d153e8a01535d98b5e24dac9a589a6248\"","category":"page"},{"location":"stdlib/SHA/#All-HMAC-functions","page":"SHA","title":"All HMAC functions","text":"","category":"section"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"HMAC context type","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"HMAC_CTX","category":"page"},{"location":"stdlib/SHA/#SHA.HMAC_CTX","page":"SHA","title":"SHA.HMAC_CTX","text":"HMAC_CTX(ctx::CTX, key::Vector{UInt8}) where {CTX<:SHA_CTX}\n\nConstruct an empty HMAC_CTX context.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-1","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"hmac_sha1","category":"page"},{"location":"stdlib/SHA/#SHA.hmac_sha1","page":"SHA","title":"SHA.hmac_sha1","text":"hmac_sha1(key, data)\n\nHash data using the sha1 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha1(key, io::IO)\n\nHash data from io with the passed key using sha1 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-2","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"hmac_sha224\nhmac_sha256\nhmac_sha384\nhmac_sha512\nhmac_sha2_224\nhmac_sha2_256\nhmac_sha2_384\nhmac_sha2_512","category":"page"},{"location":"stdlib/SHA/#SHA.hmac_sha224","page":"SHA","title":"SHA.hmac_sha224","text":"hmac_sha224(key, data)\n\nHash data using the sha224 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha224(key, io::IO)\n\nHash data from io with the passed key using sha224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha256","page":"SHA","title":"SHA.hmac_sha256","text":"hmac_sha256(key, data)\n\nHash data using the sha256 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha256(key, io::IO)\n\nHash data from io with the passed key using sha256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha384","page":"SHA","title":"SHA.hmac_sha384","text":"hmac_sha384(key, data)\n\nHash data using the sha384 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha384(key, io::IO)\n\nHash data from io with the passed key using sha384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha512","page":"SHA","title":"SHA.hmac_sha512","text":"hmac_sha512(key, data)\n\nHash data using the sha512 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha512(key, io::IO)\n\nHash data from io with the passed key using sha512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha2_224","page":"SHA","title":"SHA.hmac_sha2_224","text":"hmac_sha2_224(key, data)\n\nHash data using the sha2_224 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha2_224(key, io::IO)\n\nHash data from io with the passed key using sha2_224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha2_256","page":"SHA","title":"SHA.hmac_sha2_256","text":"hmac_sha2_256(key, data)\n\nHash data using the sha2_256 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha2_256(key, io::IO)\n\nHash data from io with the passed key using sha2_256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha2_384","page":"SHA","title":"SHA.hmac_sha2_384","text":"hmac_sha2_384(key, data)\n\nHash data using the sha2_384 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha2_384(key, io::IO)\n\nHash data from io with the passed key using sha2_384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha2_512","page":"SHA","title":"SHA.hmac_sha2_512","text":"hmac_sha2_512(key, data)\n\nHash data using the sha2_512 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha2_512(key, io::IO)\n\nHash data from io with the passed key using sha2_512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"SHA-3","category":"page"},{"location":"stdlib/SHA/","page":"SHA","title":"SHA","text":"hmac_sha3_224\nhmac_sha3_256\nhmac_sha3_384\nhmac_sha3_512","category":"page"},{"location":"stdlib/SHA/#SHA.hmac_sha3_224","page":"SHA","title":"SHA.hmac_sha3_224","text":"hmac_sha3_224(key, data)\n\nHash data using the sha3_224 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha3_224(key, io::IO)\n\nHash data from io with the passed key using sha3_224 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha3_256","page":"SHA","title":"SHA.hmac_sha3_256","text":"hmac_sha3_256(key, data)\n\nHash data using the sha3_256 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha3_256(key, io::IO)\n\nHash data from io with the passed key using sha3_256 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha3_384","page":"SHA","title":"SHA.hmac_sha3_384","text":"hmac_sha3_384(key, data)\n\nHash data using the sha3_384 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha3_384(key, io::IO)\n\nHash data from io with the passed key using sha3_384 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SHA/#SHA.hmac_sha3_512","page":"SHA","title":"SHA.hmac_sha3_512","text":"hmac_sha3_512(key, data)\n\nHash data using the sha3_512 algorithm using the passed key. See also HMAC_CTX.\n\n\n\n\n\nhmac_sha3_512(key, io::IO)\n\nHash data from io with the passed key using sha3_512 algorithm.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar","page":"Tar","title":"Tar","text":"","category":"section"},{"location":"stdlib/Tar/","page":"Tar","title":"Tar","text":"Tar.create\nTar.extract\nTar.list\nTar.rewrite\nTar.tree_hash\nTar.Header","category":"page"},{"location":"stdlib/Tar/#Tar.create","page":"Tar","title":"Tar.create","text":"create(\n [ predicate, ] dir, [ tarball ];\n [ skeleton, ] [ portable = false ]\n) -> tarball\n\n predicate :: String --> Bool\n dir :: AbstractString\n tarball :: Union{AbstractString, AbstractCmd, IO}\n skeleton :: Union{AbstractString, AbstractCmd, IO}\n portable :: Bool\n\nCreate a tar archive (\"tarball\") of the directory dir. The resulting archive is written to the path tarball or if no path is specified, a temporary path is created and returned by the function call. If tarball is an IO object then the tarball content is written to that handle instead (the handle is left open).\n\nIf a predicate function is passed, it is called on each system path that is encountered while recursively searching dir and path is only included in the tarball if predicate(path) is true. If predicate(path) returns false for a directory, then the directory is excluded entirely: nothing under that directory will be included in the archive.\n\nIf the skeleton keyword is passed then the file or IO handle given is used as a \"skeleton\" to generate the tarball. You create a skeleton file by passing the skeleton keyword to the extract command. If create is called with that skeleton file and the extracted files haven't changed, an identical tarball is recreated. The skeleton and predicate arguments cannot be used together.\n\nIf the portable flag is true then path names are checked for validity on Windows, which ensures that they don't contain illegal characters or have names that are reserved. See https://stackoverflow.com/a/31976060/659248 for details.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.extract","page":"Tar","title":"Tar.extract","text":"extract(\n [ predicate, ] tarball, [ dir ];\n [ skeleton = , ]\n [ copy_symlinks = , ]\n [ set_permissions = true, ]\n) -> dir\n\n predicate :: Header --> Bool\n tarball :: Union{AbstractString, AbstractCmd, IO}\n dir :: AbstractString\n skeleton :: Union{AbstractString, AbstractCmd, IO}\n copy_symlinks :: Bool\n set_permissions :: Bool\n\nExtract a tar archive (\"tarball\") located at the path tarball into the directory dir. If tarball is an IO object instead of a path, then the archive contents will be read from that IO stream. The archive is extracted to dir which must either be an existing empty directory or a non-existent path which can be created as a new directory. If dir is not specified, the archive is extracted into a temporary directory which is returned by extract.\n\nIf a predicate function is passed, it is called on each Header object that is encountered while extracting tarball and the entry is only extracted if the predicate(hdr) is true. This can be used to selectively extract only parts of an archive, to skip entries that cause extract to throw an error, or to record what is extracted during the extraction process.\n\nBefore it is passed to the predicate function, the Header object is somewhat modified from the raw header in the tarball: the path field is normalized to remove . entries and replace multiple consecutive slashes with a single slash. If the entry has type :hardlink, the link target path is normalized the same way so that it will match the path of the target entry; the size field is set to the size of the target path (which must be an already-seen file).\n\nIf the skeleton keyword is passed then a \"skeleton\" of the extracted tarball is written to the file or IO handle given. This skeleton file can be used to recreate an identical tarball by passing the skeleton keyword to the create function. The skeleton and predicate arguments cannot be used together.\n\nIf copy_symlinks is true then instead of extracting symbolic links as such, they will be extracted as copies of what they link to if they are internal to the tarball and if it is possible to do so. Non-internal symlinks, such as a link to /etc/passwd will not be copied. Symlinks which are in any way cyclic will also not be copied and will instead be skipped. By default, extract will detect whether symlinks can be created in dir or not and will automatically copy symlinks if they cannot be created.\n\nIf set_permissions is false, no permissions are set on the extracted files.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.list","page":"Tar","title":"Tar.list","text":"list(tarball; [ strict = true ]) -> Vector{Header}\nlist(callback, tarball; [ strict = true ])\n\n callback :: Header, [ ] --> Any\n tarball :: Union{AbstractString, AbstractCmd, IO}\n strict :: Bool\n\nList the contents of a tar archive (\"tarball\") located at the path tarball. If tarball is an IO handle, read the tar contents from that stream. Returns a vector of Header structs. See Header for details.\n\nIf a callback is provided then instead of returning a vector of headers, the callback is called on each Header. This can be useful if the number of items in the tarball is large or if you want examine items prior to an error in the tarball. If the callback function can accept a second argument of either type Vector{UInt8} or Vector{Pair{Symbol, String}} then it will be called with a representation of the raw header data either as a single byte vector or as a vector of pairs mapping field names to the raw data for that field (if these fields are concatenated together, the result is the raw data of the header).\n\nBy default list will error if it encounters any tarball contents which the extract function would refuse to extract. With strict=false it will skip these checks and list all the the contents of the tar file whether extract would extract them or not. Beware that malicious tarballs can do all sorts of crafty and unexpected things to try to trick you into doing something bad.\n\nIf the tarball argument is a skeleton file (see extract and create) then list will detect that from the file header and appropriately list or iterate the headers of the skeleton file.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.rewrite","page":"Tar","title":"Tar.rewrite","text":"rewrite(\n [ predicate, ] old_tarball, [ new_tarball ];\n [ portable = false, ]\n) -> new_tarball\n\n predicate :: Header --> Bool\n old_tarball :: Union{AbstractString, AbstractCmd, IO}\n new_tarball :: Union{AbstractString, AbstractCmd, IO}\n portable :: Bool\n\nRewrite old_tarball to the standard format that create generates, while also checking that it doesn't contain anything that would cause extract to raise an error. This is functionally equivalent to doing\n\nTar.create(Tar.extract(predicate, old_tarball), new_tarball)\n\nHowever, it never extracts anything to disk and instead uses the seek function to navigate the old tarball's data. If no new_tarball argument is passed, the new tarball is written to a temporary file whose path is returned.\n\nIf a predicate function is passed, it is called on each Header object that is encountered while extracting old_tarball and the entry is skipped unless predicate(hdr) is true. This can be used to selectively rewrite only parts of an archive, to skip entries that would cause extract to throw an error, or to record what content is encountered during the rewrite process.\n\nBefore it is passed to the predicate function, the Header object is somewhat modified from the raw header in the tarball: the path field is normalized to remove . entries and replace multiple consecutive slashes with a single slash. If the entry has type :hardlink, the link target path is normalized the same way so that it will match the path of the target entry; the size field is set to the size of the target path (which must be an already-seen file).\n\nIf the portable flag is true then path names are checked for validity on Windows, which ensures that they don't contain illegal characters or have names that are reserved. See https://stackoverflow.com/a/31976060/659248 for details.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.tree_hash","page":"Tar","title":"Tar.tree_hash","text":"tree_hash([ predicate, ] tarball;\n [ algorithm = \"git-sha1\", ]\n [ skip_empty = false ]) -> hash::String\n\n predicate :: Header --> Bool\n tarball :: Union{AbstractString, AbstractCmd, IO}\n algorithm :: AbstractString\n skip_empty :: Bool\n\nCompute a tree hash value for the file tree that the tarball contains. By default, this uses git's tree hashing algorithm with the SHA1 secure hash function (like current versions of git). This means that for any tarball whose file tree git can represent—i.e. one with only files, symlinks and non-empty directories—the hash value computed by this function will be the same as the hash value git would compute for that file tree. Note that tarballs can represent file trees with empty directories, which git cannot store, and this function can generate hashes for those, which will, by default (see skip_empty below for how to change this behavior), differ from the hash of a tarball which omits those empty directories. In short, the hash function agrees with git on all trees which git can represent, but extends (in a consistent way) the domain of hashable trees to other trees which git cannot represent.\n\nIf a predicate function is passed, it is called on each Header object that is encountered while processing tarball and an entry is only hashed if predicate(hdr) is true. This can be used to selectively hash only parts of an archive, to skip entries that cause extract to throw an error, or to record what is extracted during the hashing process.\n\nBefore it is passed to the predicate function, the Header object is somewhat modified from the raw header in the tarball: the path field is normalized to remove . entries and replace multiple consecutive slashes with a single slash. If the entry has type :hardlink, the link target path is normalized the same way so that it will match the path of the target entry; the size field is set to the size of the target path (which must be an already-seen file).\n\nCurrently supported values for algorithm are git-sha1 (the default) and git-sha256, which uses the same basic algorithm as git-sha1 but replaces the SHA1 hash function with SHA2-256, the hash function that git will transition to using in the future (due to known attacks on SHA1). Support for other file tree hashing algorithms may be added in the future.\n\nThe skip_empty option controls whether directories in the tarball which recursively contain no files or symlinks are included in the hash or ignored. In general, if you are hashing the content of a tarball or a file tree, you care about all directories, not just non-empty ones, so including these in the computed hash is the default. So why does this function even provide the option to skip empty directories? Because git refuses to store empty directories and will ignore them if you try to add them to a repo. So if you compute a reference tree hash by by adding files to a git repo and then asking git for the tree hash, the hash value that you get will match the hash value computed by tree_hash with skip_empty=true. In other words, this option allows tree_hash to emulate how git would hash a tree with empty directories. If you are hashing trees that may contain empty directories (i.e. do not come from a git repo), however, it is recommended that you hash them using a tool (such as this one) that does not ignore empty directories.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Tar/#Tar.Header","page":"Tar","title":"Tar.Header","text":"The Header type is a struct representing the essential metadata for a single record in a tar file with this definition:\n\nstruct Header\n path :: String # path relative to the root\n type :: Symbol # type indicator (see below)\n mode :: UInt16 # mode/permissions (best viewed in octal)\n size :: Int64 # size of record data in bytes\n link :: String # target path of a symlink\nend\n\nTypes are represented with the following symbols: file, hardlink, symlink, chardev, blockdev, directory, fifo, or for unknown types, the typeflag character as a symbol. Note that extract refuses to extract records types other than file, symlink and directory; list will only list other kinds of records if called with strict=false.\n\nThe tar format includes various other metadata about records, including user and group IDs, user and group names, and timestamps. The Tar package, by design, completely ignores these. When creating tar files, these fields are always set to zero/empty. When reading tar files, these fields are ignored aside from verifying header checksums for each header record for all fields.\n\n\n\n\n\n","category":"type"},{"location":"devdocs/ssair/#Julia-SSA-form-IR","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Julia uses a static single assignment intermediate representation (SSA IR) to perform optimization. This IR is different from LLVM IR, and unique to Julia. It allows for Julia specific optimizations.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Basic blocks (regions with no control flow) are explicitly annotated.\nif/else and loops are turned into goto statements.\nlines with multiple operations are split into multiple lines by introducing variables.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"For example the following Julia code:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"function foo(x)\n y = sin(x)\n if x > 5.0\n y = y + cos(x)\n end\n return exp(2) + y\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"when called with a Float64 argument is translated into:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"using InteractiveUtils\n@code_typed foo(1.0)","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"CodeInfo(\n1 ─ %1 = invoke Main.sin(x::Float64)::Float64\n│ %2 = Base.lt_float(x, 5.0)::Bool\n└── goto #3 if not %2\n2 ─ %4 = invoke Main.cos(x::Float64)::Float64\n└── %5 = Base.add_float(%1, %4)::Float64\n3 ┄ %6 = φ (#2 => %5, #1 => %1)::Float64\n│ %7 = Base.add_float(7.38905609893065, %6)::Float64\n└── return %7\n) => Float64","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"In this example, we can see all of these changes.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The first basic block is everything in","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"1 ─ %1 = invoke Main.sin(x::Float64)::Float64\n│ %2 = Base.lt_float(x, 5.0)::Bool\n└── goto #3 if not %2","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The if statement is translated into goto #3 if not %2 which goes to the 3rd basic block if x>5 isn't met and otherwise goes to the second basic block.\n%2 is an SSA value introduced to represent x > 5.","category":"page"},{"location":"devdocs/ssair/#Background","page":"Julia SSA-form IR","title":"Background","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Beginning in Julia 0.7, parts of the compiler use a new SSA-form intermediate representation (IR). Historically, the compiler would directly generate LLVM IR from a lowered form of the Julia AST. This form had most syntactic abstractions removed, but still looked a lot like an abstract syntax tree. Over time, in order to facilitate optimizations, SSA values were introduced to this IR and the IR was linearized (i.e. turned into a form where function arguments could only be SSA values or constants). However, non-SSA values (slots) remained in the IR due to the lack of Phi nodes in the IR (necessary for back-edges and re-merging of conditional control flow). This negated much of the usefulness of SSA form representation when performing middle end optimizations. Some heroic effort was put into making these optimizations work without a complete SSA form representation, but the lack of such a representation ultimately proved prohibitive.","category":"page"},{"location":"devdocs/ssair/#Categories-of-IR-nodes","page":"Julia SSA-form IR","title":"Categories of IR nodes","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The SSA IR representation has four categories of IR nodes: Phi, Pi, PhiC, and Upsilon nodes (the latter two are only used for exception handling).","category":"page"},{"location":"devdocs/ssair/#Phi-nodes-and-Pi-nodes","page":"Julia SSA-form IR","title":"Phi nodes and Pi nodes","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Phi nodes are part of generic SSA abstraction (see the link above if you're not familiar with the concept). In the Julia IR, these nodes are represented as:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"struct PhiNode\n edges::Vector{Int32}\n values::Vector{Any}\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"where we ensure that both vectors always have the same length. In the canonical representation (the one handled by codegen and the interpreter), the edge values indicate come-from statement numbers (i.e. if edge has an entry of 15, there must be a goto, gotoifnot or implicit fall through from statement 15 that targets this phi node). Values are either SSA values or constants. It is also possible for a value to be unassigned if the variable was not defined on this path. However, undefinedness checks get explicitly inserted and represented as booleans after middle end optimizations, so code generators may assume that any use of a Phi node will have an assigned value in the corresponding slot. It is also legal for the mapping to be incomplete, i.e. for a Phi node to have missing incoming edges. In that case, it must be dynamically guaranteed that the corresponding value will not be used.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Note that SSA uses semantically occur after the terminator of the corresponding predecessor (\"on the edge\"). Consequently, if multiple Phi nodes appear at the start of a basic block, they are run simultaneously. This means that in the following IR snippet, if we came from block 23, %46 will take the value associated to %45 before we entered this block.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"%45 = φ (#18 => %23, #23 => %50)\n%46 = φ (#18 => 1.0, #23 => %45)","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"PiNodes encode statically proven information that may be implicitly assumed in basic blocks dominated by a given pi node. They are conceptually equivalent to the technique introduced in the paper ABCD: Eliminating Array Bounds Checks on Demand or the predicate info nodes in LLVM. To see how they work, consider, e.g.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"%x::Union{Int, Float64} # %x is some Union{Int, Float64} typed ssa value\nif isa(x, Int)\n # use x\nelse\n # use x\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"We can perform predicate insertion and turn this into:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"%x::Union{Int, Float64} # %x is some Union{Int, Float64} typed ssa value\nif isa(x, Int)\n %x_int = PiNode(x, Int)\n # use %x_int\nelse\n %x_float = PiNode(x, Float64)\n # use %x_float\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Pi nodes are generally ignored in the interpreter, since they don't have any effect on the values, but they may sometimes lead to code generation in the compiler (e.g. to change from an implicitly union split representation to a plain unboxed representation). The main usefulness of PiNodes stems from the fact that path conditions of the values can be accumulated simply by def-use chain walking that is generally done for most optimizations that care about these conditions anyway.","category":"page"},{"location":"devdocs/ssair/#PhiC-nodes-and-Upsilon-nodes","page":"Julia SSA-form IR","title":"PhiC nodes and Upsilon nodes","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Exception handling complicates the SSA story moderately, because exception handling introduces additional control flow edges into the IR across which values must be tracked. One approach to do so, which is followed by LLVM, is to make calls which may throw exceptions into basic block terminators and add an explicit control flow edge to the catch handler:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"invoke @function_that_may_throw() to label %regular unwind to %catch\n\nregular:\n# Control flow continues here\n\ncatch:\n# Exceptions go here","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"However, this is problematic in a language like Julia, where at the start of the optimization pipeline, we do not know which calls throw. We would have to conservatively assume that every call (which in Julia is every statement) throws. This would have several negative effects. On the one hand, it would essentially reduce the scope of every basic block to a single call, defeating the purpose of having operations be performed at the basic block level. On the other hand, every catch basic block would have n*m phi node arguments (n, the number of statements in the critical region, m the number of live values through the catch block).","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"To work around this, we use a combination of Upsilon and PhiC nodes (the C standing for catch, written φᶜ in the IR pretty printer, because unicode subscript c is not available). There are several ways to think of these nodes, but perhaps the easiest is to think of each PhiC as a load from a unique store-many, read-once slot, with Upsilon being the corresponding store operation. The PhiC has an operand list of all the upsilon nodes that store to its implicit slot. The Upsilon nodes however, do not record which PhiC node they store to. This is done for more natural integration with the rest of the SSA IR. E.g. if there are no more uses of a PhiC node, it is safe to delete it, and the same is true of an Upsilon node. In most IR passes, PhiC nodes can be treated like Phi nodes. One can follow use-def chains through them, and they can be lifted to new PhiC nodes and new Upsilon nodes (in the same places as the original Upsilon nodes). The result of this scheme is that the number of Upsilon nodes (and PhiC arguments) is proportional to the number of assigned values to a particular variable (before SSA conversion), rather than the number of statements in the critical region.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"To see this scheme in action, consider the function","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"@noinline opaque() = invokelatest(identity, nothing) # Something opaque\nfunction foo()\n local y\n x = 1\n try\n y = 2\n opaque()\n y = 3\n error()\n catch\n end\n (x, y)\nend","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The corresponding IR (with irrelevant types stripped) is:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"1 ─ nothing::Nothing\n2 ─ %2 = $(Expr(:enter, #4))\n3 ─ %3 = ϒ (false)\n│ %4 = ϒ (#undef)\n│ %5 = ϒ (1)\n│ %6 = ϒ (true)\n│ %7 = ϒ (2)\n│ invoke Main.opaque()::Any\n│ %9 = ϒ (true)\n│ %10 = ϒ (3)\n│ invoke Main.error()::Union{}\n└── $(Expr(:unreachable))::Union{}\n4 ┄ %13 = φᶜ (%3, %6, %9)::Bool\n│ %14 = φᶜ (%4, %7, %10)::Core.Compiler.MaybeUndef(Int64)\n│ %15 = φᶜ (%5)::Core.Const(1)\n└── $(Expr(:leave, Core.SSAValue(2)))\n5 ─ $(Expr(:pop_exception, :(%2)))::Any\n│ $(Expr(:throw_undef_if_not, :y, :(%13)))::Any\n│ %19 = Core.tuple(%15, %14)\n└── return %19","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Note in particular that every value live into the critical region gets an upsilon node at the top of the critical region. This is because catch blocks are considered to have an invisible control flow edge from outside the function. As a result, no SSA value dominates the catch blocks, and all incoming values have to come through a φᶜ node.","category":"page"},{"location":"devdocs/ssair/#Main-SSA-data-structure","page":"Julia SSA-form IR","title":"Main SSA data structure","text":"","category":"section"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The main SSAIR data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. The core of the data structure is a flat vector of statements. Each statement is implicitly assigned an SSA value based on its position in the vector (i.e. the result of the statement at idx 1 can be accessed using SSAValue(1) etc). For each SSA value, we additionally maintain its type. Since, SSA values are definitionally assigned only once, this type is also the result type of the expression at the corresponding index. However, while this representation is rather efficient (since the assignments don't need to be explicitly encoded), it of course carries the drawback that order is semantically significant, so reorderings and insertions change statement numbers. Additionally, we do not keep use lists (i.e. it is impossible to walk from a def to all its uses without explicitly computing this map–def lists however are trivial since you can look up the corresponding statement from the index), so the LLVM-style RAUW (replace-all-uses-with) operation is unavailable.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"Instead, we do the following:","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"We keep a separate buffer of nodes to insert (including the position to insert them at, the type of the corresponding value and the node itself). These nodes are numbered by their occurrence in the insertion buffer, allowing their values to be immediately used elsewhere in the IR (i.e. if there are 12 statements in the original statement list, the first new statement will be accessible as SSAValue(13)).\nRAUW style operations are performed by setting the corresponding statement index to the replacement value.\nStatements are erased by setting the corresponding statement to nothing (this is essentially just a special-case convention of the above).\nIf there are any uses of the statement being erased, they will be set to nothing.","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"There is a compact! function that compacts the above data structure by performing the insertion of nodes in the appropriate place, trivial copy propagation, and renaming of uses to any changed SSA values. However, the clever part of this scheme is that this compaction can be done lazily as part of the subsequent pass. Most optimization passes need to walk over the entire list of statements, performing analysis or modifications along the way. We provide an IncrementalCompact iterator that can be used to iterate over the statement list. It will perform any necessary compaction and return the new index of the node, as well as the node itself. It is legal at this point to walk def-use chains, as well as make any modifications or deletions to the IR (insertions are disallowed however).","category":"page"},{"location":"devdocs/ssair/","page":"Julia SSA-form IR","title":"Julia SSA-form IR","text":"The idea behind this arrangement is that, since the optimization passes need to touch the corresponding memory anyway and incur the corresponding memory access penalty, performing the extra housekeeping should have comparatively little overhead (and save the overhead of maintaining these data structures during IR modification).","category":"page"},{"location":"devdocs/EscapeAnalysis/#EscapeAnalysis","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Core.Compiler.EscapeAnalysis is a compiler utility module that aims to analyze escape information of Julia's SSA-form IR a.k.a. IRCode.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"This escape analysis aims to:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"leverage Julia's high-level semantics, especially reason about escapes and aliasing via inter-procedural calls\nbe versatile enough to be used for various optimizations including alias-aware SROA, early finalize insertion, copy-free ImmutableArray construction, stack allocation of mutable objects, and so on.\nachieve a simple implementation based on a fully backward data-flow analysis implementation as well as a new lattice design that combines orthogonal lattice properties","category":"page"},{"location":"devdocs/EscapeAnalysis/#Try-it-out!","page":"EscapeAnalysis","title":"Try it out!","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"You can give a try to the escape analysis by loading the EAUtils.jl utility script that defines the convenience entries code_escapes and @code_escapes for testing and debugging purposes:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"let JULIA_DIR = normpath(Sys.BINDIR, \"..\", \"share\", \"julia\")\n # load `EscapeAnalysis` module to define the core analysis code\n include(normpath(JULIA_DIR, \"base\", \"compiler\", \"ssair\", \"EscapeAnalysis\", \"EscapeAnalysis.jl\"))\n using .EscapeAnalysis\n # load `EAUtils` module to define the utilities\n include(normpath(JULIA_DIR, \"test\", \"compiler\", \"EscapeAnalysis\", \"EAUtils.jl\"))\n using .EAUtils\nend\n\nmutable struct SafeRef{T}\n x::T\nend\nBase.getindex(x::SafeRef) = x.x;\nBase.setindex!(x::SafeRef, v) = x.x = v;\nBase.isassigned(x::SafeRef) = true;\nget′(x) = isassigned(x) ? x[] : throw(x);\n\nresult = code_escapes((String,String,String,String)) do s1, s2, s3, s4\n r1 = Ref(s1)\n r2 = Ref(s2)\n r3 = SafeRef(s3)\n try\n s1 = get′(r1)\n ret = sizeof(s1)\n catch err\n global GV = err # will definitely escape `r1`\n end\n s2 = get′(r2) # still `r2` doesn't escape fully\n s3 = get′(r3) # still `r3` doesn't escape fully\n s4 = sizeof(s4) # the argument `s4` doesn't escape here\n return s2, s3, s4\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"The symbols on the side of each call argument and SSA statements represent the following meaning:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"◌ (plain): this value is not analyzed because escape information of it won't be used anyway (when the object is isbitstype for example)\n✓ (green or cyan): this value never escapes (has_no_escape(result.state[x]) holds), colored blue if it has arg escape also (has_arg_escape(result.state[x]) holds)\n↑ (blue or yellow): this value can escape to the caller via return (has_return_escape(result.state[x]) holds), colored yellow if it has unhandled thrown escape also (has_thrown_escape(result.state[x]) holds)\nX (red): this value can escape to somewhere the escape analysis can't reason about like escapes to a global memory (has_all_escape(result.state[x]) holds)\n* (bold): this value's escape state is between the ReturnEscape and AllEscape in the partial order of EscapeInfo, colored yellow if it has unhandled thrown escape also (has_thrown_escape(result.state[x]) holds)\n′: this value has additional object field / array element information in its AliasInfo property","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Escape information of each call argument and SSA value can be inspected programmatically as like:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"result.state[Core.Argument(3)] # get EscapeInfo of `s2`\n\nresult.state[Core.SSAValue(3)] # get EscapeInfo of `r3`","category":"page"},{"location":"devdocs/EscapeAnalysis/#Analysis-Design","page":"EscapeAnalysis","title":"Analysis Design","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/#Lattice-Design","page":"EscapeAnalysis","title":"Lattice Design","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"EscapeAnalysis is implemented as a data-flow analysis that works on a lattice of x::EscapeInfo, which is composed of the following properties:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"x.Analyzed::Bool: not formally part of the lattice, only indicates x has not been analyzed or not\nx.ReturnEscape::BitSet: records SSA statements where x can escape to the caller via return\nx.ThrownEscape::BitSet: records SSA statements where x can be thrown as exception (used for the exception handling described below)\nx.AliasInfo: maintains all possible values that can be aliased to fields or array elements of x (used for the alias analysis described below)\nx.ArgEscape::Int (not implemented yet): indicates it will escape to the caller through setfield! on argument(s)","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"These attributes can be combined to create a partial lattice that has a finite height, given the invariant that an input program has a finite number of statements, which is assured by Julia's semantics. The clever part of this lattice design is that it enables a simpler implementation of lattice operations by allowing them to handle each lattice property separately[LatticeDesign].","category":"page"},{"location":"devdocs/EscapeAnalysis/#Backward-Escape-Propagation","page":"EscapeAnalysis","title":"Backward Escape Propagation","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"This escape analysis implementation is based on the data-flow algorithm described in the paper[MM02]. The analysis works on the lattice of EscapeInfo and transitions lattice elements from the bottom to the top until every lattice element gets converged to a fixed point by maintaining a (conceptual) working set that contains program counters corresponding to remaining SSA statements to be analyzed. The analysis manages a single global state that tracks EscapeInfo of each argument and SSA statement, but also note that some flow-sensitivity is encoded as program counters recorded in EscapeInfo's ReturnEscape property, which can be combined with domination analysis later to reason about flow-sensitivity if necessary.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"One distinctive design of this escape analysis is that it is fully backward, i.e. escape information flows from usages to definitions. For example, in the code snippet below, EA first analyzes the statement return %1 and imposes ReturnEscape on %1 (corresponding to obj), and then it analyzes %1 = %new(Base.RefValue{String, _2})) and propagates the ReturnEscape imposed on %1 to the call argument _2 (corresponding to s):","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,)) do s\n obj = Ref(s)\n return obj\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"The key observation here is that this backward analysis allows escape information to flow naturally along the use-def chain rather than control-flow[BackandForth]. As a result this scheme enables a simple implementation of escape analysis, e.g. PhiNode for example can be handled simply by propagating escape information imposed on a PhiNode to its predecessor values:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((Bool, String, String)) do cnd, s, t\n if cnd\n obj = Ref(s)\n else\n obj = Ref(t)\n end\n return obj\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/#EA-Alias-Analysis","page":"EscapeAnalysis","title":"Alias Analysis","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"EscapeAnalysis implements a backward field analysis in order to reason about escapes imposed on object fields with certain accuracy, and x::EscapeInfo's x.AliasInfo property exists for this purpose. It records all possible values that can be aliased to fields of x at \"usage\" sites, and then the escape information of that recorded values are propagated to the actual field values later at \"definition\" sites. More specifically, the analysis records a value that may be aliased to a field of object by analyzing getfield call, and then it propagates its escape information to the field when analyzing %new(...) expression or setfield! call[Dynamism].","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,)) do s\n obj = SafeRef(\"init\")\n obj[] = s\n v = obj[]\n return v\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"In the example above, ReturnEscape imposed on %3 (corresponding to v) is not directly propagated to %1 (corresponding to obj) but rather that ReturnEscape is only propagated to _2 (corresponding to s). Here %3 is recorded in %1's AliasInfo property as it can be aliased to the first field of %1, and then when analyzing Base.setfield!(%1, :x, _2)::String, that escape information is propagated to _2 but not to %1.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"So EscapeAnalysis tracks which IR elements can be aliased across a getfield-%new/setfield! chain in order to analyze escapes of object fields, but actually this alias analysis needs to be generalized to handle other IR elements as well. This is because in Julia IR the same object is sometimes represented by different IR elements and so we should make sure that those different IR elements that actually can represent the same object share the same escape information. IR elements that return the same object as their operand(s), such as PiNode and typeassert, can cause that IR-level aliasing and thus requires escape information imposed on any of such aliased values to be shared between them. More interestingly, it is also needed for correctly reasoning about mutations on PhiNode. Let's consider the following example:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((Bool, String,)) do cond, x\n if cond\n ϕ2 = ϕ1 = SafeRef(\"foo\")\n else\n ϕ2 = ϕ1 = SafeRef(\"bar\")\n end\n ϕ2[] = x\n y = ϕ1[]\n return y\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"ϕ1 = %5 and ϕ2 = %6 are aliased and thus ReturnEscape imposed on %8 = Base.getfield(%6, :x)::String (corresponding to y = ϕ1[]) needs to be propagated to Base.setfield!(%5, :x, _3)::String (corresponding to ϕ2[] = x). In order for such escape information to be propagated correctly, the analysis should recognize that the predecessors of ϕ1 and ϕ2 can be aliased as well and equalize their escape information.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"One interesting property of such aliasing information is that it is not known at \"usage\" site but can only be derived at \"definition\" site (as aliasing is conceptually equivalent to assignment), and thus it doesn't naturally fit in a backward analysis. In order to efficiently propagate escape information between related values, EscapeAnalysis.jl uses an approach inspired by the escape analysis algorithm explained in an old JVM paper[JVM05]. That is, in addition to managing escape lattice elements, the analysis also maintains an \"equi\"-alias set, a disjoint set of aliased arguments and SSA statements. The alias set manages values that can be aliased to each other and allows escape information imposed on any of such aliased values to be equalized between them.","category":"page"},{"location":"devdocs/EscapeAnalysis/#EA-Array-Analysis","page":"EscapeAnalysis","title":"Array Analysis","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"The alias analysis for object fields described above can also be generalized to analyze array operations. EscapeAnalysis implements handlings for various primitive array operations so that it can propagate escapes via arrayref-arrayset use-def chain and does not escape allocated arrays too conservatively:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,)) do s\n ary = Any[]\n push!(ary, SafeRef(s))\n return ary[1], length(ary)\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"In the above example EscapeAnalysis understands that %20 and %2 (corresponding to the allocated object SafeRef(s)) are aliased via the arrayset-arrayref chain and imposes ReturnEscape on them, but not impose it on the allocated array %1 (corresponding to ary). EscapeAnalysis still imposes ThrownEscape on ary since it also needs to account for potential escapes via BoundsError, but also note that such unhandled ThrownEscape can often be ignored when optimizing the ary allocation.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Furthermore, in cases when array index information as well as array dimensions can be known precisely, EscapeAnalysis is able to even reason about \"per-element\" aliasing via arrayref-arrayset chain, as EscapeAnalysis does \"per-field\" alias analysis for objects:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,String)) do s, t\n ary = Vector{Any}(undef, 2)\n ary[1] = SafeRef(s)\n ary[2] = SafeRef(t)\n return ary[1], length(ary)\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Note that ReturnEscape is only imposed on %2 (corresponding to SafeRef(s)) but not on %4 (corresponding to SafeRef(t)). This is because the allocated array's dimension and indices involved with all arrayref/arrayset operations are available as constant information and EscapeAnalysis can understand that %6 is aliased to %2 but never be aliased to %4. In this kind of case, the succeeding optimization passes will be able to replace Base.arrayref(true, %1, 1)::Any with %2 (a.k.a. \"load-forwarding\") and eventually eliminate the allocation of array %1 entirely (a.k.a. \"scalar-replacement\").","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"When compared to object field analysis, where an access to object field can be analyzed trivially using type information derived by inference, array dimension isn't encoded as type information and so we need an additional analysis to derive that information. EscapeAnalysis at this moment first does an additional simple linear scan to analyze dimensions of allocated arrays before firing up the main analysis routine so that the succeeding escape analysis can precisely analyze operations on those arrays.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"However, such precise \"per-element\" alias analysis is often hard. Essentially, the main difficulty inherit to array is that array dimension and index are often non-constant:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"loop often produces loop-variant, non-constant array indices\n(specific to vectors) array resizing changes array dimension and invalidates its constant-ness","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Let's discuss those difficulties with concrete examples.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"In the following example, EscapeAnalysis fails the precise alias analysis since the index at the Base.arrayset(false, %4, %8, %6)::Vector{Any} is not (trivially) constant. Especially Any[nothing, nothing] forms a loop and calls that arrayset operation in a loop, where %6 is represented as a ϕ-node value (whose value is control-flow dependent). As a result, ReturnEscape ends up imposed on both %23 (corresponding to SafeRef(s)) and %25 (corresponding to SafeRef(t)), although ideally we want it to be imposed only on %23 but not on %25:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,String)) do s, t\n ary = Any[nothing, nothing]\n ary[1] = SafeRef(s)\n ary[2] = SafeRef(t)\n return ary[1], length(ary)\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"The next example illustrates how vector resizing makes precise alias analysis hard. The essential difficulty is that the dimension of allocated array %1 is first initialized as 0, but it changes by the two :jl_array_grow_end calls afterwards. EscapeAnalysis currently simply gives up precise alias analysis whenever it encounters any array resizing operations and so ReturnEscape is imposed on both %2 (corresponding to SafeRef(s)) and %20 (corresponding to SafeRef(t)):","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"code_escapes((String,String)) do s, t\n ary = Any[]\n push!(ary, SafeRef(s))\n push!(ary, SafeRef(t))\n ary[1], length(ary)\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"In order to address these difficulties, we need inference to be aware of array dimensions and propagate array dimensions in a flow-sensitive way[ArrayDimension], as well as come up with nice representation of loop-variant values.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"EscapeAnalysis at this moment quickly switches to the more imprecise analysis that doesn't track precise index information in cases when array dimensions or indices are trivially non constant. The switch can naturally be implemented as a lattice join operation of EscapeInfo.AliasInfo property in the data-flow analysis framework.","category":"page"},{"location":"devdocs/EscapeAnalysis/#EA-Exception-Handling","page":"EscapeAnalysis","title":"Exception Handling","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"It would be also worth noting how EscapeAnalysis handles possible escapes via exceptions. Naively it seems enough to propagate escape information imposed on :the_exception object to all values that may be thrown in a corresponding try block. But there are actually several other ways to access to the exception object in Julia, such as Base.current_exceptions and rethrow. For example, escape analysis needs to account for potential escape of r in the example below:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"const GR = Ref{Any}();\n@noinline function rethrow_escape!()\n try\n rethrow()\n catch err\n GR[] = err\n end\nend;\nget′(x) = isassigned(x) ? x[] : throw(x);\n\ncode_escapes() do\n r = Ref{String}()\n local t\n try\n t = get′(r)\n catch err\n t = typeof(err) # `err` (which `r` aliases to) doesn't escape here\n rethrow_escape!() # but `r` escapes here\n end\n return t\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"It requires a global analysis in order to correctly reason about all possible escapes via existing exception interfaces. For now we always propagate the topmost escape information to all potentially thrown objects conservatively, since such an additional analysis might not be worthwhile to do given that exception handling and error path usually don't need to be very performance sensitive, and also optimizations of error paths might be very ineffective anyway since they are often even \"unoptimized\" intentionally for latency reasons.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"x::EscapeInfo's x.ThrownEscape property records SSA statements where x can be thrown as an exception. Using this information EscapeAnalysis can propagate possible escapes via exceptions limitedly to only those may be thrown in each try region:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"result = code_escapes((String,String)) do s1, s2\n r1 = Ref(s1)\n r2 = Ref(s2)\n local ret\n try\n s1 = get′(r1)\n ret = sizeof(s1)\n catch err\n global GV = err # will definitely escape `r1`\n end\n s2 = get′(r2) # still `r2` doesn't escape fully\n return s2\nend","category":"page"},{"location":"devdocs/EscapeAnalysis/#Analysis-Usage","page":"EscapeAnalysis","title":"Analysis Usage","text":"","category":"section"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"analyze_escapes is the entry point to analyze escape information of SSA-IR elements.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Most optimizations like SROA (sroa_pass!) are more effective when applied to an optimized source that the inlining pass (ssa_inlining_pass!) has simplified by resolving inter-procedural calls and expanding callee sources. Accordingly, analyze_escapes is also able to analyze post-inlining IR and collect escape information that is useful for certain memory-related optimizations.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"However, since certain optimization passes like inlining can change control flows and eliminate dead code, they can break the inter-procedural validity of escape information. In particularity, in order to collect inter-procedurally valid escape information, we need to analyze a pre-inlining IR.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Because of this reason, analyze_escapes can analyze IRCode at any Julia-level optimization stage, and especially, it is supposed to be used at the following two stages:","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"IPO EA: analyze pre-inlining IR to generate IPO-valid escape information cache\nLocal EA: analyze post-inlining IR to collect locally-valid escape information","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Escape information derived by IPO EA is transformed to the ArgEscapeCache data structure and cached globally. By passing an appropriate get_escape_cache callback to analyze_escapes, the escape analysis can improve analysis accuracy by utilizing cached inter-procedural information of non-inlined callees that has been derived by previous IPO EA. More interestingly, it is also valid to use IPO EA escape information for type inference, e.g., inference accuracy can be improved by forming Const/PartialStruct/MustAlias of mutable object.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"Core.Compiler.EscapeAnalysis.analyze_escapes\nCore.Compiler.EscapeAnalysis.EscapeState\nCore.Compiler.EscapeAnalysis.EscapeInfo","category":"page"},{"location":"devdocs/EscapeAnalysis/#Core.Compiler.EscapeAnalysis.analyze_escapes","page":"EscapeAnalysis","title":"Core.Compiler.EscapeAnalysis.analyze_escapes","text":"analyze_escapes(ir::IRCode, nargs::Int, get_escape_cache) -> estate::EscapeState\n\nAnalyzes escape information in ir:\n\nnargs: the number of actual arguments of the analyzed call\nget_escape_cache(::MethodInstance) -> Union{Bool,ArgEscapeCache}: retrieves cached argument escape information\n\n\n\n\n\n","category":"function"},{"location":"devdocs/EscapeAnalysis/#Core.Compiler.EscapeAnalysis.EscapeState","page":"EscapeAnalysis","title":"Core.Compiler.EscapeAnalysis.EscapeState","text":"estate::EscapeState\n\nExtended lattice that maps arguments and SSA values to escape information represented as EscapeInfo. Escape information imposed on SSA IR element x can be retrieved by estate[x].\n\n\n\n\n\n","category":"type"},{"location":"devdocs/EscapeAnalysis/#Core.Compiler.EscapeAnalysis.EscapeInfo","page":"EscapeAnalysis","title":"Core.Compiler.EscapeAnalysis.EscapeInfo","text":"x::EscapeInfo\n\nA lattice for escape information, which holds the following properties:\n\nx.Analyzed::Bool: not formally part of the lattice, only indicates whether x has been analyzed\nx.ReturnEscape::Bool: indicates x can escape to the caller via return\nx.ThrownEscape::BitSet: records SSA statement numbers where x can be thrown as exception:\nisempty(x.ThrownEscape): x will never be thrown in this call frame (the bottom)\npc ∈ x.ThrownEscape: x may be thrown at the SSA statement at pc\n-1 ∈ x.ThrownEscape: x may be thrown at arbitrary points of this call frame (the top)\nThis information will be used by escape_exception! to propagate potential escapes via exception.\nx.AliasInfo::Union{Bool,IndexableFields,IndexableElements,Unindexable}: maintains all possible values that can be aliased to fields or array elements of x:\nx.AliasInfo === false indicates the fields/elements of x aren't analyzed yet\nx.AliasInfo === true indicates the fields/elements of x can't be analyzed, e.g. the type of x is not known or is not concrete and thus its fields/elements can't be known precisely\nx.AliasInfo::IndexableFields records all the possible values that can be aliased to fields of object x with precise index information\nx.AliasInfo::IndexableElements records all the possible values that can be aliased to elements of array x with precise index information\nx.AliasInfo::Unindexable records all the possible values that can be aliased to fields/elements of x without precise index information\nx.Liveness::BitSet: records SSA statement numbers where x should be live, e.g. to be used as a call argument, to be returned to a caller, or preserved for :foreigncall:\nisempty(x.Liveness): x is never be used in this call frame (the bottom)\n0 ∈ x.Liveness also has the special meaning that it's a call argument of the currently analyzed call frame (and thus it's visible from the caller immediately).\npc ∈ x.Liveness: x may be used at the SSA statement at pc\n-1 ∈ x.Liveness: x may be used at arbitrary points of this call frame (the top)\n\nThere are utility constructors to create common EscapeInfos, e.g.,\n\nNoEscape(): the bottom(-like) element of this lattice, meaning it won't escape to anywhere\nAllEscape(): the topmost element of this lattice, meaning it will escape to everywhere\n\nanalyze_escapes will transition these elements from the bottom to the top, in the same direction as Julia's native type inference routine. An abstract state will be initialized with the bottom(-like) elements:\n\nthe call arguments are initialized as ArgEscape(), whose Liveness property includes 0 to indicate that it is passed as a call argument and visible from a caller immediately\nthe other states are initialized as NotAnalyzed(), which is a special lattice element that is slightly lower than NoEscape, but at the same time doesn't represent any meaning other than it's not analyzed yet (thus it's not formally part of the lattice)\n\n\n\n\n\n","category":"type"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[LatticeDesign]: Our type inference implementation takes the alternative approach, where each lattice property is represented by a special lattice element type object. It turns out that it started to complicate implementations of the lattice operations mainly because it often requires conversion rules between each lattice element type object. And we are working on overhauling our type inference lattice implementation with EscapeInfo-like lattice design.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[MM02]: A Graph-Free approach to Data-Flow Analysis. Markas Mohnen, 2002, April. https://api.semanticscholar.org/CorpusID:28519618.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[BackandForth]: Our type inference algorithm in contrast is implemented as a forward analysis, because type information usually flows from \"definition\" to \"usage\" and it is more natural and effective to propagate such information in a forward way.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[Dynamism]: In some cases, however, object fields can't be analyzed precisely. For example, object may escape to somewhere EscapeAnalysis can't account for possible memory effects on it, or fields of the objects simply can't be known because of the lack of type information. In such cases AliasInfo property is raised to the topmost element within its own lattice order, and it causes succeeding field analysis to be conservative and escape information imposed on fields of an unanalyzable object to be propagated to the object itself.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[JVM05]: Escape Analysis in the Context of Dynamic Compilation and Deoptimization. Thomas Kotzmann and Hanspeter Mössenböck, 2005, June. https://dl.acm.org/doi/10.1145/1064979.1064996.","category":"page"},{"location":"devdocs/EscapeAnalysis/","page":"EscapeAnalysis","title":"EscapeAnalysis","text":"[ArrayDimension]: Otherwise we will need yet another forward data-flow analysis on top of the escape analysis.","category":"page"},{"location":"devdocs/aot/#Ahead-of-Time-Compilation","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"This document describes the design and structure of the ahead-of-time (AOT) compilation system in Julia. This system is used when generating system images and package images. Much of the implementation described here is located in aotcompile.cpp, staticdata.c, and processor.cpp","category":"page"},{"location":"devdocs/aot/#Introduction","page":"Ahead of Time Compilation","title":"Introduction","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Though Julia normally compiles code just-in-time (JIT), it is possible to compile code ahead of time and save the resulting code to a file. This can be useful for a number of reasons:","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"To reduce the time it takes to start a Julia process.\nTo reduce the time spent in the JIT compiler instead of executing code (time to first execution, TTFX).\nTo reduce the amount of memory used by the JIT compiler.","category":"page"},{"location":"devdocs/aot/#High-Level-Overview","page":"Ahead of Time Compilation","title":"High-Level Overview","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The following descriptions are a snapshot of the current implementation details of the end-to-end pipeline that happens internally when the user compiles a new AOT module, such as occurs when they type using Foo. These details are likely to change over time as we implement better ways to handle them, so current implementations may not exactly match the dataflow and functions described below.","category":"page"},{"location":"devdocs/aot/#Compiling-Code-Images","page":"Ahead of Time Compilation","title":"Compiling Code Images","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Firstly, the methods that need to be compiled to native code must be identified. This can only be done by actually executing the code to be compiled, as the set of methods that need to be compiled depends on the types of the arguments passed to the methods, and method invocations with certain combinations of types may not be known until runtime. During this process, the exact methods that the compiler sees are tracked for later compilation, producing a compilation trace.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"note: Note\nCurrently when compiling images, Julia runs the trace generation in a different process than the process performing the AOT compilation. This can have impacts when attempting to use a debugger during precompilation. The best way to debug precompilation with a debugger is to use the rr debugger, record the entire process tree, use rr ps to identify the relevant failing process, and then use rr replay -p PID to replay just the failing process.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Once the methods to be compiled have been identified, they are passed to the jl_create_system_image function. This function sets up a number of data structures that will be used when serializing native code to a file, and then calls jl_create_native with the array of methods. jl_create_native runs codegen on the methods produces one or more LLVM modules. jl_create_system_image then records some useful information about what codegen produced from the module(s).","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The module(s) are then passed to jl_dump_native, along with the information recorded by jl_create_system_image. jl_dump_native contains the code necessary to serialize the module(s) to bitcode, object, or assembly files depending on the command-line options passed to Julia. The serialized code and information are then written to a file as an archive.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The final step is to run a system linker on the object files in the archive produced by jl_dump_native. Once this step is complete, a shared library containing the compiled code is produced.","category":"page"},{"location":"devdocs/aot/#Loading-Code-Images","page":"Ahead of Time Compilation","title":"Loading Code Images","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"When loading a code image, the shared library produced by the linker is loaded into memory. The system image data is then loaded from the shared library. This data contains information about the types, methods, and code instances that were compiled into the shared library. This data is used to restore the state of the runtime to what it was when the code image was compiled.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"If the code image was compiled with multiversioning, the loader will pick the appropriate version of each function to use based on the CPU features available on the current machine.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"For system images, since no other code has been loaded, the state of the runtime is now the same as it was when the code image was compiled. For package images, the environment may have changed compared to when the code was compiled, so each method must be checked against the global method table to determine if it is still valid code.","category":"page"},{"location":"devdocs/aot/#Compiling-Methods","page":"Ahead of Time Compilation","title":"Compiling Methods","text":"","category":"section"},{"location":"devdocs/aot/#Tracing-Compiled-Methods","page":"Ahead of Time Compilation","title":"Tracing Compiled Methods","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Julia has a command-line flag to record all of the methods that are compiled by the JIT compiler, --trace-compile=filename. When a function is compiled and this flag has a filename, Julia will print out a precompile statement to that file with the method and argument types it was called with. This therefore generates a precompile script that can be used later in the AOT compilation process. The PrecompileTools package has tooling that can make taking advantage of this functionality easier for package developers.","category":"page"},{"location":"devdocs/aot/#jl_create_system_image","page":"Ahead of Time Compilation","title":"jl_create_system_image","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"jl_create_system_image saves all of the Julia-specific metadata necessary to later restore the state of the runtime. This includes data such as code instances, method instances, method tables, and type information. This function also sets up the data structures necessary to serialize the native code to a file. Finally, it calls jl_create_native to create one or more LLVM modules containing the native code for the methods passed to it. jl_create_native is responsible for running codegen on the methods passed to it.","category":"page"},{"location":"devdocs/aot/#jl_dump_native","page":"Ahead of Time Compilation","title":"jl_dump_native","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"jl_dump_native is responsible for serializing the LLVM module containing the native code to a file. In addition to the module, the system image data produced by jl_create_system_image is compiled as a global variable. The output of this method is bitcode, object, and/or assembly archives containing the code and system image data.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"jl_dump_native is typically one of the larger time sinks when emitting native code, with much of the time spent in optimizing LLVM IR and emitting machine code. Therefore, this function is capable of multithreading the optimization and machine code emission steps. This multithreading is parameterized on the size of the module, but can be explicitly overridden by setting the JULIA_IMAGE_THREADS environment variable. The default maximum number of threads is half the number of available threads, but setting it to be lower can reduce peak memory usage during compilation.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"jl_dump_native can also produce native code optimized for multiple architectures, when integrated with the Julia loader. This is triggered by setting the JULIA_CPU_TARGET environment variable and mediated by the multiversioning pass in the optimization pipeline. To make this work with multithreading, an annotation step is added before the module is split into submodules that are emitted on their own threads, and this annotation step uses information available throughout the entire module to decide what functions are cloned for different architectures. Once the annotation has happened, individual threads can emit code for different architectures in parallel, knowing that a different submodule is guaranteed to produce the necessary functions that will be called by a cloned function.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Some other metadata about how the module was serialized is also stored in the archive, such as the number of threads used to serialize the module and the number of functions that were compiled.","category":"page"},{"location":"devdocs/aot/#Static-Linking","page":"Ahead of Time Compilation","title":"Static Linking","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The final step in the AOT compilation process is to run a linker on the object files in the archive produced by jl_dump_native. This produces a shared library containing the compiled code. This shared library can then be loaded by Julia to restore the state of the runtime. When compiling a system image, the native linker used by a C compiler is used to produce the final shared library. For package images, the LLVM linker LLD is used to provide a more consistent linking interface.","category":"page"},{"location":"devdocs/aot/#Loading-Code-Images-2","page":"Ahead of Time Compilation","title":"Loading Code Images","text":"","category":"section"},{"location":"devdocs/aot/#Loading-the-Shared-Library","page":"Ahead of Time Compilation","title":"Loading the Shared Library","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The first step in loading a code image is to load the shared library produced by the linker. This is done by calling jl_dlopen on the path to the shared library. This function is responsible for loading the shared library and resolving all of the symbols in the library.","category":"page"},{"location":"devdocs/aot/#Loading-Native-Code","page":"Ahead of Time Compilation","title":"Loading Native Code","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The loader first needs to identify whether the native code that was compiled is valid for the architecture that the loader is running on. This is necessary to avoid executing instructions that older CPUs do not recognize. This is done by checking the CPU features available on the current machine against the CPU features that the code was compiled for. When multiversioning is enabled, the loader will pick the appropriate version of each function to use based on the CPU features available on the current machine. If none of the feature sets that were multiversioned, the loader will throw an error.","category":"page"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"Part of the multiversioning pass creates a number of global arrays of all of the functions in the module. When this process is multithreaded, an array of arrays is created, which the loader reorganizes into one large array with all of the functions that were compiled for this architecture. A similar process occurs for the global variables in the module.","category":"page"},{"location":"devdocs/aot/#Setting-Up-Julia-State","page":"Ahead of Time Compilation","title":"Setting Up Julia State","text":"","category":"section"},{"location":"devdocs/aot/","page":"Ahead of Time Compilation","title":"Ahead of Time Compilation","text":"The loader then uses the global variables and functions produced from loading native code to set up Julia runtime core data structures in the current process. This setup involves adding types and methods to the Julia runtime, and making the cached native code available for use by other Julia functions and the interpreter. For package images, each method must be validated, in that the global method table's state must match the state that the package image was compiled for. In particular, if a different set of methods exists at the load time compared to compile time of the package image, the method must be invalidated and recompiled on first use. This is necessary to ensure that execution semantics remain the same regardless of if a package was precompiled or if the code was directly executed. System images do not need to perform this validation, since the global method table is empty at load time. Thus, system images have faster load times than package images.","category":"page"},{"location":"manual/control-flow/#Control-Flow","page":"Control Flow","title":"Control Flow","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Julia provides a variety of control flow constructs:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Compound Expressions: begin and ;.\nConditional Evaluation: if-elseif-else and ?: (ternary operator).\nShort-Circuit Evaluation: logical operators && (“and”) and || (“or”), and also chained comparisons.\nRepeated Evaluation: Loops: while and for.\nException Handling: try-catch, error and throw.\nTasks (aka Coroutines): yieldto.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The first five control flow mechanisms are standard to high-level programming languages. Tasks are not so standard: they provide non-local control flow, making it possible to switch between temporarily-suspended computations. This is a powerful construct: both exception handling and cooperative multitasking are implemented in Julia using tasks. Everyday programming requires no direct usage of tasks, but certain problems can be solved much more easily by using tasks.","category":"page"},{"location":"manual/control-flow/#man-compound-expressions","page":"Control Flow","title":"Compound Expressions","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Sometimes it is convenient to have a single expression which evaluates several subexpressions in order, returning the value of the last subexpression as its value. There are two Julia constructs that accomplish this: begin blocks and ; chains. The value of both compound expression constructs is that of the last subexpression. Here's an example of a begin block:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> z = begin\n x = 1\n y = 2\n x + y\n end\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Since these are fairly small, simple expressions, they could easily be placed onto a single line, which is where the ; chain syntax comes in handy:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> z = (x = 1; y = 2; x + y)\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This syntax is particularly useful with the terse single-line function definition form introduced in Functions. Although it is typical, there is no requirement that begin blocks be multiline or that ; chains be single-line:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> begin x = 1; y = 2; x + y end\n3\n\njulia> (x = 1;\n y = 2;\n x + y)\n3","category":"page"},{"location":"manual/control-flow/#man-conditional-evaluation","page":"Control Flow","title":"Conditional Evaluation","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Conditional evaluation allows portions of code to be evaluated or not evaluated depending on the value of a boolean expression. Here is the anatomy of the if-elseif-else conditional syntax:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"if x < y\n println(\"x is less than y\")\nelseif x > y\n println(\"x is greater than y\")\nelse\n println(\"x is equal to y\")\nend","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"If the condition expression x < y is true, then the corresponding block is evaluated; otherwise the condition expression x > y is evaluated, and if it is true, the corresponding block is evaluated; if neither expression is true, the else block is evaluated. Here it is in action:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function test(x, y)\n if x < y\n println(\"x is less than y\")\n elseif x > y\n println(\"x is greater than y\")\n else\n println(\"x is equal to y\")\n end\n end\ntest (generic function with 1 method)\n\njulia> test(1, 2)\nx is less than y\n\njulia> test(2, 1)\nx is greater than y\n\njulia> test(1, 1)\nx is equal to y","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The elseif and else blocks are optional, and as many elseif blocks as desired can be used. The condition expressions in the if-elseif-else construct are evaluated until the first one evaluates to true, after which the associated block is evaluated, and no further condition expressions or blocks are evaluated.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"if blocks are \"leaky\", i.e. they do not introduce a local scope. This means that new variables defined inside the if clauses can be used after the if block, even if they weren't defined before. So, we could have defined the test function above as","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function test(x,y)\n if x < y\n relation = \"less than\"\n elseif x == y\n relation = \"equal to\"\n else\n relation = \"greater than\"\n end\n println(\"x is \", relation, \" y.\")\n end\ntest (generic function with 1 method)\n\njulia> test(2, 1)\nx is greater than y.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The variable relation is declared inside the if block, but used outside. However, when depending on this behavior, make sure all possible code paths define a value for the variable. The following change to the above function results in a runtime error","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function test(x,y)\n if x < y\n relation = \"less than\"\n elseif x == y\n relation = \"equal to\"\n end\n println(\"x is \", relation, \" y.\")\n end\ntest (generic function with 1 method)\n\njulia> test(1,2)\nx is less than y.\n\njulia> test(2,1)\nERROR: UndefVarError: `relation` not defined in local scope\nStacktrace:\n [1] test(::Int64, ::Int64) at ./none:7","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"if blocks also return a value, which may seem unintuitive to users coming from many other languages. This value is simply the return value of the last executed statement in the branch that was chosen, so","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> x = 3\n3\n\njulia> if x > 0\n \"positive!\"\n else\n \"negative...\"\n end\n\"positive!\"","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Note that very short conditional statements (one-liners) are frequently expressed using Short-Circuit Evaluation in Julia, as outlined in the next section.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Unlike C, MATLAB, Perl, Python, and Ruby – but like Java, and a few other stricter, typed languages – it is an error if the value of a conditional expression is anything but true or false:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> if 1\n println(\"true\")\n end\nERROR: TypeError: non-boolean (Int64) used in boolean context","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This error indicates that the conditional was of the wrong type: Int64 rather than the required Bool.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The so-called \"ternary operator\", ?:, is closely related to the if-elseif-else syntax, but is used where a conditional choice between single expression values is required, as opposed to conditional execution of longer blocks of code. It gets its name from being the only operator in most languages taking three operands:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"a ? b : c","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The expression a, before the ?, is a condition expression, and the ternary operation evaluates the expression b, before the :, if the condition a is true or the expression c, after the :, if it is false. Note that the spaces around ? and : are mandatory: an expression like a?b:c is not a valid ternary expression (but a newline is acceptable after both the ? and the :).","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The easiest way to understand this behavior is to see an example. In the previous example, the println call is shared by all three branches: the only real choice is which literal string to print. This could be written more concisely using the ternary operator. For the sake of clarity, let's try a two-way version first:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> x = 1; y = 2;\n\njulia> println(x < y ? \"less than\" : \"not less than\")\nless than\n\njulia> x = 1; y = 0;\n\njulia> println(x < y ? \"less than\" : \"not less than\")\nnot less than","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"If the expression x < y is true, the entire ternary operator expression evaluates to the string \"less than\" and otherwise it evaluates to the string \"not less than\". The original three-way example requires chaining multiple uses of the ternary operator together:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> test(x, y) = println(x < y ? \"x is less than y\" :\n x > y ? \"x is greater than y\" : \"x is equal to y\")\ntest (generic function with 1 method)\n\njulia> test(1, 2)\nx is less than y\n\njulia> test(2, 1)\nx is greater than y\n\njulia> test(1, 1)\nx is equal to y","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"To facilitate chaining, the operator associates from right to left.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"It is significant that like if-elseif-else, the expressions before and after the : are only evaluated if the condition expression evaluates to true or false, respectively:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> v(x) = (println(x); x)\nv (generic function with 1 method)\n\njulia> 1 < 2 ? v(\"yes\") : v(\"no\")\nyes\n\"yes\"\n\njulia> 1 > 2 ? v(\"yes\") : v(\"no\")\nno\n\"no\"","category":"page"},{"location":"manual/control-flow/#Short-Circuit-Evaluation","page":"Control Flow","title":"Short-Circuit Evaluation","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The && and || operators in Julia correspond to logical “and” and “or” operations, respectively, and are typically used for this purpose. However, they have an additional property of short-circuit evaluation: they don't necessarily evaluate their second argument, as explained below. (There are also bitwise & and | operators that can be used as logical “and” and “or” without short-circuit behavior, but beware that & and | have higher precedence than && and || for evaluation order.)","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Short-circuit evaluation is quite similar to conditional evaluation. The behavior is found in most imperative programming languages having the && and || boolean operators: in a series of boolean expressions connected by these operators, only the minimum number of expressions are evaluated as are necessary to determine the final boolean value of the entire chain. Some languages (like Python) refer to them as and (&&) and or (||). Explicitly, this means that:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"In the expression a && b, the subexpression b is only evaluated if a evaluates to true.\nIn the expression a || b, the subexpression b is only evaluated if a evaluates to false.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The reasoning is that a && b must be false if a is false, regardless of the value of b, and likewise, the value of a || b must be true if a is true, regardless of the value of b. Both && and || associate to the right, but && has higher precedence than || does. It's easy to experiment with this behavior:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> t(x) = (println(x); true)\nt (generic function with 1 method)\n\njulia> f(x) = (println(x); false)\nf (generic function with 1 method)\n\njulia> t(1) && t(2)\n1\n2\ntrue\n\njulia> t(1) && f(2)\n1\n2\nfalse\n\njulia> f(1) && t(2)\n1\nfalse\n\njulia> f(1) && f(2)\n1\nfalse\n\njulia> t(1) || t(2)\n1\ntrue\n\njulia> t(1) || f(2)\n1\ntrue\n\njulia> f(1) || t(2)\n1\n2\ntrue\n\njulia> f(1) || f(2)\n1\n2\nfalse","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"You can easily experiment in the same way with the associativity and precedence of various combinations of && and || operators.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This behavior is frequently used in Julia to form an alternative to very short if statements. Instead of if end, one can write && (which could be read as: and then ). Similarly, instead of if ! end, one can write || (which could be read as: or else ).","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"For example, a recursive factorial routine could be defined like this:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function fact(n::Int)\n n >= 0 || error(\"n must be non-negative\")\n n == 0 && return 1\n n * fact(n-1)\n end\nfact (generic function with 1 method)\n\njulia> fact(5)\n120\n\njulia> fact(0)\n1\n\njulia> fact(-1)\nERROR: n must be non-negative\nStacktrace:\n [1] error at ./error.jl:33 [inlined]\n [2] fact(::Int64) at ./none:2\n [3] top-level scope","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Boolean operations without short-circuit evaluation can be done with the bitwise boolean operators introduced in Mathematical Operations and Elementary Functions: & and |. These are normal functions, which happen to support infix operator syntax, but always evaluate their arguments:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> f(1) & t(2)\n1\n2\nfalse\n\njulia> t(1) | t(2)\n1\n2\ntrue","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Just like condition expressions used in if, elseif or the ternary operator, the operands of && or || must be boolean values (true or false). Using a non-boolean value anywhere except for the last entry in a conditional chain is an error:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> 1 && true\nERROR: TypeError: non-boolean (Int64) used in boolean context","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"On the other hand, any type of expression can be used at the end of a conditional chain. It will be evaluated and returned depending on the preceding conditionals:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> true && (x = (1, 2, 3))\n(1, 2, 3)\n\njulia> false && (x = (1, 2, 3))\nfalse","category":"page"},{"location":"manual/control-flow/#man-loops","page":"Control Flow","title":"Repeated Evaluation: Loops","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"There are two constructs for repeated evaluation of expressions: the while loop and the for loop. Here is an example of a while loop:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> i = 1;\n\njulia> while i <= 3\n println(i)\n global i += 1\n end\n1\n2\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The while loop evaluates the condition expression (i <= 3 in this case), and as long it remains true, keeps also evaluating the body of the while loop. If the condition expression is false when the while loop is first reached, the body is never evaluated.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The for loop makes common repeated evaluation idioms easier to write. Since counting up and down like the above while loop does is so common, it can be expressed more concisely with a for loop:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i = 1:3\n println(i)\n end\n1\n2\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Here the 1:3 is a range object, representing the sequence of numbers 1, 2, 3. The for loop iterates through these values, assigning each one in turn to the variable i. In general, the for construct can loop over any \"iterable\" object (or \"container\"), from a range like 1:3 or 1:3:13 (a StepRange indicating every 3rd integer 1, 4, 7, …, 13) to more generic containers like arrays, including iterators defined by user code or external packages. For containers other than ranges, the alternative (but fully equivalent) keyword in or ∈ is typically used instead of =, since it makes the code read more clearly:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i in [1,4,0]\n println(i)\n end\n1\n4\n0\n\njulia> for s ∈ [\"foo\",\"bar\",\"baz\"]\n println(s)\n end\nfoo\nbar\nbaz","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Various types of iterable containers will be introduced and discussed in later sections of the manual (see, e.g., Multi-dimensional Arrays).","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"One rather important distinction between the previous while loop form and the for loop form is the scope during which the variable is visible. A for loop always introduces a new iteration variable in its body, regardless of whether a variable of the same name exists in the enclosing scope. This implies that on the one hand i need not be declared before the loop. On the other hand it will not be visible outside the loop, nor will an outside variable of the same name be affected. You'll either need a new interactive session instance or a different variable name to test this:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for j = 1:3\n println(j)\n end\n1\n2\n3\n\njulia> j\nERROR: UndefVarError: `j` not defined in `Main`","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> j = 0;\n\njulia> for j = 1:3\n println(j)\n end\n1\n2\n3\n\njulia> j\n0","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Use for outer to modify the latter behavior and reuse an existing local variable.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"See Scope of Variables for a detailed explanation of variable scope, outer, and how it works in Julia.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"It is sometimes convenient to terminate the repetition of a while before the test condition is falsified or stop iterating in a for loop before the end of the iterable object is reached. This can be accomplished with the break keyword:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> i = 1;\n\njulia> while true\n println(i)\n if i >= 3\n break\n end\n global i += 1\n end\n1\n2\n3\n\njulia> for j = 1:1000\n println(j)\n if j >= 3\n break\n end\n end\n1\n2\n3","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Without the break keyword, the above while loop would never terminate on its own, and the for loop would iterate up to 1000. These loops are both exited early by using break.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"In other circumstances, it is handy to be able to stop an iteration and move on to the next one immediately. The continue keyword accomplishes this:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i = 1:10\n if i % 3 != 0\n continue\n end\n println(i)\n end\n3\n6\n9","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This is a somewhat contrived example since we could produce the same behavior more clearly by negating the condition and placing the println call inside the if block. In realistic usage there is more code to be evaluated after the continue, and often there are multiple points from which one calls continue.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Multiple nested for loops can be combined into a single outer loop, forming the cartesian product of its iterables:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i = 1:2, j = 3:4\n println((i, j))\n end\n(1, 3)\n(1, 4)\n(2, 3)\n(2, 4)","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"With this syntax, iterables may still refer to outer loop variables; e.g. for i = 1:n, j = 1:i is valid. However a break statement inside such a loop exits the entire nest of loops, not just the inner one. Both variables (i and j) are set to their current iteration values each time the inner loop runs. Therefore, assignments to i will not be visible to subsequent iterations:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for i = 1:2, j = 3:4\n println((i, j))\n i = 0\n end\n(1, 3)\n(1, 4)\n(2, 3)\n(2, 4)","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"If this example were rewritten to use a for keyword for each variable, then the output would be different: the second and fourth values would contain 0.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Multiple containers can be iterated over at the same time in a single for loop using zip:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> for (j, k) in zip([1 2 3], [4 5 6 7])\n println((j,k))\n end\n(1, 4)\n(2, 5)\n(3, 6)","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Using zip will create an iterator that is a tuple containing the subiterators for the containers passed to it. The zip iterator will iterate over all subiterators in order, choosing the ith element of each subiterator in the ith iteration of the for loop. Once any of the subiterators run out, the for loop will stop.","category":"page"},{"location":"manual/control-flow/#Exception-Handling","page":"Control Flow","title":"Exception Handling","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"When an unexpected condition occurs, a function may be unable to return a reasonable value to its caller. In such cases, it may be best for the exceptional condition to either terminate the program while printing a diagnostic error message, or if the programmer has provided code to handle such exceptional circumstances then allow that code to take the appropriate action.","category":"page"},{"location":"manual/control-flow/#Built-in-Exceptions","page":"Control Flow","title":"Built-in Exceptions","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Exceptions are thrown when an unexpected condition has occurred. The built-in Exceptions listed below all interrupt the normal flow of control.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Exception\nArgumentError\nBoundsError\nCompositeException\nDimensionMismatch\nDivideError\nDomainError\nEOFError\nErrorException\nInexactError\nInitError\nInterruptException\nInvalidStateException\nKeyError\nLoadError\nOutOfMemoryError\nReadOnlyMemoryError\nRemoteException\nMethodError\nOverflowError\nMeta.ParseError\nSystemError\nTypeError\nUndefRefError\nUndefVarError\nStringIndexError","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"For example, the sqrt function throws a DomainError if applied to a negative real value:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> sqrt(-1)\nERROR: DomainError with -1.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"You may define your own exceptions in the following way:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> struct MyCustomException <: Exception end","category":"page"},{"location":"manual/control-flow/#The-[throw](@ref)-function","page":"Control Flow","title":"The throw function","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Exceptions can be created explicitly with throw. For example, a function defined only for non-negative numbers could be written to throw a DomainError if the argument is negative:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> f(x) = x>=0 ? exp(-x) : throw(DomainError(x, \"argument must be non-negative\"))\nf (generic function with 1 method)\n\njulia> f(1)\n0.36787944117144233\n\njulia> f(-1)\nERROR: DomainError with -1:\nargument must be non-negative\nStacktrace:\n [1] f(::Int64) at ./none:1","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Note that DomainError without parentheses is not an exception, but a type of exception. It needs to be called to obtain an Exception object:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> typeof(DomainError(nothing)) <: Exception\ntrue\n\njulia> typeof(DomainError) <: Exception\nfalse","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Additionally, some exception types take one or more arguments that are used for error reporting:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> throw(UndefVarError(:x))\nERROR: UndefVarError: `x` not defined","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"This mechanism can be implemented easily by custom exception types following the way UndefVarError is written:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> struct MyUndefVarError <: Exception\n var::Symbol\n end\n\njulia> Base.showerror(io::IO, e::MyUndefVarError) = print(io, e.var, \" not defined\")","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"note: Note\nWhen writing an error message, it is preferred to make the first word lowercase. For example,size(A) == size(B) || throw(DimensionMismatch(\"size of A not equal to size of B\"))is preferred oversize(A) == size(B) || throw(DimensionMismatch(\"Size of A not equal to size of B\")).However, sometimes it makes sense to keep the uppercase first letter, for instance if an argument to a function is a capital letter:size(A,1) == size(B,2) || throw(DimensionMismatch(\"A has first dimension...\")).","category":"page"},{"location":"manual/control-flow/#Errors","page":"Control Flow","title":"Errors","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The error function is used to produce an ErrorException that interrupts the normal flow of control.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Suppose we want to stop execution immediately if the square root of a negative number is taken. To do this, we can define a fussy version of the sqrt function that raises an error if its argument is negative:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> fussy_sqrt(x) = x >= 0 ? sqrt(x) : error(\"negative x not allowed\")\nfussy_sqrt (generic function with 1 method)\n\njulia> fussy_sqrt(2)\n1.4142135623730951\n\njulia> fussy_sqrt(-1)\nERROR: negative x not allowed\nStacktrace:\n [1] error at ./error.jl:33 [inlined]\n [2] fussy_sqrt(::Int64) at ./none:1\n [3] top-level scope","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"If fussy_sqrt is called with a negative value from another function, instead of trying to continue execution of the calling function, it returns immediately, displaying the error message in the interactive session:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> function verbose_fussy_sqrt(x)\n println(\"before fussy_sqrt\")\n r = fussy_sqrt(x)\n println(\"after fussy_sqrt\")\n return r\n end\nverbose_fussy_sqrt (generic function with 1 method)\n\njulia> verbose_fussy_sqrt(2)\nbefore fussy_sqrt\nafter fussy_sqrt\n1.4142135623730951\n\njulia> verbose_fussy_sqrt(-1)\nbefore fussy_sqrt\nERROR: negative x not allowed\nStacktrace:\n [1] error at ./error.jl:33 [inlined]\n [2] fussy_sqrt at ./none:1 [inlined]\n [3] verbose_fussy_sqrt(::Int64) at ./none:3\n [4] top-level scope","category":"page"},{"location":"manual/control-flow/#The-try/catch-statement","page":"Control Flow","title":"The try/catch statement","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The try/catch statement allows for Exceptions to be tested for, and for the graceful handling of things that may ordinarily break your application. For example, in the below code the function for square root would normally throw an exception. By placing a try/catch block around it we can mitigate that here. You may choose how you wish to handle this exception, whether logging it, return a placeholder value or as in the case below where we just printed out a statement. One thing to think about when deciding how to handle unexpected situations is that using a try/catch block is much slower than using conditional branching to handle those situations. Below there are more examples of handling exceptions with a try/catch block:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> try\n sqrt(\"ten\")\n catch e\n println(\"You should have entered a numeric value\")\n end\nYou should have entered a numeric value","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"try/catch statements also allow the Exception to be saved in a variable. The following contrived example calculates the square root of the second element of x if x is indexable, otherwise assumes x is a real number and returns its square root:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"julia> sqrt_second(x) = try\n sqrt(x[2])\n catch y\n if isa(y, DomainError)\n sqrt(complex(x[2], 0))\n elseif isa(y, BoundsError)\n sqrt(x)\n end\n end\nsqrt_second (generic function with 1 method)\n\njulia> sqrt_second([1 4])\n2.0\n\njulia> sqrt_second([1 -4])\n0.0 + 2.0im\n\njulia> sqrt_second(9)\n3.0\n\njulia> sqrt_second(-9)\nERROR: DomainError with -9.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\nStacktrace:\n[...]","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Note that the symbol following catch will always be interpreted as a name for the exception, so care is needed when writing try/catch expressions on a single line. The following code will not work to return the value of x in case of an error:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"try bad() catch x end","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Instead, use a semicolon or insert a line break after catch:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"try bad() catch; x end\n\ntry bad()\ncatch\n x\nend","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"The power of the try/catch construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions. There are situations where no error has occurred, but the ability to unwind the stack and pass a value to a higher level is desirable. Julia provides the rethrow, backtrace, catch_backtrace and current_exceptions functions for more advanced error handling.","category":"page"},{"location":"manual/control-flow/#else-Clauses","page":"Control Flow","title":"else Clauses","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"compat: Julia 1.8\nThis functionality requires at least Julia 1.8.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"In some cases, one may not only want to appropriately handle the error case, but also want to run some code only if the try block succeeds. For this, an else clause can be specified after the catch block that is run whenever no error was thrown previously. The advantage over including this code in the try block instead is that any further errors don't get silently caught by the catch clause.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"local x\ntry\n x = read(\"file\", String)\ncatch\n # handle read errors\nelse\n # do something with x\nend","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"note: Note\nThe try, catch, else, and finally clauses each introduce their own scope blocks, so if a variable is only defined in the try block, it can not be accessed by the else or finally clause:julia> try\n foo = 1\n catch\n else\n foo\n end\nERROR: UndefVarError: `foo` not defined in `Main`\nSuggestion: check for spelling errors or missing imports.Use the local keyword outside the try block to make the variable accessible from anywhere within the outer scope.","category":"page"},{"location":"manual/control-flow/#finally-Clauses","page":"Control Flow","title":"finally Clauses","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"In code that performs state changes or uses resources like files, there is typically clean-up work (such as closing files) that needs to be done when the code is finished. Exceptions potentially complicate this task, since they can cause a block of code to exit before reaching its normal end. The finally keyword provides a way to run some code when a given block of code exits, regardless of how it exits.","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"For example, here is how we can guarantee that an opened file is closed:","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"f = open(\"file\")\ntry\n # operate on file f\nfinally\n close(f)\nend","category":"page"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"When control leaves the try block (for example due to a return, or just finishing normally), close(f) will be executed. If the try block exits due to an exception, the exception will continue propagating. A catch block may be combined with try and finally as well. In this case the finally block will run after catch has handled the error.","category":"page"},{"location":"manual/control-flow/#man-tasks","page":"Control Flow","title":"Tasks (aka Coroutines)","text":"","category":"section"},{"location":"manual/control-flow/","page":"Control Flow","title":"Control Flow","text":"Tasks are a control flow feature that allows computations to be suspended and resumed in a flexible manner. We mention them here only for completeness; for a full discussion see Asynchronous Programming.","category":"page"},{"location":"devdocs/meta/#Talking-to-the-compiler-(the-:meta-mechanism)","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"","category":"section"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"In some circumstances, one might wish to provide hints or instructions that a given block of code has special properties: you might always want to inline it, or you might want to turn on special compiler optimization passes. Starting with version 0.4, Julia has a convention that these instructions can be placed inside a :meta expression, which is typically (but not necessarily) the first expression in the body of a function.","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":":meta expressions are created with macros. As an example, consider the implementation of the @inline macro:","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"macro inline(ex)\n esc(isa(ex, Expr) ? pushmeta!(ex, :inline) : ex)\nend","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"Here, ex is expected to be an expression defining a function. A statement like this:","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"@inline function myfunction(x)\n x*(x+3)\nend","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"gets turned into an expression like this:","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"quote\n function myfunction(x)\n Expr(:meta, :inline)\n x*(x+3)\n end\nend","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"Base.pushmeta!(ex, tag::Union{Symbol,Expr}) appends :tag to the end of the :meta expression, creating a new :meta expression if necessary.","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"To use the metadata, you have to parse these :meta expressions. If your implementation can be performed within Julia, Base.popmeta! is very handy: Base.popmeta!(body, :symbol) will scan a function body expression (one without the function signature) for the first :meta expression containing :symbol, extract any arguments, and return a tuple (found::Bool, args::Array{Any}). If the metadata did not have any arguments, or :symbol was not found, the args array will be empty.","category":"page"},{"location":"devdocs/meta/","page":"Talking to the compiler (the :meta mechanism)","title":"Talking to the compiler (the :meta mechanism)","text":"Not yet provided is a convenient infrastructure for parsing :meta expressions from C++.","category":"page"},{"location":"devdocs/stdio/#printf()-and-stdio-in-the-Julia-runtime","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"","category":"section"},{"location":"devdocs/stdio/#Libuv-wrappers-for-stdio","page":"printf() and stdio in the Julia runtime","title":"Libuv wrappers for stdio","text":"","category":"section"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"julia.h defines libuv wrappers for the stdio.h streams:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"uv_stream_t *JL_STDIN;\nuv_stream_t *JL_STDOUT;\nuv_stream_t *JL_STDERR;","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"... and corresponding output functions:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"int jl_printf(uv_stream_t *s, const char *format, ...);\nint jl_vprintf(uv_stream_t *s, const char *format, va_list args);","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"These printf functions are used by the .c files in the src/ and cli/ directories wherever stdio is needed to ensure that output buffering is handled in a unified way.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"In special cases, like signal handlers, where the full libuv infrastructure is too heavy, jl_safe_printf() can be used to write(2) directly to STDERR_FILENO:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"void jl_safe_printf(const char *str, ...);","category":"page"},{"location":"devdocs/stdio/#Interface-between-JL_STD*-and-Julia-code","page":"printf() and stdio in the Julia runtime","title":"Interface between JL_STD* and Julia code","text":"","category":"section"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"Base.stdin, Base.stdout and Base.stderr are bound to the JL_STD* libuv streams defined in the runtime.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"Julia's __init__() function (in base/sysimg.jl) calls reinit_stdio() (in base/stream.jl) to create Julia objects for Base.stdin, Base.stdout and Base.stderr.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"reinit_stdio() uses ccall to retrieve pointers to JL_STD* and calls jl_uv_handle_type() to inspect the type of each stream. It then creates a Julia Base.IOStream, Base.TTY or Base.PipeEndpoint object to represent each stream, e.g.:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"$ julia -e 'println(typeof((stdin, stdout, stderr)))'\nTuple{Base.TTY,Base.TTY,Base.TTY}\n\n$ julia -e 'println(typeof((stdin, stdout, stderr)))' < /dev/null 2>/dev/null\nTuple{IOStream,Base.TTY,IOStream}\n\n$ echo hello | julia -e 'println(typeof((stdin, stdout, stderr)))' | cat\nTuple{Base.PipeEndpoint,Base.PipeEndpoint,Base.TTY}","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"The Base.read and Base.write methods for these streams use ccall to call libuv wrappers in src/jl_uv.c, e.g.:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"stream.jl: function write(s::IO, p::Ptr, nb::Integer)\n -> ccall(:jl_uv_write, ...)\n jl_uv.c: -> int jl_uv_write(uv_stream_t *stream, ...)\n -> uv_write(uvw, stream, buf, ...)","category":"page"},{"location":"devdocs/stdio/#printf()-during-initialization","page":"printf() and stdio in the Julia runtime","title":"printf() during initialization","text":"","category":"section"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"The libuv streams relied upon by jl_printf() etc., are not available until midway through initialization of the runtime (see init.c, init_stdio()). Error messages or warnings that need to be printed before this are routed to the standard C library fwrite() function by the following mechanism:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"In sys.c, the JL_STD* stream pointers are statically initialized to integer constants: STD*_FILENO (0, 1 and 2). In jl_uv.c the jl_uv_puts() function checks its uv_stream_t* stream argument and calls fwrite() if stream is set to STDOUT_FILENO or STDERR_FILENO.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"This allows for uniform use of jl_printf() throughout the runtime regardless of whether or not any particular piece of code is reachable before initialization is complete.","category":"page"},{"location":"devdocs/stdio/#Legacy-ios.c-library","page":"printf() and stdio in the Julia runtime","title":"Legacy ios.c library","text":"","category":"section"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"The src/support/ios.c library is inherited from femtolisp. It provides cross-platform buffered file IO and in-memory temporary buffers.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"ios.c is still used by:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"src/flisp/*.c\nsrc/dump.c – for serialization file IO and for memory buffers.\nsrc/staticdata.c – for serialization file IO and for memory buffers.\nbase/iostream.jl – for file IO (see base/fs.jl for libuv equivalent).","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"Use of ios.c in these modules is mostly self-contained and separated from the libuv I/O system. However, there is one place where femtolisp calls through to jl_printf() with a legacy ios_t stream.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"There is a hack in ios.h that makes the ios_t.bm field line up with the uv_stream_t.type and ensures that the values used for ios_t.bm to not overlap with valid UV_HANDLE_TYPE values. This allows uv_stream_t pointers to point to ios_t streams.","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"This is needed because jl_printf() caller jl_static_show() is passed an ios_t stream by femtolisp's fl_print() function. Julia's jl_uv_puts() function has special handling for this:","category":"page"},{"location":"devdocs/stdio/","page":"printf() and stdio in the Julia runtime","title":"printf() and stdio in the Julia runtime","text":"if (stream->type > UV_HANDLE_TYPE_MAX) {\n return ios_write((ios_t*)stream, str, n);\n}","category":"page"},{"location":"manual/getting-started/#man-getting-started","page":"Getting Started","title":"Getting Started","text":"","category":"section"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"Julia installation is straightforward, whether using precompiled binaries or compiling from source. Download and install Julia by following the instructions at https://julialang.org/downloads/.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"If you are coming to Julia from one of the following languages, then you should start by reading the section on noteworthy differences from MATLAB, R, Python, C/C++ or Common Lisp. This will help you avoid some common pitfalls since Julia differs from those languages in many subtle ways.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"The easiest way to learn and experiment with Julia is by starting an interactive session (also known as a read-eval-print loop or \"REPL\") by double-clicking the Julia executable or running julia from the command line:","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"using REPL\nio = IOBuffer()\nREPL.banner(io)\nbanner = String(take!(io))\nimport Markdown\nMarkdown.parse(\"```\\n\\$ julia\\n\\n$(banner)\\njulia> 1 + 2\\n3\\n\\njulia> ans\\n3\\n```\")","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"To exit the interactive session, type CTRL-D (press the Control/^ key together with the d key), or type exit(). When run in interactive mode, julia displays a banner and prompts the user for input. Once the user has entered a complete expression, such as 1 + 2, and hits enter, the interactive session evaluates the expression and shows its value. If an expression is entered into an interactive session with a trailing semicolon, its value is not shown. The variable ans is bound to the value of the last evaluated expression whether it is shown or not. The ans variable is only bound in interactive sessions, not when Julia code is run in other ways.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"To evaluate expressions written in a source file file.jl, write include(\"file.jl\").","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"To run code in a file non-interactively, you can give it as the first argument to the julia command:","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"$ julia script.jl","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"You can pass additional arguments to Julia, and to your program script.jl. A detailed list of all the available options can be found under Command-line Interface.","category":"page"},{"location":"manual/getting-started/#Resources","page":"Getting Started","title":"Resources","text":"","category":"section"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"A curated list of useful learning resources to help new users get started can be found on the learning page of the main Julia website.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"You can use the REPL as a learning resource by switching into the help mode. Switch to help mode by pressing ? at an empty julia> prompt, before typing anything else. Typing a keyword in help mode will fetch the documentation for it, along with examples. Similarly for most functions or other objects you might encounter!","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"help?> begin\nsearch: begin disable_sigint reenable_sigint\n\n begin\n\n begin...end denotes a block of code.","category":"page"},{"location":"manual/getting-started/","page":"Getting Started","title":"Getting Started","text":"If you already know Julia a bit, you might want to peek ahead at Performance Tips and Workflow Tips.","category":"page"},{"location":"devdocs/build/macos/#macOS","page":"macOS","title":"macOS","text":"","category":"section"},{"location":"devdocs/build/macos/","page":"macOS","title":"macOS","text":"You need to have the current Xcode command line utilities installed: run xcode-select --install in the terminal. You will need to rerun this terminal command after each macOS update, otherwise you may run into errors involving missing libraries or headers.","category":"page"},{"location":"devdocs/build/macos/","page":"macOS","title":"macOS","text":"The dependent libraries are now built with BinaryBuilder and will be automatically downloaded. This is the preferred way to build Julia source. In case you want to build them all on your own, you will need a 64-bit gfortran to compile Julia dependencies.","category":"page"},{"location":"devdocs/build/macos/","page":"macOS","title":"macOS","text":"brew install gcc","category":"page"},{"location":"devdocs/build/macos/","page":"macOS","title":"macOS","text":"If you have set LD_LIBRARY_PATH or DYLD_LIBRARY_PATH in your .bashrc or equivalent, Julia may be unable to find various libraries that come bundled with it. These environment variables need to be unset for Julia to work.","category":"page"},{"location":"manual/types/#man-types","page":"Types","title":"Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type systems have traditionally fallen into two quite different camps: static type systems, where every program expression must have a type computable before the execution of the program, and dynamic type systems, where nothing is known about types until run time, when the actual values manipulated by the program are available. Object orientation allows some flexibility in statically typed languages by letting code be written without the precise types of values being known at compile time. The ability to write code that can operate on different types is called polymorphism. All code in classic dynamically typed languages is polymorphic: only by explicitly checking types, or when objects fail to support operations at run-time, are the types of any values ever restricted.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Julia's type system is dynamic, but gains some of the advantages of static type systems by making it possible to indicate that certain values are of specific types. This can be of great assistance in generating efficient code, but even more significantly, it allows method dispatch on the types of function arguments to be deeply integrated with the language. Method dispatch is explored in detail in Methods, but is rooted in the type system presented here.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The default behavior in Julia when types are omitted is to allow values to be of any type. Thus, one can write many useful Julia functions without ever explicitly using types. When additional expressiveness is needed, however, it is easy to gradually introduce explicit type annotations into previously \"untyped\" code. Adding annotations serves three primary purposes: to take advantage of Julia's powerful multiple-dispatch mechanism, to improve human readability, and to catch programmer errors.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Describing Julia in the lingo of type systems, it is: dynamic, nominative and parametric. Generic types can be parameterized, and the hierarchical relationships between types are explicitly declared, rather than implied by compatible structure. One particularly distinctive feature of Julia's type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes. While this might at first seem unduly restrictive, it has many beneficial consequences with surprisingly few drawbacks. It turns out that being able to inherit behavior is much more important than being able to inherit structure, and inheriting both causes significant difficulties in traditional object-oriented languages. Other high-level aspects of Julia's type system that should be mentioned up front are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There is no division between object and non-object values: all values in Julia are true objects having a type that belongs to a single, fully connected type graph, all nodes of which are equally first-class as types.\nThere is no meaningful concept of a \"compile-time type\": the only type a value has is its actual type when the program is running. This is called a \"run-time type\" in object-oriented languages where the combination of static compilation with polymorphism makes this distinction significant.\nOnly values, not variables, have types – variables are simply names bound to values, although for simplicity we may say \"type of a variable\" as shorthand for \"type of the value to which a variable refers\".\nBoth abstract and concrete types can be parameterized by other types. They can also be parameterized by symbols, by values of any type for which isbits returns true (essentially, things like numbers and bools that are stored like C types or structs with no pointers to other objects), and also by tuples thereof. Type parameters may be omitted when they do not need to be referenced or restricted.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Julia's type system is designed to be powerful and expressive, yet clear, intuitive and unobtrusive. Many Julia programmers may never feel the need to write code that explicitly uses types. Some kinds of programming, however, become clearer, simpler, faster and more robust with declared types.","category":"page"},{"location":"manual/types/#Type-Declarations","page":"Types","title":"Type Declarations","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"The :: operator can be used to attach type annotations to expressions and variables in programs. There are two primary reasons to do this:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"As an assertion to help confirm that your program works the way you expect, and\nTo provide extra type information to the compiler, which can then improve performance in some cases.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"When appended to an expression computing a value, the :: operator is read as \"is an instance of\". It can be used anywhere to assert that the value of the expression on the left is an instance of the type on the right. When the type on the right is concrete, the value on the left must have that type as its implementation – recall that all concrete types are final, so no implementation is a subtype of any other. When the type is abstract, it suffices for the value to be implemented by a concrete type that is a subtype of the abstract type. If the type assertion is not true, an exception is thrown, otherwise, the left-hand value is returned:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> (1+2)::AbstractFloat\nERROR: TypeError: in typeassert, expected AbstractFloat, got a value of type Int64\n\njulia> (1+2)::Int\n3","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This allows a type assertion to be attached to any expression in-place.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"When appended to a variable on the left-hand side of an assignment, or as part of a local declaration, the :: operator means something a bit different: it declares the variable to always have the specified type, like a type declaration in a statically-typed language such as C. Every value assigned to the variable will be converted to the declared type using convert:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> function foo()\n x::Int8 = 100\n x\n end\nfoo (generic function with 1 method)\n\njulia> x = foo()\n100\n\njulia> typeof(x)\nInt8","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This feature is useful for avoiding performance \"gotchas\" that could occur if one of the assignments to a variable changed its type unexpectedly.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This \"declaration\" behavior only occurs in specific contexts:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"local x::Int8 # in a local declaration\nx::Int8 = 10 # as the left-hand side of an assignment","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"and applies to the whole current scope, even before the declaration.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"As of Julia 1.8, type declarations can now be used in global scope i.e. type annotations can be added to global variables to make accessing them type stable.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> x::Int = 10\n10\n\njulia> x = 3.5\nERROR: InexactError: Int64(3.5)\n\njulia> function foo(y)\n global x = 15.8 # throws an error when foo is called\n return x + y\n end\nfoo (generic function with 1 method)\n\njulia> foo(10)\nERROR: InexactError: Int64(15.8)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Declarations can also be attached to function definitions:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function sinc(x)::Float64\n if x == 0\n return 1\n end\n return sin(pi*x)/(pi*x)\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Returning from this function behaves just like an assignment to a variable with a declared type: the value is always converted to Float64.","category":"page"},{"location":"manual/types/#man-abstract-types","page":"Types","title":"Abstract Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Abstract types cannot be instantiated, and serve only as nodes in the type graph, thereby describing sets of related concrete types: those concrete types which are their descendants. We begin with abstract types even though they have no instantiation because they are the backbone of the type system: they form the conceptual hierarchy which makes Julia's type system more than just a collection of object implementations.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Recall that in Integers and Floating-Point Numbers, we introduced a variety of concrete types of numeric values: Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, Float16, Float32, and Float64. Although they have different representation sizes, Int8, Int16, Int32, Int64 and Int128 all have in common that they are signed integer types. Likewise UInt8, UInt16, UInt32, UInt64 and UInt128 are all unsigned integer types, while Float16, Float32 and Float64 are distinct in being floating-point types rather than integers. It is common for a piece of code to make sense, for example, only if its arguments are some kind of integer, but not really depend on what particular kind of integer. For example, the greatest common denominator algorithm works for all kinds of integers, but will not work for floating-point numbers. Abstract types allow the construction of a hierarchy of types, providing a context into which concrete types can fit. This allows you, for example, to easily program to any type that is an integer, without restricting an algorithm to a specific type of integer.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Abstract types are declared using the abstract type keyword. The general syntaxes for declaring an abstract type are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"abstract type «name» end\nabstract type «name» <: «supertype» end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The abstract type keyword introduces a new abstract type, whose name is given by «name». This name can be optionally followed by <: and an already-existing type, indicating that the newly declared abstract type is a subtype of this \"parent\" type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"When no supertype is given, the default supertype is Any – a predefined abstract type that all objects are instances of and all types are subtypes of. In type theory, Any is commonly called \"top\" because it is at the apex of the type graph. Julia also has a predefined abstract \"bottom\" type, at the nadir of the type graph, which is written as Union{}. It is the exact opposite of Any: no object is an instance of Union{} and all types are supertypes of Union{}.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Let's consider some of the abstract types that make up Julia's numerical hierarchy:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"abstract type Number end\nabstract type Real <: Number end\nabstract type AbstractFloat <: Real end\nabstract type Integer <: Real end\nabstract type Signed <: Integer end\nabstract type Unsigned <: Integer end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The Number type is a direct child type of Any, and Real is its child. In turn, Real has two children (it has more, but only two are shown here; we'll get to the others later): Integer and AbstractFloat, separating the world into representations of integers and representations of real numbers. Representations of real numbers include floating-point types, but also include other types, such as rationals. AbstractFloat includes only floating-point representations of real numbers. Integers are further subdivided into Signed and Unsigned varieties.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The <: operator in general means \"is a subtype of\", and, used in declarations like those above, declares the right-hand type to be an immediate supertype of the newly declared type. It can also be used in expressions as a subtype operator which returns true when its left operand is a subtype of its right operand:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Integer <: Number\ntrue\n\njulia> Integer <: AbstractFloat\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An important use of abstract types is to provide default implementations for concrete types. To give a simple example, consider:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function myplus(x,y)\n x+y\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The first thing to note is that the above argument declarations are equivalent to x::Any and y::Any. When this function is invoked, say as myplus(2,5), the dispatcher chooses the most specific method named myplus that matches the given arguments. (See Methods for more information on multiple dispatch.)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Assuming no method more specific than the above is found, Julia next internally defines and compiles a method called myplus specifically for two Int arguments based on the generic function given above, i.e., it implicitly defines and compiles:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function myplus(x::Int,y::Int)\n x+y\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"and finally, it invokes this specific method.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Thus, abstract types allow programmers to write generic functions that can later be used as the default method by many combinations of concrete types. Thanks to multiple dispatch, the programmer has full control over whether the default or more specific method is used.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An important point to note is that there is no loss in performance if the programmer relies on a function whose arguments are abstract types, because it is recompiled for each tuple of concrete argument types with which it is invoked. (There may be a performance issue, however, in the case of function arguments that are containers of abstract types; see Performance Tips.)","category":"page"},{"location":"manual/types/#Primitive-Types","page":"Types","title":"Primitive Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"warning: Warning\nIt is almost always preferable to wrap an existing primitive type in a new composite type than to define your own primitive type.This functionality exists to allow Julia to bootstrap the standard primitive types that LLVM supports. Once they are defined, there is very little reason to define more.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A primitive type is a concrete type whose data consists of plain old bits. Classic examples of primitive types are integers and floating-point values. Unlike most languages, Julia lets you declare your own primitive types, rather than providing only a fixed set of built-in ones. In fact, the standard primitive types are all defined in the language itself:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"primitive type Float16 <: AbstractFloat 16 end\nprimitive type Float32 <: AbstractFloat 32 end\nprimitive type Float64 <: AbstractFloat 64 end\n\nprimitive type Bool <: Integer 8 end\nprimitive type Char <: AbstractChar 32 end\n\nprimitive type Int8 <: Signed 8 end\nprimitive type UInt8 <: Unsigned 8 end\nprimitive type Int16 <: Signed 16 end\nprimitive type UInt16 <: Unsigned 16 end\nprimitive type Int32 <: Signed 32 end\nprimitive type UInt32 <: Unsigned 32 end\nprimitive type Int64 <: Signed 64 end\nprimitive type UInt64 <: Unsigned 64 end\nprimitive type Int128 <: Signed 128 end\nprimitive type UInt128 <: Unsigned 128 end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The general syntaxes for declaring a primitive type are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"primitive type «name» «bits» end\nprimitive type «name» <: «supertype» «bits» end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The number of bits indicates how much storage the type requires and the name gives the new type a name. A primitive type can optionally be declared to be a subtype of some supertype. If a supertype is omitted, then the type defaults to having Any as its immediate supertype. The declaration of Bool above therefore means that a boolean value takes eight bits to store, and has Integer as its immediate supertype. Currently, only sizes that are multiples of 8 bits are supported and you are likely to experience LLVM bugs with sizes other than those used above. Therefore, boolean values, although they really need just a single bit, cannot be declared to be any smaller than eight bits.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The types Bool, Int8 and UInt8 all have identical representations: they are eight-bit chunks of memory. Since Julia's type system is nominative, however, they are not interchangeable despite having identical structure. A fundamental difference between them is that they have different supertypes: Bool's direct supertype is Integer, Int8's is Signed, and UInt8's is Unsigned. All other differences between Bool, Int8, and UInt8 are matters of behavior – the way functions are defined to act when given objects of these types as arguments. This is why a nominative type system is necessary: if structure determined type, which in turn dictates behavior, then it would be impossible to make Bool behave any differently than Int8 or UInt8.","category":"page"},{"location":"manual/types/#Composite-Types","page":"Types","title":"Composite Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Composite types are called records, structs, or objects in various languages. A composite type is a collection of named fields, an instance of which can be treated as a single value. In many languages, composite types are the only kind of user-definable type, and they are by far the most commonly used user-defined type in Julia as well.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In mainstream object oriented languages, such as C++, Java, Python and Ruby, composite types also have named functions associated with them, and the combination is called an \"object\". In purer object-oriented languages, such as Ruby or Smalltalk, all values are objects whether they are composites or not. In less pure object oriented languages, including C++ and Java, some values, such as integers and floating-point values, are not objects, while instances of user-defined composite types are true objects with associated methods. In Julia, all values are objects, but functions are not bundled with the objects they operate on. This is necessary since Julia chooses which method of a function to use by multiple dispatch, meaning that the types of all of a function's arguments are considered when selecting a method, rather than just the first one (see Methods for more information on methods and dispatch). Thus, it would be inappropriate for functions to \"belong\" to only their first argument. Organizing methods into function objects rather than having named bags of methods \"inside\" each object ends up being a highly beneficial aspect of the language design.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Composite types are introduced with the struct keyword followed by a block of field names, optionally annotated with types using the :: operator:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Foo\n bar\n baz::Int\n qux::Float64\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Fields with no type annotation default to Any, and can accordingly hold any type of value.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"New objects of type Foo are created by applying the Foo type object like a function to values for its fields:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> foo = Foo(\"Hello, world.\", 23, 1.5)\nFoo(\"Hello, world.\", 23, 1.5)\n\njulia> typeof(foo)\nFoo","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"When a type is applied like a function it is called a constructor. Two constructors are generated automatically (these are called default constructors). One accepts any arguments and calls convert to convert them to the types of the fields, and the other accepts arguments that match the field types exactly. The reason both of these are generated is that this makes it easier to add new definitions without inadvertently replacing a default constructor.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since the bar field is unconstrained in type, any value will do. However, the value for baz must be convertible to Int:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Foo((), 23.5, 1)\nERROR: InexactError: Int64(23.5)\nStacktrace:\n[...]","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"You may find a list of field names using the fieldnames function.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> fieldnames(Foo)\n(:bar, :baz, :qux)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"You can access the field values of a composite object using the traditional foo.bar notation:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> foo.bar\n\"Hello, world.\"\n\njulia> foo.baz\n23\n\njulia> foo.qux\n1.5","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Composite objects declared with struct are immutable; they cannot be modified after construction. This may seem odd at first, but it has several advantages:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"It can be more efficient. Some structs can be packed efficiently into arrays, and in some cases the compiler is able to avoid allocating immutable objects entirely.\nIt is not possible to violate the invariants provided by the type's constructors.\nCode using immutable objects can be easier to reason about.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An immutable object might contain mutable objects, such as arrays, as fields. Those contained objects will remain mutable; only the fields of the immutable object itself cannot be changed to point to different objects.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Where required, mutable composite objects can be declared with the keyword mutable struct, to be discussed in the next section.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"If all the fields of an immutable structure are indistinguishable (===) then two immutable values containing those fields are also indistinguishable:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct X\n a::Int\n b::Float64\n end\n\njulia> X(1, 2) === X(1, 2)\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There is much more to say about how instances of composite types are created, but that discussion depends on both Parametric Types and on Methods, and is sufficiently important to be addressed in its own section: Constructors.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"For many user-defined types X, you may want to define a method Base.broadcastable(x::X) = Ref(x) so that instances of that type act as 0-dimensional \"scalars\" for broadcasting.","category":"page"},{"location":"manual/types/#Mutable-Composite-Types","page":"Types","title":"Mutable Composite Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"If a composite type is declared with mutable struct instead of struct, then instances of it can be modified:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> mutable struct Bar\n baz\n qux::Float64\n end\n\njulia> bar = Bar(\"Hello\", 1.5);\n\njulia> bar.qux = 2.0\n2.0\n\njulia> bar.baz = 1//2\n1//2","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An extra interface between the fields and the user can be provided through Instance Properties. This grants more control on what can be accessed and modified using the bar.baz notation.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In order to support mutation, such objects are generally allocated on the heap, and have stable memory addresses. A mutable object is like a little container that might hold different values over time, and so can only be reliably identified with its address. In contrast, an instance of an immutable type is associated with specific field values –- the field values alone tell you everything about the object. In deciding whether to make a type mutable, ask whether two instances with the same field values would be considered identical, or if they might need to change independently over time. If they would be considered identical, the type should probably be immutable.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"To recap, two essential properties define immutability in Julia:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"It is not permitted to modify the value of an immutable type.\nFor bits types this means that the bit pattern of a value once set will never change and that value is the identity of a bits type.\nFor composite types, this means that the identity of the values of its fields will never change. When the fields are bits types, that means their bits will never change, for fields whose values are mutable types like arrays, that means the fields will always refer to the same mutable value even though that mutable value's content may itself be modified.\nAn object with an immutable type may be copied freely by the compiler since its immutability makes it impossible to programmatically distinguish between the original object and a copy.\nIn particular, this means that small enough immutable values like integers and floats are typically passed to functions in registers (or stack allocated).\nMutable values, on the other hand are heap-allocated and passed to functions as pointers to heap-allocated values except in cases where the compiler is sure that there's no way to tell that this is not what is happening.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In cases where one or more fields of an otherwise mutable struct is known to be immutable, one can declare these fields as such using const as shown below. This enables some, but not all of the optimizations of immutable structs, and can be used to enforce invariants on the particular fields marked as const.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"compat: Julia 1.8\nconst annotating fields of mutable structs requires at least Julia 1.8.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> mutable struct Baz\n a::Int\n const b::Float64\n end\n\njulia> baz = Baz(1, 1.5);\n\njulia> baz.a = 2\n2\n\njulia> baz.b = 2.0\nERROR: setfield!: const field .b of type Baz cannot be changed\n[...]","category":"page"},{"location":"manual/types/#man-declared-types","page":"Types","title":"Declared Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"The three kinds of types (abstract, primitive, composite) discussed in the previous sections are actually all closely related. They share the same key properties:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"They are explicitly declared.\nThey have names.\nThey have explicitly declared supertypes.\nThey may have parameters.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Because of these shared properties, these types are internally represented as instances of the same concept, DataType, which is the type of any of these types:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof(Real)\nDataType\n\njulia> typeof(Int)\nDataType","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A DataType may be abstract or concrete. If it is concrete, it has a specified size, storage layout, and (optionally) field names. Thus a primitive type is a DataType with nonzero size, but no field names. A composite type is a DataType that has field names or is empty (zero size).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Every concrete value in the system is an instance of some DataType.","category":"page"},{"location":"manual/types/#Type-Unions","page":"Types","title":"Type Unions","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"A type union is a special abstract type which includes as objects all instances of any of its argument types, constructed using the special Union keyword:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> IntOrString = Union{Int,AbstractString}\nUnion{Int64, AbstractString}\n\njulia> 1 :: IntOrString\n1\n\njulia> \"Hello!\" :: IntOrString\n\"Hello!\"\n\njulia> 1.0 :: IntOrString\nERROR: TypeError: in typeassert, expected Union{Int64, AbstractString}, got a value of type Float64","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The compilers for many languages have an internal union construct for reasoning about types; Julia simply exposes it to the programmer. The Julia compiler is able to generate efficient code in the presence of Union types with a small number of types [1], by generating specialized code in separate branches for each possible type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A particularly useful case of a Union type is Union{T, Nothing}, where T can be any type and Nothing is the singleton type whose only instance is the object nothing. This pattern is the Julia equivalent of Nullable, Option or Maybe types in other languages. Declaring a function argument or a field as Union{T, Nothing} allows setting it either to a value of type T, or to nothing to indicate that there is no value. See this FAQ entry for more information.","category":"page"},{"location":"manual/types/#Parametric-Types","page":"Types","title":"Parametric Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"An important and powerful feature of Julia's type system is that it is parametric: types can take parameters, so that type declarations actually introduce a whole family of new types – one for each possible combination of parameter values. There are many languages that support some version of generic programming, wherein data structures and algorithms to manipulate them may be specified without specifying the exact types involved. For example, some form of generic programming exists in ML, Haskell, Ada, Eiffel, C++, Java, C#, F#, and Scala, just to name a few. Some of these languages support true parametric polymorphism (e.g. ML, Haskell, Scala), while others support ad-hoc, template-based styles of generic programming (e.g. C++, Java). With so many different varieties of generic programming and parametric types in various languages, we won't even attempt to compare Julia's parametric types to other languages, but will instead focus on explaining Julia's system in its own right. We will note, however, that because Julia is a dynamically typed language and doesn't need to make all type decisions at compile time, many traditional difficulties encountered in static parametric type systems can be relatively easily handled.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"All declared types (the DataType variety) can be parameterized, with the same syntax in each case. We will discuss them in the following order: first, parametric composite types, then parametric abstract types, and finally parametric primitive types.","category":"page"},{"location":"manual/types/#man-parametric-composite-types","page":"Types","title":"Parametric Composite Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type parameters are introduced immediately after the type name, surrounded by curly braces:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Point{T}\n x::T\n y::T\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This declaration defines a new parametric type, Point{T}, holding two \"coordinates\" of type T. What, one may ask, is T? Well, that's precisely the point of parametric types: it can be any type at all (or a value of any bits type, actually, although here it's clearly used as a type). Point{Float64} is a concrete type equivalent to the type defined by replacing T in the definition of Point with Float64. Thus, this single declaration actually declares an unlimited number of types: Point{Float64}, Point{AbstractString}, Point{Int64}, etc. Each of these is now a usable concrete type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64}\nPoint{Float64}\n\njulia> Point{AbstractString}\nPoint{AbstractString}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The type Point{Float64} is a point whose coordinates are 64-bit floating-point values, while the type Point{AbstractString} is a \"point\" whose \"coordinates\" are string objects (see Strings).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Point itself is also a valid type object, containing all instances Point{Float64}, Point{AbstractString}, etc. as subtypes:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64} <: Point\ntrue\n\njulia> Point{AbstractString} <: Point\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Other types, of course, are not subtypes of it:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Float64 <: Point\nfalse\n\njulia> AbstractString <: Point\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Concrete Point types with different values of T are never subtypes of each other:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64} <: Point{Int64}\nfalse\n\njulia> Point{Float64} <: Point{Real}\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"warning: Warning\nThis last point is very important: even though Float64 <: Real we DO NOT have Point{Float64} <: Point{Real}.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In other words, in the parlance of type theory, Julia's type parameters are invariant, rather than being covariant (or even contravariant). This is for practical reasons: while any instance of Point{Float64} may conceptually be like an instance of Point{Real} as well, the two types have different representations in memory:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"An instance of Point{Float64} can be represented compactly and efficiently as an immediate pair of 64-bit values;\nAn instance of Point{Real} must be able to hold any pair of instances of Real. Since objects that are instances of Real can be of arbitrary size and structure, in practice an instance of Point{Real} must be represented as a pair of pointers to individually allocated Real objects.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The efficiency gained by being able to store Point{Float64} objects with immediate values is magnified enormously in the case of arrays: an Array{Float64} can be stored as a contiguous memory block of 64-bit floating-point values, whereas an Array{Real} must be an array of pointers to individually allocated Real objects – which may well be boxed 64-bit floating-point values, but also might be arbitrarily large, complex objects, which are declared to be implementations of the Real abstract type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since Point{Float64} is not a subtype of Point{Real}, the following method can't be applied to arguments of type Point{Float64}:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function norm(p::Point{Real})\n sqrt(p.x^2 + p.y^2)\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A correct way to define a method that accepts all arguments of type Point{T} where T is a subtype of Real is:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"function norm(p::Point{<:Real})\n sqrt(p.x^2 + p.y^2)\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"(Equivalently, one could define function norm(p::Point{T} where T<:Real) or function norm(p::Point{T}) where T<:Real; see UnionAll Types.)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"More examples will be discussed later in Methods.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"How does one construct a Point object? It is possible to define custom constructors for composite types, which will be discussed in detail in Constructors, but in the absence of any special constructor declarations, there are two default ways of creating new composite objects, one in which the type parameters are explicitly given and the other in which they are implied by the arguments to the object constructor.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since the type Point{Float64} is a concrete type equivalent to Point declared with Float64 in place of T, it can be applied as a constructor accordingly:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> p = Point{Float64}(1.0, 2.0)\nPoint{Float64}(1.0, 2.0)\n\njulia> typeof(p)\nPoint{Float64}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"For the default constructor, exactly one argument must be supplied for each field:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64}(1.0)\nERROR: MethodError: no method matching Point{Float64}(::Float64)\nThe type `Point{Float64}` exists, but no method is defined for this combination of argument types when trying to construct it.\n[...]\n\njulia> Point{Float64}(1.0, 2.0, 3.0)\nERROR: MethodError: no method matching Point{Float64}(::Float64, ::Float64, ::Float64)\nThe type `Point{Float64}` exists, but no method is defined for this combination of argument types when trying to construct it.\n[...]","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Only one default constructor is generated for parametric types, since overriding it is not possible. This constructor accepts any arguments and converts them to the field types.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In many cases, it is redundant to provide the type of Point object one wants to construct, since the types of arguments to the constructor call already implicitly provide type information. For that reason, you can also apply Point itself as a constructor, provided that the implied value of the parameter type T is unambiguous:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> p1 = Point(1.0,2.0)\nPoint{Float64}(1.0, 2.0)\n\njulia> typeof(p1)\nPoint{Float64}\n\njulia> p2 = Point(1,2)\nPoint{Int64}(1, 2)\n\njulia> typeof(p2)\nPoint{Int64}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In the case of Point, the type of T is unambiguously implied if and only if the two arguments to Point have the same type. When this isn't the case, the constructor will fail with a MethodError:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point(1,2.5)\nERROR: MethodError: no method matching Point(::Int64, ::Float64)\nThe type `Point` exists, but no method is defined for this combination of argument types when trying to construct it.\n\nClosest candidates are:\n Point(::T, !Matched::T) where T\n @ Main none:2\n\nStacktrace:\n[...]","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Constructor methods to appropriately handle such mixed cases can be defined, but that will not be discussed until later on in Constructors.","category":"page"},{"location":"manual/types/#Parametric-Abstract-Types","page":"Types","title":"Parametric Abstract Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Parametric abstract type declarations declare a collection of abstract types, in much the same way:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> abstract type Pointy{T} end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"With this declaration, Pointy{T} is a distinct abstract type for each type or integer value of T. As with parametric composite types, each such instance is a subtype of Pointy:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Pointy{Int64} <: Pointy\ntrue\n\njulia> Pointy{1} <: Pointy\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Parametric abstract types are invariant, much as parametric composite types are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Pointy{Float64} <: Pointy{Real}\nfalse\n\njulia> Pointy{Real} <: Pointy{Float64}\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The notation Pointy{<:Real} can be used to express the Julia analogue of a covariant type, while Pointy{>:Int} the analogue of a contravariant type, but technically these represent sets of types (see UnionAll Types).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Pointy{Float64} <: Pointy{<:Real}\ntrue\n\njulia> Pointy{Real} <: Pointy{>:Int}\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Much as plain old abstract types serve to create a useful hierarchy of types over concrete types, parametric abstract types serve the same purpose with respect to parametric composite types. We could, for example, have declared Point{T} to be a subtype of Pointy{T} as follows:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Point{T} <: Pointy{T}\n x::T\n y::T\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Given such a declaration, for each choice of T, we have Point{T} as a subtype of Pointy{T}:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64} <: Pointy{Float64}\ntrue\n\njulia> Point{Real} <: Pointy{Real}\ntrue\n\njulia> Point{AbstractString} <: Pointy{AbstractString}\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This relationship is also invariant:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Point{Float64} <: Pointy{Real}\nfalse\n\njulia> Point{Float64} <: Pointy{<:Real}\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"What purpose do parametric abstract types like Pointy serve? Consider if we create a point-like implementation that only requires a single coordinate because the point is on the diagonal line x = y:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct DiagPoint{T} <: Pointy{T}\n x::T\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Now both Point{Float64} and DiagPoint{Float64} are implementations of the Pointy{Float64} abstraction, and similarly for every other possible choice of type T. This allows programming to a common interface shared by all Pointy objects, implemented for both Point and DiagPoint. This cannot be fully demonstrated, however, until we have introduced methods and dispatch in the next section, Methods.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There are situations where it may not make sense for type parameters to range freely over all possible types. In such situations, one can constrain the range of T like so:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> abstract type Pointy{T<:Real} end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"With such a declaration, it is acceptable to use any type that is a subtype of Real in place of T, but not types that are not subtypes of Real:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Pointy{Float64}\nPointy{Float64}\n\njulia> Pointy{Real}\nPointy{Real}\n\njulia> Pointy{AbstractString}\nERROR: TypeError: in Pointy, in T, expected T<:Real, got Type{AbstractString}\n\njulia> Pointy{1}\nERROR: TypeError: in Pointy, in T, expected T<:Real, got a value of type Int64","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type parameters for parametric composite types can be restricted in the same manner:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"struct Point{T<:Real} <: Pointy{T}\n x::T\n y::T\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"To give a real-world example of how all this parametric type machinery can be useful, here is the actual definition of Julia's Rational immutable type (except that we omit the constructor here for simplicity), representing an exact ratio of integers:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"struct Rational{T<:Integer} <: Real\n num::T\n den::T\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"It only makes sense to take ratios of integer values, so the parameter type T is restricted to being a subtype of Integer, and a ratio of integers represents a value on the real number line, so any Rational is an instance of the Real abstraction.","category":"page"},{"location":"manual/types/#Tuple-Types","page":"Types","title":"Tuple Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Tuples are an abstraction of the arguments of a function – without the function itself. The salient aspects of a function's arguments are their order and their types. Therefore a tuple type is similar to a parameterized immutable type where each parameter is the type of one field. For example, a 2-element tuple type resembles the following immutable type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"struct Tuple2{A,B}\n a::A\n b::B\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"However, there are three key differences:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Tuple types may have any number of parameters.\nTuple types are covariant in their parameters: Tuple{Int} is a subtype of Tuple{Any}. Therefore Tuple{Any} is considered an abstract type, and tuple types are only concrete if their parameters are.\nTuples do not have field names; fields are only accessed by index.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Tuple values are written with parentheses and commas. When a tuple is constructed, an appropriate tuple type is generated on demand:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof((1,\"foo\",2.5))\nTuple{Int64, String, Float64}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Note the implications of covariance:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Tuple{Int,AbstractString} <: Tuple{Real,Any}\ntrue\n\njulia> Tuple{Int,AbstractString} <: Tuple{Real,Real}\nfalse\n\njulia> Tuple{Int,AbstractString} <: Tuple{Real,}\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Intuitively, this corresponds to the type of a function's arguments being a subtype of the function's signature (when the signature matches).","category":"page"},{"location":"manual/types/#Vararg-Tuple-Types","page":"Types","title":"Vararg Tuple Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"The last parameter of a tuple type can be the special value Vararg, which denotes any number of trailing elements:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> mytupletype = Tuple{AbstractString,Vararg{Int}}\nTuple{AbstractString, Vararg{Int64}}\n\njulia> isa((\"1\",), mytupletype)\ntrue\n\njulia> isa((\"1\",1), mytupletype)\ntrue\n\njulia> isa((\"1\",1,2), mytupletype)\ntrue\n\njulia> isa((\"1\",1,2,3.0), mytupletype)\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Moreover Vararg{T} corresponds to zero or more elements of type T. Vararg tuple types are used to represent the arguments accepted by varargs methods (see Varargs Functions).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The special value Vararg{T,N} (when used as the last parameter of a tuple type) corresponds to exactly N elements of type T. NTuple{N,T} is a convenient alias for Tuple{Vararg{T,N}}, i.e. a tuple type containing exactly N elements of type T.","category":"page"},{"location":"manual/types/#Named-Tuple-Types","page":"Types","title":"Named Tuple Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Named tuples are instances of the NamedTuple type, which has two parameters: a tuple of symbols giving the field names, and a tuple type giving the field types. For convenience, NamedTuple types are printed using the @NamedTuple macro which provides a convenient struct-like syntax for declaring these types via key::Type declarations, where an omitted ::Type corresponds to ::Any.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof((a=1,b=\"hello\")) # prints in macro form\n@NamedTuple{a::Int64, b::String}\n\njulia> NamedTuple{(:a, :b), Tuple{Int64, String}} # long form of the type\n@NamedTuple{a::Int64, b::String}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The begin ... end form of the @NamedTuple macro allows the declarations to be split across multiple lines (similar to a struct declaration), but is otherwise equivalent:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> @NamedTuple begin\n a::Int\n b::String\n end\n@NamedTuple{a::Int64, b::String}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A NamedTuple type can be used as a constructor, accepting a single tuple argument. The constructed NamedTuple type can be either a concrete type, with both parameters specified, or a type that specifies only field names:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> @NamedTuple{a::Float32,b::String}((1, \"\"))\n(a = 1.0f0, b = \"\")\n\njulia> NamedTuple{(:a, :b)}((1, \"\"))\n(a = 1, b = \"\")","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"If field types are specified, the arguments are converted. Otherwise the types of the arguments are used directly.","category":"page"},{"location":"manual/types/#Parametric-Primitive-Types","page":"Types","title":"Parametric Primitive Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Primitive types can also be declared parametrically. For example, pointers are represented as primitive types which would be declared in Julia like this:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"# 32-bit system:\nprimitive type Ptr{T} 32 end\n\n# 64-bit system:\nprimitive type Ptr{T} 64 end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The slightly odd feature of these declarations as compared to typical parametric composite types, is that the type parameter T is not used in the definition of the type itself – it is just an abstract tag, essentially defining an entire family of types with identical structure, differentiated only by their type parameter. Thus, Ptr{Float64} and Ptr{Int64} are distinct types, even though they have identical representations. And of course, all specific pointer types are subtypes of the umbrella Ptr type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Ptr{Float64} <: Ptr\ntrue\n\njulia> Ptr{Int64} <: Ptr\ntrue","category":"page"},{"location":"manual/types/#UnionAll-Types","page":"Types","title":"UnionAll Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"We have said that a parametric type like Ptr acts as a supertype of all its instances (Ptr{Int64} etc.). How does this work? Ptr itself cannot be a normal data type, since without knowing the type of the referenced data the type clearly cannot be used for memory operations. The answer is that Ptr (or other parametric types like Array) is a different kind of type called a UnionAll type. Such a type expresses the iterated union of types for all values of some parameter.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"UnionAll types are usually written using the keyword where. For example Ptr could be more accurately written as Ptr{T} where T, meaning all values whose type is Ptr{T} for some value of T. In this context, the parameter T is also often called a \"type variable\" since it is like a variable that ranges over types. Each where introduces a single type variable, so these expressions are nested for types with multiple parameters, for example Array{T,N} where N where T.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The type application syntax A{B,C} requires A to be a UnionAll type, and first substitutes B for the outermost type variable in A. The result is expected to be another UnionAll type, into which C is then substituted. So A{B,C} is equivalent to A{B}{C}. This explains why it is possible to partially instantiate a type, as in Array{Float64}: the first parameter value has been fixed, but the second still ranges over all possible values. Using explicit where syntax, any subset of parameters can be fixed. For example, the type of all 1-dimensional arrays can be written as Array{T,1} where T.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type variables can be restricted with subtype relations. Array{T} where T<:Integer refers to all arrays whose element type is some kind of Integer. The syntax Array{<:Integer} is a convenient shorthand for Array{T} where T<:Integer. Type variables can have both lower and upper bounds. Array{T} where Int<:T<:Number refers to all arrays of Numbers that are able to contain Ints (since T must be at least as big as Int). The syntax where T>:Int also works to specify only the lower bound of a type variable, and Array{>:Int} is equivalent to Array{T} where T>:Int.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since where expressions nest, type variable bounds can refer to outer type variables. For example Tuple{T,Array{S}} where S<:AbstractArray{T} where T<:Real refers to 2-tuples whose first element is some Real, and whose second element is an Array of any kind of array whose element type contains the type of the first tuple element.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The where keyword itself can be nested inside a more complex declaration. For example, consider the two types created by the following declarations:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> const T1 = Array{Array{T, 1} where T, 1}\nVector{Vector} (alias for Array{Array{T, 1} where T, 1})\n\njulia> const T2 = Array{Array{T, 1}, 1} where T\nArray{Vector{T}, 1} where T","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type T1 defines a 1-dimensional array of 1-dimensional arrays; each of the inner arrays consists of objects of the same type, but this type may vary from one inner array to the next. On the other hand, type T2 defines a 1-dimensional array of 1-dimensional arrays all of whose inner arrays must have the same type. Note that T2 is an abstract type, e.g., Array{Array{Int,1},1} <: T2, whereas T1 is a concrete type. As a consequence, T1 can be constructed with a zero-argument constructor a=T1() but T2 cannot.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There is a convenient syntax for naming such types, similar to the short form of function definition syntax:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Vector{T} = Array{T, 1}","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This is equivalent to const Vector = Array{T,1} where T. Writing Vector{Float64} is equivalent to writing Array{Float64,1}, and the umbrella type Vector has as instances all Array objects where the second parameter – the number of array dimensions – is 1, regardless of what the element type is. In languages where parametric types must always be specified in full, this is not especially helpful, but in Julia, this allows one to write just Vector for the abstract type including all one-dimensional dense arrays of any element type.","category":"page"},{"location":"manual/types/#man-singleton-types","page":"Types","title":"Singleton types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Immutable composite types with no fields are called singletons. Formally, if","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"T is an immutable composite type (i.e. defined with struct),\na isa T && b isa T implies a === b,","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"then T is a singleton type.[2] Base.issingletontype can be used to check if a type is a singleton type. Abstract types cannot be singleton types by construction.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"From the definition, it follows that there can be only one instance of such types:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct NoFields\n end\n\njulia> NoFields() === NoFields()\ntrue\n\njulia> Base.issingletontype(NoFields)\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The === function confirms that the constructed instances of NoFields are actually one and the same.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Parametric types can be singleton types when the above condition holds. For example,","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct NoFieldsParam{T}\n end\n\njulia> Base.issingletontype(NoFieldsParam) # Can't be a singleton type ...\nfalse\n\njulia> NoFieldsParam{Int}() isa NoFieldsParam # ... because it has ...\ntrue\n\njulia> NoFieldsParam{Bool}() isa NoFieldsParam # ... multiple instances.\ntrue\n\njulia> Base.issingletontype(NoFieldsParam{Int}) # Parametrized, it is a singleton.\ntrue\n\njulia> NoFieldsParam{Int}() === NoFieldsParam{Int}()\ntrue","category":"page"},{"location":"manual/types/#Types-of-functions","page":"Types","title":"Types of functions","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Each function has its own type, which is a subtype of Function.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> foo41(x) = x + 1\nfoo41 (generic function with 1 method)\n\njulia> typeof(foo41)\ntypeof(foo41) (singleton type of function foo41, subtype of Function)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Note how typeof(foo41) prints as itself. This is merely a convention for printing, as it is a first-class object that can be used like any other value:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> T = typeof(foo41)\ntypeof(foo41) (singleton type of function foo41, subtype of Function)\n\njulia> T <: Function\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Types of functions defined at top-level are singletons. When necessary, you can compare them with ===.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Closures also have their own type, which is usually printed with names that end in #. Names and types for functions defined at different locations are distinct, but not guaranteed to be printed the same way across sessions.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof(x -> x + 1)\nvar\"#9#10\"","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Types of closures are not necessarily singletons.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> addy(y) = x -> x + y\naddy (generic function with 1 method)\n\njulia> typeof(addy(1)) === typeof(addy(2))\ntrue\n\njulia> addy(1) === addy(2)\nfalse\n\njulia> Base.issingletontype(typeof(addy(1)))\nfalse","category":"page"},{"location":"manual/types/#man-typet-type","page":"Types","title":"Type{T} type selectors","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"For each type T, Type{T} is an abstract parametric type whose only instance is the object T. Until we discuss Parametric Methods and conversions, it is difficult to explain the utility of this construct, but in short, it allows one to specialize function behavior on specific types as values. This is useful for writing methods (especially parametric ones) whose behavior depends on a type that is given as an explicit argument rather than implied by the type of one of its arguments.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since the definition is a little difficult to parse, let's look at some examples:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> isa(Float64, Type{Float64})\ntrue\n\njulia> isa(Real, Type{Float64})\nfalse\n\njulia> isa(Real, Type{Real})\ntrue\n\njulia> isa(Float64, Type{Real})\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In other words, isa(A, Type{B}) is true if and only if A and B are the same object and that object is a type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In particular, since parametric types are invariant, we have","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct TypeParamExample{T}\n x::T\n end\n\njulia> TypeParamExample isa Type{TypeParamExample}\ntrue\n\njulia> TypeParamExample{Int} isa Type{TypeParamExample}\nfalse\n\njulia> TypeParamExample{Int} isa Type{TypeParamExample{Int}}\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Without the parameter, Type is simply an abstract type which has all type objects as its instances:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> isa(Type{Float64}, Type)\ntrue\n\njulia> isa(Float64, Type)\ntrue\n\njulia> isa(Real, Type)\ntrue","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Any object that is not a type is not an instance of Type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> isa(1, Type)\nfalse\n\njulia> isa(\"foo\", Type)\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"While Type is part of Julia's type hierarchy like any other abstract parametric type, it is not commonly used outside method signatures except in some special cases. Another important use case for Type is sharpening field types which would otherwise be captured less precisely, e.g. as DataType in the example below where the default constructor could lead to performance problems in code relying on the precise wrapped type (similarly to abstract type parameters).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct WrapType{T}\n value::T\n end\n\njulia> WrapType(Float64) # default constructor, note DataType\nWrapType{DataType}(Float64)\n\njulia> WrapType(::Type{T}) where T = WrapType{Type{T}}(T)\nWrapType\n\njulia> WrapType(Float64) # sharpened constructor, note more precise Type{Float64}\nWrapType{Type{Float64}}(Float64)","category":"page"},{"location":"manual/types/#Type-Aliases","page":"Types","title":"Type Aliases","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Sometimes it is convenient to introduce a new name for an already expressible type. This can be done with a simple assignment statement. For example, UInt is aliased to either UInt32 or UInt64 as is appropriate for the size of pointers on the system:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"# 32-bit system:\njulia> UInt\nUInt32\n\n# 64-bit system:\njulia> UInt\nUInt64","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This is accomplished via the following code in base/boot.jl:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"if Int === Int64\n const UInt = UInt64\nelse\n const UInt = UInt32\nend","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Of course, this depends on what Int is aliased to – but that is predefined to be the correct type – either Int32 or Int64.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"(Note that unlike Int, Float does not exist as a type alias for a specific sized AbstractFloat. Unlike with integer registers, where the size of Int reflects the size of a native pointer on that machine, the floating point register sizes are specified by the IEEE-754 standard.)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Type aliases may be parametrized:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> const Family{T} = Set{T}\nSet\n\njulia> Family{Char} === Set{Char}\ntrue","category":"page"},{"location":"manual/types/#Operations-on-Types","page":"Types","title":"Operations on Types","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Since types in Julia are themselves objects, ordinary functions can operate on them. Some functions that are particularly useful for working with or exploring types have already been introduced, such as the <: operator, which indicates whether its left hand operand is a subtype of its right hand operand.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The isa function tests if an object is of a given type and returns true or false:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> isa(1, Int)\ntrue\n\njulia> isa(1, AbstractFloat)\nfalse","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The typeof function, already used throughout the manual in examples, returns the type of its argument. Since, as noted above, types are objects, they also have types, and we can ask what their types are:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof(Rational{Int})\nDataType\n\njulia> typeof(Union{Real,String})\nUnion","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"What if we repeat the process? What is the type of a type of a type? As it happens, types are all composite values and thus all have a type of DataType:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> typeof(DataType)\nDataType\n\njulia> typeof(Union)\nDataType","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"DataType is its own type.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Another operation that applies to some types is supertype, which reveals a type's supertype. Only declared types (DataType) have unambiguous supertypes:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> supertype(Float64)\nAbstractFloat\n\njulia> supertype(Number)\nAny\n\njulia> supertype(AbstractString)\nAny\n\njulia> supertype(Any)\nAny","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"If you apply supertype to other type objects (or non-type objects), a MethodError is raised:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> supertype(Union{Float64,Int64})\nERROR: MethodError: no method matching supertype(::Type{Union{Float64, Int64}})\nThe function `supertype` exists, but no method is defined for this combination of argument types.\n\nClosest candidates are:\n[...]","category":"page"},{"location":"manual/types/#man-custom-pretty-printing","page":"Types","title":"Custom pretty-printing","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"Often, one wants to customize how instances of a type are displayed. This is accomplished by overloading the show function. For example, suppose we define a type to represent complex numbers in polar form:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Polar{T<:Real} <: Number\n r::T\n Θ::T\n end\n\njulia> Polar(r::Real,Θ::Real) = Polar(promote(r,Θ)...)\nPolar","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Here, we've added a custom constructor function so that it can take arguments of different Real types and promote them to a common type (see Constructors and Conversion and Promotion). (Of course, we would have to define lots of other methods, too, to make it act like a Number, e.g. +, *, one, zero, promotion rules and so on.) By default, instances of this type display rather simply, with information about the type name and the field values, as e.g. Polar{Float64}(3.0,4.0).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"If we want it to display instead as 3.0 * exp(4.0im), we would define the following method to print the object to a given output object io (representing a file, terminal, buffer, etcetera; see Networking and Streams):","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Base.show(io::IO, z::Polar) = print(io, z.r, \" * exp(\", z.Θ, \"im)\")","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"More fine-grained control over display of Polar objects is possible. In particular, sometimes one wants both a verbose multi-line printing format, used for displaying a single object in the REPL and other interactive environments, and also a more compact single-line format used for print or for displaying the object as part of another object (e.g. in an array). Although by default the show(io, z) function is called in both cases, you can define a different multi-line format for displaying an object by overloading a three-argument form of show that takes the text/plain MIME type as its second argument (see Multimedia I/O), for example:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Base.show(io::IO, ::MIME\"text/plain\", z::Polar{T}) where{T} =\n print(io, \"Polar{$T} complex number:\\n \", z)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"(Note that print(..., z) here will call the 2-argument show(io, z) method.) This results in:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Polar(3, 4.0)\nPolar{Float64} complex number:\n 3.0 * exp(4.0im)\n\njulia> [Polar(3, 4.0), Polar(4.0,5.3)]\n2-element Vector{Polar{Float64}}:\n 3.0 * exp(4.0im)\n 4.0 * exp(5.3im)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"where the single-line show(io, z) form is still used for an array of Polar values. Technically, the REPL calls display(z) to display the result of executing a line, which defaults to show(stdout, MIME(\"text/plain\"), z), which in turn defaults to show(stdout, z), but you should not define new display methods unless you are defining a new multimedia display handler (see Multimedia I/O).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Moreover, you can also define show methods for other MIME types in order to enable richer display (HTML, images, etcetera) of objects in environments that support this (e.g. IJulia). For example, we can define formatted HTML display of Polar objects, with superscripts and italics, via:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> Base.show(io::IO, ::MIME\"text/html\", z::Polar{T}) where {T} =\n println(io, \"Polar{$T} complex number: \",\n z.r, \" e\", z.Θ, \" i\")","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"A Polar object will then display automatically using HTML in an environment that supports HTML display, but you can call show manually to get HTML output if you want:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> show(stdout, \"text/html\", Polar(3.0,4.0))\nPolar{Float64} complex number: 3.0 e4.0 i","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"

    An HTML renderer would display this as: Polar{Float64} complex number: 3.0 e4.0 i

    ","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"As a rule of thumb, the single-line show method should print a valid Julia expression for creating the shown object. When this show method contains infix operators, such as the multiplication operator (*) in our single-line show method for Polar above, it may not parse correctly when printed as part of another object. To see this, consider the expression object (see Program representation) which takes the square of a specific instance of our Polar type:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> a = Polar(3, 4.0)\nPolar{Float64} complex number:\n 3.0 * exp(4.0im)\n\njulia> print(:($a^2))\n3.0 * exp(4.0im) ^ 2","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Because the operator ^ has higher precedence than * (see Operator Precedence and Associativity), this output does not faithfully represent the expression a ^ 2 which should be equal to (3.0 * exp(4.0im)) ^ 2. To solve this issue, we must make a custom method for Base.show_unquoted(io::IO, z::Polar, indent::Int, precedence::Int), which is called internally by the expression object when printing:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> function Base.show_unquoted(io::IO, z::Polar, ::Int, precedence::Int)\n if Base.operator_precedence(:*) <= precedence\n print(io, \"(\")\n show(io, z)\n print(io, \")\")\n else\n show(io, z)\n end\n end\n\njulia> :($a^2)\n:((3.0 * exp(4.0im)) ^ 2)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"The method defined above adds parentheses around the call to show when the precedence of the calling operator is higher than or equal to the precedence of multiplication. This check allows expressions which parse correctly without the parentheses (such as :($a + 2) and :($a == 2)) to omit them when printing:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> :($a + 2)\n:(3.0 * exp(4.0im) + 2)\n\njulia> :($a == 2)\n:(3.0 * exp(4.0im) == 2)","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"In some cases, it is useful to adjust the behavior of show methods depending on the context. This can be achieved via the IOContext type, which allows passing contextual properties together with a wrapped IO stream. For example, we can build a shorter representation in our show method when the :compact property is set to true, falling back to the long representation if the property is false or absent:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> function Base.show(io::IO, z::Polar)\n if get(io, :compact, false)::Bool\n print(io, z.r, \"ℯ\", z.Θ, \"im\")\n else\n print(io, z.r, \" * exp(\", z.Θ, \"im)\")\n end\n end","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"This new compact representation will be used when the passed IO stream is an IOContext object with the :compact property set. In particular, this is the case when printing arrays with multiple columns (where horizontal space is limited):","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> show(IOContext(stdout, :compact=>true), Polar(3, 4.0))\n3.0ℯ4.0im\n\njulia> [Polar(3, 4.0) Polar(4.0,5.3)]\n1×2 Matrix{Polar{Float64}}:\n 3.0ℯ4.0im 4.0ℯ5.3im","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"See the IOContext documentation for a list of common properties which can be used to adjust printing.","category":"page"},{"location":"manual/types/#\"Value-types\"","page":"Types","title":"\"Value types\"","text":"","category":"section"},{"location":"manual/types/","page":"Types","title":"Types","text":"In Julia, you can't dispatch on a value such as true or false. However, you can dispatch on parametric types, and Julia allows you to include \"plain bits\" values (Types, Symbols, Integers, floating-point numbers, tuples, etc.) as type parameters. A common example is the dimensionality parameter in Array{T,N}, where T is a type (e.g., Float64) but N is just an Int.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"You can create your own custom types that take values as parameters, and use them to control dispatch of custom types. By way of illustration of this idea, let's introduce the parametric type Val{x}, and its constructor Val(x) = Val{x}(), which serves as a customary way to exploit this technique for cases where you don't need a more elaborate hierarchy.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"Val is defined as:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> struct Val{x}\n end\n\njulia> Val(x) = Val{x}()\nVal","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"There is no more to the implementation of Val than this. Some functions in Julia's standard library accept Val instances as arguments, and you can also use it to write your own functions. For example:","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"julia> firstlast(::Val{true}) = \"First\"\nfirstlast (generic function with 1 method)\n\njulia> firstlast(::Val{false}) = \"Last\"\nfirstlast (generic function with 2 methods)\n\njulia> firstlast(Val(true))\n\"First\"\n\njulia> firstlast(Val(false))\n\"Last\"","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"For consistency across Julia, the call site should always pass a Val instance rather than using a type, i.e., use foo(Val(:bar)) rather than foo(Val{:bar}).","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"It's worth noting that it's extremely easy to mis-use parametric \"value\" types, including Val; in unfavorable cases, you can easily end up making the performance of your code much worse. In particular, you would never want to write actual code as illustrated above. For more information about the proper (and improper) uses of Val, please read the more extensive discussion in the performance tips.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"[1]: \"Small\" is defined by the max_union_splitting configuration, which currently defaults to 4.","category":"page"},{"location":"manual/types/","page":"Types","title":"Types","text":"[2]: A few popular languages have singleton types, including Haskell, Scala and Ruby.","category":"page"},{"location":"stdlib/Unicode/","page":"Unicode","title":"Unicode","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Unicode/docs/src/index.md\"","category":"page"},{"location":"stdlib/Unicode/#Unicode","page":"Unicode","title":"Unicode","text":"","category":"section"},{"location":"stdlib/Unicode/","page":"Unicode","title":"Unicode","text":"The Unicode module provides essential functionality for managing Unicode characters and strings. It includes validation, category determination, normalization, case transformation, and grapheme segmentation, enabling effective Unicode data handling.","category":"page"},{"location":"stdlib/Unicode/","page":"Unicode","title":"Unicode","text":"Unicode\nUnicode.julia_chartransform\nUnicode.isassigned\nUnicode.isequal_normalized\nUnicode.normalize\nUnicode.graphemes","category":"page"},{"location":"stdlib/Unicode/#Unicode","page":"Unicode","title":"Unicode","text":"The Unicode module provides essential functionality for managing Unicode characters and strings. It includes validation, category determination, normalization, case transformation, and grapheme segmentation, enabling effective Unicode data handling.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Unicode/#Unicode.julia_chartransform","page":"Unicode","title":"Unicode.julia_chartransform","text":"Unicode.julia_chartransform(c::Union{Char,Integer})\n\nMap the Unicode character (Char) or codepoint (Integer) c to the corresponding \"equivalent\" character or codepoint, respectively, according to the custom equivalence used within the Julia parser (in addition to NFC normalization).\n\nFor example, 'µ' (U+00B5 micro) is treated as equivalent to 'μ' (U+03BC mu) by Julia's parser, so julia_chartransform performs this transformation while leaving other characters unchanged:\n\njulia> Unicode.julia_chartransform('µ')\n'μ': Unicode U+03BC (category Ll: Letter, lowercase)\n\njulia> Unicode.julia_chartransform('x')\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\njulia_chartransform is mainly useful for passing to the Unicode.normalize function in order to mimic the normalization used by the Julia parser:\n\njulia> s = \"µö\"\n\"µö\"\n\njulia> s2 = Unicode.normalize(s, compose=true, stable=true, chartransform=Unicode.julia_chartransform)\n\"μö\"\n\njulia> collect(s2)\n2-element Vector{Char}:\n 'μ': Unicode U+03BC (category Ll: Letter, lowercase)\n 'ö': Unicode U+00F6 (category Ll: Letter, lowercase)\n\njulia> s2 == string(Meta.parse(s))\ntrue\n\ncompat: Julia 1.8\nThis function was introduced in Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Unicode/#Unicode.isassigned","page":"Unicode","title":"Unicode.isassigned","text":"Unicode.isassigned(c) -> Bool\n\nReturn true if the given char or integer is an assigned Unicode code point.\n\nExamples\n\njulia> Unicode.isassigned(101)\ntrue\n\njulia> Unicode.isassigned('\\x01')\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Unicode/#Unicode.isequal_normalized","page":"Unicode","title":"Unicode.isequal_normalized","text":"isequal_normalized(s1::AbstractString, s2::AbstractString; casefold=false, stripmark=false, chartransform=identity)\n\nReturn whether s1 and s2 are canonically equivalent Unicode strings. If casefold=true, ignores case (performs Unicode case-folding); if stripmark=true, strips diacritical marks and other combining characters.\n\nAs with Unicode.normalize, you can also pass an arbitrary function via the chartransform keyword (mapping Integer codepoints to codepoints) to perform custom normalizations, such as Unicode.julia_chartransform.\n\ncompat: Julia 1.8\nThe isequal_normalized function was added in Julia 1.8.\n\nExamples\n\nFor example, the string \"noël\" can be constructed in two canonically equivalent ways in Unicode, depending on whether \"ë\" is formed from a single codepoint U+00EB or from the ASCII character 'e' followed by the U+0308 combining-diaeresis character.\n\njulia> s1 = \"noël\"\n\"noël\"\n\njulia> s2 = \"noël\"\n\"noël\"\n\njulia> s1 == s2\nfalse\n\njulia> isequal_normalized(s1, s2)\ntrue\n\njulia> isequal_normalized(s1, \"noel\", stripmark=true)\ntrue\n\njulia> isequal_normalized(s1, \"NOËL\", casefold=true)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Unicode/#Unicode.normalize","page":"Unicode","title":"Unicode.normalize","text":"Unicode.normalize(s::AbstractString; keywords...)\nUnicode.normalize(s::AbstractString, normalform::Symbol)\n\nNormalize the string s. By default, canonical composition (compose=true) is performed without ensuring Unicode versioning stability (compat=false), which produces the shortest possible equivalent string but may introduce composition characters not present in earlier Unicode versions.\n\nAlternatively, one of the four \"normal forms\" of the Unicode standard can be specified: normalform can be :NFC, :NFD, :NFKC, or :NFKD. Normal forms C (canonical composition) and D (canonical decomposition) convert different visually identical representations of the same abstract string into a single canonical form, with form C being more compact. Normal forms KC and KD additionally canonicalize \"compatibility equivalents\": they convert characters that are abstractly similar but visually distinct into a single canonical choice (e.g. they expand ligatures into the individual characters), with form KC being more compact.\n\nAlternatively, finer control and additional transformations may be obtained by calling Unicode.normalize(s; keywords...), where any number of the following boolean keywords options (which all default to false except for compose) are specified:\n\ncompose=false: do not perform canonical composition\ndecompose=true: do canonical decomposition instead of canonical composition (compose=true is ignored if present)\ncompat=true: compatibility equivalents are canonicalized\ncasefold=true: perform Unicode case folding, e.g. for case-insensitive string comparison\nnewline2lf=true, newline2ls=true, or newline2ps=true: convert various newline sequences (LF, CRLF, CR, NEL) into a linefeed (LF), line-separation (LS), or paragraph-separation (PS) character, respectively\nstripmark=true: strip diacritical marks (e.g. accents)\nstripignore=true: strip Unicode's \"default ignorable\" characters (e.g. the soft hyphen or the left-to-right marker)\nstripcc=true: strip control characters; horizontal tabs and form feeds are converted to spaces; newlines are also converted to spaces unless a newline-conversion flag was specified\nrejectna=true: throw an error if unassigned code points are found\nstable=true: enforce Unicode versioning stability (never introduce characters missing from earlier Unicode versions)\n\nYou can also use the chartransform keyword (which defaults to identity) to pass an arbitrary function mapping Integer codepoints to codepoints, which is called on each character in s as it is processed, in order to perform arbitrary additional normalizations. For example, by passing chartransform=Unicode.julia_chartransform, you can apply a few Julia-specific character normalizations that are performed by Julia when parsing identifiers (in addition to NFC normalization: compose=true, stable=true).\n\nFor example, NFKC corresponds to the options compose=true, compat=true, stable=true.\n\nExamples\n\njulia> \"é\" == Unicode.normalize(\"é\") #LHS: Unicode U+00e9, RHS: U+0065 & U+0301\ntrue\n\njulia> \"μ\" == Unicode.normalize(\"µ\", compat=true) #LHS: Unicode U+03bc, RHS: Unicode U+00b5\ntrue\n\njulia> Unicode.normalize(\"JuLiA\", casefold=true)\n\"julia\"\n\njulia> Unicode.normalize(\"JúLiA\", stripmark=true)\n\"JuLiA\"\n\ncompat: Julia 1.8\nThe chartransform keyword argument requires Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Unicode/#Unicode.graphemes","page":"Unicode","title":"Unicode.graphemes","text":"graphemes(s::AbstractString) -> GraphemeIterator\n\nReturn an iterator over substrings of s that correspond to the extended graphemes in the string, as defined by Unicode UAX #29. (Roughly, these are what users would perceive as single characters, even though they may contain more than one codepoint; for example a letter combined with an accent mark is a single grapheme.)\n\n\n\n\n\ngraphemes(s::AbstractString, m:n) -> SubString\n\nReturns a SubString of s consisting of the m-th through n-th graphemes of the string s, where the second argument m:n is an integer-valued AbstractUnitRange.\n\nLoosely speaking, this corresponds to the m:n-th user-perceived \"characters\" in the string. For example:\n\njulia> s = graphemes(\"exposé\", 3:6)\n\"posé\"\n\njulia> collect(s)\n5-element Vector{Char}:\n 'p': ASCII/Unicode U+0070 (category Ll: Letter, lowercase)\n 'o': ASCII/Unicode U+006F (category Ll: Letter, lowercase)\n 's': ASCII/Unicode U+0073 (category Ll: Letter, lowercase)\n 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)\n '́': Unicode U+0301 (category Mn: Mark, nonspacing)\n\nThis consists of the 3rd to 7th codepoints (Chars) in \"exposé\", because the grapheme \"é\" is actually two Unicode codepoints (an 'e' followed by an acute-accent combining character U+0301).\n\nBecause finding grapheme boundaries requires iteration over the string contents, the graphemes(s, m:n) function requires time proportional to the length of the string (number of codepoints) before the end of the substring.\n\ncompat: Julia 1.9\nThe m:n argument of graphemes requires Julia 1.9.\n\n\n\n\n\n","category":"function"},{"location":"devdocs/probes/#Instrumenting-Julia-with-DTrace,-and-bpftrace","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"DTrace and bpftrace are tools that enable lightweight instrumentation of processes. You can turn the instrumentation on and off while the process is running, and with instrumentation off the overhead is minimal.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"compat: Julia 1.8\nSupport for probes was added in Julia 1.8","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"note: Note\nThis documentation has been written from a Linux perspective, most of this should hold on Mac OS/Darwin and FreeBSD.","category":"page"},{"location":"devdocs/probes/#Enabling-support","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Enabling support","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"On Linux install the systemtap package that has a version of dtrace and create a Make.user file containing","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"WITH_DTRACE=1","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"to enable USDT probes.","category":"page"},{"location":"devdocs/probes/#Verifying","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Verifying","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"> readelf -n usr/lib/libjulia-internal.so.1\n\nDisplaying notes found in: .note.gnu.build-id\n Owner Data size Description\n GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)\n Build ID: 57161002f35548772a87418d2385c284ceb3ead8\n\nDisplaying notes found in: .note.stapsdt\n Owner Data size Description\n stapsdt 0x00000029 NT_STAPSDT (SystemTap probe descriptors)\n Provider: julia\n Name: gc__begin\n Location: 0x000000000013213e, Base: 0x00000000002bb4da, Semaphore: 0x0000000000346cac\n Arguments:\n stapsdt 0x00000032 NT_STAPSDT (SystemTap probe descriptors)\n Provider: julia\n Name: gc__stop_the_world\n Location: 0x0000000000132144, Base: 0x00000000002bb4da, Semaphore: 0x0000000000346cae\n Arguments:\n stapsdt 0x00000027 NT_STAPSDT (SystemTap probe descriptors)\n Provider: julia\n Name: gc__end\n Location: 0x000000000013214a, Base: 0x00000000002bb4da, Semaphore: 0x0000000000346cb0\n Arguments:\n stapsdt 0x0000002d NT_STAPSDT (SystemTap probe descriptors)\n Provider: julia\n Name: gc__finalizer\n Location: 0x0000000000132150, Base: 0x00000000002bb4da, Semaphore: 0x0000000000346cb2\n Arguments:","category":"page"},{"location":"devdocs/probes/#Adding-probes-in-libjulia","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Adding probes in libjulia","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Probes are declared in dtraces format in the file src/uprobes.d. The generated header file is included in src/julia_internal.h and if you add probes you should provide a noop implementation there.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"The header will contain a semaphore *_ENABLED and the actual call to the probe. If the probe arguments are expensive to compute you should first check if the probe is enabled and then compute the arguments and call the probe.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":" if (JL_PROBE_{PROBE}_ENABLED())\n auto expensive_arg = ...;\n JL_PROBE_{PROBE}(expensive_arg);","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"If your probe has no arguments it is preferred to not include the semaphore check. With USDT probes enabled the cost of a semaphore is a memory load, irrespective of the fact that the probe is enabled or not.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"#define JL_PROBE_GC_BEGIN_ENABLED() __builtin_expect (julia_gc__begin_semaphore, 0)\n__extension__ extern unsigned short julia_gc__begin_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Whereas the probe itself is a noop sled that will be patched to a trampoline to the probe handler.","category":"page"},{"location":"devdocs/probes/#Available-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Available probes","text":"","category":"section"},{"location":"devdocs/probes/#GC-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"GC probes","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"julia:gc__begin: GC begins running on one thread and triggers stop-the-world.\njulia:gc__stop_the_world: All threads have reached a safepoint and GC runs.\njulia:gc__mark__begin: Beginning the mark phase\njulia:gc__mark_end(scanned_bytes, perm_scanned): Mark phase ended\njulia:gc__sweep_begin(full): Starting sweep\njulia:gc__sweep_end: Sweep phase finished\njulia:gc__end: GC is finished, other threads continue work\njulia:gc__finalizer: Initial GC thread has finished running finalizers","category":"page"},{"location":"devdocs/probes/#Task-runtime-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Task runtime probes","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"julia:rt__run__task(task): Switching to task task on current thread.\njulia:rt__pause__task(task): Switching from task task on current thread.\njulia:rt__new__task(parent, child): Task parent created task child on current thread.\njulia:rt__start__task(task): Task task started for the first time with a new stack.\njulia:rt__finish__task(task): Task task finished and will no longer execute.\njulia:rt__start__process__events(task): Task task started processing libuv events.\njulia:rt__finish__process__events(task): Task task finished processing libuv events.","category":"page"},{"location":"devdocs/probes/#Task-queue-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Task queue probes","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"julia:rt__taskq__insert(ptls, task): Thread ptls attempted to insert task into a PARTR multiq.\njulia:rt__taskq__get(ptls, task): Thread ptls popped task from a PARTR multiq.","category":"page"},{"location":"devdocs/probes/#Thread-sleep/wake-probes","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Thread sleep/wake probes","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"julia:rt__sleep__check__wake(ptls, old_state): Thread (PTLS ptls) waking up, previously in state old_state.\njulia:rt__sleep__check__wakeup(ptls): Thread (PTLS ptls) woke itself up.\njulia:rt__sleep__check__sleep(ptls): Thread (PTLS ptls) is attempting to sleep.\njulia:rt__sleep__check__taskq__wake(ptls): Thread (PTLS ptls) fails to sleep due to tasks in PARTR multiq.\njulia:rt__sleep__check__task__wake(ptls): Thread (PTLS ptls) fails to sleep due to tasks in Base workqueue.\njulia:rt__sleep__check__uv__wake(ptls): Thread (PTLS ptls) fails to sleep due to libuv wakeup.","category":"page"},{"location":"devdocs/probes/#Probe-usage-examples","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Probe usage examples","text":"","category":"section"},{"location":"devdocs/probes/#GC-stop-the-world-latency","page":"Instrumenting Julia with DTrace, and bpftrace","title":"GC stop-the-world latency","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"An example bpftrace script is given in contrib/gc_stop_the_world_latency.bt and it creates a histogram of the latency for all threads to reach a safepoint.","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Running this Julia code, with julia -t 2","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"using Base.Threads\n\nfib(x) = x <= 1 ? 1 : fib(x-1) + fib(x-2)\n\nbeaver = @spawn begin\n while true\n fib(30)\n # A manual safepoint is necessary since otherwise this loop\n # may never yield to GC.\n GC.safepoint()\n end\nend\n\nallocator = @spawn begin\n while true\n zeros(1024)\n end\nend\n\nwait(allocator)","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"and in a second terminal","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"> sudo contrib/bpftrace/gc_stop_the_world_latency.bt\nAttaching 4 probes...\nTracing Julia GC Stop-The-World Latency... Hit Ctrl-C to end.\n^C\n\n\n@usecs[1743412]:\n[4, 8) 971 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|\n[8, 16) 837 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |\n[16, 32) 129 |@@@@@@ |\n[32, 64) 10 | |\n[64, 128) 1 | |","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"We can see the latency distribution of the stop-the-world phase in the executed Julia process.","category":"page"},{"location":"devdocs/probes/#Task-spawn-monitor","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Task spawn monitor","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"It's sometimes useful to know when a task is spawning other tasks. This is very easy to see with rt__new__task. The first argument to the probe, parent, is the existing task which is creating a new task. This means that if you know the address of the task you want to monitor, you can easily just look at the tasks that that specific task spawned. Let's see how to do this; first let's start a Julia session and get the PID and REPL's task address:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"> julia\n _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.2 (2021-07-14)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\n1> getpid()\n997825\n\n2> current_task()\nTask (runnable) @0x00007f524d088010","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Now we can start bpftrace and have it monitor rt__new__task for only this parent:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"sudo bpftrace -p 997825 -e 'usdt:usr/lib/libjulia-internal.so:julia:rt__new__task /arg0==0x00007f524d088010/{ printf(\"Task: %x\\n\", arg0); }'","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"(Note that in the above, arg0 is the first argument, parent).","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"And if we spawn a single task:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"@async 1+1","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"we see this task being created:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Task: 4d088010","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"However, if we spawn a bunch of tasks from that newly-spawned task:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"@async for i in 1:10\n @async 1+1\nend","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"we still only see one task from bpftrace:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Task: 4d088010","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"and it's still the same task we were monitoring! Of course, we can remove this filter to see all newly-created tasks just as easily:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"sudo bpftrace -p 997825 -e 'usdt:usr/lib/libjulia-internal.so:julia:rt__new__task { printf(\"Task: %x\\n\", arg0); }'","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Task: 4d088010\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290\nTask: 4dc4e290","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"We can see our root task, and the newly-spawned task as the parent of the ten even newer tasks.","category":"page"},{"location":"devdocs/probes/#Thundering-herd-detection","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Thundering herd detection","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Task runtimes can often suffer from the \"thundering herd\" problem: when some work is added to a quiet task runtime, all threads may be woken up from their slumber, even if there isn't enough work for each thread to process. This can cause extra latency and CPU cycles while all threads awaken (and simultaneously go back to sleep, not finding any work to execute).","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"We can see this problem illustrated with bpftrace quite easily. First, in one terminal we start Julia with multiple threads (6 in this example), and get the PID of that process:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"> julia -t 6\n _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.2 (2021-07-14)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\n1> getpid()\n997825","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"And in another terminal we start bpftrace monitoring our process, specifically probing the rt__sleep__check__wake hook:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"sudo bpftrace -p 997825 -e 'usdt:usr/lib/libjulia-internal.so:julia:rt__sleep__check__wake { printf(\"Thread wake up! %x\\n\", arg0); }'","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Now, we create and execute a single task in Julia:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Threads.@spawn 1+1","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"And in bpftrace we see printed out something like:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Thread wake up! 3f926100\nThread wake up! 3ebd5140\nThread wake up! 3f876130\nThread wake up! 3e2711a0\nThread wake up! 3e312190","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Even though we only spawned a single task (which only one thread could process at a time), we woke up all of our other threads! In the future, a smarter task runtime might only wake up a single thread (or none at all; the spawning thread could execute this task!), and we should see this behavior go away.","category":"page"},{"location":"devdocs/probes/#Task-Monitor-with-BPFnative.jl","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Task Monitor with BPFnative.jl","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"BPFnative.jl is able to attach to USDT probe points just like bpftrace. There is a demo available for monitoring the task runtime, GC, and thread sleep/wake transitions here.","category":"page"},{"location":"devdocs/probes/#Notes-on-using-bpftrace","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Notes on using bpftrace","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"An example probe in the bpftrace format looks like:","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"usdt:usr/lib/libjulia-internal.so:julia:gc__begin\n{\n @start[pid] = nsecs;\n}","category":"page"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"The probe declaration takes the kind usdt, then either the path to the library or the PID, the provider name julia and the probe name gc__begin. Note that I am using a relative path to the libjulia-internal.so, but this might need to be an absolute path on a production system.","category":"page"},{"location":"devdocs/probes/#Useful-references:","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Useful references:","text":"","category":"section"},{"location":"devdocs/probes/","page":"Instrumenting Julia with DTrace, and bpftrace","title":"Instrumenting Julia with DTrace, and bpftrace","text":"Julia Evans blog on Linux tracing systems\nLWN article on USDT and BPF\nGDB support for probes\nBrendan Gregg – Linux Performance","category":"page"},{"location":"base/constants/#lib-constants","page":"Constants","title":"Constants","text":"","category":"section"},{"location":"base/constants/","page":"Constants","title":"Constants","text":"Core.nothing\nBase.PROGRAM_FILE\nBase.ARGS\nBase.C_NULL\nBase.VERSION\nBase.DEPOT_PATH\nBase.LOAD_PATH\nBase.Sys.BINDIR\nBase.Sys.CPU_THREADS\nBase.Sys.WORD_SIZE\nBase.Sys.KERNEL\nBase.Sys.ARCH\nBase.Sys.MACHINE","category":"page"},{"location":"base/constants/#Core.nothing","page":"Constants","title":"Core.nothing","text":"nothing\n\nThe singleton instance of type Nothing, used by convention when there is no value to return (as in a C void function) or when a variable or field holds no value.\n\nSee also: isnothing, something, missing.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.PROGRAM_FILE","page":"Constants","title":"Base.PROGRAM_FILE","text":"PROGRAM_FILE\n\nA string containing the script name passed to Julia from the command line. Note that the script name remains unchanged from within included files. Alternatively see @__FILE__.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.ARGS","page":"Constants","title":"Base.ARGS","text":"ARGS\n\nAn array of the command line arguments passed to Julia, as strings.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.C_NULL","page":"Constants","title":"Base.C_NULL","text":"C_NULL\n\nThe C null pointer constant, sometimes used when calling external code.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.VERSION","page":"Constants","title":"Base.VERSION","text":"VERSION\n\nA VersionNumber object describing which version of Julia is in use. See also Version Number Literals.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.DEPOT_PATH","page":"Constants","title":"Base.DEPOT_PATH","text":"DEPOT_PATH\n\nA stack of \"depot\" locations where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, and configuration files. By default it includes:\n\n~/.julia where ~ is the user home as appropriate on the system;\nan architecture-specific shared system directory, e.g. /usr/local/share/julia;\nan architecture-independent shared system directory, e.g. /usr/share/julia.\n\nSo DEPOT_PATH might be:\n\n[joinpath(homedir(), \".julia\"), \"/usr/local/share/julia\", \"/usr/share/julia\"]\n\nThe first entry is the \"user depot\" and should be writable by and owned by the current user. The user depot is where: registries are cloned, new package versions are installed, named environments are created and updated, package repos are cloned, newly compiled package image files are saved, log files are written, development packages are checked out by default, and global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and managed by system administrators.\n\nDEPOT_PATH is populated based on the JULIA_DEPOT_PATH environment variable if set.\n\nDEPOT_PATH contents\n\nEach entry in DEPOT_PATH is a path to a directory which contains subdirectories used by Julia for various purposes. Here is an overview of some of the subdirectories that may exist in a depot:\n\nartifacts: Contains content that packages use for which Pkg manages the installation of.\nclones: Contains full clones of package repos. Maintained by Pkg.jl and used as a cache.\nconfig: Contains julia-level configuration such as a startup.jl\ncompiled: Contains precompiled *.ji files for packages. Maintained by Julia.\ndev: Default directory for Pkg.develop. Maintained by Pkg.jl and the user.\nenvironments: Default package environments. For instance the global environment for a specific julia version. Maintained by Pkg.jl.\nlogs: Contains logs of Pkg and REPL operations. Maintained by Pkg.jl and Julia.\npackages: Contains packages, some of which were explicitly installed and some which are implicit dependencies. Maintained by Pkg.jl.\nregistries: Contains package registries. By default only General. Maintained by Pkg.jl.\nscratchspaces: Contains content that a package itself installs via the Scratch.jl package. Pkg.gc() will delete content that is known to be unused.\n\nnote: Note\nPackages that want to store content should use the scratchspaces subdirectory via Scratch.jl instead of creating new subdirectories in the depot root.\n\nSee also JULIA_DEPOT_PATH, and Code Loading.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.LOAD_PATH","page":"Constants","title":"Base.LOAD_PATH","text":"LOAD_PATH\n\nAn array of paths for using and import statements to consider as project environments or package directories when loading code. It is populated based on the JULIA_LOAD_PATH environment variable if set; otherwise it defaults to [\"@\", \"@v#.#\", \"@stdlib\"]. Entries starting with @ have special meanings:\n\n@ refers to the \"current active environment\", the initial value of which is initially determined by the JULIA_PROJECT environment variable or the --project command-line option.\n@stdlib expands to the absolute path of the current Julia installation's standard library directory.\n@name refers to a named environment, which are stored in depots (see JULIA_DEPOT_PATH) under the environments subdirectory. The user's named environments are stored in ~/.julia/environments so @name would refer to the environment in ~/.julia/environments/name if it exists and contains a Project.toml file. If name contains # characters, then they are replaced with the major, minor and patch components of the Julia version number. For example, if you are running Julia 1.2 then @v#.# expands to @v1.2 and will look for an environment by that name, typically at ~/.julia/environments/v1.2.\n\nThe fully expanded value of LOAD_PATH that is searched for projects and packages can be seen by calling the Base.load_path() function.\n\nSee also JULIA_LOAD_PATH, JULIA_PROJECT, JULIA_DEPOT_PATH, and Code Loading.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.BINDIR","page":"Constants","title":"Base.Sys.BINDIR","text":"Sys.BINDIR::String\n\nA string containing the full path to the directory containing the julia executable.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.CPU_THREADS","page":"Constants","title":"Base.Sys.CPU_THREADS","text":"Sys.CPU_THREADS::Int\n\nThe number of logical CPU cores available in the system, i.e. the number of threads that the CPU can run concurrently. Note that this is not necessarily the number of CPU cores, for example, in the presence of hyper-threading.\n\nSee Hwloc.jl or CpuId.jl for extended information, including number of physical cores.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.WORD_SIZE","page":"Constants","title":"Base.Sys.WORD_SIZE","text":"Sys.WORD_SIZE::Int\n\nStandard word size on the current machine, in bits.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.KERNEL","page":"Constants","title":"Base.Sys.KERNEL","text":"Sys.KERNEL::Symbol\n\nA symbol representing the name of the operating system, as returned by uname of the build configuration.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.ARCH","page":"Constants","title":"Base.Sys.ARCH","text":"Sys.ARCH::Symbol\n\nA symbol representing the architecture of the build configuration.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/#Base.Sys.MACHINE","page":"Constants","title":"Base.Sys.MACHINE","text":"Sys.MACHINE::String\n\nA string containing the build triple.\n\n\n\n\n\n","category":"constant"},{"location":"base/constants/","page":"Constants","title":"Constants","text":"See also:","category":"page"},{"location":"base/constants/","page":"Constants","title":"Constants","text":"stdin\nstdout\nstderr\nENV\nENDIAN_BOM","category":"page"},{"location":"tutorials/profile/#Profiling","page":"Profiling","title":"Profiling","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The Profile module provides tools to help developers improve the performance of their code. When used, it takes measurements on running code, and produces output that helps you understand how much time is spent on individual line(s). The most common usage is to identify \"bottlenecks\" as targets for optimization.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Profile implements what is known as a \"sampling\" or statistical profiler. It works by periodically taking a backtrace during the execution of any task. Each backtrace captures the currently-running function and line number, plus the complete chain of function calls that led to this line, and hence is a \"snapshot\" of the current state of execution.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"If much of your run time is spent executing a particular line of code, this line will show up frequently in the set of all backtraces. In other words, the \"cost\" of a given line–or really, the cost of the sequence of function calls up to and including this line–is proportional to how often it appears in the set of all backtraces.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"A sampling profiler does not provide complete line-by-line coverage, because the backtraces occur at intervals (by default, 1 ms on Unix systems and 10 ms on Windows, although the actual scheduling is subject to operating system load). Moreover, as discussed further below, because samples are collected at a sparse subset of all execution points, the data collected by a sampling profiler is subject to statistical noise.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Despite these limitations, sampling profilers have substantial strengths:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"You do not have to make any modifications to your code to take timing measurements.\nIt can profile into Julia's core code and even (optionally) into C and Fortran libraries.\nBy running \"infrequently\" there is very little performance overhead; while profiling, your code can run at nearly native speed.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"For these reasons, it's recommended that you try using the built-in sampling profiler before considering any alternatives.","category":"page"},{"location":"tutorials/profile/#Basic-usage","page":"Profiling","title":"Basic usage","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Let's work with a simple test case:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> function myfunc()\n A = rand(200, 200, 400)\n maximum(A)\n end","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"It's a good idea to first run the code you intend to profile at least once (unless you want to profile Julia's JIT-compiler):","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> myfunc() # run once to force compilation","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Now we're ready to profile this function:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> using Profile\n\njulia> @profile myfunc()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"To see the profiling results, there are several graphical browsers. One \"family\" of visualizers is based on FlameGraphs.jl, with each family member providing a different user interface:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"VS Code is a full IDE with built-in support for profile visualization\nProfileView.jl is a stand-alone visualizer based on GTK\nProfileVega.jl uses VegaLight and integrates well with Jupyter notebooks\nStatProfilerHTML.jl produces HTML and presents some additional summaries, and also integrates well with Jupyter notebooks\nProfileSVG.jl renders SVG\nPProf.jl serves a local website for inspecting graphs, flamegraphs and more\nProfileCanvas.jl is a HTML canvas based profile viewer UI, used by the Julia VS Code extension, but can also generate interactive HTML files.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"An entirely independent approach to profile visualization is PProf.jl, which uses the external pprof tool.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Here, though, we'll use the text-based display that comes with the standard library:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> Profile.print()\n80 ./event.jl:73; (::Base.REPL.##1#2{Base.REPL.REPLBackend})()\n 80 ./REPL.jl:97; macro expansion\n 80 ./REPL.jl:66; eval_user_input(::Any, ::Base.REPL.REPLBackend)\n 80 ./boot.jl:235; eval(::Module, ::Any)\n 80 ./:?; anonymous\n 80 ./profile.jl:23; macro expansion\n 52 ./REPL[1]:2; myfunc()\n 38 ./random.jl:431; rand!(::MersenneTwister, ::Array{Float64,3}, ::Int64, ::Type{B...\n 38 ./dSFMT.jl:84; dsfmt_fill_array_close_open!(::Base.dSFMT.DSFMT_state, ::Ptr{F...\n 14 ./random.jl:278; rand\n 14 ./random.jl:277; rand\n 14 ./random.jl:366; rand\n 14 ./random.jl:369; rand\n 28 ./REPL[1]:3; myfunc()\n 28 ./reduce.jl:270; _mapreduce(::Base.#identity, ::Base.#scalarmax, ::IndexLinear,...\n 3 ./reduce.jl:426; mapreduce_impl(::Base.#identity, ::Base.#scalarmax, ::Array{F...\n 25 ./reduce.jl:428; mapreduce_impl(::Base.#identity, ::Base.#scalarmax, ::Array{F...","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Each line of this display represents a particular spot (line number) in the code. Indentation is used to indicate the nested sequence of function calls, with more-indented lines being deeper in the sequence of calls. In each line, the first \"field\" is the number of backtraces (samples) taken at this line or in any functions executed by this line. The second field is the file name and line number and the third field is the function name. Note that the specific line numbers may change as Julia's code changes; if you want to follow along, it's best to run this example yourself.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"In this example, we can see that the top level function called is in the file event.jl. This is the function that runs the REPL when you launch Julia. If you examine line 97 of REPL.jl, you'll see this is where the function eval_user_input() is called. This is the function that evaluates what you type at the REPL, and since we're working interactively these functions were invoked when we entered @profile myfunc(). The next line reflects actions taken in the @profile macro.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The first line shows that 80 backtraces were taken at line 73 of event.jl, but it's not that this line was \"expensive\" on its own: the third line reveals that all 80 of these backtraces were actually triggered inside its call to eval_user_input, and so on. To find out which operations are actually taking the time, we need to look deeper in the call chain.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The first \"important\" line in this output is this one:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"52 ./REPL[1]:2; myfunc()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"REPL refers to the fact that we defined myfunc in the REPL, rather than putting it in a file; if we had used a file, this would show the file name. The [1] shows that the function myfunc was the first expression evaluated in this REPL session. Line 2 of myfunc() contains the call to rand, and there were 52 (out of 80) backtraces that occurred at this line. Below that, you can see a call to dsfmt_fill_array_close_open! inside dSFMT.jl.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"A little further down, you see:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"28 ./REPL[1]:3; myfunc()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Line 3 of myfunc contains the call to maximum, and there were 28 (out of 80) backtraces taken here. Below that, you can see the specific places in base/reduce.jl that carry out the time-consuming operations in the maximum function for this type of input data.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Overall, we can tentatively conclude that generating the random numbers is approximately twice as expensive as finding the maximum element. We could increase our confidence in this result by collecting more samples:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> @profile (for i = 1:100; myfunc(); end)\n\njulia> Profile.print()\n[....]\n 3821 ./REPL[1]:2; myfunc()\n 3511 ./random.jl:431; rand!(::MersenneTwister, ::Array{Float64,3}, ::Int64, ::Type...\n 3511 ./dSFMT.jl:84; dsfmt_fill_array_close_open!(::Base.dSFMT.DSFMT_state, ::Ptr...\n 310 ./random.jl:278; rand\n [....]\n 2893 ./REPL[1]:3; myfunc()\n 2893 ./reduce.jl:270; _mapreduce(::Base.#identity, ::Base.#scalarmax, ::IndexLinea...\n [....]","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"In general, if you have N samples collected at a line, you can expect an uncertainty on the order of sqrt(N) (barring other sources of noise, like how busy the computer is with other tasks). The major exception to this rule is garbage collection, which runs infrequently but tends to be quite expensive. (Since Julia's garbage collector is written in C, such events can be detected using the C=true output mode described below, or by using ProfileView.jl.)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"This illustrates the default \"tree\" dump; an alternative is the \"flat\" dump, which accumulates counts independent of their nesting:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> Profile.print(format=:flat)\n Count File Line Function\n 6714 ./ -1 anonymous\n 6714 ./REPL.jl 66 eval_user_input(::Any, ::Base.REPL.REPLBackend)\n 6714 ./REPL.jl 97 macro expansion\n 3821 ./REPL[1] 2 myfunc()\n 2893 ./REPL[1] 3 myfunc()\n 6714 ./REPL[7] 1 macro expansion\n 6714 ./boot.jl 235 eval(::Module, ::Any)\n 3511 ./dSFMT.jl 84 dsfmt_fill_array_close_open!(::Base.dSFMT.DSFMT_s...\n 6714 ./event.jl 73 (::Base.REPL.##1#2{Base.REPL.REPLBackend})()\n 6714 ./profile.jl 23 macro expansion\n 3511 ./random.jl 431 rand!(::MersenneTwister, ::Array{Float64,3}, ::In...\n 310 ./random.jl 277 rand\n 310 ./random.jl 278 rand\n 310 ./random.jl 366 rand\n 310 ./random.jl 369 rand\n 2893 ./reduce.jl 270 _mapreduce(::Base.#identity, ::Base.#scalarmax, :...\n 5 ./reduce.jl 420 mapreduce_impl(::Base.#identity, ::Base.#scalarma...\n 253 ./reduce.jl 426 mapreduce_impl(::Base.#identity, ::Base.#scalarma...\n 2592 ./reduce.jl 428 mapreduce_impl(::Base.#identity, ::Base.#scalarma...\n 43 ./reduce.jl 429 mapreduce_impl(::Base.#identity, ::Base.#scalarma...","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"If your code has recursion, one potentially-confusing point is that a line in a \"child\" function can accumulate more counts than there are total backtraces. Consider the following function definitions:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"dumbsum(n::Integer) = n == 1 ? 1 : 1 + dumbsum(n-1)\ndumbsum3() = dumbsum(3)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"If you were to profile dumbsum3, and a backtrace was taken while it was executing dumbsum(1), the backtrace would look like this:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"dumbsum3\n dumbsum(3)\n dumbsum(2)\n dumbsum(1)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Consequently, this child function gets 3 counts, even though the parent only gets one. The \"tree\" representation makes this much clearer, and for this reason (among others) is probably the most useful way to view the results.","category":"page"},{"location":"tutorials/profile/#Accumulation-and-clearing","page":"Profiling","title":"Accumulation and clearing","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Results from @profile accumulate in a buffer; if you run multiple pieces of code under @profile, then Profile.print() will show you the combined results. This can be very useful, but sometimes you want to start fresh; you can do so with Profile.clear().","category":"page"},{"location":"tutorials/profile/#Options-for-controlling-the-display-of-profile-results","page":"Profiling","title":"Options for controlling the display of profile results","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Profile.print has more options than we've described so far. Let's see the full declaration:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"function print(io::IO = stdout, data = fetch(); kwargs...)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Let's first discuss the two positional arguments, and later the keyword arguments:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"io – Allows you to save the results to a buffer, e.g. a file, but the default is to print to stdout (the console).\ndata – Contains the data you want to analyze; by default that is obtained from Profile.fetch(), which pulls out the backtraces from a pre-allocated buffer. For example, if you want to profile the profiler, you could say:\ndata = copy(Profile.fetch())\nProfile.clear()\n@profile Profile.print(stdout, data) # Prints the previous results\nProfile.print() # Prints results from Profile.print()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The keyword arguments can be any combination of:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"format – Introduced above, determines whether backtraces are printed with (default, :tree) or without (:flat) indentation indicating tree structure.\nC – If true, backtraces from C and Fortran code are shown (normally they are excluded). Try running the introductory example with Profile.print(C = true). This can be extremely helpful in deciding whether it's Julia code or C code that is causing a bottleneck; setting C = true also improves the interpretability of the nesting, at the cost of longer profile dumps.\ncombine – Some lines of code contain multiple operations; for example, s += A[i] contains both an array reference (A[i]) and a sum operation. These correspond to different lines in the generated machine code, and hence there may be two or more different addresses captured during backtraces on this line. combine = true lumps them together, and is probably what you typically want, but you can generate an output separately for each unique instruction pointer with combine = false.\nmaxdepth – Limits frames at a depth higher than maxdepth in the :tree format.\nsortedby – Controls the order in :flat format. :filefuncline (default) sorts by the source line, whereas :count sorts in order of number of collected samples.\nnoisefloor – Limits frames that are below the heuristic noise floor of the sample (only applies to format :tree). A suggested value to try for this is 2.0 (the default is 0). This parameter hides samples for which n <= noisefloor * √N, where n is the number of samples on this line, and N is the number of samples for the callee.\nmincount – Limits frames with less than mincount occurrences.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"File/function names are sometimes truncated (with ...), and indentation is truncated with a +n at the beginning, where n is the number of extra spaces that would have been inserted, had there been room. If you want a complete profile of deeply-nested code, often a good idea is to save to a file using a wide displaysize in an IOContext:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"open(\"/tmp/prof.txt\", \"w\") do s\n Profile.print(IOContext(s, :displaysize => (24, 500)))\nend","category":"page"},{"location":"tutorials/profile/#Configuration","page":"Profiling","title":"Configuration","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"@profile just accumulates backtraces, and the analysis happens when you call Profile.print(). For a long-running computation, it's entirely possible that the pre-allocated buffer for storing backtraces will be filled. If that happens, the backtraces stop but your computation continues. As a consequence, you may miss some important profiling data (you will get a warning when that happens).","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"You can obtain and configure the relevant parameters this way:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Profile.init() # returns the current settings\nProfile.init(n = 10^7, delay = 0.01)","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"n is the total number of instruction pointers you can store, with a default value of 10^6. If your typical backtrace is 20 instruction pointers, then you can collect 50000 backtraces, which suggests a statistical uncertainty of less than 1%. This may be good enough for most applications.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Consequently, you are more likely to need to modify delay, expressed in seconds, which sets the amount of time that Julia gets between snapshots to perform the requested computations. A very long-running job might not need frequent backtraces. The default setting is delay = 0.001. Of course, you can decrease the delay as well as increase it; however, the overhead of profiling grows once the delay becomes similar to the amount of time needed to take a backtrace (~30 microseconds on the author's laptop).","category":"page"},{"location":"tutorials/profile/#Memory-allocation-analysis","page":"Profiling","title":"Memory allocation analysis","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"One of the most common techniques to improve performance is to reduce memory allocation. Julia provides several tools to measure this:","category":"page"},{"location":"tutorials/profile/#@time","page":"Profiling","title":"@time","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The total amount of allocation can be measured with @time, @allocated and @allocations, and specific lines triggering allocation can often be inferred from profiling via the cost of garbage collection that these lines incur. However, sometimes it is more efficient to directly measure the amount of memory allocated by each line of code.","category":"page"},{"location":"tutorials/profile/#GC-Logging","page":"Profiling","title":"GC Logging","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"While @time logs high-level stats about memory usage and garbage collection over the course of evaluating an expression, it can be useful to log each garbage collection event, to get an intuitive sense of how often the garbage collector is running, how long it's running each time, and how much garbage it collects each time. This can be enabled with GC.enable_logging(true), which causes Julia to log to stderr every time a garbage collection happens.","category":"page"},{"location":"tutorials/profile/#allocation-profiler","page":"Profiling","title":"Allocation Profiler","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"compat: Julia 1.8\nThis functionality requires at least Julia 1.8.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The allocation profiler records the stack trace, type, and size of each allocation while it is running. It can be invoked with Profile.Allocs.@profile.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"This information about the allocations is returned as an array of Alloc objects, wrapped in an AllocResults object. The best way to visualize these is currently with the PProf.jl and ProfileCanvas.jl packages, which can visualize the call stacks which are making the most allocations.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"The allocation profiler does have significant overhead, so a sample_rate argument can be passed to speed it up by making it skip some allocations. Passing sample_rate=1.0 will make it record everything (which is slow); sample_rate=0.1 will record only 10% of the allocations (faster), etc.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"compat: Julia 1.11\nOlder versions of Julia could not capture types in all cases. In older versions of Julia, if you see an allocation of type Profile.Allocs.UnknownType, it means that the profiler doesn't know what type of object was allocated. This mainly happened when the allocation was coming from generated code produced by the compiler. See issue #43688 for more info.Since Julia 1.11, all allocations should have a type reported.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"For more details on how to use this tool, please see the following talk from JuliaCon 2022: https://www.youtube.com/watch?v=BFvpwC8hEWQ","category":"page"},{"location":"tutorials/profile/#Allocation-Profiler-Example","page":"Profiling","title":"Allocation Profiler Example","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"In this simple example, we use PProf to visualize the alloc profile. You could use another visualization tool instead. We collect the profile (specifying a sample rate), then we visualize it.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"using Profile, PProf\nProfile.Allocs.clear()\nProfile.Allocs.@profile sample_rate=0.0001 my_function()\nPProf.Allocs.pprof()","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Here is a more in-depth example, showing how we can tune the sample rate. A good number of samples to aim for is around 1 - 10 thousand. Too many, and the profile visualizer can get overwhelmed, and profiling will be slow. Too few, and you don't have a representative sample.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"julia> import Profile\n\njulia> @time my_function() # Estimate allocations from a (second-run) of the function\n 0.110018 seconds (1.50 M allocations: 58.725 MiB, 17.17% gc time)\n500000\n\njulia> Profile.Allocs.clear()\n\njulia> Profile.Allocs.@profile sample_rate=0.001 begin # 1.5 M * 0.001 = ~1.5K allocs.\n my_function()\n end\n500000\n\njulia> prof = Profile.Allocs.fetch(); # If you want, you can also manually inspect the results.\n\njulia> length(prof.allocs) # Confirm we have expected number of allocations.\n1515\n\njulia> using PProf # Now, visualize with an external tool, like PProf or ProfileCanvas.\n\njulia> PProf.Allocs.pprof(prof; from_c=false) # You can optionally pass in a previously fetched profile result.\nAnalyzing 1515 allocation samples... 100%|████████████████████████████████| Time: 0:00:00\nMain binary filename not available.\nServing web UI on http://localhost:62261\n\"alloc-profile.pb.gz\"","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Then you can view the profile by navigating to http://localhost:62261, and the profile is saved to disk. See PProf package for more options.","category":"page"},{"location":"tutorials/profile/#Allocation-Profiling-Tips","page":"Profiling","title":"Allocation Profiling Tips","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"As stated above, aim for around 1-10 thousand samples in your profile.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Note that we are uniformly sampling in the space of all allocations, and are not weighting our samples by the size of the allocation. So a given allocation profile may not give a representative profile of where most bytes are allocated in your program, unless you had set sample_rate=1.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Allocations can come from users directly constructing objects, but can also come from inside the runtime or be inserted into compiled code to handle type instability. Looking at the \"source code\" view can be helpful to isolate them, and then other external tools such as Cthulhu.jl can be useful for identifying the cause of the allocation.","category":"page"},{"location":"tutorials/profile/#Allocation-Profile-Visualization-Tools","page":"Profiling","title":"Allocation Profile Visualization Tools","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"There are several profiling visualization tools now that can all display Allocation Profiles. Here is a small list of some of the main ones we know about:","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"PProf.jl\nProfileCanvas.jl\nVSCode's built-in profile visualizer (@profview_allocs) [docs needed]\nViewing the results directly in the REPL\nYou can inspect the results in the REPL via Profile.Allocs.fetch(), to view the stacktrace and type of each allocation.","category":"page"},{"location":"tutorials/profile/#Line-by-Line-Allocation-Tracking","page":"Profiling","title":"Line-by-Line Allocation Tracking","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"An alternative way to measure allocations is to start Julia with the --track-allocation= command-line option, for which you can choose none (the default, do not measure allocation), user (measure memory allocation everywhere except Julia's core code), or all (measure memory allocation at each line of Julia code). Allocation gets measured for each line of compiled code. When you quit Julia, the cumulative results are written to text files with .mem appended after the file name, residing in the same directory as the source file. Each line lists the total number of bytes allocated. The Coverage package contains some elementary analysis tools, for example to sort the lines in order of number of bytes allocated.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"In interpreting the results, there are a few important details. Under the user setting, the first line of any function directly called from the REPL will exhibit allocation due to events that happen in the REPL code itself. More significantly, JIT-compilation also adds to allocation counts, because much of Julia's compiler is written in Julia (and compilation usually requires memory allocation). The recommended procedure is to force compilation by executing all the commands you want to analyze, then call Profile.clear_malloc_data() to reset all allocation counters. Finally, execute the desired commands and quit Julia to trigger the generation of the .mem files.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"note: Note\n--track-allocation changes code generation to log the allocations, and so the allocations may be different than what happens without the option. We recommend using the allocation profiler instead.","category":"page"},{"location":"tutorials/profile/#External-Profiling","page":"Profiling","title":"External Profiling","text":"","category":"section"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Currently Julia supports Intel VTune, OProfile and perf as external profiling tools.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Depending on the tool you choose, compile with USE_INTEL_JITEVENTS, USE_OPROFILE_JITEVENTS and USE_PERF_JITEVENTS set to 1 in Make.user. Multiple flags are supported.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Before running Julia set the environment variable ENABLE_JITPROFILING to 1.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Now you have a multitude of ways to employ those tools! For example with OProfile you can try a simple recording :","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":">ENABLE_JITPROFILING=1 sudo operf -Vdebug ./julia test/fastmath.jl\n>opreport -l `which ./julia`","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Or similarly with perf :","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"$ ENABLE_JITPROFILING=1 perf record -o /tmp/perf.data --call-graph dwarf -k 1 ./julia /test/fastmath.jl\n$ perf inject --jit --input /tmp/perf.data --output /tmp/perf-jit.data\n$ perf report --call-graph -G -i /tmp/perf-jit.data","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"There are many more interesting things that you can measure about your program, to get a comprehensive list please read the Linux perf examples page.","category":"page"},{"location":"tutorials/profile/","page":"Profiling","title":"Profiling","text":"Remember that perf saves for each execution a perf.data file that, even for small programs, can get quite large. Also the perf LLVM module saves temporarily debug objects in ~/.debug/jit, remember to clean that folder frequently.","category":"page"},{"location":"devdocs/cartesian/#Base.Cartesian","page":"Base.Cartesian","title":"Base.Cartesian","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"The (non-exported) Cartesian module provides macros that facilitate writing multidimensional algorithms. Most often you can write such algorithms with straightforward techniques; however, there are a few cases where Base.Cartesian is still useful or necessary.","category":"page"},{"location":"devdocs/cartesian/#Principles-of-usage","page":"Base.Cartesian","title":"Principles of usage","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"A simple example of usage is:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@nloops 3 i A begin\n s += @nref 3 A i\nend","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"which generates the following code:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"for i_3 = axes(A, 3)\n for i_2 = axes(A, 2)\n for i_1 = axes(A, 1)\n s += A[i_1, i_2, i_3]\n end\n end\nend","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"In general, Cartesian allows you to write generic code that contains repetitive elements, like the nested loops in this example. Other applications include repeated expressions (e.g., loop unwinding) or creating function calls with variable numbers of arguments without using the \"splat\" construct (i...).","category":"page"},{"location":"devdocs/cartesian/#Basic-syntax","page":"Base.Cartesian","title":"Basic syntax","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"The (basic) syntax of @nloops is as follows:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"The first argument must be an integer (not a variable) specifying the number of loops.\nThe second argument is the symbol-prefix used for the iterator variable. Here we used i, and variables i_1, i_2, i_3 were generated.\nThe third argument specifies the range for each iterator variable. If you use a variable (symbol) here, it's taken as axes(A, dim). More flexibly, you can use the anonymous-function expression syntax described below.\nThe last argument is the body of the loop. Here, that's what appears between the begin...end.","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"There are some additional features of @nloops described in the reference section.","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@nref follows a similar pattern, generating A[i_1,i_2,i_3] from @nref 3 A i. The general practice is to read from left to right, which is why @nloops is @nloops 3 i A expr (as in for i_2 = axes(A, 2), where i_2 is to the left and the range is to the right) whereas @nref is @nref 3 A i (as in A[i_1,i_2,i_3], where the array comes first).","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"If you're developing code with Cartesian, you may find that debugging is easier when you examine the generated code, using @macroexpand:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"DocTestSetup = quote\n import Base.Cartesian: @nref\nend","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"julia> @macroexpand @nref 2 A i\n:(A[i_1, i_2])","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"DocTestSetup = nothing","category":"page"},{"location":"devdocs/cartesian/#Supplying-the-number-of-expressions","page":"Base.Cartesian","title":"Supplying the number of expressions","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"The first argument to both of these macros is the number of expressions, which must be an integer. When you're writing a function that you intend to work in multiple dimensions, this may not be something you want to hard-code. The recommended approach is to use a @generated function. Here's an example:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@generated function mysum(A::Array{T,N}) where {T,N}\n quote\n s = zero(T)\n @nloops $N i A begin\n s += @nref $N A i\n end\n s\n end\nend","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"Naturally, you can also prepare expressions or perform calculations before the quote block.","category":"page"},{"location":"devdocs/cartesian/#Anonymous-function-expressions-as-macro-arguments","page":"Base.Cartesian","title":"Anonymous-function expressions as macro arguments","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"Perhaps the single most powerful feature in Cartesian is the ability to supply anonymous-function expressions that get evaluated at parsing time. Let's consider a simple example:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@nexprs 2 j->(i_j = 1)","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"@nexprs generates n expressions that follow a pattern. This code would generate the following statements:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"i_1 = 1\ni_2 = 1","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"In each generated statement, an \"isolated\" j (the variable of the anonymous function) gets replaced by values in the range 1:2. Generally speaking, Cartesian employs a LaTeX-like syntax. This allows you to do math on the index j. Here's an example computing the strides of an array:","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"s_1 = 1\n@nexprs 3 j->(s_{j+1} = s_j * size(A, j))","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"would generate expressions","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"s_1 = 1\ns_2 = s_1 * size(A, 1)\ns_3 = s_2 * size(A, 2)\ns_4 = s_3 * size(A, 3)","category":"page"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"Anonymous-function expressions have many uses in practice.","category":"page"},{"location":"devdocs/cartesian/#dev-cartesian-reference","page":"Base.Cartesian","title":"Macro reference","text":"","category":"section"},{"location":"devdocs/cartesian/","page":"Base.Cartesian","title":"Base.Cartesian","text":"Base.Cartesian.@nloops\nBase.Cartesian.@nref\nBase.Cartesian.@nextract\nBase.Cartesian.@nexprs\nBase.Cartesian.@ncall\nBase.Cartesian.@ncallkw\nBase.Cartesian.@ntuple\nBase.Cartesian.@nall\nBase.Cartesian.@nany\nBase.Cartesian.@nif","category":"page"},{"location":"devdocs/cartesian/#Base.Cartesian.@nloops","page":"Base.Cartesian","title":"Base.Cartesian.@nloops","text":"@nloops N itersym rangeexpr bodyexpr\n@nloops N itersym rangeexpr preexpr bodyexpr\n@nloops N itersym rangeexpr preexpr postexpr bodyexpr\n\nGenerate N nested loops, using itersym as the prefix for the iteration variables. rangeexpr may be an anonymous-function expression, or a simple symbol var in which case the range is axes(var, d) for dimension d.\n\nOptionally, you can provide \"pre\" and \"post\" expressions. These get executed first and last, respectively, in the body of each loop. For example:\n\n@nloops 2 i A d -> j_d = min(i_d, 5) begin\n s += @nref 2 A j\nend\n\nwould generate:\n\nfor i_2 = axes(A, 2)\n j_2 = min(i_2, 5)\n for i_1 = axes(A, 1)\n j_1 = min(i_1, 5)\n s += A[j_1, j_2]\n end\nend\n\nIf you want just a post-expression, supply nothing for the pre-expression. Using parentheses and semicolons, you can supply multi-statement expressions.\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nref","page":"Base.Cartesian","title":"Base.Cartesian.@nref","text":"@nref N A indexexpr\n\nGenerate expressions like A[i_1, i_2, ...]. indexexpr can either be an iteration-symbol prefix, or an anonymous-function expression.\n\nExamples\n\njulia> @macroexpand Base.Cartesian.@nref 3 A i\n:(A[i_1, i_2, i_3])\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nextract","page":"Base.Cartesian","title":"Base.Cartesian.@nextract","text":"@nextract N esym isym\n\nGenerate N variables esym_1, esym_2, ..., esym_N to extract values from isym. isym can be either a Symbol or anonymous-function expression.\n\n@nextract 2 x y would generate\n\nx_1 = y[1]\nx_2 = y[2]\n\nwhile @nextract 3 x d->y[2d-1] yields\n\nx_1 = y[1]\nx_2 = y[3]\nx_3 = y[5]\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nexprs","page":"Base.Cartesian","title":"Base.Cartesian.@nexprs","text":"@nexprs N expr\n\nGenerate N expressions. expr should be an anonymous-function expression.\n\nExamples\n\njulia> @macroexpand Base.Cartesian.@nexprs 4 i -> y[i] = A[i+j]\nquote\n y[1] = A[1 + j]\n y[2] = A[2 + j]\n y[3] = A[3 + j]\n y[4] = A[4 + j]\nend\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@ncall","page":"Base.Cartesian","title":"Base.Cartesian.@ncall","text":"@ncall N f sym...\n\nGenerate a function call expression. sym represents any number of function arguments, the last of which may be an anonymous-function expression and is expanded into N arguments.\n\nFor example, @ncall 3 func a generates\n\nfunc(a_1, a_2, a_3)\n\nwhile @ncall 2 func a b i->c[i] yields\n\nfunc(a, b, c[1], c[2])\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@ncallkw","page":"Base.Cartesian","title":"Base.Cartesian.@ncallkw","text":"@ncallkw N f kw sym...\n\nGenerate a function call expression with keyword arguments kw.... As in the case of @ncall, sym represents any number of function arguments, the last of which may be an anonymous-function expression and is expanded into N arguments.\n\nExamples\n\njulia> using Base.Cartesian\n\njulia> f(x...; a, b = 1, c = 2, d = 3) = +(x..., a, b, c, d);\n\njulia> x_1, x_2 = (-1, -2); b = 0; kw = (c = 0, d = 0);\n\njulia> @ncallkw 2 f (; a = 0, b, kw...) x\n-3\n\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@ntuple","page":"Base.Cartesian","title":"Base.Cartesian.@ntuple","text":"@ntuple N expr\n\nGenerates an N-tuple. @ntuple 2 i would generate (i_1, i_2), and @ntuple 2 k->k+1 would generate (2,3).\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nall","page":"Base.Cartesian","title":"Base.Cartesian.@nall","text":"@nall N expr\n\nCheck whether all of the expressions generated by the anonymous-function expression expr evaluate to true.\n\n@nall 3 d->(i_d > 1) would generate the expression (i_1 > 1 && i_2 > 1 && i_3 > 1). This can be convenient for bounds-checking.\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nany","page":"Base.Cartesian","title":"Base.Cartesian.@nany","text":"@nany N expr\n\nCheck whether any of the expressions generated by the anonymous-function expression expr evaluate to true.\n\n@nany 3 d->(i_d > 1) would generate the expression (i_1 > 1 || i_2 > 1 || i_3 > 1).\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/cartesian/#Base.Cartesian.@nif","page":"Base.Cartesian","title":"Base.Cartesian.@nif","text":"@nif N conditionexpr expr\n@nif N conditionexpr expr elseexpr\n\nGenerates a sequence of if ... elseif ... else ... end statements. For example:\n\n@nif 3 d->(i_d >= size(A,d)) d->(error(\"Dimension \", d, \" too big\")) d->println(\"All OK\")\n\nwould generate:\n\nif i_1 > size(A, 1)\n error(\"Dimension \", 1, \" too big\")\nelseif i_2 > size(A, 2)\n error(\"Dimension \", 2, \" too big\")\nelse\n println(\"All OK\")\nend\n\n\n\n\n\n","category":"macro"},{"location":"devdocs/pkgimg/#pkgimages","page":"Package Images","title":"Package Images","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Julia package images provide object (native code) caches for Julia packages. They are similar to Julia's system image and support many of the same features. In fact the underlying serialization format is the same, and the system image is the base image that the package images are build against.","category":"page"},{"location":"devdocs/pkgimg/#High-level-overview","page":"Package Images","title":"High-level overview","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Package images are shared libraries that contain both code and data. Like .ji cache files, they are generated per package. The data section contains both global data (global variables in the package) as well as the necessary metadata about what methods and types are defined by the package. The code section contains native objects that cache the final output of Julia's LLVM-based compiler.","category":"page"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"The command line option --pkgimages=no can be used to turn off object caching for this session. Note that this means that cache files have to likely be regenerated. See JULIA_MAX_NUM_PRECOMPILE_FILES for the upper limit of variants Julia caches per default.","category":"page"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"note: Note\nWhile the package images present themselves as native shared libraries, they are only an approximation thereof. You will not be able to link against them from a native program and they must be loaded from Julia.","category":"page"},{"location":"devdocs/pkgimg/#Linking","page":"Package Images","title":"Linking","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Since the package images contain native code, we must run a linker over them before we can use them. You can set the environment variable JULIA_VERBOSE_LINKING to true to make the package image linking process verbose.","category":"page"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Furthermore, we cannot assume that the user has a working system linker installed. Therefore, Julia ships with LLD, the LLVM linker, to provide a working out of the box experience. In base/linking.jl, we implement a limited interface to be able to link package images on all supported platforms.","category":"page"},{"location":"devdocs/pkgimg/#Quirks","page":"Package Images","title":"Quirks","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Despite LLD being a multi-platform linker, it does not provide a consistent interface across platforms. Furthermore, it is meant to be used from clang or another compiler driver, we therefore reimplement some of the logic from llvm-project/clang/lib/Driver/ToolChains. Thankfully one can use lld -flavor to set lld to the right platform","category":"page"},{"location":"devdocs/pkgimg/#Windows","page":"Package Images","title":"Windows","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"To avoid having to deal with link.exe we use -flavor gnu, effectively turning lld into a cross-linker from a mingw32 environment. Windows DLLs are required to contain a _DllMainCRTStartup function and to minimize our dependence on mingw32 libraries, we inject a stub definition ourselves.","category":"page"},{"location":"devdocs/pkgimg/#MacOS","page":"Package Images","title":"MacOS","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Dynamic libraries on macOS need to link against -lSystem. On recent macOS versions, -lSystem is only available for linking when Xcode is available. To that effect we link with -undefined dynamic_lookup.","category":"page"},{"location":"devdocs/pkgimg/#pkgimgs-multi-versioning","page":"Package Images","title":"Package images optimized for multiple microarchitectures","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"Similar to multi-versioning for system images, package images support multi-versioning. If you are in a heterogeneous environment, with a unified cache, you can set the environment variable JULIA_CPU_TARGET=generic to multi-version the object caches.","category":"page"},{"location":"devdocs/pkgimg/#Flags-that-impact-package-image-creation-and-selection","page":"Package Images","title":"Flags that impact package image creation and selection","text":"","category":"section"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"These are the Julia command line flags that impact cache selection. Package images that were created with different flags will be rejected.","category":"page"},{"location":"devdocs/pkgimg/","page":"Package Images","title":"Package Images","text":"-g, --debug-info: Exact match required since it changes code generation.\n--check-bounds: Exact match required since it changes code generation.\n--inline: Exact match required since it changes code generation.\n--pkgimages: To allow running without object caching enabled.\n-O, --optimize: Reject package images generated for a lower optimization level, but allow for higher optimization levels to be loaded.","category":"page"},{"location":"devdocs/precompile_hang/#Fixing-precompilation-hangs-due-to-open-tasks-or-IO","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"","category":"section"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"On Julia 1.10 or higher, you might see the following message:","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"(Image: Screenshot of precompilation hang)","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"This may repeat. If it continues to repeat with no hints that it will resolve itself, you may have a \"precompilation hang\" that requires fixing. Even if it's transient, you might prefer to resolve it so that users will not be bothered by this warning. This page walks you through how to analyze and fix such issues.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"If you follow the advice and hit Ctrl-C, you might see","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"^C Interrupted: Exiting precompilation...\n\n 1 dependency had warnings during precompilation:\n┌ Test1 [ac89d554-e2ba-40bc-bc5c-de68b658c982]\n│ [pid 2745] waiting for IO to finish:\n│ Handle type uv_handle_t->data\n│ timer 0x55580decd1e0->0x7f94c3a4c340","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"This message conveys two key pieces of information:","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"the hang is occurring during precompilation of Test1, a dependency of Test2 (the package we were trying to load with using Test2)\nduring precompilation of Test1, Julia created a Timer object (use ?Timer if you're unfamiliar with Timers) which is still open; until that closes, the process is hung","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"If this is enough of a hint for you to figure out how timer = Timer(args...) is being created, one good solution is to add wait(timer) if timer eventually finishes on its own, or close(timer) if you need to force-close it, before the final end of the module.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"However, there are cases that may not be that straightforward. Usually the best option is to start by determining whether the hang is due to code in Test1 or whether it is due to one of Test1's dependencies:","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Option 1: Pkg.add(\"Aqua\") and use Aqua.test_persistent_tasks. This should help you identify which package is causing the problem, after which the instructions below should be followed. If needed, you can create a PkgId as Base.PkgId(UUID(\"...\"), \"Test1\"), where ... comes from the uuid entry in Test1/Project.toml.\nOption 2: manually diagnose the source of the hang.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"To manually diagnose:","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Pkg.develop(\"Test1\")\nComment out all the code included or defined in Test1, except the using/import statements.\nTry using Test2 (or even using Test1 assuming that hangs too) again","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Now we arrive at a fork in the road: either","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"the hang persists, indicating it is due to one of your dependencies\nthe hang disappears, indicating that it is due to something in your code.","category":"page"},{"location":"devdocs/precompile_hang/#pchang_deps","page":"Fixing precompilation hangs due to open tasks or IO","title":"Diagnosing and fixing hangs due to a package dependency","text":"","category":"section"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Use a binary search to identify the problematic dependency: start by commenting out half your dependencies, then when you isolate which half is responsible comment out half of that half, etc. (You don't have to remove them from the project, just comment out the using/import statements.)","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Once you've identified a suspect (here we'll call it ThePackageYouThinkIsCausingTheProblem), first try precompiling that package. If it also hangs during precompilation, continue chasing the problem backwards.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"However, most likely ThePackageYouThinkIsCausingTheProblem will precompile fine. This suggests it's in the function ThePackageYouThinkIsCausingTheProblem.__init__, which does not run during precompilation of ThePackageYouThinkIsCausingTheProblem but does in any package that loads ThePackageYouThinkIsCausingTheProblem. To test this theory, set up a minimal working example (MWE), something like","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"(@v1.10) pkg> generate MWE\n Generating project MWE:\n MWE\\Project.toml\n MWE\\src\\MWE.jl","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"where the source code of MWE.jl is","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"module MWE\nusing ThePackageYouThinkIsCausingTheProblem\nend","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"and you've added ThePackageYouThinkIsCausingTheProblem to MWE's dependencies.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"If that MWE reproduces the hang, you've found your culprit: ThePackageYouThinkIsCausingTheProblem.__init__ must be creating the Timer object. If the timer object can be safely closed, that's a good option. Otherwise, the most common solution is to avoid creating the timer while any package is being precompiled: add","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"ccall(:jl_generating_output, Cint, ()) == 1 && return nothing","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"as the first line of ThePackageYouThinkIsCausingTheProblem.__init__, and it will avoid doing any initialization in any Julia process whose purpose is to precompile packages.","category":"page"},{"location":"devdocs/precompile_hang/#pchang_fix","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing package code to avoid hangs","text":"","category":"section"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"Search your package for suggestive words (here like \"Timer\") and see if you can identify where the problem is being created. Note that a method definition like","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"maketimer() = Timer(timer -> println(\"hi\"), 0; interval=1)","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"is not problematic in and of itself: it can cause this problem only if maketimer gets called while the module is being defined. This might be happening from a top-level statement such as","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"const GLOBAL_TIMER = maketimer()","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"or it might conceivably occur in a precompile workload.","category":"page"},{"location":"devdocs/precompile_hang/","page":"Fixing precompilation hangs due to open tasks or IO","title":"Fixing precompilation hangs due to open tasks or IO","text":"If you struggle to identify the causative lines, then consider doing a binary search: comment out sections of your package (or include lines to omit entire files) until you've reduced the problem in scope.","category":"page"},{"location":"stdlib/SharedArrays/","page":"Shared Arrays","title":"Shared Arrays","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/SharedArrays/docs/src/index.md\"","category":"page"},{"location":"stdlib/SharedArrays/#Shared-Arrays","page":"Shared Arrays","title":"Shared Arrays","text":"","category":"section"},{"location":"stdlib/SharedArrays/","page":"Shared Arrays","title":"Shared Arrays","text":"SharedArray represents an array, which is shared across multiple processes, on a single machine.","category":"page"},{"location":"stdlib/SharedArrays/","page":"Shared Arrays","title":"Shared Arrays","text":"SharedArrays.SharedArray\nSharedArrays.SharedVector\nSharedArrays.SharedMatrix\nSharedArrays.procs(::SharedArray)\nSharedArrays.sdata\nSharedArrays.indexpids\nSharedArrays.localindices","category":"page"},{"location":"stdlib/SharedArrays/#SharedArrays.SharedArray","page":"Shared Arrays","title":"SharedArrays.SharedArray","text":"SharedArray{T}(dims::NTuple; init=false, pids=Int[])\nSharedArray{T,N}(...)\n\nConstruct a SharedArray of a bits type T and size dims across the processes specified by pids - all of which have to be on the same host. If N is specified by calling SharedArray{T,N}(dims), then N must match the length of dims.\n\nIf pids is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, localindices and indexpids will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.\n\nIf an init function of the type initfn(S::SharedArray) is specified, it is called on all the participating workers.\n\nThe shared array is valid as long as a reference to the SharedArray object exists on the node which created the mapping.\n\nSharedArray{T}(filename::AbstractString, dims::NTuple, [offset=0]; mode=nothing, init=false, pids=Int[])\nSharedArray{T,N}(...)\n\nConstruct a SharedArray backed by the file filename, with element type T (must be a bits type) and size dims, across the processes specified by pids - all of which have to be on the same host. This file is mmapped into the host memory, with the following consequences:\n\nThe array data must be represented in binary format (e.g., an ASCII format like CSV cannot be supported)\nAny changes you make to the array values (e.g., A[3] = 0) will also change the values on disk\n\nIf pids is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, localindices and indexpids will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.\n\nmode must be one of \"r\", \"r+\", \"w+\", or \"a+\", and defaults to \"r+\" if the file specified by filename already exists, or \"w+\" if not. If an init function of the type initfn(S::SharedArray) is specified, it is called on all the participating workers. You cannot specify an init function if the file is not writable.\n\noffset allows you to skip the specified number of bytes at the beginning of the file.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SharedArrays/#SharedArrays.SharedVector","page":"Shared Arrays","title":"SharedArrays.SharedVector","text":"SharedVector\n\nA one-dimensional SharedArray.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SharedArrays/#SharedArrays.SharedMatrix","page":"Shared Arrays","title":"SharedArrays.SharedMatrix","text":"SharedMatrix\n\nA two-dimensional SharedArray.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/SharedArrays/#Distributed.procs-Tuple{SharedArray}","page":"Shared Arrays","title":"Distributed.procs","text":"procs(S::SharedArray)\n\nGet the vector of processes mapping the shared array.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/SharedArrays/#SharedArrays.sdata","page":"Shared Arrays","title":"SharedArrays.sdata","text":"sdata(S::SharedArray)\n\nReturn the actual Array object backing S.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SharedArrays/#SharedArrays.indexpids","page":"Shared Arrays","title":"SharedArrays.indexpids","text":"indexpids(S::SharedArray)\n\nReturn the current worker's index in the list of workers mapping the SharedArray (i.e. in the same list returned by procs(S)), or 0 if the SharedArray is not mapped locally.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/SharedArrays/#SharedArrays.localindices","page":"Shared Arrays","title":"SharedArrays.localindices","text":"localindices(S::SharedArray)\n\nReturn a range describing the \"default\" indices to be handled by the current process. This range should be interpreted in the sense of linear indexing, i.e., as a sub-range of 1:length(S). In multi-process contexts, returns an empty range in the parent process (or any process for which indexpids returns 0).\n\nIt's worth emphasizing that localindices exists purely as a convenience, and you can partition work on the array among workers any way you wish. For a SharedArray, all indices should be equally fast for each worker process.\n\n\n\n\n\n","category":"function"},{"location":"manual/modules/#modules","page":"Modules","title":"Modules","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Modules in Julia help organize code into coherent units. They are delimited syntactically inside module NameOfModule ... end, and have the following features:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Modules are separate namespaces, each introducing a new global scope. This is useful, because it allows the same name to be used for different functions or global variables without conflict, as long as they are in separate modules.\nModules have facilities for detailed namespace management: each defines a set of names it exports and marks as public, and can import names from other modules with using and import (we explain these below).\nModules can be precompiled for faster loading, and may contain code for runtime initialization.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Typically, in larger Julia packages you will see module code organized into files, eg","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"module SomeModule\n\n# export, public, using, import statements are usually here; we discuss these below\n\ninclude(\"file1.jl\")\ninclude(\"file2.jl\")\n\nend","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Files and file names are mostly unrelated to modules; modules are associated only with module expressions. One can have multiple files per module, and multiple modules per file. include behaves as if the contents of the source file were evaluated in the global scope of the including module. In this chapter, we use short and simplified examples, so we won't use include.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"The recommended style is not to indent the body of the module, since that would typically lead to whole files being indented. Also, it is common to use UpperCamelCase for module names (just like types), and use the plural form if applicable, especially if the module contains a similarly named identifier, to avoid name clashes. For example,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"module FastThings\n\nstruct FastThing\n ...\nend\n\nend","category":"page"},{"location":"manual/modules/#namespace-management","page":"Modules","title":"Namespace management","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Namespace management refers to the facilities the language offers for making names in a module available in other modules. We discuss the related concepts and functionality below in detail.","category":"page"},{"location":"manual/modules/#Qualified-names","page":"Modules","title":"Qualified names","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Names for functions, variables and types in the global scope like sin, ARGS, and UnitRange always belong to a module, called the parent module, which can be found interactively with parentmodule, for example","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> parentmodule(UnitRange)\nBase","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"One can also refer to these names outside their parent module by prefixing them with their module, eg Base.UnitRange. This is called a qualified name. The parent module may be accessible using a chain of submodules like Base.Math.sin, where Base.Math is called the module path. Due to syntactic ambiguities, qualifying a name that contains only symbols, such as an operator, requires inserting a colon, e.g. Base.:+. A small number of operators additionally require parentheses, e.g. Base.:(==).","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"If a name is qualified, then it is always accessible, and in case of a function, it can also have methods added to it by using the qualified name as the function name.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Within a module, a variable name can be “reserved” without assigning to it by declaring it as global x. This prevents name conflicts for globals initialized after load time. The syntax M.x = y does not work to assign a global in another module; global assignment is always module-local.","category":"page"},{"location":"manual/modules/#Export-lists","page":"Modules","title":"Export lists","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Names (referring to functions, types, global variables, and constants) can be added to the export list of a module with export: these are the symbols that are imported when using the module. Typically, they are at or near the top of the module definition so that readers of the source code can find them easily, as in","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> module NiceStuff\n export nice, DOG\n struct Dog end # singleton type, not exported\n const DOG = Dog() # named instance, exported\n nice(x) = \"nice $x\" # function, exported\n end;\n","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"but this is just a style suggestion — a module can have multiple export statements in arbitrary locations.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"It is common to export names which form part of the API (application programming interface). In the above code, the export list suggests that users should use nice and DOG. However, since qualified names always make identifiers accessible, this is just an option for organizing APIs: unlike other languages, Julia has no facilities for truly hiding module internals.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Also, some modules don't export names at all. This is usually done if they use common words, such as derivative, in their API, which could easily clash with the export lists of other modules. We will see how to manage name clashes below.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"To mark a name as public without exporting it into the namespace of folks who call using NiceStuff, one can use public instead of export. This marks the public name(s) as part of the public API, but does not have any namespace implications. The public keyword is only available in Julia 1.11 and above. To maintain compatibility with Julia 1.10 and below, use the @compat macro from the Compat package.","category":"page"},{"location":"manual/modules/#Standalone-using-and-import","page":"Modules","title":"Standalone using and import","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Possibly the most common way of loading a module is using ModuleName. This loads the code associated with ModuleName, and brings","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"the module name\nand the elements of the export list into the surrounding global namespace.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Technically, the statement using ModuleName means that a module called ModuleName will be available for resolving names as needed. When a global variable is encountered that has no definition in the current module, the system will search for it among variables exported by ModuleName and use it if it is found there. This means that all uses of that global within the current module will resolve to the definition of that variable in ModuleName.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"To load a module from a package, the statement using ModuleName can be used. To load a module from a locally defined module, a dot needs to be added before the module name like using .ModuleName.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"To continue with our example,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"would load the above code, making NiceStuff (the module name), DOG and nice available. Dog is not on the export list, but it can be accessed if the name is qualified with the module path (which here is just the module name) as NiceStuff.Dog.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Importantly, using ModuleName is the only form for which export lists matter at all.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"In contrast,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> import .NiceStuff","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"brings only the module name into scope. Users would need to use NiceStuff.DOG, NiceStuff.Dog, and NiceStuff.nice to access its contents. Usually, import ModuleName is used in contexts when the user wants to keep the namespace clean. As we will see in the next section import .NiceStuff is equivalent to using .NiceStuff: NiceStuff.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"You can combine multiple using and import statements of the same kind in a comma-separated expression, e.g.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using LinearAlgebra, Random","category":"page"},{"location":"manual/modules/#using-and-import-with-specific-identifiers,-and-adding-methods","page":"Modules","title":"using and import with specific identifiers, and adding methods","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"When using ModuleName: or import ModuleName: is followed by a comma-separated list of names, the module is loaded, but only those specific names are brought into the namespace by the statement. For example,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff: nice, DOG","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"will import the names nice and DOG.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Importantly, the module name NiceStuff will not be in the namespace. If you want to make it accessible, you have to list it explicitly, as","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff: nice, DOG, NiceStuff","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Julia has two forms for seemingly the same thing because only import ModuleName: f allows adding methods to f without a module path. That is to say, the following example will give an error:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff: nice\n\njulia> struct Cat end\n\njulia> nice(::Cat) = \"nice 😸\"\nERROR: invalid method definition in Main: function NiceStuff.nice must be explicitly imported to be extended\nStacktrace:\n [1] top-level scope\n @ none:0\n [2] top-level scope\n @ none:1","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"This error prevents accidentally adding methods to functions in other modules that you only intended to use.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"There are two ways to deal with this. You can always qualify function names with a module path:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff\n\njulia> struct Cat end\n\njulia> NiceStuff.nice(::Cat) = \"nice 😸\"","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Alternatively, you can import the specific function name:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> import .NiceStuff: nice\n\njulia> struct Mouse end\n\njulia> nice(::Mouse) = \"nice 🐭\"\nnice (generic function with 3 methods)","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Which one you choose is a matter of style. The first form makes it clear that you are adding a method to a function in another module (remember, that the imports and the method definition may be in separate files), while the second one is shorter, which is especially convenient if you are defining multiple methods.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Once a variable is made visible via using or import, a module may not create its own variable with the same name. Imported variables are read-only; assigning to a global variable always affects a variable owned by the current module, or else raises an error.","category":"page"},{"location":"manual/modules/#Renaming-with-as","page":"Modules","title":"Renaming with as","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"An identifier brought into scope by import or using can be renamed with the keyword as. This is useful for working around name conflicts as well as for shortening names. For example, Base exports the function name read, but the CSV.jl package also provides CSV.read. If we are going to invoke CSV reading many times, it would be convenient to drop the CSV. qualifier. But then it is ambiguous whether we are referring to Base.read or CSV.read:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> read;\n\njulia> import CSV: read\nWARNING: ignoring conflicting import of CSV.read into Main","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Renaming provides a solution:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> import CSV: read as rd","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Imported packages themselves can also be renamed:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"import BenchmarkTools as BT","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"as works with using only when a single identifier is brought into scope. For example using CSV: read as rd works, but using CSV as C does not, since it operates on all of the exported names in CSV.","category":"page"},{"location":"manual/modules/#Mixing-multiple-using-and-import-statements","page":"Modules","title":"Mixing multiple using and import statements","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"When multiple using or import statements of any of the forms above are used, their effect is combined in the order they appear. For example,","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .NiceStuff # exported names and the module name\n\njulia> import .NiceStuff: nice # allows adding methods to unqualified functions\n","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"would bring all the exported names of NiceStuff and the module name itself into scope, and also allow adding methods to nice without prefixing it with a module name.","category":"page"},{"location":"manual/modules/#Handling-name-conflicts","page":"Modules","title":"Handling name conflicts","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Consider the situation where two (or more) packages export the same name, as in","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> module A\n export f\n f() = 1\n end\nA\njulia> module B\n export f\n f() = 2\n end\nB","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"The statement using .A, .B works, but when you try to call f, you get a warning","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> using .A, .B\n\njulia> f\nWARNING: both B and A export \"f\"; uses of it in module Main must be qualified\nERROR: UndefVarError: `f` not defined in `Main`","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Here, Julia cannot decide which f you are referring to, so you have to make a choice. The following solutions are commonly used:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Simply proceed with qualified names like A.f and B.f. This makes the context clear to the reader of your code, especially if f just happens to coincide but has different meaning in various packages. For example, degree has various uses in mathematics, the natural sciences, and in everyday life, and these meanings should be kept separate.\nUse the as keyword above to rename one or both identifiers, eg\njulia> using .A: f as f\n\njulia> using .B: f as g\n\nwould make B.f available as g. Here, we are assuming that you did not use using A before, which would have brought f into the namespace.\nWhen the names in question do share a meaning, it is common for one module to import it from another, or have a lightweight “base” package with the sole function of defining an interface like this, which can be used by other packages. It is conventional to have such package names end in ...Base (which has nothing to do with Julia's Base module).","category":"page"},{"location":"manual/modules/#Default-top-level-definitions-and-bare-modules","page":"Modules","title":"Default top-level definitions and bare modules","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Modules automatically contain using Core, using Base, and definitions of the eval and include functions, which evaluate expressions/files within the global scope of that module.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"If these default definitions are not wanted, modules can be defined using the keyword baremodule instead (note: Core is still imported). In terms of baremodule, a standard module looks like this:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"baremodule Mod\n\nusing Base\n\neval(x) = Core.eval(Mod, x)\ninclude(p) = Base.include(Mod, p)\n\n...\n\nend","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"If even Core is not wanted, a module that imports nothing and defines no names at all can be defined with Module(:YourNameHere, false, false) and code can be evaluated into it with @eval or Core.eval:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> arithmetic = Module(:arithmetic, false, false)\nMain.arithmetic\n\njulia> @eval arithmetic add(x, y) = $(+)(x, y)\nadd (generic function with 1 method)\n\njulia> arithmetic.add(12, 13)\n25","category":"page"},{"location":"manual/modules/#Standard-modules","page":"Modules","title":"Standard modules","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"There are three important standard modules:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Core contains all functionality \"built into\" the language.\nBase contains basic functionality that is useful in almost all cases.\nMain is the top-level module and the current module, when Julia is started.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"note: Standard library modules\nBy default Julia ships with some standard library modules. These behave like regular Julia packages except that you don't need to install them explicitly. For example, if you wanted to perform some unit testing, you could load the Test standard library as follows:using Test","category":"page"},{"location":"manual/modules/#Submodules-and-relative-paths","page":"Modules","title":"Submodules and relative paths","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Modules can contain submodules, nesting the same syntax module ... end. They can be used to introduce separate namespaces, which can be helpful for organizing complex codebases. Note that each module introduces its own scope, so submodules do not automatically “inherit” names from their parent.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"It is recommended that submodules refer to other modules within the enclosing parent module (including the latter) using relative module qualifiers in using and import statements. A relative module qualifier starts with a period (.), which corresponds to the current module, and each successive . leads to the parent of the current module. This should be followed by modules if necessary, and eventually the actual name to access, all separated by .s.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Consider the following example, where the submodule SubA defines a function, which is then extended in its “sibling” module:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> module ParentModule\n module SubA\n export add_D # exported interface\n const D = 3\n add_D(x) = x + D\n end\n using .SubA # brings `add_D` into the namespace\n export add_D # export it from ParentModule too\n module SubB\n import ..SubA: add_D # relative path for a “sibling” module\n struct Infinity end\n add_D(x::Infinity) = x\n end\n end;\n","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"You may see code in packages, which, in a similar situation, uses","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"julia> import .ParentModule.SubA: add_D\n","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"However, this operates through code loading, and thus only works if ParentModule is in a package. It is better to use relative paths.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Note that the order of definitions also matters if you are evaluating values. Consider","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"module TestPackage\n\nexport x, y\n\nx = 0\n\nmodule Sub\nusing ..TestPackage\nz = y # ERROR: UndefVarError: `y` not defined in `Main`\nend\n\ny = 1\n\nend","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"where Sub is trying to use TestPackage.y before it was defined, so it does not have a value.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"For similar reasons, you cannot use a cyclic ordering:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"module A\n\nmodule B\nusing ..C # ERROR: UndefVarError: `C` not defined in `Main.A`\nend\n\nmodule C\nusing ..B\nend\n\nend","category":"page"},{"location":"manual/modules/#Module-initialization-and-precompilation","page":"Modules","title":"Module initialization and precompilation","text":"","category":"section"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Large modules can take several seconds to load because executing all of the statements in a module often involves compiling a large amount of code. Julia creates precompiled caches of the module to reduce this time.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Precompiled module files (sometimes called \"cache files\") are created and used automatically when import or using loads a module. If the cache file(s) do not yet exist, the module will be compiled and saved for future reuse. You can also manually call Base.compilecache(Base.identify_package(\"modulename\")) to create these files without loading the module. The resulting cache files will be stored in the compiled subfolder of DEPOT_PATH[1]. If nothing about your system changes, such cache files will be used when you load the module with import or using.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Precompilation cache files store definitions of modules, types, methods, and constants. They may also store method specializations and the code generated for them, but this typically requires that the developer add explicit precompile directives or execute workloads that force compilation during the package build.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"However, if you update the module's dependencies or change its source code, the module is automatically recompiled upon using or import. Dependencies are modules it imports, the Julia build, files it includes, or explicit dependencies declared by include_dependency(path) in the module file(s).","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"For file dependencies loaded by include, a change is determined by examining whether the file size (fsize) or content (condensed into a hash) is unchanged. For file dependencies loaded by include_dependency a change is determined by examining whether the modification time (mtime) is unchanged, or equal to the modification time truncated to the nearest second (to accommodate systems that can't copy mtime with sub-second accuracy). It also takes into account whether the path to the file chosen by the search logic in require matches the path that had created the precompile file. It also takes into account the set of dependencies already loaded into the current process and won't recompile those modules, even if their files change or disappear, in order to avoid creating incompatibilities between the running system and the precompile cache. Finally, it takes account of changes in any compile-time preferences.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"If you know that a module is not safe to precompile (for example, for one of the reasons described below), you should put __precompile__(false) in the module file (typically placed at the top). This will cause Base.compilecache to throw an error, and will cause using / import to load it directly into the current process and skip the precompile and caching. This also thereby prevents the module from being imported by any other precompiled module.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"You may need to be aware of certain behaviors inherent in the creation of incremental shared libraries which may require care when writing your module. For example, external state is not preserved. To accommodate this, explicitly separate any initialization steps that must occur at runtime from steps that can occur at compile time. For this purpose, Julia allows you to define an __init__() function in your module that executes any initialization steps that must occur at runtime. This function will not be called during compilation (--output-*). Effectively, you can assume it will be run exactly once in the lifetime of the code. You may, of course, call it manually if necessary, but the default is to assume this function deals with computing state for the local machine, which does not need to be – or even should not be – captured in the compiled image. It will be called after the module is loaded into a process, including if it is being loaded into an incremental compile (--output-incremental=yes), but not if it is being loaded into a full-compilation process.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"In particular, if you define a function __init__() in a module, then Julia will call __init__() immediately after the module is loaded (e.g., by import, using, or require) at runtime for the first time (i.e., __init__ is only called once, and only after all statements in the module have been executed). Because it is called after the module is fully imported, any submodules or other imported modules have their __init__ functions called before the __init__ of the enclosing module.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Two typical uses of __init__ are calling runtime initialization functions of external C libraries and initializing global constants that involve pointers returned by external libraries. For example, suppose that we are calling a C library libfoo that requires us to call a foo_init() initialization function at runtime. Suppose that we also want to define a global constant foo_data_ptr that holds the return value of a void *foo_data() function defined by libfoo – this constant must be initialized at runtime (not at compile time) because the pointer address will change from run to run. You could accomplish this by defining the following __init__ function in your module:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"const foo_data_ptr = Ref{Ptr{Cvoid}}(0)\nfunction __init__()\n ccall((:foo_init, :libfoo), Cvoid, ())\n foo_data_ptr[] = ccall((:foo_data, :libfoo), Ptr{Cvoid}, ())\n nothing\nend","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Notice that it is perfectly possible to define a global inside a function like __init__; this is one of the advantages of using a dynamic language. But by making it a constant at global scope, we can ensure that the type is known to the compiler and allow it to generate better optimized code. Obviously, any other globals in your module that depends on foo_data_ptr would also have to be initialized in __init__.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Constants involving most Julia objects that are not produced by ccall do not need to be placed in __init__: their definitions can be precompiled and loaded from the cached module image. This includes complicated heap-allocated objects like arrays. However, any routine that returns a raw pointer value must be called at runtime for precompilation to work (Ptr objects will turn into null pointers unless they are hidden inside an isbits object). This includes the return values of the Julia functions @cfunction and pointer.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Dictionary and set types, or in general anything that depends on the output of a hash(key) method, are a trickier case. In the common case where the keys are numbers, strings, symbols, ranges, Expr, or compositions of these types (via arrays, tuples, sets, pairs, etc.) they are safe to precompile. However, for a few other key types, such as Function or DataType and generic user-defined types where you haven't defined a hash method, the fallback hash method depends on the memory address of the object (via its objectid) and hence may change from run to run. If you have one of these key types, or if you aren't sure, to be safe you can initialize this dictionary from within your __init__ function. Alternatively, you can use the IdDict dictionary type, which is specially handled by precompilation so that it is safe to initialize at compile-time.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"When using precompilation, it is important to keep a clear sense of the distinction between the compilation phase and the execution phase. In this mode, it will often be much more clearly apparent that Julia is a compiler which allows execution of arbitrary Julia code, not a standalone interpreter that also generates compiled code.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Other known potential failure scenarios include:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Global counters (for example, for attempting to uniquely identify objects). Consider the following code snippet:\nmutable struct UniquedById\n myid::Int\n let counter = 0\n UniquedById() = new(counter += 1)\n end\nend\nwhile the intent of this code was to give every instance a unique id, the counter value is recorded at the end of compilation. All subsequent usages of this incrementally compiled module will start from that same counter value.\nNote that objectid (which works by hashing the memory pointer) has similar issues (see notes on Dict usage below).\nOne alternative is to use a macro to capture @__MODULE__ and store it alone with the current counter value, however, it may be better to redesign the code to not depend on this global state.\nAssociative collections (such as Dict and Set) need to be re-hashed in __init__. (In the future, a mechanism may be provided to register an initializer function.)\nDepending on compile-time side-effects persisting through load-time. Example include: modifying arrays or other variables in other Julia modules; maintaining handles to open files or devices; storing pointers to other system resources (including memory);\nCreating accidental \"copies\" of global state from another module, by referencing it directly instead of via its lookup path. For example, (in global scope):\n#mystdout = Base.stdout #= will not work correctly, since this will copy Base.stdout into this module =#\n# instead use accessor functions:\ngetstdout() = Base.stdout #= best option =#\n# or move the assignment into the runtime:\n__init__() = global mystdout = Base.stdout #= also works =#","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Several additional restrictions are placed on the operations that can be done while precompiling code to help the user avoid other wrong-behavior situations:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"Calling eval to cause a side-effect in another module. This will also cause a warning to be emitted when the incremental precompile flag is set.\nglobal const statements from local scope after __init__() has been started (see issue #12010 for plans to add an error for this)\nReplacing a module is a runtime error while doing an incremental precompile.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"A few other points to be aware of:","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"No code reload / cache invalidation is performed after changes are made to the source files themselves, (including by Pkg.update), and no cleanup is done after Pkg.rm\nThe memory sharing behavior of a reshaped array is disregarded by precompilation (each view gets its own copy)\nExpecting the filesystem to be unchanged between compile-time and runtime e.g. @__FILE__/source_path() to find resources at runtime, or the BinDeps @checked_lib macro. Sometimes this is unavoidable. However, when possible, it can be good practice to copy resources into the module at compile-time so they won't need to be found at runtime.\nWeakRef objects and finalizers are not currently handled properly by the serializer (this will be fixed in an upcoming release).\nIt is usually best to avoid capturing references to instances of internal metadata objects such as Method, MethodInstance, MethodTable, TypeMapLevel, TypeMapEntry and fields of those objects, as this can confuse the serializer and may not lead to the outcome you desire. It is not necessarily an error to do this, but you simply need to be prepared that the system will try to copy some of these and to create a single unique instance of others.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"It is sometimes helpful during module development to turn off incremental precompilation. The command line flag --compiled-modules={yes|no|existing} enables you to toggle module precompilation on and off. When Julia is started with --compiled-modules=no the serialized modules in the compile cache are ignored when loading modules and module dependencies. In some cases, you may want to load existing precompiled modules, but not create new ones. This can be done by starting Julia with --compiled-modules=existing. More fine-grained control is available with --pkgimages={yes|no|existing}, which only affects native-code storage during precompilation. Base.compilecache can still be called manually. The state of this command line flag is passed to Pkg.build to disable automatic precompilation triggering when installing, updating, and explicitly building packages.","category":"page"},{"location":"manual/modules/","page":"Modules","title":"Modules","text":"You can also debug some precompilation failures with environment variables. Setting JULIA_VERBOSE_LINKING=true may help resolve failures in linking shared libraries of compiled native code. See the Developer Documentation part of the Julia manual, where you will find further details in the section documenting Julia's internals under \"Package Images\".","category":"page"},{"location":"devdocs/debuggingtips/#gdb-debugging-tips","page":"gdb debugging tips","title":"gdb debugging tips","text":"","category":"section"},{"location":"devdocs/debuggingtips/#Displaying-Julia-variables","page":"gdb debugging tips","title":"Displaying Julia variables","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Within gdb, any jl_value_t* object obj can be displayed using","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) call jl_(obj)","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"The object will be displayed in the julia session, not in the gdb session. This is a useful way to discover the types and values of objects being manipulated by Julia's C code.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Similarly, if you're debugging some of Julia's internals (e.g., compiler.jl), you can print obj using","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"ccall(:jl_, Cvoid, (Any,), obj)","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"This is a good way to circumvent problems that arise from the order in which julia's output streams are initialized.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Julia's flisp interpreter uses value_t objects; these can be displayed with call fl_print(fl_ctx, ios_stdout, obj).","category":"page"},{"location":"devdocs/debuggingtips/#Useful-Julia-variables-for-Inspecting","page":"gdb debugging tips","title":"Useful Julia variables for Inspecting","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"While the addresses of many variables, like singletons, can be useful to print for many failures, there are a number of additional variables (see julia.h for a complete list) that are even more useful.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(when in jl_apply_generic) mfunc and jl_uncompress_ast(mfunc->def, mfunc->code) :: for figuring out a bit about the call-stack\njl_lineno and jl_filename :: for figuring out what line in a test to go start debugging from (or figure out how far into a file has been parsed)\n$1 :: not really a variable, but still a useful shorthand for referring to the result of the last gdb command (such as print)\njl_options :: sometimes useful, since it lists all of the command line options that were successfully parsed\njl_uv_stderr :: because who doesn't like to be able to interact with stdio","category":"page"},{"location":"devdocs/debuggingtips/#Useful-Julia-functions-for-Inspecting-those-variables","page":"gdb debugging tips","title":"Useful Julia functions for Inspecting those variables","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"jl_print_task_backtraces(0) :: Similar to gdb's thread apply all bt or lldb's thread backtrace all. Runs all threads while printing backtraces for all existing tasks.\njl_gdblookup($pc) :: For looking up the current function and line.\njl_gdblookupinfo($pc) :: For looking up the current method instance object.\njl_gdbdumpcode(mi) :: For dumping all of code_typed/code_llvm/code_asm when the REPL is not working right.\njlbacktrace() :: For dumping the current Julia backtrace stack to stderr. Only usable after record_backtrace() has been called.\njl_dump_llvm_value(Value*) :: For invoking Value->dump() in gdb, where it doesn't work natively. For example, f->linfo->functionObject, f->linfo->specFunctionObject, and to_function(f->linfo).\njl_dump_llvm_module(Module*) :: For invoking Module->dump() in gdb, where it doesn't work natively.\nType->dump() :: only works in lldb. Note: add something like ;1 to prevent lldb from printing its prompt over the output\njl_eval_string(\"expr\") :: for invoking side-effects to modify the current state or to lookup symbols\njl_typeof(jl_value_t*) :: for extracting the type tag of a Julia value (in gdb, call macro define jl_typeof jl_typeof first, or pick something short like ty for the first arg to define a shorthand)","category":"page"},{"location":"devdocs/debuggingtips/#Inserting-breakpoints-for-inspection-from-gdb","page":"gdb debugging tips","title":"Inserting breakpoints for inspection from gdb","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"In your gdb session, set a breakpoint in jl_breakpoint like so:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) break jl_breakpoint","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Then within your Julia code, insert a call to jl_breakpoint by adding","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"ccall(:jl_breakpoint, Cvoid, (Any,), obj)","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"where obj can be any variable or tuple you want to be accessible in the breakpoint.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"It's particularly helpful to back up to the jl_apply frame, from which you can display the arguments to a function using, e.g.,","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) call jl_(args[0])","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Another useful frame is to_function(jl_method_instance_t *li, bool cstyle). The jl_method_instance_t* argument is a struct with a reference to the final AST sent into the compiler. However, the AST at this point will usually be compressed; to view the AST, call jl_uncompress_ast and then pass the result to jl_:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"#2 0x00007ffff7928bf7 in to_function (li=0x2812060, cstyle=false) at codegen.cpp:584\n584 abort();\n(gdb) p jl_(jl_uncompress_ast(li, li->ast))","category":"page"},{"location":"devdocs/debuggingtips/#Inserting-breakpoints-upon-certain-conditions","page":"gdb debugging tips","title":"Inserting breakpoints upon certain conditions","text":"","category":"section"},{"location":"devdocs/debuggingtips/#Loading-a-particular-file","page":"gdb debugging tips","title":"Loading a particular file","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Let's say the file is sysimg.jl:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) break jl_load if strcmp(fname, \"sysimg.jl\")==0","category":"page"},{"location":"devdocs/debuggingtips/#Calling-a-particular-method","page":"gdb debugging tips","title":"Calling a particular method","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) break jl_apply_generic if strcmp((char*)(jl_symbol_name)(jl_gf_mtable(F)->name), \"method_to_break\")==0","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Since this function is used for every call, you will make everything 1000x slower if you do this.","category":"page"},{"location":"devdocs/debuggingtips/#Dealing-with-signals","page":"gdb debugging tips","title":"Dealing with signals","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Julia requires a few signals to function properly. The profiler uses SIGUSR2 for sampling and the garbage collector uses SIGSEGV for threads synchronization. If you are debugging some code that uses the profiler or multiple threads, you may want to let the debugger ignore these signals since they can be triggered very often during normal operations. The command to do this in GDB is (replace SIGSEGV with SIGUSR2 or other signals you want to ignore):","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) handle SIGSEGV noprint nostop pass","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"The corresponding LLDB command is (after the process is started):","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(lldb) pro hand -p true -s false -n false SIGSEGV","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"If you are debugging a segfault with threaded code, you can set a breakpoint on jl_critical_error (sigdie_handler should also work on Linux and BSD) in order to only catch the actual segfault rather than the GC synchronization points.","category":"page"},{"location":"devdocs/debuggingtips/#Debugging-during-Julia's-build-process-(bootstrap)","page":"gdb debugging tips","title":"Debugging during Julia's build process (bootstrap)","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Errors that occur during make need special handling. Julia is built in two stages, constructing sys0 and sys.ji. To see what commands are running at the time of failure, use make VERBOSE=1.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"At the time of this writing, you can debug build errors during the sys0 phase from the base directory using:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"julia/base$ gdb --args ../usr/bin/julia-debug -C native --build ../usr/lib/julia/sys0 sysimg.jl","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"You might need to delete all the files in usr/lib/julia/ to get this to work.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"You can debug the sys.ji phase using:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"julia/base$ gdb --args ../usr/bin/julia-debug -C native --build ../usr/lib/julia/sys -J ../usr/lib/julia/sys0.ji sysimg.jl","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"By default, any errors will cause Julia to exit, even under gdb. To catch an error \"in the act\", set a breakpoint in jl_error (there are several other useful spots, for specific kinds of failures, including: jl_too_few_args, jl_too_many_args, and jl_throw).","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Once an error is caught, a useful technique is to walk up the stack and examine the function by inspecting the related call to jl_apply. To take a real-world example:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Breakpoint 1, jl_throw (e=0x7ffdf42de400) at task.c:802\n802 {\n(gdb) p jl_(e)\nErrorException(\"auto_unbox: unable to determine argument type\")\n$2 = void\n(gdb) bt 10\n#0 jl_throw (e=0x7ffdf42de400) at task.c:802\n#1 0x00007ffff65412fe in jl_error (str=0x7ffde56be000 <_j_str267> \"auto_unbox:\n unable to determine argument type\")\n at builtins.c:39\n#2 0x00007ffde56bd01a in julia_convert_16886 ()\n#3 0x00007ffff6541154 in jl_apply (f=0x7ffdf367f630, args=0x7fffffffc2b0, nargs=2) at julia.h:1281\n...","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"The most recent jl_apply is at frame #3, so we can go back there and look at the AST for the function julia_convert_16886. This is the uniqued name for some method of convert. f in this frame is a jl_function_t*, so we can look at the type signature, if any, from the specTypes field:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) f 3\n#3 0x00007ffff6541154 in jl_apply (f=0x7ffdf367f630, args=0x7fffffffc2b0, nargs=2) at julia.h:1281\n1281 return f->fptr((jl_value_t*)f, args, nargs);\n(gdb) p f->linfo->specTypes\n$4 = (jl_tupletype_t *) 0x7ffdf39b1030\n(gdb) p jl_( f->linfo->specTypes )\nTuple{Type{Float32}, Float64} # <-- type signature for julia_convert_16886","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Then, we can look at the AST for this function:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) p jl_( jl_uncompress_ast(f->linfo, f->linfo->ast) )\nExpr(:lambda, Array{Any, 1}[:#s29, :x], Array{Any, 1}[Array{Any, 1}[], Array{Any, 1}[Array{Any, 1}[:#s29, :Any, 0], Array{Any, 1}[:x, :Any, 0]], Array{Any, 1}[], 0], Expr(:body,\nExpr(:line, 90, :float.jl)::Any,\nExpr(:return, Expr(:call, :box, :Float32, Expr(:call, :fptrunc, :Float32, :x)::Any)::Any)::Any)::Any)::Any","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Finally, and perhaps most usefully, we can force the function to be recompiled in order to step through the codegen process. To do this, clear the cached functionObject from the jl_lamdbda_info_t*:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) p f->linfo->functionObject\n$8 = (void *) 0x1289d070\n(gdb) set f->linfo->functionObject = NULL","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Then, set a breakpoint somewhere useful (e.g. emit_function, emit_expr, emit_call, etc.), and run codegen:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) p jl_compile(f)\n... # your breakpoint here","category":"page"},{"location":"devdocs/debuggingtips/#Debugging-precompilation-errors","page":"gdb debugging tips","title":"Debugging precompilation errors","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Module precompilation spawns a separate Julia process to precompile each module. Setting a breakpoint or catching failures in a precompile worker requires attaching a debugger to the worker. The easiest approach is to set the debugger watch for new process launches matching a given name. For example:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(gdb) attach -w -n julia-debug","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"or:","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"(lldb) process attach -w -n julia-debug","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Then run a script/command to start precompilation. As described earlier, use conditional breakpoints in the parent process to catch specific file-loading events and narrow the debugging window. (some operating systems may require alternative approaches, such as following each fork from the parent process)","category":"page"},{"location":"devdocs/debuggingtips/#Mozilla's-Record-and-Replay-Framework-(rr)","page":"gdb debugging tips","title":"Mozilla's Record and Replay Framework (rr)","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"Julia now works out of the box with rr, the lightweight recording and deterministic debugging framework from Mozilla. This allows you to replay the trace of an execution deterministically. The replayed execution's address spaces, register contents, syscall data etc are exactly the same in every run.","category":"page"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"A recent version of rr (3.1.0 or higher) is required.","category":"page"},{"location":"devdocs/debuggingtips/#Reproducing-concurrency-bugs-with-rr","page":"gdb debugging tips","title":"Reproducing concurrency bugs with rr","text":"","category":"section"},{"location":"devdocs/debuggingtips/","page":"gdb debugging tips","title":"gdb debugging tips","text":"rr simulates a single-threaded machine by default. In order to debug concurrent code you can use rr record --chaos which will cause rr to simulate between one to eight cores, chosen randomly. You might therefore want to set JULIA_NUM_THREADS=8 and rerun your code under rr until you have caught your bug.","category":"page"},{"location":"manual/stacktraces/#Stack-Traces","page":"Stack Traces","title":"Stack Traces","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"The StackTraces module provides simple stack traces that are both human readable and easy to use programmatically.","category":"page"},{"location":"manual/stacktraces/#Viewing-a-stack-trace","page":"Stack Traces","title":"Viewing a stack trace","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"The primary function used to obtain a stack trace is stacktrace:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"6-element Array{Base.StackTraces.StackFrame,1}:\n top-level scope\n eval at boot.jl:317 [inlined]\n eval(::Module, ::Expr) at REPL.jl:5\n eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n macro expansion at REPL.jl:116 [inlined]\n (::getfield(REPL, Symbol(\"##28#29\")){REPL.REPLBackend})() at event.jl:92","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Calling stacktrace() returns a vector of StackTraces.StackFrame s. For ease of use, the alias StackTraces.StackTrace can be used in place of Vector{StackFrame}. (Examples with [...] indicate that output may vary depending on how the code is run.)","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> example() = stacktrace()\nexample (generic function with 1 method)\n\njulia> example()\n7-element Array{Base.StackTraces.StackFrame,1}:\n example() at REPL[1]:1\n top-level scope\n eval at boot.jl:317 [inlined]\n[...]\n\njulia> @noinline child() = stacktrace()\nchild (generic function with 1 method)\n\njulia> @noinline parent() = child()\nparent (generic function with 1 method)\n\njulia> grandparent() = parent()\ngrandparent (generic function with 1 method)\n\njulia> grandparent()\n9-element Array{Base.StackTraces.StackFrame,1}:\n child() at REPL[3]:1\n parent() at REPL[4]:1\n grandparent() at REPL[5]:1\n[...]","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Note that when calling stacktrace() you'll typically see a frame with eval at boot.jl. When calling stacktrace() from the REPL you'll also have a few extra frames in the stack from REPL.jl, usually looking something like this:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> example() = stacktrace()\nexample (generic function with 1 method)\n\njulia> example()\n7-element Array{Base.StackTraces.StackFrame,1}:\n example() at REPL[1]:1\n top-level scope\n eval at boot.jl:317 [inlined]\n eval(::Module, ::Expr) at REPL.jl:5\n eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n macro expansion at REPL.jl:116 [inlined]\n (::getfield(REPL, Symbol(\"##28#29\")){REPL.REPLBackend})() at event.jl:92","category":"page"},{"location":"manual/stacktraces/#Extracting-useful-information","page":"Stack Traces","title":"Extracting useful information","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Each StackTraces.StackFrame contains the function name, file name, line number, lambda info, a flag indicating whether the frame has been inlined, a flag indicating whether it is a C function (by default C functions do not appear in the stack trace), and an integer representation of the pointer returned by backtrace:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> frame = stacktrace()[3]\neval(::Module, ::Expr) at REPL.jl:5\n\njulia> frame.func\n:eval\n\njulia> frame.file\nSymbol(\"~/julia/usr/share/julia/stdlib/v0.7/REPL/src/REPL.jl\")\n\njulia> frame.line\n5\n\njulia> frame.linfo\nMethodInstance for eval(::Module, ::Expr)\n\njulia> frame.inlined\nfalse\n\njulia> frame.from_c\nfalse\n\njulia> frame.pointer\n0x00007f92d6293171","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"This makes stack trace information available programmatically for logging, error handling, and more.","category":"page"},{"location":"manual/stacktraces/#Error-handling","page":"Stack Traces","title":"Error handling","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"While having easy access to information about the current state of the callstack can be helpful in many places, the most obvious application is in error handling and debugging.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> @noinline bad_function() = undeclared_variable\nbad_function (generic function with 1 method)\n\njulia> @noinline example() = try\n bad_function()\n catch\n stacktrace()\n end\nexample (generic function with 1 method)\n\njulia> example()\n7-element Array{Base.StackTraces.StackFrame,1}:\n example() at REPL[2]:4\n top-level scope\n eval at boot.jl:317 [inlined]\n[...]","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"You may notice that in the example above the first stack frame points at line 4, where stacktrace is called, rather than line 2, where bad_function is called, and bad_function's frame is missing entirely. This is understandable, given that stacktrace is called from the context of the catch. While in this example it's fairly easy to find the actual source of the error, in complex cases tracking down the source of the error becomes nontrivial.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"This can be remedied by passing the result of catch_backtrace to stacktrace. Instead of returning callstack information for the current context, catch_backtrace returns stack information for the context of the most recent exception:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> @noinline bad_function() = undeclared_variable\nbad_function (generic function with 1 method)\n\njulia> @noinline example() = try\n bad_function()\n catch\n stacktrace(catch_backtrace())\n end\nexample (generic function with 1 method)\n\njulia> example()\n8-element Array{Base.StackTraces.StackFrame,1}:\n bad_function() at REPL[1]:1\n example() at REPL[2]:2\n[...]","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Notice that the stack trace now indicates the appropriate line number and the missing frame.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> @noinline child() = error(\"Whoops!\")\nchild (generic function with 1 method)\n\njulia> @noinline parent() = child()\nparent (generic function with 1 method)\n\njulia> @noinline function grandparent()\n try\n parent()\n catch err\n println(\"ERROR: \", err.msg)\n stacktrace(catch_backtrace())\n end\n end\ngrandparent (generic function with 1 method)\n\njulia> grandparent()\nERROR: Whoops!\n10-element Array{Base.StackTraces.StackFrame,1}:\n error at error.jl:33 [inlined]\n child() at REPL[1]:1\n parent() at REPL[2]:1\n grandparent() at REPL[3]:3\n[...]","category":"page"},{"location":"manual/stacktraces/#Exception-stacks-and-[current_exceptions](@ref)","page":"Stack Traces","title":"Exception stacks and current_exceptions","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"compat: Julia 1.1\nException stacks requires at least Julia 1.1.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"While handling an exception further exceptions may be thrown. It can be useful to inspect all these exceptions to identify the root cause of a problem. The julia runtime supports this by pushing each exception onto an internal exception stack as it occurs. When the code exits a catch normally, any exceptions which were pushed onto the stack in the associated try are considered to be successfully handled and are removed from the stack.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"The stack of current exceptions can be accessed using the current_exceptions function. For example,","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> try\n error(\"(A) The root cause\")\n catch\n try\n error(\"(B) An exception while handling the exception\")\n catch\n for (exc, bt) in current_exceptions()\n showerror(stdout, exc, bt)\n println(stdout)\n end\n end\n end\n(A) The root cause\nStacktrace:\n [1] error(::String) at error.jl:33\n [2] top-level scope at REPL[7]:2\n [3] eval(::Module, ::Any) at boot.jl:319\n [4] eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n [5] macro expansion at REPL.jl:117 [inlined]\n [6] (::getfield(REPL, Symbol(\"##26#27\")){REPL.REPLBackend})() at task.jl:259\n(B) An exception while handling the exception\nStacktrace:\n [1] error(::String) at error.jl:33\n [2] top-level scope at REPL[7]:5\n [3] eval(::Module, ::Any) at boot.jl:319\n [4] eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n [5] macro expansion at REPL.jl:117 [inlined]\n [6] (::getfield(REPL, Symbol(\"##26#27\")){REPL.REPLBackend})() at task.jl:259","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"In this example the root cause exception (A) is first on the stack, with a further exception (B) following it. After exiting both catch blocks normally (i.e., without throwing a further exception) all exceptions are removed from the stack and are no longer accessible.","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"The exception stack is stored on the Task where the exceptions occurred. When a task fails with uncaught exceptions, current_exceptions(task) may be used to inspect the exception stack for that task.","category":"page"},{"location":"manual/stacktraces/#Comparison-with-[backtrace](@ref)","page":"Stack Traces","title":"Comparison with backtrace","text":"","category":"section"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"A call to backtrace returns a vector of Union{Ptr{Nothing}, Base.InterpreterIP}, which may then be passed into stacktrace for translation:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> trace = backtrace()\n18-element Array{Union{Ptr{Nothing}, Base.InterpreterIP},1}:\n Ptr{Nothing} @0x00007fd8734c6209\n Ptr{Nothing} @0x00007fd87362b342\n Ptr{Nothing} @0x00007fd87362c136\n Ptr{Nothing} @0x00007fd87362c986\n Ptr{Nothing} @0x00007fd87362d089\n Base.InterpreterIP(CodeInfo(:(begin\n Core.SSAValue(0) = backtrace()\n trace = Core.SSAValue(0)\n return Core.SSAValue(0)\n end)), 0x0000000000000000)\n Ptr{Nothing} @0x00007fd87362e4cf\n[...]\n\njulia> stacktrace(trace)\n6-element Array{Base.StackTraces.StackFrame,1}:\n top-level scope\n eval at boot.jl:317 [inlined]\n eval(::Module, ::Expr) at REPL.jl:5\n eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n macro expansion at REPL.jl:116 [inlined]\n (::getfield(REPL, Symbol(\"##28#29\")){REPL.REPLBackend})() at event.jl:92","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Notice that the vector returned by backtrace had 18 elements, while the vector returned by stacktrace only has 6. This is because, by default, stacktrace removes any lower-level C functions from the stack. If you want to include stack frames from C calls, you can do it like this:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> stacktrace(trace, true)\n21-element Array{Base.StackTraces.StackFrame,1}:\n jl_apply_generic at gf.c:2167\n do_call at interpreter.c:324\n eval_value at interpreter.c:416\n eval_body at interpreter.c:559\n jl_interpret_toplevel_thunk_callback at interpreter.c:798\n top-level scope\n jl_interpret_toplevel_thunk at interpreter.c:807\n jl_toplevel_eval_flex at toplevel.c:856\n jl_toplevel_eval_in at builtins.c:624\n eval at boot.jl:317 [inlined]\n eval(::Module, ::Expr) at REPL.jl:5\n jl_apply_generic at gf.c:2167\n eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85\n jl_apply_generic at gf.c:2167\n macro expansion at REPL.jl:116 [inlined]\n (::getfield(REPL, Symbol(\"##28#29\")){REPL.REPLBackend})() at event.jl:92\n jl_fptr_trampoline at gf.c:1838\n jl_apply_generic at gf.c:2167\n jl_apply at julia.h:1540 [inlined]\n start_task at task.c:268\n ip:0xffffffffffffffff","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"Individual pointers returned by backtrace can be translated into StackTraces.StackFrame s by passing them into StackTraces.lookup:","category":"page"},{"location":"manual/stacktraces/","page":"Stack Traces","title":"Stack Traces","text":"julia> pointer = backtrace()[1];\n\njulia> frame = StackTraces.lookup(pointer)\n1-element Array{Base.StackTraces.StackFrame,1}:\n jl_apply_generic at gf.c:2167\n\njulia> println(\"The top frame is from $(frame[1].func)!\")\nThe top frame is from jl_apply_generic!","category":"page"},{"location":"devdocs/external_profilers/#External-Profiler-Support","page":"External Profiler Support","title":"External Profiler Support","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Julia provides explicit support for some external tracing profilers, enabling you to obtain a high-level overview of the runtime's execution behavior.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The currently supported profilers are:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Tracy\nIntel VTune (ITTAPI)","category":"page"},{"location":"devdocs/external_profilers/#Adding-New-Zones","page":"External Profiler Support","title":"Adding New Zones","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To add new zones, use the JL_TIMING macro. You can find numerous examples throughout the codebase by searching for JL_TIMING. To add a new type of zone you add it to JL_TIMING_OWNERS (and possibly JL_TIMING_EVENTS).","category":"page"},{"location":"devdocs/external_profilers/#Dynamically-Enabling-and-Disabling-Zones","page":"External Profiler Support","title":"Dynamically Enabling and Disabling Zones","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The JULIA_TIMING_SUBSYSTEMS environment variable allows you to enable or disable zones for a specific Julia run. For instance, setting the variable to +GC,-INFERENCE will enable the GC zones and disable the INFERENCE zones.","category":"page"},{"location":"devdocs/external_profilers/#Tracy-Profiler","page":"External Profiler Support","title":"Tracy Profiler","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Tracy is a flexible profiler that can be optionally integrated with Julia.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"A typical Tracy session might look like this:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"(Image: Typical Tracy usage)","category":"page"},{"location":"devdocs/external_profilers/#Building-Julia-with-Tracy","page":"External Profiler Support","title":"Building Julia with Tracy","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To enable Tracy integration, build Julia with the extra option WITH_TRACY=1 in the Make.user file.","category":"page"},{"location":"devdocs/external_profilers/#Installing-the-Tracy-Profile-Viewer","page":"External Profiler Support","title":"Installing the Tracy Profile Viewer","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The easiest way to obtain the profile viewer is by adding the TracyProfiler_jll package and launching the profiler with:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"run(TracyProfiler_jll.tracy())","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"note: Note\nOn macOS, you may want to set the TRACY_DPI_SCALE environment variable to 1.0 if the UI elements in the profiler appear excessively large.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To run a \"headless\" instance that saves the trace to disk, use","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"run(`$(TracyProfiler_jll.capture()) -o mytracefile.tracy`)","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"instead.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"For information on using the Tracy UI, refer to the Tracy manual.","category":"page"},{"location":"devdocs/external_profilers/#Profiling-Julia-with-Tracy","page":"External Profiler Support","title":"Profiling Julia with Tracy","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"A typical workflow for profiling Julia with Tracy involves starting Julia using:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"JULIA_WAIT_FOR_TRACY=1 ./julia -e '...'","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The environment variable ensures that Julia waits until it has successfully connected to the Tracy profiler before continuing execution. Afterward, use the Tracy profiler UI, click Connect, and Julia execution should resume and profiling should start.","category":"page"},{"location":"devdocs/external_profilers/#Profiling-package-precompilation-with-Tracy","page":"External Profiler Support","title":"Profiling package precompilation with Tracy","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To profile a package precompilation process it is easiest to explicitly call into Base.compilecache with the package you want to precompile:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"pkg = Base.identify_package(\"SparseArrays\")\nwithenv(\"JULIA_WAIT_FOR_TRACY\" => 1, \"TRACY_PORT\" => 9001) do\n Base.compilecache(pkg)\nend","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Here, we use a custom port for tracy which makes it easier to find the correct client in the Tracy UI to connect to.","category":"page"},{"location":"devdocs/external_profilers/#Adding-metadata-to-zones","page":"External Profiler Support","title":"Adding metadata to zones","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The various jl_timing_show_* and jl_timing_printf functions can be used to attach a string (or strings) to a zone. For example, the trace zone for inference shows the method instance that is being inferred.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"The TracyCZoneColor function can be used to set the color of a certain zone. Search through the codebase to see how it is used.","category":"page"},{"location":"devdocs/external_profilers/#Viewing-Tracy-files-in-your-browser","page":"External Profiler Support","title":"Viewing Tracy files in your browser","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Visit https://topolarity.github.io/trace-viewer/ for an (experimental) web viewer for Tracy traces.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"You can open a local .tracy file or provide a URL from the web (e.g. a file in a Github repo). If you load a trace file from the web, you can also share the page URL directly with others, enabling them to view the same trace.","category":"page"},{"location":"devdocs/external_profilers/#Enabling-stack-trace-samples","page":"External Profiler Support","title":"Enabling stack trace samples","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"To enable call stack sampling in Tracy, build Julia with these options in your Make.user file:","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"WITH_TRACY := 1\nWITH_TRACY_CALLSTACKS := 1\nUSE_BINARYBUILDER_LIBTRACYCLIENT := 0","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"You may also need to run make -C deps clean-libtracyclient to force a re-build of Tracy.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"This feature has a significant impact on trace size and profiling overhead, so it is recommended to leave call stack sampling off when possible, especially if you intend to share your trace files online.","category":"page"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"Note that the Julia JIT runtime does not yet have integration for Tracy's symbolification, so Julia functions will typically be unknown in these stack traces.","category":"page"},{"location":"devdocs/external_profilers/#Intel-VTune-(ITTAPI)-Profiler","page":"External Profiler Support","title":"Intel VTune (ITTAPI) Profiler","text":"","category":"section"},{"location":"devdocs/external_profilers/","page":"External Profiler Support","title":"External Profiler Support","text":"This section is yet to be written.","category":"page"},{"location":"base/collections/#Collections-and-Data-Structures","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"","category":"section"},{"location":"base/collections/#lib-collections-iteration","page":"Collections and Data Structures","title":"Iteration","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Sequential iteration is implemented by the iterate function. The general for loop:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"for i in iter # or \"for i = iter\"\n # body\nend","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"is translated into:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"next = iterate(iter)\nwhile next !== nothing\n (i, state) = next\n # body\n next = iterate(iter, state)\nend","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"The state object may be anything, and should be chosen appropriately for each iterable type. See the manual section on the iteration interface for more details about defining a custom iterable type.","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.iterate\nBase.IteratorSize\nBase.IteratorEltype","category":"page"},{"location":"base/collections/#Base.iterate","page":"Collections and Data Structures","title":"Base.iterate","text":"iterate(iter [, state]) -> Union{Nothing, Tuple{Any, Any}}\n\nAdvance the iterator to obtain the next element. If no elements remain, nothing should be returned. Otherwise, a 2-tuple of the next element and the new iteration state should be returned.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.IteratorSize","page":"Collections and Data Structures","title":"Base.IteratorSize","text":"IteratorSize(itertype::Type) -> IteratorSize\n\nGiven the type of an iterator, return one of the following values:\n\nSizeUnknown() if the length (number of elements) cannot be determined in advance.\nHasLength() if there is a fixed, finite length.\nHasShape{N}() if there is a known length plus a notion of multidimensional shape (as for an array). In this case N should give the number of dimensions, and the axes function is valid for the iterator.\nIsInfinite() if the iterator yields values forever.\n\nThe default value (for iterators that do not define this function) is HasLength(). This means that most iterators are assumed to implement length.\n\nThis trait is generally used to select between algorithms that pre-allocate space for their result, and algorithms that resize their result incrementally.\n\njulia> Base.IteratorSize(1:5)\nBase.HasShape{1}()\n\njulia> Base.IteratorSize((2,3))\nBase.HasLength()\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.IteratorEltype","page":"Collections and Data Structures","title":"Base.IteratorEltype","text":"IteratorEltype(itertype::Type) -> IteratorEltype\n\nGiven the type of an iterator, return one of the following values:\n\nEltypeUnknown() if the type of elements yielded by the iterator is not known in advance.\nHasEltype() if the element type is known, and eltype would return a meaningful value.\n\nHasEltype() is the default, since iterators are assumed to implement eltype.\n\nThis trait is generally used to select between algorithms that pre-allocate a specific type of result, and algorithms that pick a result type based on the types of yielded values.\n\njulia> Base.IteratorEltype(1:5)\nBase.HasEltype()\n\n\n\n\n\n","category":"type"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"AbstractRange\nUnitRange\nTuple\nNumber\nAbstractArray\nBitSet\nIdDict\nDict\nWeakKeyDict\nEachLine\nAbstractString\nSet\nPair\nNamedTuple","category":"page"},{"location":"base/collections/#Constructors-and-Types","page":"Collections and Data Structures","title":"Constructors and Types","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.AbstractRange\nBase.OrdinalRange\nBase.AbstractUnitRange\nBase.StepRange\nBase.UnitRange\nBase.LinRange","category":"page"},{"location":"base/collections/#Base.AbstractRange","page":"Collections and Data Structures","title":"Base.AbstractRange","text":"AbstractRange{T} <: AbstractVector{T}\n\nSupertype for linear ranges with elements of type T. UnitRange, LinRange and other types are subtypes of this.\n\nAll subtypes must define step. Thus LogRange is not a subtype of AbstractRange.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.OrdinalRange","page":"Collections and Data Structures","title":"Base.OrdinalRange","text":"OrdinalRange{T, S} <: AbstractRange{T}\n\nSupertype for ordinal ranges with elements of type T with spacing(s) of type S. The steps should be always-exact multiples of oneunit, and T should be a \"discrete\" type, which cannot have values smaller than oneunit. For example, Integer or Date types would qualify, whereas Float64 would not (since this type can represent values smaller than oneunit(Float64). UnitRange, StepRange, and other types are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.AbstractUnitRange","page":"Collections and Data Structures","title":"Base.AbstractUnitRange","text":"AbstractUnitRange{T} <: OrdinalRange{T, T}\n\nSupertype for ranges with a step size of oneunit(T) with elements of type T. UnitRange and other types are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.StepRange","page":"Collections and Data Structures","title":"Base.StepRange","text":"StepRange{T, S} <: OrdinalRange{T, S}\n\nRanges with elements of type T with spacing of type S. The step between each element is constant, and the range is defined in terms of a start and stop of type T and a step of type S. Neither T nor S should be floating point types. The syntax a:b:c with b != 0 and a, b, and c all integers creates a StepRange.\n\nExamples\n\njulia> collect(StepRange(1, Int8(2), 10))\n5-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n\njulia> typeof(StepRange(1, Int8(2), 10))\nStepRange{Int64, Int8}\n\njulia> typeof(1:3:6)\nStepRange{Int64, Int64}\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.UnitRange","page":"Collections and Data Structures","title":"Base.UnitRange","text":"UnitRange{T<:Real}\n\nA range parameterized by a start and stop of type T, filled with elements spaced by 1 from start until stop is exceeded. The syntax a:b with a and b both Integers creates a UnitRange.\n\nExamples\n\njulia> collect(UnitRange(2.3, 5.2))\n3-element Vector{Float64}:\n 2.3\n 3.3\n 4.3\n\njulia> typeof(1:10)\nUnitRange{Int64}\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.LinRange","page":"Collections and Data Structures","title":"Base.LinRange","text":"LinRange{T,L}\n\nA range with len linearly spaced elements between its start and stop. The size of the spacing is controlled by len, which must be an Integer.\n\nExamples\n\njulia> LinRange(1.5, 5.5, 9)\n9-element LinRange{Float64, Int64}:\n 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5\n\nCompared to using range, directly constructing a LinRange should have less overhead but won't try to correct for floating point errors:\n\njulia> collect(range(-0.1, 0.3, length=5))\n5-element Vector{Float64}:\n -0.1\n 0.0\n 0.1\n 0.2\n 0.3\n\njulia> collect(LinRange(-0.1, 0.3, 5))\n5-element Vector{Float64}:\n -0.1\n -1.3877787807814457e-17\n 0.09999999999999999\n 0.19999999999999998\n 0.3\n\nSee also Logrange for logarithmically spaced points.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#General-Collections","page":"Collections and Data Structures","title":"General Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.isempty\nBase.isdone\nBase.empty!\nBase.length\nBase.checked_length","category":"page"},{"location":"base/collections/#Base.isempty","page":"Collections and Data Structures","title":"Base.isempty","text":"isempty(collection) -> Bool\n\nDetermine whether a collection is empty (has no elements).\n\nwarning: Warning\nisempty(itr) may consume the next element of a stateful iterator itr unless an appropriate Base.isdone(itr) method is defined. Stateful iterators should implement isdone, but you may want to avoid using isempty when writing generic code which should support any iterator type.\n\nExamples\n\njulia> isempty([])\ntrue\n\njulia> isempty([1 2 3])\nfalse\n\n\n\n\n\nisempty(condition)\n\nReturn true if no tasks are waiting on the condition, false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.isdone","page":"Collections and Data Structures","title":"Base.isdone","text":"isdone(itr, [state]) -> Union{Bool, Missing}\n\nThis function provides a fast-path hint for iterator completion. This is useful for stateful iterators that want to avoid having elements consumed if they are not going to be exposed to the user (e.g. when checking for done-ness in isempty or zip).\n\nStateful iterators that want to opt into this feature should define an isdone method that returns true/false depending on whether the iterator is done or not. Stateless iterators need not implement this function.\n\nIf the result is missing, callers may go ahead and compute iterate(x, state) === nothing to compute a definite answer.\n\nSee also iterate, isempty\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.empty!","page":"Collections and Data Structures","title":"Base.empty!","text":"empty!(collection) -> collection\n\nRemove all elements from a collection.\n\nExamples\n\njulia> A = Dict(\"a\" => 1, \"b\" => 2)\nDict{String, Int64} with 2 entries:\n \"b\" => 2\n \"a\" => 1\n\njulia> empty!(A);\n\njulia> A\nDict{String, Int64}()\n\n\n\n\n\nempty!(c::Channel)\n\nEmpty a Channel c by calling empty! on the internal buffer. Return the empty channel.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.length","page":"Collections and Data Structures","title":"Base.length","text":"length(collection) -> Integer\n\nReturn the number of elements in the collection.\n\nUse lastindex to get the last valid index of an indexable collection.\n\nSee also: size, ndims, eachindex.\n\nExamples\n\njulia> length(1:5)\n5\n\njulia> length([1, 2, 3, 4])\n4\n\njulia> length([1 2; 3 4])\n4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.checked_length","page":"Collections and Data Structures","title":"Base.checked_length","text":"Base.checked_length(r)\n\nCalculates length(r), but may check for overflow errors where applicable when the result doesn't fit into Union{Integer(eltype(r)),Int}.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"AbstractRange\nUnitRange\nTuple\nNumber\nAbstractArray\nBitSet\nIdDict\nDict\nWeakKeyDict\nAbstractString\nSet\nNamedTuple","category":"page"},{"location":"base/collections/#Iterable-Collections","page":"Collections and Data Structures","title":"Iterable Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.in\nBase.:∉\nBase.hasfastin\nBase.eltype\nBase.indexin\nBase.unique\nBase.unique!\nBase.allunique\nBase.allequal\nBase.reduce(::Any, ::Any)\nBase.reduce(::Any, ::AbstractArray)\nBase.foldl(::Any, ::Any)\nBase.foldr(::Any, ::Any)\nBase.maximum\nBase.maximum!\nBase.minimum\nBase.minimum!\nBase.extrema\nBase.extrema!\nBase.argmax\nBase.argmin\nBase.findmax\nBase.findmin\nBase.findmax!\nBase.findmin!\nBase.sum\nBase.sum!\nBase.prod\nBase.prod!\nBase.any(::Any)\nBase.any(::AbstractArray, ::Any)\nBase.any!\nBase.all(::Any)\nBase.all(::AbstractArray, ::Any)\nBase.all!\nBase.count\nBase.foreach\nBase.map\nBase.map!\nBase.mapreduce(::Any, ::Any, ::Any)\nBase.mapfoldl(::Any, ::Any, ::Any)\nBase.mapfoldr(::Any, ::Any, ::Any)\nBase.first\nBase.last\nBase.front\nBase.tail\nBase.step\nBase.collect(::Any)\nBase.collect(::Type, ::Any)\nBase.filter\nBase.filter!\nBase.replace(::Any, ::Pair...)\nBase.replace(::Base.Callable, ::Any)\nBase.replace!\nBase.rest\nBase.split_rest","category":"page"},{"location":"base/collections/#Base.in","page":"Collections and Data Structures","title":"Base.in","text":"in(item, collection) -> Bool\n∈(item, collection) -> Bool\n\nDetermine whether an item is in the given collection, in the sense that it is == to one of the values generated by iterating over the collection. Return a Bool value, except if item is missing or collection contains missing but not item, in which case missing is returned (three-valued logic, matching the behavior of any and ==).\n\nSome collections follow a slightly different definition. For example, Sets check whether the item isequal to one of the elements; Dicts look for key=>value pairs, and the key is compared using isequal.\n\nTo test for the presence of a key in a dictionary, use haskey or k in keys(dict). For the collections mentioned above, the result is always a Bool.\n\nWhen broadcasting with in.(items, collection) or items .∈ collection, both items and collection are broadcasted over, which is often not what is intended. For example, if both arguments are vectors (and the dimensions match), the result is a vector indicating whether each value in collection items is in the value at the corresponding position in collection. To get a vector indicating whether each value in items is in collection, wrap collection in a tuple or a Ref like this: in.(items, Ref(collection)) or items .∈ Ref(collection).\n\nSee also: ∉, insorted, contains, occursin, issubset.\n\nExamples\n\njulia> a = 1:3:20\n1:3:19\n\njulia> 4 in a\ntrue\n\njulia> 5 in a\nfalse\n\njulia> missing in [1, 2]\nmissing\n\njulia> 1 in [2, missing]\nmissing\n\njulia> 1 in [1, missing]\ntrue\n\njulia> missing in Set([1, 2])\nfalse\n\njulia> (1=>missing) in Dict(1=>10, 2=>20)\nmissing\n\njulia> [1, 2] .∈ [2, 3]\n2-element BitVector:\n 0\n 0\n\njulia> [1, 2] .∈ ([2, 3],)\n2-element BitVector:\n 0\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.:∉","page":"Collections and Data Structures","title":"Base.:∉","text":"∉(item, collection) -> Bool\n∌(collection, item) -> Bool\n\nNegation of ∈ and ∋, i.e. checks that item is not in collection.\n\nWhen broadcasting with items .∉ collection, both items and collection are broadcasted over, which is often not what is intended. For example, if both arguments are vectors (and the dimensions match), the result is a vector indicating whether each value in collection items is not in the value at the corresponding position in collection. To get a vector indicating whether each value in items is not in collection, wrap collection in a tuple or a Ref like this: items .∉ Ref(collection).\n\nExamples\n\njulia> 1 ∉ 2:4\ntrue\n\njulia> 1 ∉ 1:3\nfalse\n\njulia> [1, 2] .∉ [2, 3]\n2-element BitVector:\n 1\n 1\n\njulia> [1, 2] .∉ ([2, 3],)\n2-element BitVector:\n 1\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.hasfastin","page":"Collections and Data Structures","title":"Base.hasfastin","text":"Base.hasfastin(T)\n\nDetermine whether the computation x ∈ collection where collection::T can be considered as a \"fast\" operation (typically constant or logarithmic complexity). The definition hasfastin(x) = hasfastin(typeof(x)) is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.\n\nThe default for hasfastin(T) is true for subtypes of AbstractSet, AbstractDict and AbstractRange and false otherwise.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.eltype","page":"Collections and Data Structures","title":"Base.eltype","text":"eltype(type)\n\nDetermine the type of the elements generated by iterating a collection of the given type. For dictionary types, this will be a Pair{KeyType,ValType}. The definition eltype(x) = eltype(typeof(x)) is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types.\n\nSee also: keytype, typeof.\n\nExamples\n\njulia> eltype(fill(1f0, (2,2)))\nFloat32\n\njulia> eltype(fill(0x1, (2,2)))\nUInt8\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.indexin","page":"Collections and Data Structures","title":"Base.indexin","text":"indexin(a, b)\n\nReturn an array containing the first index in b for each value in a that is a member of b. The output array contains nothing wherever a is not a member of b.\n\nSee also: sortperm, findfirst.\n\nExamples\n\njulia> a = ['a', 'b', 'c', 'b', 'd', 'a'];\n\njulia> b = ['a', 'b', 'c'];\n\njulia> indexin(a, b)\n6-element Vector{Union{Nothing, Int64}}:\n 1\n 2\n 3\n 2\n nothing\n 1\n\njulia> indexin(b, a)\n3-element Vector{Union{Nothing, Int64}}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.unique","page":"Collections and Data Structures","title":"Base.unique","text":"unique(itr)\n\nReturn an array containing only the unique elements of collection itr, as determined by isequal and hash, in the order that the first of each set of equivalent elements originally appears. The element type of the input is preserved.\n\nSee also: unique!, allunique, allequal.\n\nExamples\n\njulia> unique([1, 2, 6, 2])\n3-element Vector{Int64}:\n 1\n 2\n 6\n\njulia> unique(Real[1, 1.0, 2])\n2-element Vector{Real}:\n 1\n 2\n\n\n\n\n\nunique(f, itr)\n\nReturn an array containing one value from itr for each unique value produced by f applied to elements of itr.\n\nExamples\n\njulia> unique(x -> x^2, [1, -1, 3, -3, 4])\n3-element Vector{Int64}:\n 1\n 3\n 4\n\nThis functionality can also be used to extract the indices of the first occurrences of unique elements in an array:\n\njulia> a = [3.1, 4.2, 5.3, 3.1, 3.1, 3.1, 4.2, 1.7];\n\njulia> i = unique(i -> a[i], eachindex(a))\n4-element Vector{Int64}:\n 1\n 2\n 3\n 8\n\njulia> a[i]\n4-element Vector{Float64}:\n 3.1\n 4.2\n 5.3\n 1.7\n\njulia> a[i] == unique(a)\ntrue\n\n\n\n\n\nunique(A::AbstractArray; dims::Int)\n\nReturn unique regions of A along dimension dims.\n\nExamples\n\njulia> A = map(isodd, reshape(Vector(1:8), (2,2,2)))\n2×2×2 Array{Bool, 3}:\n[:, :, 1] =\n 1 1\n 0 0\n\n[:, :, 2] =\n 1 1\n 0 0\n\njulia> unique(A)\n2-element Vector{Bool}:\n 1\n 0\n\njulia> unique(A, dims=2)\n2×1×2 Array{Bool, 3}:\n[:, :, 1] =\n 1\n 0\n\n[:, :, 2] =\n 1\n 0\n\njulia> unique(A, dims=3)\n2×2×1 Array{Bool, 3}:\n[:, :, 1] =\n 1 1\n 0 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.unique!","page":"Collections and Data Structures","title":"Base.unique!","text":"unique!(f, A::AbstractVector)\n\nSelects one value from A for each unique value produced by f applied to elements of A, then return the modified A.\n\ncompat: Julia 1.1\nThis method is available as of Julia 1.1.\n\nExamples\n\njulia> unique!(x -> x^2, [1, -1, 3, -3, 4])\n3-element Vector{Int64}:\n 1\n 3\n 4\n\njulia> unique!(n -> n%3, [5, 1, 8, 9, 3, 4, 10, 7, 2, 6])\n3-element Vector{Int64}:\n 5\n 1\n 9\n\njulia> unique!(iseven, [2, 3, 5, 7, 9])\n2-element Vector{Int64}:\n 2\n 3\n\n\n\n\n\nunique!(A::AbstractVector)\n\nRemove duplicate items as determined by isequal and hash, then return the modified A. unique! will return the elements of A in the order that they occur. If you do not care about the order of the returned data, then calling (sort!(A); unique!(A)) will be much more efficient as long as the elements of A can be sorted.\n\nExamples\n\njulia> unique!([1, 1, 1])\n1-element Vector{Int64}:\n 1\n\njulia> A = [7, 3, 2, 3, 7, 5];\n\njulia> unique!(A)\n4-element Vector{Int64}:\n 7\n 3\n 2\n 5\n\njulia> B = [7, 6, 42, 6, 7, 42];\n\njulia> sort!(B); # unique! is able to process sorted data much more efficiently.\n\njulia> unique!(B)\n3-element Vector{Int64}:\n 6\n 7\n 42\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.allunique","page":"Collections and Data Structures","title":"Base.allunique","text":"allunique(itr) -> Bool\nallunique(f, itr) -> Bool\n\nReturn true if all values from itr are distinct when compared with isequal. Or if all of [f(x) for x in itr] are distinct, for the second method.\n\nNote that allunique(f, itr) may call f fewer than length(itr) times. The precise number of calls is regarded as an implementation detail.\n\nallunique may use a specialized implementation when the input is sorted.\n\nSee also: unique, issorted, allequal.\n\ncompat: Julia 1.11\nThe method allunique(f, itr) requires at least Julia 1.11.\n\nExamples\n\njulia> allunique([1, 2, 3])\ntrue\n\njulia> allunique([1, 2, 1, 2])\nfalse\n\njulia> allunique(Real[1, 1.0, 2])\nfalse\n\njulia> allunique([NaN, 2.0, NaN, 4.0])\nfalse\n\njulia> allunique(abs, [1, -1, 2])\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.allequal","page":"Collections and Data Structures","title":"Base.allequal","text":"allequal(itr) -> Bool\nallequal(f, itr) -> Bool\n\nReturn true if all values from itr are equal when compared with isequal. Or if all of [f(x) for x in itr] are equal, for the second method.\n\nNote that allequal(f, itr) may call f fewer than length(itr) times. The precise number of calls is regarded as an implementation detail.\n\nSee also: unique, allunique.\n\ncompat: Julia 1.8\nThe allequal function requires at least Julia 1.8.\n\ncompat: Julia 1.11\nThe method allequal(f, itr) requires at least Julia 1.11.\n\nExamples\n\njulia> allequal([])\ntrue\n\njulia> allequal([1])\ntrue\n\njulia> allequal([1, 1])\ntrue\n\njulia> allequal([1, 2])\nfalse\n\njulia> allequal(Dict(:a => 1, :b => 1))\nfalse\n\njulia> allequal(abs2, [1, -1])\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.reduce-Tuple{Any, Any}","page":"Collections and Data Structures","title":"Base.reduce","text":"reduce(op, itr; [init])\n\nReduce the given collection itr with the given binary operator op. If provided, the initial value init must be a neutral element for op that will be returned for empty collections. It is unspecified whether init is used for non-empty collections.\n\nFor empty collections, providing init will be necessary, except for some special cases (e.g. when op is one of +, *, max, min, &, |) when Julia can determine the neutral element of op.\n\nReductions for certain commonly-used operators may have special implementations, and should be used instead: maximum(itr), minimum(itr), sum(itr), prod(itr), any(itr), all(itr). There are efficient methods for concatenating certain arrays of arrays by calling reduce(vcat, arr) or reduce(hcat, arr).\n\nThe associativity of the reduction is implementation dependent. This means that you can't use non-associative operations like - because it is undefined whether reduce(-,[1,2,3]) should be evaluated as (1-2)-3 or 1-(2-3). Use foldl or foldr instead for guaranteed left or right associativity.\n\nSome operations accumulate error. Parallelism will be easier if the reduction can be executed in groups. Future versions of Julia might change the algorithm. Note that the elements are not reordered if you use an ordered collection.\n\nExamples\n\njulia> reduce(*, [2; 3; 4])\n24\n\njulia> reduce(*, [2; 3; 4]; init=-1)\n-24\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.reduce-Tuple{Any, AbstractArray}","page":"Collections and Data Structures","title":"Base.reduce","text":"reduce(f, A::AbstractArray; dims=:, [init])\n\nReduce 2-argument function f along dimensions of A. dims is a vector specifying the dimensions to reduce, and the keyword argument init is the initial value to use in the reductions. For +, *, max and min the init argument is optional.\n\nThe associativity of the reduction is implementation-dependent; if you need a particular associativity, e.g. left-to-right, you should write your own loop or consider using foldl or foldr. See documentation for reduce.\n\nExamples\n\njulia> a = reshape(Vector(1:16), (4,4))\n4×4 Matrix{Int64}:\n 1 5 9 13\n 2 6 10 14\n 3 7 11 15\n 4 8 12 16\n\njulia> reduce(max, a, dims=2)\n4×1 Matrix{Int64}:\n 13\n 14\n 15\n 16\n\njulia> reduce(max, a, dims=1)\n1×4 Matrix{Int64}:\n 4 8 12 16\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.foldl-Tuple{Any, Any}","page":"Collections and Data Structures","title":"Base.foldl","text":"foldl(op, itr; [init])\n\nLike reduce, but with guaranteed left associativity. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.\n\nSee also mapfoldl, foldr, accumulate.\n\nExamples\n\njulia> foldl(=>, 1:4)\n((1 => 2) => 3) => 4\n\njulia> foldl(=>, 1:4; init=0)\n(((0 => 1) => 2) => 3) => 4\n\njulia> accumulate(=>, (1,2,3,4))\n(1, 1 => 2, (1 => 2) => 3, ((1 => 2) => 3) => 4)\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.foldr-Tuple{Any, Any}","page":"Collections and Data Structures","title":"Base.foldr","text":"foldr(op, itr; [init])\n\nLike reduce, but with guaranteed right associativity. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.\n\nExamples\n\njulia> foldr(=>, 1:4)\n1 => (2 => (3 => 4))\n\njulia> foldr(=>, 1:4; init=0)\n1 => (2 => (3 => (4 => 0)))\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.maximum","page":"Collections and Data Structures","title":"Base.maximum","text":"maximum(f, itr; [init])\n\nReturn the largest result of calling function f on each element of itr.\n\nThe value returned for empty itr can be specified by init. It must be a neutral element for max (i.e. which is less than or equal to any other element) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> maximum(length, [\"Julion\", \"Julia\", \"Jule\"])\n6\n\njulia> maximum(length, []; init=-1)\n-1\n\njulia> maximum(sin, Real[]; init=-1.0) # good, since output of sin is >= -1\n-1.0\n\n\n\n\n\nmaximum(itr; [init])\n\nReturn the largest element in a collection.\n\nThe value returned for empty itr can be specified by init. It must be a neutral element for max (i.e. which is less than or equal to any other element) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> maximum(-20.5:10)\n9.5\n\njulia> maximum([1,2,3])\n3\n\njulia> maximum(())\nERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer\nStacktrace:\n[...]\n\njulia> maximum((); init=-Inf)\n-Inf\n\n\n\n\n\nmaximum(A::AbstractArray; dims)\n\nCompute the maximum value of an array over the given dimensions. See also the max(a,b) function to take the maximum of two or more arguments, which can be applied elementwise to arrays via max.(a,b).\n\nSee also: maximum!, extrema, findmax, argmax.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> maximum(A, dims=1)\n1×2 Matrix{Int64}:\n 3 4\n\njulia> maximum(A, dims=2)\n2×1 Matrix{Int64}:\n 2\n 4\n\n\n\n\n\nmaximum(f, A::AbstractArray; dims)\n\nCompute the maximum value by calling the function f on each element of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> maximum(abs2, A, dims=1)\n1×2 Matrix{Int64}:\n 9 16\n\njulia> maximum(abs2, A, dims=2)\n2×1 Matrix{Int64}:\n 4\n 16\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.maximum!","page":"Collections and Data Structures","title":"Base.maximum!","text":"maximum!(r, A)\n\nCompute the maximum value of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> maximum!([1; 1], A)\n2-element Vector{Int64}:\n 2\n 4\n\njulia> maximum!([1 1], A)\n1×2 Matrix{Int64}:\n 3 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.minimum","page":"Collections and Data Structures","title":"Base.minimum","text":"minimum(f, itr; [init])\n\nReturn the smallest result of calling function f on each element of itr.\n\nThe value returned for empty itr can be specified by init. It must be a neutral element for min (i.e. which is greater than or equal to any other element) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> minimum(length, [\"Julion\", \"Julia\", \"Jule\"])\n4\n\njulia> minimum(length, []; init=typemax(Int64))\n9223372036854775807\n\njulia> minimum(sin, Real[]; init=1.0) # good, since output of sin is <= 1\n1.0\n\n\n\n\n\nminimum(itr; [init])\n\nReturn the smallest element in a collection.\n\nThe value returned for empty itr can be specified by init. It must be a neutral element for min (i.e. which is greater than or equal to any other element) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> minimum(-20.5:10)\n-20.5\n\njulia> minimum([1,2,3])\n1\n\njulia> minimum([])\nERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer\nStacktrace:\n[...]\n\njulia> minimum([]; init=Inf)\nInf\n\n\n\n\n\nminimum(A::AbstractArray; dims)\n\nCompute the minimum value of an array over the given dimensions. See also the min(a,b) function to take the minimum of two or more arguments, which can be applied elementwise to arrays via min.(a,b).\n\nSee also: minimum!, extrema, findmin, argmin.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> minimum(A, dims=1)\n1×2 Matrix{Int64}:\n 1 2\n\njulia> minimum(A, dims=2)\n2×1 Matrix{Int64}:\n 1\n 3\n\n\n\n\n\nminimum(f, A::AbstractArray; dims)\n\nCompute the minimum value by calling the function f on each element of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> minimum(abs2, A, dims=1)\n1×2 Matrix{Int64}:\n 1 4\n\njulia> minimum(abs2, A, dims=2)\n2×1 Matrix{Int64}:\n 1\n 9\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.minimum!","page":"Collections and Data Structures","title":"Base.minimum!","text":"minimum!(r, A)\n\nCompute the minimum value of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> minimum!([1; 1], A)\n2-element Vector{Int64}:\n 1\n 3\n\njulia> minimum!([1 1], A)\n1×2 Matrix{Int64}:\n 1 2\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.extrema","page":"Collections and Data Structures","title":"Base.extrema","text":"extrema(itr; [init]) -> (mn, mx)\n\nCompute both the minimum mn and maximum mx element in a single pass, and return them as a 2-tuple.\n\nThe value returned for empty itr can be specified by init. It must be a 2-tuple whose first and second elements are neutral elements for min and max respectively (i.e. which are greater/less than or equal to any other element). As a consequence, when itr is empty the returned (mn, mx) tuple will satisfy mn ≥ mx. When init is specified it may be used even for non-empty itr.\n\ncompat: Julia 1.8\nKeyword argument init requires Julia 1.8 or later.\n\nExamples\n\njulia> extrema(2:10)\n(2, 10)\n\njulia> extrema([9,pi,4.5])\n(3.141592653589793, 9.0)\n\njulia> extrema([]; init = (Inf, -Inf))\n(Inf, -Inf)\n\n\n\n\n\nextrema(f, itr; [init]) -> (mn, mx)\n\nCompute both the minimum mn and maximum mx of f applied to each element in itr and return them as a 2-tuple. Only one pass is made over itr.\n\nThe value returned for empty itr can be specified by init. It must be a 2-tuple whose first and second elements are neutral elements for min and max respectively (i.e. which are greater/less than or equal to any other element). It is used for non-empty collections. Note: it implies that, for empty itr, the returned value (mn, mx) satisfies mn ≥ mx even though for non-empty itr it satisfies mn ≤ mx. This is a \"paradoxical\" but yet expected result.\n\ncompat: Julia 1.2\nThis method requires Julia 1.2 or later.\n\ncompat: Julia 1.8\nKeyword argument init requires Julia 1.8 or later.\n\nExamples\n\njulia> extrema(sin, 0:π)\n(0.0, 0.9092974268256817)\n\njulia> extrema(sin, Real[]; init = (1.0, -1.0)) # good, since -1 ≤ sin(::Real) ≤ 1\n(1.0, -1.0)\n\n\n\n\n\nextrema(A::AbstractArray; dims) -> Array{Tuple}\n\nCompute the minimum and maximum elements of an array over the given dimensions.\n\nSee also: minimum, maximum, extrema!.\n\nExamples\n\njulia> A = reshape(Vector(1:2:16), (2,2,2))\n2×2×2 Array{Int64, 3}:\n[:, :, 1] =\n 1 5\n 3 7\n\n[:, :, 2] =\n 9 13\n 11 15\n\njulia> extrema(A, dims = (1,2))\n1×1×2 Array{Tuple{Int64, Int64}, 3}:\n[:, :, 1] =\n (1, 7)\n\n[:, :, 2] =\n (9, 15)\n\n\n\n\n\nextrema(f, A::AbstractArray; dims) -> Array{Tuple}\n\nCompute the minimum and maximum of f applied to each element in the given dimensions of A.\n\ncompat: Julia 1.2\nThis method requires Julia 1.2 or later.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.extrema!","page":"Collections and Data Structures","title":"Base.extrema!","text":"extrema!(r, A)\n\nCompute the minimum and maximum value of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\ncompat: Julia 1.8\nThis method requires Julia 1.8 or later.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> extrema!([(1, 1); (1, 1)], A)\n2-element Vector{Tuple{Int64, Int64}}:\n (1, 2)\n (3, 4)\n\njulia> extrema!([(1, 1);; (1, 1)], A)\n1×2 Matrix{Tuple{Int64, Int64}}:\n (1, 3) (2, 4)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.argmax","page":"Collections and Data Structures","title":"Base.argmax","text":"argmax(r::AbstractRange)\n\nRanges can have multiple maximal elements. In that case argmax will return a maximal index, but not necessarily the first one.\n\n\n\n\n\nargmax(f, domain)\n\nReturn a value x from domain for which f(x) is maximised. If there are multiple maximal values for f(x) then the first one will be found.\n\ndomain must be a non-empty iterable.\n\nValues are compared with isless.\n\ncompat: Julia 1.7\nThis method requires Julia 1.7 or later.\n\nSee also argmin, findmax.\n\nExamples\n\njulia> argmax(abs, -10:5)\n-10\n\njulia> argmax(cos, 0:π/2:2π)\n0.0\n\n\n\n\n\nargmax(itr)\n\nReturn the index or key of the maximal element in a collection. If there are multiple maximal elements, then the first one will be returned.\n\nThe collection must not be empty.\n\nIndices are of the same type as those returned by keys(itr) and pairs(itr).\n\nValues are compared with isless.\n\nSee also: argmin, findmax.\n\nExamples\n\njulia> argmax([8, 0.1, -9, pi])\n1\n\njulia> argmax([1, 7, 7, 6])\n2\n\njulia> argmax([1, 7, 7, NaN])\n4\n\n\n\n\n\nargmax(A; dims) -> indices\n\nFor an array input, return the indices of the maximum elements over the given dimensions. NaN is treated as greater than all other values except missing.\n\nExamples\n\njulia> A = [1.0 2; 3 4]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> argmax(A, dims=1)\n1×2 Matrix{CartesianIndex{2}}:\n CartesianIndex(2, 1) CartesianIndex(2, 2)\n\njulia> argmax(A, dims=2)\n2×1 Matrix{CartesianIndex{2}}:\n CartesianIndex(1, 2)\n CartesianIndex(2, 2)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.argmin","page":"Collections and Data Structures","title":"Base.argmin","text":"argmin(r::AbstractRange)\n\nRanges can have multiple minimal elements. In that case argmin will return a minimal index, but not necessarily the first one.\n\n\n\n\n\nargmin(f, domain)\n\nReturn a value x from domain for which f(x) is minimised. If there are multiple minimal values for f(x) then the first one will be found.\n\ndomain must be a non-empty iterable.\n\nNaN is treated as less than all other values except missing.\n\ncompat: Julia 1.7\nThis method requires Julia 1.7 or later.\n\nSee also argmax, findmin.\n\nExamples\n\njulia> argmin(sign, -10:5)\n-10\n\njulia> argmin(x -> -x^3 + x^2 - 10, -5:5)\n5\n\njulia> argmin(acos, 0:0.1:1)\n1.0\n\n\n\n\n\nargmin(itr)\n\nReturn the index or key of the minimal element in a collection. If there are multiple minimal elements, then the first one will be returned.\n\nThe collection must not be empty.\n\nIndices are of the same type as those returned by keys(itr) and pairs(itr).\n\nNaN is treated as less than all other values except missing.\n\nSee also: argmax, findmin.\n\nExamples\n\njulia> argmin([8, 0.1, -9, pi])\n3\n\njulia> argmin([7, 1, 1, 6])\n2\n\njulia> argmin([7, 1, 1, NaN])\n4\n\n\n\n\n\nargmin(A; dims) -> indices\n\nFor an array input, return the indices of the minimum elements over the given dimensions. NaN is treated as less than all other values except missing.\n\nExamples\n\njulia> A = [1.0 2; 3 4]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> argmin(A, dims=1)\n1×2 Matrix{CartesianIndex{2}}:\n CartesianIndex(1, 1) CartesianIndex(1, 2)\n\njulia> argmin(A, dims=2)\n2×1 Matrix{CartesianIndex{2}}:\n CartesianIndex(1, 1)\n CartesianIndex(2, 1)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.findmax","page":"Collections and Data Structures","title":"Base.findmax","text":"findmax(f, domain) -> (f(x), index)\n\nReturn a pair of a value in the codomain (outputs of f) and the index or key of the corresponding value in the domain (inputs to f) such that f(x) is maximised. If there are multiple maximal points, then the first one will be returned.\n\ndomain must be a non-empty iterable supporting keys. Indices are of the same type as those returned by keys(domain).\n\nValues are compared with isless.\n\ncompat: Julia 1.7\nThis method requires Julia 1.7 or later.\n\nExamples\n\njulia> findmax(identity, 5:9)\n(9, 5)\n\njulia> findmax(-, 1:10)\n(-1, 1)\n\njulia> findmax(first, [(1, :a), (3, :b), (3, :c)])\n(3, 2)\n\njulia> findmax(cos, 0:π/2:2π)\n(1.0, 1)\n\n\n\n\n\nfindmax(itr) -> (x, index)\n\nReturn the maximal element of the collection itr and its index or key. If there are multiple maximal elements, then the first one will be returned. Values are compared with isless.\n\nIndices are of the same type as those returned by keys(itr) and pairs(itr).\n\nSee also: findmin, argmax, maximum.\n\nExamples\n\njulia> findmax([8, 0.1, -9, pi])\n(8.0, 1)\n\njulia> findmax([1, 7, 7, 6])\n(7, 2)\n\njulia> findmax([1, 7, 7, NaN])\n(NaN, 4)\n\n\n\n\n\nfindmax(A; dims) -> (maxval, index)\n\nFor an array input, returns the value and index of the maximum over the given dimensions. NaN is treated as greater than all other values except missing.\n\nExamples\n\njulia> A = [1.0 2; 3 4]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> findmax(A, dims=1)\n([3.0 4.0], CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(2, 2)])\n\njulia> findmax(A, dims=2)\n([2.0; 4.0;;], CartesianIndex{2}[CartesianIndex(1, 2); CartesianIndex(2, 2);;])\n\n\n\n\n\nfindmax(f, A; dims) -> (f(x), index)\n\nFor an array input, returns the value in the codomain and index of the corresponding value which maximize f over the given dimensions.\n\nExamples\n\njulia> A = [-1.0 1; -0.5 2]\n2×2 Matrix{Float64}:\n -1.0 1.0\n -0.5 2.0\n\njulia> findmax(abs2, A, dims=1)\n([1.0 4.0], CartesianIndex{2}[CartesianIndex(1, 1) CartesianIndex(2, 2)])\n\njulia> findmax(abs2, A, dims=2)\n([1.0; 4.0;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 2);;])\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.findmin","page":"Collections and Data Structures","title":"Base.findmin","text":"findmin(f, domain) -> (f(x), index)\n\nReturn a pair of a value in the codomain (outputs of f) and the index or key of the corresponding value in the domain (inputs to f) such that f(x) is minimised. If there are multiple minimal points, then the first one will be returned.\n\ndomain must be a non-empty iterable.\n\nIndices are of the same type as those returned by keys(domain) and pairs(domain).\n\nNaN is treated as less than all other values except missing.\n\ncompat: Julia 1.7\nThis method requires Julia 1.7 or later.\n\nExamples\n\njulia> findmin(identity, 5:9)\n(5, 1)\n\njulia> findmin(-, 1:10)\n(-10, 10)\n\njulia> findmin(first, [(2, :a), (2, :b), (3, :c)])\n(2, 1)\n\njulia> findmin(cos, 0:π/2:2π)\n(-1.0, 3)\n\n\n\n\n\nfindmin(itr) -> (x, index)\n\nReturn the minimal element of the collection itr and its index or key. If there are multiple minimal elements, then the first one will be returned. NaN is treated as less than all other values except missing.\n\nIndices are of the same type as those returned by keys(itr) and pairs(itr).\n\nSee also: findmax, argmin, minimum.\n\nExamples\n\njulia> findmin([8, 0.1, -9, pi])\n(-9.0, 3)\n\njulia> findmin([1, 7, 7, 6])\n(1, 1)\n\njulia> findmin([1, 7, 7, NaN])\n(NaN, 4)\n\n\n\n\n\nfindmin(A; dims) -> (minval, index)\n\nFor an array input, returns the value and index of the minimum over the given dimensions. NaN is treated as less than all other values except missing.\n\nExamples\n\njulia> A = [1.0 2; 3 4]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> findmin(A, dims=1)\n([1.0 2.0], CartesianIndex{2}[CartesianIndex(1, 1) CartesianIndex(1, 2)])\n\njulia> findmin(A, dims=2)\n([1.0; 3.0;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 1);;])\n\n\n\n\n\nfindmin(f, A; dims) -> (f(x), index)\n\nFor an array input, returns the value in the codomain and index of the corresponding value which minimize f over the given dimensions.\n\nExamples\n\njulia> A = [-1.0 1; -0.5 2]\n2×2 Matrix{Float64}:\n -1.0 1.0\n -0.5 2.0\n\njulia> findmin(abs2, A, dims=1)\n([0.25 1.0], CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(1, 2)])\n\njulia> findmin(abs2, A, dims=2)\n([1.0; 0.25;;], CartesianIndex{2}[CartesianIndex(1, 1); CartesianIndex(2, 1);;])\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.findmax!","page":"Collections and Data Structures","title":"Base.findmax!","text":"findmax!(rval, rind, A) -> (maxval, index)\n\nFind the maximum of A and the corresponding linear index along singleton dimensions of rval and rind, and store the results in rval and rind. NaN is treated as greater than all other values except missing.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.findmin!","page":"Collections and Data Structures","title":"Base.findmin!","text":"findmin!(rval, rind, A) -> (minval, index)\n\nFind the minimum of A and the corresponding linear index along singleton dimensions of rval and rind, and store the results in rval and rind. NaN is treated as less than all other values except missing.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.sum","page":"Collections and Data Structures","title":"Base.sum","text":"sum(f, itr; [init])\n\nSum the results of calling function f on each element of itr.\n\nThe return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.\n\nThe value returned for empty itr can be specified by init. It must be the additive identity (i.e. zero) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> sum(abs2, [2; 3; 4])\n29\n\nNote the important difference between sum(A) and reduce(+, A) for arrays with small integer eltype:\n\njulia> sum(Int8[100, 28])\n128\n\njulia> reduce(+, Int8[100, 28])\n-128\n\nIn the former case, the integers are widened to system word size and therefore the result is 128. In the latter case, no such widening happens and integer overflow results in -128.\n\n\n\n\n\nsum(itr; [init])\n\nReturn the sum of all elements in a collection.\n\nThe return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.\n\nThe value returned for empty itr can be specified by init. It must be the additive identity (i.e. zero) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nSee also: reduce, mapreduce, count, union.\n\nExamples\n\njulia> sum(1:20)\n210\n\njulia> sum(1:20; init = 0.0)\n210.0\n\n\n\n\n\nsum(A::AbstractArray; dims)\n\nSum elements of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> sum(A, dims=1)\n1×2 Matrix{Int64}:\n 4 6\n\njulia> sum(A, dims=2)\n2×1 Matrix{Int64}:\n 3\n 7\n\n\n\n\n\nsum(f, A::AbstractArray; dims)\n\nSum the results of calling function f on each element of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> sum(abs2, A, dims=1)\n1×2 Matrix{Int64}:\n 10 20\n\njulia> sum(abs2, A, dims=2)\n2×1 Matrix{Int64}:\n 5\n 25\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.sum!","page":"Collections and Data Structures","title":"Base.sum!","text":"sum!(r, A)\n\nSum elements of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> sum!([1; 1], A)\n2-element Vector{Int64}:\n 3\n 7\n\njulia> sum!([1 1], A)\n1×2 Matrix{Int64}:\n 4 6\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.prod","page":"Collections and Data Structures","title":"Base.prod","text":"prod(f, itr; [init])\n\nReturn the product of f applied to each element of itr.\n\nThe return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.\n\nThe value returned for empty itr can be specified by init. It must be the multiplicative identity (i.e. one) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nExamples\n\njulia> prod(abs2, [2; 3; 4])\n576\n\n\n\n\n\nprod(itr; [init])\n\nReturn the product of all elements of a collection.\n\nThe return type is Int for signed integers of less than system word size, and UInt for unsigned integers of less than system word size. For all other arguments, a common return type is found to which all arguments are promoted.\n\nThe value returned for empty itr can be specified by init. It must be the multiplicative identity (i.e. one) as it is unspecified whether init is used for non-empty collections.\n\ncompat: Julia 1.6\nKeyword argument init requires Julia 1.6 or later.\n\nSee also: reduce, cumprod, any.\n\nExamples\n\njulia> prod(1:5)\n120\n\njulia> prod(1:5; init = 1.0)\n120.0\n\n\n\n\n\nprod(A::AbstractArray; dims)\n\nMultiply elements of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> prod(A, dims=1)\n1×2 Matrix{Int64}:\n 3 8\n\njulia> prod(A, dims=2)\n2×1 Matrix{Int64}:\n 2\n 12\n\n\n\n\n\nprod(f, A::AbstractArray; dims)\n\nMultiply the results of calling the function f on each element of an array over the given dimensions.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> prod(abs2, A, dims=1)\n1×2 Matrix{Int64}:\n 9 64\n\njulia> prod(abs2, A, dims=2)\n2×1 Matrix{Int64}:\n 4\n 144\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.prod!","page":"Collections and Data Structures","title":"Base.prod!","text":"prod!(r, A)\n\nMultiply elements of A over the singleton dimensions of r, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> prod!([1; 1], A)\n2-element Vector{Int64}:\n 2\n 12\n\njulia> prod!([1 1], A)\n1×2 Matrix{Int64}:\n 3 8\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.any-Tuple{Any}","page":"Collections and Data Structures","title":"Base.any","text":"any(itr) -> Bool\n\nTest whether any elements of a boolean collection are true, returning true as soon as the first true value in itr is encountered (short-circuiting). To short-circuit on false, use all.\n\nIf the input contains missing values, return missing if all non-missing values are false (or equivalently, if the input contains no true value), following three-valued logic.\n\nSee also: all, count, sum, |, , ||.\n\nExamples\n\njulia> a = [true,false,false,true]\n4-element Vector{Bool}:\n 1\n 0\n 0\n 1\n\njulia> any(a)\ntrue\n\njulia> any((println(i); v) for (i, v) in enumerate(a))\n1\ntrue\n\njulia> any([missing, true])\ntrue\n\njulia> any([false, missing])\nmissing\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.any-Tuple{AbstractArray, Any}","page":"Collections and Data Structures","title":"Base.any","text":"any(p, itr) -> Bool\n\nDetermine whether predicate p returns true for any elements of itr, returning true as soon as the first item in itr for which p returns true is encountered (short-circuiting). To short-circuit on false, use all.\n\nIf the input contains missing values, return missing if all non-missing values are false (or equivalently, if the input contains no true value), following three-valued logic.\n\nExamples\n\njulia> any(i->(4<=i<=6), [3,5,7])\ntrue\n\njulia> any(i -> (println(i); i > 3), 1:10)\n1\n2\n3\n4\ntrue\n\njulia> any(i -> i > 0, [1, missing])\ntrue\n\njulia> any(i -> i > 0, [-1, missing])\nmissing\n\njulia> any(i -> i > 0, [-1, 0])\nfalse\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.any!","page":"Collections and Data Structures","title":"Base.any!","text":"any!(r, A)\n\nTest whether any values in A along the singleton dimensions of r are true, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [true false; true false]\n2×2 Matrix{Bool}:\n 1 0\n 1 0\n\njulia> any!([1; 1], A)\n2-element Vector{Int64}:\n 1\n 1\n\njulia> any!([1 1], A)\n1×2 Matrix{Int64}:\n 1 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.all-Tuple{Any}","page":"Collections and Data Structures","title":"Base.all","text":"all(itr) -> Bool\n\nTest whether all elements of a boolean collection are true, returning false as soon as the first false value in itr is encountered (short-circuiting). To short-circuit on true, use any.\n\nIf the input contains missing values, return missing if all non-missing values are true (or equivalently, if the input contains no false value), following three-valued logic.\n\nSee also: all!, any, count, &, , &&, allunique.\n\nExamples\n\njulia> a = [true,false,false,true]\n4-element Vector{Bool}:\n 1\n 0\n 0\n 1\n\njulia> all(a)\nfalse\n\njulia> all((println(i); v) for (i, v) in enumerate(a))\n1\n2\nfalse\n\njulia> all([missing, false])\nfalse\n\njulia> all([true, missing])\nmissing\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.all-Tuple{AbstractArray, Any}","page":"Collections and Data Structures","title":"Base.all","text":"all(p, itr) -> Bool\n\nDetermine whether predicate p returns true for all elements of itr, returning false as soon as the first item in itr for which p returns false is encountered (short-circuiting). To short-circuit on true, use any.\n\nIf the input contains missing values, return missing if all non-missing values are true (or equivalently, if the input contains no false value), following three-valued logic.\n\nExamples\n\njulia> all(i->(4<=i<=6), [4,5,6])\ntrue\n\njulia> all(i -> (println(i); i < 3), 1:10)\n1\n2\n3\nfalse\n\njulia> all(i -> i > 0, [1, missing])\nmissing\n\njulia> all(i -> i > 0, [-1, missing])\nfalse\n\njulia> all(i -> i > 0, [1, 2])\ntrue\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.all!","page":"Collections and Data Structures","title":"Base.all!","text":"all!(r, A)\n\nTest whether all values in A along the singleton dimensions of r are true, and write results to r.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> A = [true false; true false]\n2×2 Matrix{Bool}:\n 1 0\n 1 0\n\njulia> all!([1; 1], A)\n2-element Vector{Int64}:\n 0\n 0\n\njulia> all!([1 1], A)\n1×2 Matrix{Int64}:\n 1 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.count","page":"Collections and Data Structures","title":"Base.count","text":"count([f=identity,] itr; init=0) -> Integer\n\nCount the number of elements in itr for which the function f returns true. If f is omitted, count the number of true elements in itr (which should be a collection of boolean values). init optionally specifies the value to start counting from and therefore also determines the output type.\n\ncompat: Julia 1.6\ninit keyword was added in Julia 1.6.\n\nSee also: any, sum.\n\nExamples\n\njulia> count(i->(4<=i<=6), [2,3,4,5,6])\n3\n\njulia> count([true, false, true, true])\n3\n\njulia> count(>(3), 1:7, init=0x03)\n0x07\n\n\n\n\n\ncount(\n pattern::Union{AbstractChar,AbstractString,AbstractPattern},\n string::AbstractString;\n overlap::Bool = false,\n)\n\nReturn the number of matches for pattern in string. This is equivalent to calling length(findall(pattern, string)) but more efficient.\n\nIf overlap=true, the matching sequences are allowed to overlap indices in the original string, otherwise they must be from disjoint character ranges.\n\ncompat: Julia 1.3\nThis method requires at least Julia 1.3.\n\ncompat: Julia 1.7\nUsing a character as the pattern requires at least Julia 1.7.\n\nExamples\n\njulia> count('a', \"JuliaLang\")\n2\n\njulia> count(r\"a(.)a\", \"cabacabac\", overlap=true)\n3\n\njulia> count(r\"a(.)a\", \"cabacabac\")\n2\n\n\n\n\n\ncount([f=identity,] A::AbstractArray; dims=:)\n\nCount the number of elements in A for which f returns true over the given dimensions.\n\ncompat: Julia 1.5\ndims keyword was added in Julia 1.5.\n\ncompat: Julia 1.6\ninit keyword was added in Julia 1.6.\n\nExamples\n\njulia> A = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> count(<=(2), A, dims=1)\n1×2 Matrix{Int64}:\n 1 1\n\njulia> count(<=(2), A, dims=2)\n2×1 Matrix{Int64}:\n 2\n 0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.foreach","page":"Collections and Data Structures","title":"Base.foreach","text":"foreach(f, c...) -> Nothing\n\nCall function f on each element of iterable c. For multiple iterable arguments, f is called elementwise, and iteration stops when any iterator is finished.\n\nforeach should be used instead of map when the results of f are not needed, for example in foreach(println, array).\n\nExamples\n\njulia> tri = 1:3:7; res = Int[];\n\njulia> foreach(x -> push!(res, x^2), tri)\n\njulia> res\n3-element Vector{Int64}:\n 1\n 16\n 49\n\njulia> foreach((x, y) -> println(x, \" with \", y), tri, 'a':'z')\n1 with a\n4 with b\n7 with c\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.map","page":"Collections and Data Structures","title":"Base.map","text":"map(f, c...) -> collection\n\nTransform collection c by applying f to each element. For multiple collection arguments, apply f elementwise, and stop when any of them is exhausted.\n\nSee also map!, foreach, mapreduce, mapslices, zip, Iterators.map.\n\nExamples\n\njulia> map(x -> x * 2, [1, 2, 3])\n3-element Vector{Int64}:\n 2\n 4\n 6\n\njulia> map(+, [1, 2, 3], [10, 20, 30, 400, 5000])\n3-element Vector{Int64}:\n 11\n 22\n 33\n\n\n\n\n\nmap(f, A::AbstractArray...) -> N-array\n\nWhen acting on multi-dimensional arrays of the same ndims, they must all have the same axes, and the answer will too.\n\nSee also broadcast, which allows mismatched sizes.\n\nExamples\n\njulia> map(//, [1 2; 3 4], [4 3; 2 1])\n2×2 Matrix{Rational{Int64}}:\n 1//4 2//3\n 3//2 4//1\n\njulia> map(+, [1 2; 3 4], zeros(2,1))\nERROR: DimensionMismatch\n\njulia> map(+, [1 2; 3 4], [1,10,100,1000], zeros(3,1)) # iterates until 3rd is exhausted\n3-element Vector{Float64}:\n 2.0\n 13.0\n 102.0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.map!","page":"Collections and Data Structures","title":"Base.map!","text":"map!(function, destination, collection...)\n\nLike map, but stores the result in destination rather than a new collection. destination must be at least as large as the smallest collection.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nSee also: map, foreach, zip, copyto!.\n\nExamples\n\njulia> a = zeros(3);\n\njulia> map!(x -> x * 2, a, [1, 2, 3]);\n\njulia> a\n3-element Vector{Float64}:\n 2.0\n 4.0\n 6.0\n\njulia> map!(+, zeros(Int, 5), 100:999, 1:3)\n5-element Vector{Int64}:\n 101\n 103\n 105\n 0\n 0\n\n\n\n\n\nmap!(f, values(dict::AbstractDict))\n\nModifies dict by transforming each value from val to f(val). Note that the type of dict cannot be changed: if f(val) is not an instance of the value type of dict then it will be converted to the value type if possible and otherwise raise an error.\n\ncompat: Julia 1.2\nmap!(f, values(dict::AbstractDict)) requires Julia 1.2 or later.\n\nExamples\n\njulia> d = Dict(:a => 1, :b => 2)\nDict{Symbol, Int64} with 2 entries:\n :a => 1\n :b => 2\n\njulia> map!(v -> v-1, values(d))\nValueIterator for a Dict{Symbol, Int64} with 2 entries. Values:\n 0\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.mapreduce-Tuple{Any, Any, Any}","page":"Collections and Data Structures","title":"Base.mapreduce","text":"mapreduce(f, op, itrs...; [init])\n\nApply function f to each element(s) in itrs, and then reduce the result using the binary function op. If provided, init must be a neutral element for op that will be returned for empty collections. It is unspecified whether init is used for non-empty collections. In general, it will be necessary to provide init to work with empty collections.\n\nmapreduce is functionally equivalent to calling reduce(op, map(f, itr); init=init), but will in general execute faster since no intermediate collection needs to be created. See documentation for reduce and map.\n\ncompat: Julia 1.2\nmapreduce with multiple iterators requires Julia 1.2 or later.\n\nExamples\n\njulia> mapreduce(x->x^2, +, [1:3;]) # == 1 + 4 + 9\n14\n\nThe associativity of the reduction is implementation-dependent. Additionally, some implementations may reuse the return value of f for elements that appear multiple times in itr. Use mapfoldl or mapfoldr instead for guaranteed left or right associativity and invocation of f for every value.\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.mapfoldl-Tuple{Any, Any, Any}","page":"Collections and Data Structures","title":"Base.mapfoldl","text":"mapfoldl(f, op, itr; [init])\n\nLike mapreduce, but with guaranteed left associativity, as in foldl. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.mapfoldr-Tuple{Any, Any, Any}","page":"Collections and Data Structures","title":"Base.mapfoldr","text":"mapfoldr(f, op, itr; [init])\n\nLike mapreduce, but with guaranteed right associativity, as in foldr. If provided, the keyword argument init will be used exactly once. In general, it will be necessary to provide init to work with empty collections.\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.first","page":"Collections and Data Structures","title":"Base.first","text":"first(coll)\n\nGet the first element of an iterable collection. Return the start point of an AbstractRange even if it is empty.\n\nSee also: only, firstindex, last.\n\nExamples\n\njulia> first(2:2:10)\n2\n\njulia> first([1; 2; 3; 4])\n1\n\n\n\n\n\nfirst(itr, n::Integer)\n\nGet the first n elements of the iterable collection itr, or fewer elements if itr is not long enough.\n\nSee also: startswith, Iterators.take.\n\ncompat: Julia 1.6\nThis method requires at least Julia 1.6.\n\nExamples\n\njulia> first([\"foo\", \"bar\", \"qux\"], 2)\n2-element Vector{String}:\n \"foo\"\n \"bar\"\n\njulia> first(1:6, 10)\n1:6\n\njulia> first(Bool[], 1)\nBool[]\n\n\n\n\n\nfirst(s::AbstractString, n::Integer)\n\nGet a string consisting of the first n characters of s.\n\nExamples\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 0)\n\"\"\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 1)\n\"∀\"\n\njulia> first(\"∀ϵ≠0: ϵ²>0\", 3)\n\"∀ϵ≠\"\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.last","page":"Collections and Data Structures","title":"Base.last","text":"last(coll)\n\nGet the last element of an ordered collection, if it can be computed in O(1) time. This is accomplished by calling lastindex to get the last index. Return the end point of an AbstractRange even if it is empty.\n\nSee also first, endswith.\n\nExamples\n\njulia> last(1:2:10)\n9\n\njulia> last([1; 2; 3; 4])\n4\n\n\n\n\n\nlast(itr, n::Integer)\n\nGet the last n elements of the iterable collection itr, or fewer elements if itr is not long enough.\n\ncompat: Julia 1.6\nThis method requires at least Julia 1.6.\n\nExamples\n\njulia> last([\"foo\", \"bar\", \"qux\"], 2)\n2-element Vector{String}:\n \"bar\"\n \"qux\"\n\njulia> last(1:6, 10)\n1:6\n\njulia> last(Float64[], 1)\nFloat64[]\n\n\n\n\n\nlast(s::AbstractString, n::Integer)\n\nGet a string consisting of the last n characters of s.\n\nExamples\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 0)\n\"\"\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 1)\n\"0\"\n\njulia> last(\"∀ϵ≠0: ϵ²>0\", 3)\n\"²>0\"\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.front","page":"Collections and Data Structures","title":"Base.front","text":"front(x::Tuple)::Tuple\n\nReturn a Tuple consisting of all but the last component of x.\n\nSee also: first, tail.\n\nExamples\n\njulia> Base.front((1,2,3))\n(1, 2)\n\njulia> Base.front(())\nERROR: ArgumentError: Cannot call front on an empty tuple.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.tail","page":"Collections and Data Structures","title":"Base.tail","text":"tail(x::Tuple)::Tuple\n\nReturn a Tuple consisting of all but the first component of x.\n\nSee also: front, rest, first, Iterators.peel.\n\nExamples\n\njulia> Base.tail((1,2,3))\n(2, 3)\n\njulia> Base.tail(())\nERROR: ArgumentError: Cannot call tail on an empty tuple.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.step","page":"Collections and Data Structures","title":"Base.step","text":"step(r)\n\nGet the step size of an AbstractRange object.\n\nExamples\n\njulia> step(1:10)\n1\n\njulia> step(1:2:10)\n2\n\njulia> step(2.5:0.3:10.9)\n0.3\n\njulia> step(range(2.5, stop=10.9, length=85))\n0.1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.collect-Tuple{Any}","page":"Collections and Data Structures","title":"Base.collect","text":"collect(collection)\n\nReturn an Array of all items in a collection or iterator. For dictionaries, returns a Vector of key=>value Pairs. If the argument is array-like or is an iterator with the HasShape trait, the result will have the same shape and number of dimensions as the argument.\n\nUsed by comprehensions to turn a generator expression into an Array. Thus, on generators, the square-brackets notation may be used instead of calling collect, see second example.\n\nExamples\n\nCollect items from a UnitRange{Int64} collection:\n\njulia> collect(1:3)\n3-element Vector{Int64}:\n 1\n 2\n 3\n\nCollect items from a generator (same output as [x^2 for x in 1:3]):\n\njulia> collect(x^2 for x in 1:3)\n3-element Vector{Int64}:\n 1\n 4\n 9\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.collect-Tuple{Type, Any}","page":"Collections and Data Structures","title":"Base.collect","text":"collect(element_type, collection)\n\nReturn an Array with the given element type of all items in a collection or iterable. The result has the same shape and number of dimensions as collection.\n\nExamples\n\njulia> collect(Float64, 1:2:5)\n3-element Vector{Float64}:\n 1.0\n 3.0\n 5.0\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.filter","page":"Collections and Data Structures","title":"Base.filter","text":"filter(f, a)\n\nReturn a copy of collection a, removing elements for which f is false. The function f is passed one argument.\n\ncompat: Julia 1.4\nSupport for a as a tuple requires at least Julia 1.4.\n\nSee also: filter!, Iterators.filter.\n\nExamples\n\njulia> a = 1:10\n1:10\n\njulia> filter(isodd, a)\n5-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n\n\n\n\n\nfilter(f)\n\nCreate a function that filters its arguments with function f using filter, i.e. a function equivalent to x -> filter(f, x).\n\nThe returned function is of type Base.Fix1{typeof(filter)}, which can be used to implement specialized methods.\n\nExamples\n\njulia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)\n(1, 2, 4, 6)\n\njulia> map(filter(iseven), [1:3, 2:4, 3:5])\n3-element Vector{Vector{Int64}}:\n [2]\n [2, 4]\n [4]\n\ncompat: Julia 1.9\nThis method requires at least Julia 1.9.\n\n\n\n\n\nfilter(f, d::AbstractDict)\n\nReturn a copy of d, removing elements for which f is false. The function f is passed key=>value pairs.\n\nExamples\n\njulia> d = Dict(1=>\"a\", 2=>\"b\")\nDict{Int64, String} with 2 entries:\n 2 => \"b\"\n 1 => \"a\"\n\njulia> filter(p->isodd(p.first), d)\nDict{Int64, String} with 1 entry:\n 1 => \"a\"\n\n\n\n\n\nfilter(f, itr::SkipMissing{<:AbstractArray})\n\nReturn a vector similar to the array wrapped by the given SkipMissing iterator but with all missing elements and those for which f returns false removed.\n\ncompat: Julia 1.2\nThis method requires Julia 1.2 or later.\n\nExamples\n\njulia> x = [1 2; missing 4]\n2×2 Matrix{Union{Missing, Int64}}:\n 1 2\n missing 4\n\njulia> filter(isodd, skipmissing(x))\n1-element Vector{Int64}:\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.filter!","page":"Collections and Data Structures","title":"Base.filter!","text":"filter!(f, a)\n\nUpdate collection a, removing elements for which f is false. The function f is passed one argument.\n\nExamples\n\njulia> filter!(isodd, Vector(1:10))\n5-element Vector{Int64}:\n 1\n 3\n 5\n 7\n 9\n\n\n\n\n\nfilter!(f, d::AbstractDict)\n\nUpdate d, removing elements for which f is false. The function f is passed key=>value pairs.\n\nExamples\n\njulia> d = Dict(1=>\"a\", 2=>\"b\", 3=>\"c\")\nDict{Int64, String} with 3 entries:\n 2 => \"b\"\n 3 => \"c\"\n 1 => \"a\"\n\njulia> filter!(p->isodd(p.first), d)\nDict{Int64, String} with 2 entries:\n 3 => \"c\"\n 1 => \"a\"\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.replace-Tuple{Any, Vararg{Pair}}","page":"Collections and Data Structures","title":"Base.replace","text":"replace(A, old_new::Pair...; [count::Integer])\n\nReturn a copy of collection A where, for each pair old=>new in old_new, all occurrences of old are replaced by new. Equality is determined using isequal. If count is specified, then replace at most count occurrences in total.\n\nThe element type of the result is chosen using promotion (see promote_type) based on the element type of A and on the types of the new values in pairs. If count is omitted and the element type of A is a Union, the element type of the result will not include singleton types which are replaced with values of a different type: for example, Union{T,Missing} will become T if missing is replaced.\n\nSee also replace!, splice!, delete!, insert!.\n\ncompat: Julia 1.7\nVersion 1.7 is required to replace elements of a Tuple.\n\nExamples\n\njulia> replace([1, 2, 1, 3], 1=>0, 2=>4, count=2)\n4-element Vector{Int64}:\n 0\n 4\n 1\n 3\n\njulia> replace([1, missing], missing=>0)\n2-element Vector{Int64}:\n 1\n 0\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.replace-Tuple{Union{Function, Type}, Any}","page":"Collections and Data Structures","title":"Base.replace","text":"replace(new::Union{Function, Type}, A; [count::Integer])\n\nReturn a copy of A where each value x in A is replaced by new(x). If count is specified, then replace at most count values in total (replacements being defined as new(x) !== x).\n\ncompat: Julia 1.7\nVersion 1.7 is required to replace elements of a Tuple.\n\nExamples\n\njulia> replace(x -> isodd(x) ? 2x : x, [1, 2, 3, 4])\n4-element Vector{Int64}:\n 2\n 2\n 6\n 4\n\njulia> replace(Dict(1=>2, 3=>4)) do kv\n first(kv) < 3 ? first(kv)=>3 : kv\n end\nDict{Int64, Int64} with 2 entries:\n 3 => 4\n 1 => 3\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.replace!","page":"Collections and Data Structures","title":"Base.replace!","text":"replace!(A, old_new::Pair...; [count::Integer])\n\nFor each pair old=>new in old_new, replace all occurrences of old in collection A by new. Equality is determined using isequal. If count is specified, then replace at most count occurrences in total. See also replace.\n\nExamples\n\njulia> replace!([1, 2, 1, 3], 1=>0, 2=>4, count=2)\n4-element Vector{Int64}:\n 0\n 4\n 1\n 3\n\njulia> replace!(Set([1, 2, 3]), 1=>0)\nSet{Int64} with 3 elements:\n 0\n 2\n 3\n\n\n\n\n\nreplace!(new::Union{Function, Type}, A; [count::Integer])\n\nReplace each element x in collection A by new(x). If count is specified, then replace at most count values in total (replacements being defined as new(x) !== x).\n\nExamples\n\njulia> replace!(x -> isodd(x) ? 2x : x, [1, 2, 3, 4])\n4-element Vector{Int64}:\n 2\n 2\n 6\n 4\n\njulia> replace!(Dict(1=>2, 3=>4)) do kv\n first(kv) < 3 ? first(kv)=>3 : kv\n end\nDict{Int64, Int64} with 2 entries:\n 3 => 4\n 1 => 3\n\njulia> replace!(x->2x, Set([3, 6]))\nSet{Int64} with 2 elements:\n 6\n 12\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.rest","page":"Collections and Data Structures","title":"Base.rest","text":"Base.rest(collection[, itr_state])\n\nGeneric function for taking the tail of collection, starting from a specific iteration state itr_state. Return a Tuple, if collection itself is a Tuple, a subtype of AbstractVector, if collection is an AbstractArray, a subtype of AbstractString if collection is an AbstractString, and an arbitrary iterator, falling back to Iterators.rest(collection[, itr_state]), otherwise.\n\nCan be overloaded for user-defined collection types to customize the behavior of slurping in assignments in final position, like a, b... = collection.\n\ncompat: Julia 1.6\nBase.rest requires at least Julia 1.6.\n\nSee also: first, Iterators.rest, Base.split_rest.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> first, state = iterate(a)\n(1, 2)\n\njulia> first, Base.rest(a, state)\n(1, [3, 2, 4])\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.split_rest","page":"Collections and Data Structures","title":"Base.split_rest","text":"Base.split_rest(collection, n::Int[, itr_state]) -> (rest_but_n, last_n)\n\nGeneric function for splitting the tail of collection, starting from a specific iteration state itr_state. Returns a tuple of two new collections. The first one contains all elements of the tail but the n last ones, which make up the second collection.\n\nThe type of the first collection generally follows that of Base.rest, except that the fallback case is not lazy, but is collected eagerly into a vector.\n\nCan be overloaded for user-defined collection types to customize the behavior of slurping in assignments in non-final position, like a, b..., c = collection.\n\ncompat: Julia 1.9\nBase.split_rest requires at least Julia 1.9.\n\nSee also: Base.rest.\n\nExamples\n\njulia> a = [1 2; 3 4]\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> first, state = iterate(a)\n(1, 2)\n\njulia> first, Base.split_rest(a, 1, state)\n(1, ([3, 2], [4]))\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Indexable-Collections","page":"Collections and Data Structures","title":"Indexable Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.getindex\nBase.setindex!\nBase.firstindex\nBase.lastindex","category":"page"},{"location":"base/collections/#Base.getindex","page":"Collections and Data Structures","title":"Base.getindex","text":"getindex(collection, key...)\n\nRetrieve the value(s) stored at the given key or index within a collection. The syntax a[i,j,...] is converted by the compiler to getindex(a, i, j, ...).\n\nSee also get, keys, eachindex.\n\nExamples\n\njulia> A = Dict(\"a\" => 1, \"b\" => 2)\nDict{String, Int64} with 2 entries:\n \"b\" => 2\n \"a\" => 1\n\njulia> getindex(A, \"a\")\n1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.setindex!","page":"Collections and Data Structures","title":"Base.setindex!","text":"setindex!(collection, value, key...)\n\nStore the given value at the given key or index within a collection. The syntax a[i,j,...] = x is converted by the compiler to (setindex!(a, x, i, j, ...); x).\n\nExamples\n\njulia> a = Dict(\"a\"=>1)\nDict{String, Int64} with 1 entry:\n \"a\" => 1\n\njulia> setindex!(a, 2, \"b\")\nDict{String, Int64} with 2 entries:\n \"b\" => 2\n \"a\" => 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.firstindex","page":"Collections and Data Structures","title":"Base.firstindex","text":"firstindex(collection) -> Integer\nfirstindex(collection, d) -> Integer\n\nReturn the first index of collection. If d is given, return the first index of collection along dimension d.\n\nThe syntaxes A[begin] and A[1, begin] lower to A[firstindex(A)] and A[1, firstindex(A, 2)], respectively.\n\nSee also: first, axes, lastindex, nextind.\n\nExamples\n\njulia> firstindex([1,2,4])\n1\n\njulia> firstindex(rand(3,4,5), 2)\n1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.lastindex","page":"Collections and Data Structures","title":"Base.lastindex","text":"lastindex(collection) -> Integer\nlastindex(collection, d) -> Integer\n\nReturn the last index of collection. If d is given, return the last index of collection along dimension d.\n\nThe syntaxes A[end] and A[end, end] lower to A[lastindex(A)] and A[lastindex(A, 1), lastindex(A, 2)], respectively.\n\nSee also: axes, firstindex, eachindex, prevind.\n\nExamples\n\njulia> lastindex([1,2,4])\n3\n\njulia> lastindex(rand(3,4,5), 2)\n4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Array\nBitArray\nAbstractArray\nSubArray","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Partially implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"AbstractRange\nUnitRange\nTuple\nAbstractString\nDict\nIdDict\nWeakKeyDict\nNamedTuple","category":"page"},{"location":"base/collections/#Dictionaries","page":"Collections and Data Structures","title":"Dictionaries","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Dict is the standard dictionary. Its implementation uses hash as the hashing function for the key, and isequal to determine equality. Define these two functions for custom types to override how they are stored in a hash table.","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"IdDict is a special hash table where the keys are always object identities.","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"WeakKeyDict is a hash table implementation where the keys are weak references to objects, and thus may be garbage collected even when referenced in a hash table. Like Dict it uses hash for hashing and isequal for equality, unlike Dict it does not convert keys on insertion.","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Dicts can be created by passing pair objects constructed with => to a Dict constructor: Dict(\"A\"=>1, \"B\"=>2). This call will attempt to infer type information from the keys and values (i.e. this example creates a Dict{String, Int64}). To explicitly specify types use the syntax Dict{KeyType,ValueType}(...). For example, Dict{String,Int32}(\"A\"=>1, \"B\"=>2).","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Dictionaries may also be created with generators. For example, Dict(i => f(i) for i = 1:10).","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Given a dictionary D, the syntax D[x] returns the value of key x (if it exists) or throws an error, and D[x] = y stores the key-value pair x => y in D (replacing any existing value for the key x). Multiple arguments to D[...] are converted to tuples; for example, the syntax D[x,y] is equivalent to D[(x,y)], i.e. it refers to the value keyed by the tuple (x,y).","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.AbstractDict\nBase.Dict\nBase.IdDict\nBase.WeakKeyDict\nBase.ImmutableDict\nBase.PersistentDict\nBase.haskey\nBase.get\nBase.get!\nBase.getkey\nBase.delete!\nBase.pop!(::Any, ::Any, ::Any)\nBase.keys\nBase.values\nBase.pairs\nBase.merge\nBase.mergewith\nBase.merge!\nBase.mergewith!\nBase.sizehint!\nBase.keytype\nBase.valtype","category":"page"},{"location":"base/collections/#Base.AbstractDict","page":"Collections and Data Structures","title":"Base.AbstractDict","text":"AbstractDict{K, V}\n\nSupertype for dictionary-like types with keys of type K and values of type V. Dict, IdDict and other types are subtypes of this. An AbstractDict{K, V} should be an iterator of Pair{K, V}.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.Dict","page":"Collections and Data Structures","title":"Base.Dict","text":"Dict([itr])\n\nDict{K,V}() constructs a hash table with keys of type K and values of type V. Keys are compared with isequal and hashed with hash.\n\nGiven a single iterable argument, constructs a Dict whose key-value pairs are taken from 2-tuples (key,value) generated by the argument.\n\nExamples\n\njulia> Dict([(\"A\", 1), (\"B\", 2)])\nDict{String, Int64} with 2 entries:\n \"B\" => 2\n \"A\" => 1\n\nAlternatively, a sequence of pair arguments may be passed.\n\njulia> Dict(\"A\"=>1, \"B\"=>2)\nDict{String, Int64} with 2 entries:\n \"B\" => 2\n \"A\" => 1\n\nwarning: Warning\nKeys are allowed to be mutable, but if you do mutate stored keys, the hash table may become internally inconsistent, in which case the Dict will not work properly. IdDict can be an alternative if you need to mutate keys.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.IdDict","page":"Collections and Data Structures","title":"Base.IdDict","text":"IdDict([itr])\n\nIdDict{K,V}() constructs a hash table using objectid as hash and === as equality with keys of type K and values of type V. See Dict for further help and IdSet for the set version of this.\n\nIn the example below, the Dict keys are all isequal and therefore get hashed the same, so they get overwritten. The IdDict hashes by object-id, and thus preserves the 3 different keys.\n\nExamples\n\njulia> Dict(true => \"yes\", 1 => \"no\", 1.0 => \"maybe\")\nDict{Real, String} with 1 entry:\n 1.0 => \"maybe\"\n\njulia> IdDict(true => \"yes\", 1 => \"no\", 1.0 => \"maybe\")\nIdDict{Any, String} with 3 entries:\n true => \"yes\"\n 1.0 => \"maybe\"\n 1 => \"no\"\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.WeakKeyDict","page":"Collections and Data Structures","title":"Base.WeakKeyDict","text":"WeakKeyDict([itr])\n\nWeakKeyDict() constructs a hash table where the keys are weak references to objects which may be garbage collected even when referenced in a hash table.\n\nSee Dict for further help. Note, unlike Dict, WeakKeyDict does not convert keys on insertion, as this would imply the key object was unreferenced anywhere before insertion.\n\nSee also WeakRef.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.ImmutableDict","page":"Collections and Data Structures","title":"Base.ImmutableDict","text":"ImmutableDict\n\nImmutableDict is a dictionary implemented as an immutable linked list, which is optimal for small dictionaries that are constructed over many individual insertions. Note that it is not possible to remove a value, although it can be partially overridden and hidden by inserting a new value with the same key.\n\nImmutableDict(KV::Pair)\n\nCreate a new entry in the ImmutableDict for a key => value pair\n\nuse (key => value) in dict to see if this particular combination is in the properties set\nuse get(dict, key, default) to retrieve the most recent value for a particular key\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.PersistentDict","page":"Collections and Data Structures","title":"Base.PersistentDict","text":"PersistentDict\n\nPersistentDict is a dictionary implemented as an hash array mapped trie, which is optimal for situations where you need persistence, each operation returns a new dictionary separate from the previous one, but the underlying implementation is space-efficient and may share storage across multiple separate dictionaries.\n\nnote: Note\nIt behaves like an IdDict.\n\nPersistentDict(KV::Pair)\n\nExamples\n\njulia> dict = Base.PersistentDict(:a=>1)\nBase.PersistentDict{Symbol, Int64} with 1 entry:\n :a => 1\n\njulia> dict2 = Base.delete(dict, :a)\nBase.PersistentDict{Symbol, Int64}()\n\njulia> dict3 = Base.PersistentDict(dict, :a=>2)\nBase.PersistentDict{Symbol, Int64} with 1 entry:\n :a => 2\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.haskey","page":"Collections and Data Structures","title":"Base.haskey","text":"haskey(collection, key) -> Bool\n\nDetermine whether a collection has a mapping for a given key.\n\nExamples\n\njulia> D = Dict('a'=>2, 'b'=>3)\nDict{Char, Int64} with 2 entries:\n 'a' => 2\n 'b' => 3\n\njulia> haskey(D, 'a')\ntrue\n\njulia> haskey(D, 'c')\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.get","page":"Collections and Data Structures","title":"Base.get","text":"get(collection, key, default)\n\nReturn the value stored for the given key, or the given default value if no mapping for the key is present.\n\ncompat: Julia 1.7\nFor tuples and numbers, this function requires at least Julia 1.7.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2);\n\njulia> get(d, \"a\", 3)\n1\n\njulia> get(d, \"c\", 3)\n3\n\n\n\n\n\nget(f::Union{Function, Type}, collection, key)\n\nReturn the value stored for the given key, or if no mapping for the key is present, return f(). Use get! to also store the default value in the dictionary.\n\nThis is intended to be called using do block syntax\n\nget(dict, key) do\n # default value calculated here\n time()\nend\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.get!","page":"Collections and Data Structures","title":"Base.get!","text":"get!(collection, key, default)\n\nReturn the value stored for the given key, or if no mapping for the key is present, store key => default, and return default.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2, \"c\"=>3);\n\njulia> get!(d, \"a\", 5)\n1\n\njulia> get!(d, \"d\", 4)\n4\n\njulia> d\nDict{String, Int64} with 4 entries:\n \"c\" => 3\n \"b\" => 2\n \"a\" => 1\n \"d\" => 4\n\n\n\n\n\nget!(f::Union{Function, Type}, collection, key)\n\nReturn the value stored for the given key, or if no mapping for the key is present, store key => f(), and return f().\n\nThis is intended to be called using do block syntax.\n\nExamples\n\njulia> squares = Dict{Int, Int}();\n\njulia> function get_square!(d, i)\n get!(d, i) do\n i^2\n end\n end\nget_square! (generic function with 1 method)\n\njulia> get_square!(squares, 2)\n4\n\njulia> squares\nDict{Int64, Int64} with 1 entry:\n 2 => 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.getkey","page":"Collections and Data Structures","title":"Base.getkey","text":"getkey(collection, key, default)\n\nReturn the key matching argument key if one exists in collection, otherwise return default.\n\nExamples\n\njulia> D = Dict('a'=>2, 'b'=>3)\nDict{Char, Int64} with 2 entries:\n 'a' => 2\n 'b' => 3\n\njulia> getkey(D, 'a', 1)\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\njulia> getkey(D, 'd', 'a')\n'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.delete!","page":"Collections and Data Structures","title":"Base.delete!","text":"delete!(collection, key)\n\nDelete the mapping for the given key in a collection, if any, and return the collection.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2)\nDict{String, Int64} with 2 entries:\n \"b\" => 2\n \"a\" => 1\n\njulia> delete!(d, \"b\")\nDict{String, Int64} with 1 entry:\n \"a\" => 1\n\njulia> delete!(d, \"b\") # d is left unchanged\nDict{String, Int64} with 1 entry:\n \"a\" => 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.pop!-Tuple{Any, Any, Any}","page":"Collections and Data Structures","title":"Base.pop!","text":"pop!(collection, key[, default])\n\nDelete and return the mapping for key if it exists in collection, otherwise return default, or throw an error if default is not specified.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2, \"c\"=>3);\n\njulia> pop!(d, \"a\")\n1\n\njulia> pop!(d, \"d\")\nERROR: KeyError: key \"d\" not found\nStacktrace:\n[...]\n\njulia> pop!(d, \"e\", 4)\n4\n\n\n\n\n\n","category":"method"},{"location":"base/collections/#Base.keys","page":"Collections and Data Structures","title":"Base.keys","text":"keys(iterator)\n\nFor an iterator or collection that has keys and values (e.g. arrays and dictionaries), return an iterator over the keys.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.values","page":"Collections and Data Structures","title":"Base.values","text":"values(iterator)\n\nFor an iterator or collection that has keys and values, return an iterator over the values. This function simply returns its argument by default, since the elements of a general iterator are normally considered its \"values\".\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2);\n\njulia> values(d)\nValueIterator for a Dict{String, Int64} with 2 entries. Values:\n 2\n 1\n\njulia> values([2])\n1-element Vector{Int64}:\n 2\n\n\n\n\n\nvalues(a::AbstractDict)\n\nReturn an iterator over all values in a collection. collect(values(a)) returns an array of values. When the values are stored internally in a hash table, as is the case for Dict, the order in which they are returned may vary. But keys(a) and values(a) both iterate a and return the elements in the same order.\n\nExamples\n\njulia> D = Dict('a'=>2, 'b'=>3)\nDict{Char, Int64} with 2 entries:\n 'a' => 2\n 'b' => 3\n\njulia> collect(values(D))\n2-element Vector{Int64}:\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.pairs","page":"Collections and Data Structures","title":"Base.pairs","text":"pairs(IndexLinear(), A)\npairs(IndexCartesian(), A)\npairs(IndexStyle(A), A)\n\nAn iterator that accesses each element of the array A, returning i => x, where i is the index for the element and x = A[i]. Identical to pairs(A), except that the style of index can be selected. Also similar to enumerate(A), except i will be a valid index for A, while enumerate always counts from 1 regardless of the indices of A.\n\nSpecifying IndexLinear() ensures that i will be an integer; specifying IndexCartesian() ensures that i will be a Base.CartesianIndex; specifying IndexStyle(A) chooses whichever has been defined as the native indexing style for array A.\n\nMutation of the bounds of the underlying array will invalidate this iterator.\n\nExamples\n\njulia> A = [\"a\" \"d\"; \"b\" \"e\"; \"c\" \"f\"];\n\njulia> for (index, value) in pairs(IndexStyle(A), A)\n println(\"$index $value\")\n end\n1 a\n2 b\n3 c\n4 d\n5 e\n6 f\n\njulia> S = view(A, 1:2, :);\n\njulia> for (index, value) in pairs(IndexStyle(S), S)\n println(\"$index $value\")\n end\nCartesianIndex(1, 1) a\nCartesianIndex(2, 1) b\nCartesianIndex(1, 2) d\nCartesianIndex(2, 2) e\n\nSee also IndexStyle, axes.\n\n\n\n\n\npairs(collection)\n\nReturn an iterator over key => value pairs for any collection that maps a set of keys to a set of values. This includes arrays, where the keys are the array indices.\n\nExamples\n\njulia> a = Dict(zip([\"a\", \"b\", \"c\"], [1, 2, 3]))\nDict{String, Int64} with 3 entries:\n \"c\" => 3\n \"b\" => 2\n \"a\" => 1\n\njulia> pairs(a)\nDict{String, Int64} with 3 entries:\n \"c\" => 3\n \"b\" => 2\n \"a\" => 1\n\njulia> foreach(println, pairs([\"a\", \"b\", \"c\"]))\n1 => \"a\"\n2 => \"b\"\n3 => \"c\"\n\njulia> (;a=1, b=2, c=3) |> pairs |> collect\n3-element Vector{Pair{Symbol, Int64}}:\n :a => 1\n :b => 2\n :c => 3\n\njulia> (;a=1, b=2, c=3) |> collect\n3-element Vector{Int64}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.merge","page":"Collections and Data Structures","title":"Base.merge","text":"merge(initial::Face, others::Face...)\n\nMerge the properties of the initial face and others, with later faces taking priority.\n\n\n\n\n\nmerge(d::AbstractDict, others::AbstractDict...)\n\nConstruct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of the merged collections. If the same key is present in another collection, the value for that key will be the value it has in the last collection listed. See also mergewith for custom handling of values with the same key.\n\nExamples\n\njulia> a = Dict(\"foo\" => 0.0, \"bar\" => 42.0)\nDict{String, Float64} with 2 entries:\n \"bar\" => 42.0\n \"foo\" => 0.0\n\njulia> b = Dict(\"baz\" => 17, \"bar\" => 4711)\nDict{String, Int64} with 2 entries:\n \"bar\" => 4711\n \"baz\" => 17\n\njulia> merge(a, b)\nDict{String, Float64} with 3 entries:\n \"bar\" => 4711.0\n \"baz\" => 17.0\n \"foo\" => 0.0\n\njulia> merge(b, a)\nDict{String, Float64} with 3 entries:\n \"bar\" => 42.0\n \"baz\" => 17.0\n \"foo\" => 0.0\n\n\n\n\n\nmerge(a::NamedTuple, bs::NamedTuple...)\n\nConstruct a new named tuple by merging two or more existing ones, in a left-associative manner. Merging proceeds left-to-right, between pairs of named tuples, and so the order of fields present in both the leftmost and rightmost named tuples take the same position as they are found in the leftmost named tuple. However, values are taken from matching fields in the rightmost named tuple that contains that field. Fields present in only the rightmost named tuple of a pair are appended at the end. A fallback is implemented for when only a single named tuple is supplied, with signature merge(a::NamedTuple).\n\ncompat: Julia 1.1\nMerging 3 or more NamedTuple requires at least Julia 1.1.\n\nExamples\n\njulia> merge((a=1, b=2, c=3), (b=4, d=5))\n(a = 1, b = 4, c = 3, d = 5)\n\njulia> merge((a=1, b=2), (b=3, c=(d=1,)), (c=(d=2,),))\n(a = 1, b = 3, c = (d = 2,))\n\n\n\n\n\nmerge(a::NamedTuple, iterable)\n\nInterpret an iterable of key-value pairs as a named tuple, and perform a merge.\n\njulia> merge((a=1, b=2, c=3), [:b=>4, :d=>5])\n(a = 1, b = 4, c = 3, d = 5)\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.mergewith","page":"Collections and Data Structures","title":"Base.mergewith","text":"mergewith(combine, d::AbstractDict, others::AbstractDict...)\nmergewith(combine)\nmerge(combine, d::AbstractDict, others::AbstractDict...)\n\nConstruct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of the merged collections. Values with the same key will be combined using the combiner function. The curried form mergewith(combine) returns the function (args...) -> mergewith(combine, args...).\n\nMethod merge(combine::Union{Function,Type}, args...) as an alias of mergewith(combine, args...) is still available for backward compatibility.\n\ncompat: Julia 1.5\nmergewith requires Julia 1.5 or later.\n\nExamples\n\njulia> a = Dict(\"foo\" => 0.0, \"bar\" => 42.0)\nDict{String, Float64} with 2 entries:\n \"bar\" => 42.0\n \"foo\" => 0.0\n\njulia> b = Dict(\"baz\" => 17, \"bar\" => 4711)\nDict{String, Int64} with 2 entries:\n \"bar\" => 4711\n \"baz\" => 17\n\njulia> mergewith(+, a, b)\nDict{String, Float64} with 3 entries:\n \"bar\" => 4753.0\n \"baz\" => 17.0\n \"foo\" => 0.0\n\njulia> ans == mergewith(+)(a, b)\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.merge!","page":"Collections and Data Structures","title":"Base.merge!","text":"merge!(d::AbstractDict, others::AbstractDict...)\n\nUpdate collection with pairs from the other collections. See also merge.\n\nExamples\n\njulia> d1 = Dict(1 => 2, 3 => 4);\n\njulia> d2 = Dict(1 => 4, 4 => 5);\n\njulia> merge!(d1, d2);\n\njulia> d1\nDict{Int64, Int64} with 3 entries:\n 4 => 5\n 3 => 4\n 1 => 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.mergewith!","page":"Collections and Data Structures","title":"Base.mergewith!","text":"mergewith!(combine, d::AbstractDict, others::AbstractDict...) -> d\nmergewith!(combine)\nmerge!(combine, d::AbstractDict, others::AbstractDict...) -> d\n\nUpdate collection with pairs from the other collections. Values with the same key will be combined using the combiner function. The curried form mergewith!(combine) returns the function (args...) -> mergewith!(combine, args...).\n\nMethod merge!(combine::Union{Function,Type}, args...) as an alias of mergewith!(combine, args...) is still available for backward compatibility.\n\ncompat: Julia 1.5\nmergewith! requires Julia 1.5 or later.\n\nExamples\n\njulia> d1 = Dict(1 => 2, 3 => 4);\n\njulia> d2 = Dict(1 => 4, 4 => 5);\n\njulia> mergewith!(+, d1, d2);\n\njulia> d1\nDict{Int64, Int64} with 3 entries:\n 4 => 5\n 3 => 4\n 1 => 6\n\njulia> mergewith!(-, d1, d1);\n\njulia> d1\nDict{Int64, Int64} with 3 entries:\n 4 => 0\n 3 => 0\n 1 => 0\n\njulia> foldl(mergewith!(+), [d1, d2]; init=Dict{Int64, Int64}())\nDict{Int64, Int64} with 3 entries:\n 4 => 5\n 3 => 0\n 1 => 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.sizehint!","page":"Collections and Data Structures","title":"Base.sizehint!","text":"sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s\n\nSuggest that collection s reserve capacity for at least n elements. That is, if you expect that you're going to have to push a lot of values onto s, you can avoid the cost of incremental reallocation by doing it once up front; this can improve performance.\n\nIf first is true, then any additional space is reserved before the start of the collection. This way, subsequent calls to pushfirst! (instead of push!) may become faster. Supplying this keyword may result in an error if the collection is not ordered or if pushfirst! is not supported for this collection.\n\nIf shrink=true (the default), the collection's capacity may be reduced if its current capacity is greater than n.\n\nSee also resize!.\n\nNotes on the performance model\n\nFor types that support sizehint!,\n\npush! and append! methods generally may (but are not required to) preallocate extra storage. For types implemented in Base, they typically do, using a heuristic optimized for a general use case.\nsizehint! may control this preallocation. Again, it typically does this for types in Base.\nempty! is nearly costless (and O(1)) for types that support this kind of preallocation.\n\ncompat: Julia 1.11\nThe shrink and first arguments were added in Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.keytype","page":"Collections and Data Structures","title":"Base.keytype","text":"keytype(T::Type{<:AbstractArray})\nkeytype(A::AbstractArray)\n\nReturn the key type of an array. This is equal to the eltype of the result of keys(...), and is provided mainly for compatibility with the dictionary interface.\n\nExamples\n\njulia> keytype([1, 2, 3]) == Int\ntrue\n\njulia> keytype([1 2; 3 4])\nCartesianIndex{2}\n\ncompat: Julia 1.2\nFor arrays, this function requires at least Julia 1.2.\n\n\n\n\n\nkeytype(type)\n\nGet the key type of a dictionary type. Behaves similarly to eltype.\n\nExamples\n\njulia> keytype(Dict(Int32(1) => \"foo\"))\nInt32\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.valtype","page":"Collections and Data Structures","title":"Base.valtype","text":"valtype(T::Type{<:AbstractArray})\nvaltype(A::AbstractArray)\n\nReturn the value type of an array. This is identical to eltype and is provided mainly for compatibility with the dictionary interface.\n\nExamples\n\njulia> valtype([\"one\", \"two\", \"three\"])\nString\n\ncompat: Julia 1.2\nFor arrays, this function requires at least Julia 1.2.\n\n\n\n\n\nvaltype(type)\n\nGet the value type of a dictionary type. Behaves similarly to eltype.\n\nExamples\n\njulia> valtype(Dict(Int32(1) => \"foo\"))\nString\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Dict\nIdDict\nWeakKeyDict","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Partially implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Set\nBitSet\nIdSet\nEnvDict\nArray\nBitArray\nImmutableDict\nPersistentDict\nIterators.Pairs","category":"page"},{"location":"base/collections/#Set-Like-Collections","page":"Collections and Data Structures","title":"Set-Like Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.AbstractSet\nBase.Set\nBase.BitSet\nBase.IdSet\nBase.union\nBase.union!\nBase.intersect\nBase.setdiff\nBase.setdiff!\nBase.symdiff\nBase.symdiff!\nBase.intersect!\nBase.issubset\nBase.in!\nBase.:⊈\nBase.:⊊\nBase.issetequal\nBase.isdisjoint","category":"page"},{"location":"base/collections/#Base.AbstractSet","page":"Collections and Data Structures","title":"Base.AbstractSet","text":"AbstractSet{T}\n\nSupertype for set-like types whose elements are of type T. Set, BitSet and other types are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.Set","page":"Collections and Data Structures","title":"Base.Set","text":"Set{T} <: AbstractSet{T}\n\nSets are mutable containers that provide fast membership testing.\n\nSets have efficient implementations of set operations such as in, union and intersect. Elements in a Set are unique, as determined by the elements' definition of isequal. The order of elements in a Set is an implementation detail and cannot be relied on.\n\nSee also: AbstractSet, BitSet, Dict, push!, empty!, union!, in, isequal\n\nExamples\n\njulia> s = Set(\"aaBca\")\nSet{Char} with 3 elements:\n 'a'\n 'c'\n 'B'\n\njulia> push!(s, 'b')\nSet{Char} with 4 elements:\n 'a'\n 'b'\n 'B'\n 'c'\n\njulia> s = Set([NaN, 0.0, 1.0, 2.0]);\n\njulia> -0.0 in s # isequal(0.0, -0.0) is false\nfalse\n\njulia> NaN in s # isequal(NaN, NaN) is true\ntrue\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.BitSet","page":"Collections and Data Structures","title":"Base.BitSet","text":"BitSet([itr])\n\nConstruct a sorted set of Ints generated by the given iterable object, or an empty set. Implemented as a bit string, and therefore designed for dense integer sets. If the set will be sparse (for example, holding a few very large integers), use Set instead.\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.IdSet","page":"Collections and Data Structures","title":"Base.IdSet","text":"IdSet{T}([itr])\nIdSet()\n\nIdSet{T}() constructs a set (see Set) using === as equality with values of type V.\n\nIn the example below, the values are all isequal so they get overwritten. The IdSet compares by === so preserves the 3 different keys.\n\nExamples ≡≡≡≡≡≡≡≡\n\njulia> Set(Any[true, 1, 1.0]) Set{Any} with 1 element: 1.0\n\njulia> IdSet{Any}(Any[true, 1, 1.0]) IdSet{Any} with 3 elements: 1.0 1 true\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.union","page":"Collections and Data Structures","title":"Base.union","text":"union(s, itrs...)\n∪(s, itrs...)\n\nConstruct an object containing all distinct elements from all of the arguments.\n\nThe first argument controls what kind of container is returned. If this is an array, it maintains the order in which elements first appear.\n\nUnicode ∪ can be typed by writing \\cup then pressing tab in the Julia REPL, and in many editors. This is an infix operator, allowing s ∪ itr.\n\nSee also unique, intersect, isdisjoint, vcat, Iterators.flatten.\n\nExamples\n\njulia> union([1, 2], [3])\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> union([4 2 3 4 4], 1:3, 3.0)\n4-element Vector{Float64}:\n 4.0\n 2.0\n 3.0\n 1.0\n\njulia> (0, 0.0) ∪ (-0.0, NaN)\n3-element Vector{Real}:\n 0\n -0.0\n NaN\n\njulia> union(Set([1, 2]), 2:3)\nSet{Int64} with 3 elements:\n 2\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.union!","page":"Collections and Data Structures","title":"Base.union!","text":"union!(s::Union{AbstractSet,AbstractVector}, itrs...)\n\nConstruct the union of passed in sets and overwrite s with the result. Maintain order with arrays.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> a = Set([3, 4, 5]);\n\njulia> union!(a, 1:2:7);\n\njulia> a\nSet{Int64} with 5 elements:\n 5\n 4\n 7\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.intersect","page":"Collections and Data Structures","title":"Base.intersect","text":"intersect(s, itrs...)\n∩(s, itrs...)\n\nConstruct the set containing those elements which appear in all of the arguments.\n\nThe first argument controls what kind of container is returned. If this is an array, it maintains the order in which elements first appear.\n\nUnicode ∩ can be typed by writing \\cap then pressing tab in the Julia REPL, and in many editors. This is an infix operator, allowing s ∩ itr.\n\nSee also setdiff, isdisjoint, issubset, issetequal.\n\ncompat: Julia 1.8\nAs of Julia 1.8 intersect returns a result with the eltype of the type-promoted eltypes of the two inputs\n\nExamples\n\njulia> intersect([1, 2, 3], [3, 4, 5])\n1-element Vector{Int64}:\n 3\n\njulia> intersect([1, 4, 4, 5, 6], [6, 4, 6, 7, 8])\n2-element Vector{Int64}:\n 4\n 6\n\njulia> intersect(1:16, 7:99)\n7:16\n\njulia> (0, 0.0) ∩ (-0.0, 0)\n1-element Vector{Real}:\n 0\n\njulia> intersect(Set([1, 2]), BitSet([2, 3]), 1.0:10.0)\nSet{Float64} with 1 element:\n 2.0\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.setdiff","page":"Collections and Data Structures","title":"Base.setdiff","text":"setdiff(s, itrs...)\n\nConstruct the set of elements in s but not in any of the iterables in itrs. Maintain order with arrays.\n\nSee also setdiff!, union and intersect.\n\nExamples\n\njulia> setdiff([1,2,3], [3,4,5])\n2-element Vector{Int64}:\n 1\n 2\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.setdiff!","page":"Collections and Data Structures","title":"Base.setdiff!","text":"setdiff!(s, itrs...)\n\nRemove from set s (in-place) each element of each iterable from itrs. Maintain order with arrays.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\nExamples\n\njulia> a = Set([1, 3, 4, 5]);\n\njulia> setdiff!(a, 1:2:6);\n\njulia> a\nSet{Int64} with 1 element:\n 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.symdiff","page":"Collections and Data Structures","title":"Base.symdiff","text":"symdiff(s, itrs...)\n\nConstruct the symmetric difference of elements in the passed in sets. When s is not an AbstractSet, the order is maintained.\n\nSee also symdiff!, setdiff, union and intersect.\n\nExamples\n\njulia> symdiff([1,2,3], [3,4,5], [4,5,6])\n3-element Vector{Int64}:\n 1\n 2\n 6\n\njulia> symdiff([1,2,1], [2, 1, 2])\nInt64[]\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.symdiff!","page":"Collections and Data Structures","title":"Base.symdiff!","text":"symdiff!(s::Union{AbstractSet,AbstractVector}, itrs...)\n\nConstruct the symmetric difference of the passed in sets, and overwrite s with the result. When s is an array, the order is maintained. Note that in this case the multiplicity of elements matters.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.intersect!","page":"Collections and Data Structures","title":"Base.intersect!","text":"intersect!(s::Union{AbstractSet,AbstractVector}, itrs...)\n\nIntersect all passed in sets and overwrite s with the result. Maintain order with arrays.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.issubset","page":"Collections and Data Structures","title":"Base.issubset","text":"issubset(a, b) -> Bool\n⊆(a, b) -> Bool\n⊇(b, a) -> Bool\n\nDetermine whether every element of a is also in b, using in.\n\nSee also ⊊, ⊈, ∩, ∪, contains.\n\nExamples\n\njulia> issubset([1, 2], [1, 2, 3])\ntrue\n\njulia> [1, 2, 3] ⊆ [1, 2]\nfalse\n\njulia> [1, 2, 3] ⊇ [1, 2]\ntrue\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.in!","page":"Collections and Data Structures","title":"Base.in!","text":"in!(x, s::AbstractSet) -> Bool\n\nIf x is in s, return true. If not, push x into s and return false. This is equivalent to in(x, s) ? true : (push!(s, x); false), but may have a more efficient implementation.\n\nSee also: in, push!, Set\n\ncompat: Julia 1.11\nThis function requires at least 1.11.\n\nExamples\n\njulia> s = Set{Any}([1, 2, 3]); in!(4, s)\nfalse\n\njulia> length(s)\n4\n\njulia> in!(0x04, s)\ntrue\n\njulia> s\nSet{Any} with 4 elements:\n 4\n 2\n 3\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.:⊈","page":"Collections and Data Structures","title":"Base.:⊈","text":"⊈(a, b) -> Bool\n⊉(b, a) -> Bool\n\nNegation of ⊆ and ⊇, i.e. checks that a is not a subset of b.\n\nSee also issubset (⊆), ⊊.\n\nExamples\n\njulia> (1, 2) ⊈ (2, 3)\ntrue\n\njulia> (1, 2) ⊈ (1, 2, 3)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.:⊊","page":"Collections and Data Structures","title":"Base.:⊊","text":"⊊(a, b) -> Bool\n⊋(b, a) -> Bool\n\nDetermines if a is a subset of, but not equal to, b.\n\nSee also issubset (⊆), ⊈.\n\nExamples\n\njulia> (1, 2) ⊊ (1, 2, 3)\ntrue\n\njulia> (1, 2) ⊊ (1, 2)\nfalse\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.issetequal","page":"Collections and Data Structures","title":"Base.issetequal","text":"issetequal(a, b) -> Bool\n\nDetermine whether a and b have the same elements. Equivalent to a ⊆ b && b ⊆ a but more efficient when possible.\n\nSee also: isdisjoint, union.\n\nExamples\n\njulia> issetequal([1, 2], [1, 2, 3])\nfalse\n\njulia> issetequal([1, 2], [2, 1])\ntrue\n\n\n\n\n\nissetequal(x)\n\nCreate a function that compares its argument to x using issetequal, i.e. a function equivalent to y -> issetequal(y, x). The returned function is of type Base.Fix2{typeof(issetequal)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.11\nThis functionality requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.isdisjoint","page":"Collections and Data Structures","title":"Base.isdisjoint","text":"isdisjoint(a, b) -> Bool\n\nDetermine whether the collections a and b are disjoint. Equivalent to isempty(a ∩ b) but more efficient when possible.\n\nSee also: intersect, isempty, issetequal.\n\ncompat: Julia 1.5\nThis function requires at least Julia 1.5.\n\nExamples\n\njulia> isdisjoint([1, 2], [2, 3, 4])\nfalse\n\njulia> isdisjoint([3, 1], [2, 4])\ntrue\n\n\n\n\n\nisdisjoint(x)\n\nCreate a function that compares its argument to x using isdisjoint, i.e. a function equivalent to y -> isdisjoint(y, x). The returned function is of type Base.Fix2{typeof(isdisjoint)}, which can be used to implement specialized methods.\n\ncompat: Julia 1.11\nThis functionality requires at least Julia 1.11.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Set\nBitSet\nIdSet","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Partially implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Array","category":"page"},{"location":"base/collections/#Dequeues","page":"Collections and Data Structures","title":"Dequeues","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.push!\nBase.pop!\nBase.popat!\nBase.pushfirst!\nBase.popfirst!\nBase.insert!\nBase.deleteat!\nBase.keepat!\nBase.splice!\nBase.resize!\nBase.append!\nBase.prepend!","category":"page"},{"location":"base/collections/#Base.push!","page":"Collections and Data Structures","title":"Base.push!","text":"push!(collection, items...) -> collection\n\nInsert one or more items in collection. If collection is an ordered container, the items are inserted at the end (in the given order).\n\nExamples\n\njulia> push!([1, 2, 3], 4, 5, 6)\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\nIf collection is ordered, use append! to add all the elements of another collection to it. The result of the preceding example is equivalent to append!([1, 2, 3], [4, 5, 6]). For AbstractSet objects, union! can be used instead.\n\nSee sizehint! for notes about the performance model.\n\nSee also pushfirst!.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.pop!","page":"Collections and Data Structures","title":"Base.pop!","text":"pop!(collection) -> item\n\nRemove an item in collection and return it. If collection is an ordered container, the last item is returned; for unordered containers, an arbitrary element is returned.\n\nSee also: popfirst!, popat!, delete!, deleteat!, splice!, and push!.\n\nExamples\n\njulia> A=[1, 2, 3]\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> pop!(A)\n3\n\njulia> A\n2-element Vector{Int64}:\n 1\n 2\n\njulia> S = Set([1, 2])\nSet{Int64} with 2 elements:\n 2\n 1\n\njulia> pop!(S)\n2\n\njulia> S\nSet{Int64} with 1 element:\n 1\n\njulia> pop!(Dict(1=>2))\n1 => 2\n\n\n\n\n\npop!(collection, key[, default])\n\nDelete and return the mapping for key if it exists in collection, otherwise return default, or throw an error if default is not specified.\n\nExamples\n\njulia> d = Dict(\"a\"=>1, \"b\"=>2, \"c\"=>3);\n\njulia> pop!(d, \"a\")\n1\n\njulia> pop!(d, \"d\")\nERROR: KeyError: key \"d\" not found\nStacktrace:\n[...]\n\njulia> pop!(d, \"e\", 4)\n4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.popat!","page":"Collections and Data Structures","title":"Base.popat!","text":"popat!(a::Vector, i::Integer, [default])\n\nRemove the item at the given i and return it. Subsequent items are shifted to fill the resulting gap. When i is not a valid index for a, return default, or throw an error if default is not specified.\n\nSee also: pop!, popfirst!, deleteat!, splice!.\n\ncompat: Julia 1.5\nThis function is available as of Julia 1.5.\n\nExamples\n\njulia> a = [4, 3, 2, 1]; popat!(a, 2)\n3\n\njulia> a\n3-element Vector{Int64}:\n 4\n 2\n 1\n\njulia> popat!(a, 4, missing)\nmissing\n\njulia> popat!(a, 4)\nERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.pushfirst!","page":"Collections and Data Structures","title":"Base.pushfirst!","text":"pushfirst!(collection, items...) -> collection\n\nInsert one or more items at the beginning of collection.\n\nThis function is called unshift in many other programming languages.\n\nExamples\n\njulia> pushfirst!([1, 2, 3, 4], 5, 6)\n6-element Vector{Int64}:\n 5\n 6\n 1\n 2\n 3\n 4\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.popfirst!","page":"Collections and Data Structures","title":"Base.popfirst!","text":"popfirst!(collection) -> item\n\nRemove the first item from collection.\n\nThis function is called shift in many other programming languages.\n\nSee also: pop!, popat!, delete!.\n\nExamples\n\njulia> A = [1, 2, 3, 4, 5, 6]\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\njulia> popfirst!(A)\n1\n\njulia> A\n5-element Vector{Int64}:\n 2\n 3\n 4\n 5\n 6\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.insert!","page":"Collections and Data Structures","title":"Base.insert!","text":"insert!(a::Vector, index::Integer, item)\n\nInsert an item into a at the given index. index is the index of item in the resulting a.\n\nSee also: push!, replace, popat!, splice!.\n\nExamples\n\njulia> insert!(Any[1:6;], 3, \"here\")\n7-element Vector{Any}:\n 1\n 2\n \"here\"\n 3\n 4\n 5\n 6\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.deleteat!","page":"Collections and Data Structures","title":"Base.deleteat!","text":"deleteat!(a::Vector, i::Integer)\n\nRemove the item at the given i and return the modified a. Subsequent items are shifted to fill the resulting gap.\n\nSee also: keepat!, delete!, popat!, splice!.\n\nExamples\n\njulia> deleteat!([6, 5, 4, 3, 2, 1], 2)\n5-element Vector{Int64}:\n 6\n 4\n 3\n 2\n 1\n\n\n\n\n\ndeleteat!(a::Vector, inds)\n\nRemove the items at the indices given by inds, and return the modified a. Subsequent items are shifted to fill the resulting gap.\n\ninds can be either an iterator or a collection of sorted and unique integer indices, or a boolean vector of the same length as a with true indicating entries to delete.\n\nExamples\n\njulia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)\n3-element Vector{Int64}:\n 5\n 3\n 1\n\njulia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])\n3-element Vector{Int64}:\n 5\n 3\n 1\n\njulia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))\nERROR: ArgumentError: indices must be unique and sorted\nStacktrace:\n[...]\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.keepat!","page":"Collections and Data Structures","title":"Base.keepat!","text":"keepat!(a::Vector, inds)\nkeepat!(a::BitVector, inds)\n\nRemove the items at all the indices which are not given by inds, and return the modified a. Items which are kept are shifted to fill the resulting gaps.\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\ninds must be an iterator of sorted and unique integer indices. See also deleteat!.\n\ncompat: Julia 1.7\nThis function is available as of Julia 1.7.\n\nExamples\n\njulia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)\n3-element Vector{Int64}:\n 6\n 4\n 2\n\n\n\n\n\nkeepat!(a::Vector, m::AbstractVector{Bool})\nkeepat!(a::BitVector, m::AbstractVector{Bool})\n\nThe in-place version of logical indexing a = a[m]. That is, keepat!(a, m) on vectors of equal length a and m will remove all elements from a for which m at the corresponding index is false.\n\nExamples\n\njulia> a = [:a, :b, :c];\n\njulia> keepat!(a, [true, false, true])\n2-element Vector{Symbol}:\n :a\n :c\n\njulia> a\n2-element Vector{Symbol}:\n :a\n :c\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.splice!","page":"Collections and Data Structures","title":"Base.splice!","text":"splice!(a::Vector, index::Integer, [replacement]) -> item\n\nRemove the item at the given index, and return the removed item. Subsequent items are shifted left to fill the resulting gap. If specified, replacement values from an ordered collection will be spliced in place of the removed item.\n\nSee also: replace, delete!, deleteat!, pop!, popat!.\n\nExamples\n\njulia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)\n2\n\njulia> A\n5-element Vector{Int64}:\n 6\n 5\n 4\n 3\n 1\n\njulia> splice!(A, 5, -1)\n1\n\njulia> A\n5-element Vector{Int64}:\n 6\n 5\n 4\n 3\n -1\n\njulia> splice!(A, 1, [-1, -2, -3])\n6\n\njulia> A\n7-element Vector{Int64}:\n -1\n -2\n -3\n 5\n 4\n 3\n -1\n\nTo insert replacement before an index n without removing any items, use splice!(collection, n:n-1, replacement).\n\n\n\n\n\nsplice!(a::Vector, indices, [replacement]) -> items\n\nRemove items at specified indices, and return a collection containing the removed items. Subsequent items are shifted left to fill the resulting gaps. If specified, replacement values from an ordered collection will be spliced in place of the removed items; in this case, indices must be a AbstractUnitRange.\n\nTo insert replacement before an index n without removing any items, use splice!(collection, n:n-1, replacement).\n\nwarning: Warning\nBehavior can be unexpected when any mutated argument shares memory with any other argument.\n\ncompat: Julia 1.5\nPrior to Julia 1.5, indices must always be a UnitRange.\n\ncompat: Julia 1.8\nPrior to Julia 1.8, indices must be a UnitRange if splicing in replacement values.\n\nExamples\n\njulia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)\nInt64[]\n\njulia> A\n8-element Vector{Int64}:\n -1\n -2\n -3\n 2\n 5\n 4\n 3\n -1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.resize!","page":"Collections and Data Structures","title":"Base.resize!","text":"resize!(a::Vector, n::Integer) -> Vector\n\nResize a to contain n elements. If n is smaller than the current collection length, the first n elements will be retained. If n is larger, the new elements are not guaranteed to be initialized.\n\nExamples\n\njulia> resize!([6, 5, 4, 3, 2, 1], 3)\n3-element Vector{Int64}:\n 6\n 5\n 4\n\njulia> a = resize!([6, 5, 4, 3, 2, 1], 8);\n\njulia> length(a)\n8\n\njulia> a[1:6]\n6-element Vector{Int64}:\n 6\n 5\n 4\n 3\n 2\n 1\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.append!","page":"Collections and Data Structures","title":"Base.append!","text":"append!(collection, collections...) -> collection.\n\nFor an ordered container collection, add the elements of each collections to the end of it.\n\ncompat: Julia 1.6\nSpecifying multiple collections to be appended requires at least Julia 1.6.\n\nExamples\n\njulia> append!([1], [2, 3])\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> append!([1, 2, 3], [4, 5], [6])\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\nUse push! to add individual items to collection which are not already themselves in another collection. The result of the preceding example is equivalent to push!([1, 2, 3], 4, 5, 6).\n\nSee sizehint! for notes about the performance model.\n\nSee also vcat for vectors, union! for sets, and prepend! and pushfirst! for the opposite order.\n\n\n\n\n\n","category":"function"},{"location":"base/collections/#Base.prepend!","page":"Collections and Data Structures","title":"Base.prepend!","text":"prepend!(a::Vector, collections...) -> collection\n\nInsert the elements of each collections to the beginning of a.\n\nWhen collections specifies multiple collections, order is maintained: elements of collections[1] will appear leftmost in a, and so on.\n\ncompat: Julia 1.6\nSpecifying multiple collections to be prepended requires at least Julia 1.6.\n\nExamples\n\njulia> prepend!([3], [1, 2])\n3-element Vector{Int64}:\n 1\n 2\n 3\n\njulia> prepend!([6], [1, 2], [3, 4, 5])\n6-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n\n\n\n\n\n","category":"function"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Fully implemented by:","category":"page"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Vector (a.k.a. 1-dimensional Array)\nBitVector (a.k.a. 1-dimensional BitArray)","category":"page"},{"location":"base/collections/#Utility-Collections","page":"Collections and Data Structures","title":"Utility Collections","text":"","category":"section"},{"location":"base/collections/","page":"Collections and Data Structures","title":"Collections and Data Structures","text":"Base.Pair\nIterators.Pairs","category":"page"},{"location":"base/collections/#Core.Pair","page":"Collections and Data Structures","title":"Core.Pair","text":"Pair(x, y)\nx => y\n\nConstruct a Pair object with type Pair{typeof(x), typeof(y)}. The elements are stored in the fields first and second. They can also be accessed via iteration (but a Pair is treated as a single \"scalar\" for broadcasting operations).\n\nSee also Dict.\n\nExamples\n\njulia> p = \"foo\" => 7\n\"foo\" => 7\n\njulia> typeof(p)\nPair{String, Int64}\n\njulia> p.first\n\"foo\"\n\njulia> for x in p\n println(x)\n end\nfoo\n7\n\njulia> replace.([\"xops\", \"oxps\"], \"x\" => \"o\")\n2-element Vector{String}:\n \"oops\"\n \"oops\"\n\n\n\n\n\n","category":"type"},{"location":"base/collections/#Base.Pairs","page":"Collections and Data Structures","title":"Base.Pairs","text":"Base.Pairs(values, keys) <: AbstractDict{eltype(keys), eltype(values)}\n\nTransforms an indexable container into a Dictionary-view of the same data. Modifying the key-space of the underlying data may invalidate this object.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#man-distributed","page":"Distributed Computing","title":"Distributed Computing","text":"","category":"section"},{"location":"stdlib/Distributed/","page":"Distributed Computing","title":"Distributed Computing","text":"Distributed\nDistributed.addprocs\nDistributed.nprocs\nDistributed.nworkers\nDistributed.procs()\nDistributed.procs(::Integer)\nDistributed.workers\nDistributed.rmprocs\nDistributed.interrupt\nDistributed.myid\nDistributed.pmap\nDistributed.RemoteException\nDistributed.ProcessExitedException\nDistributed.Future\nDistributed.RemoteChannel\nDistributed.fetch(::Distributed.Future)\nDistributed.fetch(::RemoteChannel)\nDistributed.remotecall(::Any, ::Integer, ::Any...)\nDistributed.remotecall_wait(::Any, ::Integer, ::Any...)\nDistributed.remotecall_fetch(::Any, ::Integer, ::Any...)\nDistributed.remote_do(::Any, ::Integer, ::Any...)\nDistributed.put!(::RemoteChannel, ::Any...)\nDistributed.put!(::Distributed.Future, ::Any)\nDistributed.take!(::RemoteChannel, ::Any...)\nDistributed.isready(::RemoteChannel, ::Any...)\nDistributed.isready(::Distributed.Future)\nDistributed.AbstractWorkerPool\nDistributed.WorkerPool\nDistributed.CachingPool\nDistributed.default_worker_pool\nDistributed.clear!\nDistributed.remote\nDistributed.remotecall(::Any, ::AbstractWorkerPool, ::Any...)\nDistributed.remotecall_wait(::Any, ::AbstractWorkerPool, ::Any...)\nDistributed.remotecall_fetch(::Any, ::AbstractWorkerPool, ::Any...)\nDistributed.remote_do(::Any, ::AbstractWorkerPool, ::Any...)\nDistributed.@spawn\nDistributed.@spawnat\nDistributed.@fetch\nDistributed.@fetchfrom\nDistributed.@distributed\nDistributed.@everywhere\nDistributed.remoteref_id\nDistributed.channel_from_id\nDistributed.worker_id_from_socket\nDistributed.cluster_cookie()\nDistributed.cluster_cookie(::Any)","category":"page"},{"location":"stdlib/Distributed/#Distributed","page":"Distributed Computing","title":"Distributed","text":"Tools for distributed parallel processing.\n\n\n\n\n\n","category":"module"},{"location":"stdlib/Distributed/#Distributed.addprocs","page":"Distributed Computing","title":"Distributed.addprocs","text":"addprocs(manager::ClusterManager; kwargs...) -> List of process identifiers\n\nLaunches worker processes via the specified cluster manager.\n\nFor example, Beowulf clusters are supported via a custom cluster manager implemented in the package ClusterManagers.jl.\n\nThe number of seconds a newly launched worker waits for connection establishment from the master can be specified via variable JULIA_WORKER_TIMEOUT in the worker process's environment. Relevant only when using TCP/IP as transport.\n\nTo launch workers without blocking the REPL, or the containing function if launching workers programmatically, execute addprocs in its own task.\n\nExamples\n\n# On busy clusters, call `addprocs` asynchronously\nt = @async addprocs(...)\n\n# Utilize workers as and when they come online\nif nprocs() > 1 # Ensure at least one new worker is available\n .... # perform distributed execution\nend\n\n# Retrieve newly launched worker IDs, or any error messages\nif istaskdone(t) # Check if `addprocs` has completed to ensure `fetch` doesn't block\n if nworkers() == N\n new_pids = fetch(t)\n else\n fetch(t)\n end\nend\n\n\n\n\n\naddprocs(machines; tunnel=false, sshflags=``, max_parallel=10, kwargs...) -> List of process identifiers\n\nAdd worker processes on remote machines via SSH. Configuration is done with keyword arguments (see below). In particular, the exename keyword can be used to specify the path to the julia binary on the remote machine(s).\n\nmachines is a vector of \"machine specifications\" which are given as strings of the form [user@]host[:port] [bind_addr[:port]]. user defaults to current user and port to the standard SSH port. If [bind_addr[:port]] is specified, other workers will connect to this worker at the specified bind_addr and port.\n\nIt is possible to launch multiple processes on a remote host by using a tuple in the machines vector or the form (machine_spec, count), where count is the number of workers to be launched on the specified host. Passing :auto as the worker count will launch as many workers as the number of CPU threads on the remote host.\n\nExamples:\n\naddprocs([\n \"remote1\", # one worker on 'remote1' logging in with the current username\n \"user@remote2\", # one worker on 'remote2' logging in with the 'user' username\n \"user@remote3:2222\", # specifying SSH port to '2222' for 'remote3'\n (\"user@remote4\", 4), # launch 4 workers on 'remote4'\n (\"user@remote5\", :auto), # launch as many workers as CPU threads on 'remote5'\n])\n\nKeyword arguments:\n\ntunnel: if true then SSH tunneling will be used to connect to the worker from the master process. Default is false.\nmultiplex: if true then SSH multiplexing is used for SSH tunneling. Default is false.\nssh: the name or path of the SSH client executable used to start the workers. Default is \"ssh\".\nsshflags: specifies additional ssh options, e.g. sshflags=`-i /home/foo/bar.pem`\nmax_parallel: specifies the maximum number of workers connected to in parallel at a host. Defaults to 10.\nshell: specifies the type of shell to which ssh connects on the workers.\nshell=:posix: a POSIX-compatible Unix/Linux shell (sh, ksh, bash, dash, zsh, etc.). The default.\nshell=:csh: a Unix C shell (csh, tcsh).\nshell=:wincmd: Microsoft Windows cmd.exe.\ndir: specifies the working directory on the workers. Defaults to the host's current directory (as found by pwd())\nenable_threaded_blas: if true then BLAS will run on multiple threads in added processes. Default is false.\nexename: name of the julia executable. Defaults to \"$(Sys.BINDIR)/julia\" or \"$(Sys.BINDIR)/julia-debug\" as the case may be. It is recommended that a common Julia version is used on all remote machines because serialization and code distribution might fail otherwise.\nexeflags: additional flags passed to the worker processes.\ntopology: Specifies how the workers connect to each other. Sending a message between unconnected workers results in an error.\ntopology=:all_to_all: All processes are connected to each other. The default.\ntopology=:master_worker: Only the driver process, i.e. pid 1 connects to the workers. The workers do not connect to each other.\ntopology=:custom: The launch method of the cluster manager specifies the connection topology via fields ident and connect_idents in WorkerConfig. A worker with a cluster manager identity ident will connect to all workers specified in connect_idents.\nlazy: Applicable only with topology=:all_to_all. If true, worker-worker connections are setup lazily, i.e. they are setup at the first instance of a remote call between workers. Default is true.\nenv: provide an array of string pairs such as env=[\"JULIA_DEPOT_PATH\"=>\"/depot\"] to request that environment variables are set on the remote machine. By default only the environment variable JULIA_WORKER_TIMEOUT is passed automatically from the local to the remote environment.\ncmdline_cookie: pass the authentication cookie via the --worker commandline option. The (more secure) default behaviour of passing the cookie via ssh stdio may hang with Windows workers that use older (pre-ConPTY) Julia or Windows versions, in which case cmdline_cookie=true offers a work-around.\n\ncompat: Julia 1.6\nThe keyword arguments ssh, shell, env and cmdline_cookie were added in Julia 1.6.\n\nEnvironment variables:\n\nIf the master process fails to establish a connection with a newly launched worker within 60.0 seconds, the worker treats it as a fatal situation and terminates. This timeout can be controlled via environment variable JULIA_WORKER_TIMEOUT. The value of JULIA_WORKER_TIMEOUT on the master process specifies the number of seconds a newly launched worker waits for connection establishment.\n\n\n\n\n\naddprocs(np::Integer=Sys.CPU_THREADS; restrict=true, kwargs...) -> List of process identifiers\n\nLaunch np workers on the local host using the in-built LocalManager.\n\nLocal workers inherit the current package environment (i.e., active project, LOAD_PATH, and DEPOT_PATH) from the main process.\n\nwarning: Warning\nNote that workers do not run a ~/.julia/config/startup.jl startup script, nor do they synchronize their global state (such as command-line switches, global variables, new method definitions, and loaded modules) with any of the other running processes.\n\nKeyword arguments:\n\nrestrict::Bool: if true (default) binding is restricted to 127.0.0.1.\ndir, exename, exeflags, env, topology, lazy, enable_threaded_blas: same effect as for SSHManager, see documentation for addprocs(machines::AbstractVector).\n\ncompat: Julia 1.9\nThe inheriting of the package environment and the env keyword argument were added in Julia 1.9.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.nprocs","page":"Distributed Computing","title":"Distributed.nprocs","text":"nprocs()\n\nGet the number of available processes.\n\nExamples\n\njulia> nprocs()\n3\n\njulia> workers()\n2-element Array{Int64,1}:\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.nworkers","page":"Distributed Computing","title":"Distributed.nworkers","text":"nworkers()\n\nGet the number of available worker processes. This is one less than nprocs(). Equal to nprocs() if nprocs() == 1.\n\nExamples\n\n$ julia -p 2\n\njulia> nprocs()\n3\n\njulia> nworkers()\n2\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.procs-Tuple{}","page":"Distributed Computing","title":"Distributed.procs","text":"procs()\n\nReturn a list of all process identifiers, including pid 1 (which is not included by workers()).\n\nExamples\n\n$ julia -p 2\n\njulia> procs()\n3-element Array{Int64,1}:\n 1\n 2\n 3\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.procs-Tuple{Integer}","page":"Distributed Computing","title":"Distributed.procs","text":"procs(pid::Integer)\n\nReturn a list of all process identifiers on the same physical node. Specifically all workers bound to the same ip-address as pid are returned.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.workers","page":"Distributed Computing","title":"Distributed.workers","text":"workers()\n\nReturn a list of all worker process identifiers.\n\nExamples\n\n$ julia -p 2\n\njulia> workers()\n2-element Array{Int64,1}:\n 2\n 3\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.rmprocs","page":"Distributed Computing","title":"Distributed.rmprocs","text":"rmprocs(pids...; waitfor=typemax(Int))\n\nRemove the specified workers. Note that only process 1 can add or remove workers.\n\nArgument waitfor specifies how long to wait for the workers to shut down:\n\nIf unspecified, rmprocs will wait until all requested pids are removed.\nAn ErrorException is raised if all workers cannot be terminated before the requested waitfor seconds.\nWith a waitfor value of 0, the call returns immediately with the workers scheduled for removal in a different task. The scheduled Task object is returned. The user should call wait on the task before invoking any other parallel calls.\n\nExamples\n\n$ julia -p 5\n\njulia> t = rmprocs(2, 3, waitfor=0)\nTask (runnable) @0x0000000107c718d0\n\njulia> wait(t)\n\njulia> workers()\n3-element Array{Int64,1}:\n 4\n 5\n 6\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.interrupt","page":"Distributed Computing","title":"Distributed.interrupt","text":"interrupt(pids::Integer...)\n\nInterrupt the current executing task on the specified workers. This is equivalent to pressing Ctrl-C on the local machine. If no arguments are given, all workers are interrupted.\n\n\n\n\n\ninterrupt(pids::AbstractVector=workers())\n\nInterrupt the current executing task on the specified workers. This is equivalent to pressing Ctrl-C on the local machine. If no arguments are given, all workers are interrupted.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.myid","page":"Distributed Computing","title":"Distributed.myid","text":"myid()\n\nGet the id of the current process.\n\nExamples\n\njulia> myid()\n1\n\njulia> remotecall_fetch(() -> myid(), 4)\n4\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.pmap","page":"Distributed Computing","title":"Distributed.pmap","text":"pmap(f, [::AbstractWorkerPool], c...; distributed=true, batch_size=1, on_error=nothing, retry_delays=[], retry_check=nothing) -> collection\n\nTransform collection c by applying f to each element using available workers and tasks.\n\nFor multiple collection arguments, apply f elementwise.\n\nNote that f must be made available to all worker processes; see Code Availability and Loading Packages for details.\n\nIf a worker pool is not specified all available workers will be used via a CachingPool.\n\nBy default, pmap distributes the computation over all specified workers. To use only the local process and distribute over tasks, specify distributed=false. This is equivalent to using asyncmap. For example, pmap(f, c; distributed=false) is equivalent to asyncmap(f,c; ntasks=()->nworkers())\n\npmap can also use a mix of processes and tasks via the batch_size argument. For batch sizes greater than 1, the collection is processed in multiple batches, each of length batch_size or less. A batch is sent as a single request to a free worker, where a local asyncmap processes elements from the batch using multiple concurrent tasks.\n\nAny error stops pmap from processing the remainder of the collection. To override this behavior you can specify an error handling function via argument on_error which takes in a single argument, i.e., the exception. The function can stop the processing by rethrowing the error, or, to continue, return any value which is then returned inline with the results to the caller.\n\nConsider the following two examples. The first one returns the exception object inline, the second a 0 in place of any exception:\n\njulia> pmap(x->iseven(x) ? error(\"foo\") : x, 1:4; on_error=identity)\n4-element Array{Any,1}:\n 1\n ErrorException(\"foo\")\n 3\n ErrorException(\"foo\")\n\njulia> pmap(x->iseven(x) ? error(\"foo\") : x, 1:4; on_error=ex->0)\n4-element Array{Int64,1}:\n 1\n 0\n 3\n 0\n\nErrors can also be handled by retrying failed computations. Keyword arguments retry_delays and retry_check are passed through to retry as keyword arguments delays and check respectively. If batching is specified, and an entire batch fails, all items in the batch are retried.\n\nNote that if both on_error and retry_delays are specified, the on_error hook is called before retrying. If on_error does not throw (or rethrow) an exception, the element will not be retried.\n\nExample: On errors, retry f on an element a maximum of 3 times without any delay between retries.\n\npmap(f, c; retry_delays = zeros(3))\n\nExample: Retry f only if the exception is not of type InexactError, with exponentially increasing delays up to 3 times. Return a NaN in place for all InexactError occurrences.\n\npmap(f, c; on_error = e->(isa(e, InexactError) ? NaN : rethrow()), retry_delays = ExponentialBackOff(n = 3))\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.RemoteException","page":"Distributed Computing","title":"Distributed.RemoteException","text":"RemoteException(captured)\n\nExceptions on remote computations are captured and rethrown locally. A RemoteException wraps the pid of the worker and a captured exception. A CapturedException captures the remote exception and a serializable form of the call stack when the exception was raised.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.ProcessExitedException","page":"Distributed Computing","title":"Distributed.ProcessExitedException","text":"ProcessExitedException(worker_id::Int)\n\nAfter a client Julia process has exited, further attempts to reference the dead child will throw this exception.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.Future","page":"Distributed Computing","title":"Distributed.Future","text":"Future(w::Int, rrid::RRID, v::Union{Some, Nothing}=nothing)\n\nA Future is a placeholder for a single computation of unknown termination status and time. For multiple potential computations, see RemoteChannel. See remoteref_id for identifying an AbstractRemoteRef.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.RemoteChannel","page":"Distributed Computing","title":"Distributed.RemoteChannel","text":"RemoteChannel(pid::Integer=myid())\n\nMake a reference to a Channel{Any}(1) on process pid. The default pid is the current process.\n\nRemoteChannel(f::Function, pid::Integer=myid())\n\nCreate references to remote channels of a specific size and type. f is a function that when executed on pid must return an implementation of an AbstractChannel.\n\nFor example, RemoteChannel(()->Channel{Int}(10), pid), will return a reference to a channel of type Int and size 10 on pid.\n\nThe default pid is the current process.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Base.fetch-Tuple{Distributed.Future}","page":"Distributed Computing","title":"Base.fetch","text":"fetch(x::Future)\n\nWait for and get the value of a Future. The fetched value is cached locally. Further calls to fetch on the same reference return the cached value. If the remote value is an exception, throws a RemoteException which captures the remote exception and backtrace.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.fetch-Tuple{RemoteChannel}","page":"Distributed Computing","title":"Base.fetch","text":"fetch(c::RemoteChannel)\n\nWait for and get a value from a RemoteChannel. Exceptions raised are the same as for a Future. Does not remove the item fetched.\n\n\n\n\n\nfetch(x::Any)\n\nReturn x.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall-Tuple{Any, Integer, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall","text":"remotecall(f, id::Integer, args...; kwargs...) -> Future\n\nCall a function f asynchronously on the given arguments on the specified process. Return a Future. Keyword arguments, if any, are passed through to f.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall_wait-Tuple{Any, Integer, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall_wait","text":"remotecall_wait(f, id::Integer, args...; kwargs...)\n\nPerform a faster wait(remotecall(...)) in one message on the Worker specified by worker id id. Keyword arguments, if any, are passed through to f.\n\nSee also wait and remotecall.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall_fetch-Tuple{Any, Integer, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall_fetch","text":"remotecall_fetch(f, id::Integer, args...; kwargs...)\n\nPerform fetch(remotecall(...)) in one message. Keyword arguments, if any, are passed through to f. Any remote exceptions are captured in a RemoteException and thrown.\n\nSee also fetch and remotecall.\n\nExamples\n\n$ julia -p 2\n\njulia> remotecall_fetch(sqrt, 2, 4)\n2.0\n\njulia> remotecall_fetch(sqrt, 2, -4)\nERROR: On worker 2:\nDomainError with -4.0:\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\n...\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remote_do-Tuple{Any, Integer, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remote_do","text":"remote_do(f, id::Integer, args...; kwargs...) -> nothing\n\nExecutes f on worker id asynchronously. Unlike remotecall, it does not store the result of computation, nor is there a way to wait for its completion.\n\nA successful invocation indicates that the request has been accepted for execution on the remote node.\n\nWhile consecutive remotecalls to the same worker are serialized in the order they are invoked, the order of executions on the remote worker is undetermined. For example, remote_do(f1, 2); remotecall(f2, 2); remote_do(f3, 2) will serialize the call to f1, followed by f2 and f3 in that order. However, it is not guaranteed that f1 is executed before f3 on worker 2.\n\nAny exceptions thrown by f are printed to stderr on the remote worker.\n\nKeyword arguments, if any, are passed through to f.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.put!-Tuple{RemoteChannel, Vararg{Any}}","page":"Distributed Computing","title":"Base.put!","text":"put!(rr::RemoteChannel, args...)\n\nStore a set of values to the RemoteChannel. If the channel is full, blocks until space is available. Return the first argument.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.put!-Tuple{Distributed.Future, Any}","page":"Distributed Computing","title":"Base.put!","text":"put!(rr::Future, v)\n\nStore a value to a Future rr. Futures are write-once remote references. A put! on an already set Future throws an Exception. All asynchronous remote calls return Futures and set the value to the return value of the call upon completion.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.take!-Tuple{RemoteChannel, Vararg{Any}}","page":"Distributed Computing","title":"Base.take!","text":"take!(rr::RemoteChannel, args...)\n\nFetch value(s) from a RemoteChannel rr, removing the value(s) in the process.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.isready-Tuple{RemoteChannel, Vararg{Any}}","page":"Distributed Computing","title":"Base.isready","text":"isready(rr::RemoteChannel, args...)\n\nDetermine whether a RemoteChannel has a value stored to it. Note that this function can cause race conditions, since by the time you receive its result it may no longer be true. However, it can be safely used on a Future since they are assigned only once.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Base.isready-Tuple{Distributed.Future}","page":"Distributed Computing","title":"Base.isready","text":"isready(rr::Future)\n\nDetermine whether a Future has a value stored to it.\n\nIf the argument Future is owned by a different node, this call will block to wait for the answer. It is recommended to wait for rr in a separate task instead or to use a local Channel as a proxy:\n\np = 1\nf = Future(p)\nerrormonitor(@async put!(f, remotecall_fetch(long_computation, p)))\nisready(f) # will not block\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.AbstractWorkerPool","page":"Distributed Computing","title":"Distributed.AbstractWorkerPool","text":"AbstractWorkerPool\n\nSupertype for worker pools such as WorkerPool and CachingPool. An AbstractWorkerPool should implement:\n\npush! - add a new worker to the overall pool (available + busy)\nput! - put back a worker to the available pool\ntake! - take a worker from the available pool (to be used for remote function execution)\nlength - number of workers available in the overall pool\nisready - return false if a take! on the pool would block, else true\n\nThe default implementations of the above (on a AbstractWorkerPool) require fields\n\nchannel::Channel{Int}\nworkers::Set{Int}\n\nwhere channel contains free worker pids and workers is the set of all workers associated with this pool.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.WorkerPool","page":"Distributed Computing","title":"Distributed.WorkerPool","text":"WorkerPool(workers::Union{Vector{Int},AbstractRange{Int}})\n\nCreate a WorkerPool from a vector or range of worker ids.\n\nExamples\n\n$ julia -p 3\n\njulia> WorkerPool([2, 3])\nWorkerPool(Channel{Int64}(sz_max:9223372036854775807,sz_curr:2), Set([2, 3]), RemoteChannel{Channel{Any}}(1, 1, 6))\n\njulia> WorkerPool(2:4)\nWorkerPool(Channel{Int64}(sz_max:9223372036854775807,sz_curr:2), Set([4, 2, 3]), RemoteChannel{Channel{Any}}(1, 1, 7))\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.CachingPool","page":"Distributed Computing","title":"Distributed.CachingPool","text":"CachingPool(workers::Vector{Int})\n\nAn implementation of an AbstractWorkerPool. remote, remotecall_fetch, pmap (and other remote calls which execute functions remotely) benefit from caching the serialized/deserialized functions on the worker nodes, especially closures (which may capture large amounts of data).\n\nThe remote cache is maintained for the lifetime of the returned CachingPool object. To clear the cache earlier, use clear!(pool).\n\nFor global variables, only the bindings are captured in a closure, not the data. let blocks can be used to capture global data.\n\nExamples\n\nconst foo = rand(10^8);\nwp = CachingPool(workers())\nlet foo = foo\n pmap(i -> sum(foo) + i, wp, 1:100);\nend\n\nThe above would transfer foo only once to each worker.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.default_worker_pool","page":"Distributed Computing","title":"Distributed.default_worker_pool","text":"default_worker_pool()\n\nAbstractWorkerPool containing idle workers - used by remote(f) and pmap (by default). Unless one is explicitly set via default_worker_pool!(pool), the default worker pool is initialized to a WorkerPool.\n\nExamples\n\n$ julia -p 3\n\njulia> default_worker_pool()\nWorkerPool(Channel{Int64}(sz_max:9223372036854775807,sz_curr:3), Set([4, 2, 3]), RemoteChannel{Channel{Any}}(1, 1, 4))\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.clear!","page":"Distributed Computing","title":"Distributed.clear!","text":"clear!(syms, pids=workers(); mod=Main)\n\nClears global bindings in modules by initializing them to nothing. syms should be of type Symbol or a collection of Symbols . pids and mod identify the processes and the module in which global variables are to be reinitialized. Only those names found to be defined under mod are cleared.\n\nAn exception is raised if a global constant is requested to be cleared.\n\n\n\n\n\nclear!(pool::CachingPool) -> pool\n\nRemoves all cached functions from all participating workers.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.remote","page":"Distributed Computing","title":"Distributed.remote","text":"remote([p::AbstractWorkerPool], f) -> Function\n\nReturn an anonymous function that executes function f on an available worker (drawn from WorkerPool p if provided) using remotecall_fetch.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.remotecall-Tuple{Any, AbstractWorkerPool, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall","text":"remotecall(f, pool::AbstractWorkerPool, args...; kwargs...) -> Future\n\nWorkerPool variant of remotecall(f, pid, ....). Wait for and take a free worker from pool and perform a remotecall on it.\n\nExamples\n\n$ julia -p 3\n\njulia> wp = WorkerPool([2, 3]);\n\njulia> A = rand(3000);\n\njulia> f = remotecall(maximum, wp, A)\nFuture(2, 1, 6, nothing)\n\nIn this example, the task ran on pid 2, called from pid 1.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall_wait-Tuple{Any, AbstractWorkerPool, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall_wait","text":"remotecall_wait(f, pool::AbstractWorkerPool, args...; kwargs...) -> Future\n\nWorkerPool variant of remotecall_wait(f, pid, ....). Wait for and take a free worker from pool and perform a remotecall_wait on it.\n\nExamples\n\n$ julia -p 3\n\njulia> wp = WorkerPool([2, 3]);\n\njulia> A = rand(3000);\n\njulia> f = remotecall_wait(maximum, wp, A)\nFuture(3, 1, 9, nothing)\n\njulia> fetch(f)\n0.9995177101692958\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remotecall_fetch-Tuple{Any, AbstractWorkerPool, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remotecall_fetch","text":"remotecall_fetch(f, pool::AbstractWorkerPool, args...; kwargs...) -> result\n\nWorkerPool variant of remotecall_fetch(f, pid, ....). Waits for and takes a free worker from pool and performs a remotecall_fetch on it.\n\nExamples\n\n$ julia -p 3\n\njulia> wp = WorkerPool([2, 3]);\n\njulia> A = rand(3000);\n\njulia> remotecall_fetch(maximum, wp, A)\n0.9995177101692958\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.remote_do-Tuple{Any, AbstractWorkerPool, Vararg{Any}}","page":"Distributed Computing","title":"Distributed.remote_do","text":"remote_do(f, pool::AbstractWorkerPool, args...; kwargs...) -> nothing\n\nWorkerPool variant of remote_do(f, pid, ....). Wait for and take a free worker from pool and perform a remote_do on it.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.@spawn","page":"Distributed Computing","title":"Distributed.@spawn","text":"@spawn expr\n\nCreate a closure around an expression and run it on an automatically-chosen process, returning a Future to the result. This macro is deprecated; @spawnat :any expr should be used instead.\n\nExamples\n\njulia> addprocs(3);\n\njulia> f = @spawn myid()\nFuture(2, 1, 5, nothing)\n\njulia> fetch(f)\n2\n\njulia> f = @spawn myid()\nFuture(3, 1, 7, nothing)\n\njulia> fetch(f)\n3\n\ncompat: Julia 1.3\nAs of Julia 1.3 this macro is deprecated. Use @spawnat :any instead.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@spawnat","page":"Distributed Computing","title":"Distributed.@spawnat","text":"@spawnat p expr\n\nCreate a closure around an expression and run the closure asynchronously on process p. Return a Future to the result. If p is the quoted literal symbol :any, then the system will pick a processor to use automatically.\n\nExamples\n\njulia> addprocs(3);\n\njulia> f = @spawnat 2 myid()\nFuture(2, 1, 3, nothing)\n\njulia> fetch(f)\n2\n\njulia> f = @spawnat :any myid()\nFuture(3, 1, 7, nothing)\n\njulia> fetch(f)\n3\n\ncompat: Julia 1.3\nThe :any argument is available as of Julia 1.3.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@fetch","page":"Distributed Computing","title":"Distributed.@fetch","text":"@fetch expr\n\nEquivalent to fetch(@spawnat :any expr). See fetch and @spawnat.\n\nExamples\n\njulia> addprocs(3);\n\njulia> @fetch myid()\n2\n\njulia> @fetch myid()\n3\n\njulia> @fetch myid()\n4\n\njulia> @fetch myid()\n2\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@fetchfrom","page":"Distributed Computing","title":"Distributed.@fetchfrom","text":"@fetchfrom\n\nEquivalent to fetch(@spawnat p expr). See fetch and @spawnat.\n\nExamples\n\njulia> addprocs(3);\n\njulia> @fetchfrom 2 myid()\n2\n\njulia> @fetchfrom 4 myid()\n4\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@distributed","page":"Distributed Computing","title":"Distributed.@distributed","text":"@distributed\n\nA distributed memory, parallel for loop of the form :\n\n@distributed [reducer] for var = range\n body\nend\n\nThe specified range is partitioned and locally executed across all workers. In case an optional reducer function is specified, @distributed performs local reductions on each worker with a final reduction on the calling process.\n\nNote that without a reducer function, @distributed executes asynchronously, i.e. it spawns independent tasks on all available workers and returns immediately without waiting for completion. To wait for completion, prefix the call with @sync, like :\n\n@sync @distributed for var = range\n body\nend\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.@everywhere","page":"Distributed Computing","title":"Distributed.@everywhere","text":"@everywhere [procs()] expr\n\nExecute an expression under Main on all procs. Errors on any of the processes are collected into a CompositeException and thrown. For example:\n\n@everywhere bar = 1\n\nwill define Main.bar on all current processes. Any processes added later (say with addprocs()) will not have the expression defined.\n\nUnlike @spawnat, @everywhere does not capture any local variables. Instead, local variables can be broadcast using interpolation:\n\nfoo = 1\n@everywhere bar = $foo\n\nThe optional argument procs allows specifying a subset of all processes to have execute the expression.\n\nSimilar to calling remotecall_eval(Main, procs, expr), but with two extra features:\n\n- `using` and `import` statements run on the calling process first, to ensure\n packages are precompiled.\n- The current source file path used by `include` is propagated to other processes.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Distributed/#Distributed.remoteref_id","page":"Distributed Computing","title":"Distributed.remoteref_id","text":"remoteref_id(r::AbstractRemoteRef) -> RRID\n\nFutures and RemoteChannels are identified by fields:\n\nwhere - refers to the node where the underlying object/storage referred to by the reference actually exists.\nwhence - refers to the node the remote reference was created from. Note that this is different from the node where the underlying object referred to actually exists. For example calling RemoteChannel(2) from the master process would result in a where value of 2 and a whence value of 1.\nid is unique across all references created from the worker specified by whence.\n\nTaken together, whence and id uniquely identify a reference across all workers.\n\nremoteref_id is a low-level API which returns a RRID object that wraps whence and id values of a remote reference.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.channel_from_id","page":"Distributed Computing","title":"Distributed.channel_from_id","text":"channel_from_id(id) -> c\n\nA low-level API which returns the backing AbstractChannel for an id returned by remoteref_id. The call is valid only on the node where the backing channel exists.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.worker_id_from_socket","page":"Distributed Computing","title":"Distributed.worker_id_from_socket","text":"worker_id_from_socket(s) -> pid\n\nA low-level API which, given a IO connection or a Worker, returns the pid of the worker it is connected to. This is useful when writing custom serialize methods for a type, which optimizes the data written out depending on the receiving process id.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.cluster_cookie-Tuple{}","page":"Distributed Computing","title":"Distributed.cluster_cookie","text":"cluster_cookie() -> cookie\n\nReturn the cluster cookie.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.cluster_cookie-Tuple{Any}","page":"Distributed Computing","title":"Distributed.cluster_cookie","text":"cluster_cookie(cookie) -> cookie\n\nSet the passed cookie as the cluster cookie, then returns it.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Cluster-Manager-Interface","page":"Distributed Computing","title":"Cluster Manager Interface","text":"","category":"section"},{"location":"stdlib/Distributed/","page":"Distributed Computing","title":"Distributed Computing","text":"This interface provides a mechanism to launch and manage Julia workers on different cluster environments. There are two types of managers present in Base: LocalManager, for launching additional workers on the same host, and SSHManager, for launching on remote hosts via ssh. TCP/IP sockets are used to connect and transport messages between processes. It is possible for Cluster Managers to provide a different transport.","category":"page"},{"location":"stdlib/Distributed/","page":"Distributed Computing","title":"Distributed Computing","text":"Distributed.ClusterManager\nDistributed.WorkerConfig\nDistributed.launch\nDistributed.manage\nDistributed.kill(::ClusterManager, ::Int, ::WorkerConfig)\nDistributed.connect(::ClusterManager, ::Int, ::WorkerConfig)\nDistributed.init_worker\nDistributed.start_worker\nDistributed.process_messages\nDistributed.default_addprocs_params","category":"page"},{"location":"stdlib/Distributed/#Distributed.ClusterManager","page":"Distributed Computing","title":"Distributed.ClusterManager","text":"ClusterManager\n\nSupertype for cluster managers, which control workers processes as a cluster. Cluster managers implement how workers can be added, removed and communicated with. SSHManager and LocalManager are subtypes of this.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.WorkerConfig","page":"Distributed Computing","title":"Distributed.WorkerConfig","text":"WorkerConfig\n\nType used by ClusterManagers to control workers added to their clusters. Some fields are used by all cluster managers to access a host:\n\nio – the connection used to access the worker (a subtype of IO or Nothing)\nhost – the host address (either a String or Nothing)\nport – the port on the host used to connect to the worker (either an Int or Nothing)\n\nSome are used by the cluster manager to add workers to an already-initialized host:\n\ncount – the number of workers to be launched on the host\nexename – the path to the Julia executable on the host, defaults to \"$(Sys.BINDIR)/julia\" or \"$(Sys.BINDIR)/julia-debug\"\nexeflags – flags to use when launching Julia remotely\n\nThe userdata field is used to store information for each worker by external managers.\n\nSome fields are used by SSHManager and similar managers:\n\ntunnel – true (use tunneling), false (do not use tunneling), or nothing (use default for the manager)\nmultiplex – true (use SSH multiplexing for tunneling) or false\nforward – the forwarding option used for -L option of ssh\nbind_addr – the address on the remote host to bind to\nsshflags – flags to use in establishing the SSH connection\nmax_parallel – the maximum number of workers to connect to in parallel on the host\n\nSome fields are used by both LocalManagers and SSHManagers:\n\nconnect_at – determines whether this is a worker-to-worker or driver-to-worker setup call\nprocess – the process which will be connected (usually the manager will assign this during addprocs)\nospid – the process ID according to the host OS, used to interrupt worker processes\nenviron – private dictionary used to store temporary information by Local/SSH managers\nident – worker as identified by the ClusterManager\nconnect_idents – list of worker ids the worker must connect to if using a custom topology\nenable_threaded_blas – true, false, or nothing, whether to use threaded BLAS or not on the workers\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Distributed/#Distributed.launch","page":"Distributed Computing","title":"Distributed.launch","text":"launch(manager::ClusterManager, params::Dict, launched::Array, launch_ntfy::Condition)\n\nImplemented by cluster managers. For every Julia worker launched by this function, it should append a WorkerConfig entry to launched and notify launch_ntfy. The function MUST exit once all workers, requested by manager have been launched. params is a dictionary of all keyword arguments addprocs was called with.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.manage","page":"Distributed Computing","title":"Distributed.manage","text":"manage(manager::ClusterManager, id::Integer, config::WorkerConfig. op::Symbol)\n\nImplemented by cluster managers. It is called on the master process, during a worker's lifetime, with appropriate op values:\n\nwith :register/:deregister when a worker is added / removed from the Julia worker pool.\nwith :interrupt when interrupt(workers) is called. The ClusterManager should signal the appropriate worker with an interrupt signal.\nwith :finalize for cleanup purposes.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Base.kill-Tuple{ClusterManager, Int64, WorkerConfig}","page":"Distributed Computing","title":"Base.kill","text":"kill(manager::ClusterManager, pid::Int, config::WorkerConfig)\n\nImplemented by cluster managers. It is called on the master process, by rmprocs. It should cause the remote worker specified by pid to exit. kill(manager::ClusterManager.....) executes a remote exit() on pid.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Sockets.connect-Tuple{ClusterManager, Int64, WorkerConfig}","page":"Distributed Computing","title":"Sockets.connect","text":"connect(manager::ClusterManager, pid::Int, config::WorkerConfig) -> (instrm::IO, outstrm::IO)\n\nImplemented by cluster managers using custom transports. It should establish a logical connection to worker with id pid, specified by config and return a pair of IO objects. Messages from pid to current process will be read off instrm, while messages to be sent to pid will be written to outstrm. The custom transport implementation must ensure that messages are delivered and received completely and in order. connect(manager::ClusterManager.....) sets up TCP/IP socket connections in-between workers.\n\n\n\n\n\n","category":"method"},{"location":"stdlib/Distributed/#Distributed.init_worker","page":"Distributed Computing","title":"Distributed.init_worker","text":"init_worker(cookie::AbstractString, manager::ClusterManager=DefaultClusterManager())\n\nCalled by cluster managers implementing custom transports. It initializes a newly launched process as a worker. Command line argument --worker[=] has the effect of initializing a process as a worker using TCP/IP sockets for transport. cookie is a cluster_cookie.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.start_worker","page":"Distributed Computing","title":"Distributed.start_worker","text":"start_worker([out::IO=stdout], cookie::AbstractString=readline(stdin); close_stdin::Bool=true, stderr_to_stdout::Bool=true)\n\nstart_worker is an internal function which is the default entry point for worker processes connecting via TCP/IP. It sets up the process as a Julia cluster worker.\n\nhost:port information is written to stream out (defaults to stdout).\n\nThe function reads the cookie from stdin if required, and listens on a free port (or if specified, the port in the --bind-to command line option) and schedules tasks to process incoming TCP connections and requests. It also (optionally) closes stdin and redirects stderr to stdout.\n\nIt does not return.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.process_messages","page":"Distributed Computing","title":"Distributed.process_messages","text":"process_messages(r_stream::IO, w_stream::IO, incoming::Bool=true)\n\nCalled by cluster managers using custom transports. It should be called when the custom transport implementation receives the first message from a remote worker. The custom transport must manage a logical connection to the remote worker and provide two IO objects, one for incoming messages and the other for messages addressed to the remote worker. If incoming is true, the remote peer initiated the connection. Whichever of the pair initiates the connection sends the cluster cookie and its Julia version number to perform the authentication handshake.\n\nSee also cluster_cookie.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Distributed/#Distributed.default_addprocs_params","page":"Distributed Computing","title":"Distributed.default_addprocs_params","text":"default_addprocs_params(mgr::ClusterManager) -> Dict{Symbol, Any}\n\nImplemented by cluster managers. The default keyword parameters passed when calling addprocs(mgr). The minimal set of options is available by calling default_addprocs_params()\n\n\n\n\n\n","category":"function"},{"location":"manual/conversion-and-promotion/#conversion-and-promotion","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Julia has a system for promoting arguments of mathematical operators to a common type, which has been mentioned in various other sections, including Integers and Floating-Point Numbers, Mathematical Operations and Elementary Functions, Types, and Methods. In this section, we explain how this promotion system works, as well as how to extend it to new types and apply it to functions besides built-in mathematical operators. Traditionally, programming languages fall into two camps with respect to promotion of arithmetic arguments:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Automatic promotion for built-in arithmetic types and operators. In most languages, built-in numeric types, when used as operands to arithmetic operators with infix syntax, such as +, -, *, and /, are automatically promoted to a common type to produce the expected results. C, Java, Perl, and Python, to name a few, all correctly compute the sum 1 + 1.5 as the floating-point value 2.5, even though one of the operands to + is an integer. These systems are convenient and designed carefully enough that they are generally all-but-invisible to the programmer: hardly anyone consciously thinks of this promotion taking place when writing such an expression, but compilers and interpreters must perform conversion before addition since integers and floating-point values cannot be added as-is. Complex rules for such automatic conversions are thus inevitably part of specifications and implementations for such languages.\nNo automatic promotion. This camp includes Ada and ML – very \"strict\" statically typed languages. In these languages, every conversion must be explicitly specified by the programmer. Thus, the example expression 1 + 1.5 would be a compilation error in both Ada and ML. Instead one must write real(1) + 1.5, explicitly converting the integer 1 to a floating-point value before performing addition. Explicit conversion everywhere is so inconvenient, however, that even Ada has some degree of automatic conversion: integer literals are promoted to the expected integer type automatically, and floating-point literals are similarly promoted to appropriate floating-point types.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"In a sense, Julia falls into the \"no automatic promotion\" category: mathematical operators are just functions with special syntax, and the arguments of functions are never automatically converted. However, one may observe that applying mathematical operations to a wide variety of mixed argument types is just an extreme case of polymorphic multiple dispatch – something which Julia's dispatch and type systems are particularly well-suited to handle. \"Automatic\" promotion of mathematical operands simply emerges as a special application: Julia comes with pre-defined catch-all dispatch rules for mathematical operators, invoked when no specific implementation exists for some combination of operand types. These catch-all rules first promote all operands to a common type using user-definable promotion rules, and then invoke a specialized implementation of the operator in question for the resulting values, now of the same type. User-defined types can easily participate in this promotion system by defining methods for conversion to and from other types, and providing a handful of promotion rules defining what types they should promote to when mixed with other types.","category":"page"},{"location":"manual/conversion-and-promotion/#Conversion","page":"Conversion and Promotion","title":"Conversion","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The standard way to obtain a value of a certain type T is to call the type's constructor, T(x). However, there are cases where it's convenient to convert a value from one type to another without the programmer asking for it explicitly. One example is assigning a value into an array: if A is a Vector{Float64}, the expression A[1] = 2 should work by automatically converting the 2 from Int to Float64, and storing the result in the array. This is done via the convert function.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The convert function generally takes two arguments: the first is a type object and the second is a value to convert to that type. The returned value is the value converted to an instance of given type. The simplest way to understand this function is to see it in action:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> x = 12\n12\n\njulia> typeof(x)\nInt64\n\njulia> xu = convert(UInt8, x)\n0x0c\n\njulia> typeof(xu)\nUInt8\n\njulia> xf = convert(AbstractFloat, x)\n12.0\n\njulia> typeof(xf)\nFloat64\n\njulia> a = Any[1 2 3; 4 5 6]\n2×3 Matrix{Any}:\n 1 2 3\n 4 5 6\n\njulia> convert(Array{Float64}, a)\n2×3 Matrix{Float64}:\n 1.0 2.0 3.0\n 4.0 5.0 6.0","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Conversion isn't always possible, in which case a MethodError is thrown indicating that convert doesn't know how to perform the requested conversion:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> convert(AbstractFloat, \"foo\")\nERROR: MethodError: Cannot `convert` an object of type String to an object of type AbstractFloat\n[...]","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Some languages consider parsing strings as numbers or formatting numbers as strings to be conversions (many dynamic languages will even perform conversion for you automatically). This is not the case in Julia. Even though some strings can be parsed as numbers, most strings are not valid representations of numbers, and only a very limited subset of them are. Therefore in Julia the dedicated parse function must be used to perform this operation, making it more explicit.","category":"page"},{"location":"manual/conversion-and-promotion/#When-is-convert-called?","page":"Conversion and Promotion","title":"When is convert called?","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The following language constructs call convert:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Assigning to an array converts to the array's element type.\nAssigning to a field of an object converts to the declared type of the field.\nConstructing an object with new converts to the object's declared field types.\nAssigning to a variable with a declared type (e.g. local x::T) converts to that type.\nA function with a declared return type converts its return value to that type.\nPassing a value to ccall converts it to the corresponding argument type.","category":"page"},{"location":"manual/conversion-and-promotion/#Conversion-vs.-Construction","page":"Conversion and Promotion","title":"Conversion vs. Construction","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Note that the behavior of convert(T, x) appears to be nearly identical to T(x). Indeed, it usually is. However, there is a key semantic difference: since convert can be called implicitly, its methods are restricted to cases that are considered \"safe\" or \"unsurprising\". convert will only convert between types that represent the same basic kind of thing (e.g. different representations of numbers, or different string encodings). It is also usually lossless; converting a value to a different type and back again should result in the exact same value.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"There are four general kinds of cases where constructors differ from convert:","category":"page"},{"location":"manual/conversion-and-promotion/#Constructors-for-types-unrelated-to-their-arguments","page":"Conversion and Promotion","title":"Constructors for types unrelated to their arguments","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Some constructors don't implement the concept of \"conversion\". For example, Timer(2) creates a 2-second timer, which is not really a \"conversion\" from an integer to a timer.","category":"page"},{"location":"manual/conversion-and-promotion/#Mutable-collections","page":"Conversion and Promotion","title":"Mutable collections","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"convert(T, x) is expected to return the original x if x is already of type T. In contrast, if T is a mutable collection type then T(x) should always make a new collection (copying elements from x).","category":"page"},{"location":"manual/conversion-and-promotion/#Wrapper-types","page":"Conversion and Promotion","title":"Wrapper types","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"For some types which \"wrap\" other values, the constructor may wrap its argument inside a new object even if it is already of the requested type. For example Some(x) wraps x to indicate that a value is present (in a context where the result might be a Some or nothing). However, x itself might be the object Some(y), in which case the result is Some(Some(y)), with two levels of wrapping. convert(Some, x), on the other hand, would just return x since it is already a Some.","category":"page"},{"location":"manual/conversion-and-promotion/#Constructors-that-don't-return-instances-of-their-own-type","page":"Conversion and Promotion","title":"Constructors that don't return instances of their own type","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"In very rare cases it might make sense for the constructor T(x) to return an object not of type T. This could happen if a wrapper type is its own inverse (e.g. Flip(Flip(x)) === x), or to support an old calling syntax for backwards compatibility when a library is restructured. But convert(T, x) should always return a value of type T.","category":"page"},{"location":"manual/conversion-and-promotion/#Defining-New-Conversions","page":"Conversion and Promotion","title":"Defining New Conversions","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"When defining a new type, initially all ways of creating it should be defined as constructors. If it becomes clear that implicit conversion would be useful, and that some constructors meet the above \"safety\" criteria, then convert methods can be added. These methods are typically quite simple, as they only need to call the appropriate constructor. Such a definition might look like this:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"import Base: convert\nconvert(::Type{MyType}, x) = MyType(x)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The type of the first argument of this method is Type{MyType}, the only instance of which is MyType. Thus, this method is only invoked when the first argument is the type value MyType. Notice the syntax used for the first argument: the argument name is omitted prior to the :: symbol, and only the type is given. This is the syntax in Julia for a function argument whose type is specified but whose value does not need to be referenced by name.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"All instances of some abstract types are by default considered \"sufficiently similar\" that a universal convert definition is provided in Julia Base. For example, this definition states that it's valid to convert any Number type to any other by calling a 1-argument constructor:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"convert(::Type{T}, x::Number) where {T<:Number} = T(x)::T","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"This means that new Number types only need to define constructors, since this definition will handle convert for them. An identity conversion is also provided to handle the case where the argument is already of the requested type:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"convert(::Type{T}, x::T) where {T<:Number} = x","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Similar definitions exist for AbstractString, AbstractArray, and AbstractDict.","category":"page"},{"location":"manual/conversion-and-promotion/#Promotion","page":"Conversion and Promotion","title":"Promotion","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Promotion refers to converting values of mixed types to a single common type. Although it is not strictly necessary, it is generally implied that the common type to which the values are converted can faithfully represent all of the original values. In this sense, the term \"promotion\" is appropriate since the values are converted to a \"greater\" type – i.e. one which can represent all of the input values in a single common type. It is important, however, not to confuse this with object-oriented (structural) super-typing, or Julia's notion of abstract super-types: promotion has nothing to do with the type hierarchy, and everything to do with converting between alternate representations. For instance, although every Int32 value can also be represented as a Float64 value, Int32 is not a subtype of Float64.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Promotion to a common \"greater\" type is performed in Julia by the promote function, which takes any number of arguments, and returns a tuple of the same number of values, converted to a common type, or throws an exception if promotion is not possible. The most common use case for promotion is to convert numeric arguments to a common type:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> promote(1, 2.5)\n(1.0, 2.5)\n\njulia> promote(1, 2.5, 3)\n(1.0, 2.5, 3.0)\n\njulia> promote(2, 3//4)\n(2//1, 3//4)\n\njulia> promote(1, 2.5, 3, 3//4)\n(1.0, 2.5, 3.0, 0.75)\n\njulia> promote(1.5, im)\n(1.5 + 0.0im, 0.0 + 1.0im)\n\njulia> promote(1 + 2im, 3//4)\n(1//1 + 2//1*im, 3//4 + 0//1*im)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Floating-point values are promoted to the largest of the floating-point argument types. Integer values are promoted to the largest of the integer argument types. If the types are the same size but differ in signedness, the unsigned type is chosen. Mixtures of integers and floating-point values are promoted to a floating-point type big enough to hold all the values. Integers mixed with rationals are promoted to rationals. Rationals mixed with floats are promoted to floats. Complex values mixed with real values are promoted to the appropriate kind of complex value.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"That is really all there is to using promotions. The rest is just a matter of clever application, the most typical \"clever\" application being the definition of catch-all methods for numeric operations like the arithmetic operators +, -, * and /. Here are some of the catch-all method definitions given in promotion.jl:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"+(x::Number, y::Number) = +(promote(x,y)...)\n-(x::Number, y::Number) = -(promote(x,y)...)\n*(x::Number, y::Number) = *(promote(x,y)...)\n/(x::Number, y::Number) = /(promote(x,y)...)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"These method definitions say that in the absence of more specific rules for adding, subtracting, multiplying and dividing pairs of numeric values, promote the values to a common type and then try again. That's all there is to it: nowhere else does one ever need to worry about promotion to a common numeric type for arithmetic operations – it just happens automatically. There are definitions of catch-all promotion methods for a number of other arithmetic and mathematical functions in promotion.jl, but beyond that, there are hardly any calls to promote required in Julia Base. The most common usages of promote occur in outer constructors methods, provided for convenience, to allow constructor calls with mixed types to delegate to an inner type with fields promoted to an appropriate common type. For example, recall that rational.jl provides the following outer constructor method:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Rational(n::Integer, d::Integer) = Rational(promote(n,d)...)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"This allows calls like the following to work:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> x = Rational(Int8(15),Int32(-5))\n-3//1\n\njulia> typeof(x)\nRational{Int32}","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"For most user-defined types, it is better practice to require programmers to supply the expected types to constructor functions explicitly, but sometimes, especially for numeric problems, it can be convenient to do promotion automatically.","category":"page"},{"location":"manual/conversion-and-promotion/#Defining-Promotion-Rules","page":"Conversion and Promotion","title":"Defining Promotion Rules","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Although one could, in principle, define methods for the promote function directly, this would require many redundant definitions for all possible permutations of argument types. Instead, the behavior of promote is defined in terms of an auxiliary function called promote_rule, which one can provide methods for. The promote_rule function takes a pair of type objects and returns another type object, such that instances of the argument types will be promoted to the returned type. Thus, by defining the rule:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"import Base: promote_rule\npromote_rule(::Type{Float64}, ::Type{Float32}) = Float64","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"one declares that when 64-bit and 32-bit floating-point values are promoted together, they should be promoted to 64-bit floating-point. The promotion type does not need to be one of the argument types. For example, the following promotion rules both occur in Julia Base:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"promote_rule(::Type{BigInt}, ::Type{Float64}) = BigFloat\npromote_rule(::Type{BigInt}, ::Type{Int8}) = BigInt","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"In the latter case, the result type is BigInt since BigInt is the only type large enough to hold integers for arbitrary-precision integer arithmetic. Also note that one does not need to define both promote_rule(::Type{A}, ::Type{B}) and promote_rule(::Type{B}, ::Type{A}) – the symmetry is implied by the way promote_rule is used in the promotion process.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The promote_rule function is used as a building block to define a second function called promote_type, which, given any number of type objects, returns the common type to which those values, as arguments to promote should be promoted. Thus, if one wants to know, in absence of actual values, what type a collection of values of certain types would promote to, one can use promote_type:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"julia> promote_type(Int8, Int64)\nInt64","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Note that we do not overload promote_type directly: we overload promote_rule instead. promote_type uses promote_rule, and adds the symmetry. Overloading it directly can cause ambiguity errors. We overload promote_rule to define how things should be promoted, and we use promote_type to query that.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Internally, promote_type is used inside of promote to determine what type argument values should be converted to for promotion. The curious reader can read the code in promotion.jl, which defines the complete promotion mechanism in about 35 lines.","category":"page"},{"location":"manual/conversion-and-promotion/#Case-Study:-Rational-Promotions","page":"Conversion and Promotion","title":"Case Study: Rational Promotions","text":"","category":"section"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"Finally, we finish off our ongoing case study of Julia's rational number type, which makes relatively sophisticated use of the promotion mechanism with the following promotion rules:","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"import Base: promote_rule\npromote_rule(::Type{Rational{T}}, ::Type{S}) where {T<:Integer,S<:Integer} = Rational{promote_type(T,S)}\npromote_rule(::Type{Rational{T}}, ::Type{Rational{S}}) where {T<:Integer,S<:Integer} = Rational{promote_type(T,S)}\npromote_rule(::Type{Rational{T}}, ::Type{S}) where {T<:Integer,S<:AbstractFloat} = promote_type(T,S)","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"The first rule says that promoting a rational number with any other integer type promotes to a rational type whose numerator/denominator type is the result of promotion of its numerator/denominator type with the other integer type. The second rule applies the same logic to two different types of rational numbers, resulting in a rational of the promotion of their respective numerator/denominator types. The third and final rule dictates that promoting a rational with a float results in the same type as promoting the numerator/denominator type with the float.","category":"page"},{"location":"manual/conversion-and-promotion/","page":"Conversion and Promotion","title":"Conversion and Promotion","text":"This small handful of promotion rules, together with the type's constructors and the default convert method for numbers, are sufficient to make rational numbers interoperate completely naturally with all of Julia's other numeric types – integers, floating-point numbers, and complex numbers. By providing appropriate conversion methods and promotion rules in the same manner, any user-defined numeric type can interoperate just as naturally with Julia's predefined numerics.","category":"page"},{"location":"devdocs/ast/#Julia-ASTs","page":"Julia ASTs","title":"Julia ASTs","text":"","category":"section"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Julia has two representations of code. First there is a surface syntax AST returned by the parser (e.g. the Meta.parse function), and manipulated by macros. It is a structured representation of code as it is written, constructed by julia-parser.scm from a character stream. Next there is a lowered form, or IR (intermediate representation), which is used by type inference and code generation. In the lowered form there are fewer types of nodes, all macros are expanded, and all control flow is converted to explicit branches and sequences of statements. The lowered form is constructed by julia-syntax.scm.","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"First we will focus on the AST, since it is needed to write macros.","category":"page"},{"location":"devdocs/ast/#Surface-syntax-AST","page":"Julia ASTs","title":"Surface syntax AST","text":"","category":"section"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Front end ASTs consist almost entirely of Exprs and atoms (e.g. symbols, numbers). There is generally a different expression head for each visually distinct syntactic form. Examples will be given in s-expression syntax. Each parenthesized list corresponds to an Expr, where the first element is the head. For example (call f x) corresponds to Expr(:call, :f, :x) in Julia.","category":"page"},{"location":"devdocs/ast/#Calls","page":"Julia ASTs","title":"Calls","text":"","category":"section"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Input AST\nf(x) (call f x)\nf(x, y=1, z=2) (call f x (kw y 1) (kw z 2))\nf(x; y=1) (call f (parameters (kw y 1)) x)\nf(x...) (call f (... x))","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"do syntax:","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"f(x) do a,b\n body\nend","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"parses as (do (call f x) (-> (tuple a b) (block body))).","category":"page"},{"location":"devdocs/ast/#Operators","page":"Julia ASTs","title":"Operators","text":"","category":"section"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Most uses of operators are just function calls, so they are parsed with the head call. However some operators are special forms (not necessarily function calls), and in those cases the operator itself is the expression head. In julia-parser.scm these are referred to as \"syntactic operators\". Some operators (+ and *) use N-ary parsing; chained calls are parsed as a single N-argument call. Finally, chains of comparisons have their own special expression structure.","category":"page"},{"location":"devdocs/ast/","page":"Julia ASTs","title":"Julia ASTs","text":"Input AST\nx+y (call + x y)\na+b+c+d (call + a b c d)\n2x (call * 2 x)\na&&b (&& a b)\nx += 1 (+= x 1)\na ? 1 : 2 (if a 1 2)\na,b (tuple a b)\na==b (call == a b)\n1 @printf \"Hello %s\" \"world\"\nHello world\n\njulia> @printf \"Scientific notation %e\" 1.234\nScientific notation 1.234000e+00\n\njulia> @printf \"Scientific notation three digits %.3e\" 1.23456\nScientific notation three digits 1.235e+00\n\njulia> @printf \"Decimal two digits %.2f\" 1.23456\nDecimal two digits 1.23\n\njulia> @printf \"Padded to length 5 %5i\" 123\nPadded to length 5 123\n\njulia> @printf \"Padded with zeros to length 6 %06i\" 123\nPadded with zeros to length 6 000123\n\njulia> @printf \"Use shorter of decimal or scientific %g %g\" 1.23 12300000.0\nUse shorter of decimal or scientific 1.23 1.23e+07\n\njulia> @printf \"Use dynamic width and precision %*.*f\" 10 2 0.12345\nUse dynamic width and precision 0.12\n\nFor a systematic specification of the format, see here. See also @sprintf to get the result as a String instead of it being printed.\n\nCaveats\n\nInf and NaN are printed consistently as Inf and NaN for flags %a, %A, %e, %E, %f, %F, %g, and %G. Furthermore, if a floating point number is equally close to the numeric values of two possible output strings, the output string further away from zero is chosen.\n\nExamples\n\njulia> @printf(\"%f %F %f %F\", Inf, Inf, NaN, NaN)\nInf Inf NaN NaN\n\njulia> @printf \"%.0f %.1f %f\" 0.5 0.025 -0.0078125\n0 0.0 -0.007812\n\ncompat: Julia 1.8\nStarting in Julia 1.8, %s (string) and %c (character) widths are computed using textwidth, which e.g. ignores zero-width characters (such as combining characters for diacritical marks) and treats certain \"wide\" characters (e.g. emoji) as width 2.\n\ncompat: Julia 1.10\nDynamic width specifiers like %*s and %0*.*f require Julia 1.10.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Printf/#Printf.@sprintf","page":"Printf","title":"Printf.@sprintf","text":"@sprintf(\"%Fmt\", args...)\n\nReturn @printf formatted output as string.\n\nExamples\n\njulia> @sprintf \"this is a %s %15.1f\" \"test\" 34.567\n\"this is a test 34.6\"\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Printf/#Printf.Format","page":"Printf","title":"Printf.Format","text":"Printf.Format(format_str)\n\nCreate a C printf-compatible format object that can be used for formatting values.\n\nThe input format_str can include any valid format specifier character and modifiers.\n\nA Format object can be passed to Printf.format(f::Format, args...) to produce a formatted string, or Printf.format(io::IO, f::Format, args...) to print the formatted string directly to io.\n\nFor convenience, the Printf.format\"...\" string macro form can be used for building a Printf.Format object at macro-expansion-time.\n\ncompat: Julia 1.6\nPrintf.Format requires Julia 1.6 or later.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Printf/#Printf.format","page":"Printf","title":"Printf.format","text":"Printf.format(f::Printf.Format, args...) => String\nPrintf.format(io::IO, f::Printf.Format, args...)\n\nApply a printf format object f to provided args and return the formatted string (1st method), or print directly to an io object (2nd method). See @printf for more details on C printf support.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"EditURL = \"https://github.com/JuliaLang/julia/blob/master/stdlib/Test/docs/src/index.md\"","category":"page"},{"location":"stdlib/Test/#Unit-Testing","page":"Unit Testing","title":"Unit Testing","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"DocTestSetup = :(using Test)","category":"page"},{"location":"stdlib/Test/#Testing-Base-Julia","page":"Unit Testing","title":"Testing Base Julia","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Julia is under rapid development and has an extensive test suite to verify functionality across multiple platforms. If you build Julia from source, you can run this test suite with make test. In a binary install, you can run the test suite using Base.runtests().","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Base.runtests","category":"page"},{"location":"stdlib/Test/#Base.runtests","page":"Unit Testing","title":"Base.runtests","text":"Base.runtests(tests=[\"all\"]; ncores=ceil(Int, Sys.CPU_THREADS / 2),\n exit_on_error=false, revise=false, [seed])\n\nRun the Julia unit tests listed in tests, which can be either a string or an array of strings, using ncores processors. If exit_on_error is false, when one test fails, all remaining tests in other files will still be run; they are otherwise discarded, when exit_on_error == true. If revise is true, the Revise package is used to load any modifications to Base or to the standard libraries before running the tests. If a seed is provided via the keyword argument, it is used to seed the global RNG in the context where the tests are run; otherwise the seed is chosen randomly.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Basic-Unit-Tests","page":"Unit Testing","title":"Basic Unit Tests","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"The Test module provides simple unit testing functionality. Unit testing is a way to see if your code is correct by checking that the results are what you expect. It can be helpful to ensure your code still works after you make changes, and can be used when developing as a way of specifying the behaviors your code should have when complete. You may also want to look at the documentation for adding tests to your Julia Package.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Simple unit testing can be performed with the @test and @test_throws macros:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@test\nTest.@test_throws","category":"page"},{"location":"stdlib/Test/#Test.@test","page":"Unit Testing","title":"Test.@test","text":"@test ex\n@test f(args...) key=val ...\n@test ex broken=true\n@test ex skip=true\n\nTest that the expression ex evaluates to true. If executed inside a @testset, return a Pass Result if it does, a Fail Result if it is false, and an Error Result if it could not be evaluated. If executed outside a @testset, throw an exception instead of returning Fail or Error.\n\nExamples\n\njulia> @test true\nTest Passed\n\njulia> @test [1, 2] + [2, 1] == [3, 3]\nTest Passed\n\nThe @test f(args...) key=val... form is equivalent to writing @test f(args..., key=val...) which can be useful when the expression is a call using infix syntax such as approximate comparisons:\n\njulia> @test π ≈ 3.14 atol=0.01\nTest Passed\n\nThis is equivalent to the uglier test @test ≈(π, 3.14, atol=0.01). It is an error to supply more than one expression unless the first is a call expression and the rest are assignments (k=v).\n\nYou can use any key for the key=val arguments, except for broken and skip, which have special meanings in the context of @test:\n\nbroken=cond indicates a test that should pass but currently consistently fails when cond==true. Tests that the expression ex evaluates to false or causes an exception. Returns a Broken Result if it does, or an Error Result if the expression evaluates to true. Regular @test ex is evaluated when cond==false.\nskip=cond marks a test that should not be executed but should be included in test summary reporting as Broken, when cond==true. This can be useful for tests that intermittently fail, or tests of not-yet-implemented functionality. Regular @test ex is evaluated when cond==false.\n\nExamples\n\njulia> @test 2 + 2 ≈ 6 atol=1 broken=true\nTest Broken\n Expression: ≈(2 + 2, 6, atol = 1)\n\njulia> @test 2 + 2 ≈ 5 atol=1 broken=false\nTest Passed\n\njulia> @test 2 + 2 == 5 skip=true\nTest Broken\n Skipped: 2 + 2 == 5\n\njulia> @test 2 + 2 == 4 skip=false\nTest Passed\n\ncompat: Julia 1.7\nThe broken and skip keyword arguments require at least Julia 1.7.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.@test_throws","page":"Unit Testing","title":"Test.@test_throws","text":"@test_throws exception expr\n\nTests that the expression expr throws exception. The exception may specify either a type, a string, regular expression, or list of strings occurring in the displayed error message, a matching function, or a value (which will be tested for equality by comparing fields). Note that @test_throws does not support a trailing keyword form.\n\ncompat: Julia 1.8\nThe ability to specify anything other than a type or a value as exception requires Julia v1.8 or later.\n\nExamples\n\njulia> @test_throws BoundsError [1, 2, 3][4]\nTest Passed\n Thrown: BoundsError\n\njulia> @test_throws DimensionMismatch [1, 2, 3] + [1, 2]\nTest Passed\n Thrown: DimensionMismatch\n\njulia> @test_throws \"Try sqrt(Complex\" sqrt(-1)\nTest Passed\n Message: \"DomainError with -1.0:\\nsqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).\"\n\nIn the final example, instead of matching a single string it could alternatively have been performed with:\n\n[\"Try\", \"Complex\"] (a list of strings)\nr\"Try sqrt\\([Cc]omplex\" (a regular expression)\nstr -> occursin(\"complex\", str) (a matching function)\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"For example, suppose we want to check our new function foo(x) works as expected:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> using Test\n\njulia> foo(x) = length(x)^2\nfoo (generic function with 1 method)","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If the condition is true, a Pass is returned:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test foo(\"bar\") == 9\nTest Passed\n\njulia> @test foo(\"fizz\") >= 10\nTest Passed","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If the condition is false, then a Fail is returned and an exception is thrown:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test foo(\"f\") == 20\nTest Failed at none:1\n Expression: foo(\"f\") == 20\n Evaluated: 1 == 20\n\nERROR: There was an error during testing","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If the condition could not be evaluated because an exception was thrown, which occurs in this case because length is not defined for symbols, an Error object is returned and an exception is thrown:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test foo(:cat) == 1\nError During Test\n Test threw an exception of type MethodError\n Expression: foo(:cat) == 1\n MethodError: no method matching length(::Symbol)\n The function `length` exists, but no method is defined for this combination of argument types.\n\n Closest candidates are:\n length(::SimpleVector) at essentials.jl:256\n length(::Base.MethodList) at reflection.jl:521\n length(::MethodTable) at reflection.jl:597\n ...\n Stacktrace:\n [...]\nERROR: There was an error during testing","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If we expect that evaluating an expression should throw an exception, then we can use @test_throws to check that this occurs:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test_throws MethodError foo(:cat)\nTest Passed\n Thrown: MethodError","category":"page"},{"location":"stdlib/Test/#Working-with-Test-Sets","page":"Unit Testing","title":"Working with Test Sets","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Typically a large number of tests are used to make sure functions work correctly over a range of inputs. In the event a test fails, the default behavior is to throw an exception immediately. However, it is normally preferable to run the rest of the tests first to get a better picture of how many errors there are in the code being tested.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"note: Note\nThe @testset will create a local scope of its own when running the tests in it.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"The @testset macro can be used to group tests into sets. All the tests in a test set will be run, and at the end of the test set a summary will be printed. If any of the tests failed, or could not be evaluated due to an error, the test set will then throw a TestSetException.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@testset\nTest.TestSetException","category":"page"},{"location":"stdlib/Test/#Test.@testset","page":"Unit Testing","title":"Test.@testset","text":"@testset [CustomTestSet] [options...] [\"description\"] begin test_ex end\n@testset [CustomTestSet] [options...] [\"description $v\"] for v in itr test_ex end\n@testset [CustomTestSet] [options...] [\"description $v, $w\"] for v in itrv, w in itrw test_ex end\n@testset [CustomTestSet] [options...] [\"description\"] test_func()\n@testset let v = v, w = w; test_ex; end\n\nWith begin/end or function call\n\nWhen @testset is used, with begin/end or a single function call, the macro starts a new test set in which to evaluate the given expression.\n\nIf no custom testset type is given it defaults to creating a DefaultTestSet. DefaultTestSet records all the results and, if there are any Fails or Errors, throws an exception at the end of the top-level (non-nested) test set, along with a summary of the test results.\n\nAny custom testset type (subtype of AbstractTestSet) can be given and it will also be used for any nested @testset invocations. The given options are only applied to the test set where they are given. The default test set type accepts three boolean options:\n\nverbose: if true, the result summary of the nested testsets is shown even when they all pass (the default is false).\nshowtiming: if true, the duration of each displayed testset is shown (the default is true).\nfailfast: if true, any test failure or error will cause the testset and any child testsets to return immediately (the default is false). This can also be set globally via the env var JULIA_TEST_FAILFAST.\n\ncompat: Julia 1.8\n@testset test_func() requires at least Julia 1.8.\n\ncompat: Julia 1.9\nfailfast requires at least Julia 1.9.\n\nThe description string accepts interpolation from the loop indices. If no description is provided, one is constructed based on the variables. If a function call is provided, its name will be used. Explicit description strings override this behavior.\n\nBy default the @testset macro will return the testset object itself, though this behavior can be customized in other testset types. If a for loop is used then the macro collects and returns a list of the return values of the finish method, which by default will return a list of the testset objects used in each iteration.\n\nBefore the execution of the body of a @testset, there is an implicit call to Random.seed!(seed) where seed is the current seed of the global RNG. Moreover, after the execution of the body, the state of the global RNG is restored to what it was before the @testset. This is meant to ease reproducibility in case of failure, and to allow seamless re-arrangements of @testsets regardless of their side-effect on the global RNG state.\n\nExamples\n\njulia> @testset \"trigonometric identities\" begin\n θ = 2/3*π\n @test sin(-θ) ≈ -sin(θ)\n @test cos(-θ) ≈ cos(θ)\n @test sin(2θ) ≈ 2*sin(θ)*cos(θ)\n @test cos(2θ) ≈ cos(θ)^2 - sin(θ)^2\n end;\nTest Summary: | Pass Total Time\ntrigonometric identities | 4 4 0.2s\n\n@testset for\n\nWhen @testset for is used, the macro starts a new test for each iteration of the provided loop. The semantics of each test set are otherwise identical to that of that begin/end case (as if used for each loop iteration).\n\n@testset let\n\nWhen @testset let is used, the macro starts a transparent test set with the given object added as a context object to any failing test contained therein. This is useful when performing a set of related tests on one larger object and it is desirable to print this larger object when any of the individual tests fail. Transparent test sets do not introduce additional levels of nesting in the test set hierarchy and are passed through directly to the parent test set (with the context object appended to any failing tests.)\n\ncompat: Julia 1.9\n@testset let requires at least Julia 1.9.\n\ncompat: Julia 1.10\nMultiple let assignments are supported since Julia 1.10.\n\nExamples\n\njulia> @testset let logi = log(im)\n @test imag(logi) == π/2\n @test !iszero(real(logi))\n end\nTest Failed at none:3\n Expression: !(iszero(real(logi)))\n Context: logi = 0.0 + 1.5707963267948966im\n\nERROR: There was an error during testing\n\njulia> @testset let logi = log(im), op = !iszero\n @test imag(logi) == π/2\n @test op(real(logi))\n end\nTest Failed at none:3\n Expression: op(real(logi))\n Context: logi = 0.0 + 1.5707963267948966im\n op = !iszero\n\nERROR: There was an error during testing\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.TestSetException","page":"Unit Testing","title":"Test.TestSetException","text":"TestSetException\n\nThrown when a test set finishes and not all tests passed.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"We can put our tests for the foo(x) function in a test set:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @testset \"Foo Tests\" begin\n @test foo(\"a\") == 1\n @test foo(\"ab\") == 4\n @test foo(\"abc\") == 9\n end;\nTest Summary: | Pass Total Time\nFoo Tests | 3 3 0.0s","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test sets can also be nested:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @testset \"Foo Tests\" begin\n @testset \"Animals\" begin\n @test foo(\"cat\") == 9\n @test foo(\"dog\") == foo(\"cat\")\n end\n @testset \"Arrays $i\" for i in 1:3\n @test foo(zeros(i)) == i^2\n @test foo(fill(1.0, i)) == i^2\n end\n end;\nTest Summary: | Pass Total Time\nFoo Tests | 8 8 0.0s","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"As well as call functions:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> f(x) = @test isone(x)\nf (generic function with 1 method)\n\njulia> @testset f(1);\nTest Summary: | Pass Total Time\nf | 1 1 0.0s","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"This can be used to allow for factorization of test sets, making it easier to run individual test sets by running the associated functions instead. Note that in the case of functions, the test set will be given the name of the called function. In the event that a nested test set has no failures, as happened here, it will be hidden in the summary, unless the verbose=true option is passed:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @testset verbose = true \"Foo Tests\" begin\n @testset \"Animals\" begin\n @test foo(\"cat\") == 9\n @test foo(\"dog\") == foo(\"cat\")\n end\n @testset \"Arrays $i\" for i in 1:3\n @test foo(zeros(i)) == i^2\n @test foo(fill(1.0, i)) == i^2\n end\n end;\nTest Summary: | Pass Total Time\nFoo Tests | 8 8 0.0s\n Animals | 2 2 0.0s\n Arrays 1 | 2 2 0.0s\n Arrays 2 | 2 2 0.0s\n Arrays 3 | 2 2 0.0s","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If we do have a test failure, only the details for the failed test sets will be shown:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @testset \"Foo Tests\" begin\n @testset \"Animals\" begin\n @testset \"Felines\" begin\n @test foo(\"cat\") == 9\n end\n @testset \"Canines\" begin\n @test foo(\"dog\") == 9\n end\n end\n @testset \"Arrays\" begin\n @test foo(zeros(2)) == 4\n @test foo(fill(1.0, 4)) == 15\n end\n end\n\nArrays: Test Failed\n Expression: foo(fill(1.0, 4)) == 15\n Evaluated: 16 == 15\n[...]\nTest Summary: | Pass Fail Total Time\nFoo Tests | 3 1 4 0.0s\n Animals | 2 2 0.0s\n Arrays | 1 1 2 0.0s\nERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken.","category":"page"},{"location":"stdlib/Test/#Testing-Log-Statements","page":"Unit Testing","title":"Testing Log Statements","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"One can use the @test_logs macro to test log statements, or use a TestLogger.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@test_logs\nTest.TestLogger\nTest.LogRecord","category":"page"},{"location":"stdlib/Test/#Test.@test_logs","page":"Unit Testing","title":"Test.@test_logs","text":"@test_logs [log_patterns...] [keywords] expression\n\nCollect a list of log records generated by expression using collect_test_logs, check that they match the sequence log_patterns, and return the value of expression. The keywords provide some simple filtering of log records: the min_level keyword controls the minimum log level which will be collected for the test, the match_mode keyword defines how matching will be performed (the default :all checks that all logs and patterns match pairwise; use :any to check that the pattern matches at least once somewhere in the sequence.)\n\nThe most useful log pattern is a simple tuple of the form (level,message). A different number of tuple elements may be used to match other log metadata, corresponding to the arguments to passed to AbstractLogger via the handle_message function: (level,message,module,group,id,file,line). Elements which are present will be matched pairwise with the log record fields using == by default, with the special cases that Symbols may be used for the standard log levels, and Regexs in the pattern will match string or Symbol fields using occursin.\n\nExamples\n\nConsider a function which logs a warning, and several debug messages:\n\nfunction foo(n)\n @info \"Doing foo with n=$n\"\n for i=1:n\n @debug \"Iteration $i\"\n end\n 42\nend\n\nWe can test the info message using\n\n@test_logs (:info,\"Doing foo with n=2\") foo(2)\n\nIf we also wanted to test the debug messages, these need to be enabled with the min_level keyword:\n\nusing Logging\n@test_logs (:info,\"Doing foo with n=2\") (:debug,\"Iteration 1\") (:debug,\"Iteration 2\") min_level=Logging.Debug foo(2)\n\nIf you want to test that some particular messages are generated while ignoring the rest, you can set the keyword match_mode=:any:\n\nusing Logging\n@test_logs (:info,) (:debug,\"Iteration 42\") min_level=Logging.Debug match_mode=:any foo(100)\n\nThe macro may be chained with @test to also test the returned value:\n\n@test (@test_logs (:info,\"Doing foo with n=2\") foo(2)) == 42\n\nIf you want to test for the absence of warnings, you can omit specifying log patterns and set the min_level accordingly:\n\n# test that the expression logs no messages when the logger level is warn:\n@test_logs min_level=Logging.Warn @info(\"Some information\") # passes\n@test_logs min_level=Logging.Warn @warn(\"Some information\") # fails\n\nIf you want to test the absence of warnings (or error messages) in stderr which are not generated by @warn, see @test_nowarn.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.TestLogger","page":"Unit Testing","title":"Test.TestLogger","text":"TestLogger(; min_level=Info, catch_exceptions=false)\n\nCreate a TestLogger which captures logged messages in its logs::Vector{LogRecord} field.\n\nSet min_level to control the LogLevel, catch_exceptions for whether or not exceptions thrown as part of log event generation should be caught, and respect_maxlog for whether or not to follow the convention of logging messages with maxlog=n for some integer n at most n times.\n\nSee also: LogRecord.\n\nExamples\n\njulia> using Test, Logging\n\njulia> f() = @info \"Hi\" number=5;\n\njulia> test_logger = TestLogger();\n\njulia> with_logger(test_logger) do\n f()\n @info \"Bye!\"\n end\n\njulia> @test test_logger.logs[1].message == \"Hi\"\nTest Passed\n\njulia> @test test_logger.logs[1].kwargs[:number] == 5\nTest Passed\n\njulia> @test test_logger.logs[2].message == \"Bye!\"\nTest Passed\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.LogRecord","page":"Unit Testing","title":"Test.LogRecord","text":"LogRecord\n\nStores the results of a single log event. Fields:\n\nlevel: the LogLevel of the log message\nmessage: the textual content of the log message\n_module: the module of the log event\ngroup: the logging group (by default, the name of the file containing the log event)\nid: the ID of the log event\nfile: the file containing the log event\nline: the line within the file of the log event\nkwargs: any keyword arguments passed to the log event\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Other-Test-Macros","page":"Unit Testing","title":"Other Test Macros","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"As calculations on floating-point values can be imprecise, you can perform approximate equality checks using either @test a ≈ b (where ≈, typed via tab completion of \\approx, is the isapprox function) or use isapprox directly.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test 1 ≈ 0.999999999\nTest Passed\n\njulia> @test 1 ≈ 0.999999\nTest Failed at none:1\n Expression: 1 ≈ 0.999999\n Evaluated: 1 ≈ 0.999999\n\nERROR: There was an error during testing","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"You can specify relative and absolute tolerances by setting the rtol and atol keyword arguments of isapprox, respectively, after the ≈ comparison:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"julia> @test 1 ≈ 0.999999 rtol=1e-5\nTest Passed","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Note that this is not a specific feature of the ≈ but rather a general feature of the @test macro: @test a b key=val is transformed by the macro into @test op(a, b, key=val). It is, however, particularly useful for ≈ tests.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@inferred\nTest.@test_deprecated\nTest.@test_warn\nTest.@test_nowarn","category":"page"},{"location":"stdlib/Test/#Test.@inferred","page":"Unit Testing","title":"Test.@inferred","text":"@inferred [AllowedType] f(x)\n\nTests that the call expression f(x) returns a value of the same type inferred by the compiler. It is useful to check for type stability.\n\nf(x) can be any call expression. Returns the result of f(x) if the types match, and an Error Result if it finds different types.\n\nOptionally, AllowedType relaxes the test, by making it pass when either the type of f(x) matches the inferred type modulo AllowedType, or when the return type is a subtype of AllowedType. This is useful when testing type stability of functions returning a small union such as Union{Nothing, T} or Union{Missing, T}.\n\njulia> f(a) = a > 1 ? 1 : 1.0\nf (generic function with 1 method)\n\njulia> typeof(f(2))\nInt64\n\njulia> @code_warntype f(2)\nMethodInstance for f(::Int64)\n from f(a) @ Main none:1\nArguments\n #self#::Core.Const(f)\n a::Int64\nBody::UNION{FLOAT64, INT64}\n1 ─ %1 = (a > 1)::Bool\n└── goto #3 if not %1\n2 ─ return 1\n3 ─ return 1.0\n\njulia> @inferred f(2)\nERROR: return type Int64 does not match inferred return type Union{Float64, Int64}\n[...]\n\njulia> @inferred max(1, 2)\n2\n\njulia> g(a) = a < 10 ? missing : 1.0\ng (generic function with 1 method)\n\njulia> @inferred g(20)\nERROR: return type Float64 does not match inferred return type Union{Missing, Float64}\n[...]\n\njulia> @inferred Missing g(20)\n1.0\n\njulia> h(a) = a < 10 ? missing : f(a)\nh (generic function with 1 method)\n\njulia> @inferred Missing h(20)\nERROR: return type Int64 does not match inferred return type Union{Missing, Float64, Int64}\n[...]\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.@test_deprecated","page":"Unit Testing","title":"Test.@test_deprecated","text":"@test_deprecated [pattern] expression\n\nWhen --depwarn=yes, test that expression emits a deprecation warning and return the value of expression. The log message string will be matched against pattern which defaults to r\"deprecated\"i.\n\nWhen --depwarn=no, simply return the result of executing expression. When --depwarn=error, check that an ErrorException is thrown.\n\nExamples\n\n# Deprecated in julia 0.7\n@test_deprecated num2hex(1)\n\n# The returned value can be tested by chaining with @test:\n@test (@test_deprecated num2hex(1)) == \"0000000000000001\"\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.@test_warn","page":"Unit Testing","title":"Test.@test_warn","text":"@test_warn msg expr\n\nTest whether evaluating expr results in stderr output that contains the msg string or matches the msg regular expression. If msg is a boolean function, tests whether msg(output) returns true. If msg is a tuple or array, checks that the error output contains/matches each item in msg. Returns the result of evaluating expr.\n\nSee also @test_nowarn to check for the absence of error output.\n\nNote: Warnings generated by @warn cannot be tested with this macro. Use @test_logs instead.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test.@test_nowarn","page":"Unit Testing","title":"Test.@test_nowarn","text":"@test_nowarn expr\n\nTest whether evaluating expr results in empty stderr output (no warnings or other messages). Returns the result of evaluating expr.\n\nNote: The absence of warnings generated by @warn cannot be tested with this macro. Use @test_logs instead.\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Broken-Tests","page":"Unit Testing","title":"Broken Tests","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"If a test fails consistently it can be changed to use the @test_broken macro. This will denote the test as Broken if the test continues to fail and alerts the user via an Error if the test succeeds.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@test_broken","category":"page"},{"location":"stdlib/Test/#Test.@test_broken","page":"Unit Testing","title":"Test.@test_broken","text":"@test_broken ex\n@test_broken f(args...) key=val ...\n\nIndicates a test that should pass but currently consistently fails. Tests that the expression ex evaluates to false or causes an exception. Returns a Broken Result if it does, or an Error Result if the expression evaluates to true. This is equivalent to @test ex broken=true.\n\nThe @test_broken f(args...) key=val... form works as for the @test macro.\n\nExamples\n\njulia> @test_broken 1 == 2\nTest Broken\n Expression: 1 == 2\n\njulia> @test_broken 1 == 2 atol=0.1\nTest Broken\n Expression: ==(1, 2, atol = 0.1)\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"@test_skip is also available to skip a test without evaluation, but counting the skipped test in the test set reporting. The test will not run but gives a Broken Result.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.@test_skip","category":"page"},{"location":"stdlib/Test/#Test.@test_skip","page":"Unit Testing","title":"Test.@test_skip","text":"@test_skip ex\n@test_skip f(args...) key=val ...\n\nMarks a test that should not be executed but should be included in test summary reporting as Broken. This can be useful for tests that intermittently fail, or tests of not-yet-implemented functionality. This is equivalent to @test ex skip=true.\n\nThe @test_skip f(args...) key=val... form works as for the @test macro.\n\nExamples\n\njulia> @test_skip 1 == 2\nTest Broken\n Skipped: 1 == 2\n\njulia> @test_skip 1 == 2 atol=0.1\nTest Broken\n Skipped: ==(1, 2, atol = 0.1)\n\n\n\n\n\n","category":"macro"},{"location":"stdlib/Test/#Test-result-types","page":"Unit Testing","title":"Test result types","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.Result\nTest.Pass\nTest.Fail\nTest.Error\nTest.Broken","category":"page"},{"location":"stdlib/Test/#Test.Result","page":"Unit Testing","title":"Test.Result","text":"Test.Result\n\nAll tests produce a result object. This object may or may not be stored, depending on whether the test is part of a test set.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.Pass","page":"Unit Testing","title":"Test.Pass","text":"Test.Pass <: Test.Result\n\nThe test condition was true, i.e. the expression evaluated to true or the correct exception was thrown.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.Fail","page":"Unit Testing","title":"Test.Fail","text":"Test.Fail <: Test.Result\n\nThe test condition was false, i.e. the expression evaluated to false or the correct exception was not thrown.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.Error","page":"Unit Testing","title":"Test.Error","text":"Test.Error <: Test.Result\n\nThe test condition couldn't be evaluated due to an exception, or it evaluated to something other than a Bool. In the case of @test_broken it is used to indicate that an unexpected Pass Result occurred.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.Broken","page":"Unit Testing","title":"Test.Broken","text":"Test.Broken <: Test.Result\n\nThe test condition is the expected (failed) result of a broken test, or was explicitly skipped with @test_skip.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Creating-Custom-AbstractTestSet-Types","page":"Unit Testing","title":"Creating Custom AbstractTestSet Types","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Packages can create their own AbstractTestSet subtypes by implementing the record and finish methods. The subtype should have a one-argument constructor taking a description string, with any options passed in as keyword arguments.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.record\nTest.finish","category":"page"},{"location":"stdlib/Test/#Test.record","page":"Unit Testing","title":"Test.record","text":"record(ts::AbstractTestSet, res::Result)\n\nRecord a result to a testset. This function is called by the @testset infrastructure each time a contained @test macro completes, and is given the test result (which could be an Error). This will also be called with an Error if an exception is thrown inside the test block but outside of a @test context.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.finish","page":"Unit Testing","title":"Test.finish","text":"finish(ts::AbstractTestSet)\n\nDo any final processing necessary for the given testset. This is called by the @testset infrastructure after a test block executes.\n\nCustom AbstractTestSet subtypes should call record on their parent (if there is one) to add themselves to the tree of test results. This might be implemented as:\n\nif get_testset_depth() != 0\n # Attach this test set to the parent test set\n parent_ts = get_testset()\n record(parent_ts, self)\n return self\nend\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test takes responsibility for maintaining a stack of nested testsets as they are executed, but any result accumulation is the responsibility of the AbstractTestSet subtype. You can access this stack with the get_testset and get_testset_depth methods. Note that these functions are not exported.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.get_testset\nTest.get_testset_depth","category":"page"},{"location":"stdlib/Test/#Test.get_testset","page":"Unit Testing","title":"Test.get_testset","text":"get_testset()\n\nRetrieve the active test set from the task's local storage. If no test set is active, use the fallback default test set.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.get_testset_depth","page":"Unit Testing","title":"Test.get_testset_depth","text":"get_testset_depth()\n\nReturn the number of active test sets, not including the default test set\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test also makes sure that nested @testset invocations use the same AbstractTestSet subtype as their parent unless it is set explicitly. It does not propagate any properties of the testset. Option inheritance behavior can be implemented by packages using the stack infrastructure that Test provides.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Defining a basic AbstractTestSet subtype might look like:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"import Test: Test, record, finish\nusing Test: AbstractTestSet, Result, Pass, Fail, Error\nusing Test: get_testset_depth, get_testset\nstruct CustomTestSet <: Test.AbstractTestSet\n description::AbstractString\n foo::Int\n results::Vector\n # constructor takes a description string and options keyword arguments\n CustomTestSet(desc; foo=1) = new(desc, foo, [])\nend\n\nrecord(ts::CustomTestSet, child::AbstractTestSet) = push!(ts.results, child)\nrecord(ts::CustomTestSet, res::Result) = push!(ts.results, res)\nfunction finish(ts::CustomTestSet)\n # just record if we're not the top-level parent\n if get_testset_depth() > 0\n record(get_testset(), ts)\n return ts\n end\n\n # so the results are printed if we are at the top level\n Test.print_test_results(ts)\n return ts\nend","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"And using that testset looks like:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"@testset CustomTestSet foo=4 \"custom testset inner 2\" begin\n # this testset should inherit the type, but not the argument.\n @testset \"custom testset inner\" begin\n @test true\n end\nend","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"In order to use a custom testset and have the recorded results printed as part of any outer default testset, also define Test.get_test_counts. This might look like so:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"using Test: AbstractTestSet, Pass, Fail, Error, Broken, get_test_counts, TestCounts, format_duration\n\nfunction Test.get_test_counts(ts::CustomTestSet)\n passes, fails, errors, broken = 0, 0, 0, 0\n # cumulative results\n c_passes, c_fails, c_errors, c_broken = 0, 0, 0, 0\n\n for t in ts.results\n # count up results\n isa(t, Pass) && (passes += 1)\n isa(t, Fail) && (fails += 1)\n isa(t, Error) && (errors += 1)\n isa(t, Broken) && (broken += 1)\n # handle children\n if isa(t, AbstractTestSet)\n tc = get_test_counts(t)::TestCounts\n c_passes += tc.passes + tc.cumulative_passes\n c_fails += tc.fails + tc.cumulative_fails\n c_errors += tc.errors + tc.cumulative_errors\n c_broken += tc.broken + tc.cumulative_broken\n end\n end\n # get a duration, if we have one\n duration = format_duration(ts)\n return TestCounts(true, passes, fails, errors, broken, c_passes, c_fails, c_errors, c_broken, duration)\nend","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.TestCounts\nTest.get_test_counts\nTest.format_duration\nTest.print_test_results","category":"page"},{"location":"stdlib/Test/#Test.TestCounts","page":"Unit Testing","title":"Test.TestCounts","text":"TestCounts\n\nHolds the state for recursively gathering the results of a test set for display purposes.\n\nFields:\n\ncustomized: Whether the function get_test_counts was customized for the AbstractTestSet this counts object is for. If a custom method was defined, always pass true to the constructor.\npasses: The number of passing @test invocations.\nfails: The number of failing @test invocations.\nerrors: The number of erroring @test invocations.\nbroken: The number of broken @test invocations.\npasses: The cumulative number of passing @test invocations.\nfails: The cumulative number of failing @test invocations.\nerrors: The cumulative number of erroring @test invocations.\nbroken: The cumulative number of broken @test invocations.\nduration: The total duration the AbstractTestSet in question ran for, as a formatted String.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.get_test_counts","page":"Unit Testing","title":"Test.get_test_counts","text":"\" gettestcounts(::AbstractTestSet) -> TestCounts\n\nRecursive function that counts the number of test results of each type directly in the testset, and totals across the child testsets.\n\nCustom AbstractTestSet should implement this function to get their totals counted & displayed with DefaultTestSet as well.\n\nIf this is not implemented for a custom TestSet, the printing falls back to reporting x for failures and ?s for the duration.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.format_duration","page":"Unit Testing","title":"Test.format_duration","text":"format_duration(::AbstractTestSet)\n\nReturn a formatted string for printing the duration the testset ran for.\n\nIf not defined, falls back to \"?s\".\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.print_test_results","page":"Unit Testing","title":"Test.print_test_results","text":"print_test_results(ts::AbstractTestSet, depth_pad=0)\n\nPrint the results of an AbstractTestSet as a formatted table.\n\ndepth_pad refers to how much padding should be added in front of all output.\n\nCalled inside of Test.finish, if the finished testset is the topmost testset.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test-utilities","page":"Unit Testing","title":"Test utilities","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Test.GenericArray\nTest.GenericDict\nTest.GenericOrder\nTest.GenericSet\nTest.GenericString\nTest.detect_ambiguities\nTest.detect_unbound_args","category":"page"},{"location":"stdlib/Test/#Test.GenericArray","page":"Unit Testing","title":"Test.GenericArray","text":"The GenericArray can be used to test generic array APIs that program to the AbstractArray interface, in order to ensure that functions can work with array types besides the standard Array type.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.GenericDict","page":"Unit Testing","title":"Test.GenericDict","text":"The GenericDict can be used to test generic dict APIs that program to the AbstractDict interface, in order to ensure that functions can work with associative types besides the standard Dict type.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.GenericOrder","page":"Unit Testing","title":"Test.GenericOrder","text":"The GenericOrder can be used to test APIs for their support of generic ordered types.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.GenericSet","page":"Unit Testing","title":"Test.GenericSet","text":"The GenericSet can be used to test generic set APIs that program to the AbstractSet interface, in order to ensure that functions can work with set types besides the standard Set and BitSet types.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.GenericString","page":"Unit Testing","title":"Test.GenericString","text":"The GenericString can be used to test generic string APIs that program to the AbstractString interface, in order to ensure that functions can work with string types besides the standard String type.\n\n\n\n\n\n","category":"type"},{"location":"stdlib/Test/#Test.detect_ambiguities","page":"Unit Testing","title":"Test.detect_ambiguities","text":"detect_ambiguities(mod1, mod2...; recursive=false,\n ambiguous_bottom=false,\n allowed_undefineds=nothing)\n\nReturn a vector of (Method,Method) pairs of ambiguous methods defined in the specified modules. Use recursive=true to test in all submodules.\n\nambiguous_bottom controls whether ambiguities triggered only by Union{} type parameters are included; in most cases you probably want to set this to false. See Base.isambiguous.\n\nSee Test.detect_unbound_args for an explanation of allowed_undefineds.\n\ncompat: Julia 1.8\nallowed_undefineds requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Test.detect_unbound_args","page":"Unit Testing","title":"Test.detect_unbound_args","text":"detect_unbound_args(mod1, mod2...; recursive=false, allowed_undefineds=nothing)\n\nReturn a vector of Methods which may have unbound type parameters. Use recursive=true to test in all submodules.\n\nBy default, any undefined symbols trigger a warning. This warning can be suppressed by supplying a collection of GlobalRefs for which the warning can be skipped. For example, setting\n\nallowed_undefineds = Set([GlobalRef(Base, :active_repl),\n GlobalRef(Base, :active_repl_backend)])\n\nwould suppress warnings about Base.active_repl and Base.active_repl_backend.\n\ncompat: Julia 1.8\nallowed_undefineds requires at least Julia 1.8.\n\n\n\n\n\n","category":"function"},{"location":"stdlib/Test/#Workflow-for-Testing-Packages","page":"Unit Testing","title":"Workflow for Testing Packages","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Using the tools available to us in the previous sections, here is a potential workflow of creating a package and adding tests to it.","category":"page"},{"location":"stdlib/Test/#Generating-an-Example-Package","page":"Unit Testing","title":"Generating an Example Package","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"For this workflow, we will create a package called Example:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"pkg> generate Example\nshell> cd Example\nshell> mkdir test\npkg> activate .","category":"page"},{"location":"stdlib/Test/#Creating-Sample-Functions","page":"Unit Testing","title":"Creating Sample Functions","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"The number one requirement for testing a package is to have functionality to test. For that, we will add some simple functions to Example that we can test. Add the following to src/Example.jl:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"module Example\n\nfunction greet()\n \"Hello world!\"\nend\n\nfunction simple_add(a, b)\n a + b\nend\n\nfunction type_multiply(a::Float64, b::Float64)\n a * b\nend\n\nexport greet, simple_add, type_multiply\n\nend","category":"page"},{"location":"stdlib/Test/#Creating-a-Test-Environment","page":"Unit Testing","title":"Creating a Test Environment","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"From within the root of the Example package, navigate to the test directory, activate a new environment there, and add the Test package to the environment:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"shell> cd test\npkg> activate .\n(test) pkg> add Test","category":"page"},{"location":"stdlib/Test/#Testing-Our-Package","page":"Unit Testing","title":"Testing Our Package","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Now, we are ready to add tests to Example. It is standard practice to create a file within the test directory called runtests.jl which contains the test sets we want to run. Go ahead and create that file within the test directory and add the following code to it:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"using Example\nusing Test\n\n@testset \"Example tests\" begin\n\n @testset \"Math tests\" begin\n include(\"math_tests.jl\")\n end\n\n @testset \"Greeting tests\" begin\n include(\"greeting_tests.jl\")\n end\nend","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"We will need to create those two included files, math_tests.jl and greeting_tests.jl, and add some tests to them.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Note: Notice how we did not have to specify add Example into the test environment's Project.toml. This is a benefit of Julia's testing system that you could read about more here.","category":"page"},{"location":"stdlib/Test/#Writing-Tests-for-math_tests.jl","page":"Unit Testing","title":"Writing Tests for math_tests.jl","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Using our knowledge of Test.jl, here are some example tests we could add to math_tests.jl:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"@testset \"Testset 1\" begin\n @test 2 == simple_add(1, 1)\n @test 3.5 == simple_add(1, 2.5)\n @test_throws MethodError simple_add(1, \"A\")\n @test_throws MethodError simple_add(1, 2, 3)\nend\n\n@testset \"Testset 2\" begin\n @test 1.0 == type_multiply(1.0, 1.0)\n @test isa(type_multiply(2.0, 2.0), Float64)\n @test_throws MethodError type_multiply(1, 2.5)\nend","category":"page"},{"location":"stdlib/Test/#Writing-Tests-for-greeting_tests.jl","page":"Unit Testing","title":"Writing Tests for greeting_tests.jl","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Using our knowledge of Test.jl, here are some example tests we could add to greeting_tests.jl:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"@testset \"Testset 3\" begin\n @test \"Hello world!\" == greet()\n @test_throws MethodError greet(\"Antonia\")\nend","category":"page"},{"location":"stdlib/Test/#Testing-Our-Package-2","page":"Unit Testing","title":"Testing Our Package","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Now that we have added our tests and our runtests.jl script in test, we can test our Example package by going back to the root of the Example package environment and reactivating the Example environment:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"shell> cd ..\npkg> activate .","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"From there, we can finally run our test suite as follows:","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"(Example) pkg> test\n Testing Example\n Status `/tmp/jl_Yngpvy/Project.toml`\n [fa318bd2] Example v0.1.0 `/home/src/Projects/tmp/errata/Example`\n [8dfed614] Test `@stdlib/Test`\n Status `/tmp/jl_Yngpvy/Manifest.toml`\n [fa318bd2] Example v0.1.0 `/home/src/Projects/tmp/errata/Example`\n [2a0f44e3] Base64 `@stdlib/Base64`\n [b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`\n [56ddb016] Logging `@stdlib/Logging`\n [d6f4376e] Markdown `@stdlib/Markdown`\n [9a3f8284] Random `@stdlib/Random`\n [ea8e919c] SHA `@stdlib/SHA`\n [9e88b42a] Serialization `@stdlib/Serialization`\n [8dfed614] Test `@stdlib/Test`\n Testing Running tests...\nTest Summary: | Pass Total\nExample tests | 9 9\n Testing Example tests passed","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"And if all went correctly, you should see a similar output as above. Using Test.jl, more complicated tests can be added for packages but this should ideally point developers in the direction of how to get started with testing their own created packages.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"DocTestSetup = nothing","category":"page"},{"location":"stdlib/Test/#Code-Coverage","page":"Unit Testing","title":"Code Coverage","text":"","category":"section"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"Code coverage tracking during tests can be enabled using the pkg> test --coverage flag (or at a lower level using the --code-coverage julia arg). This is on by default in the julia-runtest GitHub action.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"To evaluate coverage either manually inspect the .cov files that are generated beside the source files locally, or in CI use the julia-processcoverage GitHub action.","category":"page"},{"location":"stdlib/Test/","page":"Unit Testing","title":"Unit Testing","text":"compat: Julia 1.11\nSince Julia 1.11, coverage is not collected during the package precompilation phase.","category":"page"},{"location":"manual/interfaces/#Interfaces","page":"Interfaces","title":"Interfaces","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"A lot of the power and extensibility in Julia comes from a collection of informal interfaces. By extending a few specific methods to work for a custom type, objects of that type not only receive those functionalities, but they are also able to be used in other methods that are written to generically build upon those behaviors.","category":"page"},{"location":"manual/interfaces/#man-interface-iteration","page":"Interfaces","title":"Iteration","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"There are two methods that are always required:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Required method Brief description\niterate(iter) Returns either a tuple of the first item and initial state or nothing if empty\niterate(iter, state) Returns either a tuple of the next item and next state or nothing if no items remain","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"There are several more methods that should be defined in some circumstances. Please note that you should always define at least one of Base.IteratorSize(IterType) and length(iter) because the default definition of Base.IteratorSize(IterType) is Base.HasLength().","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Method When should this method be defined? Default definition Brief description\nBase.IteratorSize(IterType) If default is not appropriate Base.HasLength() One of Base.HasLength(), Base.HasShape{N}(), Base.IsInfinite(), or Base.SizeUnknown() as appropriate\nlength(iter) If Base.IteratorSize() returns Base.HasLength() or Base.HasShape{N}() (undefined) The number of items, if known\nsize(iter, [dim]) If Base.IteratorSize() returns Base.HasShape{N}() (undefined) The number of items in each dimension, if known\nBase.IteratorEltype(IterType) If default is not appropriate Base.HasEltype() Either Base.EltypeUnknown() or Base.HasEltype() as appropriate\neltype(IterType) If default is not appropriate Any The type of the first entry of the tuple returned by iterate()\nBase.isdone(iter, [state]) Must be defined if iterator is stateful missing Fast-path hint for iterator completion. If not defined for a stateful iterator then functions that check for done-ness, like isempty() and zip(), may mutate the iterator and cause buggy behaviour!","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Sequential iteration is implemented by the iterate function. Instead of mutating objects as they are iterated over, Julia iterators may keep track of the iteration state externally from the object. The return value from iterate is always either a tuple of a value and a state, or nothing if no elements remain. The state object will be passed back to the iterate function on the next iteration and is generally considered an implementation detail private to the iterable object.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Any object that defines this function is iterable and can be used in the many functions that rely upon iteration. It can also be used directly in a for loop since the syntax:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"for item in iter # or \"for item = iter\"\n # body\nend","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"is translated into:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"next = iterate(iter)\nwhile next !== nothing\n (item, state) = next\n # body\n next = iterate(iter, state)\nend","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"A simple example is an iterable sequence of square numbers with a defined length:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> struct Squares\n count::Int\n end\n\njulia> Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"With only iterate definition, the Squares type is already pretty powerful. We can iterate over all the elements:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> for item in Squares(7)\n println(item)\n end\n1\n4\n9\n16\n25\n36\n49","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"We can use many of the builtin methods that work with iterables, like in or sum:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> 25 in Squares(10)\ntrue\n\njulia> sum(Squares(100))\n338350","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"There are a few more methods we can extend to give Julia more information about this iterable collection. We know that the elements in a Squares sequence will always be Int. By extending the eltype method, we can give that information to Julia and help it make more specialized code in the more complicated methods. We also know the number of elements in our sequence, so we can extend length, too:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type\n\njulia> Base.length(S::Squares) = S.count","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Now, when we ask Julia to collect all the elements into an array it can preallocate a Vector{Int} of the right size instead of naively push!ing each element into a Vector{Any}:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> collect(Squares(4))\n4-element Vector{Int64}:\n 1\n 4\n 9\n 16","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"While we can rely upon generic implementations, we can also extend specific methods where we know there is a simpler algorithm. For example, there's a formula to compute the sum of squares, so we can override the generic iterative version with a more performant solution:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.sum(S::Squares) = (n = S.count; return n*(n+1)*(2n+1)÷6)\n\njulia> sum(Squares(1803))\n1955361914","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"This is a very common pattern throughout Julia Base: a small set of required methods define an informal interface that enable many fancier behaviors. In some cases, types will want to additionally specialize those extra behaviors when they know a more efficient algorithm can be used in their specific case.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"It is also often useful to allow iteration over a collection in reverse order by iterating over Iterators.reverse(iterator). To actually support reverse-order iteration, however, an iterator type T needs to implement iterate for Iterators.Reverse{T}. (Given r::Iterators.Reverse{T}, the underling iterator of type T is r.itr.) In our Squares example, we would implement Iterators.Reverse{Squares} methods:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.iterate(rS::Iterators.Reverse{Squares}, state=rS.itr.count) = state < 1 ? nothing : (state*state, state-1)\n\njulia> collect(Iterators.reverse(Squares(4)))\n4-element Vector{Int64}:\n 16\n 9\n 4\n 1","category":"page"},{"location":"manual/interfaces/#Indexing","page":"Interfaces","title":"Indexing","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Brief description\ngetindex(X, i) X[i], indexed access, non-scalar i should allocate a copy\nsetindex!(X, v, i) X[i] = v, indexed assignment\nfirstindex(X) The first index, used in X[begin]\nlastindex(X) The last index, used in X[end]","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For the Squares iterable above, we can easily compute the ith element of the sequence by squaring it. We can expose this as an indexing expression S[i]. To opt into this behavior, Squares simply needs to define getindex:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> function Base.getindex(S::Squares, i::Int)\n 1 <= i <= S.count || throw(BoundsError(S, i))\n return i*i\n end\n\njulia> Squares(100)[23]\n529","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Additionally, to support the syntax S[begin] and S[end], we must define firstindex and lastindex to specify the first and last valid indices, respectively:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.firstindex(S::Squares) = 1\n\njulia> Base.lastindex(S::Squares) = length(S)\n\njulia> Squares(23)[end]\n529","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For multi-dimensional begin/end indexing as in a[3, begin, 7], for example, you should define firstindex(a, dim) and lastindex(a, dim) (which default to calling first and last on axes(a, dim), respectively).","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Note, though, that the above only defines getindex with one integer index. Indexing with anything other than an Int will throw a MethodError saying that there was no matching method. In order to support indexing with ranges or vectors of Ints, separate methods must be written:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.getindex(S::Squares, i::Number) = S[convert(Int, i)]\n\njulia> Base.getindex(S::Squares, I) = [S[i] for i in I]\n\njulia> Squares(10)[[3,4.,5]]\n3-element Vector{Int64}:\n 9\n 16\n 25","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"While this is starting to support more of the indexing operations supported by some of the builtin types, there's still quite a number of behaviors missing. This Squares sequence is starting to look more and more like a vector as we've added behaviors to it. Instead of defining all these behaviors ourselves, we can officially define it as a subtype of an AbstractArray.","category":"page"},{"location":"manual/interfaces/#man-interface-array","page":"Interfaces","title":"Abstract Arrays","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Brief description\nsize(A) Returns a tuple containing the dimensions of A\ngetindex(A, i::Int) (if IndexLinear) Linear scalar indexing\ngetindex(A, I::Vararg{Int, N}) (if IndexCartesian, where N = ndims(A)) N-dimensional scalar indexing\nOptional methods Default definition Brief description\nIndexStyle(::Type) IndexCartesian() Returns either IndexLinear() or IndexCartesian(). See the description below.\nsetindex!(A, v, i::Int) (if IndexLinear) Scalar indexed assignment\nsetindex!(A, v, I::Vararg{Int, N}) (if IndexCartesian, where N = ndims(A)) N-dimensional scalar indexed assignment\ngetindex(A, I...) defined in terms of scalar getindex Multidimensional and nonscalar indexing\nsetindex!(A, X, I...) defined in terms of scalar setindex! Multidimensional and nonscalar indexed assignment\niterate defined in terms of scalar getindex Iteration\nlength(A) prod(size(A)) Number of elements\nsimilar(A) similar(A, eltype(A), size(A)) Return a mutable array with the same shape and element type\nsimilar(A, ::Type{S}) similar(A, S, size(A)) Return a mutable array with the same shape and the specified element type\nsimilar(A, dims::Dims) similar(A, eltype(A), dims) Return a mutable array with the same element type and size dims\nsimilar(A, ::Type{S}, dims::Dims) Array{S}(undef, dims) Return a mutable array with the specified element type and size\nNon-traditional indices Default definition Brief description\naxes(A) map(OneTo, size(A)) Return a tuple of AbstractUnitRange{<:Integer} of valid indices. The axes should be their own axes, that is axes.(axes(A),1) == axes(A) should be satisfied.\nsimilar(A, ::Type{S}, inds) similar(A, S, Base.to_shape(inds)) Return a mutable array with the specified indices inds (see below)\nsimilar(T::Union{Type,Function}, inds) T(Base.to_shape(inds)) Return an array similar to T with the specified indices inds (see below)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If a type is defined as a subtype of AbstractArray, it inherits a very large set of rich behaviors including iteration and multidimensional indexing built on top of single-element access. See the arrays manual page and the Julia Base section for more supported methods.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"A key part in defining an AbstractArray subtype is IndexStyle. Since indexing is such an important part of an array and often occurs in hot loops, it's important to make both indexing and indexed assignment as efficient as possible. Array data structures are typically defined in one of two ways: either it most efficiently accesses its elements using just one index (linear indexing) or it intrinsically accesses the elements with indices specified for every dimension. These two modalities are identified by Julia as IndexLinear() and IndexCartesian(). Converting a linear index to multiple indexing subscripts is typically very expensive, so this provides a traits-based mechanism to enable efficient generic code for all array types.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"This distinction determines which scalar indexing methods the type must define. IndexLinear() arrays are simple: just define getindex(A::ArrayType, i::Int). When the array is subsequently indexed with a multidimensional set of indices, the fallback getindex(A::AbstractArray, I...) efficiently converts the indices into one linear index and then calls the above method. IndexCartesian() arrays, on the other hand, require methods to be defined for each supported dimensionality with ndims(A) Int indices. For example, SparseMatrixCSC from the SparseArrays standard library module, only supports two dimensions, so it just defines getindex(A::SparseMatrixCSC, i::Int, j::Int). The same holds for setindex!.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Returning to the sequence of squares from above, we could instead define it as a subtype of an AbstractArray{Int, 1}:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> struct SquaresVector <: AbstractArray{Int, 1}\n count::Int\n end\n\njulia> Base.size(S::SquaresVector) = (S.count,)\n\njulia> Base.IndexStyle(::Type{<:SquaresVector}) = IndexLinear()\n\njulia> Base.getindex(S::SquaresVector, i::Int) = i*i","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Note that it's very important to specify the two parameters of the AbstractArray; the first defines the eltype, and the second defines the ndims. That supertype and those three methods are all it takes for SquaresVector to be an iterable, indexable, and completely functional array:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> s = SquaresVector(4)\n4-element SquaresVector:\n 1\n 4\n 9\n 16\n\njulia> s[s .> 8]\n2-element Vector{Int64}:\n 9\n 16\n\njulia> s + s\n4-element Vector{Int64}:\n 2\n 8\n 18\n 32\n\njulia> sin.(s)\n4-element Vector{Float64}:\n 0.8414709848078965\n -0.7568024953079282\n 0.4121184852417566\n -0.2879033166650653","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"As a more complicated example, let's define our own toy N-dimensional sparse-like array type built on top of Dict:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> struct SparseArray{T,N} <: AbstractArray{T,N}\n data::Dict{NTuple{N,Int}, T}\n dims::NTuple{N,Int}\n end\n\njulia> SparseArray(::Type{T}, dims::Int...) where {T} = SparseArray(T, dims);\n\njulia> SparseArray(::Type{T}, dims::NTuple{N,Int}) where {T,N} = SparseArray{T,N}(Dict{NTuple{N,Int}, T}(), dims);\n\njulia> Base.size(A::SparseArray) = A.dims\n\njulia> Base.similar(A::SparseArray, ::Type{T}, dims::Dims) where {T} = SparseArray(T, dims)\n\njulia> Base.getindex(A::SparseArray{T,N}, I::Vararg{Int,N}) where {T,N} = get(A.data, I, zero(T))\n\njulia> Base.setindex!(A::SparseArray{T,N}, v, I::Vararg{Int,N}) where {T,N} = (A.data[I] = v)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Notice that this is an IndexCartesian array, so we must manually define getindex and setindex! at the dimensionality of the array. Unlike the SquaresVector, we are able to define setindex!, and so we can mutate the array:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> A = SparseArray(Float64, 3, 3)\n3×3 SparseArray{Float64, 2}:\n 0.0 0.0 0.0\n 0.0 0.0 0.0\n 0.0 0.0 0.0\n\njulia> fill!(A, 2)\n3×3 SparseArray{Float64, 2}:\n 2.0 2.0 2.0\n 2.0 2.0 2.0\n 2.0 2.0 2.0\n\njulia> A[:] = 1:length(A); A\n3×3 SparseArray{Float64, 2}:\n 1.0 4.0 7.0\n 2.0 5.0 8.0\n 3.0 6.0 9.0","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The result of indexing an AbstractArray can itself be an array (for instance when indexing by an AbstractRange). The AbstractArray fallback methods use similar to allocate an Array of the appropriate size and element type, which is filled in using the basic indexing method described above. However, when implementing an array wrapper you often want the result to be wrapped as well:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> A[1:2,:]\n2×3 SparseArray{Float64, 2}:\n 1.0 4.0 7.0\n 2.0 5.0 8.0","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In this example it is accomplished by defining Base.similar(A::SparseArray, ::Type{T}, dims::Dims) where T to create the appropriate wrapped array. (Note that while similar supports 1- and 2-argument forms, in most case you only need to specialize the 3-argument form.) For this to work it's important that SparseArray is mutable (supports setindex!). Defining similar, getindex and setindex! for SparseArray also makes it possible to copy the array:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> copy(A)\n3×3 SparseArray{Float64, 2}:\n 1.0 4.0 7.0\n 2.0 5.0 8.0\n 3.0 6.0 9.0","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In addition to all the iterable and indexable methods from above, these types can also interact with each other and use most of the methods defined in Julia Base for AbstractArrays:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> A[SquaresVector(3)]\n3-element SparseArray{Float64, 1}:\n 1.0\n 4.0\n 9.0\n\njulia> sum(A)\n45.0","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If you are defining an array type that allows non-traditional indexing (indices that start at something other than 1), you should specialize axes. You should also specialize similar so that the dims argument (ordinarily a Dims size-tuple) can accept AbstractUnitRange objects, perhaps range-types Ind of your own design. For more information, see Arrays with custom indices.","category":"page"},{"location":"manual/interfaces/#man-interface-strided-arrays","page":"Interfaces","title":"Strided Arrays","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Brief description\nstrides(A) Return the distance in memory (in number of elements) between adjacent elements in each dimension as a tuple. If A is an AbstractArray{T,0}, this should return an empty tuple.\nBase.unsafe_convert(::Type{Ptr{T}}, A) Return the native address of an array.\nBase.elsize(::Type{<:A}) Return the stride between consecutive elements in the array.\nOptional methods Default definition Brief description\nstride(A, i::Int) strides(A)[i] Return the distance in memory (in number of elements) between adjacent elements in dimension k.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"A strided array is a subtype of AbstractArray whose entries are stored in memory with fixed strides. Provided the element type of the array is compatible with BLAS, a strided array can utilize BLAS and LAPACK routines for more efficient linear algebra routines. A typical example of a user-defined strided array is one that wraps a standard Array with additional structure.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Warning: do not implement these methods if the underlying storage is not actually strided, as it may lead to incorrect results or segmentation faults.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Here are some examples to demonstrate which type of arrays are strided and which are not:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"1:5 # not strided (there is no storage associated with this array.)\nVector(1:5) # is strided with strides (1,)\nA = [1 5; 2 6; 3 7; 4 8] # is strided with strides (1,4)\nV = view(A, 1:2, :) # is strided with strides (1,4)\nV = view(A, 1:2:3, 1:2) # is strided with strides (2,4)\nV = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not fixed.","category":"page"},{"location":"manual/interfaces/#man-interfaces-broadcasting","page":"Interfaces","title":"Customizing broadcasting","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Brief description\nBase.BroadcastStyle(::Type{SrcType}) = SrcStyle() Broadcasting behavior of SrcType\nBase.similar(bc::Broadcasted{DestStyle}, ::Type{ElType}) Allocation of output container\nOptional methods \nBase.BroadcastStyle(::Style1, ::Style2) = Style12() Precedence rules for mixing styles\nBase.axes(x) Declaration of the indices of x, as per axes(x).\nBase.broadcastable(x) Convert x to an object that has axes and supports indexing\nBypassing default machinery \nBase.copy(bc::Broadcasted{DestStyle}) Custom implementation of broadcast\nBase.copyto!(dest, bc::Broadcasted{DestStyle}) Custom implementation of broadcast!, specializing on DestStyle\nBase.copyto!(dest::DestType, bc::Broadcasted{Nothing}) Custom implementation of broadcast!, specializing on DestType\nBase.Broadcast.broadcasted(f, args...) Override the default lazy behavior within a fused expression\nBase.Broadcast.instantiate(bc::Broadcasted{DestStyle}) Override the computation of the lazy broadcast's axes","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Broadcasting is triggered by an explicit call to broadcast or broadcast!, or implicitly by \"dot\" operations like A .+ b or f.(x, y). Any object that has axes and supports indexing can participate as an argument in broadcasting, and by default the result is stored in an Array. This basic framework is extensible in three major ways:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Ensuring that all arguments support broadcast\nSelecting an appropriate output array for the given set of arguments\nSelecting an efficient implementation for the given set of arguments","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Not all types support axes and indexing, but many are convenient to allow in broadcast. The Base.broadcastable function is called on each argument to broadcast, allowing it to return something different that supports axes and indexing. By default, this is the identity function for all AbstractArrays and Numbers — they already support axes and indexing.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If a type is intended to act like a \"0-dimensional scalar\" (a single object) rather than as a container for broadcasting, then the following method should be defined:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.broadcastable(o::MyType) = Ref(o)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"that returns the argument wrapped in a 0-dimensional Ref container. For example, such a wrapper method is defined for types themselves, functions, special singletons like missing and nothing, and dates.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Custom array-like types can specialize Base.broadcastable to define their shape, but they should follow the convention that collect(Base.broadcastable(x)) == collect(x). A notable exception is AbstractString; strings are special-cased to behave as scalars for the purposes of broadcast even though they are iterable collections of their characters (see Strings for more).","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The next two steps (selecting the output array and implementation) are dependent upon determining a single answer for a given set of arguments. Broadcast must take all the varied types of its arguments and collapse them down to just one output array and one implementation. Broadcast calls this single answer a \"style\". Every broadcastable object each has its own preferred style, and a promotion-like system is used to combine these styles into a single answer — the \"destination style\".","category":"page"},{"location":"manual/interfaces/#Broadcast-Styles","page":"Interfaces","title":"Broadcast Styles","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle is the abstract type from which all broadcast styles are derived. When used as a function it has two possible forms, unary (single-argument) and binary. The unary variant states that you intend to implement specific broadcasting behavior and/or output type, and do not wish to rely on the default fallback Broadcast.DefaultArrayStyle.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"To override these defaults, you can define a custom BroadcastStyle for your object:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"struct MyStyle <: Broadcast.BroadcastStyle end\nBase.BroadcastStyle(::Type{<:MyType}) = MyStyle()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In some cases it might be convenient not to have to define MyStyle, in which case you can leverage one of the general broadcast wrappers:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle(::Type{<:MyType}) = Broadcast.Style{MyType}() can be used for arbitrary types.\nBase.BroadcastStyle(::Type{<:MyType}) = Broadcast.ArrayStyle{MyType}() is preferred if MyType is an AbstractArray.\nFor AbstractArrays that only support a certain dimensionality, create a subtype of Broadcast.AbstractArrayStyle{N} (see below).","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"When your broadcast operation involves several arguments, individual argument styles get combined to determine a single DestStyle that controls the type of the output container. For more details, see below.","category":"page"},{"location":"manual/interfaces/#Selecting-an-appropriate-output-array","page":"Interfaces","title":"Selecting an appropriate output array","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The broadcast style is computed for every broadcasting operation to allow for dispatch and specialization. The actual allocation of the result array is handled by similar, using the Broadcasted object as its first argument.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType})","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The fallback definition is","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"similar(bc::Broadcasted{DefaultArrayStyle{N}}, ::Type{ElType}) where {N,ElType} =\n similar(Array{ElType}, axes(bc))","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"However, if needed you can specialize on any or all of these arguments. The final argument bc is a lazy representation of a (potentially fused) broadcast operation, a Broadcasted object. For these purposes, the most important fields of the wrapper are f and args, describing the function and argument list, respectively. Note that the argument list can — and often does — include other nested Broadcasted wrappers.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For a complete example, let's say you have created a type, ArrayAndChar, that stores an array and a single character:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"struct ArrayAndChar{T,N} <: AbstractArray{T,N}\n data::Array{T,N}\n char::Char\nend\nBase.size(A::ArrayAndChar) = size(A.data)\nBase.getindex(A::ArrayAndChar{T,N}, inds::Vararg{Int,N}) where {T,N} = A.data[inds...]\nBase.setindex!(A::ArrayAndChar{T,N}, val, inds::Vararg{Int,N}) where {T,N} = A.data[inds...] = val\nBase.showarg(io::IO, A::ArrayAndChar, toplevel) = print(io, typeof(A), \" with char '\", A.char, \"'\")","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"You might want broadcasting to preserve the char \"metadata\". First we define","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar}()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"This means we must also define a corresponding similar method:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{ArrayAndChar}}, ::Type{ElType}) where ElType\n # Scan the inputs for the ArrayAndChar:\n A = find_aac(bc)\n # Use the char field of A to create the output\n ArrayAndChar(similar(Array{ElType}, axes(bc)), A.char)\nend\n\n\"`A = find_aac(As)` returns the first ArrayAndChar among the arguments.\"\nfind_aac(bc::Base.Broadcast.Broadcasted) = find_aac(bc.args)\nfind_aac(args::Tuple) = find_aac(find_aac(args[1]), Base.tail(args))\nfind_aac(x) = x\nfind_aac(::Tuple{}) = nothing\nfind_aac(a::ArrayAndChar, rest) = a\nfind_aac(::Any, rest) = find_aac(rest)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"From these definitions, one obtains the following behavior:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> a = ArrayAndChar([1 2; 3 4], 'x')\n2×2 ArrayAndChar{Int64, 2} with char 'x':\n 1 2\n 3 4\n\njulia> a .+ 1\n2×2 ArrayAndChar{Int64, 2} with char 'x':\n 2 3\n 4 5\n\njulia> a .+ [5,10]\n2×2 ArrayAndChar{Int64, 2} with char 'x':\n 6 7\n 13 14","category":"page"},{"location":"manual/interfaces/#extending-in-place-broadcast","page":"Interfaces","title":"Extending broadcast with custom implementations","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In general, a broadcast operation is represented by a lazy Broadcasted container that holds onto the function to be applied alongside its arguments. Those arguments may themselves be more nested Broadcasted containers, forming a large expression tree to be evaluated. A nested tree of Broadcasted containers is directly constructed by the implicit dot syntax; 5 .+ 2.*x is transiently represented by Broadcasted(+, 5, Broadcasted(*, 2, x)), for example. This is invisible to users as it is immediately realized through a call to copy, but it is this container that provides the basis for broadcast's extensibility for authors of custom types. The built-in broadcast machinery will then determine the result type and size based upon the arguments, allocate it, and then finally copy the realization of the Broadcasted object into it with a default copyto!(::AbstractArray, ::Broadcasted) method. The built-in fallback broadcast and broadcast! methods similarly construct a transient Broadcasted representation of the operation so they can follow the same codepath. This allows custom array implementations to provide their own copyto! specialization to customize and optimize broadcasting. This is again determined by the computed broadcast style. This is such an important part of the operation that it is stored as the first type parameter of the Broadcasted type, allowing for dispatch and specialization.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For some types, the machinery to \"fuse\" operations across nested levels of broadcasting is not available or could be done more efficiently incrementally. In such cases, you may need or want to evaluate x .* (x .+ 1) as if it had been written broadcast(*, x, broadcast(+, x, 1)), where the inner operation is evaluated before tackling the outer operation. This sort of eager operation is directly supported by a bit of indirection; instead of directly constructing Broadcasted objects, Julia lowers the fused expression x .* (x .+ 1) to Broadcast.broadcasted(*, x, Broadcast.broadcasted(+, x, 1)). Now, by default, broadcasted just calls the Broadcasted constructor to create the lazy representation of the fused expression tree, but you can choose to override it for a particular combination of function and arguments.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"As an example, the builtin AbstractRange objects use this machinery to optimize pieces of broadcasted expressions that can be eagerly evaluated purely in terms of the start, step, and length (or stop) instead of computing every single element. Just like all the other machinery, broadcasted also computes and exposes the combined broadcast style of its arguments, so instead of specializing on broadcasted(f, args...), you can specialize on broadcasted(::DestStyle, f, args...) for any combination of style, function, and arguments.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For example, the following definition supports the negation of ranges:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange) = range(-first(r), step=-step(r), length=length(r))","category":"page"},{"location":"manual/interfaces/#extending-in-place-broadcast-2","page":"Interfaces","title":"Extending in-place broadcasting","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In-place broadcasting can be supported by defining the appropriate copyto!(dest, bc::Broadcasted) method. Because you might want to specialize either on dest or the specific subtype of bc, to avoid ambiguities between packages we recommend the following convention.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If you wish to specialize on a particular style DestStyle, define a method for","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"copyto!(dest, bc::Broadcasted{DestStyle})","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Optionally, with this form you can also specialize on the type of dest.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If instead you want to specialize on the destination type DestType without specializing on DestStyle, then you should define a method with the following signature:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"copyto!(dest::DestType, bc::Broadcasted{Nothing})","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"This leverages a fallback implementation of copyto! that converts the wrapper into a Broadcasted{Nothing}. Consequently, specializing on DestType has lower precedence than methods that specialize on DestStyle.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Similarly, you can completely override out-of-place broadcasting with a copy(::Broadcasted) method.","category":"page"},{"location":"manual/interfaces/#Working-with-Broadcasted-objects","page":"Interfaces","title":"Working with Broadcasted objects","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In order to implement such a copy or copyto!, method, of course, you must work with the Broadcasted wrapper to compute each element. There are two main ways of doing so:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Broadcast.flatten recomputes the potentially nested operation into a single function and flat list of arguments. You are responsible for implementing the broadcasting shape rules yourself, but this may be helpful in limited situations.\nIterating over the CartesianIndices of the axes(::Broadcasted) and using indexing with the resulting CartesianIndex object to compute the result.","category":"page"},{"location":"manual/interfaces/#writing-binary-broadcasting-rules","page":"Interfaces","title":"Writing binary broadcasting rules","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"The precedence rules are defined by binary BroadcastStyle calls:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle(::Style1, ::Style2) = Style12()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"where Style12 is the BroadcastStyle you want to choose for outputs involving arguments of Style1 and Style2. For example,","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Base.BroadcastStyle(::Broadcast.Style{Tuple}, ::Broadcast.AbstractArrayStyle{0}) = Broadcast.Style{Tuple}()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"indicates that Tuple \"wins\" over zero-dimensional arrays (the output container will be a tuple). It is worth noting that you do not need to (and should not) define both argument orders of this call; defining one is sufficient no matter what order the user supplies the arguments in.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For AbstractArray types, defining a BroadcastStyle supersedes the fallback choice, Broadcast.DefaultArrayStyle. DefaultArrayStyle and the abstract supertype, AbstractArrayStyle, store the dimensionality as a type parameter to support specialized array types that have fixed dimensionality requirements.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"DefaultArrayStyle \"loses\" to any other AbstractArrayStyle that has been defined because of the following methods:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"BroadcastStyle(a::AbstractArrayStyle{Any}, ::DefaultArrayStyle) = a\nBroadcastStyle(a::AbstractArrayStyle{N}, ::DefaultArrayStyle{N}) where N = a\nBroadcastStyle(a::AbstractArrayStyle{M}, ::DefaultArrayStyle{N}) where {M,N} =\n typeof(a)(Val(max(M, N)))","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"You do not need to write binary BroadcastStyle rules unless you want to establish precedence for two or more non-DefaultArrayStyle types.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"If your array type does have fixed dimensionality requirements, then you should subtype AbstractArrayStyle. For example, the sparse array code has the following definitions:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"struct SparseVecStyle <: Broadcast.AbstractArrayStyle{1} end\nstruct SparseMatStyle <: Broadcast.AbstractArrayStyle{2} end\nBase.BroadcastStyle(::Type{<:SparseVector}) = SparseVecStyle()\nBase.BroadcastStyle(::Type{<:SparseMatrixCSC}) = SparseMatStyle()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Whenever you subtype AbstractArrayStyle, you also need to define rules for combining dimensionalities, by creating a constructor for your style that takes a Val(N) argument. For example:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"SparseVecStyle(::Val{0}) = SparseVecStyle()\nSparseVecStyle(::Val{1}) = SparseVecStyle()\nSparseVecStyle(::Val{2}) = SparseMatStyle()\nSparseVecStyle(::Val{N}) where N = Broadcast.DefaultArrayStyle{N}()","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"These rules indicate that the combination of a SparseVecStyle with 0- or 1-dimensional arrays yields another SparseVecStyle, that its combination with a 2-dimensional array yields a SparseMatStyle, and anything of higher dimensionality falls back to the dense arbitrary-dimensional framework. These rules allow broadcasting to keep the sparse representation for operations that result in one or two dimensional outputs, but produce an Array for any other dimensionality.","category":"page"},{"location":"manual/interfaces/#man-instance-properties","page":"Interfaces","title":"Instance Properties","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Default definition Brief description\npropertynames(x::ObjType, private::Bool=false) fieldnames(typeof(x)) Return a tuple of the properties (x.property) of an object x. If private=true, also return property names intended to be kept as private\ngetproperty(x::ObjType, s::Symbol) getfield(x, s) Return property s of x. x.s calls getproperty(x, :s).\nsetproperty!(x::ObjType, s::Symbol, v) setfield!(x, s, v) Set property s of x to v. x.s = v calls setproperty!(x, :s, v). Should return v.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Sometimes, it is desirable to change how the end-user interacts with the fields of an object. Instead of granting direct access to type fields, an extra layer of abstraction between the user and the code can be provided by overloading object.field. Properties are what the user sees of the object, fields what the object actually is.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"By default, properties and fields are the same. However, this behavior can be changed. For example, take this representation of a point in a plane in polar coordinates:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> mutable struct Point\n r::Float64\n ϕ::Float64\n end\n\njulia> p = Point(7.0, pi/4)\nPoint(7.0, 0.7853981633974483)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"As described in the table above dot access p.r is the same as getproperty(p, :r) which is by default the same as getfield(p, :r):","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> propertynames(p)\n(:r, :ϕ)\n\njulia> getproperty(p, :r), getproperty(p, :ϕ)\n(7.0, 0.7853981633974483)\n\njulia> p.r, p.ϕ\n(7.0, 0.7853981633974483)\n\njulia> getfield(p, :r), getproperty(p, :ϕ)\n(7.0, 0.7853981633974483)","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"However, we may want users to be unaware that Point stores the coordinates as r and ϕ (fields), and instead interact with x and y (properties). The methods in the first column can be defined to add new functionality:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> Base.propertynames(::Point, private::Bool=false) = private ? (:x, :y, :r, :ϕ) : (:x, :y)\n\njulia> function Base.getproperty(p::Point, s::Symbol)\n if s === :x\n return getfield(p, :r) * cos(getfield(p, :ϕ))\n elseif s === :y\n return getfield(p, :r) * sin(getfield(p, :ϕ))\n else\n # This allows accessing fields with p.r and p.ϕ\n return getfield(p, s)\n end\n end\n\njulia> function Base.setproperty!(p::Point, s::Symbol, f)\n if s === :x\n y = p.y\n setfield!(p, :r, sqrt(f^2 + y^2))\n setfield!(p, :ϕ, atan(y, f))\n return f\n elseif s === :y\n x = p.x\n setfield!(p, :r, sqrt(x^2 + f^2))\n setfield!(p, :ϕ, atan(f, x))\n return f\n else\n # This allow modifying fields with p.r and p.ϕ\n return setfield!(p, s, f)\n end\n end","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"It is important that getfield and setfield are used inside getproperty and setproperty! instead of the dot syntax, since the dot syntax would make the functions recursive which can lead to type inference issues. We can now try out the new functionality:","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> propertynames(p)\n(:x, :y)\n\njulia> p.x\n4.949747468305833\n\njulia> p.y = 4.0\n4.0\n\njulia> p.r\n6.363961030678928","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Finally, it is worth noting that adding instance properties like this is quite rarely done in Julia and should in general only be done if there is a good reason for doing so.","category":"page"},{"location":"manual/interfaces/#man-rounding-interface","page":"Interfaces","title":"Rounding","text":"","category":"section"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"Methods to implement Default definition Brief description\nround(x::ObjType, r::RoundingMode) none Round x and return the result. If possible, round should return an object of the same type as x\nround(T::Type, x::ObjType, r::RoundingMode) convert(T, round(x, r)) Round x, returning the result as a T","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"To support rounding on a new type it is typically sufficient to define the single method round(x::ObjType, r::RoundingMode). The passed rounding mode determines in which direction the value should be rounded. The most commonly used rounding modes are RoundNearest, RoundToZero, RoundDown, and RoundUp, as these rounding modes are used in the definitions of the one argument round, method, and trunc, floor, and ceil, respectively.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"In some cases, it is possible to define a three-argument round method that is more accurate or performant than the two-argument method followed by conversion. In this case it is acceptable to define the three argument method in addition to the two argument method. If it is impossible to represent the rounded result as an object of the type T, then the three argument method should throw an InexactError.","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"For example, if we have an Interval type which represents a range of possible values similar to https://github.com/JuliaPhysics/Measurements.jl, we may define rounding on that type with the following","category":"page"},{"location":"manual/interfaces/","page":"Interfaces","title":"Interfaces","text":"julia> struct Interval{T}\n min::T\n max::T\n end\n\njulia> Base.round(x::Interval, r::RoundingMode) = Interval(round(x.min, r), round(x.max, r))\n\njulia> x = Interval(1.7, 2.2)\nInterval{Float64}(1.7, 2.2)\n\njulia> round(x)\nInterval{Float64}(2.0, 2.0)\n\njulia> floor(x)\nInterval{Float64}(1.0, 2.0)\n\njulia> ceil(x)\nInterval{Float64}(2.0, 3.0)\n\njulia> trunc(x)\nInterval{Float64}(1.0, 2.0)","category":"page"}] } diff --git a/en/v1.12-dev/stdlib/ArgTools/index.html b/en/v1.12-dev/stdlib/ArgTools/index.html index ad328253cdd3..69230938291c 100644 --- a/en/v1.12-dev/stdlib/ArgTools/index.html +++ b/en/v1.12-dev/stdlib/ArgTools/index.html @@ -26,4 +26,4 @@ ## test using `arg` ## end ## post-test cleanup ## -end

    This method is useful if you need to specify path instead of using path name generated by tempname(). Since path is passed from outside of arg_writers, the path is not an argument to the do block in this form.

    ArgTools.@arg_testMacro
    @arg_test arg1 arg2 ... body

    The @arg_test macro is used to convert arg functions provided by arg_readers and arg_writers into actual argument values. When you write @arg_test arg body it is equivalent to arg(arg -> body).

    +end

    This method is useful if you need to specify path instead of using path name generated by tempname(). Since path is passed from outside of arg_writers, the path is not an argument to the do block in this form.

    ArgTools.@arg_testMacro
    @arg_test arg1 arg2 ... body

    The @arg_test macro is used to convert arg functions provided by arg_readers and arg_writers into actual argument values. When you write @arg_test arg body it is equivalent to arg(arg -> body).

    diff --git a/en/v1.12-dev/stdlib/Artifacts/index.html b/en/v1.12-dev/stdlib/Artifacts/index.html index 13444c84747a..c9bc6d99d4c8 100644 --- a/en/v1.12-dev/stdlib/Artifacts/index.html +++ b/en/v1.12-dev/stdlib/Artifacts/index.html @@ -9,4 +9,4 @@ platform::AbstractPlatform = HostPlatform())

    Thin wrapper around artifact_meta() to return the hash of the specified, platform- collapsed artifact. Returns nothing if no mapping can be found.

    Julia 1.3

    This function requires at least Julia 1.3.

    Artifacts.find_artifacts_tomlFunction
    find_artifacts_toml(path::String)

    Given the path to a .jl file, (such as the one returned by __source__.file in a macro context), find the (Julia)Artifacts.toml that is contained within the containing project (if it exists), otherwise return nothing.

    Julia 1.3

    This function requires at least Julia 1.3.

    Artifacts.@artifact_strMacro
    macro artifact_str(name)

    Return the on-disk path to an artifact. Automatically looks the artifact up by name in the project's (Julia)Artifacts.toml file. Throws an error on if the requested artifact is not present. If run in the REPL, searches for the toml file starting in the current directory, see find_artifacts_toml() for more.

    If the artifact is marked "lazy" and the package has using LazyArtifacts defined, the artifact will be downloaded on-demand with Pkg the first time this macro tries to compute the path. The files will then be left installed locally for later.

    If name contains a forward or backward slash, all elements after the first slash will be taken to be path names indexing into the artifact, allowing for an easy one-liner to access a single file/directory within an artifact. Example:

    ffmpeg_path = @artifact"FFMPEG/bin/ffmpeg"
    Julia 1.3

    This macro requires at least Julia 1.3.

    Julia 1.6

    Slash-indexing requires at least Julia 1.6.

    Artifacts.artifact_existsFunction
    artifact_exists(hash::SHA1; honor_overrides::Bool=true)

    Return whether or not the given artifact (identified by its sha1 git tree hash) exists on-disk. Note that it is possible that the given artifact exists in multiple locations (e.g. within multiple depots).

    Julia 1.3

    This function requires at least Julia 1.3.

    Artifacts.artifact_pathFunction
    artifact_path(hash::SHA1; honor_overrides::Bool=true)

    Given an artifact (identified by SHA1 git tree hash), return its installation path. If the artifact does not exist, returns the location it would be installed to.

    Julia 1.3

    This function requires at least Julia 1.3.

    Artifacts.select_downloadable_artifactsFunction
    select_downloadable_artifacts(artifacts_toml::String;
                                   platform = HostPlatform,
                                   include_lazy = false,
    -                              pkg_uuid = nothing)

    Return a dictionary where every entry is an artifact from the given Artifacts.toml that should be downloaded for the requested platform. Lazy artifacts are included if include_lazy is set.

    + pkg_uuid = nothing)

    Return a dictionary where every entry is an artifact from the given Artifacts.toml that should be downloaded for the requested platform. Lazy artifacts are included if include_lazy is set.

    diff --git a/en/v1.12-dev/stdlib/Base64/index.html b/en/v1.12-dev/stdlib/Base64/index.html index 79245a7dd8fe..ade04989add8 100644 --- a/en/v1.12-dev/stdlib/Base64/index.html +++ b/en/v1.12-dev/stdlib/Base64/index.html @@ -37,4 +37,4 @@ 0x21 julia> String(b) -"Hello!"
    Base64.stringmimeFunction
    stringmime(mime, x; context=nothing)

    Return an AbstractString containing the representation of x in the requested mime type. This is similar to repr(mime, x) except that binary data is base64-encoded as an ASCII string.

    The optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to show.

    +"Hello!"
    Base64.stringmimeFunction
    stringmime(mime, x; context=nothing)

    Return an AbstractString containing the representation of x in the requested mime type. This is similar to repr(mime, x) except that binary data is base64-encoded as an ASCII string.

    The optional keyword argument context can be set to :key=>value pair or an IO or IOContext object whose attributes are used for the I/O stream passed to show.

    diff --git a/en/v1.12-dev/stdlib/CRC32c/index.html b/en/v1.12-dev/stdlib/CRC32c/index.html index 69dd3a1ced9c..7a649f1c9241 100644 --- a/en/v1.12-dev/stdlib/CRC32c/index.html +++ b/en/v1.12-dev/stdlib/CRC32c/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    CRC32c

    Standard library module for computing the CRC-32c checksum.

    CRC32c.crc32cFunction
    crc32c(data, crc::UInt32=0x00000000)

    Compute the CRC-32c checksum of the given data, which can be an Array{UInt8}, a contiguous subarray thereof, or a String. Optionally, you can pass a starting crc integer to be mixed in with the checksum. The crc parameter can be used to compute a checksum on data divided into chunks: performing crc32c(data2, crc32c(data1)) is equivalent to the checksum of [data1; data2]. (Technically, a little-endian checksum is computed.)

    There is also a method crc32c(io, nb, crc) to checksum nb bytes from a stream io, or crc32c(io, crc) to checksum all the remaining bytes. Hence you can do open(crc32c, filename) to checksum an entire file, or crc32c(seekstart(buf)) to checksum an IOBuffer without calling take!.

    For a String, note that the result is specific to the UTF-8 encoding (a different checksum would be obtained from a different Unicode encoding). To checksum an a::Array of some other bitstype, you can do crc32c(reinterpret(UInt8,a)), but note that the result may be endian-dependent.

    CRC32c.crc32cMethod
    crc32c(io::IO, [nb::Integer,] crc::UInt32=0x00000000)

    Read up to nb bytes from io and return the CRC-32c checksum, optionally mixed with a starting crc integer. If nb is not supplied, then io will be read until the end of the stream.

    +

    CRC32c

    Standard library module for computing the CRC-32c checksum.

    CRC32c.crc32cFunction
    crc32c(data, crc::UInt32=0x00000000)

    Compute the CRC-32c checksum of the given data, which can be an Array{UInt8}, a contiguous subarray thereof, or a String. Optionally, you can pass a starting crc integer to be mixed in with the checksum. The crc parameter can be used to compute a checksum on data divided into chunks: performing crc32c(data2, crc32c(data1)) is equivalent to the checksum of [data1; data2]. (Technically, a little-endian checksum is computed.)

    There is also a method crc32c(io, nb, crc) to checksum nb bytes from a stream io, or crc32c(io, crc) to checksum all the remaining bytes. Hence you can do open(crc32c, filename) to checksum an entire file, or crc32c(seekstart(buf)) to checksum an IOBuffer without calling take!.

    For a String, note that the result is specific to the UTF-8 encoding (a different checksum would be obtained from a different Unicode encoding). To checksum an a::Array of some other bitstype, you can do crc32c(reinterpret(UInt8,a)), but note that the result may be endian-dependent.

    CRC32c.crc32cMethod
    crc32c(io::IO, [nb::Integer,] crc::UInt32=0x00000000)

    Read up to nb bytes from io and return the CRC-32c checksum, optionally mixed with a starting crc integer. If nb is not supplied, then io will be read until the end of the stream.

    diff --git a/en/v1.12-dev/stdlib/Dates/index.html b/en/v1.12-dev/stdlib/Dates/index.html index d902f6cf16e8..7e4044a9d8a6 100644 --- a/en/v1.12-dev/stdlib/Dates/index.html +++ b/en/v1.12-dev/stdlib/Dates/index.html @@ -520,4 +520,4 @@ "2018-08-08T12:00:43.001"
    Dates.ISODateFormatConstant
    Dates.ISODateFormat

    Describes the ISO8601 formatting for a date. This is the default value for Dates.format of a Date.

    Examples

    julia> Dates.format(Date(2018, 8, 8), ISODateFormat)
     "2018-08-08"
    Dates.ISOTimeFormatConstant
    Dates.ISOTimeFormat

    Describes the ISO8601 formatting for a time. This is the default value for Dates.format of a Time.

    Examples

    julia> Dates.format(Time(12, 0, 43, 1), ISOTimeFormat)
     "12:00:43.001"
    Dates.RFC1123FormatConstant
    Dates.RFC1123Format

    Describes the RFC1123 formatting for a date and time.

    Examples

    julia> Dates.format(DateTime(2018, 8, 8, 12, 0, 43, 1), RFC1123Format)
    -"Wed, 08 Aug 2018 12:00:43"
    • 1The notion of the UT second is actually quite fundamental. There are basically two different notions of time generally accepted, one based on the physical rotation of the earth (one full rotation = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different absolute length depending on the day! Anyway, the fact that Date and DateTime are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds and all their complexity can be avoided. This basis of time is formally called UT or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every day has 24 hours and leads to more natural calculations when working with calendar dates.
    +"Wed, 08 Aug 2018 12:00:43"
    • 1The notion of the UT second is actually quite fundamental. There are basically two different notions of time generally accepted, one based on the physical rotation of the earth (one full rotation = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different absolute length depending on the day! Anyway, the fact that Date and DateTime are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds and all their complexity can be avoided. This basis of time is formally called UT or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every day has 24 hours and leads to more natural calculations when working with calendar dates.
    diff --git a/en/v1.12-dev/stdlib/DelimitedFiles/index.html b/en/v1.12-dev/stdlib/DelimitedFiles/index.html index 8cf73f661560..1f8fc349374d 100644 --- a/en/v1.12-dev/stdlib/DelimitedFiles/index.html +++ b/en/v1.12-dev/stdlib/DelimitedFiles/index.html @@ -125,4 +125,4 @@ 3 7 4 8 -julia> rm("delim_file.txt") +julia> rm("delim_file.txt") diff --git a/en/v1.12-dev/stdlib/Distributed/index.html b/en/v1.12-dev/stdlib/Distributed/index.html index 585ce28d18d5..2b315abc4cf7 100644 --- a/en/v1.12-dev/stdlib/Distributed/index.html +++ b/en/v1.12-dev/stdlib/Distributed/index.html @@ -70,7 +70,7 @@ 1 0 3 - 0

    Errors can also be handled by retrying failed computations. Keyword arguments retry_delays and retry_check are passed through to retry as keyword arguments delays and check respectively. If batching is specified, and an entire batch fails, all items in the batch are retried.

    Note that if both on_error and retry_delays are specified, the on_error hook is called before retrying. If on_error does not throw (or rethrow) an exception, the element will not be retried.

    Example: On errors, retry f on an element a maximum of 3 times without any delay between retries.

    pmap(f, c; retry_delays = zeros(3))

    Example: Retry f only if the exception is not of type InexactError, with exponentially increasing delays up to 3 times. Return a NaN in place for all InexactError occurrences.

    pmap(f, c; on_error = e->(isa(e, InexactError) ? NaN : rethrow()), retry_delays = ExponentialBackOff(n = 3))
    Distributed.RemoteExceptionType
    RemoteException(captured)

    Exceptions on remote computations are captured and rethrown locally. A RemoteException wraps the pid of the worker and a captured exception. A CapturedException captures the remote exception and a serializable form of the call stack when the exception was raised.

    Distributed.ProcessExitedExceptionType
    ProcessExitedException(worker_id::Int)

    After a client Julia process has exited, further attempts to reference the dead child will throw this exception.

    Distributed.FutureType
    Future(w::Int, rrid::RRID, v::Union{Some, Nothing}=nothing)

    A Future is a placeholder for a single computation of unknown termination status and time. For multiple potential computations, see RemoteChannel. See remoteref_id for identifying an AbstractRemoteRef.

    Distributed.RemoteChannelType
    RemoteChannel(pid::Integer=myid())

    Make a reference to a Channel{Any}(1) on process pid. The default pid is the current process.

    RemoteChannel(f::Function, pid::Integer=myid())

    Create references to remote channels of a specific size and type. f is a function that when executed on pid must return an implementation of an AbstractChannel.

    For example, RemoteChannel(()->Channel{Int}(10), pid), will return a reference to a channel of type Int and size 10 on pid.

    The default pid is the current process.

    Base.fetchMethod
    fetch(x::Future)

    Wait for and get the value of a Future. The fetched value is cached locally. Further calls to fetch on the same reference return the cached value. If the remote value is an exception, throws a RemoteException which captures the remote exception and backtrace.

    Base.fetchMethod
    fetch(c::RemoteChannel)

    Wait for and get a value from a RemoteChannel. Exceptions raised are the same as for a Future. Does not remove the item fetched.

    fetch(x::Any)

    Return x.

    source
    Distributed.remotecallMethod
    remotecall(f, id::Integer, args...; kwargs...) -> Future

    Call a function f asynchronously on the given arguments on the specified process. Return a Future. Keyword arguments, if any, are passed through to f.

    Distributed.remotecall_waitMethod
    remotecall_wait(f, id::Integer, args...; kwargs...)

    Perform a faster wait(remotecall(...)) in one message on the Worker specified by worker id id. Keyword arguments, if any, are passed through to f.

    See also wait and remotecall.

    Distributed.remotecall_fetchMethod
    remotecall_fetch(f, id::Integer, args...; kwargs...)

    Perform fetch(remotecall(...)) in one message. Keyword arguments, if any, are passed through to f. Any remote exceptions are captured in a RemoteException and thrown.

    See also fetch and remotecall.

    Examples

    $ julia -p 2
    + 0

    Errors can also be handled by retrying failed computations. Keyword arguments retry_delays and retry_check are passed through to retry as keyword arguments delays and check respectively. If batching is specified, and an entire batch fails, all items in the batch are retried.

    Note that if both on_error and retry_delays are specified, the on_error hook is called before retrying. If on_error does not throw (or rethrow) an exception, the element will not be retried.

    Example: On errors, retry f on an element a maximum of 3 times without any delay between retries.

    pmap(f, c; retry_delays = zeros(3))

    Example: Retry f only if the exception is not of type InexactError, with exponentially increasing delays up to 3 times. Return a NaN in place for all InexactError occurrences.

    pmap(f, c; on_error = e->(isa(e, InexactError) ? NaN : rethrow()), retry_delays = ExponentialBackOff(n = 3))
    Distributed.RemoteExceptionType
    RemoteException(captured)

    Exceptions on remote computations are captured and rethrown locally. A RemoteException wraps the pid of the worker and a captured exception. A CapturedException captures the remote exception and a serializable form of the call stack when the exception was raised.

    Distributed.ProcessExitedExceptionType
    ProcessExitedException(worker_id::Int)

    After a client Julia process has exited, further attempts to reference the dead child will throw this exception.

    Distributed.FutureType
    Future(w::Int, rrid::RRID, v::Union{Some, Nothing}=nothing)

    A Future is a placeholder for a single computation of unknown termination status and time. For multiple potential computations, see RemoteChannel. See remoteref_id for identifying an AbstractRemoteRef.

    Distributed.RemoteChannelType
    RemoteChannel(pid::Integer=myid())

    Make a reference to a Channel{Any}(1) on process pid. The default pid is the current process.

    RemoteChannel(f::Function, pid::Integer=myid())

    Create references to remote channels of a specific size and type. f is a function that when executed on pid must return an implementation of an AbstractChannel.

    For example, RemoteChannel(()->Channel{Int}(10), pid), will return a reference to a channel of type Int and size 10 on pid.

    The default pid is the current process.

    Base.fetchMethod
    fetch(x::Future)

    Wait for and get the value of a Future. The fetched value is cached locally. Further calls to fetch on the same reference return the cached value. If the remote value is an exception, throws a RemoteException which captures the remote exception and backtrace.

    Base.fetchMethod
    fetch(c::RemoteChannel)

    Wait for and get a value from a RemoteChannel. Exceptions raised are the same as for a Future. Does not remove the item fetched.

    fetch(x::Any)

    Return x.

    source
    Distributed.remotecallMethod
    remotecall(f, id::Integer, args...; kwargs...) -> Future

    Call a function f asynchronously on the given arguments on the specified process. Return a Future. Keyword arguments, if any, are passed through to f.

    Distributed.remotecall_waitMethod
    remotecall_wait(f, id::Integer, args...; kwargs...)

    Perform a faster wait(remotecall(...)) in one message on the Worker specified by worker id id. Keyword arguments, if any, are passed through to f.

    See also wait and remotecall.

    Distributed.remotecall_fetchMethod
    remotecall_fetch(f, id::Integer, args...; kwargs...)

    Perform fetch(remotecall(...)) in one message. Keyword arguments, if any, are passed through to f. Any remote exceptions are captured in a RemoteException and thrown.

    See also fetch and remotecall.

    Examples

    $ julia -p 2
     
     julia> remotecall_fetch(sqrt, 2, 4)
     2.0
    @@ -168,4 +168,4 @@
     end
    Distributed.@everywhereMacro
    @everywhere [procs()] expr

    Execute an expression under Main on all procs. Errors on any of the processes are collected into a CompositeException and thrown. For example:

    @everywhere bar = 1

    will define Main.bar on all current processes. Any processes added later (say with addprocs()) will not have the expression defined.

    Unlike @spawnat, @everywhere does not capture any local variables. Instead, local variables can be broadcast using interpolation:

    foo = 1
     @everywhere bar = $foo

    The optional argument procs allows specifying a subset of all processes to have execute the expression.

    Similar to calling remotecall_eval(Main, procs, expr), but with two extra features:

    - `using` and `import` statements run on the calling process first, to ensure
       packages are precompiled.
    -- The current source file path used by `include` is propagated to other processes.
    Distributed.remoteref_idFunction
    remoteref_id(r::AbstractRemoteRef) -> RRID

    Futures and RemoteChannels are identified by fields:

    • where - refers to the node where the underlying object/storage referred to by the reference actually exists.

    • whence - refers to the node the remote reference was created from. Note that this is different from the node where the underlying object referred to actually exists. For example calling RemoteChannel(2) from the master process would result in a where value of 2 and a whence value of 1.

    • id is unique across all references created from the worker specified by whence.

    Taken together, whence and id uniquely identify a reference across all workers.

    remoteref_id is a low-level API which returns a RRID object that wraps whence and id values of a remote reference.

    Distributed.channel_from_idFunction
    channel_from_id(id) -> c

    A low-level API which returns the backing AbstractChannel for an id returned by remoteref_id. The call is valid only on the node where the backing channel exists.

    Distributed.worker_id_from_socketFunction
    worker_id_from_socket(s) -> pid

    A low-level API which, given a IO connection or a Worker, returns the pid of the worker it is connected to. This is useful when writing custom serialize methods for a type, which optimizes the data written out depending on the receiving process id.

    Distributed.cluster_cookieMethod
    cluster_cookie(cookie) -> cookie

    Set the passed cookie as the cluster cookie, then returns it.

    Cluster Manager Interface

    This interface provides a mechanism to launch and manage Julia workers on different cluster environments. There are two types of managers present in Base: LocalManager, for launching additional workers on the same host, and SSHManager, for launching on remote hosts via ssh. TCP/IP sockets are used to connect and transport messages between processes. It is possible for Cluster Managers to provide a different transport.

    Distributed.ClusterManagerType
    ClusterManager

    Supertype for cluster managers, which control workers processes as a cluster. Cluster managers implement how workers can be added, removed and communicated with. SSHManager and LocalManager are subtypes of this.

    Distributed.WorkerConfigType
    WorkerConfig

    Type used by ClusterManagers to control workers added to their clusters. Some fields are used by all cluster managers to access a host:

    • io – the connection used to access the worker (a subtype of IO or Nothing)
    • host – the host address (either a String or Nothing)
    • port – the port on the host used to connect to the worker (either an Int or Nothing)

    Some are used by the cluster manager to add workers to an already-initialized host:

    • count – the number of workers to be launched on the host
    • exename – the path to the Julia executable on the host, defaults to "$(Sys.BINDIR)/julia" or "$(Sys.BINDIR)/julia-debug"
    • exeflags – flags to use when launching Julia remotely

    The userdata field is used to store information for each worker by external managers.

    Some fields are used by SSHManager and similar managers:

    • tunneltrue (use tunneling), false (do not use tunneling), or nothing (use default for the manager)
    • multiplextrue (use SSH multiplexing for tunneling) or false
    • forward – the forwarding option used for -L option of ssh
    • bind_addr – the address on the remote host to bind to
    • sshflags – flags to use in establishing the SSH connection
    • max_parallel – the maximum number of workers to connect to in parallel on the host

    Some fields are used by both LocalManagers and SSHManagers:

    • connect_at – determines whether this is a worker-to-worker or driver-to-worker setup call
    • process – the process which will be connected (usually the manager will assign this during addprocs)
    • ospid – the process ID according to the host OS, used to interrupt worker processes
    • environ – private dictionary used to store temporary information by Local/SSH managers
    • ident – worker as identified by the ClusterManager
    • connect_idents – list of worker ids the worker must connect to if using a custom topology
    • enable_threaded_blastrue, false, or nothing, whether to use threaded BLAS or not on the workers
    Distributed.launchFunction
    launch(manager::ClusterManager, params::Dict, launched::Array, launch_ntfy::Condition)

    Implemented by cluster managers. For every Julia worker launched by this function, it should append a WorkerConfig entry to launched and notify launch_ntfy. The function MUST exit once all workers, requested by manager have been launched. params is a dictionary of all keyword arguments addprocs was called with.

    Distributed.manageFunction
    manage(manager::ClusterManager, id::Integer, config::WorkerConfig. op::Symbol)

    Implemented by cluster managers. It is called on the master process, during a worker's lifetime, with appropriate op values:

    • with :register/:deregister when a worker is added / removed from the Julia worker pool.
    • with :interrupt when interrupt(workers) is called. The ClusterManager should signal the appropriate worker with an interrupt signal.
    • with :finalize for cleanup purposes.
    Base.killMethod
    kill(manager::ClusterManager, pid::Int, config::WorkerConfig)

    Implemented by cluster managers. It is called on the master process, by rmprocs. It should cause the remote worker specified by pid to exit. kill(manager::ClusterManager.....) executes a remote exit() on pid.

    Sockets.connectMethod
    connect(manager::ClusterManager, pid::Int, config::WorkerConfig) -> (instrm::IO, outstrm::IO)

    Implemented by cluster managers using custom transports. It should establish a logical connection to worker with id pid, specified by config and return a pair of IO objects. Messages from pid to current process will be read off instrm, while messages to be sent to pid will be written to outstrm. The custom transport implementation must ensure that messages are delivered and received completely and in order. connect(manager::ClusterManager.....) sets up TCP/IP socket connections in-between workers.

    Distributed.init_workerFunction
    init_worker(cookie::AbstractString, manager::ClusterManager=DefaultClusterManager())

    Called by cluster managers implementing custom transports. It initializes a newly launched process as a worker. Command line argument --worker[=<cookie>] has the effect of initializing a process as a worker using TCP/IP sockets for transport. cookie is a cluster_cookie.

    Distributed.start_workerFunction
    start_worker([out::IO=stdout], cookie::AbstractString=readline(stdin); close_stdin::Bool=true, stderr_to_stdout::Bool=true)

    start_worker is an internal function which is the default entry point for worker processes connecting via TCP/IP. It sets up the process as a Julia cluster worker.

    host:port information is written to stream out (defaults to stdout).

    The function reads the cookie from stdin if required, and listens on a free port (or if specified, the port in the --bind-to command line option) and schedules tasks to process incoming TCP connections and requests. It also (optionally) closes stdin and redirects stderr to stdout.

    It does not return.

    Distributed.process_messagesFunction
    process_messages(r_stream::IO, w_stream::IO, incoming::Bool=true)

    Called by cluster managers using custom transports. It should be called when the custom transport implementation receives the first message from a remote worker. The custom transport must manage a logical connection to the remote worker and provide two IO objects, one for incoming messages and the other for messages addressed to the remote worker. If incoming is true, the remote peer initiated the connection. Whichever of the pair initiates the connection sends the cluster cookie and its Julia version number to perform the authentication handshake.

    See also cluster_cookie.

    Distributed.default_addprocs_paramsFunction
    default_addprocs_params(mgr::ClusterManager) -> Dict{Symbol, Any}

    Implemented by cluster managers. The default keyword parameters passed when calling addprocs(mgr). The minimal set of options is available by calling default_addprocs_params()

    +- The current source file path used by `include` is propagated to other processes.
    Distributed.remoteref_idFunction
    remoteref_id(r::AbstractRemoteRef) -> RRID

    Futures and RemoteChannels are identified by fields:

    • where - refers to the node where the underlying object/storage referred to by the reference actually exists.

    • whence - refers to the node the remote reference was created from. Note that this is different from the node where the underlying object referred to actually exists. For example calling RemoteChannel(2) from the master process would result in a where value of 2 and a whence value of 1.

    • id is unique across all references created from the worker specified by whence.

    Taken together, whence and id uniquely identify a reference across all workers.

    remoteref_id is a low-level API which returns a RRID object that wraps whence and id values of a remote reference.

    Distributed.channel_from_idFunction
    channel_from_id(id) -> c

    A low-level API which returns the backing AbstractChannel for an id returned by remoteref_id. The call is valid only on the node where the backing channel exists.

    Distributed.worker_id_from_socketFunction
    worker_id_from_socket(s) -> pid

    A low-level API which, given a IO connection or a Worker, returns the pid of the worker it is connected to. This is useful when writing custom serialize methods for a type, which optimizes the data written out depending on the receiving process id.

    Distributed.cluster_cookieMethod
    cluster_cookie(cookie) -> cookie

    Set the passed cookie as the cluster cookie, then returns it.

    Cluster Manager Interface

    This interface provides a mechanism to launch and manage Julia workers on different cluster environments. There are two types of managers present in Base: LocalManager, for launching additional workers on the same host, and SSHManager, for launching on remote hosts via ssh. TCP/IP sockets are used to connect and transport messages between processes. It is possible for Cluster Managers to provide a different transport.

    Distributed.ClusterManagerType
    ClusterManager

    Supertype for cluster managers, which control workers processes as a cluster. Cluster managers implement how workers can be added, removed and communicated with. SSHManager and LocalManager are subtypes of this.

    Distributed.WorkerConfigType
    WorkerConfig

    Type used by ClusterManagers to control workers added to their clusters. Some fields are used by all cluster managers to access a host:

    • io – the connection used to access the worker (a subtype of IO or Nothing)
    • host – the host address (either a String or Nothing)
    • port – the port on the host used to connect to the worker (either an Int or Nothing)

    Some are used by the cluster manager to add workers to an already-initialized host:

    • count – the number of workers to be launched on the host
    • exename – the path to the Julia executable on the host, defaults to "$(Sys.BINDIR)/julia" or "$(Sys.BINDIR)/julia-debug"
    • exeflags – flags to use when launching Julia remotely

    The userdata field is used to store information for each worker by external managers.

    Some fields are used by SSHManager and similar managers:

    • tunneltrue (use tunneling), false (do not use tunneling), or nothing (use default for the manager)
    • multiplextrue (use SSH multiplexing for tunneling) or false
    • forward – the forwarding option used for -L option of ssh
    • bind_addr – the address on the remote host to bind to
    • sshflags – flags to use in establishing the SSH connection
    • max_parallel – the maximum number of workers to connect to in parallel on the host

    Some fields are used by both LocalManagers and SSHManagers:

    • connect_at – determines whether this is a worker-to-worker or driver-to-worker setup call
    • process – the process which will be connected (usually the manager will assign this during addprocs)
    • ospid – the process ID according to the host OS, used to interrupt worker processes
    • environ – private dictionary used to store temporary information by Local/SSH managers
    • ident – worker as identified by the ClusterManager
    • connect_idents – list of worker ids the worker must connect to if using a custom topology
    • enable_threaded_blastrue, false, or nothing, whether to use threaded BLAS or not on the workers
    Distributed.launchFunction
    launch(manager::ClusterManager, params::Dict, launched::Array, launch_ntfy::Condition)

    Implemented by cluster managers. For every Julia worker launched by this function, it should append a WorkerConfig entry to launched and notify launch_ntfy. The function MUST exit once all workers, requested by manager have been launched. params is a dictionary of all keyword arguments addprocs was called with.

    Distributed.manageFunction
    manage(manager::ClusterManager, id::Integer, config::WorkerConfig. op::Symbol)

    Implemented by cluster managers. It is called on the master process, during a worker's lifetime, with appropriate op values:

    • with :register/:deregister when a worker is added / removed from the Julia worker pool.
    • with :interrupt when interrupt(workers) is called. The ClusterManager should signal the appropriate worker with an interrupt signal.
    • with :finalize for cleanup purposes.
    Base.killMethod
    kill(manager::ClusterManager, pid::Int, config::WorkerConfig)

    Implemented by cluster managers. It is called on the master process, by rmprocs. It should cause the remote worker specified by pid to exit. kill(manager::ClusterManager.....) executes a remote exit() on pid.

    Sockets.connectMethod
    connect(manager::ClusterManager, pid::Int, config::WorkerConfig) -> (instrm::IO, outstrm::IO)

    Implemented by cluster managers using custom transports. It should establish a logical connection to worker with id pid, specified by config and return a pair of IO objects. Messages from pid to current process will be read off instrm, while messages to be sent to pid will be written to outstrm. The custom transport implementation must ensure that messages are delivered and received completely and in order. connect(manager::ClusterManager.....) sets up TCP/IP socket connections in-between workers.

    Distributed.init_workerFunction
    init_worker(cookie::AbstractString, manager::ClusterManager=DefaultClusterManager())

    Called by cluster managers implementing custom transports. It initializes a newly launched process as a worker. Command line argument --worker[=<cookie>] has the effect of initializing a process as a worker using TCP/IP sockets for transport. cookie is a cluster_cookie.

    Distributed.start_workerFunction
    start_worker([out::IO=stdout], cookie::AbstractString=readline(stdin); close_stdin::Bool=true, stderr_to_stdout::Bool=true)

    start_worker is an internal function which is the default entry point for worker processes connecting via TCP/IP. It sets up the process as a Julia cluster worker.

    host:port information is written to stream out (defaults to stdout).

    The function reads the cookie from stdin if required, and listens on a free port (or if specified, the port in the --bind-to command line option) and schedules tasks to process incoming TCP connections and requests. It also (optionally) closes stdin and redirects stderr to stdout.

    It does not return.

    Distributed.process_messagesFunction
    process_messages(r_stream::IO, w_stream::IO, incoming::Bool=true)

    Called by cluster managers using custom transports. It should be called when the custom transport implementation receives the first message from a remote worker. The custom transport must manage a logical connection to the remote worker and provide two IO objects, one for incoming messages and the other for messages addressed to the remote worker. If incoming is true, the remote peer initiated the connection. Whichever of the pair initiates the connection sends the cluster cookie and its Julia version number to perform the authentication handshake.

    See also cluster_cookie.

    Distributed.default_addprocs_paramsFunction
    default_addprocs_params(mgr::ClusterManager) -> Dict{Symbol, Any}

    Implemented by cluster managers. The default keyword parameters passed when calling addprocs(mgr). The minimal set of options is available by calling default_addprocs_params()

    diff --git a/en/v1.12-dev/stdlib/Downloads/index.html b/en/v1.12-dev/stdlib/Downloads/index.html index e055dffe11d9..8181a8606b50 100644 --- a/en/v1.12-dev/stdlib/Downloads/index.html +++ b/en/v1.12-dev/stdlib/Downloads/index.html @@ -58,4 +58,4 @@ code :: Int message :: String response :: Response -end

    RequestError is a type capturing the properties of a failed response to a request as an exception object:

    • url: the original URL that was requested without any redirects
    • code: the libcurl error code; 0 if a protocol-only error occurred
    • message: the libcurl error message indicating what went wrong
    • response: response object capturing what response info is available

    The same RequestError type is thrown by download if the request was successful but there was a protocol-level error indicated by a status code that is not in the 2xx range, in which case code will be zero and the message field will be the empty string. The request API only throws a RequestError if the libcurl error code is non-zero, in which case the included response object is likely to have a status of zero and an empty message. There are, however, situations where a curl-level error is thrown due to a protocol error, in which case both the inner and outer code and message may be of interest.

    Downloads.DownloaderType
    Downloader(; [ grace::Real = 30 ])

    Downloader objects are used to perform individual download operations. Connections, name lookups and other resources are shared within a Downloader. These connections and resources are cleaned up after a configurable grace period (default: 30 seconds) since anything was downloaded with it, or when it is garbage collected, whichever comes first. If the grace period is set to zero, all resources will be cleaned up immediately as soon as there are no more ongoing downloads in progress. If the grace period is set to Inf then resources are not cleaned up until Downloader is garbage collected.

    +end

    RequestError is a type capturing the properties of a failed response to a request as an exception object:

    • url: the original URL that was requested without any redirects
    • code: the libcurl error code; 0 if a protocol-only error occurred
    • message: the libcurl error message indicating what went wrong
    • response: response object capturing what response info is available

    The same RequestError type is thrown by download if the request was successful but there was a protocol-level error indicated by a status code that is not in the 2xx range, in which case code will be zero and the message field will be the empty string. The request API only throws a RequestError if the libcurl error code is non-zero, in which case the included response object is likely to have a status of zero and an empty message. There are, however, situations where a curl-level error is thrown due to a protocol error, in which case both the inner and outer code and message may be of interest.

    Downloads.DownloaderType
    Downloader(; [ grace::Real = 30 ])

    Downloader objects are used to perform individual download operations. Connections, name lookups and other resources are shared within a Downloader. These connections and resources are cleaned up after a configurable grace period (default: 30 seconds) since anything was downloaded with it, or when it is garbage collected, whichever comes first. If the grace period is set to zero, all resources will be cleaned up immediately as soon as there are no more ongoing downloads in progress. If the grace period is set to Inf then resources are not cleaned up until Downloader is garbage collected.

    diff --git a/en/v1.12-dev/stdlib/FileWatching/index.html b/en/v1.12-dev/stdlib/FileWatching/index.html index 67aee449c95f..5a4d5d050a3d 100644 --- a/en/v1.12-dev/stdlib/FileWatching/index.html +++ b/en/v1.12-dev/stdlib/FileWatching/index.html @@ -5,4 +5,4 @@ gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash});

    File Events

    FileWatching.poll_fdFunction
    poll_fd(fd, timeout_s::Real=-1; readable=false, writable=false)

    Monitor a file descriptor fd for changes in the read or write availability, and with a timeout given by timeout_s seconds.

    The keyword arguments determine which of read and/or write status should be monitored; at least one of them must be set to true.

    The returned value is an object with boolean fields readable, writable, and timedout, giving the result of the polling.

    FileWatching.poll_fileFunction
    poll_file(path::AbstractString, interval_s::Real=5.007, timeout_s::Real=-1) -> (previous::StatStruct, current)

    Monitor a file for changes by polling every interval_s seconds until a change occurs or timeout_s seconds have elapsed. The interval_s should be a long period; the default is 5.007 seconds.

    Returns a pair of status objects (previous, current) when a change is detected. The previous status is always a StatStruct, but it may have all of the fields zeroed (indicating the file didn't previously exist, or wasn't previously accessible).

    The current status object may be a StatStruct, an EOFError (indicating the timeout elapsed), or some other Exception subtype (if the stat operation failed - for example, if the path does not exist).

    To determine when a file was modified, compare current isa StatStruct && mtime(prev) != mtime(current) to detect notification of changes. However, using watch_file for this operation is preferred, since it is more reliable and efficient, although in some situations it may not be available.

    FileWatching.watch_fileFunction
    watch_file(path::AbstractString, timeout_s::Real=-1)

    Watch file or directory path for changes until a change occurs or timeout_s seconds have elapsed. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.

    The returned value is an object with boolean fields renamed, changed, and timedout, giving the result of watching the file.

    This behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.

    FileWatching.watch_folderFunction
    watch_folder(path::AbstractString, timeout_s::Real=-1)

    Watches a file or directory path for changes until a change has occurred or timeout_s seconds have elapsed. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.

    This will continuing tracking changes for path in the background until unwatch_folder is called on the same path.

    The returned value is an pair where the first field is the name of the changed file (if available) and the second field is an object with boolean fields renamed, changed, and timedout, giving the event.

    This behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.

    FileWatching.unwatch_folderFunction
    unwatch_folder(path::AbstractString)

    Stop background tracking of changes for path. It is not recommended to do this while another task is waiting for watch_folder to return on the same path, as the result may be unpredictable.

    Pidfile

    A simple utility tool for creating advisory pidfiles (lock files).

    Primary Functions

    FileWatching.Pidfile.mkpidlockFunction
    mkpidlock([f::Function], at::String, [pid::Cint]; kwopts...)
     mkpidlock(at::String, proc::Process; kwopts...)

    Create a pidfile lock for the path "at" for the current process or the process identified by pid or proc. Can take a function to execute once locked, for usage in do blocks, after which the lock will be automatically closed. If the lock fails and wait is false, then an error is thrown.

    The lock will be released by either close, a finalizer, or shortly after proc exits. Make sure the return value is live through the end of the critical section of your program, so the finalizer does not reclaim it early.

    Optional keyword arguments:

    • mode: file access mode (modified by the process umask). Defaults to world-readable.
    • poll_interval: Specify the maximum time to between attempts (if watch_file doesn't work)
    • stale_age: Delete an existing pidfile (ignoring the lock) if it is older than this many seconds, based on its mtime. The file won't be deleted until 5x longer than this if the pid in the file appears that it may be valid. Or 25x longer if refresh is overridden to 0 to disable lock refreshing. By default this is disabled (stale_age = 0), but a typical recommended value would be about 3-5x an estimated normal completion time.
    • refresh: Keeps a lock from becoming stale by updating the mtime every interval of time that passes. By default, this is set to stale_age/2, which is the recommended value.
    • wait: If true, block until we get the lock, if false, raise error if lock fails.
    FileWatching.Pidfile.trymkpidlockFunction
    trymkpidlock([f::Function], at::String, [pid::Cint]; kwopts...)
    -trymkpidlock(at::String, proc::Process; kwopts...)

    Like mkpidlock except returns false instead of waiting if the file is already locked.

    Julia 1.10

    This function requires at least Julia 1.10.

    Base.closeMethod
    close(lock::LockMonitor)

    Release a pidfile lock.

    Helper Functions

    FileWatching.Pidfile.open_exclusiveFunction
    open_exclusive(path::String; mode, poll_interval, wait, stale_age, refresh) :: File

    Create a new a file for read-write advisory-exclusive access. If wait is false then error out if the lock files exist otherwise block until we get the lock.

    For a description of the keyword arguments, see mkpidlock.

    FileWatching.Pidfile.tryopen_exclusiveFunction
    tryopen_exclusive(path::String, mode::Integer = 0o444) :: Union{Void, File}

    Try to create a new file for read-write advisory-exclusive access, return nothing if it already exists.

    FileWatching.Pidfile.parse_pidfileFunction
    parse_pidfile(file::Union{IO, String}) => (pid, hostname, age)

    Attempt to parse our pidfile format, replaced an element with (0, "", 0.0), respectively, for any read that failed.

    FileWatching.Pidfile.stale_pidfileFunction
    stale_pidfile(path::String, stale_age::Real, refresh::Real) :: Bool

    Helper function for open_exclusive for deciding if a pidfile is stale.

    FileWatching.Pidfile.isvalidpidFunction
    isvalidpid(hostname::String, pid::Cuint) :: Bool

    Attempt to conservatively estimate whether pid is a valid process id.

    Base.Filesystem.touchMethod
    Base.touch(::Pidfile.LockMonitor)

    Update the mtime on the lock, to indicate it is still fresh.

    See also the refresh keyword in the mkpidlock constructor.

    +trymkpidlock(at::String, proc::Process; kwopts...)

    Like mkpidlock except returns false instead of waiting if the file is already locked.

    Julia 1.10

    This function requires at least Julia 1.10.

    Base.closeMethod
    close(lock::LockMonitor)

    Release a pidfile lock.

    Helper Functions

    FileWatching.Pidfile.open_exclusiveFunction
    open_exclusive(path::String; mode, poll_interval, wait, stale_age, refresh) :: File

    Create a new a file for read-write advisory-exclusive access. If wait is false then error out if the lock files exist otherwise block until we get the lock.

    For a description of the keyword arguments, see mkpidlock.

    FileWatching.Pidfile.tryopen_exclusiveFunction
    tryopen_exclusive(path::String, mode::Integer = 0o444) :: Union{Void, File}

    Try to create a new file for read-write advisory-exclusive access, return nothing if it already exists.

    FileWatching.Pidfile.parse_pidfileFunction
    parse_pidfile(file::Union{IO, String}) => (pid, hostname, age)

    Attempt to parse our pidfile format, replaced an element with (0, "", 0.0), respectively, for any read that failed.

    FileWatching.Pidfile.stale_pidfileFunction
    stale_pidfile(path::String, stale_age::Real, refresh::Real) :: Bool

    Helper function for open_exclusive for deciding if a pidfile is stale.

    FileWatching.Pidfile.isvalidpidFunction
    isvalidpid(hostname::String, pid::Cuint) :: Bool

    Attempt to conservatively estimate whether pid is a valid process id.

    Base.Filesystem.touchMethod
    Base.touch(::Pidfile.LockMonitor)

    Update the mtime on the lock, to indicate it is still fresh.

    See also the refresh keyword in the mkpidlock constructor.

    diff --git a/en/v1.12-dev/stdlib/Future/index.html b/en/v1.12-dev/stdlib/Future/index.html index 52bd2e500551..282d05afd32f 100644 --- a/en/v1.12-dev/stdlib/Future/index.html +++ b/en/v1.12-dev/stdlib/Future/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Future

    The Future module implements future behavior of already existing functions, which will replace the current version in a future release of Julia.

    Future.copy!Function
    Future.copy!(dst, src) -> dst

    Copy src into dst.

    Julia 1.1

    This function has moved to Base with Julia 1.1, consider using copy!(dst, src) instead. Future.copy! will be deprecated in the future.

    Future.randjumpFunction
    randjump(r::MersenneTwister, steps::Integer) -> MersenneTwister

    Create an initialized MersenneTwister object, whose state is moved forward (without generating numbers) from r by steps steps. One such step corresponds to the generation of two Float64 numbers. For each different value of steps, a large polynomial has to be generated internally. One is already pre-computed for steps=big(10)^20.

    +

    Future

    The Future module implements future behavior of already existing functions, which will replace the current version in a future release of Julia.

    Future.copy!Function
    Future.copy!(dst, src) -> dst

    Copy src into dst.

    Julia 1.1

    This function has moved to Base with Julia 1.1, consider using copy!(dst, src) instead. Future.copy! will be deprecated in the future.

    Future.randjumpFunction
    randjump(r::MersenneTwister, steps::Integer) -> MersenneTwister

    Create an initialized MersenneTwister object, whose state is moved forward (without generating numbers) from r by steps steps. One such step corresponds to the generation of two Float64 numbers. For each different value of steps, a large polynomial has to be generated internally. One is already pre-computed for steps=big(10)^20.

    diff --git a/en/v1.12-dev/stdlib/InteractiveUtils/index.html b/en/v1.12-dev/stdlib/InteractiveUtils/index.html index f1b5ec6f7112..d698b9a43648 100644 --- a/en/v1.12-dev/stdlib/InteractiveUtils/index.html +++ b/en/v1.12-dev/stdlib/InteractiveUtils/index.html @@ -3,7 +3,7 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Interactive Utilities

    The InteractiveUtils module provides utilities for interactive use of Julia, such as code introspection and clipboard access. It is intended for interactive work and is loaded automatically in interactive mode.

    Base.Docs.aproposFunction
    apropos([io::IO=stdout], pattern::Union{AbstractString,Regex})

    Search available docstrings for entries containing pattern.

    When pattern is a string, case is ignored. Results are printed to io.

    apropos can be called from the help mode in the REPL by wrapping the query in double quotes:

    help?> "pattern"
    source
    InteractiveUtils.varinfoFunction
    varinfo(m::Module=Main, pattern::Regex=r""; all=false, imported=false, recursive=false, sortby::Symbol=:name, minsize::Int=0)

    Return a markdown table giving information about public global variables in a module, optionally restricted to those matching pattern.

    The memory consumption estimate is an approximate lower bound on the size of the internal structure of the object.

    • all : also list non-public objects defined in the module, deprecated objects, and compiler-generated objects.
    • imported : also list objects explicitly imported from other modules.
    • recursive : recursively include objects in sub-modules, observing the same settings in each.
    • sortby : the column to sort results by. Options are :name (default), :size, and :summary.
    • minsize : only includes objects with size at least minsize bytes. Defaults to 0.

    The output of varinfo is intended for display purposes only. See also names to get an array of symbols defined in a module, which is suitable for more general manipulations.

    InteractiveUtils.versioninfoFunction
    versioninfo(io::IO=stdout; verbose::Bool=false)

    Print information about the version of Julia in use. The output is controlled with boolean keyword arguments:

    • verbose: print all additional information
    Warning

    The output of this function may contain sensitive information. Before sharing the output, please review the output and remove any data that should not be shared publicly.

    See also: VERSION.

    InteractiveUtils.methodswithFunction
    methodswith(typ[, module or function]; supertypes::Bool=false])

    Return an array of methods with an argument of type typ.

    The optional second argument restricts the search to a particular module or function (the default is all top-level modules).

    If keyword supertypes is true, also return arguments with a parent type of typ, excluding type Any.

    See also: methods.

    InteractiveUtils.subtypesFunction
    subtypes(T::DataType)

    Return a list of immediate subtypes of DataType T. Note that all currently loaded subtypes are included, including those not visible in the current module.

    See also supertype, supertypes, methodswith.

    Examples

    julia> subtypes(Integer)
    +

    Interactive Utilities

    The InteractiveUtils module provides utilities for interactive use of Julia, such as code introspection and clipboard access. It is intended for interactive work and is loaded automatically in interactive mode.

    Base.Docs.aproposFunction
    apropos([io::IO=stdout], pattern::Union{AbstractString,Regex})

    Search available docstrings for entries containing pattern.

    When pattern is a string, case is ignored. Results are printed to io.

    apropos can be called from the help mode in the REPL by wrapping the query in double quotes:

    help?> "pattern"
    source
    InteractiveUtils.varinfoFunction
    varinfo(m::Module=Main, pattern::Regex=r""; all=false, imported=false, recursive=false, sortby::Symbol=:name, minsize::Int=0)

    Return a markdown table giving information about public global variables in a module, optionally restricted to those matching pattern.

    The memory consumption estimate is an approximate lower bound on the size of the internal structure of the object.

    • all : also list non-public objects defined in the module, deprecated objects, and compiler-generated objects.
    • imported : also list objects explicitly imported from other modules.
    • recursive : recursively include objects in sub-modules, observing the same settings in each.
    • sortby : the column to sort results by. Options are :name (default), :size, and :summary.
    • minsize : only includes objects with size at least minsize bytes. Defaults to 0.

    The output of varinfo is intended for display purposes only. See also names to get an array of symbols defined in a module, which is suitable for more general manipulations.

    InteractiveUtils.versioninfoFunction
    versioninfo(io::IO=stdout; verbose::Bool=false)

    Print information about the version of Julia in use. The output is controlled with boolean keyword arguments:

    • verbose: print all additional information
    Warning

    The output of this function may contain sensitive information. Before sharing the output, please review the output and remove any data that should not be shared publicly.

    See also: VERSION.

    InteractiveUtils.methodswithFunction
    methodswith(typ[, module or function]; supertypes::Bool=false])

    Return an array of methods with an argument of type typ.

    The optional second argument restricts the search to a particular module or function (the default is all top-level modules).

    If keyword supertypes is true, also return arguments with a parent type of typ, excluding type Any.

    See also: methods.

    InteractiveUtils.subtypesFunction
    subtypes(T::DataType)

    Return a list of immediate subtypes of DataType T. Note that all currently loaded subtypes are included, including those not visible in the current module.

    See also supertype, supertypes, methodswith.

    Examples

    julia> subtypes(Integer)
     3-element Vector{Any}:
      Bool
      Signed
    @@ -29,4 +29,4 @@
           1.8 ms  CodecZlib
           0.8 ms  Compat
          13.1 ms  FilePathsBase 28.39% compilation time
    -   1681.2 ms  CSV 92.40% compilation time
    Julia 1.8

    This macro requires at least Julia 1.8

    InteractiveUtils.clipboardFunction
    clipboard(x)

    Send a printed form of x to the operating system clipboard ("copy").

    clipboard() -> String

    Return a string with the contents of the operating system clipboard ("paste").

    + 1681.2 ms CSV 92.40% compilation time
    Julia 1.8

    This macro requires at least Julia 1.8

    InteractiveUtils.clipboardFunction
    clipboard(x)

    Send a printed form of x to the operating system clipboard ("copy").

    clipboard() -> String

    Return a string with the contents of the operating system clipboard ("paste").

    diff --git a/en/v1.12-dev/stdlib/JuliaSyntaxHighlighting/index.html b/en/v1.12-dev/stdlib/JuliaSyntaxHighlighting/index.html index aa67b7e118e4..8505785676c8 100644 --- a/en/v1.12-dev/stdlib/JuliaSyntaxHighlighting/index.html +++ b/en/v1.12-dev/stdlib/JuliaSyntaxHighlighting/index.html @@ -26,4 +26,4 @@ (5:5, :face => :julia_number) (6:6, :face => :julia_operator) (7:7, :face => :julia_number) - (8:8, :face => :julia_rainbow_paren_1) + (8:8, :face => :julia_rainbow_paren_1) diff --git a/en/v1.12-dev/stdlib/LazyArtifacts/index.html b/en/v1.12-dev/stdlib/LazyArtifacts/index.html index 030973c74c69..69181da69ea1 100644 --- a/en/v1.12-dev/stdlib/LazyArtifacts/index.html +++ b/en/v1.12-dev/stdlib/LazyArtifacts/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Lazy Artifacts

    In order for a package to download artifacts lazily, LazyArtifacts must be explicitly listed as a dependency of that package.

    For further information on artifacts, see Artifacts.

    +

    Lazy Artifacts

    In order for a package to download artifacts lazily, LazyArtifacts must be explicitly listed as a dependency of that package.

    For further information on artifacts, see Artifacts.

    diff --git a/en/v1.12-dev/stdlib/LibCURL/index.html b/en/v1.12-dev/stdlib/LibCURL/index.html index 1a10c3172c61..04983c5b0195 100644 --- a/en/v1.12-dev/stdlib/LibCURL/index.html +++ b/en/v1.12-dev/stdlib/LibCURL/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -
    +
    diff --git a/en/v1.12-dev/stdlib/LibGit2/index.html b/en/v1.12-dev/stdlib/LibGit2/index.html index 04f593b64b8f..73d94c4625d8 100644 --- a/en/v1.12-dev/stdlib/LibGit2/index.html +++ b/en/v1.12-dev/stdlib/LibGit2/index.html @@ -23,7 +23,7 @@ GitTree(repo::GitRepo, spec::AbstractString)

    Return a GitTree object from repo specified by hash/spec.

    • hash is a full (GitHash) or partial (GitShortHash) hash.
    • spec is a textual specification: see the git docs for a full list.
    LibGit2.BlameOptionsType
    LibGit2.BlameOptions

    Matches the git_blame_options struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • flags: one of Consts.BLAME_NORMAL or Consts.BLAME_FIRST_PARENT (the other blame flags are not yet implemented by libgit2).
    • min_match_characters: the minimum number of alphanumeric characters which much change in a commit in order for the change to be associated with that commit. The default is 20. Only takes effect if one of the Consts.BLAME_*_COPIES flags are used, which libgit2 does not implement yet.
    • newest_commit: the GitHash of the newest commit from which to look at changes.
    • oldest_commit: the GitHash of the oldest commit from which to look at changes.
    • min_line: the first line of the file from which to starting blaming. The default is 1.
    • max_line: the last line of the file to which to blame. The default is 0, meaning the last line of the file.
    LibGit2.MergeOptionsType
    LibGit2.MergeOptions

    Matches the git_merge_options struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • flags: an enum for flags describing merge behavior. Defined in git_merge_flag_t. The corresponding Julia enum is GIT_MERGE and has values:
      • MERGE_FIND_RENAMES: detect if a file has been renamed between the common ancestor and the "ours" or "theirs" side of the merge. Allows merges where a file has been renamed.
      • MERGE_FAIL_ON_CONFLICT: exit immediately if a conflict is found rather than trying to resolve it.
      • MERGE_SKIP_REUC: do not write the REUC extension on the index resulting from the merge.
      • MERGE_NO_RECURSIVE: if the commits being merged have multiple merge bases, use the first one, rather than trying to recursively merge the bases.
    • rename_threshold: how similar two files must to consider one a rename of the other. This is an integer that sets the percentage similarity. The default is 50.
    • target_limit: the maximum number of files to compare with to look for renames. The default is 200.
    • metric: optional custom function to use to determine the similarity between two files for rename detection.
    • recursion_limit: the upper limit on the number of merges of common ancestors to perform to try to build a new virtual merge base for the merge. The default is no limit. This field is only present on libgit2 versions newer than 0.24.0.
    • default_driver: the merge driver to use if both sides have changed. This field is only present on libgit2 versions newer than 0.25.0.
    • file_favor: how to handle conflicting file contents for the text driver.
      • MERGE_FILE_FAVOR_NORMAL: if both sides of the merge have changes to a section, make a note of the conflict in the index which git checkout will use to create a merge file, which the user can then reference to resolve the conflicts. This is the default.
      • MERGE_FILE_FAVOR_OURS: if both sides of the merge have changes to a section, use the version in the "ours" side of the merge in the index.
      • MERGE_FILE_FAVOR_THEIRS: if both sides of the merge have changes to a section, use the version in the "theirs" side of the merge in the index.
      • MERGE_FILE_FAVOR_UNION: if both sides of the merge have changes to a section, include each unique line from both sides in the file which is put into the index.
    • file_flags: guidelines for merging files.
    LibGit2.ProxyOptionsType
    LibGit2.ProxyOptions

    Options for connecting through a proxy.

    Matches the git_proxy_options struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • proxytype: an enum for the type of proxy to use. Defined in git_proxy_t. The corresponding Julia enum is GIT_PROXY and has values:
      • PROXY_NONE: do not attempt the connection through a proxy.
      • PROXY_AUTO: attempt to figure out the proxy configuration from the git configuration.
      • PROXY_SPECIFIED: connect using the URL given in the url field of this struct.
      Default is to auto-detect the proxy type.
    • url: the URL of the proxy.
    • credential_cb: a pointer to a callback function which will be called if the remote requires authentication to connect.
    • certificate_cb: a pointer to a callback function which will be called if certificate verification fails. This lets the user decide whether or not to keep connecting. If the function returns 1, connecting will be allowed. If it returns 0, the connection will not be allowed. A negative value can be used to return errors.
    • payload: the payload to be provided to the two callback functions.

    Examples

    julia> fo = LibGit2.FetchOptions(
                proxy_opts = LibGit2.ProxyOptions(url = Cstring("https://my_proxy_url.com")))
     
    -julia> fetch(remote, "master", options=fo)
    LibGit2.PushOptionsType
    LibGit2.PushOptions

    Matches the git_push_options struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • parallelism: if a pack file must be created, this variable sets the number of worker threads which will be spawned by the packbuilder. If 0, the packbuilder will auto-set the number of threads to use. The default is 1.
    • callbacks: the callbacks (e.g. for authentication with the remote) to use for the push.
    • proxy_opts: only relevant if the LibGit2 version is greater than or equal to 0.25.0. Sets options for using a proxy to communicate with a remote. See ProxyOptions for more information.
    • custom_headers: only relevant if the LibGit2 version is greater than or equal to 0.24.0. Extra headers needed for the push operation.
    LibGit2.RebaseOperationType
    LibGit2.RebaseOperation

    Describes a single instruction/operation to be performed during the rebase. Matches the git_rebase_operation struct.

    The fields represent:

    • optype: the type of rebase operation currently being performed. The options are:
      • REBASE_OPERATION_PICK: cherry-pick the commit in question.
      • REBASE_OPERATION_REWORD: cherry-pick the commit in question, but rewrite its message using the prompt.
      • REBASE_OPERATION_EDIT: cherry-pick the commit in question, but allow the user to edit the commit's contents and its message.
      • REBASE_OPERATION_SQUASH: squash the commit in question into the previous commit. The commit messages of the two commits will be merged.
      • REBASE_OPERATION_FIXUP: squash the commit in question into the previous commit. Only the commit message of the previous commit will be used.
      • REBASE_OPERATION_EXEC: do not cherry-pick a commit. Run a command and continue if the command exits successfully.
    • id: the GitHash of the commit being worked on during this rebase step.
    • exec: in case REBASE_OPERATION_EXEC is used, the command to run during this step (for instance, running the test suite after each commit).
    LibGit2.RebaseOptionsType
    LibGit2.RebaseOptions

    Matches the git_rebase_options struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • quiet: inform other git clients helping with/working on the rebase that the rebase should be done "quietly". Used for interoperability. The default is 1.
    • inmemory: start an in-memory rebase. Callers working on the rebase can go through its steps and commit any changes, but cannot rewind HEAD or update the repository. The workdir will not be modified. Only present on libgit2 versions newer than or equal to 0.24.0.
    • rewrite_notes_ref: name of the reference to notes to use to rewrite the commit notes as the rebase is finished.
    • merge_opts: merge options controlling how the trees will be merged at each rebase step. Only present on libgit2 versions newer than or equal to 0.24.0.
    • checkout_opts: checkout options for writing files when initializing the rebase, stepping through it, and aborting it. See CheckoutOptions for more information.
    LibGit2.SignatureStructType
    LibGit2.SignatureStruct

    An action signature (e.g. for committers, taggers, etc). Matches the git_signature struct.

    The fields represent:

    • name: The full name of the committer or author of the commit.
    • email: The email at which the committer/author can be contacted.
    • when: a TimeStruct indicating when the commit was authored/committed into the repository.
    LibGit2.StatusEntryType
    LibGit2.StatusEntry

    Providing the differences between the file as it exists in HEAD and the index, and providing the differences between the index and the working directory. Matches the git_status_entry struct.

    The fields represent:

    • status: contains the status flags for the file, indicating if it is current, or has been changed in some way in the index or work tree.
    • head_to_index: a pointer to a DiffDelta which encapsulates the difference(s) between the file as it exists in HEAD and in the index.
    • index_to_workdir: a pointer to a DiffDelta which encapsulates the difference(s) between the file as it exists in the index and in the workdir.
    LibGit2.StatusOptionsType
    LibGit2.StatusOptions

    Options to control how git_status_foreach_ext() will issue callbacks. Matches the git_status_opt_t struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • show: a flag for which files to examine and in which order. The default is Consts.STATUS_SHOW_INDEX_AND_WORKDIR.
    • flags: flags for controlling any callbacks used in a status call.
    • pathspec: an array of paths to use for path-matching. The behavior of the path-matching will vary depending on the values of show and flags.
    • The baseline is the tree to be used for comparison to the working directory and index; defaults to HEAD.
    LibGit2.StrArrayStructType
    LibGit2.StrArrayStruct

    A LibGit2 representation of an array of strings. Matches the git_strarray struct.

    When fetching data from LibGit2, a typical usage would look like:

    sa_ref = Ref(StrArrayStruct())
    +julia> fetch(remote, "master", options=fo)
    LibGit2.PushOptionsType
    LibGit2.PushOptions

    Matches the git_push_options struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • parallelism: if a pack file must be created, this variable sets the number of worker threads which will be spawned by the packbuilder. If 0, the packbuilder will auto-set the number of threads to use. The default is 1.
    • callbacks: the callbacks (e.g. for authentication with the remote) to use for the push.
    • proxy_opts: only relevant if the LibGit2 version is greater than or equal to 0.25.0. Sets options for using a proxy to communicate with a remote. See ProxyOptions for more information.
    • custom_headers: only relevant if the LibGit2 version is greater than or equal to 0.24.0. Extra headers needed for the push operation.
    • remote_push_options: only relevant if the LibGit2 version is greater than or equal to 1.8.0. "Push options" to deliver to the remote.
    LibGit2.RebaseOperationType
    LibGit2.RebaseOperation

    Describes a single instruction/operation to be performed during the rebase. Matches the git_rebase_operation struct.

    The fields represent:

    • optype: the type of rebase operation currently being performed. The options are:
      • REBASE_OPERATION_PICK: cherry-pick the commit in question.
      • REBASE_OPERATION_REWORD: cherry-pick the commit in question, but rewrite its message using the prompt.
      • REBASE_OPERATION_EDIT: cherry-pick the commit in question, but allow the user to edit the commit's contents and its message.
      • REBASE_OPERATION_SQUASH: squash the commit in question into the previous commit. The commit messages of the two commits will be merged.
      • REBASE_OPERATION_FIXUP: squash the commit in question into the previous commit. Only the commit message of the previous commit will be used.
      • REBASE_OPERATION_EXEC: do not cherry-pick a commit. Run a command and continue if the command exits successfully.
    • id: the GitHash of the commit being worked on during this rebase step.
    • exec: in case REBASE_OPERATION_EXEC is used, the command to run during this step (for instance, running the test suite after each commit).
    LibGit2.RebaseOptionsType
    LibGit2.RebaseOptions

    Matches the git_rebase_options struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • quiet: inform other git clients helping with/working on the rebase that the rebase should be done "quietly". Used for interoperability. The default is 1.
    • inmemory: start an in-memory rebase. Callers working on the rebase can go through its steps and commit any changes, but cannot rewind HEAD or update the repository. The workdir will not be modified. Only present on libgit2 versions newer than or equal to 0.24.0.
    • rewrite_notes_ref: name of the reference to notes to use to rewrite the commit notes as the rebase is finished.
    • merge_opts: merge options controlling how the trees will be merged at each rebase step. Only present on libgit2 versions newer than or equal to 0.24.0.
    • checkout_opts: checkout options for writing files when initializing the rebase, stepping through it, and aborting it. See CheckoutOptions for more information.
    LibGit2.SignatureStructType
    LibGit2.SignatureStruct

    An action signature (e.g. for committers, taggers, etc). Matches the git_signature struct.

    The fields represent:

    • name: The full name of the committer or author of the commit.
    • email: The email at which the committer/author can be contacted.
    • when: a TimeStruct indicating when the commit was authored/committed into the repository.
    LibGit2.StatusEntryType
    LibGit2.StatusEntry

    Providing the differences between the file as it exists in HEAD and the index, and providing the differences between the index and the working directory. Matches the git_status_entry struct.

    The fields represent:

    • status: contains the status flags for the file, indicating if it is current, or has been changed in some way in the index or work tree.
    • head_to_index: a pointer to a DiffDelta which encapsulates the difference(s) between the file as it exists in HEAD and in the index.
    • index_to_workdir: a pointer to a DiffDelta which encapsulates the difference(s) between the file as it exists in the index and in the workdir.
    LibGit2.StatusOptionsType
    LibGit2.StatusOptions

    Options to control how git_status_foreach_ext() will issue callbacks. Matches the git_status_opt_t struct.

    The fields represent:

    • version: version of the struct in use, in case this changes later. For now, always 1.
    • show: a flag for which files to examine and in which order. The default is Consts.STATUS_SHOW_INDEX_AND_WORKDIR.
    • flags: flags for controlling any callbacks used in a status call.
    • pathspec: an array of paths to use for path-matching. The behavior of the path-matching will vary depending on the values of show and flags.
    • The baseline is the tree to be used for comparison to the working directory and index; defaults to HEAD.
    LibGit2.StrArrayStructType
    LibGit2.StrArrayStruct

    A LibGit2 representation of an array of strings. Matches the git_strarray struct.

    When fetching data from LibGit2, a typical usage would look like:

    sa_ref = Ref(StrArrayStruct())
     @check ccall(..., (Ptr{StrArrayStruct},), sa_ref)
     res = convert(Vector{String}, sa_ref[])
     free(sa_ref)

    In particular, note that LibGit2.free should be called afterward on the Ref object.

    Conversely, when passing a vector of strings to LibGit2, it is generally simplest to rely on implicit conversion:

    strs = String[...]
    @@ -239,4 +239,4 @@
     julia> LibGit2.url(remote)
     "https://github.com/JuliaLang/Example.jl"
    LibGit2.withFunction
    with(f::Function, obj)

    Resource management helper function. Applies f to obj, making sure to call close on obj after f successfully returns or throws an error. Ensures that allocated git resources are finalized as soon as they are no longer needed.

    LibGit2.with_warnFunction
    with_warn(f::Function, ::Type{T}, args...)

    Resource management helper function. Apply f to args, first constructing an instance of type T from args. Makes sure to call close on the resulting object after f successfully returns or throws an error. Ensures that allocated git resources are finalized as soon as they are no longer needed. If an error is thrown by f, a warning is shown containing the error.

    LibGit2.workdirFunction
    LibGit2.workdir(repo::GitRepo)

    Return the location of the working directory of repo. This will throw an error for bare repositories.

    Note

    This will typically be the parent directory of gitdir(repo), but can be different in some cases: e.g. if either the core.worktree configuration variable or the GIT_WORK_TREE environment variable is set.

    See also gitdir, path.

    LibGit2.GitObjectMethod
    (::Type{T})(te::GitTreeEntry) where T<:GitObject

    Get the git object to which te refers and return it as its actual type (the type entrytype would show), for instance a GitBlob or GitTag.

    Examples

    tree = LibGit2.GitTree(repo, "HEAD^{tree}")
     tree_entry = tree[1]
    -blob = LibGit2.GitBlob(tree_entry)
    LibGit2.isfilledFunction
    isfilled(cred::AbstractCredential) -> Bool

    Verifies that a credential is ready for use in authentication.

    LibGit2.CredentialPayloadType
    LibGit2.CredentialPayload

    Retains the state between multiple calls to the credential callback for the same URL. A CredentialPayload instance is expected to be reset! whenever it will be used with a different URL.

    LibGit2.approveFunction
    approve(payload::CredentialPayload; shred::Bool=true) -> Nothing

    Store the payload credential for re-use in a future authentication. Should only be called when authentication was successful.

    The shred keyword controls whether sensitive information in the payload credential field should be destroyed. Should only be set to false during testing.

    LibGit2.rejectFunction
    reject(payload::CredentialPayload; shred::Bool=true) -> Nothing

    Discard the payload credential from begin re-used in future authentication. Should only be called when authentication was unsuccessful.

    The shred keyword controls whether sensitive information in the payload credential field should be destroyed. Should only be set to false during testing.

    LibGit2.Consts.GIT_CONFIGType

    Priority level of a config file.

    These priority levels correspond to the natural escalation logic (from higher to lower) when searching for config entries in git.

    • CONFIG_LEVEL_DEFAULT - Open the global, XDG and system configuration files if any available.
    • CONFIG_LEVEL_PROGRAMDATA - System-wide on Windows, for compatibility with portable git
    • CONFIG_LEVEL_SYSTEM - System-wide configuration file; /etc/gitconfig on Linux systems
    • CONFIG_LEVEL_XDG - XDG compatible configuration file; typically ~/.config/git/config
    • CONFIG_LEVEL_GLOBAL - User-specific configuration file (also called Global configuration file); typically ~/.gitconfig
    • CONFIG_LEVEL_LOCAL - Repository specific configuration file; $WORK_DIR/.git/config on non-bare repos
    • CONFIG_LEVEL_APP - Application specific configuration file; freely defined by applications
    • CONFIG_HIGHEST_LEVEL - Represents the highest level available config file (i.e. the most specific config file available that actually is loaded)
    +blob = LibGit2.GitBlob(tree_entry)
    LibGit2.isfilledFunction
    isfilled(cred::AbstractCredential) -> Bool

    Verifies that a credential is ready for use in authentication.

    LibGit2.CredentialPayloadType
    LibGit2.CredentialPayload

    Retains the state between multiple calls to the credential callback for the same URL. A CredentialPayload instance is expected to be reset! whenever it will be used with a different URL.

    LibGit2.approveFunction
    approve(payload::CredentialPayload; shred::Bool=true) -> Nothing

    Store the payload credential for re-use in a future authentication. Should only be called when authentication was successful.

    The shred keyword controls whether sensitive information in the payload credential field should be destroyed. Should only be set to false during testing.

    LibGit2.rejectFunction
    reject(payload::CredentialPayload; shred::Bool=true) -> Nothing

    Discard the payload credential from begin re-used in future authentication. Should only be called when authentication was unsuccessful.

    The shred keyword controls whether sensitive information in the payload credential field should be destroyed. Should only be set to false during testing.

    LibGit2.Consts.GIT_CONFIGType

    Priority level of a config file.

    These priority levels correspond to the natural escalation logic (from higher to lower) when searching for config entries in git.

    • CONFIG_LEVEL_DEFAULT - Open the global, XDG and system configuration files if any available.
    • CONFIG_LEVEL_PROGRAMDATA - System-wide on Windows, for compatibility with portable git
    • CONFIG_LEVEL_SYSTEM - System-wide configuration file; /etc/gitconfig on Linux systems
    • CONFIG_LEVEL_XDG - XDG compatible configuration file; typically ~/.config/git/config
    • CONFIG_LEVEL_GLOBAL - User-specific configuration file (also called Global configuration file); typically ~/.gitconfig
    • CONFIG_LEVEL_LOCAL - Repository specific configuration file; $WORK_DIR/.git/config on non-bare repos
    • CONFIG_LEVEL_WORKTREE - Worktree specific configuration file; $GIT_DIR/config.worktree
    • CONFIG_LEVEL_APP - Application specific configuration file; freely defined by applications
    • CONFIG_HIGHEST_LEVEL - Represents the highest level available config file (i.e. the most specific config file available that actually is loaded)
    diff --git a/en/v1.12-dev/stdlib/Libdl/index.html b/en/v1.12-dev/stdlib/Libdl/index.html index df49c0e81933..2a22091a5049 100644 --- a/en/v1.12-dev/stdlib/Libdl/index.html +++ b/en/v1.12-dev/stdlib/Libdl/index.html @@ -3,16 +3,16 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -
    LibdlModule

    The Libdl module in Julia provides specialized and lower-level facilities for dynamic linking with shared libraries. While Julia inherently supports linking to runtime shared libraries through the ccall intrinsic, Libdl extends this capability by offering additional, more granular control. It enables users to search for shared libraries both in memory and the filesystem, manually load them with specific runtime linker options, and look up library symbols as low-level pointers.

    Dynamic Linker

    Base.Libc.Libdl.dlopenFunction
    dlopen(libfile::AbstractString [, flags::Integer]; throw_error:Bool = true)

    Load a shared library, returning an opaque handle.

    The extension given by the constant dlext (.so, .dll, or .dylib) can be omitted from the libfile string, as it is automatically appended if needed. If libfile is not an absolute path name, then the paths in the array DL_LOAD_PATH are searched for libfile, followed by the system load path.

    The optional flags argument is a bitwise-or of zero or more of RTLD_LOCAL, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, and RTLD_FIRST. These are converted to the corresponding flags of the POSIX (and/or GNU libc and/or MacOS) dlopen command, if possible, or are ignored if the specified functionality is not available on the current platform. The default flags are platform specific. On MacOS the default dlopen flags are RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL while on other platforms the defaults are RTLD_LAZY|RTLD_DEEPBIND|RTLD_LOCAL. An important usage of these flags is to specify non default behavior for when the dynamic library loader binds library references to exported symbols and if the bound references are put into process local or global scope. For instance RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL allows the library's symbols to be available for usage in other shared libraries, addressing situations where there are dependencies between shared libraries.

    If the library cannot be found, this method throws an error, unless the keyword argument throw_error is set to false, in which case this method returns nothing.

    Note

    From Julia 1.6 on, this method replaces paths starting with @executable_path/ with the path to the Julia executable, allowing for relocatable relative-path loads. In Julia 1.5 and earlier, this only worked on macOS.

    source
    Base.Libc.Libdl.dlopen_eFunction
    dlopen_e(libfile::AbstractString [, flags::Integer])

    Similar to dlopen, except returns C_NULL instead of raising errors. This method is now deprecated in favor of dlopen(libfile::AbstractString [, flags::Integer]; throw_error=false).

    source
    Base.Libc.Libdl.RTLD_NOWConstant
    RTLD_DEEPBIND
    +
    LibdlModule

    The Libdl module in Julia provides specialized and lower-level facilities for dynamic linking with shared libraries. While Julia inherently supports linking to runtime shared libraries through the ccall intrinsic, Libdl extends this capability by offering additional, more granular control. It enables users to search for shared libraries both in memory and the filesystem, manually load them with specific runtime linker options, and look up library symbols as low-level pointers.

    Dynamic Linker

    Base.Libc.Libdl.dlopenFunction
    dlopen(libfile::AbstractString [, flags::Integer]; throw_error:Bool = true)

    Load a shared library, returning an opaque handle.

    The extension given by the constant dlext (.so, .dll, or .dylib) can be omitted from the libfile string, as it is automatically appended if needed. If libfile is not an absolute path name, then the paths in the array DL_LOAD_PATH are searched for libfile, followed by the system load path.

    The optional flags argument is a bitwise-or of zero or more of RTLD_LOCAL, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, and RTLD_FIRST. These are converted to the corresponding flags of the POSIX (and/or GNU libc and/or MacOS) dlopen command, if possible, or are ignored if the specified functionality is not available on the current platform. The default flags are platform specific. On MacOS the default dlopen flags are RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL while on other platforms the defaults are RTLD_LAZY|RTLD_DEEPBIND|RTLD_LOCAL. An important usage of these flags is to specify non default behavior for when the dynamic library loader binds library references to exported symbols and if the bound references are put into process local or global scope. For instance RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL allows the library's symbols to be available for usage in other shared libraries, addressing situations where there are dependencies between shared libraries.

    If the library cannot be found, this method throws an error, unless the keyword argument throw_error is set to false, in which case this method returns nothing.

    Note

    From Julia 1.6 on, this method replaces paths starting with @executable_path/ with the path to the Julia executable, allowing for relocatable relative-path loads. In Julia 1.5 and earlier, this only worked on macOS.

    source
    Base.Libc.Libdl.dlopen_eFunction
    dlopen_e(libfile::AbstractString [, flags::Integer])

    Similar to dlopen, except returns C_NULL instead of raising errors. This method is now deprecated in favor of dlopen(libfile::AbstractString [, flags::Integer]; throw_error=false).

    source
    Base.Libc.Libdl.RTLD_NOWConstant
    RTLD_DEEPBIND
     RTLD_FIRST
     RTLD_GLOBAL
     RTLD_LAZY
     RTLD_LOCAL
     RTLD_NODELETE
     RTLD_NOLOAD
    -RTLD_NOW

    Enum constant for dlopen. See your platform man page for details, if applicable.

    source
    Base.Libc.Libdl.dlsymFunction
    dlsym(handle, sym; throw_error::Bool = true)

    Look up a symbol from a shared library handle, return callable function pointer on success.

    If the symbol cannot be found, this method throws an error, unless the keyword argument throw_error is set to false, in which case this method returns nothing.

    source
    Base.Libc.Libdl.dlsym_eFunction
    dlsym_e(handle, sym)

    Look up a symbol from a shared library handle, silently return C_NULL on lookup failure. This method is now deprecated in favor of dlsym(handle, sym; throw_error=false).

    source
    Base.Libc.Libdl.dlcloseFunction
    dlclose(handle)

    Close shared library referenced by handle.

    source
    dlclose(::Nothing)

    For the very common pattern usage pattern of

    try
    +RTLD_NOW

    Enum constant for dlopen. See your platform man page for details, if applicable.

    source
    Base.Libc.Libdl.dlsymFunction
    dlsym(handle, sym; throw_error::Bool = true)

    Look up a symbol from a shared library handle, return callable function pointer on success.

    If the symbol cannot be found, this method throws an error, unless the keyword argument throw_error is set to false, in which case this method returns nothing.

    source
    Base.Libc.Libdl.dlsym_eFunction
    dlsym_e(handle, sym)

    Look up a symbol from a shared library handle, silently return C_NULL on lookup failure. This method is now deprecated in favor of dlsym(handle, sym; throw_error=false).

    source
    Base.Libc.Libdl.dlcloseFunction
    dlclose(handle)

    Close shared library referenced by handle.

    source
    dlclose(::Nothing)

    For the very common pattern usage pattern of

    try
         hdl = dlopen(library_name)
         ... do something
     finally
         dlclose(hdl)
    -end

    We define a dlclose() method that accepts a parameter of type Nothing, so that user code does not have to change its behavior for the case that library_name was not found.

    source
    Base.Libc.Libdl.dlpathFunction
    dlpath(handle::Ptr{Cvoid})

    Given a library handle from dlopen, return the full path.

    source
    dlpath(libname::Union{AbstractString, Symbol})

    Get the full path of the library libname.

    Examples

    julia> dlpath("libjulia")
    source
    Base.Libc.Libdl.find_libraryFunction
    find_library(names [, locations])

    Searches for the first library in names in the paths in the locations list, DL_LOAD_PATH, or system library paths (in that order) which can successfully be dlopen'd. On success, the return value will be one of the names (potentially prefixed by one of the paths in locations). This string can be assigned to a global const and used as the library name in future ccall's. On failure, it returns the empty string.

    source
    Base.DL_LOAD_PATHConstant
    DL_LOAD_PATH

    When calling dlopen, the paths in this list will be searched first, in order, before searching the system locations for a valid library handle.

    source
    +end

    We define a dlclose() method that accepts a parameter of type Nothing, so that user code does not have to change its behavior for the case that library_name was not found.

    source
    Base.Libc.Libdl.dlpathFunction
    dlpath(handle::Ptr{Cvoid})

    Given a library handle from dlopen, return the full path.

    source
    dlpath(libname::Union{AbstractString, Symbol})

    Get the full path of the library libname.

    Examples

    julia> dlpath("libjulia")
    source
    Base.Libc.Libdl.find_libraryFunction
    find_library(names [, locations])

    Searches for the first library in names in the paths in the locations list, DL_LOAD_PATH, or system library paths (in that order) which can successfully be dlopen'd. On success, the return value will be one of the names (potentially prefixed by one of the paths in locations). This string can be assigned to a global const and used as the library name in future ccall's. On failure, it returns the empty string.

    source
    Base.DL_LOAD_PATHConstant
    DL_LOAD_PATH

    When calling dlopen, the paths in this list will be searched first, in order, before searching the system locations for a valid library handle.

    source
    diff --git a/en/v1.12-dev/stdlib/LinearAlgebra/index.html b/en/v1.12-dev/stdlib/LinearAlgebra/index.html index 9e8b050cae19..3860e3f1977d 100644 --- a/en/v1.12-dev/stdlib/LinearAlgebra/index.html +++ b/en/v1.12-dev/stdlib/LinearAlgebra/index.html @@ -2033,7 +2033,7 @@ 1.0 1.4142135623730951 1.7320508075688772 - 2.0source
    sqrt(A::AbstractMatrix)

    If A has no negative real eigenvalues, compute the principal matrix square root of A, that is the unique matrix $X$ with eigenvalues having positive real part such that $X^2 = A$. Otherwise, a nonprincipal square root is returned.

    If A is real-symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the square root. For such matrices, eigenvalues λ that appear to be slightly negative due to roundoff errors are treated as if they were zero. More precisely, matrices with all eigenvalues ≥ -rtol*(max |λ|) are treated as semidefinite (yielding a Hermitian square root), with negative eigenvalues taken to be zero. rtol is a keyword argument to sqrt (in the Hermitian/real-symmetric case only) that defaults to machine precision scaled by size(A,1).

    Otherwise, the square root is determined by means of the Björck-Hammarling method [BH83], which computes the complex Schur form (schur) and then the complex square root of the triangular factor. If a real square root exists, then an extension of this method [H87] that computes the real Schur form and then the real square root of the quasi-triangular factor is instead used.

    Examples

    julia> A = [4 0; 0 4]
    + 2.0
    source
    sqrt(A::AbstractMatrix)

    If A has no negative real eigenvalues, compute the principal matrix square root of A, that is the unique matrix $X$ with eigenvalues having positive real part such that $X^2 = A$. Otherwise, a nonprincipal square root is returned.

    If A is real-symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the square root. For such matrices, eigenvalues λ that appear to be slightly negative due to roundoff errors are treated as if they were zero. More precisely, matrices with all eigenvalues ≥ -rtol*(max |λ|) are treated as semidefinite (yielding a Hermitian square root), with negative eigenvalues taken to be zero. rtol is a keyword argument to sqrt (in the Hermitian/real-symmetric case only) that defaults to machine precision scaled by size(A,1).

    Otherwise, the square root is determined by means of the Björck-Hammarling method [BH83], which computes the complex Schur form (schur) and then the complex square root of the triangular factor. If a real square root exists, then an extension of this method [H87] that computes the real Schur form and then the real square root of the quasi-triangular factor is instead used.

    Examples

    julia> A = [4 0; 0 4]
     2×2 Matrix{Int64}:
      4  0
      0  4
    @@ -2607,4 +2607,4 @@
     2.0
    LinearAlgebra.BLAS.iamaxFunction
    iamax(n, dx, incx)
     iamax(dx)

    Find the index of the element of dx with the maximum absolute value. n is the length of dx, and incx is the stride. If n and incx are not provided, they assume default values of n=length(dx) and incx=stride1(dx).

    Level 2 BLAS functions

    The level 2 BLAS functions were published in [(Dongarra, 1988)][Dongarra-1988], and define matrix-vector operations.

    [Dongarra-1988]: https://dl.acm.org/doi/10.1145/42288.42291

    return a vector

    LinearAlgebra.BLAS.gemv!Function
    gemv!(tA, alpha, A, x, beta, y)

    Update the vector y as alpha*A*x + beta*y or alpha*A'x + beta*y according to tA. alpha and beta are scalars. Return the updated y.

    LinearAlgebra.BLAS.gbmv!Function
    gbmv!(trans, m, kl, ku, alpha, A, x, beta, y)

    Update vector y as alpha*A*x + beta*y or alpha*A'*x + beta*y according to trans. The matrix A is a general band matrix of dimension m by size(A,2) with kl sub-diagonals and ku super-diagonals. alpha and beta are scalars. Return the updated y.

    LinearAlgebra.BLAS.gbmvFunction
    gbmv(trans, m, kl, ku, alpha, A, x)

    Return alpha*A*x or alpha*A'*x according to trans. The matrix A is a general band matrix of dimension m by size(A,2) with kl sub-diagonals and ku super-diagonals, and alpha is a scalar.

    LinearAlgebra.BLAS.hemv!Function
    hemv!(ul, alpha, A, x, beta, y)

    Update the vector y as alpha*A*x + beta*y. A is assumed to be Hermitian. Only the ul triangle of A is used. alpha and beta are scalars. Return the updated y.

    LinearAlgebra.BLAS.hemvMethod
    hemv(ul, alpha, A, x)

    Return alpha*A*x. A is assumed to be Hermitian. Only the ul triangle of A is used. alpha is a scalar.

    LinearAlgebra.BLAS.hpmv!Function
    hpmv!(uplo, α, AP, x, β, y)

    Update vector y as α*A*x + β*y, where A is a Hermitian matrix provided in packed format AP.

    With uplo = 'U', the array AP must contain the upper triangular part of the Hermitian matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.

    With uplo = 'L', the array AP must contain the lower triangular part of the Hermitian matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.

    The scalar inputs α and β must be complex or real numbers.

    The array inputs x, y and AP must all be of ComplexF32 or ComplexF64 type.

    Return the updated y.

    Julia 1.5

    hpmv! requires at least Julia 1.5.

    LinearAlgebra.BLAS.symv!Function
    symv!(ul, alpha, A, x, beta, y)

    Update the vector y as alpha*A*x + beta*y. A is assumed to be symmetric. Only the ul triangle of A is used. alpha and beta are scalars. Return the updated y.

    LinearAlgebra.BLAS.symvMethod
    symv(ul, alpha, A, x)

    Return alpha*A*x. A is assumed to be symmetric. Only the ul triangle of A is used. alpha is a scalar.

    LinearAlgebra.BLAS.sbmv!Function
    sbmv!(uplo, k, alpha, A, x, beta, y)

    Update vector y as alpha*A*x + beta*y where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. The storage layout for A is described the reference BLAS module, level-2 BLAS at https://www.netlib.org/lapack/explore-html/. Only the uplo triangle of A is used.

    Return the updated y.

    LinearAlgebra.BLAS.sbmvMethod
    sbmv(uplo, k, alpha, A, x)

    Return alpha*A*x where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. Only the uplo triangle of A is used.

    LinearAlgebra.BLAS.sbmvMethod
    sbmv(uplo, k, A, x)

    Return A*x where A is a symmetric band matrix of order size(A,2) with k super-diagonals stored in the argument A. Only the uplo triangle of A is used.

    LinearAlgebra.BLAS.spmv!Function
    spmv!(uplo, α, AP, x, β, y)

    Update vector y as α*A*x + β*y, where A is a symmetric matrix provided in packed format AP.

    With uplo = 'U', the array AP must contain the upper triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.

    With uplo = 'L', the array AP must contain the lower triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.

    The scalar inputs α and β must be real.

    The array inputs x, y and AP must all be of Float32 or Float64 type.

    Return the updated y.

    Julia 1.5

    spmv! requires at least Julia 1.5.

    LinearAlgebra.BLAS.trmv!Function
    trmv!(ul, tA, dA, A, b)

    Return op(A)*b, where op is determined by tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. The multiplication occurs in-place on b.

    LinearAlgebra.BLAS.trmvFunction
    trmv(ul, tA, dA, A, b)

    Return op(A)*b, where op is determined by tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.

    LinearAlgebra.BLAS.trsv!Function
    trsv!(ul, tA, dA, A, b)

    Overwrite b with the solution to A*x = b or one of the other two variants determined by tA and ul. dA determines if the diagonal values are read or are assumed to be all ones. Return the updated b.

    LinearAlgebra.BLAS.trsvFunction
    trsv(ul, tA, dA, A, b)

    Return the solution to A*x = b or one of the other two variants determined by tA and ul. dA determines if the diagonal values are read or are assumed to be all ones.

    return a matrix

    LinearAlgebra.BLAS.ger!Function
    ger!(alpha, x, y, A)

    Rank-1 update of the matrix A with vectors x and y as alpha*x*y' + A.

    LinearAlgebra.BLAS.her!Function
    her!(uplo, alpha, x, A)

    Methods for complex arrays only. Rank-1 update of the Hermitian matrix A with vector x as alpha*x*x' + A. uplo controls which triangle of A is updated. Returns A.

    LinearAlgebra.BLAS.syr!Function
    syr!(uplo, alpha, x, A)

    Rank-1 update of the symmetric matrix A with vector x as alpha*x*transpose(x) + A. uplo controls which triangle of A is updated. Returns A.

    LinearAlgebra.BLAS.spr!Function
    spr!(uplo, α, x, AP)

    Update matrix A as A+α*x*x', where A is a symmetric matrix provided in packed format AP and x is a vector.

    With uplo = 'U', the array AP must contain the upper triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[1, 2] and A[2, 2] respectively, and so on.

    With uplo = 'L', the array AP must contain the lower triangular part of the symmetric matrix packed sequentially, column by column, so that AP[1] contains A[1, 1], AP[2] and AP[3] contain A[2, 1] and A[3, 1] respectively, and so on.

    The scalar input α must be real.

    The array inputs x and AP must all be of Float32 or Float64 type. Return the updated AP.

    Julia 1.8

    spr! requires at least Julia 1.8.

    Level 3 BLAS functions

    The level 3 BLAS functions were published in [(Dongarra, 1990)][Dongarra-1990], and define matrix-matrix operations.

    [Dongarra-1990]: https://dl.acm.org/doi/10.1145/77626.79170

    LinearAlgebra.BLAS.gemmt!Function
    gemmt!(uplo, tA, tB, alpha, A, B, beta, C)

    Update the lower or upper triangular part specified by uplo of C as alpha*A*B + beta*C or the other variants according to tA and tB. Return the updated C.

    Julia 1.11

    gemmt! requires at least Julia 1.11.

    LinearAlgebra.BLAS.gemmtMethod
    gemmt(uplo, tA, tB, alpha, A, B)

    Return the lower or upper triangular part specified by uplo of A*B or the other three variants according to tA and tB.

    Julia 1.11

    gemmt requires at least Julia 1.11.

    LinearAlgebra.BLAS.gemmtMethod
    gemmt(uplo, tA, tB, A, B)

    Return the lower or upper triangular part specified by uplo of A*B or the other three variants according to tA and tB.

    Julia 1.11

    gemmt requires at least Julia 1.11.

    LinearAlgebra.BLAS.gemm!Function
    gemm!(tA, tB, alpha, A, B, beta, C)

    Update C as alpha*A*B + beta*C or the other three variants according to tA and tB. Return the updated C.

    LinearAlgebra.BLAS.gemmMethod
    gemm(tA, tB, alpha, A, B)

    Return alpha*A*B or the other three variants according to tA and tB.

    LinearAlgebra.BLAS.symm!Function
    symm!(side, ul, alpha, A, B, beta, C)

    Update C as alpha*A*B + beta*C or alpha*B*A + beta*C according to side. A is assumed to be symmetric. Only the ul triangle of A is used. Return the updated C.

    LinearAlgebra.BLAS.symmMethod
    symm(side, ul, alpha, A, B)

    Return alpha*A*B or alpha*B*A according to side. A is assumed to be symmetric. Only the ul triangle of A is used.

    LinearAlgebra.BLAS.symmMethod
    symm(side, ul, A, B)

    Return A*B or B*A according to side. A is assumed to be symmetric. Only the ul triangle of A is used.

    LinearAlgebra.BLAS.hemm!Function
    hemm!(side, ul, alpha, A, B, beta, C)

    Update C as alpha*A*B + beta*C or alpha*B*A + beta*C according to side. A is assumed to be Hermitian. Only the ul triangle of A is used. Return the updated C.

    LinearAlgebra.BLAS.hemmMethod
    hemm(side, ul, alpha, A, B)

    Return alpha*A*B or alpha*B*A according to side. A is assumed to be Hermitian. Only the ul triangle of A is used.

    LinearAlgebra.BLAS.hemmMethod
    hemm(side, ul, A, B)

    Return A*B or B*A according to side. A is assumed to be Hermitian. Only the ul triangle of A is used.

    LinearAlgebra.BLAS.syrk!Function
    syrk!(uplo, trans, alpha, A, beta, C)

    Rank-k update of the symmetric matrix C as alpha*A*transpose(A) + beta*C or alpha*transpose(A)*A + beta*C according to trans. Only the uplo triangle of C is used. Return C.

    LinearAlgebra.BLAS.syrkFunction
    syrk(uplo, trans, alpha, A)

    Return either the upper triangle or the lower triangle of A, according to uplo, of alpha*A*transpose(A) or alpha*transpose(A)*A, according to trans.

    LinearAlgebra.BLAS.herk!Function
    herk!(uplo, trans, alpha, A, beta, C)

    Methods for complex arrays only. Rank-k update of the Hermitian matrix C as alpha*A*A' + beta*C or alpha*A'*A + beta*C according to trans. Only the uplo triangle of C is updated. Returns C.

    LinearAlgebra.BLAS.herkFunction
    herk(uplo, trans, alpha, A)

    Methods for complex arrays only. Returns the uplo triangle of alpha*A*A' or alpha*A'*A, according to trans.

    LinearAlgebra.BLAS.syr2k!Function
    syr2k!(uplo, trans, alpha, A, B, beta, C)

    Rank-2k update of the symmetric matrix C as alpha*A*transpose(B) + alpha*B*transpose(A) + beta*C or alpha*transpose(A)*B + alpha*transpose(B)*A + beta*C according to trans. Only the uplo triangle of C is used. Returns C.

    LinearAlgebra.BLAS.syr2kFunction
    syr2k(uplo, trans, alpha, A, B)

    Returns the uplo triangle of alpha*A*transpose(B) + alpha*B*transpose(A) or alpha*transpose(A)*B + alpha*transpose(B)*A, according to trans.

    syr2k(uplo, trans, A, B)

    Return the uplo triangle of A*transpose(B) + B*transpose(A) or transpose(A)*B + transpose(B)*A, according to trans.

    LinearAlgebra.BLAS.her2k!Function
    her2k!(uplo, trans, alpha, A, B, beta, C)

    Rank-2k update of the Hermitian matrix C as alpha*A*B' + alpha*B*A' + beta*C or alpha*A'*B + alpha*B'*A + beta*C according to trans. The scalar beta has to be real. Only the uplo triangle of C is used. Return C.

    LinearAlgebra.BLAS.her2kFunction
    her2k(uplo, trans, alpha, A, B)

    Return the uplo triangle of alpha*A*B' + alpha*B*A' or alpha*A'*B + alpha*B'*A, according to trans.

    her2k(uplo, trans, A, B)

    Return the uplo triangle of A*B' + B*A' or A'*B + B'*A, according to trans.

    LinearAlgebra.BLAS.trmm!Function
    trmm!(side, ul, tA, dA, alpha, A, B)

    Update B as alpha*A*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. Return the updated B.

    LinearAlgebra.BLAS.trmmFunction
    trmm(side, ul, tA, dA, alpha, A, B)

    Return alpha*A*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.

    LinearAlgebra.BLAS.trsm!Function
    trsm!(side, ul, tA, dA, alpha, A, B)

    Overwrite B with the solution to A*X = alpha*B or one of the other three variants determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones. Returns the updated B.

    LinearAlgebra.BLAS.trsmFunction
    trsm(side, ul, tA, dA, alpha, A, B)

    Return the solution to A*X = alpha*B or one of the other three variants determined by determined by side and tA. Only the ul triangle of A is used. dA determines if the diagonal values are read or are assumed to be all ones.

    LAPACK functions

    LinearAlgebra.LAPACK provides wrappers for some of the LAPACK functions for linear algebra. Those functions that overwrite one of the input arrays have names ending in '!'.

    Usually a function has 4 methods defined, one each for Float64, Float32, ComplexF64 and ComplexF32 arrays.

    Note that the LAPACK API provided by Julia can and will change in the future. Since this API is not user-facing, there is no commitment to support/deprecate this specific set of functions in future releases.

    LinearAlgebra.LAPACK.gbtrf!Function
    gbtrf!(kl, ku, m, AB) -> (AB, ipiv)

    Compute the LU factorization of a banded matrix AB. kl is the first subdiagonal containing a nonzero band, ku is the last superdiagonal containing one, and m is the first dimension of the matrix AB. Returns the LU factorization in-place and ipiv, the vector of pivots used.

    LinearAlgebra.LAPACK.gbtrs!Function
    gbtrs!(trans, kl, ku, m, AB, ipiv, B)

    Solve the equation AB * X = B. trans determines the orientation of AB. It may be N (no transpose), T (transpose), or C (conjugate transpose). kl is the first subdiagonal containing a nonzero band, ku is the last superdiagonal containing one, and m is the first dimension of the matrix AB. ipiv is the vector of pivots returned from gbtrf!. Returns the vector or matrix X, overwriting B in-place.

    LinearAlgebra.LAPACK.gebal!Function
    gebal!(job, A) -> (ilo, ihi, scale)

    Balance the matrix A before computing its eigensystem or Schur factorization. job can be one of N (A will not be permuted or scaled), P (A will only be permuted), S (A will only be scaled), or B (A will be both permuted and scaled). Modifies A in-place and returns ilo, ihi, and scale. If permuting was turned on, A[i,j] = 0 if j > i and 1 < j < ilo or j > ihi. scale contains information about the scaling/permutations performed.

    LinearAlgebra.LAPACK.gebak!Function
    gebak!(job, side, ilo, ihi, scale, V)

    Transform the eigenvectors V of a matrix balanced using gebal! to the unscaled/unpermuted eigenvectors of the original matrix. Modifies V in-place. side can be L (left eigenvectors are transformed) or R (right eigenvectors are transformed).

    LinearAlgebra.LAPACK.gebrd!Function
    gebrd!(A) -> (A, d, e, tauq, taup)

    Reduce A in-place to bidiagonal form A = QBP'. Returns A, containing the bidiagonal matrix B; d, containing the diagonal elements of B; e, containing the off-diagonal elements of B; tauq, containing the elementary reflectors representing Q; and taup, containing the elementary reflectors representing P.

    LinearAlgebra.LAPACK.gelqf!Function
    gelqf!(A, tau)

    Compute the LQ factorization of A, A = LQ. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.

    Returns A and tau modified in-place.

    gelqf!(A) -> (A, tau)

    Compute the LQ factorization of A, A = LQ.

    Returns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.

    LinearAlgebra.LAPACK.geqlf!Function
    geqlf!(A, tau)

    Compute the QL factorization of A, A = QL. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.

    Returns A and tau modified in-place.

    geqlf!(A) -> (A, tau)

    Compute the QL factorization of A, A = QL.

    Returns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.

    LinearAlgebra.LAPACK.geqrf!Function
    geqrf!(A, tau)

    Compute the QR factorization of A, A = QR. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.

    Returns A and tau modified in-place.

    geqrf!(A) -> (A, tau)

    Compute the QR factorization of A, A = QR.

    Returns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.

    LinearAlgebra.LAPACK.geqp3!Function
    geqp3!(A, [jpvt, tau]) -> (A, tau, jpvt)

    Compute the pivoted QR factorization of A, AP = QR using BLAS level 3. P is a pivoting matrix, represented by jpvt. tau stores the elementary reflectors. The arguments jpvt and tau are optional and allow for passing preallocated arrays. When passed, jpvt must have length greater than or equal to n if A is an (m x n) matrix and tau must have length greater than or equal to the smallest dimension of A. On entry, if jpvt[j] does not equal zero then the jth column of A is permuted to the front of AP.

    A, jpvt, and tau are modified in-place.

    LinearAlgebra.LAPACK.gerqf!Function
    gerqf!(A, tau)

    Compute the RQ factorization of A, A = RQ. tau contains scalars which parameterize the elementary reflectors of the factorization. tau must have length greater than or equal to the smallest dimension of A.

    Returns A and tau modified in-place.

    gerqf!(A) -> (A, tau)

    Compute the RQ factorization of A, A = RQ.

    Returns A, modified in-place, and tau, which contains scalars which parameterize the elementary reflectors of the factorization.

    LinearAlgebra.LAPACK.geqrt!Function
    geqrt!(A, T)

    Compute the blocked QR factorization of A, A = QR. T contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization. The first dimension of T sets the block size and it must be between 1 and n. The second dimension of T must equal the smallest dimension of A.

    Returns A and T modified in-place.

    geqrt!(A, nb) -> (A, T)

    Compute the blocked QR factorization of A, A = QR. nb sets the block size and it must be between 1 and n, the second dimension of A.

    Returns A, modified in-place, and T, which contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization.

    LinearAlgebra.LAPACK.geqrt3!Function
    geqrt3!(A, T)

    Recursively computes the blocked QR factorization of A, A = QR. T contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization. The first dimension of T sets the block size and it must be between 1 and n. The second dimension of T must equal the smallest dimension of A.

    Returns A and T modified in-place.

    geqrt3!(A) -> (A, T)

    Recursively computes the blocked QR factorization of A, A = QR.

    Returns A, modified in-place, and T, which contains upper triangular block reflectors which parameterize the elementary reflectors of the factorization.

    LinearAlgebra.LAPACK.getrf!Function
    getrf!(A, ipiv) -> (A, ipiv, info)

    Compute the pivoted LU factorization of A, A = LU. ipiv contains the pivoting information and info a code which indicates success (info = 0), a singular value in U (info = i, in which case U[i,i] is singular), or an error code (info < 0).

    getrf!(A) -> (A, ipiv, info)

    Compute the pivoted LU factorization of A, A = LU.

    Returns A, modified in-place, ipiv, the pivoting information, and an info code which indicates success (info = 0), a singular value in U (info = i, in which case U[i,i] is singular), or an error code (info < 0).

    LinearAlgebra.LAPACK.tzrzf!Function
    tzrzf!(A) -> (A, tau)

    Transforms the upper trapezoidal matrix A to upper triangular form in-place. Returns A and tau, the scalar parameters for the elementary reflectors of the transformation.

    LinearAlgebra.LAPACK.ormrz!Function
    ormrz!(side, trans, A, tau, C)

    Multiplies the matrix C by Q from the transformation supplied by tzrzf!. Depending on side or trans the multiplication can be left-sided (side = L, Q*C) or right-sided (side = R, C*Q) and Q can be unmodified (trans = N), transposed (trans = T), or conjugate transposed (trans = C). Returns matrix C which is modified in-place with the result of the multiplication.

    LinearAlgebra.LAPACK.gels!Function
    gels!(trans, A, B) -> (F, B, ssr)

    Solves the linear equation A * X = B, transpose(A) * X = B, or adjoint(A) * X = B using a QR or LQ factorization. Modifies the matrix/vector B in place with the solution. A is overwritten with its QR or LQ factorization. trans may be one of N (no modification), T (transpose), or C (conjugate transpose). gels! searches for the minimum norm/least squares solution. A may be under or over determined. The solution is returned in B.

    LinearAlgebra.LAPACK.gesv!Function
    gesv!(A, B) -> (B, A, ipiv)

    Solves the linear equation A * X = B where A is a square matrix using the LU factorization of A. A is overwritten with its LU factorization and B is overwritten with the solution X. ipiv contains the pivoting information for the LU factorization of A.

    LinearAlgebra.LAPACK.getrs!Function
    getrs!(trans, A, ipiv, B)

    Solves the linear equation A * X = B, transpose(A) * X = B, or adjoint(A) * X = B for square A. Modifies the matrix/vector B in place with the solution. A is the LU factorization from getrf!, with ipiv the pivoting information. trans may be one of N (no modification), T (transpose), or C (conjugate transpose).

    LinearAlgebra.LAPACK.getri!Function
    getri!(A, ipiv)

    Computes the inverse of A, using its LU factorization found by getrf!. ipiv is the pivot information output and A contains the LU factorization of getrf!. A is overwritten with its inverse.

    LinearAlgebra.LAPACK.gesvx!Function
    gesvx!(fact, trans, A, AF, ipiv, equed, R, C, B) -> (X, equed, R, C, B, rcond, ferr, berr, work)

    Solves the linear equation A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) using the LU factorization of A. fact may be E, in which case A will be equilibrated and copied to AF; F, in which case AF and ipiv from a previous LU factorization are inputs; or N, in which case A will be copied to AF and then factored. If fact = F, equed may be N, meaning A has not been equilibrated; R, meaning A was multiplied by Diagonal(R) from the left; C, meaning A was multiplied by Diagonal(C) from the right; or B, meaning A was multiplied by Diagonal(R) from the left and Diagonal(C) from the right. If fact = F and equed = R or B the elements of R must all be positive. If fact = F and equed = C or B the elements of C must all be positive.

    Returns the solution X; equed, which is an output if fact is not N, and describes the equilibration that was performed; R, the row equilibration diagonal; C, the column equilibration diagonal; B, which may be overwritten with its equilibrated form Diagonal(R)*B (if trans = N and equed = R,B) or Diagonal(C)*B (if trans = T,C and equed = C,B); rcond, the reciprocal condition number of A after equilbrating; ferr, the forward error bound for each solution vector in X; berr, the forward error bound for each solution vector in X; and work, the reciprocal pivot growth factor.

    gesvx!(A, B)

    The no-equilibration, no-transpose simplification of gesvx!.

    LinearAlgebra.LAPACK.gelsd!Function
    gelsd!(A, B, rcond) -> (B, rnk)

    Computes the least norm solution of A * X = B by finding the SVD factorization of A, then dividing-and-conquering the problem. B is overwritten with the solution X. Singular values below rcond will be treated as zero. Returns the solution in B and the effective rank of A in rnk.

    LinearAlgebra.LAPACK.gelsy!Function
    gelsy!(A, B, rcond) -> (B, rnk)

    Computes the least norm solution of A * X = B by finding the full QR factorization of A, then dividing-and-conquering the problem. B is overwritten with the solution X. Singular values below rcond will be treated as zero. Returns the solution in B and the effective rank of A in rnk.

    LinearAlgebra.LAPACK.gglse!Function
    gglse!(A, c, B, d) -> (X,res)

    Solves the equation A * x = c where x is subject to the equality constraint B * x = d. Uses the formula ||c - A*x||^2 = 0 to solve. Returns X and the residual sum-of-squares.

    LinearAlgebra.LAPACK.geev!Function
    geev!(jobvl, jobvr, A) -> (W, VL, VR)

    Finds the eigensystem of A. If jobvl = N, the left eigenvectors of A aren't computed. If jobvr = N, the right eigenvectors of A aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. Returns the eigenvalues in W, the right eigenvectors in VR, and the left eigenvectors in VL.

    LinearAlgebra.LAPACK.gesdd!Function
    gesdd!(job, A) -> (U, S, VT)

    Finds the singular value decomposition of A, A = U * S * V', using a divide and conquer approach. If job = A, all the columns of U and the rows of V' are computed. If job = N, no columns of U or rows of V' are computed. If job = O, A is overwritten with the columns of (thin) U and the rows of (thin) V'. If job = S, the columns of (thin) U and the rows of (thin) V' are computed and returned separately.

    LinearAlgebra.LAPACK.gesvd!Function
    gesvd!(jobu, jobvt, A) -> (U, S, VT)

    Finds the singular value decomposition of A, A = U * S * V'. If jobu = A, all the columns of U are computed. If jobvt = A all the rows of V' are computed. If jobu = N, no columns of U are computed. If jobvt = N no rows of V' are computed. If jobu = O, A is overwritten with the columns of (thin) U. If jobvt = O, A is overwritten with the rows of (thin) V'. If jobu = S, the columns of (thin) U are computed and returned separately. If jobvt = S the rows of (thin) V' are computed and returned separately. jobu and jobvt can't both be O.

    Returns U, S, and Vt, where S are the singular values of A.

    LinearAlgebra.LAPACK.ggsvd!Function
    ggsvd!(jobu, jobv, jobq, A, B) -> (U, V, Q, alpha, beta, k, l, R)

    Finds the generalized singular value decomposition of A and B, U'*A*Q = D1*R and V'*B*Q = D2*R. D1 has alpha on its diagonal and D2 has beta on its diagonal. If jobu = U, the orthogonal/unitary matrix U is computed. If jobv = V the orthogonal/unitary matrix V is computed. If jobq = Q, the orthogonal/unitary matrix Q is computed. If jobu, jobv or jobq is N, that matrix is not computed. This function is only available in LAPACK versions prior to 3.6.0.

    LinearAlgebra.LAPACK.ggsvd3!Function
    ggsvd3!(jobu, jobv, jobq, A, B) -> (U, V, Q, alpha, beta, k, l, R)

    Finds the generalized singular value decomposition of A and B, U'*A*Q = D1*R and V'*B*Q = D2*R. D1 has alpha on its diagonal and D2 has beta on its diagonal. If jobu = U, the orthogonal/unitary matrix U is computed. If jobv = V the orthogonal/unitary matrix V is computed. If jobq = Q, the orthogonal/unitary matrix Q is computed. If jobu, jobv, or jobq is N, that matrix is not computed. This function requires LAPACK 3.6.0.

    LinearAlgebra.LAPACK.geevx!Function
    geevx!(balanc, jobvl, jobvr, sense, A) -> (A, w, VL, VR, ilo, ihi, scale, abnrm, rconde, rcondv)

    Finds the eigensystem of A with matrix balancing. If jobvl = N, the left eigenvectors of A aren't computed. If jobvr = N, the right eigenvectors of A aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. If balanc = N, no balancing is performed. If balanc = P, A is permuted but not scaled. If balanc = S, A is scaled but not permuted. If balanc = B, A is permuted and scaled. If sense = N, no reciprocal condition numbers are computed. If sense = E, reciprocal condition numbers are computed for the eigenvalues only. If sense = V, reciprocal condition numbers are computed for the right eigenvectors only. If sense = B, reciprocal condition numbers are computed for the right eigenvectors and the eigenvectors. If sense = E,B, the right and left eigenvectors must be computed.

    LinearAlgebra.LAPACK.ggev!Function
    ggev!(jobvl, jobvr, A, B) -> (alpha, beta, vl, vr)

    Finds the generalized eigendecomposition of A and B. If jobvl = N, the left eigenvectors aren't computed. If jobvr = N, the right eigenvectors aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed.

    LinearAlgebra.LAPACK.ggev3!Function
    ggev3!(jobvl, jobvr, A, B) -> (alpha, beta, vl, vr)

    Finds the generalized eigendecomposition of A and B using a blocked algorithm. If jobvl = N, the left eigenvectors aren't computed. If jobvr = N, the right eigenvectors aren't computed. If jobvl = V or jobvr = V, the corresponding eigenvectors are computed. This function requires LAPACK 3.6.0.

    LinearAlgebra.LAPACK.gtsv!Function
    gtsv!(dl, d, du, B)

    Solves the equation A * X = B where A is a tridiagonal matrix with dl on the subdiagonal, d on the diagonal, and du on the superdiagonal.

    Overwrites B with the solution X and returns it.

    LinearAlgebra.LAPACK.gttrf!Function
    gttrf!(dl, d, du) -> (dl, d, du, du2, ipiv)

    Finds the LU factorization of a tridiagonal matrix with dl on the subdiagonal, d on the diagonal, and du on the superdiagonal.

    Modifies dl, d, and du in-place and returns them and the second superdiagonal du2 and the pivoting vector ipiv.

    LinearAlgebra.LAPACK.gttrs!Function
    gttrs!(trans, dl, d, du, du2, ipiv, B)

    Solves the equation A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) using the LU factorization computed by gttrf!. B is overwritten with the solution X.

    LinearAlgebra.LAPACK.orglq!Function
    orglq!(A, tau, k = length(tau))

    Explicitly finds the matrix Q of a LQ factorization after calling gelqf! on A. Uses the output of gelqf!. A is overwritten by Q.

    LinearAlgebra.LAPACK.orgqr!Function
    orgqr!(A, tau, k = length(tau))

    Explicitly finds the matrix Q of a QR factorization after calling geqrf! on A. Uses the output of geqrf!. A is overwritten by Q.

    LinearAlgebra.LAPACK.orgql!Function
    orgql!(A, tau, k = length(tau))

    Explicitly finds the matrix Q of a QL factorization after calling geqlf! on A. Uses the output of geqlf!. A is overwritten by Q.

    LinearAlgebra.LAPACK.orgrq!Function
    orgrq!(A, tau, k = length(tau))

    Explicitly finds the matrix Q of a RQ factorization after calling gerqf! on A. Uses the output of gerqf!. A is overwritten by Q.

    LinearAlgebra.LAPACK.ormlq!Function
    ormlq!(side, trans, A, tau, C)

    Computes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a LQ factorization of A computed using gelqf!. C is overwritten.

    LinearAlgebra.LAPACK.ormqr!Function
    ormqr!(side, trans, A, tau, C)

    Computes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QR factorization of A computed using geqrf!. C is overwritten.

    LinearAlgebra.LAPACK.ormql!Function
    ormql!(side, trans, A, tau, C)

    Computes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QL factorization of A computed using geqlf!. C is overwritten.

    LinearAlgebra.LAPACK.ormrq!Function
    ormrq!(side, trans, A, tau, C)

    Computes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a RQ factorization of A computed using gerqf!. C is overwritten.

    LinearAlgebra.LAPACK.gemqrt!Function
    gemqrt!(side, trans, V, T, C)

    Computes Q * C (trans = N), transpose(Q) * C (trans = T), adjoint(Q) * C (trans = C) for side = L or the equivalent right-sided multiplication for side = R using Q from a QR factorization of A computed using geqrt!. C is overwritten.

    LinearAlgebra.LAPACK.posv!Function
    posv!(uplo, A, B) -> (A, B)

    Finds the solution to A * X = B where A is a symmetric or Hermitian positive definite matrix. If uplo = U the upper Cholesky decomposition of A is computed. If uplo = L the lower Cholesky decomposition of A is computed. A is overwritten by its Cholesky decomposition. B is overwritten with the solution X.

    LinearAlgebra.LAPACK.potrf!Function
    potrf!(uplo, A)

    Computes the Cholesky (upper if uplo = U, lower if uplo = L) decomposition of positive-definite matrix A. A is overwritten and returned with an info code.

    LinearAlgebra.LAPACK.potri!Function
    potri!(uplo, A)

    Computes the inverse of positive-definite matrix A after calling potrf! to find its (upper if uplo = U, lower if uplo = L) Cholesky decomposition.

    A is overwritten by its inverse and returned.

    LinearAlgebra.LAPACK.potrs!Function
    potrs!(uplo, A, B)

    Finds the solution to A * X = B where A is a symmetric or Hermitian positive definite matrix whose Cholesky decomposition was computed by potrf!. If uplo = U the upper Cholesky decomposition of A was computed. If uplo = L the lower Cholesky decomposition of A was computed. B is overwritten with the solution X.

    LinearAlgebra.LAPACK.pstrf!Function
    pstrf!(uplo, A, tol) -> (A, piv, rank, info)

    Computes the (upper if uplo = U, lower if uplo = L) pivoted Cholesky decomposition of positive-definite matrix A with a user-set tolerance tol. A is overwritten by its Cholesky decomposition.

    Returns A, the pivots piv, the rank of A, and an info code. If info = 0, the factorization succeeded. If info = i > 0, then A is indefinite or rank-deficient.

    LinearAlgebra.LAPACK.ptsv!Function
    ptsv!(D, E, B)

    Solves A * X = B for positive-definite tridiagonal A. D is the diagonal of A and E is the off-diagonal. B is overwritten with the solution X and returned.

    LinearAlgebra.LAPACK.pttrf!Function
    pttrf!(D, E)

    Computes the LDLt factorization of a positive-definite tridiagonal matrix with D as diagonal and E as off-diagonal. D and E are overwritten and returned.

    LinearAlgebra.LAPACK.pttrs!Function
    pttrs!(D, E, B)

    Solves A * X = B for positive-definite tridiagonal A with diagonal D and off-diagonal E after computing A's LDLt factorization using pttrf!. B is overwritten with the solution X.

    LinearAlgebra.LAPACK.trtri!Function
    trtri!(uplo, diag, A)

    Finds the inverse of (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. A is overwritten with its inverse.

    LinearAlgebra.LAPACK.trtrs!Function
    trtrs!(uplo, trans, diag, A, B)

    Solves A * X = B (trans = N), transpose(A) * X = B (trans = T), or adjoint(A) * X = B (trans = C) for (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. B is overwritten with the solution X.

    LinearAlgebra.LAPACK.trcon!Function
    trcon!(norm, uplo, diag, A)

    Finds the reciprocal condition number of (upper if uplo = U, lower if uplo = L) triangular matrix A. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. If norm = I, the condition number is found in the infinity norm. If norm = O or 1, the condition number is found in the one norm.

    LinearAlgebra.LAPACK.trevc!Function
    trevc!(side, howmny, select, T, VL = similar(T), VR = similar(T))

    Finds the eigensystem of an upper triangular matrix T. If side = R, the right eigenvectors are computed. If side = L, the left eigenvectors are computed. If side = B, both sets are computed. If howmny = A, all eigenvectors are found. If howmny = B, all eigenvectors are found and backtransformed using VL and VR. If howmny = S, only the eigenvectors corresponding to the values in select are computed.

    LinearAlgebra.LAPACK.trrfs!Function
    trrfs!(uplo, trans, diag, A, B, X, Ferr, Berr) -> (Ferr, Berr)

    Estimates the error in the solution to A * X = B (trans = N), transpose(A) * X = B (trans = T), adjoint(A) * X = B (trans = C) for side = L, or the equivalent equations a right-handed side = R X * A after computing X using trtrs!. If uplo = U, A is upper triangular. If uplo = L, A is lower triangular. If diag = N, A has non-unit diagonal elements. If diag = U, all diagonal elements of A are one. Ferr and Berr are optional inputs. Ferr is the forward error and Berr is the backward error, each component-wise.

    LinearAlgebra.LAPACK.stev!Function
    stev!(job, dv, ev) -> (dv, Zmat)

    Computes the eigensystem for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If job = N only the eigenvalues are found and returned in dv. If job = V then the eigenvectors are also found and returned in Zmat.

    LinearAlgebra.LAPACK.stebz!Function
    stebz!(range, order, vl, vu, il, iu, abstol, dv, ev) -> (dv, iblock, isplit)

    Computes the eigenvalues for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. If order = B, eigvalues are ordered within a block. If order = E, they are ordered across all the blocks. abstol can be set as a tolerance for convergence.

    LinearAlgebra.LAPACK.stegr!Function
    stegr!(jobz, range, dv, ev, vl, vu, il, iu) -> (w, Z)

    Computes the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) for a symmetric tridiagonal matrix with dv as diagonal and ev as off-diagonal. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. The eigenvalues are returned in w and the eigenvectors in Z.

    LinearAlgebra.LAPACK.stein!Function
    stein!(dv, ev_in, w_in, iblock_in, isplit_in)

    Computes the eigenvectors for a symmetric tridiagonal matrix with dv as diagonal and ev_in as off-diagonal. w_in specifies the input eigenvalues for which to find corresponding eigenvectors. iblock_in specifies the submatrices corresponding to the eigenvalues in w_in. isplit_in specifies the splitting points between the submatrix blocks.

    LinearAlgebra.LAPACK.syconv!Function
    syconv!(uplo, A, ipiv) -> (A, work)

    Converts a symmetric matrix A (which has been factorized into a triangular matrix) into two matrices L and D. If uplo = U, A is upper triangular. If uplo = L, it is lower triangular. ipiv is the pivot vector from the triangular factorization. A is overwritten by L and D.

    LinearAlgebra.LAPACK.sysv!Function
    sysv!(uplo, A, B) -> (B, A, ipiv)

    Finds the solution to A * X = B for symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X. A is overwritten by its Bunch-Kaufman factorization. ipiv contains pivoting information about the factorization.

    LinearAlgebra.LAPACK.sytrf!Function
    sytrf!(uplo, A) -> (A, ipiv, info)

    Computes the Bunch-Kaufman factorization of a symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.

    Returns A, overwritten by the factorization, a pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.

    sytrf!(uplo, A, ipiv) -> (A, ipiv, info)

    Computes the Bunch-Kaufman factorization of a symmetric matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.

    Returns A, overwritten by the factorization, the pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.

    LinearAlgebra.LAPACK.sytri!Function
    sytri!(uplo, A, ipiv)

    Computes the inverse of a symmetric matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. A is overwritten by its inverse.

    LinearAlgebra.LAPACK.sytrs!Function
    sytrs!(uplo, A, ipiv, B)

    Solves the equation A * X = B for a symmetric matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X.

    LinearAlgebra.LAPACK.hesv!Function
    hesv!(uplo, A, B) -> (B, A, ipiv)

    Finds the solution to A * X = B for Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X. A is overwritten by its Bunch-Kaufman factorization. ipiv contains pivoting information about the factorization.

    LinearAlgebra.LAPACK.hetrf!Function
    hetrf!(uplo, A) -> (A, ipiv, info)

    Computes the Bunch-Kaufman factorization of a Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.

    Returns A, overwritten by the factorization, a pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.

    hetrf!(uplo, A, ipiv) -> (A, ipiv, info)

    Computes the Bunch-Kaufman factorization of a Hermitian matrix A. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored.

    Returns A, overwritten by the factorization, the pivot vector ipiv, and the error code info which is a non-negative integer. If info is positive the matrix is singular and the diagonal part of the factorization is exactly zero at position info.

    LinearAlgebra.LAPACK.hetri!Function
    hetri!(uplo, A, ipiv)

    Computes the inverse of a Hermitian matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. A is overwritten by its inverse.

    LinearAlgebra.LAPACK.hetrs!Function
    hetrs!(uplo, A, ipiv, B)

    Solves the equation A * X = B for a Hermitian matrix A using the results of sytrf!. If uplo = U, the upper half of A is stored. If uplo = L, the lower half is stored. B is overwritten by the solution X.

    LinearAlgebra.LAPACK.syev!Function
    syev!(jobz, uplo, A)

    Finds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used.

    LinearAlgebra.LAPACK.syevr!Function
    syevr!(jobz, range, uplo, A, vl, vu, il, iu, abstol) -> (W, Z)

    Finds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used. If range = A, all the eigenvalues are found. If range = V, the eigenvalues in the half-open interval (vl, vu] are found. If range = I, the eigenvalues with indices between il and iu are found. abstol can be set as a tolerance for convergence.

    The eigenvalues are returned in W and the eigenvectors in Z.

    LinearAlgebra.LAPACK.syevd!Function
    syevd!(jobz, uplo, A)

    Finds the eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A. If uplo = U, the upper triangle of A is used. If uplo = L, the lower triangle of A is used.

    Use the divide-and-conquer method, instead of the QR iteration used by syev! or multiple relatively robust representations used by syevr!. See James W. Demmel et al, SIAM J. Sci. Comput. 30, 3, 1508 (2008) for a comparison of the accuracy and performatce of different methods.

    LinearAlgebra.LAPACK.sygvd!Function
    sygvd!(itype, jobz, uplo, A, B) -> (w, A, B)

    Finds the generalized eigenvalues (jobz = N) or eigenvalues and eigenvectors (jobz = V) of a symmetric matrix A and symmetric positive-definite matrix B. If uplo = U, the upper triangles of A and B are used. If uplo = L, the lower triangles of A and B are used. If itype = 1, the problem to solve is A * x = lambda * B * x. If itype = 2, the problem to solve is A * B * x = lambda * x. If itype = 3, the problem to solve is B * A * x = lambda * x.

    LinearAlgebra.LAPACK.bdsqr!Function
    bdsqr!(uplo, d, e_, Vt, U, C) -> (d, Vt, U, C)

    Computes the singular value decomposition of a bidiagonal matrix with d on the diagonal and e_ on the off-diagonal. If uplo = U, e_ is the superdiagonal. If uplo = L, e_ is the subdiagonal. Can optionally also compute the product Q' * C.

    Returns the singular values in d, and the matrix C overwritten with Q' * C.

    LinearAlgebra.LAPACK.bdsdc!Function
    bdsdc!(uplo, compq, d, e_) -> (d, e, u, vt, q, iq)

    Computes the singular value decomposition of a bidiagonal matrix with d on the diagonal and e_ on the off-diagonal using a divide and conqueq method. If uplo = U, e_ is the superdiagonal. If uplo = L, e_ is the subdiagonal. If compq = N, only the singular values are found. If compq = I, the singular values and vectors are found. If compq = P, the singular values and vectors are found in compact form. Only works for real types.

    Returns the singular values in d, and if compq = P, the compact singular vectors in iq.

    LinearAlgebra.LAPACK.gecon!Function
    gecon!(normtype, A, anorm)

    Finds the reciprocal condition number of matrix A. If normtype = I, the condition number is found in the infinity norm. If normtype = O or 1, the condition number is found in the one norm. A must be the result of getrf! and anorm is the norm of A in the relevant norm.

    LinearAlgebra.LAPACK.gehrd!Function
    gehrd!(ilo, ihi, A) -> (A, tau)

    Converts a matrix A to Hessenberg form. If A is balanced with gebal! then ilo and ihi are the outputs of gebal!. Otherwise they should be ilo = 1 and ihi = size(A,2). tau contains the elementary reflectors of the factorization.

    LinearAlgebra.LAPACK.orghr!Function
    orghr!(ilo, ihi, A, tau)

    Explicitly finds Q, the orthogonal/unitary matrix from gehrd!. ilo, ihi, A, and tau must correspond to the input/output to gehrd!.

    LinearAlgebra.LAPACK.gees!Function
    gees!(jobvs, A) -> (A, vs, w)

    Computes the eigenvalues (jobvs = N) or the eigenvalues and Schur vectors (jobvs = V) of matrix A. A is overwritten by its Schur form.

    Returns A, vs containing the Schur vectors, and w, containing the eigenvalues.

    LinearAlgebra.LAPACK.gges!Function
    gges!(jobvsl, jobvsr, A, B) -> (A, B, alpha, beta, vsl, vsr)

    Computes the generalized eigenvalues, generalized Schur form, left Schur vectors (jobsvl = V), or right Schur vectors (jobvsr = V) of A and B.

    The generalized eigenvalues are returned in alpha and beta. The left Schur vectors are returned in vsl and the right Schur vectors are returned in vsr.

    LinearAlgebra.LAPACK.gges3!Function
    gges3!(jobvsl, jobvsr, A, B) -> (A, B, alpha, beta, vsl, vsr)

    Computes the generalized eigenvalues, generalized Schur form, left Schur vectors (jobsvl = V), or right Schur vectors (jobvsr = V) of A and B using a blocked algorithm. This function requires LAPACK 3.6.0.

    The generalized eigenvalues are returned in alpha and beta. The left Schur vectors are returned in vsl and the right Schur vectors are returned in vsr.

    LinearAlgebra.LAPACK.trexc!Function
    trexc!(compq, ifst, ilst, T, Q) -> (T, Q)
     trexc!(ifst, ilst, T, Q) -> (T, Q)

    Reorder the Schur factorization T of a matrix, such that the diagonal block of T with row index ifst is moved to row index ilst. If compq = V, the Schur vectors Q are reordered. If compq = N they are not modified. The 4-arg method calls the 5-arg method with compq = V.

    LinearAlgebra.LAPACK.trsen!Function
    trsen!(job, compq, select, T, Q) -> (T, Q, w, s, sep)
    -trsen!(select, T, Q) -> (T, Q, w, s, sep)

    Reorder the Schur factorization of a matrix and optionally finds reciprocal condition numbers. If job = N, no condition numbers are found. If job = E, only the condition number for this cluster of eigenvalues is found. If job = V, only the condition number for the invariant subspace is found. If job = B then the condition numbers for the cluster and subspace are found. If compq = V the Schur vectors Q are updated. If compq = N the Schur vectors are not modified. select determines which eigenvalues are in the cluster. The 3-arg method calls the 5-arg method with job = N and compq = V.

    Returns T, Q, reordered eigenvalues in w, the condition number of the cluster of eigenvalues s, and the condition number of the invariant subspace sep.

    LinearAlgebra.LAPACK.tgsen!Function
    tgsen!(select, S, T, Q, Z) -> (S, T, alpha, beta, Q, Z)

    Reorders the vectors of a generalized Schur decomposition. select specifies the eigenvalues in each cluster.

    LinearAlgebra.LAPACK.trsyl!Function
    trsyl!(transa, transb, A, B, C, isgn=1) -> (C, scale)

    Solves the Sylvester matrix equation A * X +/- X * B = scale*C where A and B are both quasi-upper triangular. If transa = N, A is not modified. If transa = T, A is transposed. If transa = C, A is conjugate transposed. Similarly for transb and B. If isgn = 1, the equation A * X + X * B = scale * C is solved. If isgn = -1, the equation A * X - X * B = scale * C is solved.

    Returns X (overwriting C) and scale.

    LinearAlgebra.LAPACK.hseqr!Function
    hseqr!(job, compz, ilo, ihi, H, Z) -> (H, Z, w)

    Computes all eigenvalues and (optionally) the Schur factorization of a matrix reduced to Hessenberg form. If H is balanced with gebal! then ilo and ihi are the outputs of gebal!. Otherwise they should be ilo = 1 and ihi = size(H,2). tau contains the elementary reflectors of the factorization.

    • ACM832Davis, Timothy A. (2004b). Algorithm 832: UMFPACK V4.3–-an Unsymmetric-Pattern Multifrontal Method. ACM Trans. Math. Softw., 30(2), 196–199. doi:10.1145/992200.992206
    • ACM887Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008). Algorithm 887: CHOLMOD, Supernodal Sparse Cholesky Factorization and Update/Downdate. ACM Trans. Math. Softw., 35(3). doi:10.1145/1391989.1391995
    • DavisHager2009Davis, Timothy A., & Hager, W. W. (2009). Dynamic Supernodes in Sparse Cholesky Update/Downdate and Triangular Solves. ACM Trans. Math. Softw., 35(4). doi:10.1145/1462173.1462176
    • Bischof1987C Bischof and C Van Loan, "The WY representation for products of Householder matrices", SIAM J Sci Stat Comput 8 (1987), s2-s13. doi:10.1137/0908009
    • Schreiber1989R Schreiber and C Van Loan, "A storage-efficient WY representation for products of Householder transformations", SIAM J Sci Stat Comput 10 (1989), 53-57. doi:10.1137/0910005
    • ACM933Foster, L. V., & Davis, T. A. (2013). Algorithm 933: Reliable Calculation of Numerical Rank, Null Space Bases, Pseudoinverse Solutions, and Basic Solutions Using SuitesparseQR. ACM Trans. Math. Softw., 40(1). doi:10.1145/2513109.2513116
    • Bunch1977J R Bunch and L Kaufman, Some stable methods for calculating inertia and solving symmetric linear systems, Mathematics of Computation 31:137 (1977), 163-179. url.
    • issue8859Issue 8859, "Fix least squares", https://github.com/JuliaLang/julia/pull/8859
    • B96Åke Björck, "Numerical Methods for Least Squares Problems", SIAM Press, Philadelphia, 1996, "Other Titles in Applied Mathematics", Vol. 51. doi:10.1137/1.9781611971484
    • S84G. W. Stewart, "Rank Degeneracy", SIAM Journal on Scientific and Statistical Computing, 5(2), 1984, 403-413. doi:10.1137/0905030
    • KY88Konstantinos Konstantinides and Kung Yao, "Statistical analysis of effective singular values in matrix rank determination", IEEE Transactions on Acoustics, Speech and Signal Processing, 36(5), 1988, 757-763. doi:10.1109/29.1585
    • H05Nicholas J. Higham, "The squaring and scaling method for the matrix exponential revisited", SIAM Journal on Matrix Analysis and Applications, 26(4), 2005, 1179-1193. doi:10.1137/090768539
    • AH12Awad H. Al-Mohy and Nicholas J. Higham, "Improved inverse scaling and squaring algorithms for the matrix logarithm", SIAM Journal on Scientific Computing, 34(4), 2012, C153-C169. doi:10.1137/110852553
    • AHR13Awad H. Al-Mohy, Nicholas J. Higham and Samuel D. Relton, "Computing the Fréchet derivative of the matrix logarithm and estimating the condition number", SIAM Journal on Scientific Computing, 35(4), 2013, C394-C410. doi:10.1137/120885991
    • BH83Åke Björck and Sven Hammarling, "A Schur method for the square root of a matrix", Linear Algebra and its Applications, 52-53, 1983, 127-140. doi:10.1016/0024-3795(83)80010-X
    • H87Nicholas J. Higham, "Computing real square roots of a real matrix", Linear Algebra and its Applications, 88-89, 1987, 405-430. doi:10.1016/0024-3795(87)90118-2
    • S03Matthew I. Smith, "A Schur Algorithm for Computing Matrix pth Roots", SIAM Journal on Matrix Analysis and Applications, vol. 24, 2003, pp. 971–989. doi:10.1137/S0895479801392697
    • AH16_1Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_2Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_3Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_4Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_5Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_6Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    +trsen!(select, T, Q) -> (T, Q, w, s, sep)

    Reorder the Schur factorization of a matrix and optionally finds reciprocal condition numbers. If job = N, no condition numbers are found. If job = E, only the condition number for this cluster of eigenvalues is found. If job = V, only the condition number for the invariant subspace is found. If job = B then the condition numbers for the cluster and subspace are found. If compq = V the Schur vectors Q are updated. If compq = N the Schur vectors are not modified. select determines which eigenvalues are in the cluster. The 3-arg method calls the 5-arg method with job = N and compq = V.

    Returns T, Q, reordered eigenvalues in w, the condition number of the cluster of eigenvalues s, and the condition number of the invariant subspace sep.

    LinearAlgebra.LAPACK.tgsen!Function
    tgsen!(select, S, T, Q, Z) -> (S, T, alpha, beta, Q, Z)

    Reorders the vectors of a generalized Schur decomposition. select specifies the eigenvalues in each cluster.

    LinearAlgebra.LAPACK.trsyl!Function
    trsyl!(transa, transb, A, B, C, isgn=1) -> (C, scale)

    Solves the Sylvester matrix equation A * X +/- X * B = scale*C where A and B are both quasi-upper triangular. If transa = N, A is not modified. If transa = T, A is transposed. If transa = C, A is conjugate transposed. Similarly for transb and B. If isgn = 1, the equation A * X + X * B = scale * C is solved. If isgn = -1, the equation A * X - X * B = scale * C is solved.

    Returns X (overwriting C) and scale.

    LinearAlgebra.LAPACK.hseqr!Function
    hseqr!(job, compz, ilo, ihi, H, Z) -> (H, Z, w)

    Computes all eigenvalues and (optionally) the Schur factorization of a matrix reduced to Hessenberg form. If H is balanced with gebal! then ilo and ihi are the outputs of gebal!. Otherwise they should be ilo = 1 and ihi = size(H,2). tau contains the elementary reflectors of the factorization.

    • ACM832Davis, Timothy A. (2004b). Algorithm 832: UMFPACK V4.3–-an Unsymmetric-Pattern Multifrontal Method. ACM Trans. Math. Softw., 30(2), 196–199. doi:10.1145/992200.992206
    • ACM887Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008). Algorithm 887: CHOLMOD, Supernodal Sparse Cholesky Factorization and Update/Downdate. ACM Trans. Math. Softw., 35(3). doi:10.1145/1391989.1391995
    • DavisHager2009Davis, Timothy A., & Hager, W. W. (2009). Dynamic Supernodes in Sparse Cholesky Update/Downdate and Triangular Solves. ACM Trans. Math. Softw., 35(4). doi:10.1145/1462173.1462176
    • Bischof1987C Bischof and C Van Loan, "The WY representation for products of Householder matrices", SIAM J Sci Stat Comput 8 (1987), s2-s13. doi:10.1137/0908009
    • Schreiber1989R Schreiber and C Van Loan, "A storage-efficient WY representation for products of Householder transformations", SIAM J Sci Stat Comput 10 (1989), 53-57. doi:10.1137/0910005
    • ACM933Foster, L. V., & Davis, T. A. (2013). Algorithm 933: Reliable Calculation of Numerical Rank, Null Space Bases, Pseudoinverse Solutions, and Basic Solutions Using SuitesparseQR. ACM Trans. Math. Softw., 40(1). doi:10.1145/2513109.2513116
    • Bunch1977J R Bunch and L Kaufman, Some stable methods for calculating inertia and solving symmetric linear systems, Mathematics of Computation 31:137 (1977), 163-179. url.
    • issue8859Issue 8859, "Fix least squares", https://github.com/JuliaLang/julia/pull/8859
    • B96Åke Björck, "Numerical Methods for Least Squares Problems", SIAM Press, Philadelphia, 1996, "Other Titles in Applied Mathematics", Vol. 51. doi:10.1137/1.9781611971484
    • S84G. W. Stewart, "Rank Degeneracy", SIAM Journal on Scientific and Statistical Computing, 5(2), 1984, 403-413. doi:10.1137/0905030
    • KY88Konstantinos Konstantinides and Kung Yao, "Statistical analysis of effective singular values in matrix rank determination", IEEE Transactions on Acoustics, Speech and Signal Processing, 36(5), 1988, 757-763. doi:10.1109/29.1585
    • H05Nicholas J. Higham, "The squaring and scaling method for the matrix exponential revisited", SIAM Journal on Matrix Analysis and Applications, 26(4), 2005, 1179-1193. doi:10.1137/090768539
    • AH12Awad H. Al-Mohy and Nicholas J. Higham, "Improved inverse scaling and squaring algorithms for the matrix logarithm", SIAM Journal on Scientific Computing, 34(4), 2012, C153-C169. doi:10.1137/110852553
    • AHR13Awad H. Al-Mohy, Nicholas J. Higham and Samuel D. Relton, "Computing the Fréchet derivative of the matrix logarithm and estimating the condition number", SIAM Journal on Scientific Computing, 35(4), 2013, C394-C410. doi:10.1137/120885991
    • BH83Åke Björck and Sven Hammarling, "A Schur method for the square root of a matrix", Linear Algebra and its Applications, 52-53, 1983, 127-140. doi:10.1016/0024-3795(83)80010-X
    • H87Nicholas J. Higham, "Computing real square roots of a real matrix", Linear Algebra and its Applications, 88-89, 1987, 405-430. doi:10.1016/0024-3795(87)90118-2
    • S03Matthew I. Smith, "A Schur Algorithm for Computing Matrix pth Roots", SIAM Journal on Matrix Analysis and Applications, vol. 24, 2003, pp. 971–989. doi:10.1137/S0895479801392697
    • AH16_1Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_2Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_3Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_4Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_5Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    • AH16_6Mary Aprahamian and Nicholas J. Higham, "Matrix Inverse Trigonometric and Inverse Hyperbolic Functions: Theory and Algorithms", MIMS EPrint: 2016.4. https://doi.org/10.1137/16M1057577
    diff --git a/en/v1.12-dev/stdlib/Logging/index.html b/en/v1.12-dev/stdlib/Logging/index.html index 969055ee3cb6..c5ea6d6f683e 100644 --- a/en/v1.12-dev/stdlib/Logging/index.html +++ b/en/v1.12-dev/stdlib/Logging/index.html @@ -93,13 +93,13 @@ for i=1:10000 @info "With the default backend, you will only see (i = $i) ten times" maxlog=10 @debug "Algorithm1" i progress=i/10000 -endsource
    Logging.LogLevelType
    LogLevel(level)

    Severity/verbosity of a log record.

    The log level provides a key against which potential log records may be filtered, before any other work is done to construct the log record data structure itself.

    Examples

    julia> Logging.LogLevel(0) == Logging.Info
    -true
    source

    Processing events with AbstractLogger

    Event processing is controlled by overriding functions associated with AbstractLogger:

    Methods to implementBrief description
    Logging.handle_messageHandle a log event
    Logging.shouldlogEarly filtering of events
    Logging.min_enabled_levelLower bound for log level of accepted events
    Optional methodsDefault definitionBrief description
    Logging.catch_exceptionstrueCatch exceptions during event evaluation
    Logging.AbstractLoggerType

    A logger controls how log records are filtered and dispatched. When a log record is generated, the logger is the first piece of user configurable code which gets to inspect the record and decide what to do with it.

    source
    Logging.handle_messageFunction
    handle_message(logger, level, message, _module, group, id, file, line; key1=val1, ...)

    Log a message to logger at level. The logical location at which the message was generated is given by module _module and group; the source location by file and line. id is an arbitrary unique value (typically a Symbol) to be used as a key to identify the log statement when filtering.

    source
    Logging.shouldlogFunction
    shouldlog(logger, level, _module, group, id)

    Return true when logger accepts a message at level, generated for _module, group and with unique log identifier id.

    source
    Logging.min_enabled_levelFunction
    min_enabled_level(logger)

    Return the minimum enabled level for logger for early filtering. That is, the log level below or equal to which all messages are filtered.

    source
    Logging.catch_exceptionsFunction
    catch_exceptions(logger)

    Return true if the logger should catch exceptions which happen during log record construction. By default, messages are caught

    By default all exceptions are caught to prevent log message generation from crashing the program. This lets users confidently toggle little-used functionality - such as debug logging - in a production system.

    If you want to use logging as an audit trail you should disable this for your logger type.

    source
    Logging.disable_loggingFunction
    disable_logging(level)

    Disable all log messages at log levels equal to or less than level. This is a global setting, intended to make debug logging extremely cheap when disabled.

    Examples

    Logging.disable_logging(Logging.Info) # Disable debug and info
    source

    Using Loggers

    Logger installation and inspection:

    Logging.global_loggerFunction
    global_logger()

    Return the global logger, used to receive messages when no specific logger exists for the current task.

    global_logger(logger)

    Set the global logger to logger, and return the previous global logger.

    source
    Logging.with_loggerFunction
    with_logger(function, logger)

    Execute function, directing all log messages to logger.

    Examples

    function test(x)
    +end
    source
    Logging.LogLevelType
    LogLevel(level)

    Severity/verbosity of a log record.

    The log level provides a key against which potential log records may be filtered, before any other work is done to construct the log record data structure itself.

    Examples

    julia> Logging.LogLevel(0) == Logging.Info
    +true
    source

    Processing events with AbstractLogger

    Event processing is controlled by overriding functions associated with AbstractLogger:

    Methods to implementBrief description
    Logging.handle_messageHandle a log event
    Logging.shouldlogEarly filtering of events
    Logging.min_enabled_levelLower bound for log level of accepted events
    Optional methodsDefault definitionBrief description
    Logging.catch_exceptionstrueCatch exceptions during event evaluation
    Logging.AbstractLoggerType

    A logger controls how log records are filtered and dispatched. When a log record is generated, the logger is the first piece of user configurable code which gets to inspect the record and decide what to do with it.

    source
    Logging.handle_messageFunction
    handle_message(logger, level, message, _module, group, id, file, line; key1=val1, ...)

    Log a message to logger at level. The logical location at which the message was generated is given by module _module and group; the source location by file and line. id is an arbitrary unique value (typically a Symbol) to be used as a key to identify the log statement when filtering.

    source
    Logging.shouldlogFunction
    shouldlog(logger, level, _module, group, id)

    Return true when logger accepts a message at level, generated for _module, group and with unique log identifier id.

    source
    Logging.min_enabled_levelFunction
    min_enabled_level(logger)

    Return the minimum enabled level for logger for early filtering. That is, the log level below or equal to which all messages are filtered.

    source
    Logging.catch_exceptionsFunction
    catch_exceptions(logger)

    Return true if the logger should catch exceptions which happen during log record construction. By default, messages are caught

    By default all exceptions are caught to prevent log message generation from crashing the program. This lets users confidently toggle little-used functionality - such as debug logging - in a production system.

    If you want to use logging as an audit trail you should disable this for your logger type.

    source
    Logging.disable_loggingFunction
    disable_logging(level)

    Disable all log messages at log levels equal to or less than level. This is a global setting, intended to make debug logging extremely cheap when disabled.

    Examples

    Logging.disable_logging(Logging.Info) # Disable debug and info
    source

    Using Loggers

    Logger installation and inspection:

    Logging.global_loggerFunction
    global_logger()

    Return the global logger, used to receive messages when no specific logger exists for the current task.

    global_logger(logger)

    Set the global logger to logger, and return the previous global logger.

    source
    Logging.with_loggerFunction
    with_logger(function, logger)

    Execute function, directing all log messages to logger.

    Examples

    function test(x)
         @info "x = $x"
     end
     
     with_logger(logger) do
         test(1)
         test([1,2])
    -end
    source
    Logging.current_loggerFunction
    current_logger()

    Return the logger for the current task, or the global logger if none is attached to the task.

    source

    Loggers that are supplied with the system:

    Logging.NullLoggerType
    NullLogger()

    Logger which disables all messages and produces no output - the logger equivalent of /dev/null.

    source
    Logging.ConsoleLoggerType
    ConsoleLogger([stream,] min_level=Info; meta_formatter=default_metafmt,
    -              show_limited=true, right_justify=0)

    Logger with formatting optimized for readability in a text console, for example interactive work with the Julia REPL.

    Log levels less than min_level are filtered out.

    Message formatting can be controlled by setting keyword arguments:

    • meta_formatter is a function which takes the log event metadata (level, _module, group, id, file, line) and returns a face name (used in the constructed AnnotatedString), prefix and suffix for the log message. The default is to prefix with the log level and a suffix containing the module, file and line location.
    • show_limited limits the printing of large data structures to something which can fit on the screen by setting the :limit IOContext key during formatting.
    • right_justify is the integer column which log metadata is right justified at. The default is zero (metadata goes on its own line).
    Logging.SimpleLoggerType
    SimpleLogger([stream,] min_level=Info)

    Simplistic logger for logging all messages with level greater than or equal to min_level to stream. If stream is closed then messages with log level greater or equal to Warn will be logged to stderr and below to stdout.

    source
    +endsource
    Logging.current_loggerFunction
    current_logger()

    Return the logger for the current task, or the global logger if none is attached to the task.

    source

    Loggers that are supplied with the system:

    Logging.NullLoggerType
    NullLogger()

    Logger which disables all messages and produces no output - the logger equivalent of /dev/null.

    source
    Logging.ConsoleLoggerType
    ConsoleLogger([stream,] min_level=Info; meta_formatter=default_metafmt,
    +              show_limited=true, right_justify=0)

    Logger with formatting optimized for readability in a text console, for example interactive work with the Julia REPL.

    Log levels less than min_level are filtered out.

    Message formatting can be controlled by setting keyword arguments:

    • meta_formatter is a function which takes the log event metadata (level, _module, group, id, file, line) and returns a face name (used in the constructed AnnotatedString), prefix and suffix for the log message. The default is to prefix with the log level and a suffix containing the module, file and line location.
    • show_limited limits the printing of large data structures to something which can fit on the screen by setting the :limit IOContext key during formatting.
    • right_justify is the integer column which log metadata is right justified at. The default is zero (metadata goes on its own line).
    Logging.SimpleLoggerType
    SimpleLogger([stream,] min_level=Info)

    Simplistic logger for logging all messages with level greater than or equal to min_level to stream. If stream is closed then messages with log level greater or equal to Warn will be logged to stderr and below to stdout.

    source
    diff --git a/en/v1.12-dev/stdlib/Markdown/index.html b/en/v1.12-dev/stdlib/Markdown/index.html index 43f2fab1de1d..3c7de0578e29 100644 --- a/en/v1.12-dev/stdlib/Markdown/index.html +++ b/en/v1.12-dev/stdlib/Markdown/index.html @@ -114,4 +114,4 @@ Markdown.MD
    Markdown.htmlFunction
    html([io::IO], md)

    Output the contents of the Markdown object md in HTML format, either writing to an (optional) io stream or returning a string.

    One can alternatively use show(io, "text/html", md) or repr("text/html", md), which differ in that they wrap the output in a <div class="markdown"> ... </div> element.

    Examples

    julia> html(md"hello _world_")
     "<p>hello <em>world</em></p>\n"
    Markdown.latexFunction
    latex([io::IO], md)

    Output the contents of the Markdown object md in LaTeX format, either writing to an (optional) io stream or returning a string.

    One can alternatively use show(io, "text/latex", md) or repr("text/latex", md).

    Examples

    julia> latex(md"hello _world_")
    -"hello \\emph{world}\n\n"
    +"hello \\emph{world}\n\n" diff --git a/en/v1.12-dev/stdlib/Mmap/index.html b/en/v1.12-dev/stdlib/Mmap/index.html index 1d215f0c58fe..629b07e91829 100644 --- a/en/v1.12-dev/stdlib/Mmap/index.html +++ b/en/v1.12-dev/stdlib/Mmap/index.html @@ -55,4 +55,4 @@ julia> close(io) -julia> rm("mmap.bin")

    This creates a 25-by-30000 BitArray, linked to the file associated with stream io.

    Mmap.sync!Function
    Mmap.sync!(array)

    Forces synchronization between the in-memory version of a memory-mapped Array or BitArray and the on-disk version.

    +julia> rm("mmap.bin")

    This creates a 25-by-30000 BitArray, linked to the file associated with stream io.

    Mmap.sync!Function
    Mmap.sync!(array)

    Forces synchronization between the in-memory version of a memory-mapped Array or BitArray and the on-disk version.

    diff --git a/en/v1.12-dev/stdlib/NetworkOptions/index.html b/en/v1.12-dev/stdlib/NetworkOptions/index.html index 293a67e92ce3..e65edabcd371 100644 --- a/en/v1.12-dev/stdlib/NetworkOptions/index.html +++ b/en/v1.12-dev/stdlib/NetworkOptions/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Network Options

    NetworkOptions.ca_rootsFunction
    ca_roots() :: Union{Nothing, String}

    The ca_roots() function tells the caller where, if anywhere, to find a file or directory of PEM-encoded certificate authority roots. By default, on systems like Windows and macOS where the built-in TLS engines know how to verify hosts using the system's built-in certificate verification mechanism, this function will return nothing. On classic UNIX systems (excluding macOS), root certificates are typically stored in a file in /etc: the common places for the current UNIX system will be searched and if one of these paths exists, it will be returned; if none of these typical root certificate paths exist, then the path to the set of root certificates that are bundled with Julia is returned.

    The default value returned by ca_roots() may be overridden by setting the JULIA_SSL_CA_ROOTS_PATH, SSL_CERT_DIR, or SSL_CERT_FILE environment variables, in which case this function will always return the value of the first of these variables that is set (whether the path exists or not). If JULIA_SSL_CA_ROOTS_PATH is set to the empty string, then the other variables are ignored (as if unset); if the other variables are set to the empty string, they behave is if they are not set.

    NetworkOptions.ca_roots_pathFunction
    ca_roots_path() :: String

    The ca_roots_path() function is similar to the ca_roots() function except that it always returns a path to a file or directory of PEM-encoded certificate authority roots. When called on a system like Windows or macOS, where system root certificates are not stored in the file system, it will currently return the path to the set of root certificates that are bundled with Julia. (In the future, this function may instead extract the root certificates from the system and save them to a file whose path would be returned.)

    If it is possible to configure a library that uses TLS to use the system certificates that is generally preferable: i.e. it is better to use ca_roots() which returns nothing to indicate that the system certs should be used. The ca_roots_path() function should only be used when configuring libraries which require a path to a file or directory for root certificates.

    The default value returned by ca_roots_path() may be overridden by setting the JULIA_SSL_CA_ROOTS_PATH, SSL_CERT_DIR, or SSL_CERT_FILE environment variables, in which case this function will always return the value of the first of these variables that is set (whether the path exists or not). If JULIA_SSL_CA_ROOTS_PATH is set to the empty string, then the other variables are ignored (as if unset); if the other variables are set to the empty string, they behave is if they are not set.

    NetworkOptions.ssh_dirFunction
    ssh_dir() :: String

    The ssh_dir() function returns the location of the directory where the ssh program keeps/looks for configuration files. By default this is ~/.ssh but this can be overridden by setting the environment variable SSH_DIR.

    NetworkOptions.ssh_key_passFunction
    ssh_key_pass() :: String

    The ssh_key_pass() function returns the value of the environment variable SSH_KEY_PASS if it is set or nothing if it is not set. In the future, this may be able to find a password by other means, such as secure system storage, so packages that need a password to decrypt an SSH private key should use this API instead of directly checking the environment variable so that they gain such capabilities automatically when they are added.

    NetworkOptions.ssh_key_nameFunction
    ssh_key_name() :: String

    The ssh_key_name() function returns the base name of key files that SSH should use for when establishing a connection. There is usually no reason that this function should be called directly and libraries should generally use the ssh_key_path and ssh_pub_key_path functions to get full paths. If the environment variable SSH_KEY_NAME is set then this function returns that; otherwise it returns id_rsa by default.

    NetworkOptions.ssh_key_pathFunction
    ssh_key_path() :: String

    The ssh_key_path() function returns the path of the SSH private key file that should be used for SSH connections. If the SSH_KEY_PATH environment variable is set then it will return that value. Otherwise it defaults to returning

    joinpath(ssh_dir(), ssh_key_name())

    This default value in turn depends on the SSH_DIR and SSH_KEY_NAME environment variables.

    NetworkOptions.ssh_pub_key_pathFunction
    ssh_pub_key_path() :: String

    The ssh_pub_key_path() function returns the path of the SSH public key file that should be used for SSH connections. If the SSH_PUB_KEY_PATH environment variable is set then it will return that value. If that isn't set but SSH_KEY_PATH is set, it will return that path with the .pub suffix appended. If neither is set, it defaults to returning

    joinpath(ssh_dir(), ssh_key_name() * ".pub")

    This default value in turn depends on the SSH_DIR and SSH_KEY_NAME environment variables.

    NetworkOptions.ssh_known_hosts_filesFunction
    ssh_known_hosts_files() :: Vector{String}

    The ssh_known_hosts_files() function returns a vector of paths of SSH known hosts files that should be used when establishing the identities of remote servers for SSH connections. By default this function returns

    [joinpath(ssh_dir(), "known_hosts"), bundled_known_hosts]

    where bundled_known_hosts is the path of a copy of a known hosts file that is bundled with this package (containing known hosts keys for github.com and gitlab.com). If the environment variable SSH_KNOWN_HOSTS_FILES is set, however, then its value is split into paths on the : character (or on ; on Windows) and this vector of paths is returned instead. If any component of this vector is empty, it is expanded to the default known hosts paths.

    Packages that use ssh_known_hosts_files() should ideally look for matching entries by comparing the host name and key types, considering the first entry in any of the files which matches to be the definitive identity of the host. If the caller cannot compare the key type (e.g. because it has been hashes) then it must approximate the above algorithm by looking for all matching entries for a host in each file: if a file has any entries for a host then one of them must match; the caller should only continue to search further known hosts files if there are no entries for the host in question in an earlier file.

    NetworkOptions.ssh_known_hosts_fileFunction
    ssh_known_hosts_file() :: String

    The ssh_known_hosts_file() function returns a single path of an SSH known hosts file that should be used when establishing the identities of remote servers for SSH connections. It returns the first path returned by ssh_known_hosts_files that actually exists. Callers who can look in more than one known hosts file should use ssh_known_hosts_files instead and look for host matches in all the files returned as described in that function's docs.

    NetworkOptions.verify_hostFunction
    verify_host(url::AbstractString, [transport::AbstractString]) :: Bool

    The verify_host function tells the caller whether the identity of a host should be verified when communicating over secure transports like TLS or SSH. The url argument may be:

    1. a proper URL staring with proto://
    2. an ssh-style bare host name or host name prefixed with user@
    3. an scp-style host as above, followed by : and a path location

    In each case the host name part is parsed out and the decision about whether to verify or not is made based solely on the host name, not anything else about the input URL. In particular, the protocol of the URL does not matter (more below).

    The transport argument indicates the kind of transport that the query is about. The currently known values are SSL/ssl (alias TLS/tls) and SSH/ssh. If the transport is omitted, the query will return true only if the host name should not be verified regardless of transport.

    The host name is matched against the host patterns in the relevant environment variables depending on whether transport is supplied and what its value is:

    • JULIA_NO_VERIFY_HOSTS — hosts that should not be verified for any transport
    • JULIA_SSL_NO_VERIFY_HOSTS — hosts that should not be verified for SSL/TLS
    • JULIA_SSH_NO_VERIFY_HOSTS — hosts that should not be verified for SSH
    • JULIA_ALWAYS_VERIFY_HOSTS — hosts that should always be verified

    The values of each of these variables is a comma-separated list of host name patterns with the following syntax — each pattern is split on . into parts and each part must one of:

    1. A literal domain name component consisting of one or more ASCII letter, digit, hyphen or underscore (technically not part of a legal host name, but sometimes used). A literal domain name component matches only itself.
    2. A **, which matches zero or more domain name components.
    3. A *, which match any one domain name component.

    When matching a host name against a pattern list in one of these variables, the host name is split on . into components and that sequence of words is matched against the pattern: a literal pattern matches exactly one host name component with that value; a * pattern matches exactly one host name component with any value; a ** pattern matches any number of host name components. For example:

    • ** matches any host name
    • **.org matches any host name in the .org top-level domain
    • example.com matches only the exact host name example.com
    • *.example.com matches api.example.com but not example.com or v1.api.example.com
    • **.example.com matches any domain under example.com, including example.com itself, api.example.com and v1.api.example.com
    +

    Network Options

    NetworkOptions.ca_rootsFunction
    ca_roots() :: Union{Nothing, String}

    The ca_roots() function tells the caller where, if anywhere, to find a file or directory of PEM-encoded certificate authority roots. By default, on systems like Windows and macOS where the built-in TLS engines know how to verify hosts using the system's built-in certificate verification mechanism, this function will return nothing. On classic UNIX systems (excluding macOS), root certificates are typically stored in a file in /etc: the common places for the current UNIX system will be searched and if one of these paths exists, it will be returned; if none of these typical root certificate paths exist, then the path to the set of root certificates that are bundled with Julia is returned.

    The default value returned by ca_roots() may be overridden by setting the JULIA_SSL_CA_ROOTS_PATH, SSL_CERT_DIR, or SSL_CERT_FILE environment variables, in which case this function will always return the value of the first of these variables that is set (whether the path exists or not). If JULIA_SSL_CA_ROOTS_PATH is set to the empty string, then the other variables are ignored (as if unset); if the other variables are set to the empty string, they behave is if they are not set.

    NetworkOptions.ca_roots_pathFunction
    ca_roots_path() :: String

    The ca_roots_path() function is similar to the ca_roots() function except that it always returns a path to a file or directory of PEM-encoded certificate authority roots. When called on a system like Windows or macOS, where system root certificates are not stored in the file system, it will currently return the path to the set of root certificates that are bundled with Julia. (In the future, this function may instead extract the root certificates from the system and save them to a file whose path would be returned.)

    If it is possible to configure a library that uses TLS to use the system certificates that is generally preferable: i.e. it is better to use ca_roots() which returns nothing to indicate that the system certs should be used. The ca_roots_path() function should only be used when configuring libraries which require a path to a file or directory for root certificates.

    The default value returned by ca_roots_path() may be overridden by setting the JULIA_SSL_CA_ROOTS_PATH, SSL_CERT_DIR, or SSL_CERT_FILE environment variables, in which case this function will always return the value of the first of these variables that is set (whether the path exists or not). If JULIA_SSL_CA_ROOTS_PATH is set to the empty string, then the other variables are ignored (as if unset); if the other variables are set to the empty string, they behave is if they are not set.

    NetworkOptions.ssh_dirFunction
    ssh_dir() :: String

    The ssh_dir() function returns the location of the directory where the ssh program keeps/looks for configuration files. By default this is ~/.ssh but this can be overridden by setting the environment variable SSH_DIR.

    NetworkOptions.ssh_key_passFunction
    ssh_key_pass() :: String

    The ssh_key_pass() function returns the value of the environment variable SSH_KEY_PASS if it is set or nothing if it is not set. In the future, this may be able to find a password by other means, such as secure system storage, so packages that need a password to decrypt an SSH private key should use this API instead of directly checking the environment variable so that they gain such capabilities automatically when they are added.

    NetworkOptions.ssh_key_nameFunction
    ssh_key_name() :: String

    The ssh_key_name() function returns the base name of key files that SSH should use for when establishing a connection. There is usually no reason that this function should be called directly and libraries should generally use the ssh_key_path and ssh_pub_key_path functions to get full paths. If the environment variable SSH_KEY_NAME is set then this function returns that; otherwise it returns id_rsa by default.

    NetworkOptions.ssh_key_pathFunction
    ssh_key_path() :: String

    The ssh_key_path() function returns the path of the SSH private key file that should be used for SSH connections. If the SSH_KEY_PATH environment variable is set then it will return that value. Otherwise it defaults to returning

    joinpath(ssh_dir(), ssh_key_name())

    This default value in turn depends on the SSH_DIR and SSH_KEY_NAME environment variables.

    NetworkOptions.ssh_pub_key_pathFunction
    ssh_pub_key_path() :: String

    The ssh_pub_key_path() function returns the path of the SSH public key file that should be used for SSH connections. If the SSH_PUB_KEY_PATH environment variable is set then it will return that value. If that isn't set but SSH_KEY_PATH is set, it will return that path with the .pub suffix appended. If neither is set, it defaults to returning

    joinpath(ssh_dir(), ssh_key_name() * ".pub")

    This default value in turn depends on the SSH_DIR and SSH_KEY_NAME environment variables.

    NetworkOptions.ssh_known_hosts_filesFunction
    ssh_known_hosts_files() :: Vector{String}

    The ssh_known_hosts_files() function returns a vector of paths of SSH known hosts files that should be used when establishing the identities of remote servers for SSH connections. By default this function returns

    [joinpath(ssh_dir(), "known_hosts"), bundled_known_hosts]

    where bundled_known_hosts is the path of a copy of a known hosts file that is bundled with this package (containing known hosts keys for github.com and gitlab.com). If the environment variable SSH_KNOWN_HOSTS_FILES is set, however, then its value is split into paths on the : character (or on ; on Windows) and this vector of paths is returned instead. If any component of this vector is empty, it is expanded to the default known hosts paths.

    Packages that use ssh_known_hosts_files() should ideally look for matching entries by comparing the host name and key types, considering the first entry in any of the files which matches to be the definitive identity of the host. If the caller cannot compare the key type (e.g. because it has been hashes) then it must approximate the above algorithm by looking for all matching entries for a host in each file: if a file has any entries for a host then one of them must match; the caller should only continue to search further known hosts files if there are no entries for the host in question in an earlier file.

    NetworkOptions.ssh_known_hosts_fileFunction
    ssh_known_hosts_file() :: String

    The ssh_known_hosts_file() function returns a single path of an SSH known hosts file that should be used when establishing the identities of remote servers for SSH connections. It returns the first path returned by ssh_known_hosts_files that actually exists. Callers who can look in more than one known hosts file should use ssh_known_hosts_files instead and look for host matches in all the files returned as described in that function's docs.

    NetworkOptions.verify_hostFunction
    verify_host(url::AbstractString, [transport::AbstractString]) :: Bool

    The verify_host function tells the caller whether the identity of a host should be verified when communicating over secure transports like TLS or SSH. The url argument may be:

    1. a proper URL staring with proto://
    2. an ssh-style bare host name or host name prefixed with user@
    3. an scp-style host as above, followed by : and a path location

    In each case the host name part is parsed out and the decision about whether to verify or not is made based solely on the host name, not anything else about the input URL. In particular, the protocol of the URL does not matter (more below).

    The transport argument indicates the kind of transport that the query is about. The currently known values are SSL/ssl (alias TLS/tls) and SSH/ssh. If the transport is omitted, the query will return true only if the host name should not be verified regardless of transport.

    The host name is matched against the host patterns in the relevant environment variables depending on whether transport is supplied and what its value is:

    • JULIA_NO_VERIFY_HOSTS — hosts that should not be verified for any transport
    • JULIA_SSL_NO_VERIFY_HOSTS — hosts that should not be verified for SSL/TLS
    • JULIA_SSH_NO_VERIFY_HOSTS — hosts that should not be verified for SSH
    • JULIA_ALWAYS_VERIFY_HOSTS — hosts that should always be verified

    The values of each of these variables is a comma-separated list of host name patterns with the following syntax — each pattern is split on . into parts and each part must one of:

    1. A literal domain name component consisting of one or more ASCII letter, digit, hyphen or underscore (technically not part of a legal host name, but sometimes used). A literal domain name component matches only itself.
    2. A **, which matches zero or more domain name components.
    3. A *, which match any one domain name component.

    When matching a host name against a pattern list in one of these variables, the host name is split on . into components and that sequence of words is matched against the pattern: a literal pattern matches exactly one host name component with that value; a * pattern matches exactly one host name component with any value; a ** pattern matches any number of host name components. For example:

    • ** matches any host name
    • **.org matches any host name in the .org top-level domain
    • example.com matches only the exact host name example.com
    • *.example.com matches api.example.com but not example.com or v1.api.example.com
    • **.example.com matches any domain under example.com, including example.com itself, api.example.com and v1.api.example.com
    diff --git a/en/v1.12-dev/stdlib/Pkg/index.html b/en/v1.12-dev/stdlib/Pkg/index.html index e92a968b71c1..fc754b782b3e 100644 --- a/en/v1.12-dev/stdlib/Pkg/index.html +++ b/en/v1.12-dev/stdlib/Pkg/index.html @@ -32,4 +32,4 @@ (tutorial) pkg> status Status `~/tutorial/Project.toml` [7876af07] Example v0.5.3 - [682c06a0] JSON v0.21.3

    We can see that the tutorial environment now contains Example and JSON.

    Note

    If you have the same package (at the same version) installed in multiple environments, the package will only be downloaded and stored on the hard drive once. This makes environments very lightweight and effectively free to create. Only using the default environment with a huge number of packages in it is a common beginners mistake in Julia. Learning how to use environments effectively will improve your experience with Julia packages.

    For more information about environments, see the Working with Environments section of the documentation.

    If you are ever stuck, you can ask Pkg for help:

    (@v1.9) pkg> ?

    You should see a list of available commands along with short descriptions. You can ask for more detailed help by specifying a command:

    (@v1.9) pkg> ?develop

    This guide should help you get started with Pkg. Pkg has much more to offer in terms of powerful package management, read the full manual to learn more!

    + [682c06a0] JSON v0.21.3

    We can see that the tutorial environment now contains Example and JSON.

    Note

    If you have the same package (at the same version) installed in multiple environments, the package will only be downloaded and stored on the hard drive once. This makes environments very lightweight and effectively free to create. Only using the default environment with a huge number of packages in it is a common beginners mistake in Julia. Learning how to use environments effectively will improve your experience with Julia packages.

    For more information about environments, see the Working with Environments section of the documentation.

    If you are ever stuck, you can ask Pkg for help:

    (@v1.9) pkg> ?

    You should see a list of available commands along with short descriptions. You can ask for more detailed help by specifying a command:

    (@v1.9) pkg> ?develop

    This guide should help you get started with Pkg. Pkg has much more to offer in terms of powerful package management, read the full manual to learn more!

    diff --git a/en/v1.12-dev/stdlib/Printf/index.html b/en/v1.12-dev/stdlib/Printf/index.html index 3a42e953c1d4..0d492fb27995 100644 --- a/en/v1.12-dev/stdlib/Printf/index.html +++ b/en/v1.12-dev/stdlib/Printf/index.html @@ -31,4 +31,4 @@ julia> @printf "%.0f %.1f %f" 0.5 0.025 -0.0078125 0 0.0 -0.007812
    Julia 1.8

    Starting in Julia 1.8, %s (string) and %c (character) widths are computed using textwidth, which e.g. ignores zero-width characters (such as combining characters for diacritical marks) and treats certain "wide" characters (e.g. emoji) as width 2.

    Julia 1.10

    Dynamic width specifiers like %*s and %0*.*f require Julia 1.10.

    Printf.@sprintfMacro
    @sprintf("%Fmt", args...)

    Return @printf formatted output as string.

    Examples

    julia> @sprintf "this is a %s %15.1f" "test" 34.567
     "this is a test            34.6"
    Printf.FormatType
    Printf.Format(format_str)

    Create a C printf-compatible format object that can be used for formatting values.

    The input format_str can include any valid format specifier character and modifiers.

    A Format object can be passed to Printf.format(f::Format, args...) to produce a formatted string, or Printf.format(io::IO, f::Format, args...) to print the formatted string directly to io.

    For convenience, the Printf.format"..." string macro form can be used for building a Printf.Format object at macro-expansion-time.

    Julia 1.6

    Printf.Format requires Julia 1.6 or later.

    Printf.formatFunction
    Printf.format(f::Printf.Format, args...) => String
    -Printf.format(io::IO, f::Printf.Format, args...)

    Apply a printf format object f to provided args and return the formatted string (1st method), or print directly to an io object (2nd method). See @printf for more details on C printf support.

    +Printf.format(io::IO, f::Printf.Format, args...)

    Apply a printf format object f to provided args and return the formatted string (1st method), or print directly to an io object (2nd method). See @printf for more details on C printf support.

    diff --git a/en/v1.12-dev/stdlib/Profile/index.html b/en/v1.12-dev/stdlib/Profile/index.html index f71f05e54a56..6d619b7a7023 100644 --- a/en/v1.12-dev/stdlib/Profile/index.html +++ b/en/v1.12-dev/stdlib/Profile/index.html @@ -52,4 +52,4 @@ julia> Profile.take_heap_snapshot("snapshot"; streaming=true)

    where "snapshot" is the filepath as the prefix for the generated files.

    Once the snapshot files are generated, they could be assembled offline with the following command:

    julia> using Profile
     
    -julia> Profile.HeapSnapshot.assemble_snapshot("snapshot", "snapshot.heapsnapshot")

    The resulting heap snapshot file can be uploaded to chrome devtools to be viewed. For more information, see the chrome devtools docs.

    +julia> Profile.HeapSnapshot.assemble_snapshot("snapshot", "snapshot.heapsnapshot")

    The resulting heap snapshot file can be uploaded to chrome devtools to be viewed. For more information, see the chrome devtools docs.

    diff --git a/en/v1.12-dev/stdlib/REPL/index.html b/en/v1.12-dev/stdlib/REPL/index.html index dcca142c5844..6649b94fc084 100644 --- a/en/v1.12-dev/stdlib/REPL/index.html +++ b/en/v1.12-dev/stdlib/REPL/index.html @@ -10,8 +10,8 @@ (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | - | | |_| | | | (_| | | Version 1.12.0-DEV.246 (2024-03-26) - _/ |\__'_|_|_|\__'_| | Commit 86a697c7fea (0 days old master) + | | |_| | | | (_| | | Version 1.12.0-DEV.247 (2024-03-26) + _/ |\__'_|_|_|\__'_| | Commit 64de065a183 (0 days old master) |__/ | @@ -339,7 +339,7 @@ YEP! orange NOPE grape ⧐ YEP! strawberry -↓ NOPE blueberry

    Aside from the overall charset option, for RadioMenu the configurable options are:

    • cursor::Char='>'|'→': character to use for cursor
    • up_arrow::Char='^'|'↑': character to use for up arrow
    • down_arrow::Char='v'|'↓': character to use for down arrow
    • updown_arrow::Char='I'|'↕': character to use for up/down arrow in one-line page
    • scroll_wrap::Bool=false: optionally wrap-around at the beginning/end of a menu
    • ctrl_c_interrupt::Bool=true: If false, return empty on ^C, if true throw InterruptException() on ^C

    MultiSelectMenu adds:

    • checked::String="[X]"|"✓": string to use for checked
    • unchecked::String="[ ]"|"⬚"): string to use for unchecked

    You can create new menu types of your own. Types that are derived from TerminalMenus.ConfiguredMenu configure the menu options at construction time.

    Legacy interface

    Prior to Julia 1.6, and still supported throughout Julia 1.x, one can also configure menus by calling TerminalMenus.config().

    References

    REPL

    Base.atreplinitFunction
    atreplinit(f)

    Register a one-argument function to be called before the REPL interface is initialized in interactive sessions; this is useful to customize the interface. The argument of f is the REPL object. This function should be called from within the .julia/config/startup.jl initialization file.

    source

    TerminalMenus

    REPL.TerminalMenus.RadioMenuType
    RadioMenu

    A menu that allows a user to select a single option from a list.

    Sample Output

    julia> request(RadioMenu(options, pagesize=4))
    +↓  NOPE blueberry

    Aside from the overall charset option, for RadioMenu the configurable options are:

    • cursor::Char='>'|'→': character to use for cursor
    • up_arrow::Char='^'|'↑': character to use for up arrow
    • down_arrow::Char='v'|'↓': character to use for down arrow
    • updown_arrow::Char='I'|'↕': character to use for up/down arrow in one-line page
    • scroll_wrap::Bool=false: optionally wrap-around at the beginning/end of a menu
    • ctrl_c_interrupt::Bool=true: If false, return empty on ^C, if true throw InterruptException() on ^C

    MultiSelectMenu adds:

    • checked::String="[X]"|"✓": string to use for checked
    • unchecked::String="[ ]"|"⬚"): string to use for unchecked

    You can create new menu types of your own. Types that are derived from TerminalMenus.ConfiguredMenu configure the menu options at construction time.

    Legacy interface

    Prior to Julia 1.6, and still supported throughout Julia 1.x, one can also configure menus by calling TerminalMenus.config().

    References

    REPL

    Base.atreplinitFunction
    atreplinit(f)

    Register a one-argument function to be called before the REPL interface is initialized in interactive sessions; this is useful to customize the interface. The argument of f is the REPL object. This function should be called from within the .julia/config/startup.jl initialization file.

    source

    TerminalMenus

    REPL.TerminalMenus.RadioMenuType
    RadioMenu

    A menu that allows a user to select a single option from a list.

    Sample Output

    julia> request(RadioMenu(options, pagesize=4))
     Choose your favorite fruit:
     ^  grape
        strawberry
    @@ -359,4 +359,4 @@
     You like the following fruits:
       - orange
       - grape
    -  - peach

    Configuration

    REPL.TerminalMenus.ConfigType
    Config(; scroll_wrap=false, ctrl_c_interrupt=true, charset=:ascii, cursor::Char, up_arrow::Char, down_arrow::Char)

    Configure behavior for selection menus via keyword arguments:

    • scroll_wrap, if true, causes the menu to wrap around when scrolling above the first or below the last entry
    • ctrl_c_interrupt, if true, throws an InterruptException if the user hits Ctrl-C during menu selection. If false, TerminalMenus.request will return the default result from TerminalMenus.selected.
    • charset affects the default values for cursor, up_arrow, and down_arrow, and can be :ascii or :unicode
    • cursor is the character printed to indicate the option that will be chosen by hitting "Enter." Defaults are '>' or '→', depending on charset.
    • up_arrow is the character printed when the display does not include the first entry. Defaults are '^' or '↑', depending on charset.
    • down_arrow is the character printed when the display does not include the last entry. Defaults are 'v' or '↓', depending on charset.

    Subtypes of ConfiguredMenu will print cursor, up_arrow, and down_arrow automatically as needed, your writeline method should not print them.

    Julia 1.6

    Config is available as of Julia 1.6. On older releases use the global CONFIG.

    REPL.TerminalMenus.MultiSelectConfigType
    MultiSelectConfig(; charset=:ascii, checked::String, unchecked::String, kwargs...)

    Configure behavior for a multiple-selection menu via keyword arguments:

    • checked is the string to print when an option has been selected. Defaults are "[X]" or "✓", depending on charset.
    • unchecked is the string to print when an option has not been selected. Defaults are "[ ]" or "⬚", depending on charset.

    All other keyword arguments are as described for TerminalMenus.Config. checked and unchecked are not printed automatically, and should be printed by your writeline method.

    Julia 1.6

    MultiSelectConfig is available as of Julia 1.6. On older releases use the global CONFIG.

    REPL.TerminalMenus.configFunction
    config( <see arguments> )

    Keyword-only function to configure global menu parameters

    Arguments

    • charset::Symbol=:na: ui characters to use (:ascii or :unicode); overridden by other arguments
    • cursor::Char='>'|'→': character to use for cursor
    • up_arrow::Char='^'|'↑': character to use for up arrow
    • down_arrow::Char='v'|'↓': character to use for down arrow
    • checked::String="[X]"|"✓": string to use for checked
    • unchecked::String="[ ]"|"⬚"): string to use for unchecked
    • scroll::Symbol=:nowrap: If :wrap wrap cursor around top and bottom, if :nowrap do not wrap cursor
    • supress_output::Bool=false: Ignored legacy argument, pass suppress_output as a keyword argument to request instead.
    • ctrl_c_interrupt::Bool=true: If false, return empty on ^C, if true throw InterruptException() on ^C
    Julia 1.6

    As of Julia 1.6, config is deprecated. Use Config or MultiSelectConfig instead.

    User interaction

    REPL.TerminalMenus.requestFunction
    request(m::AbstractMenu; cursor=1)

    Display the menu and enter interactive mode. cursor indicates the item number used for the initial cursor position. cursor can be either an Int or a RefValue{Int}. The latter is useful for observation and control of the cursor position from the outside.

    Returns selected(m).

    Julia 1.6

    The cursor argument requires Julia 1.6 or later.

    request([term,] msg::AbstractString, m::AbstractMenu)

    Shorthand for println(msg); request(m).

    AbstractMenu extension interface

    Any subtype of AbstractMenu must be mutable, and must contain the fields pagesize::Int and pageoffset::Int. Any subtype must also implement the following functions:

    REPL.TerminalMenus.pickFunction
    pick(m::AbstractMenu, cursor::Int)

    Defines what happens when a user presses the Enter key while the menu is open. If true is returned, request() will exit. cursor indexes the position of the selection.

    REPL.TerminalMenus.cancelFunction
    cancel(m::AbstractMenu)

    Define what happens when a user cancels ('q' or ctrl-c) a menu. request() will always exit after calling this function.

    REPL.TerminalMenus.writelineFunction
    writeline(buf::IO, m::AbstractMenu, idx::Int, iscursor::Bool)

    Write the option at index idx to buf. iscursor, if true, indicates that this item is at the current cursor position (the one that will be selected by hitting "Enter").

    If m is a ConfiguredMenu, TerminalMenus will print the cursor indicator. Otherwise the callee is expected to handle such printing.

    Julia 1.6

    writeline requires Julia 1.6 or higher.

    On older versions of Julia, this was writeLine(buf::IO, m::AbstractMenu, idx, iscursor::Bool) and m is assumed to be unconfigured. The selection and cursor indicators can be obtained from TerminalMenus.CONFIG.

    This older function is supported on all Julia 1.x versions but will be dropped in Julia 2.0.

    It must also implement either options or numoptions:

    REPL.TerminalMenus.optionsFunction
    options(m::AbstractMenu)

    Return a list of strings to be displayed as options in the current page.

    Alternatively, implement numoptions, in which case options is not needed.

    REPL.TerminalMenus.numoptionsFunction
    numoptions(m::AbstractMenu) -> Int

    Return the number of options in menu m. Defaults to length(options(m)).

    Julia 1.6

    This function requires Julia 1.6 or later.

    If the subtype does not have a field named selected, it must also implement

    REPL.TerminalMenus.selectedFunction
    selected(m::AbstractMenu)

    Return information about the user-selected option. By default it returns m.selected.

    The following are optional but can allow additional customization:

    REPL.TerminalMenus.headerFunction
    header(m::AbstractMenu) -> String

    Return a header string to be printed above the menu. Defaults to "".

    + - peach

    Configuration

    REPL.TerminalMenus.ConfigType
    Config(; scroll_wrap=false, ctrl_c_interrupt=true, charset=:ascii, cursor::Char, up_arrow::Char, down_arrow::Char)

    Configure behavior for selection menus via keyword arguments:

    • scroll_wrap, if true, causes the menu to wrap around when scrolling above the first or below the last entry
    • ctrl_c_interrupt, if true, throws an InterruptException if the user hits Ctrl-C during menu selection. If false, TerminalMenus.request will return the default result from TerminalMenus.selected.
    • charset affects the default values for cursor, up_arrow, and down_arrow, and can be :ascii or :unicode
    • cursor is the character printed to indicate the option that will be chosen by hitting "Enter." Defaults are '>' or '→', depending on charset.
    • up_arrow is the character printed when the display does not include the first entry. Defaults are '^' or '↑', depending on charset.
    • down_arrow is the character printed when the display does not include the last entry. Defaults are 'v' or '↓', depending on charset.

    Subtypes of ConfiguredMenu will print cursor, up_arrow, and down_arrow automatically as needed, your writeline method should not print them.

    Julia 1.6

    Config is available as of Julia 1.6. On older releases use the global CONFIG.

    REPL.TerminalMenus.MultiSelectConfigType
    MultiSelectConfig(; charset=:ascii, checked::String, unchecked::String, kwargs...)

    Configure behavior for a multiple-selection menu via keyword arguments:

    • checked is the string to print when an option has been selected. Defaults are "[X]" or "✓", depending on charset.
    • unchecked is the string to print when an option has not been selected. Defaults are "[ ]" or "⬚", depending on charset.

    All other keyword arguments are as described for TerminalMenus.Config. checked and unchecked are not printed automatically, and should be printed by your writeline method.

    Julia 1.6

    MultiSelectConfig is available as of Julia 1.6. On older releases use the global CONFIG.

    REPL.TerminalMenus.configFunction
    config( <see arguments> )

    Keyword-only function to configure global menu parameters

    Arguments

    • charset::Symbol=:na: ui characters to use (:ascii or :unicode); overridden by other arguments
    • cursor::Char='>'|'→': character to use for cursor
    • up_arrow::Char='^'|'↑': character to use for up arrow
    • down_arrow::Char='v'|'↓': character to use for down arrow
    • checked::String="[X]"|"✓": string to use for checked
    • unchecked::String="[ ]"|"⬚"): string to use for unchecked
    • scroll::Symbol=:nowrap: If :wrap wrap cursor around top and bottom, if :nowrap do not wrap cursor
    • supress_output::Bool=false: Ignored legacy argument, pass suppress_output as a keyword argument to request instead.
    • ctrl_c_interrupt::Bool=true: If false, return empty on ^C, if true throw InterruptException() on ^C
    Julia 1.6

    As of Julia 1.6, config is deprecated. Use Config or MultiSelectConfig instead.

    User interaction

    REPL.TerminalMenus.requestFunction
    request(m::AbstractMenu; cursor=1)

    Display the menu and enter interactive mode. cursor indicates the item number used for the initial cursor position. cursor can be either an Int or a RefValue{Int}. The latter is useful for observation and control of the cursor position from the outside.

    Returns selected(m).

    Julia 1.6

    The cursor argument requires Julia 1.6 or later.

    request([term,] msg::AbstractString, m::AbstractMenu)

    Shorthand for println(msg); request(m).

    AbstractMenu extension interface

    Any subtype of AbstractMenu must be mutable, and must contain the fields pagesize::Int and pageoffset::Int. Any subtype must also implement the following functions:

    REPL.TerminalMenus.pickFunction
    pick(m::AbstractMenu, cursor::Int)

    Defines what happens when a user presses the Enter key while the menu is open. If true is returned, request() will exit. cursor indexes the position of the selection.

    REPL.TerminalMenus.cancelFunction
    cancel(m::AbstractMenu)

    Define what happens when a user cancels ('q' or ctrl-c) a menu. request() will always exit after calling this function.

    REPL.TerminalMenus.writelineFunction
    writeline(buf::IO, m::AbstractMenu, idx::Int, iscursor::Bool)

    Write the option at index idx to buf. iscursor, if true, indicates that this item is at the current cursor position (the one that will be selected by hitting "Enter").

    If m is a ConfiguredMenu, TerminalMenus will print the cursor indicator. Otherwise the callee is expected to handle such printing.

    Julia 1.6

    writeline requires Julia 1.6 or higher.

    On older versions of Julia, this was writeLine(buf::IO, m::AbstractMenu, idx, iscursor::Bool) and m is assumed to be unconfigured. The selection and cursor indicators can be obtained from TerminalMenus.CONFIG.

    This older function is supported on all Julia 1.x versions but will be dropped in Julia 2.0.

    It must also implement either options or numoptions:

    REPL.TerminalMenus.optionsFunction
    options(m::AbstractMenu)

    Return a list of strings to be displayed as options in the current page.

    Alternatively, implement numoptions, in which case options is not needed.

    REPL.TerminalMenus.numoptionsFunction
    numoptions(m::AbstractMenu) -> Int

    Return the number of options in menu m. Defaults to length(options(m)).

    Julia 1.6

    This function requires Julia 1.6 or later.

    If the subtype does not have a field named selected, it must also implement

    REPL.TerminalMenus.selectedFunction
    selected(m::AbstractMenu)

    Return information about the user-selected option. By default it returns m.selected.

    The following are optional but can allow additional customization:

    REPL.TerminalMenus.headerFunction
    header(m::AbstractMenu) -> String

    Return a header string to be printed above the menu. Defaults to "".

    diff --git a/en/v1.12-dev/stdlib/Random/index.html b/en/v1.12-dev/stdlib/Random/index.html index 45177cb6eacc..45d024587b5c 100644 --- a/en/v1.12-dev/stdlib/Random/index.html +++ b/en/v1.12-dev/stdlib/Random/index.html @@ -260,4 +260,4 @@ SamplerSimple(die, Sampler(RNG, 1:die.nsides, r)) rand(rng::AbstractRNG, sp::SamplerSimple{Die}) = rand(rng, sp.data)

    Here, sp.data refers to the second parameter in the call to the SamplerSimple constructor (in this case equal to Sampler(rng, 1:die.nsides, r)), while the Die object can be accessed via sp[].

    Like SamplerDie, any custom sampler must be a subtype of Sampler{T} where T is the type of the generated values. Note that SamplerSimple(x, data) isa Sampler{eltype(x)}, so this constrains what the first argument to SamplerSimple can be (it's recommended to use SamplerSimple like in the Die example, where x is simply forwarded while defining a Sampler method). Similarly, SamplerTrivial(x) isa Sampler{eltype(x)}.

    Another helper type is currently available for other cases, Random.SamplerTag, but is considered as internal API, and can break at any time without proper deprecations.

    Using distinct algorithms for scalar or array generation

    In some cases, whether one wants to generate only a handful of values or a large number of values will have an impact on the choice of algorithm. This is handled with the third parameter of the Sampler constructor. Let's assume we defined two helper types for Die, say SamplerDie1 which should be used to generate only few random values, and SamplerDieMany for many values. We can use those types as follows:

    Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{1}) = SamplerDie1(...)
    -Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{Inf}) = SamplerDieMany(...)

    Of course, rand must also be defined on those types (i.e. rand(::AbstractRNG, ::SamplerDie1) and rand(::AbstractRNG, ::SamplerDieMany)). Note that, as usual, SamplerTrivial and SamplerSimple can be used if custom types are not necessary.

    Note: Sampler(rng, x) is simply a shorthand for Sampler(rng, x, Val(Inf)), and Random.Repetition is an alias for Union{Val{1}, Val{Inf}}.

    Creating new generators

    The API is not clearly defined yet, but as a rule of thumb:

    1. any rand method producing "basic" types (isbitstype integer and floating types in Base) should be defined for this specific RNG, if they are needed;
    2. other documented rand methods accepting an AbstractRNG should work out of the box, (provided the methods from 1) what are relied on are implemented), but can of course be specialized for this RNG if there is room for optimization;
    3. copy for pseudo-RNGs should return an independent copy that generates the exact same random sequence as the original from that point when called in the same way. When this is not feasible (e.g. hardware-based RNGs), copy must not be implemented.

    Concerning 1), a rand method may happen to work automatically, but it's not officially supported and may break without warnings in a subsequent release.

    To define a new rand method for an hypothetical MyRNG generator, and a value specification s (e.g. s == Int, or s == 1:10) of type S==typeof(s) or S==Type{s} if s is a type, the same two methods as we saw before must be defined:

    1. Sampler(::Type{MyRNG}, ::S, ::Repetition), which returns an object of type say SamplerS
    2. rand(rng::MyRNG, sp::SamplerS)

    It can happen that Sampler(rng::AbstractRNG, ::S, ::Repetition) is already defined in the Random module. It would then be possible to skip step 1) in practice (if one wants to specialize generation for this particular RNG type), but the corresponding SamplerS type is considered as internal detail, and may be changed without warning.

    Specializing array generation

    In some cases, for a given RNG type, generating an array of random values can be more efficient with a specialized method than by merely using the decoupling technique explained before. This is for example the case for MersenneTwister, which natively writes random values in an array.

    To implement this specialization for MyRNG and for a specification s, producing elements of type S, the following method can be defined: rand!(rng::MyRNG, a::AbstractArray{S}, ::SamplerS), where SamplerS is the type of the sampler returned by Sampler(MyRNG, s, Val(Inf)). Instead of AbstractArray, it's possible to implement the functionality only for a subtype, e.g. Array{S}. The non-mutating array method of rand will automatically call this specialization internally.

    Reproducibility

    By using an RNG parameter initialized with a given seed, you can reproduce the same pseudorandom number sequence when running your program multiple times. However, a minor release of Julia (e.g. 1.3 to 1.4) may change the sequence of pseudorandom numbers generated from a specific seed, in particular if MersenneTwister is used. (Even if the sequence produced by a low-level function like rand does not change, the output of higher-level functions like randsubseq may change due to algorithm updates.) Rationale: guaranteeing that pseudorandom streams never change prohibits many algorithmic improvements.

    If you need to guarantee exact reproducibility of random data, it is advisable to simply save the data (e.g. as a supplementary attachment in a scientific publication). (You can also, of course, specify a particular Julia version and package manifest, especially if you require bit reproducibility.)

    Software tests that rely on specific "random" data should also generally either save the data, embed it into the test code, or use third-party packages like StableRNGs.jl. On the other hand, tests that should pass for most random data (e.g. testing A \ (A*x) ≈ x for a random matrix A = randn(n,n)) can use an RNG with a fixed seed to ensure that simply running the test many times does not encounter a failure due to very improbable data (e.g. an extremely ill-conditioned matrix).

    The statistical distribution from which random samples are drawn is guaranteed to be the same across any minor Julia releases.

    +Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{Inf}) = SamplerDieMany(...)

    Of course, rand must also be defined on those types (i.e. rand(::AbstractRNG, ::SamplerDie1) and rand(::AbstractRNG, ::SamplerDieMany)). Note that, as usual, SamplerTrivial and SamplerSimple can be used if custom types are not necessary.

    Note: Sampler(rng, x) is simply a shorthand for Sampler(rng, x, Val(Inf)), and Random.Repetition is an alias for Union{Val{1}, Val{Inf}}.

    Creating new generators

    The API is not clearly defined yet, but as a rule of thumb:

    1. any rand method producing "basic" types (isbitstype integer and floating types in Base) should be defined for this specific RNG, if they are needed;
    2. other documented rand methods accepting an AbstractRNG should work out of the box, (provided the methods from 1) what are relied on are implemented), but can of course be specialized for this RNG if there is room for optimization;
    3. copy for pseudo-RNGs should return an independent copy that generates the exact same random sequence as the original from that point when called in the same way. When this is not feasible (e.g. hardware-based RNGs), copy must not be implemented.

    Concerning 1), a rand method may happen to work automatically, but it's not officially supported and may break without warnings in a subsequent release.

    To define a new rand method for an hypothetical MyRNG generator, and a value specification s (e.g. s == Int, or s == 1:10) of type S==typeof(s) or S==Type{s} if s is a type, the same two methods as we saw before must be defined:

    1. Sampler(::Type{MyRNG}, ::S, ::Repetition), which returns an object of type say SamplerS
    2. rand(rng::MyRNG, sp::SamplerS)

    It can happen that Sampler(rng::AbstractRNG, ::S, ::Repetition) is already defined in the Random module. It would then be possible to skip step 1) in practice (if one wants to specialize generation for this particular RNG type), but the corresponding SamplerS type is considered as internal detail, and may be changed without warning.

    Specializing array generation

    In some cases, for a given RNG type, generating an array of random values can be more efficient with a specialized method than by merely using the decoupling technique explained before. This is for example the case for MersenneTwister, which natively writes random values in an array.

    To implement this specialization for MyRNG and for a specification s, producing elements of type S, the following method can be defined: rand!(rng::MyRNG, a::AbstractArray{S}, ::SamplerS), where SamplerS is the type of the sampler returned by Sampler(MyRNG, s, Val(Inf)). Instead of AbstractArray, it's possible to implement the functionality only for a subtype, e.g. Array{S}. The non-mutating array method of rand will automatically call this specialization internally.

    Reproducibility

    By using an RNG parameter initialized with a given seed, you can reproduce the same pseudorandom number sequence when running your program multiple times. However, a minor release of Julia (e.g. 1.3 to 1.4) may change the sequence of pseudorandom numbers generated from a specific seed, in particular if MersenneTwister is used. (Even if the sequence produced by a low-level function like rand does not change, the output of higher-level functions like randsubseq may change due to algorithm updates.) Rationale: guaranteeing that pseudorandom streams never change prohibits many algorithmic improvements.

    If you need to guarantee exact reproducibility of random data, it is advisable to simply save the data (e.g. as a supplementary attachment in a scientific publication). (You can also, of course, specify a particular Julia version and package manifest, especially if you require bit reproducibility.)

    Software tests that rely on specific "random" data should also generally either save the data, embed it into the test code, or use third-party packages like StableRNGs.jl. On the other hand, tests that should pass for most random data (e.g. testing A \ (A*x) ≈ x for a random matrix A = randn(n,n)) can use an RNG with a fixed seed to ensure that simply running the test many times does not encounter a failure due to very improbable data (e.g. an extremely ill-conditioned matrix).

    The statistical distribution from which random samples are drawn is guaranteed to be the same across any minor Julia releases.

    diff --git a/en/v1.12-dev/stdlib/SHA/index.html b/en/v1.12-dev/stdlib/SHA/index.html index 2efa3d1f6c99..47e01b422dbe 100644 --- a/en/v1.12-dev/stdlib/SHA/index.html +++ b/en/v1.12-dev/stdlib/SHA/index.html @@ -119,4 +119,4 @@ 0x00000000000000000000000000000094 julia> bytes2hex(digest!(ctx)) -"bc49a6f2aa29b27ee5ed1e944edd7f3d153e8a01535d98b5e24dac9a589a6248"

    All HMAC functions

    HMAC context type

    SHA.HMAC_CTXType
    HMAC_CTX(ctx::CTX, key::Vector{UInt8}) where {CTX<:SHA_CTX}

    Construct an empty HMAC_CTX context.

    SHA-1

    SHA.hmac_sha1Function
    hmac_sha1(key, data)

    Hash data using the sha1 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha1(key, io::IO)

    Hash data from io with the passed key using sha1 algorithm.

    SHA-2

    SHA.hmac_sha224Function
    hmac_sha224(key, data)

    Hash data using the sha224 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha224(key, io::IO)

    Hash data from io with the passed key using sha224 algorithm.

    SHA.hmac_sha256Function
    hmac_sha256(key, data)

    Hash data using the sha256 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha256(key, io::IO)

    Hash data from io with the passed key using sha256 algorithm.

    SHA.hmac_sha384Function
    hmac_sha384(key, data)

    Hash data using the sha384 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha384(key, io::IO)

    Hash data from io with the passed key using sha384 algorithm.

    SHA.hmac_sha512Function
    hmac_sha512(key, data)

    Hash data using the sha512 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha512(key, io::IO)

    Hash data from io with the passed key using sha512 algorithm.

    SHA.hmac_sha2_224Function
    hmac_sha2_224(key, data)

    Hash data using the sha2_224 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha2_224(key, io::IO)

    Hash data from io with the passed key using sha2_224 algorithm.

    SHA.hmac_sha2_256Function
    hmac_sha2_256(key, data)

    Hash data using the sha2_256 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha2_256(key, io::IO)

    Hash data from io with the passed key using sha2_256 algorithm.

    SHA.hmac_sha2_384Function
    hmac_sha2_384(key, data)

    Hash data using the sha2_384 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha2_384(key, io::IO)

    Hash data from io with the passed key using sha2_384 algorithm.

    SHA.hmac_sha2_512Function
    hmac_sha2_512(key, data)

    Hash data using the sha2_512 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha2_512(key, io::IO)

    Hash data from io with the passed key using sha2_512 algorithm.

    SHA-3

    SHA.hmac_sha3_224Function
    hmac_sha3_224(key, data)

    Hash data using the sha3_224 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha3_224(key, io::IO)

    Hash data from io with the passed key using sha3_224 algorithm.

    SHA.hmac_sha3_256Function
    hmac_sha3_256(key, data)

    Hash data using the sha3_256 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha3_256(key, io::IO)

    Hash data from io with the passed key using sha3_256 algorithm.

    SHA.hmac_sha3_384Function
    hmac_sha3_384(key, data)

    Hash data using the sha3_384 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha3_384(key, io::IO)

    Hash data from io with the passed key using sha3_384 algorithm.

    SHA.hmac_sha3_512Function
    hmac_sha3_512(key, data)

    Hash data using the sha3_512 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha3_512(key, io::IO)

    Hash data from io with the passed key using sha3_512 algorithm.

    +"bc49a6f2aa29b27ee5ed1e944edd7f3d153e8a01535d98b5e24dac9a589a6248"

    All HMAC functions

    HMAC context type

    SHA.HMAC_CTXType
    HMAC_CTX(ctx::CTX, key::Vector{UInt8}) where {CTX<:SHA_CTX}

    Construct an empty HMAC_CTX context.

    SHA-1

    SHA.hmac_sha1Function
    hmac_sha1(key, data)

    Hash data using the sha1 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha1(key, io::IO)

    Hash data from io with the passed key using sha1 algorithm.

    SHA-2

    SHA.hmac_sha224Function
    hmac_sha224(key, data)

    Hash data using the sha224 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha224(key, io::IO)

    Hash data from io with the passed key using sha224 algorithm.

    SHA.hmac_sha256Function
    hmac_sha256(key, data)

    Hash data using the sha256 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha256(key, io::IO)

    Hash data from io with the passed key using sha256 algorithm.

    SHA.hmac_sha384Function
    hmac_sha384(key, data)

    Hash data using the sha384 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha384(key, io::IO)

    Hash data from io with the passed key using sha384 algorithm.

    SHA.hmac_sha512Function
    hmac_sha512(key, data)

    Hash data using the sha512 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha512(key, io::IO)

    Hash data from io with the passed key using sha512 algorithm.

    SHA.hmac_sha2_224Function
    hmac_sha2_224(key, data)

    Hash data using the sha2_224 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha2_224(key, io::IO)

    Hash data from io with the passed key using sha2_224 algorithm.

    SHA.hmac_sha2_256Function
    hmac_sha2_256(key, data)

    Hash data using the sha2_256 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha2_256(key, io::IO)

    Hash data from io with the passed key using sha2_256 algorithm.

    SHA.hmac_sha2_384Function
    hmac_sha2_384(key, data)

    Hash data using the sha2_384 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha2_384(key, io::IO)

    Hash data from io with the passed key using sha2_384 algorithm.

    SHA.hmac_sha2_512Function
    hmac_sha2_512(key, data)

    Hash data using the sha2_512 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha2_512(key, io::IO)

    Hash data from io with the passed key using sha2_512 algorithm.

    SHA-3

    SHA.hmac_sha3_224Function
    hmac_sha3_224(key, data)

    Hash data using the sha3_224 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha3_224(key, io::IO)

    Hash data from io with the passed key using sha3_224 algorithm.

    SHA.hmac_sha3_256Function
    hmac_sha3_256(key, data)

    Hash data using the sha3_256 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha3_256(key, io::IO)

    Hash data from io with the passed key using sha3_256 algorithm.

    SHA.hmac_sha3_384Function
    hmac_sha3_384(key, data)

    Hash data using the sha3_384 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha3_384(key, io::IO)

    Hash data from io with the passed key using sha3_384 algorithm.

    SHA.hmac_sha3_512Function
    hmac_sha3_512(key, data)

    Hash data using the sha3_512 algorithm using the passed key. See also HMAC_CTX.

    hmac_sha3_512(key, io::IO)

    Hash data from io with the passed key using sha3_512 algorithm.

    diff --git a/en/v1.12-dev/stdlib/Serialization/index.html b/en/v1.12-dev/stdlib/Serialization/index.html index 39b45cc3f471..25c30b69c360 100644 --- a/en/v1.12-dev/stdlib/Serialization/index.html +++ b/en/v1.12-dev/stdlib/Serialization/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -

    Serialization

    Provides serialization of Julia objects.

    Serialization.serializeFunction
    serialize(stream::IO, value)

    Write an arbitrary value to a stream in an opaque format, such that it can be read back by deserialize. The read-back value will be as identical as possible to the original, but note that Ptr values are serialized as all-zero bit patterns (NULL).

    An 8-byte identifying header is written to the stream first. To avoid writing the header, construct a Serializer and use it as the first argument to serialize instead. See also Serialization.writeheader.

    The data format can change in minor (1.x) Julia releases, but files written by prior 1.x versions will remain readable. The main exception to this is when the definition of a type in an external package changes. If that occurs, it may be necessary to specify an explicit compatible version of the affected package in your environment. Renaming functions, even private functions, inside packages can also put existing files out of sync. Anonymous functions require special care: because their names are automatically generated, minor code changes can cause them to be renamed. Serializing anonymous functions should be avoided in files intended for long-term storage.

    In some cases, the word size (32- or 64-bit) of the reading and writing machines must match. In rarer cases the OS or architecture must also match, for example when using packages that contain platform-dependent code.

    serialize(filename::AbstractString, value)

    Open a file and serialize the given value to it.

    Julia 1.1

    This method is available as of Julia 1.1.

    Serialization.deserializeFunction
    deserialize(stream)

    Read a value written by serialize. deserialize assumes the binary data read from stream is correct and has been serialized by a compatible implementation of serialize. deserialize is designed for simplicity and performance, and so does not validate the data read. Malformed data can result in process termination. The caller must ensure the integrity and correctness of data read from stream.

    deserialize(filename::AbstractString)

    Open a file and deserialize its contents.

    Julia 1.1

    This method is available as of Julia 1.1.

    Serialization.writeheaderFunction
    Serialization.writeheader(s::AbstractSerializer)

    Write an identifying header to the specified serializer. The header consists of 8 bytes as follows:

    OffsetDescription
    0tag byte (0x37)
    1-2signature bytes "JL"
    3protocol version
    4bits 0-1: endianness: 0 = little, 1 = big
    4bits 2-3: platform: 0 = 32-bit, 1 = 64-bit
    5-7reserved
    +

    Serialization

    Provides serialization of Julia objects.

    Serialization.serializeFunction
    serialize(stream::IO, value)

    Write an arbitrary value to a stream in an opaque format, such that it can be read back by deserialize. The read-back value will be as identical as possible to the original, but note that Ptr values are serialized as all-zero bit patterns (NULL).

    An 8-byte identifying header is written to the stream first. To avoid writing the header, construct a Serializer and use it as the first argument to serialize instead. See also Serialization.writeheader.

    The data format can change in minor (1.x) Julia releases, but files written by prior 1.x versions will remain readable. The main exception to this is when the definition of a type in an external package changes. If that occurs, it may be necessary to specify an explicit compatible version of the affected package in your environment. Renaming functions, even private functions, inside packages can also put existing files out of sync. Anonymous functions require special care: because their names are automatically generated, minor code changes can cause them to be renamed. Serializing anonymous functions should be avoided in files intended for long-term storage.

    In some cases, the word size (32- or 64-bit) of the reading and writing machines must match. In rarer cases the OS or architecture must also match, for example when using packages that contain platform-dependent code.

    serialize(filename::AbstractString, value)

    Open a file and serialize the given value to it.

    Julia 1.1

    This method is available as of Julia 1.1.

    Serialization.deserializeFunction
    deserialize(stream)

    Read a value written by serialize. deserialize assumes the binary data read from stream is correct and has been serialized by a compatible implementation of serialize. deserialize is designed for simplicity and performance, and so does not validate the data read. Malformed data can result in process termination. The caller must ensure the integrity and correctness of data read from stream.

    deserialize(filename::AbstractString)

    Open a file and deserialize its contents.

    Julia 1.1

    This method is available as of Julia 1.1.

    Serialization.writeheaderFunction
    Serialization.writeheader(s::AbstractSerializer)

    Write an identifying header to the specified serializer. The header consists of 8 bytes as follows:

    OffsetDescription
    0tag byte (0x37)
    1-2signature bytes "JL"
    3protocol version
    4bits 0-1: endianness: 0 = little, 1 = big
    4bits 2-3: platform: 0 = 32-bit, 1 = 64-bit
    5-7reserved
    diff --git a/en/v1.12-dev/stdlib/SharedArrays/index.html b/en/v1.12-dev/stdlib/SharedArrays/index.html index e708ee85ea15..786752790685 100644 --- a/en/v1.12-dev/stdlib/SharedArrays/index.html +++ b/en/v1.12-dev/stdlib/SharedArrays/index.html @@ -5,4 +5,4 @@ gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash});

    Shared Arrays

    SharedArray represents an array, which is shared across multiple processes, on a single machine.

    SharedArrays.SharedArrayType
    SharedArray{T}(dims::NTuple; init=false, pids=Int[])
     SharedArray{T,N}(...)

    Construct a SharedArray of a bits type T and size dims across the processes specified by pids - all of which have to be on the same host. If N is specified by calling SharedArray{T,N}(dims), then N must match the length of dims.

    If pids is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, localindices and indexpids will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.

    If an init function of the type initfn(S::SharedArray) is specified, it is called on all the participating workers.

    The shared array is valid as long as a reference to the SharedArray object exists on the node which created the mapping.

    SharedArray{T}(filename::AbstractString, dims::NTuple, [offset=0]; mode=nothing, init=false, pids=Int[])
    -SharedArray{T,N}(...)

    Construct a SharedArray backed by the file filename, with element type T (must be a bits type) and size dims, across the processes specified by pids - all of which have to be on the same host. This file is mmapped into the host memory, with the following consequences:

    • The array data must be represented in binary format (e.g., an ASCII format like CSV cannot be supported)

    • Any changes you make to the array values (e.g., A[3] = 0) will also change the values on disk

    If pids is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, localindices and indexpids will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.

    mode must be one of "r", "r+", "w+", or "a+", and defaults to "r+" if the file specified by filename already exists, or "w+" if not. If an init function of the type initfn(S::SharedArray) is specified, it is called on all the participating workers. You cannot specify an init function if the file is not writable.

    offset allows you to skip the specified number of bytes at the beginning of the file.

    Distributed.procsMethod
    procs(S::SharedArray)

    Get the vector of processes mapping the shared array.

    SharedArrays.sdataFunction
    sdata(S::SharedArray)

    Return the actual Array object backing S.

    SharedArrays.indexpidsFunction
    indexpids(S::SharedArray)

    Return the current worker's index in the list of workers mapping the SharedArray (i.e. in the same list returned by procs(S)), or 0 if the SharedArray is not mapped locally.

    SharedArrays.localindicesFunction
    localindices(S::SharedArray)

    Return a range describing the "default" indices to be handled by the current process. This range should be interpreted in the sense of linear indexing, i.e., as a sub-range of 1:length(S). In multi-process contexts, returns an empty range in the parent process (or any process for which indexpids returns 0).

    It's worth emphasizing that localindices exists purely as a convenience, and you can partition work on the array among workers any way you wish. For a SharedArray, all indices should be equally fast for each worker process.

    +SharedArray{T,N}(...)

    Construct a SharedArray backed by the file filename, with element type T (must be a bits type) and size dims, across the processes specified by pids - all of which have to be on the same host. This file is mmapped into the host memory, with the following consequences:

    • The array data must be represented in binary format (e.g., an ASCII format like CSV cannot be supported)

    • Any changes you make to the array values (e.g., A[3] = 0) will also change the values on disk

    If pids is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, localindices and indexpids will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.

    mode must be one of "r", "r+", "w+", or "a+", and defaults to "r+" if the file specified by filename already exists, or "w+" if not. If an init function of the type initfn(S::SharedArray) is specified, it is called on all the participating workers. You cannot specify an init function if the file is not writable.

    offset allows you to skip the specified number of bytes at the beginning of the file.

    Distributed.procsMethod
    procs(S::SharedArray)

    Get the vector of processes mapping the shared array.

    SharedArrays.sdataFunction
    sdata(S::SharedArray)

    Return the actual Array object backing S.

    SharedArrays.indexpidsFunction
    indexpids(S::SharedArray)

    Return the current worker's index in the list of workers mapping the SharedArray (i.e. in the same list returned by procs(S)), or 0 if the SharedArray is not mapped locally.

    SharedArrays.localindicesFunction
    localindices(S::SharedArray)

    Return a range describing the "default" indices to be handled by the current process. This range should be interpreted in the sense of linear indexing, i.e., as a sub-range of 1:length(S). In multi-process contexts, returns an empty range in the parent process (or any process for which indexpids returns 0).

    It's worth emphasizing that localindices exists purely as a convenience, and you can partition work on the array among workers any way you wish. For a SharedArray, all indices should be equally fast for each worker process.

    diff --git a/en/v1.12-dev/stdlib/Sockets/index.html b/en/v1.12-dev/stdlib/Sockets/index.html index 10c301110be4..c37086059c23 100644 --- a/en/v1.12-dev/stdlib/Sockets/index.html +++ b/en/v1.12-dev/stdlib/Sockets/index.html @@ -64,4 +64,4 @@ Stacktrace: [...] nested task error: foo -[...]source
    Sockets.sendFunction
    send(socket::UDPSocket, host::IPAddr, port::Integer, msg)

    Send msg over socket to host:port.

    Sockets.recvFunction
    recv(socket::UDPSocket)

    Read a UDP packet from the specified socket, and return the bytes received. This call blocks.

    Sockets.recvfromFunction
    recvfrom(socket::UDPSocket) -> (host_port, data)

    Read a UDP packet from the specified socket, returning a tuple of (host_port, data), where host_port will be an InetAddr{IPv4} or InetAddr{IPv6}, as appropriate.

    Julia 1.3

    Prior to Julia version 1.3, the first returned value was an address (IPAddr). In version 1.3 it was changed to an InetAddr.

    Sockets.setoptFunction
    setopt(sock::UDPSocket; multicast_loop=nothing, multicast_ttl=nothing, enable_broadcast=nothing, ttl=nothing)

    Set UDP socket options.

    • multicast_loop: loopback for multicast packets (default: true).
    • multicast_ttl: TTL for multicast packets (default: nothing).
    • enable_broadcast: flag must be set to true if socket will be used for broadcast messages, or else the UDP system will return an access error (default: false).
    • ttl: Time-to-live of packets sent on the socket (default: nothing).
    Sockets.nagleFunction
    nagle(socket::Union{TCPServer, TCPSocket}, enable::Bool)

    Nagle's algorithm batches multiple small TCP packets into larger ones. This can improve throughput but worsen latency. Nagle's algorithm is enabled by default. This function sets whether Nagle's algorithm is active on a given TCP server or socket. The opposite option is called TCP_NODELAY in other languages.

    Julia 1.3

    This function requires Julia 1.3 or later.

    Sockets.quickackFunction
    quickack(socket::Union{TCPServer, TCPSocket}, enable::Bool)

    On Linux systems, the TCP_QUICKACK is disabled or enabled on socket.

    +[...]source
    Sockets.sendFunction
    send(socket::UDPSocket, host::IPAddr, port::Integer, msg)

    Send msg over socket to host:port.

    Sockets.recvFunction
    recv(socket::UDPSocket)

    Read a UDP packet from the specified socket, and return the bytes received. This call blocks.

    Sockets.recvfromFunction
    recvfrom(socket::UDPSocket) -> (host_port, data)

    Read a UDP packet from the specified socket, returning a tuple of (host_port, data), where host_port will be an InetAddr{IPv4} or InetAddr{IPv6}, as appropriate.

    Julia 1.3

    Prior to Julia version 1.3, the first returned value was an address (IPAddr). In version 1.3 it was changed to an InetAddr.

    Sockets.setoptFunction
    setopt(sock::UDPSocket; multicast_loop=nothing, multicast_ttl=nothing, enable_broadcast=nothing, ttl=nothing)

    Set UDP socket options.

    • multicast_loop: loopback for multicast packets (default: true).
    • multicast_ttl: TTL for multicast packets (default: nothing).
    • enable_broadcast: flag must be set to true if socket will be used for broadcast messages, or else the UDP system will return an access error (default: false).
    • ttl: Time-to-live of packets sent on the socket (default: nothing).
    Sockets.nagleFunction
    nagle(socket::Union{TCPServer, TCPSocket}, enable::Bool)

    Nagle's algorithm batches multiple small TCP packets into larger ones. This can improve throughput but worsen latency. Nagle's algorithm is enabled by default. This function sets whether Nagle's algorithm is active on a given TCP server or socket. The opposite option is called TCP_NODELAY in other languages.

    Julia 1.3

    This function requires Julia 1.3 or later.

    Sockets.quickackFunction
    quickack(socket::Union{TCPServer, TCPSocket}, enable::Bool)

    On Linux systems, the TCP_QUICKACK is disabled or enabled on socket.

    diff --git a/en/v1.12-dev/stdlib/SparseArrays/index.html b/en/v1.12-dev/stdlib/SparseArrays/index.html index 319793d88316..3e87b8aa8e0b 100644 --- a/en/v1.12-dev/stdlib/SparseArrays/index.html +++ b/en/v1.12-dev/stdlib/SparseArrays/index.html @@ -256,4 +256,4 @@ [C::AbstractSparseMatrixCSC{Tv,Ti}]) where {Tv,Ti}

    Bilaterally permute A, storing result PAQ (A[p,q]) in X. Stores intermediate result (AQ)^T (transpose(A[:,q])) in optional argument C if present. Requires that none of X, A, and, if present, C alias each other; to store result PAQ back into A, use the following method lacking X:

    permute!(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
              q::AbstractVector{<:Integer}[, C::AbstractSparseMatrixCSC{Tv,Ti},
              [workcolptr::Vector{Ti}]]) where {Tv,Ti}

    X's dimensions must match those of A (size(X, 1) == size(A, 1) and size(X, 2) == size(A, 2)), and X must have enough storage to accommodate all allocated entries in A (length(rowvals(X)) >= nnz(A) and length(nonzeros(X)) >= nnz(A)). Column-permutation q's length must match A's column count (length(q) == size(A, 2)). Row-permutation p's length must match A's row count (length(p) == size(A, 1)).

    C's dimensions must match those of transpose(A) (size(C, 1) == size(A, 2) and size(C, 2) == size(A, 1)), and C must have enough storage to accommodate all allocated entries in A (length(rowvals(C)) >= nnz(A) and length(nonzeros(C)) >= nnz(A)).

    For additional (algorithmic) information, and for versions of these methods that forgo argument checking, see (unexported) parent methods unchecked_noalias_permute! and unchecked_aliasing_permute!.

    See also permute.

    SparseArrays.halfperm!Function
    halfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},
    -          q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}

    Column-permute and transpose A, simultaneously applying f to each entry of A, storing the result (f(A)Q)^T (map(f, transpose(A[:,q]))) in X.

    Element type Tv of X must match f(::TvA), where TvA is the element type of A. X's dimensions must match those of transpose(A) (size(X, 1) == size(A, 2) and size(X, 2) == size(A, 1)), and X must have enough storage to accommodate all allocated entries in A (length(rowvals(X)) >= nnz(A) and length(nonzeros(X)) >= nnz(A)). Column-permutation q's length must match A's column count (length(q) == size(A, 2)).

    This method is the parent of several methods performing transposition and permutation operations on SparseMatrixCSCs. As this method performs no argument checking, prefer the safer child methods ([c]transpose[!], permute[!]) to direct use.

    This method implements the HALFPERM algorithm described in F. Gustavson, "Two fast algorithms for sparse matrices: multiplication and permuted transposition," ACM TOMS 4(3), 250-269 (1978). The algorithm runs in O(size(A, 1), size(A, 2), nnz(A)) time and requires no space beyond that passed in.

    SparseArrays.ftranspose!Function
    ftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}

    Transpose A and store it in X while applying the function f to the non-zero elements. Does not remove the zeros created by f. size(X) must be equal to size(transpose(A)). No additional memory is allocated other than resizing the rowval and nzval of X, if needed.

    See halfperm!

    Noteworthy External Sparse Packages

    Several other Julia packages provide sparse matrix implementations that should be mentioned:

    1. SuiteSparseGraphBLAS.jl is a wrapper over the fast, multithreaded SuiteSparse:GraphBLAS C library. On CPU this is typically the fastest option, often significantly outperforming MKLSparse.

    2. CUDA.jl exposes the CUSPARSE library for GPU sparse matrix operations.

    3. SparseMatricesCSR.jl provides a Julia native implementation of the Compressed Sparse Rows (CSR) format.

    4. MKLSparse.jl accelerates SparseArrays sparse-dense matrix operations using Intel's MKL library.

    5. SparseArrayKit.jl available for multidimensional sparse arrays.

    6. LuxurySparse.jl provides static sparse array formats, as well as a coordinate format.

    7. ExtendableSparse.jl enables fast insertion into sparse matrices using a lazy approach to new stored indices.

    8. Finch.jl supports extensive multidimensional sparse array formats and operations through a mini tensor language and compiler, all in native Julia. Support for COO, CSF, CSR, CSC and more, as well as operations like broadcast, reduce, etc. and custom operations.

    + q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}

    Column-permute and transpose A, simultaneously applying f to each entry of A, storing the result (f(A)Q)^T (map(f, transpose(A[:,q]))) in X.

    Element type Tv of X must match f(::TvA), where TvA is the element type of A. X's dimensions must match those of transpose(A) (size(X, 1) == size(A, 2) and size(X, 2) == size(A, 1)), and X must have enough storage to accommodate all allocated entries in A (length(rowvals(X)) >= nnz(A) and length(nonzeros(X)) >= nnz(A)). Column-permutation q's length must match A's column count (length(q) == size(A, 2)).

    This method is the parent of several methods performing transposition and permutation operations on SparseMatrixCSCs. As this method performs no argument checking, prefer the safer child methods ([c]transpose[!], permute[!]) to direct use.

    This method implements the HALFPERM algorithm described in F. Gustavson, "Two fast algorithms for sparse matrices: multiplication and permuted transposition," ACM TOMS 4(3), 250-269 (1978). The algorithm runs in O(size(A, 1), size(A, 2), nnz(A)) time and requires no space beyond that passed in.

    SparseArrays.ftranspose!Function
    ftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}

    Transpose A and store it in X while applying the function f to the non-zero elements. Does not remove the zeros created by f. size(X) must be equal to size(transpose(A)). No additional memory is allocated other than resizing the rowval and nzval of X, if needed.

    See halfperm!

    Noteworthy External Sparse Packages

    Several other Julia packages provide sparse matrix implementations that should be mentioned:

    1. SuiteSparseGraphBLAS.jl is a wrapper over the fast, multithreaded SuiteSparse:GraphBLAS C library. On CPU this is typically the fastest option, often significantly outperforming MKLSparse.

    2. CUDA.jl exposes the CUSPARSE library for GPU sparse matrix operations.

    3. SparseMatricesCSR.jl provides a Julia native implementation of the Compressed Sparse Rows (CSR) format.

    4. MKLSparse.jl accelerates SparseArrays sparse-dense matrix operations using Intel's MKL library.

    5. SparseArrayKit.jl available for multidimensional sparse arrays.

    6. LuxurySparse.jl provides static sparse array formats, as well as a coordinate format.

    7. ExtendableSparse.jl enables fast insertion into sparse matrices using a lazy approach to new stored indices.

    8. Finch.jl supports extensive multidimensional sparse array formats and operations through a mini tensor language and compiler, all in native Julia. Support for COO, CSF, CSR, CSC and more, as well as operations like broadcast, reduce, etc. and custom operations.

    diff --git a/en/v1.12-dev/stdlib/Statistics/index.html b/en/v1.12-dev/stdlib/Statistics/index.html index 1d00de5abcf0..3e34e868911c 100644 --- a/en/v1.12-dev/stdlib/Statistics/index.html +++ b/en/v1.12-dev/stdlib/Statistics/index.html @@ -120,4 +120,4 @@ 18.000000000000004 julia> quantile(skipmissing([1, 10, missing]), 0.5) -5.5 +5.5 diff --git a/en/v1.12-dev/stdlib/StyledStrings/index.html b/en/v1.12-dev/stdlib/StyledStrings/index.html index dd684e96ecb7..ea7d95635d60 100644 --- a/en/v1.12-dev/stdlib/StyledStrings/index.html +++ b/en/v1.12-dev/stdlib/StyledStrings/index.html @@ -83,4 +83,4 @@ julia> tryparse(SimpleColor, "#9558b2") SimpleColor(#9558b2) -julia> tryparse(SimpleColor, "#nocolor")
    Base.mergeMethod
    merge(initial::Face, others::Face...)

    Merge the properties of the initial face and others, with later faces taking priority.

    +julia> tryparse(SimpleColor, "#nocolor")
    Base.mergeMethod
    merge(initial::Face, others::Face...)

    Merge the properties of the initial face and others, with later faces taking priority.

    diff --git a/en/v1.12-dev/stdlib/TOML/index.html b/en/v1.12-dev/stdlib/TOML/index.html index d2b67252bf91..a96cbae73a64 100644 --- a/en/v1.12-dev/stdlib/TOML/index.html +++ b/en/v1.12-dev/stdlib/TOML/index.html @@ -79,4 +79,4 @@ parse(p::Parser, x::Union{AbstractString, IO})

    Parse the string or stream x, and return the resulting table (dictionary). Throw a ParserError upon failure.

    See also TOML.tryparse.

    TOML.parsefileFunction
    parsefile(f::AbstractString)
     parsefile(p::Parser, f::AbstractString)

    Parse file f and return the resulting table (dictionary). Throw a ParserError upon failure.

    See also TOML.tryparsefile.

    TOML.tryparseFunction
    tryparse(x::Union{AbstractString, IO})
     tryparse(p::Parser, x::Union{AbstractString, IO})

    Parse the string or stream x, and return the resulting table (dictionary). Return a ParserError upon failure.

    See also TOML.parse.

    TOML.tryparsefileFunction
    tryparsefile(f::AbstractString)
    -tryparsefile(p::Parser, f::AbstractString)

    Parse file f and return the resulting table (dictionary). Return a ParserError upon failure.

    See also TOML.parsefile.

    TOML.printFunction
    print([to_toml::Function], io::IO [=stdout], data::AbstractDict; sorted=false, by=identity, inline_tables::IdSet{<:AbstractDict})

    Write data as TOML syntax to the stream io. If the keyword argument sorted is set to true, sort tables according to the function given by the keyword argument by. If the keyword argument inline_tables is given, it should be a set of tables that should be printed "inline".

    The following data types are supported: AbstractDict, AbstractVector, AbstractString, Integer, AbstractFloat, Bool, Dates.DateTime, Dates.Time, Dates.Date. Note that the integers and floats need to be convertible to Float64 and Int64 respectively. For other data types, pass the function to_toml that takes the data types and returns a value of a supported type.

    TOML.ParserType
    Parser()

    Constructor for a TOML Parser. Note that in most cases one does not need to explicitly create a Parser but instead one directly use use TOML.parsefile or TOML.parse. Using an explicit parser will however reuse some internal data structures which can be beneficial for performance if a larger number of small files are parsed.

    TOML.ParserErrorType
    ParserError

    Type that is returned from tryparse and tryparsefile when parsing fails. It contains (among others) the following fields:

    • pos, the position in the string when the error happened
    • table, the result that so far was successfully parsed
    • type, an error type, different for different types of errors
    +tryparsefile(p::Parser, f::AbstractString)

    Parse file f and return the resulting table (dictionary). Return a ParserError upon failure.

    See also TOML.parsefile.

    TOML.printFunction
    print([to_toml::Function], io::IO [=stdout], data::AbstractDict; sorted=false, by=identity, inline_tables::IdSet{<:AbstractDict})

    Write data as TOML syntax to the stream io. If the keyword argument sorted is set to true, sort tables according to the function given by the keyword argument by. If the keyword argument inline_tables is given, it should be a set of tables that should be printed "inline".

    The following data types are supported: AbstractDict, AbstractVector, AbstractString, Integer, AbstractFloat, Bool, Dates.DateTime, Dates.Time, Dates.Date. Note that the integers and floats need to be convertible to Float64 and Int64 respectively. For other data types, pass the function to_toml that takes the data types and returns a value of a supported type.

    TOML.ParserType
    Parser()

    Constructor for a TOML Parser. Note that in most cases one does not need to explicitly create a Parser but instead one directly use use TOML.parsefile or TOML.parse. Using an explicit parser will however reuse some internal data structures which can be beneficial for performance if a larger number of small files are parsed.

    TOML.ParserErrorType
    ParserError

    Type that is returned from tryparse and tryparsefile when parsing fails. It contains (among others) the following fields:

    • pos, the position in the string when the error happened
    • table, the result that so far was successfully parsed
    • type, an error type, different for different types of errors
    diff --git a/en/v1.12-dev/stdlib/Tar/index.html b/en/v1.12-dev/stdlib/Tar/index.html index 5601a295ce47..5dd42b4b2322 100644 --- a/en/v1.12-dev/stdlib/Tar/index.html +++ b/en/v1.12-dev/stdlib/Tar/index.html @@ -50,4 +50,4 @@ mode :: UInt16 # mode/permissions (best viewed in octal) size :: Int64 # size of record data in bytes link :: String # target path of a symlink -end

    Types are represented with the following symbols: file, hardlink, symlink, chardev, blockdev, directory, fifo, or for unknown types, the typeflag character as a symbol. Note that extract refuses to extract records types other than file, symlink and directory; list will only list other kinds of records if called with strict=false.

    The tar format includes various other metadata about records, including user and group IDs, user and group names, and timestamps. The Tar package, by design, completely ignores these. When creating tar files, these fields are always set to zero/empty. When reading tar files, these fields are ignored aside from verifying header checksums for each header record for all fields.

    +end

    Types are represented with the following symbols: file, hardlink, symlink, chardev, blockdev, directory, fifo, or for unknown types, the typeflag character as a symbol. Note that extract refuses to extract records types other than file, symlink and directory; list will only list other kinds of records if called with strict=false.

    The tar format includes various other metadata about records, including user and group IDs, user and group names, and timestamps. The Tar package, by design, completely ignores these. When creating tar files, these fields are always set to zero/empty. When reading tar files, these fields are ignored aside from verifying header checksums for each header record for all fields.

    diff --git a/en/v1.12-dev/stdlib/Test/index.html b/en/v1.12-dev/stdlib/Test/index.html index c7b90b311dc6..e707c0464cb6 100644 --- a/en/v1.12-dev/stdlib/Test/index.html +++ b/en/v1.12-dev/stdlib/Test/index.html @@ -4,7 +4,7 @@ gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash});

    Unit Testing

    Testing Base Julia

    Julia is under rapid development and has an extensive test suite to verify functionality across multiple platforms. If you build Julia from source, you can run this test suite with make test. In a binary install, you can run the test suite using Base.runtests().

    Base.runtestsFunction
    Base.runtests(tests=["all"]; ncores=ceil(Int, Sys.CPU_THREADS / 2),
    -              exit_on_error=false, revise=false, [seed])

    Run the Julia unit tests listed in tests, which can be either a string or an array of strings, using ncores processors. If exit_on_error is false, when one test fails, all remaining tests in other files will still be run; they are otherwise discarded, when exit_on_error == true. If revise is true, the Revise package is used to load any modifications to Base or to the standard libraries before running the tests. If a seed is provided via the keyword argument, it is used to seed the global RNG in the context where the tests are run; otherwise the seed is chosen randomly.

    source

    Basic Unit Tests

    The Test module provides simple unit testing functionality. Unit testing is a way to see if your code is correct by checking that the results are what you expect. It can be helpful to ensure your code still works after you make changes, and can be used when developing as a way of specifying the behaviors your code should have when complete. You may also want to look at the documentation for adding tests to your Julia Package.

    Simple unit testing can be performed with the @test and @test_throws macros:

    Test.@testMacro
    @test ex
    +              exit_on_error=false, revise=false, [seed])

    Run the Julia unit tests listed in tests, which can be either a string or an array of strings, using ncores processors. If exit_on_error is false, when one test fails, all remaining tests in other files will still be run; they are otherwise discarded, when exit_on_error == true. If revise is true, the Revise package is used to load any modifications to Base or to the standard libraries before running the tests. If a seed is provided via the keyword argument, it is used to seed the global RNG in the context where the tests are run; otherwise the seed is chosen randomly.

    source

    Basic Unit Tests

    The Test module provides simple unit testing functionality. Unit testing is a way to see if your code is correct by checking that the results are what you expect. It can be helpful to ensure your code still works after you make changes, and can be used when developing as a way of specifying the behaviors your code should have when complete. You may also want to look at the documentation for adding tests to your Julia Package.

    Simple unit testing can be performed with the @test and @test_throws macros:

    Test.@testMacro
    @test ex
     @test f(args...) key=val ...
     @test ex broken=true
     @test ex skip=true

    Test that the expression ex evaluates to true. If executed inside a @testset, return a Pass Result if it does, a Fail Result if it is false, and an Error Result if it could not be evaluated. If executed outside a @testset, throw an exception instead of returning Fail or Error.

    Examples

    julia> @test true
    @@ -375,4 +375,4 @@
          Testing Running tests...
     Test Summary: | Pass  Total
     Example tests |    9      9
    -     Testing Example tests passed

    And if all went correctly, you should see a similar output as above. Using Test.jl, more complicated tests can be added for packages but this should ideally point developers in the direction of how to get started with testing their own created packages.

    Code Coverage

    Code coverage tracking during tests can be enabled using the pkg> test --coverage flag (or at a lower level using the --code-coverage julia arg). This is on by default in the julia-runtest GitHub action.

    To evaluate coverage either manually inspect the .cov files that are generated beside the source files locally, or in CI use the julia-processcoverage GitHub action.

    Julia 1.11

    Since Julia 1.11, coverage is not collected during the package precompilation phase.

    + Testing Example tests passed

    And if all went correctly, you should see a similar output as above. Using Test.jl, more complicated tests can be added for packages but this should ideally point developers in the direction of how to get started with testing their own created packages.

    Code Coverage

    Code coverage tracking during tests can be enabled using the pkg> test --coverage flag (or at a lower level using the --code-coverage julia arg). This is on by default in the julia-runtest GitHub action.

    To evaluate coverage either manually inspect the .cov files that are generated beside the source files locally, or in CI use the julia-processcoverage GitHub action.

    Julia 1.11

    Since Julia 1.11, coverage is not collected during the package precompilation phase.

    diff --git a/en/v1.12-dev/stdlib/UUIDs/index.html b/en/v1.12-dev/stdlib/UUIDs/index.html index 7f7abeebf609..44c728aa549e 100644 --- a/en/v1.12-dev/stdlib/UUIDs/index.html +++ b/en/v1.12-dev/stdlib/UUIDs/index.html @@ -22,4 +22,4 @@ julia> u5 = uuid5(u4, "julia") UUID("2df91e3f-da06-5362-a6fe-03772f2e14c9")
    UUIDs.uuid_versionFunction
    uuid_version(u::UUID) -> Int

    Inspects the given UUID and returns its version (see RFC 4122).

    Examples

    julia> uuid_version(uuid4())
    -4
    +4 diff --git a/en/v1.12-dev/stdlib/Unicode/index.html b/en/v1.12-dev/stdlib/Unicode/index.html index c86a74db66a2..19e004f47322 100644 --- a/en/v1.12-dev/stdlib/Unicode/index.html +++ b/en/v1.12-dev/stdlib/Unicode/index.html @@ -59,4 +59,4 @@ 'o': ASCII/Unicode U+006F (category Ll: Letter, lowercase) 's': ASCII/Unicode U+0073 (category Ll: Letter, lowercase) 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase) - '́': Unicode U+0301 (category Mn: Mark, nonspacing)

    This consists of the 3rd to 7th codepoints (Chars) in "exposé", because the grapheme "é" is actually two Unicode codepoints (an 'e' followed by an acute-accent combining character U+0301).

    Because finding grapheme boundaries requires iteration over the string contents, the graphemes(s, m:n) function requires time proportional to the length of the string (number of codepoints) before the end of the substring.

    Julia 1.9

    The m:n argument of graphemes requires Julia 1.9.

    + '́': Unicode U+0301 (category Mn: Mark, nonspacing)

    This consists of the 3rd to 7th codepoints (Chars) in "exposé", because the grapheme "é" is actually two Unicode codepoints (an 'e' followed by an acute-accent combining character U+0301).

    Because finding grapheme boundaries requires iteration over the string contents, the graphemes(s, m:n) function requires time proportional to the length of the string (number of codepoints) before the end of the substring.

    Julia 1.9

    The m:n argument of graphemes requires Julia 1.9.

    diff --git a/en/v1.12-dev/tutorials/creating-packages/index.html b/en/v1.12-dev/tutorials/creating-packages/index.html index 556b9d730545..1aad114128ea 100644 --- a/en/v1.12-dev/tutorials/creating-packages/index.html +++ b/en/v1.12-dev/tutorials/creating-packages/index.html @@ -183,4 +183,4 @@ end end
  • Make the following change in the conditionally-loaded code:

    isdefined(Base, :get_extension) ? (using Contour) : (using ..Contour)
  • Add Requires to [weakdeps] in your Project.toml file, so that it is listed in both [deps] and [weakdeps]. Julia 1.9+ knows to not install it as a regular dependency, whereas earlier versions will consider it a dependency.

  • The package should now work with Requires.jl on Julia versions before extensions were introduced and with extensions on more recent Julia versions.

    Transition from normal dependency to extension

    This section is relevant if you have a normal dependency that you want to transition be an extension (while still having the dependency be a normal dependency on Julia versions that do not support extensions). This is done by making the following changes (using the example above):

    • Make sure that the package is both in the [deps] and [weakdeps] section. Newer Julia versions will ignore dependencies in [deps] that are also in [weakdeps].
    • Add the following to your main package file (typically at the bottom):
      if !isdefined(Base, :get_extension)
         include("../ext/PlottingContourExt.jl")
      -end

    Using an extension while supporting older Julia versions

    In the case where one wants to use an extension (without worrying about the feature of the extension being available on older Julia versions) while still supporting older Julia versions the packages under [weakdeps] should be duplicated into [extras]. This is an unfortunate duplication, but without doing this the project verifier under older Julia versions will throw an error if it finds packages under [compat] that is not listed in [extras].

    Package naming rules

    Package names should be sensible to most Julia users, even to those who are not domain experts. The following rules apply to the General registry but may be useful for other package registries as well.

    Since the General registry belongs to the entire community, people may have opinions about your package name when you publish it, especially if it's ambiguous or can be confused with something other than what it is. Usually, you will then get suggestions for a new name that may fit your package better.

    1. Avoid jargon. In particular, avoid acronyms unless there is minimal possibility of confusion.

      • It's ok to say USA if you're talking about the USA.
      • It's not ok to say PMA, even if you're talking about positive mental attitude.
    2. Avoid using Julia in your package name or prefixing it with Ju.

      • It is usually clear from context and to your users that the package is a Julia package.
      • Package names already have a .jl extension, which communicates to users that Package.jl is a Julia package.
      • Having Julia in the name can imply that the package is connected to, or endorsed by, contributors to the Julia language itself.
    3. Packages that provide most of their functionality in association with a new type should have pluralized names.

      • DataFrames provides the DataFrame type.
      • BloomFilters provides the BloomFilter type.
      • In contrast, JuliaParser provides no new type, but instead new functionality in the JuliaParser.parse() function.
    4. Err on the side of clarity, even if clarity seems long-winded to you.

      • RandomMatrices is a less ambiguous name than RndMat or RMT, even though the latter are shorter.
    5. A less systematic name may suit a package that implements one of several possible approaches to its domain.

      • Julia does not have a single comprehensive plotting package. Instead, Gadfly, PyPlot, Winston and other packages each implement a unique approach based on a particular design philosophy.
      • In contrast, SortingAlgorithms provides a consistent interface to use many well-established sorting algorithms.
    6. Packages that wrap external libraries or programs can be named after those libraries or programs.

      • CPLEX.jl wraps the CPLEX library, which can be identified easily in a web search.
      • MATLAB.jl provides an interface to call the MATLAB engine from within Julia.
    7. Avoid naming a package closely to an existing package

      • Websocket is too close to WebSockets and can be confusing to users. Rather use a new name such as SimpleWebsockets.
    8. Avoid using a distinctive name that is already in use in a well known, unrelated project.

      • Don't use the names Tkinter.jl, TkinterGUI.jl, etc. for a package that is unrelated to the popular tkinter python package, even if it provides bindings to Tcl/Tk. A package name of Tkinter.jl would only be appropriate if the package used Python's library to accomplish its work or was spearheaded by the same community of developers.
      • It's okay to name a package HTTP.jl even though it is unrelated to the popular rust crate http because in most usages the name "http" refers to the hypertext transfer protocol, not to the http rust crate.
      • It's okay to name a package OpenSSL.jl if it provides an interface to the OpenSSL library, even without explicit affiliation with the creators of the OpenSSL (provided there's no copyright or trademark infringement etc.)

    Registering packages

    Once a package is ready it can be registered with the General Registry (see also the FAQ). Currently, packages are submitted via Registrator. In addition to Registrator, TagBot helps manage the process of tagging releases.

    Best Practices

    Packages should avoid mutating their own state (writing to files within their package directory). Packages should, in general, not assume that they are located in a writable location (e.g. if installed as part of a system-wide depot) or even a stable one (e.g. if they are bundled into a system image by PackageCompiler.jl). To support the various use cases in the Julia package ecosystem, the Pkg developers have created a number of auxiliary packages and techniques to help package authors create self-contained, immutable, and relocatable packages:

    • Artifacts can be used to bundle chunks of data alongside your package, or even allow them to be downloaded on-demand. Prefer artifacts over attempting to open a file via a path such as joinpath(@__DIR__, "data", "my_dataset.csv") as this is non-relocatable. Once your package has been precompiled, the result of @__DIR__ will have been baked into your precompiled package data, and if you attempt to distribute this package, it will attempt to load files at the wrong location. Artifacts can be bundled and accessed easily using the artifact"name" string macro.

    • Scratch.jl provides the notion of "scratch spaces", mutable containers of data for packages. Scratch spaces are designed for data caches that are completely managed by a package and should be removed when the package itself is uninstalled. For important user-generated data, packages should continue to write out to a user-specified path that is not managed by Julia or Pkg.

    • Preferences.jl allows packages to read and write preferences to the top-level Project.toml. These preferences can be read at runtime or compile-time, to enable or disable different aspects of package behavior. Packages previously would write out files to their own package directories to record options set by the user or environment, but this is highly discouraged now that Preferences is available.

    +end

    Using an extension while supporting older Julia versions

    In the case where one wants to use an extension (without worrying about the feature of the extension being available on older Julia versions) while still supporting older Julia versions the packages under [weakdeps] should be duplicated into [extras]. This is an unfortunate duplication, but without doing this the project verifier under older Julia versions will throw an error if it finds packages under [compat] that is not listed in [extras].

    Package naming rules

    Package names should be sensible to most Julia users, even to those who are not domain experts. The following rules apply to the General registry but may be useful for other package registries as well.

    Since the General registry belongs to the entire community, people may have opinions about your package name when you publish it, especially if it's ambiguous or can be confused with something other than what it is. Usually, you will then get suggestions for a new name that may fit your package better.

    1. Avoid jargon. In particular, avoid acronyms unless there is minimal possibility of confusion.

      • It's ok to say USA if you're talking about the USA.
      • It's not ok to say PMA, even if you're talking about positive mental attitude.
    2. Avoid using Julia in your package name or prefixing it with Ju.

      • It is usually clear from context and to your users that the package is a Julia package.
      • Package names already have a .jl extension, which communicates to users that Package.jl is a Julia package.
      • Having Julia in the name can imply that the package is connected to, or endorsed by, contributors to the Julia language itself.
    3. Packages that provide most of their functionality in association with a new type should have pluralized names.

      • DataFrames provides the DataFrame type.
      • BloomFilters provides the BloomFilter type.
      • In contrast, JuliaParser provides no new type, but instead new functionality in the JuliaParser.parse() function.
    4. Err on the side of clarity, even if clarity seems long-winded to you.

      • RandomMatrices is a less ambiguous name than RndMat or RMT, even though the latter are shorter.
    5. A less systematic name may suit a package that implements one of several possible approaches to its domain.

      • Julia does not have a single comprehensive plotting package. Instead, Gadfly, PyPlot, Winston and other packages each implement a unique approach based on a particular design philosophy.
      • In contrast, SortingAlgorithms provides a consistent interface to use many well-established sorting algorithms.
    6. Packages that wrap external libraries or programs can be named after those libraries or programs.

      • CPLEX.jl wraps the CPLEX library, which can be identified easily in a web search.
      • MATLAB.jl provides an interface to call the MATLAB engine from within Julia.
    7. Avoid naming a package closely to an existing package

      • Websocket is too close to WebSockets and can be confusing to users. Rather use a new name such as SimpleWebsockets.
    8. Avoid using a distinctive name that is already in use in a well known, unrelated project.

      • Don't use the names Tkinter.jl, TkinterGUI.jl, etc. for a package that is unrelated to the popular tkinter python package, even if it provides bindings to Tcl/Tk. A package name of Tkinter.jl would only be appropriate if the package used Python's library to accomplish its work or was spearheaded by the same community of developers.
      • It's okay to name a package HTTP.jl even though it is unrelated to the popular rust crate http because in most usages the name "http" refers to the hypertext transfer protocol, not to the http rust crate.
      • It's okay to name a package OpenSSL.jl if it provides an interface to the OpenSSL library, even without explicit affiliation with the creators of the OpenSSL (provided there's no copyright or trademark infringement etc.)

    Registering packages

    Once a package is ready it can be registered with the General Registry (see also the FAQ). Currently, packages are submitted via Registrator. In addition to Registrator, TagBot helps manage the process of tagging releases.

    Best Practices

    Packages should avoid mutating their own state (writing to files within their package directory). Packages should, in general, not assume that they are located in a writable location (e.g. if installed as part of a system-wide depot) or even a stable one (e.g. if they are bundled into a system image by PackageCompiler.jl). To support the various use cases in the Julia package ecosystem, the Pkg developers have created a number of auxiliary packages and techniques to help package authors create self-contained, immutable, and relocatable packages:

    • Artifacts can be used to bundle chunks of data alongside your package, or even allow them to be downloaded on-demand. Prefer artifacts over attempting to open a file via a path such as joinpath(@__DIR__, "data", "my_dataset.csv") as this is non-relocatable. Once your package has been precompiled, the result of @__DIR__ will have been baked into your precompiled package data, and if you attempt to distribute this package, it will attempt to load files at the wrong location. Artifacts can be bundled and accessed easily using the artifact"name" string macro.

    • Scratch.jl provides the notion of "scratch spaces", mutable containers of data for packages. Scratch spaces are designed for data caches that are completely managed by a package and should be removed when the package itself is uninstalled. For important user-generated data, packages should continue to write out to a user-specified path that is not managed by Julia or Pkg.

    • Preferences.jl allows packages to read and write preferences to the top-level Project.toml. These preferences can be read at runtime or compile-time, to enable or disable different aspects of package behavior. Packages previously would write out files to their own package directories to record options set by the user or environment, but this is highly discouraged now that Preferences is available.

    diff --git a/en/v1.12-dev/tutorials/external/index.html b/en/v1.12-dev/tutorials/external/index.html index 9f004d7979de..dc208addb54b 100644 --- a/en/v1.12-dev/tutorials/external/index.html +++ b/en/v1.12-dev/tutorials/external/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-28835595-6', {'page_path': location.pathname + location.search + location.hash}); -
    +
    diff --git a/en/v1.12-dev/tutorials/profile/index.html b/en/v1.12-dev/tutorials/profile/index.html index 8566269b4be9..d79028baea95 100644 --- a/en/v1.12-dev/tutorials/profile/index.html +++ b/en/v1.12-dev/tutorials/profile/index.html @@ -97,4 +97,4 @@ "alloc-profile.pb.gz"

    Then you can view the profile by navigating to http://localhost:62261, and the profile is saved to disk. See PProf package for more options.

    Allocation Profiling Tips

    As stated above, aim for around 1-10 thousand samples in your profile.

    Note that we are uniformly sampling in the space of all allocations, and are not weighting our samples by the size of the allocation. So a given allocation profile may not give a representative profile of where most bytes are allocated in your program, unless you had set sample_rate=1.

    Allocations can come from users directly constructing objects, but can also come from inside the runtime or be inserted into compiled code to handle type instability. Looking at the "source code" view can be helpful to isolate them, and then other external tools such as Cthulhu.jl can be useful for identifying the cause of the allocation.

    Allocation Profile Visualization Tools

    There are several profiling visualization tools now that can all display Allocation Profiles. Here is a small list of some of the main ones we know about:

    • PProf.jl
    • ProfileCanvas.jl
    • VSCode's built-in profile visualizer (@profview_allocs) [docs needed]
    • Viewing the results directly in the REPL
      • You can inspect the results in the REPL via Profile.Allocs.fetch(), to view the stacktrace and type of each allocation.

    Line-by-Line Allocation Tracking

    An alternative way to measure allocations is to start Julia with the --track-allocation=<setting> command-line option, for which you can choose none (the default, do not measure allocation), user (measure memory allocation everywhere except Julia's core code), or all (measure memory allocation at each line of Julia code). Allocation gets measured for each line of compiled code. When you quit Julia, the cumulative results are written to text files with .mem appended after the file name, residing in the same directory as the source file. Each line lists the total number of bytes allocated. The Coverage package contains some elementary analysis tools, for example to sort the lines in order of number of bytes allocated.

    In interpreting the results, there are a few important details. Under the user setting, the first line of any function directly called from the REPL will exhibit allocation due to events that happen in the REPL code itself. More significantly, JIT-compilation also adds to allocation counts, because much of Julia's compiler is written in Julia (and compilation usually requires memory allocation). The recommended procedure is to force compilation by executing all the commands you want to analyze, then call Profile.clear_malloc_data() to reset all allocation counters. Finally, execute the desired commands and quit Julia to trigger the generation of the .mem files.

    Note

    --track-allocation changes code generation to log the allocations, and so the allocations may be different than what happens without the option. We recommend using the allocation profiler instead.

    External Profiling

    Currently Julia supports Intel VTune, OProfile and perf as external profiling tools.

    Depending on the tool you choose, compile with USE_INTEL_JITEVENTS, USE_OPROFILE_JITEVENTS and USE_PERF_JITEVENTS set to 1 in Make.user. Multiple flags are supported.

    Before running Julia set the environment variable ENABLE_JITPROFILING to 1.

    Now you have a multitude of ways to employ those tools! For example with OProfile you can try a simple recording :

    >ENABLE_JITPROFILING=1 sudo operf -Vdebug ./julia test/fastmath.jl
     >opreport -l `which ./julia`

    Or similarly with perf :

    $ ENABLE_JITPROFILING=1 perf record -o /tmp/perf.data --call-graph dwarf -k 1 ./julia /test/fastmath.jl
     $ perf inject --jit --input /tmp/perf.data --output /tmp/perf-jit.data
    -$ perf report --call-graph -G -i /tmp/perf-jit.data

    There are many more interesting things that you can measure about your program, to get a comprehensive list please read the Linux perf examples page.

    Remember that perf saves for each execution a perf.data file that, even for small programs, can get quite large. Also the perf LLVM module saves temporarily debug objects in ~/.debug/jit, remember to clean that folder frequently.

    +$ perf report --call-graph -G -i /tmp/perf-jit.data

    There are many more interesting things that you can measure about your program, to get a comprehensive list please read the Linux perf examples page.

    Remember that perf saves for each execution a perf.data file that, even for small programs, can get quite large. Also the perf LLVM module saves temporarily debug objects in ~/.debug/jit, remember to clean that folder frequently.